//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: EconItemSchema: Defines a schema for econ items // //============================================================================= #ifndef ECONITEMSCHEMA_H #define ECONITEMSCHEMA_H #ifdef _WIN32 #pragma once #endif // Valve code doesn't play nicely with standard headers on some platforms sometimes. #ifdef min #undef min #endif #ifdef max #undef max #endif #include #include "KeyValues.h" #include "tier1/utldict.h" #include "tier1/utlhashmaplarge.h" #include "econ_item_constants.h" #include "item_selection_criteria.h" #include "bitvec.h" #include "language.h" #include "smartptr.h" #include "rtime.h" #include "checksum_sha1.h" #if defined(CLIENT_DLL) || defined(GAME_DLL) #include "engine/ivmodelinfo.h" #include "engine/ivmodelrender.h" #include "ilocalize.h" #endif #include "gamestringpool.h" class CEconItemSchema; class CEconItem; class CEconSharedObjectCache; class CSOItemRecipe; union attribute_data_union_t { float asFloat; uint32 asUint32; byte *asBlobPointer; }; struct static_attrib_t { static_attrib_t() { iDefIndex = 0; m_value.asBlobPointer = NULL; #ifdef GC_DLL bForceGCToGenerate = false; m_pKVCustomData = NULL; #endif // GC_DLL } ~static_attrib_t() { #ifdef GC_DLL if ( m_pKVCustomData ) m_pKVCustomData->deleteThis(); m_pKVCustomData = NULL; #endif } static_attrib_t( const static_attrib_t& rhs ) { iDefIndex = rhs.iDefIndex; m_value = rhs.m_value; #ifdef GC_DLL m_pKVCustomData = rhs.m_pKVCustomData ? rhs.m_pKVCustomData->MakeCopy() : NULL; bForceGCToGenerate = rhs.bForceGCToGenerate; #endif } attrib_definition_index_t iDefIndex; attribute_data_union_t m_value; #ifdef GC_DLL bool bForceGCToGenerate; KeyValues *m_pKVCustomData; #endif // GC_DLL // Parses a single subsection from a multi-line attribute block that looks like: // // "attributes" // { // "cannot trade" // { // "attribute_class" "cannot_trade" // "value" "1" // } // "kill eater" // { // "attribute_class" "kill_eater" // "force_gc_to_generate" "1" // "use_custom_logic" "gifts_given_out" // } // } // // The "force_gc_to_generate" and "use_custom_logic" fields will only be parsed on the GC. Will return // true/false based on whether the whole attribute and value parsed successfully. bool BInitFromKV_MultiLine( const char *pszContext, KeyValues *pKVAttribute, CUtlVector *pVecErrors ); // Parses a single subsection from a single-line attribute block that looks like: // // CharacterAttributes // { // "increase buff duration" 9.0 // "damage bonus" 2.0 // } // // It's impossible to specify GC-generated attributes in this format. Will return true/false based on // whether the whole attribute and value parsed successfully. bool BInitFromKV_SingleLine( const char *pszContext, KeyValues *pKVAttribute, CUtlVector *pVecErrors, bool bEnableTerribleBackwardsCompatibilitySchemaParsingCode = true ); // Data access helpers. const class CEconItemAttributeDefinition *GetAttributeDefinition() const; const class ISchemaAttributeType *GetAttributeType() const; }; typedef uint16 equipped_class_t; typedef uint16 equipped_slot_t; typedef uint8 equipped_preset_t; #define INVALID_EQUIPPED_SLOT ((equipped_slot_t)-1) #define INVALID_STYLE_INDEX ((style_index_t)-1) #define INVALID_PRESET_INDEX ((equipped_preset_t)-1) enum EEquipType_t { EQUIP_TYPE_CLASS = 0, EQUIP_TYPE_ACCOUNT, EQUIP_TYPE_INVALID, }; // Streamable weapons cause stutters when people enter PVS. Turn it off for now. // #define WITH_STREAMABLE_WEAPONS //----------------------------------------------------------------------------- // IEconItemPropertyGenerator //----------------------------------------------------------------------------- class IEconItemPropertyGenerator { public: virtual ~IEconItemPropertyGenerator() { } MUST_CHECK_RETURN virtual bool BGenerateProperties( CEconItem *pItem ) const = 0; }; //----------------------------------------------------------------------------- // Item Series //----------------------------------------------------------------------------- class CEconItemSeriesDefinition { public: CEconItemSeriesDefinition( void ); CEconItemSeriesDefinition( const CEconItemSeriesDefinition &that ); CEconItemSeriesDefinition &operator=( const CEconItemSeriesDefinition& rhs ); ~CEconItemSeriesDefinition( void ) { } bool BInitFromKV( KeyValues *pKVItem, CUtlVector *pVecErrors = NULL ); int32 GetDBValue( void ) const { return m_nValue; } const char *GetName( void ) const { return !m_strName.IsEmpty() ? m_strName.String() : "unknown"; } const char *GetLocKey( void ) const { return !m_strLockKey.IsEmpty() ? m_strLockKey.String() : "unknown"; } const char *GetUiFile( void ) const { return !m_strUiFile.IsEmpty() ? m_strUiFile.String() : "unknown"; } private: // The value that the game/DB will know this series by int32 m_nValue; CUtlString m_strName; // Key Name CUtlString m_strLockKey; // Localization key CUtlString m_strUiFile; // Ui File (.res file) }; //----------------------------------------------------------------------------- // CEconItemRarityDefinition //----------------------------------------------------------------------------- class CEconItemRarityDefinition { public: CEconItemRarityDefinition( void ); ~CEconItemRarityDefinition( void ) { } bool BInitFromKV( KeyValues *pKVItem, KeyValues *pKVRarityWeights, CEconItemSchema &pschema, CUtlVector *pVecErrors = NULL ); int32 GetDBValue( void ) const { return m_nValue; } const char *GetName( void ) const { return !m_strName.IsEmpty() ? m_strName.String() : "unknown"; } const char *GetLocKey( void ) const { return m_strLocKey.String(); } const char *GetWepLocKey( void ) const { return m_strWepLocKey.String(); } const char *GetDropSound( void ) const { return m_strDropSound.String(); } attrib_colors_t GetAttribColor( void ) const { return m_iAttribColor; } const char *GetNextRarity( void ) const { return m_strNextRarity.String(); } int32 GetLootlistWeight( void ) const { return m_nLootlistWeight; } private: // The value that the game/DB will know this rarity by int32 m_nValue; attrib_colors_t m_iAttribColor; // The English name of the rarity CUtlString m_strName; // The localization key for this rarity. CUtlString m_strLocKey; // The localization key for this rarity, for weapons. CUtlString m_strWepLocKey; // The loot list name associated with this rarity. CUtlString m_strDropSound; CUtlString m_strNextRarity; int32 m_nLootlistWeight; }; //----------------------------------------------------------------------------- // CEconItemQualityDefinition // Template Definition of a randomly created item //----------------------------------------------------------------------------- class CEconItemQualityDefinition { public: CEconItemQualityDefinition( void ); CEconItemQualityDefinition( const CEconItemQualityDefinition &that ); CEconItemQualityDefinition &operator=( const CEconItemQualityDefinition& rhs ); ~CEconItemQualityDefinition( void ) { } bool BInitFromKV( KeyValues *pKVItem, CUtlVector *pVecErrors = NULL ); int32 GetDBValue( void ) const { return m_nValue; } const char *GetName( void ) const { return !m_strName.IsEmpty() ? m_strName.Get() : "unknown"; } bool CanSupportSet( void ) const { return m_bCanSupportSet; } const char *GetHexColor( void ) const { return !m_strHexColor.IsEmpty() ? m_strHexColor.Get() : "B2B2B2"; } #ifdef DBGFLAG_VALIDATE void Validate( CValidator &validator, const char *pchName ) { VALIDATE_SCOPE(); ValidateObj( m_strName ); } #endif // DBGFLAG_VALIDATE private: // The value that the game/DB will know this quality by int32 m_nValue; // The English name of the quality CUtlConstString m_strName; // if this is true the support tool is allowed to set this quality level on any item bool m_bCanSupportSet; // A hex string representing the color this quality should display as. Used primarily for display on the Web. CUtlConstString m_strHexColor; }; //----------------------------------------------------------------------------- // CEconColorDefinition //----------------------------------------------------------------------------- class CEconColorDefinition { public: bool BInitFromKV( KeyValues *pKVColor, CUtlVector *pVecErrors = NULL ); const char *GetName( void ) const { return m_strName.Get(); } const char *GetColorName( void ) const { return m_strColorName.Get(); } // meant for passing into VGUI styles, etc. const char *GetHexColor( void ) const { return m_strHexColor.Get(); } private: // The English name of this color. Only used for lookup. CUtlConstString m_strName; // The VGUI name of the color in our schema. This will be used to set values // for VGUI controls. CUtlConstString m_strColorName; // The hex string value of this color. This will be used for Web display. CUtlConstString m_strHexColor; }; //----------------------------------------------------------------------------- // CEconItemSetDefinition // Definition of an item set //----------------------------------------------------------------------------- class CEconItemSetDefinition { public: CEconItemSetDefinition( void ); CEconItemSetDefinition( const CEconItemSetDefinition &that ); CEconItemSetDefinition &operator=( const CEconItemSetDefinition& rhs ); ~CEconItemSetDefinition( void ) {} bool BInitFromKV( KeyValues *pKVItemSet, CUtlVector *pVecErrors = NULL ); void IterateAttributes( class IEconItemAttributeIterator *pIterator ) const; public: const char *m_pszName; const char *m_pszLocalizedName; CUtlVector m_iItemDefs; int m_iBundleItemDef; // Item def of the store bundle for this set, if any bool m_bIsHiddenSet; // If true, this set and any bonuses will only be visible if the whole set is equipped. struct itemset_attrib_t { attrib_definition_index_t m_iAttribDefIndex; float m_flValue; }; CUtlVector m_iAttributes; }; //----------------------------------------------------------------------------- class CEconItemCollectionDefinition { public: CEconItemCollectionDefinition( void ); ~CEconItemCollectionDefinition( void ) {} bool BInitFromKV( KeyValues *pKVItemCollection, CUtlVector *pVecErrors = NULL ); uint8 GetMinRarity() const { return m_iRarityMin; } uint8 GetMaxRarity() const { return m_iRarityMax; } public: const char *m_pszName; const char *m_pszLocalizedName; const char *m_pszLocalizedDesc; CUtlVector m_iItemDefs; private: bool m_bIsReferenceCollection; uint8 m_iRarityMin; uint8 m_iRarityMax; }; //----------------------------------------------------------------------------- class CEconItemPaintKitDefinition { public: CEconItemPaintKitDefinition( void ); ~CEconItemPaintKitDefinition( void ); bool BInitFromKV( KeyValues *pKVItemPaintKit, CUtlVector *pVecErrors = NULL ); //KeyValues *GetKVP() { return m_pKVItem; } const char *GetName() const { return m_pszName; } const char *GetLocalizeName() const { return m_pszLocalizedName; } KeyValues *GetPaintKitWearKV( int nWear ); private: const char *m_pszName; const char *m_pszLocalizedName; CUtlVector< KeyValues * > m_vecPaintKitWearKVP; }; //----------------------------------------------------------------------------- class CEconOperationDefinition { public: CEconOperationDefinition( void ); ~CEconOperationDefinition( void ); bool BInitFromKV( KeyValues *pKVOperation, CUtlVector *pVecErrors = NULL ); const char *GetName() const { return m_pszName; } operation_definition_index_t GetOperationID() const { return m_unOperationID; } item_definition_index_t GetRequiredItemDefIndex() const { return m_unRequiredItemDefIndex; } item_definition_index_t GetGatewayItemDefIndex() const { return m_unGatewayItemDefIndex; } KeyValues *GetKVP() { return m_pKVItem; } // use the date that we stop giving things to players as expiry date bool IsExpired() const { return CRTime::RTime32TimeCur() > GetStopGivingToPlayerDate(); } bool IsActive() const { return CRTime::RTime32TimeCur() >= GetStartDate() && !IsExpired(); } const char *GetQuestLogOverrideResFile() const { return m_pszQuestLogResFile; } const char *GetQuestListOverrideResFile() const { return m_pszQuestListResFile; } RTime32 GetStartDate() const { return m_OperationStartDate; } RTime32 GetStopGivingToPlayerDate() const { return m_StopGivingToPlayerDate; } RTime32 GetStopAddingToQueueDate() const { return m_StopAddingToQueueDate; } const char *GetOperationLootlist() const { return m_pszOperationLootList; } bool IsCampaign() const { return m_bIsCampaign; } uint32 GetMaxDropCount() const { return m_unMaxDropCount; } #ifdef GC_DLL enum EContractRewardLootlist_t { REWARD_CASE, REWARD_WEAPON, NUM_REWARDS }; const char *GetContractRewardLootlist( EContractRewardLootlist_t eType ) const { return m_pszContractRewardLootlist[ eType ]; } RTime32 GetMinQueueFreq() const; RTime32 GetMaxQueueFreq() const; RTime32 GetMinDropFreq() const; RTime32 GetMaxDropFreq() const; uint8 GetNumSeededContracts() const { return m_unSeed; } uint16 GetNumMaxHeldDrops() const { return m_unMaxHeldDrops; } int GetNumMaxQueueCount() const { return m_nMaxQueueCount; } uint8 GetMaxDropPerThink() const { return m_unMaxDropPerThink; } #endif // GC_DLL private: const char *m_pszName; operation_definition_index_t m_unOperationID; // things operation periodically drops const char *m_pszOperationLootList; bool m_bIsCampaign; uint32 m_unMaxDropCount; const char *m_pszQuestLogResFile; const char *m_pszQuestListResFile; item_definition_index_t m_unRequiredItemDefIndex; item_definition_index_t m_unGatewayItemDefIndex; // Defindex of the item users need to acquire in order to get the required item. Could be the required item itself. RTime32 m_OperationStartDate; // when the operation starts and gives out rewards RTime32 m_StopGivingToPlayerDate; // when the operation stops giving quests to player RTime32 m_StopAddingToQueueDate; // when the operation stops adding more quests to the bucket #ifdef GC_DLL const char *m_pszContractRewardLootlist[ NUM_REWARDS ]; // in seconds RTime32 m_rtQueueFreqMin; RTime32 m_rtQueueFreqMax; RTime32 m_rtDropFreqMin; RTime32 m_rtDropFreqMax; uint8 m_unSeed; uint16 m_unMaxHeldDrops; int m_nMaxQueueCount; uint8 m_unMaxDropPerThink; #endif // GC_DLL KeyValues *m_pKVItem; }; //----------------------------------------------------------------------------- // CEconLootListDefinition // Definition of a loot list //----------------------------------------------------------------------------- class IEconLootList { public: virtual ~IEconLootList() { } MUST_CHECK_RETURN virtual bool BPublicListContents() const = 0; MUST_CHECK_RETURN virtual const char *GetLootListHeaderLocalizationKey() const = 0; MUST_CHECK_RETURN virtual const char *GetLootListFooterLocalizationKey() const = 0; MUST_CHECK_RETURN virtual const char *GetLootListCollectionReference() const = 0; class IEconLootListIterator { public: virtual ~IEconLootListIterator() { } virtual void OnIterate( item_definition_index_t unItemDefIndex ) = 0; }; virtual void EnumerateUserFacingPotentialDrops( IEconLootListIterator *pIt ) const = 0; #ifdef GC_DLL MUST_CHECK_RETURN virtual bool BGenerateSingleRollRandomItems( const CEconGameAccount *pGameAccount, bool bFreeAccount, CUtlVector *out_pvecItems, const CUtlVector< item_definition_index_t > *pVecAvoidItemDefs = NULL ) const = 0; #endif // GC_DLL }; #ifdef GC_DLL struct lootlist_attrib_t { static_attrib_t m_staticAttrib; float m_flWeight; bool BInitFromKV( const char *pszContext, KeyValues *pKVKey, CEconItemSchema &pschema, CUtlVector *pVecErrors ); }; struct random_attrib_t { float m_flChanceOfRandomAttribute; float m_flTotalAttributeWeight; bool m_bPickAllAttributes; CUtlVector m_RandomAttributes; bool RollRandomAttributes( CUtlVector< static_attrib_t >& vecAttributes, const CEconGameAccount *pGameAccount ) const; }; #endif // GC_DLL class CEconLootListDefinition : public IEconLootList { public: struct drop_period_t { bool IsValidForTime( const RTime32& time ) const; RTime32 m_DropStartDate; RTime32 m_DropEndDate; }; struct drop_item_t { int m_iItemOrLootlistDef; // negative values indicate nested loot lists float m_flWeight; drop_period_t m_dropPeriod; }; struct loot_list_additional_drop_t { float m_fChance; bool m_bPremiumOnly; const char *m_pszLootListDefName; int m_iRequiredHolidayIndex; drop_period_t m_dropPeriod; }; virtual ~CEconLootListDefinition(); bool BInitFromKV( KeyValues *pKVLootList, CEconItemSchema &pschema, CUtlVector *pVecErrors ); const char *GetName() const { return m_pszName; } virtual const char *GetLootListHeaderLocalizationKey() const OVERRIDE { return m_pszLootListHeader; } virtual const char *GetLootListFooterLocalizationKey() const OVERRIDE { return m_pszLootListFooter; } virtual const char *GetLootListCollectionReference() const OVERRIDE { return m_pszCollectionReference; } const CUtlVector& GetLootListContents() const { return m_DropList; } #ifdef GC_DLL const CUtlVector& GetAdditionalDrops() const { return m_AdditionalDrops; } #endif virtual void EnumerateUserFacingPotentialDrops( IEconLootListIterator *pIt ) const OVERRIDE; virtual bool BPublicListContents() const OVERRIDE { return m_bPublicListContents; } #ifdef GC_DLL public: struct rolled_item_defs_t { const CEconItemDefinition *m_pItemDef; CCopyableUtlVector< const CEconLootListDefinition * > m_vecAffectingLootLists; }; bool AddRandomAtrributes( KeyValues *pRandomAttributesKV, CEconItemSchema &pschema, CUtlVector *pVecErrors = NULL ); bool AddRandomAttributesFromTemplates( KeyValues *pRandomAttributesKV, CEconItemSchema &pschema, CUtlVector *pVecErrors = NULL ); // Generates a single roll for this loot list as well as each "additional drop" loot list specified. This will return // true if all items were created successfully or false if anything went wrong in any of the relevant lootlists. All // items created will be returned via out_pvecItems. MUST_CHECK_RETURN virtual bool BGenerateSingleRollRandomItems( const CEconGameAccount *pGameAccount, bool bFreeAccount, CUtlVector *out_pvecItems, const CUtlVector< item_definition_index_t > *pVecAvoidItemDefs = NULL ) const OVERRIDE; void RollRandomAttributes( CUtlVector< static_attrib_t >& vecAttributes, const CEconGameAccount *pGameAccount ) const; bool RollRandomItemsAndAdditionalItems( IUniformRandomStream *pRandomStream, bool bFreeAccount, CUtlVector *out_pVecRolledItems, const CUtlVector< item_definition_index_t > *pVecAvoidItemDefs = NULL ) const; uint8 GetRarity() const { return m_unRarity; } void GetRarityLootLists( CUtlVector< const CEconLootListDefinition* > *out_pVecRarityLootList ) const; void GetItemDefs( CUtlVector< item_definition_index_t > *out_pVecItemDefs ) const; private: bool RollRandomItemDef( IUniformRandomStream *pRandomStream, bool bFreeAccount, CUtlVector *out_pVecRolledItems, const CUtlVector< item_definition_index_t > *pVecAvoidItemDefs = NULL ) const; bool BIsInternalNoDupesLootList() const { return m_iNoDupesIterations >= 0; } MUST_CHECK_RETURN bool BInitPropertyGeneratorsFromKV( KeyValues *pKV, CUtlVector *pVecErrors ); #endif private: const char *m_pszName; const char *m_pszLootListHeader; const char *m_pszLootListFooter; const char *m_pszCollectionReference; CUtlVector m_DropList; bool m_bPublicListContents; // do not show loot list contents to users (ie., when listing crate contents on Steam) #ifdef GC_DLL MUST_CHECK_RETURN bool BAttachLootListAttributes( const CEconGameAccount *pGameAccount, CEconItem *pItem ) const; int m_iNoDupesIterations; // if less than zero, "no dupes" functionality disabled; if greater than or equal to zero, the number of iterations we want to run through passing no-dupe sets CUtlVector m_RandomAttribs; CUtlVector m_AdditionalDrops; CUtlVector m_PropertyGenerators; uint8 m_unRarity; #endif // GC_DLL }; //----------------------------------------------------------------------------- // CEconCraftingRecipeDefinition // Template Definition of an item recipe //----------------------------------------------------------------------------- class CEconCraftingRecipeDefinition { public: CEconCraftingRecipeDefinition( void ); virtual ~CEconCraftingRecipeDefinition( void ) { } bool BInitFromKV( KeyValues *pKVItem, CUtlVector *pVecErrors = NULL ); #ifdef GC_DLL bool BIsCraftableByUnverifiedClients() const { return m_bIsCraftableByUnverifiedClient; } #endif // GC_DLL virtual void CopyPolymorphic( const CEconCraftingRecipeDefinition *pSourceDef ) { *this = *pSourceDef; } void SetDefinitionIndex( uint32 iIndex ) { m_nDefIndex = iIndex; } int32 GetDefinitionIndex( void ) const { return m_nDefIndex; } const char *GetName( void ) const { return !m_strName.IsEmpty() ? m_strName.String() : "unknown"; } const char *GetName_A( void ) const { return !m_strN_A.IsEmpty() ? m_strN_A.String() : "unknown"; } const char *GetDescInputs( void ) const { return !m_strDescInputs.IsEmpty() ? m_strDescInputs.String() : "unknown"; } const char *GetDescOutputs( void ) const { return !m_strDescOutputs.IsEmpty() ? m_strDescOutputs.String() : "unknown"; } const char *GetDescI_A( void ) const { return !m_strDI_A.IsEmpty() ? m_strDI_A.String() : "unknown"; } const char *GetDescI_B( void ) const { return !m_strDI_B.IsEmpty() ? m_strDI_B.String() : "unknown"; } const char *GetDescI_C( void ) const { return !m_strDI_C.IsEmpty() ? m_strDI_C.String() : "unknown"; } const char *GetDescO_A( void ) const { return !m_strDO_A.IsEmpty() ? m_strDO_A.String() : "unknown"; } const char *GetDescO_B( void ) const { return !m_strDO_B.IsEmpty() ? m_strDO_B.String() : "unknown"; } const char *GetDescO_C( void ) const { return !m_strDO_C.IsEmpty() ? m_strDO_C.String() : "unknown"; } bool IsDisabled( void ) const { return m_bDisabled; } bool RequiresAllSameClass( void ) { return m_bRequiresAllSameClass; } bool RequiresAllSameSlot( void ) { return m_bRequiresAllSameSlot; } bool IsPremiumAccountOnly( void ) const { return m_bPremiumAccountOnly; } recipecategories_t GetCategory( void ) const { return m_iCategory; } int GetTotalInputItemsRequired( void ) const; int GetTotalOutputItems( void ) const { return m_OutputItemsCriteria.Count(); } // Returns true if the vector contains a set of items that matches the inputs for this recipe virtual bool ItemListMatchesInputs( CUtlVector *vecCraftingItems, KeyValues *out_pCraftParams = NULL, bool bIgnoreSlop = false, CUtlVector *vecChosenItems = NULL ) const; const CUtlVector *GetInputItems( void ) const { return &m_InputItemsCriteria; } const CUtlVector &GetInputItemDupeCounts( void ) const { return m_InputItemDupeCounts; } const CUtlVector &GetOutputItems( void ) const { return m_OutputItemsCriteria; } #ifdef DBGFLAG_VALIDATE void Validate( CValidator &validator, const char *pchName ) { VALIDATE_SCOPE(); ValidateObj( m_InputItemsCriteria ); ValidateObj( m_InputItemDupeCounts ); ValidateObj( m_OutputItemsCriteria ); } #endif // DBGFLAG_VALIDATE // Serializes the criteria to and from messages bool BSerializeToMsg( CSOItemRecipe & msg ) const; bool BDeserializeFromMsg( const CSOItemRecipe & msg ); protected: // The number used to refer to this definition in the DB int32 m_nDefIndex; // Localization key strings CUtlString m_strName; CUtlString m_strN_A; CUtlString m_strDescInputs; CUtlString m_strDescOutputs; CUtlString m_strDI_A; CUtlString m_strDI_B; CUtlString m_strDI_C; CUtlString m_strDO_A; CUtlString m_strDO_B; CUtlString m_strDO_C; bool m_bDisabled; #ifdef GC_DLL bool m_bIsCraftableByUnverifiedClient; #endif // GC_DLL bool m_bRequiresAllSameClass; bool m_bRequiresAllSameSlot; int m_iCacheClassUsageForOutputFromItem; int m_iCacheSlotUsageForOutputFromItem; int m_iCacheSetForOutputFromItem; bool m_bPremiumAccountOnly; recipecategories_t m_iCategory; // The list of items that a required to make this recipe CUtlVector m_InputItemsCriteria; CUtlVector m_InputItemDupeCounts; // The list of items that are generated by this recipe CUtlVector m_OutputItemsCriteria; }; //----------------------------------------------------------------------------- // Purpose: Attribute definition details //----------------------------------------------------------------------------- enum { ATTDESCFORM_VALUE_IS_PERCENTAGE, // Printed as: ((m_flValue*100)-100.0) ATTDESCFORM_VALUE_IS_INVERTED_PERCENTAGE, // Printed as: ((m_flValue*100)-100.0) if it's > 1.0, or ((1.0-m_flModifier)*100) if it's < 1.0 ATTDESCFORM_VALUE_IS_ADDITIVE, // Printed as: m_flValue ATTDESCFORM_VALUE_IS_ADDITIVE_PERCENTAGE, // Printed as: (m_flValue*100) ATTDESCFORM_VALUE_IS_OR, // Printed as: m_flValue, but results are ORd together instead of added ATTDESCFORM_VALUE_IS_DATE, // Printed as a date ATTDESCFORM_VALUE_IS_ACCOUNT_ID, // Printed as steam user name ATTDESCFORM_VALUE_IS_PARTICLE_INDEX, // Printed as a particle description ATTDESCFORM_VALUE_IS_KILLSTREAKEFFECT_INDEX,// Printed as killstreak effect description ATTDESCFORM_VALUE_IS_KILLSTREAK_IDLEEFFECT_INDEX, // Printed as idle effect description ATTDESCFORM_VALUE_IS_ITEM_DEF, // Printed as item name ATTDESCFORM_VALUE_IS_FROM_LOOKUP_TABLE, // Printed as a string from a lookup table, specified by the attribute definition name }; // Coloring for attribute lines enum attrib_effect_types_t { ATTRIB_EFFECT_UNUSUAL = 0, ATTRIB_EFFECT_STRANGE, ATTRIB_EFFECT_NEUTRAL, ATTRIB_EFFECT_POSITIVE, ATTRIB_EFFECT_NEGATIVE, NUM_EFFECT_TYPES, }; enum EAssetClassAttrExportRule_t { k_EAssetClassAttrExportRule_Default = 0, k_EAssetClassAttrExportRule_Bucketed = ( 1 << 0 ), // attribute exports bucketed value to Steam Community k_EAssetClassAttrExportRule_Skip = ( 1 << 1 ), // attribute value is not exported to Steam Community k_EAssetClassAttrExportRule_GCOnly = ( 1 << 2 ), // attribute only lives on GC and not exported to any external request }; //----------------------------------------------------------------------------- // CEconItemAttributeDefinition // Template definition of a randomly created attribute //----------------------------------------------------------------------------- class CEconItemAttributeDefinition { public: CEconItemAttributeDefinition( void ); CEconItemAttributeDefinition( const CEconItemAttributeDefinition &that ); CEconItemAttributeDefinition &operator=( const CEconItemAttributeDefinition& rhs ); ~CEconItemAttributeDefinition( void ); bool BInitFromKV( KeyValues *pKVAttribute, CUtlVector *pVecErrors = NULL ); attrib_definition_index_t GetDefinitionIndex( void ) const { return m_nDefIndex; } // Attribute name referenced in the db. const char *GetDefinitionName( void ) const { return m_pszDefinitionName; } KeyValues *GetRawDefinition( void ) const { return m_pKVAttribute; } // Data accessing bool IsHidden( void ) const { return m_bHidden; } bool BForceWebSchemaOutput( void ) const { return m_bWebSchemaOutputForced; } bool BIsSetBonusAttribute( void ) const { return m_bIsSetBonus; } bool CanAffectMarketName( void ) const { return m_bCanAffectMarketName; } bool CanAffectRecipeComponentName( void ) const { return m_bCanAffectRecipeComponentName; } bool IsStoredAsInteger( void ) const { return m_bStoredAsInteger; } bool IsStoredAsFloat( void ) const { return !m_bStoredAsInteger; } int GetUserGenerationType( void ) const { return m_iUserGenerationType; } bool IsInstanceData() const { return m_bInstanceData; } EAssetClassAttrExportRule_t GetAssetClassAttrExportRule() const { return m_eAssetClassAttrExportRule; } uint32 GetAssetClassBucket() const { return m_unAssetClassBucket; } int GetDescriptionFormat( void ) const { return m_iDescriptionFormat; } const char *GetDescriptionString( void ) const { return m_pszDescriptionString; } const char *GetArmoryDescString( void ) const { return m_pszArmoryDesc; } const char *GetAttributeClass( void ) const { return m_pszAttributeClass; } econ_tag_handle_t GetItemDefinitionTag( void ) const { return m_ItemDefinitionTag; } attrib_effect_types_t GetEffectType( void ) const { return m_iEffectType; } const class ISchemaAttributeType *GetAttributeType( void ) const { return m_pAttrType; } #ifndef GC_DLL void ClearStringCache( void ) const { m_iszAttributeClass = NULL_STRING; } string_t GetCachedClass( void ) const { if ( m_iszAttributeClass == NULL_STRING && m_pszAttributeClass ) { m_iszAttributeClass = AllocPooledString( m_pszAttributeClass ); } return m_iszAttributeClass; } #endif #ifdef DBGFLAG_VALIDATE void Validate( CValidator &validator, const char *pchName ) { VALIDATE_SCOPE(); ValidatePtr( m_pKVAttribute ); } #endif // DBGFLAG_VALIDATE private: // The raw keyvalues for this attribute definition. KeyValues *m_pKVAttribute; // Required valued from m_pKVAttribute: // The number used to refer to this definition in the DB attrib_definition_index_t m_nDefIndex; // A pointer to the schema-global type data for this attribute. This maps attribute types to functionality // for loading/storing, both to memory and the DB. const class ISchemaAttributeType *m_pAttrType; // --------------------------------------------- // Display related data // --------------------------------------------- // If true, this attribute isn't shown in the item description bool m_bHidden; // If true, this attribute's description is always output in web api calls regardless of the hidden flag. bool m_bWebSchemaOutputForced; // Whether or not the value is stored as an integer in the DB. bool m_bStoredAsInteger; // If this is true the attribute is counted as "instance" data for purposes of asset class in the Steam Economy. Non-instance // properties are considered things that can differentiate items at a fundamental level (ie., definition index, quality); instance // properties are more things like additional customizations -- score for strange items, paint color, etc. bool m_bInstanceData; EAssetClassAttrExportRule_t m_eAssetClassAttrExportRule; // if this is true the attribute will not be exported for asset class uint32 m_unAssetClassBucket; // if this is set then attribute value is bucketed when exported for asset class // Set item bonus attributes use a different attribute parser and make assumptions about memory layout. We // don't really use these for any new content currently and it isn't worth touching all the old code. // // At runtime, this flag is used to determine whether or not to rebuild dynamic attributes attached to // players on respawn. bool m_bIsSetBonus; // Whether or not this attribute is supposed to only come from user actions. These attributes are used for // player item upgrades, etc. and cannot be set on items directly in the schema. int m_iUserGenerationType; // Overall positive/negative effect. Used to color the attribute. attrib_effect_types_t m_iEffectType; // Contains the description format & string for this attribute int m_iDescriptionFormat; const char *m_pszDescriptionString; // Contains information on how to describe items with this attribute in the Armory const char *m_pszArmoryDesc; // Used to allow unique items to specify attributes by name. const char *m_pszDefinitionName; // The class name of this attribute. Used in creation, and to hook the attribute into the actual code that uses it. const char *m_pszAttributeClass; // Allowed to affect the market bucketization name. We dont want things like the strange level to affect the name, // but we do want things like crate series number and strangifier targets to get their own buckets. bool m_bCanAffectMarketName; // Allowed to list itself in the name of an item in the recipe component description. bool m_bCanAffectRecipeComponentName; // Do item definitions with this attribute specified automatically get an additional tag applied? econ_tag_handle_t m_ItemDefinitionTag; #ifndef GC_DLL mutable string_t m_iszAttributeClass; // Same as the above, but used for fast lookup when applying attributes. #endif }; //----------------------------------------------------------------------------- // Visual data storage in item definitions //----------------------------------------------------------------------------- #define TEAM_VISUAL_SECTIONS 5 #define MAX_VISUALS_CUSTOM_SOUNDS 10 struct attachedparticlesystem_t { attachedparticlesystem_t() : pszSystemName( NULL ) , bFollowRootBone( NULL ) , iCustomType( 0 ) , nSystemID( 0 ) , fRefireTime( 0 ) // only works for taunt effects, currently , bDrawInViewModel( false ) , bUseSuffixName( false ) , bHasViewModelSpecificEffect ( false ) { V_memset( pszControlPoints, 0, sizeof( pszControlPoints ) ); } const char *pszSystemName; bool bFollowRootBone; int iCustomType; int nSystemID; float fRefireTime; // only works for taunt effects, currently bool bDrawInViewModel; bool bUseSuffixName; bool bHasViewModelSpecificEffect; const char *pszControlPoints[7]; }; #if defined(CLIENT_DLL) || defined(GAME_DLL) enum { kAttachedModelDisplayFlag_WorldModel = 0x01, kAttachedModelDisplayFlag_ViewModel = 0x02, kAttachedModelDisplayFlag_MaskAll = kAttachedModelDisplayFlag_WorldModel | kAttachedModelDisplayFlag_ViewModel, }; struct attachedmodel_t { const char *m_pszModelName; int m_iModelDisplayFlags; }; enum wearableanimplayback_t { WAP_ON_SPAWN, // Play this animation immediately on spawning the wearable WAP_START_BUILDING, // Game code will start this anim whenever a player wearing this item deploys their builder weapon. WAP_STOP_BUILDING, // Game code will start this anim whenever a player wearing this item holsters their builder weapon. WAP_START_TAUNTING, // Game code will start this anim whenever a player wearing this item taunts WAP_STOP_TAUNTING, // Game code will start this anim whenever a player wearing this item stops taunting NUM_WAP_TYPES, }; struct animation_on_wearable_t { int iActivity; const char *pszActivity; const char *pszReplacement; int iReplacement; // Replacement activity to play. Might be set to one of kActivityLookup_Unknown/kActivityLookup_Missing. const char *pszSequence; const char *pszRequiredItem; const char *pszScene; }; struct activity_on_wearable_t { wearableanimplayback_t iPlayback; int iActivity; const char *pszActivity; }; struct codecontrolledbodygroupdata_t { const char *pFuncName; void *pFunc; }; // This is a workaround because Source practice is to disable operator=() for CUtlMap. struct perteamvisuals_maps_t { perteamvisuals_maps_t() { m_ModifiedBodyGroupNames.SetLessFunc( StringLessThan ); m_CodeControlledBodyGroupNames.SetLessFunc( StringLessThan ); } void operator=( const perteamvisuals_maps_t& other ) { DeepCopyMap( other.m_ModifiedBodyGroupNames, &m_ModifiedBodyGroupNames ); DeepCopyMap( other.m_CodeControlledBodyGroupNames, &m_CodeControlledBodyGroupNames ); } CUtlMap m_ModifiedBodyGroupNames; // Better method: hide multiple body groups by name. CUtlMap m_CodeControlledBodyGroupNames; }; #endif // defined(CLIENT_DLL) || defined(GAME_DLL) class CEconStyleInfo { public: CEconStyleInfo() { for ( int i = 0; i < TEAM_VISUAL_SECTIONS; i++ ) { m_iSkins[i] = 0; m_iViewmodelSkins[i] = -1; } m_pszName = NULL; m_pszBasePlayerModel = NULL; m_bIsSelectable = true; m_pszInventoryImage = NULL; m_pszBodygroupName = NULL; m_iBodygroupSubmodelIndex = -1; m_sIconURLSmall = ""; m_sIconURLLarge = ""; } virtual ~CEconStyleInfo() { // } virtual void BInitFromKV( KeyValues *pKVItem, CUtlVector *pVecErrors ); #if defined(CLIENT_DLL) || defined(GAME_DLL) virtual void GeneratePrecacheModelStringsForStyle( CUtlVector *out_pVecModelStrings ) const; #endif int GetSkin( int iTeam, bool bViewmodel ) const { Assert( iTeam >= 0 ); Assert( iTeam < TEAM_VISUAL_SECTIONS ); if ( bViewmodel && m_iViewmodelSkins[ iTeam ] != -1 ) { return m_iViewmodelSkins[ iTeam ]; } return m_iSkins[iTeam]; } const char *GetName() const { return m_pszName; } const char *GetBasePlayerDisplayModel() const { return m_pszBasePlayerModel; } const CUtlVector& GetAdditionalHideBodygroups() const { return m_vecAdditionalHideBodygroups; } bool IsSelectable() const { return m_bIsSelectable; } const char *GetInventoryImage() const { return m_pszInventoryImage; } const char *GetBodygroupName() const { return m_pszBodygroupName; } int GetBodygroupSubmodelIndex() const { return m_iBodygroupSubmodelIndex; } const char *GetIconURLSmall() const { return m_sIconURLSmall; } const char *GetIconURLLarge() const { return m_sIconURLLarge; } void SetIconURLSmall( const char *szURL ) { m_sIconURLSmall = szURL; } void SetIconURLLarge( const char *szURL ) { m_sIconURLLarge = szURL; } protected: int m_iSkins[TEAM_VISUAL_SECTIONS]; int m_iViewmodelSkins[TEAM_VISUAL_SECTIONS]; const char *m_pszName; const char *m_pszBasePlayerModel; bool m_bIsSelectable; const char *m_pszInventoryImage; const char *m_pszBodygroupName; int m_iBodygroupSubmodelIndex; CUtlVector m_vecAdditionalHideBodygroups; private: CUtlString m_sIconURLSmall; CUtlString m_sIconURLLarge; }; struct perteamvisuals_t { perteamvisuals_t() { #if defined(CLIENT_DLL) || defined(GAME_DLL) iHideParentBodyGroup = -1; iSkin = -1; bUsePerClassBodygroups = false; pszMaterialOverride = NULL; pszMuzzleFlash = NULL; pszTracerEffect = NULL; pszParticleEffect = NULL; for ( int i = 0; i < MAX_VISUALS_CUSTOM_SOUNDS; i++ ) { pszCustomSounds[i] = NULL; } for ( int i = 0; i < NUM_SHOOT_SOUND_TYPES; i++ ) { pszWeaponSoundReplacements[i] = NULL; } m_iViewModelBodyGroupOverride = -1; m_iViewModelBodyGroupStateOverride = -1; m_iWorldModelBodyGroupOverride = -1; m_iWorldModelBodyGroupStateOverride = -1; #endif // defined(CLIENT_DLL) || defined(GAME_DLL) } ~perteamvisuals_t() { m_Styles.PurgeAndDeleteElements(); } #if defined(CLIENT_DLL) || defined(GAME_DLL) int iHideParentBodyGroup; // Properties necessary for the game client/server but not for the GC. perteamvisuals_maps_t m_Maps; int iSkin; bool bUsePerClassBodygroups; CUtlVector m_AttachedModels; CUtlVector m_AttachedModelsFestive; // Attr controlled Festive Attachments CUtlVector m_AttachedParticles; CUtlVector m_Animations; CUtlVector m_Activities; const char *pszCustomSounds[MAX_VISUALS_CUSTOM_SOUNDS]; const char *pszMaterialOverride; const char *pszMuzzleFlash; const char *pszTracerEffect; const char *pszParticleEffect; const char *pszWeaponSoundReplacements[NUM_SHOOT_SOUND_TYPES]; int m_iViewModelBodyGroupOverride; int m_iViewModelBodyGroupStateOverride; int m_iWorldModelBodyGroupOverride; int m_iWorldModelBodyGroupStateOverride; #endif // defined(CLIENT_DLL) || defined(GAME_DLL) // The GC does care about styles. CUtlVector m_Styles; }; enum item_capabilities_t { ITEM_CAP_NONE = 0, ITEM_CAP_PAINTABLE = 1 << 0, ITEM_CAP_NAMEABLE = 1 << 1, ITEM_CAP_DECODABLE = 1 << 2, ITEM_CAP_CAN_BE_CRAFTED_IF_PURCHASED = 1 << 3, // was ITEM_CAP_CAN_MOD_SOCKET ITEM_CAP_CAN_CUSTOMIZE_TEXTURE = 1 << 4, ITEM_CAP_USABLE = 1 << 5, ITEM_CAP_USABLE_GC = 1 << 6, ITEM_CAP_CAN_GIFT_WRAP = 1 << 7, ITEM_CAP_USABLE_OUT_OF_GAME = 1 << 8, ITEM_CAP_CAN_COLLECT = 1 << 9, ITEM_CAP_CAN_CRAFT_COUNT = 1 << 10, ITEM_CAP_CAN_CRAFT_MARK = 1 << 11, ITEM_CAP_PAINTABLE_TEAM_COLORS = 1 << 12, ITEM_CAP_CAN_BE_RESTORED = 1 << 13, // can users remove properties (paint, nametag, etc.) from this item via the in-game UI? ITEM_CAP_CAN_USE_STRANGE_PARTS = 1 << 14, ITEM_CAP_CAN_CARD_UPGRADE = 1 << 15, ITEM_CAP_CAN_STRANGIFY = 1 << 16, ITEM_CAP_CAN_KILLSTREAKIFY = 1 << 17, ITEM_CAP_CAN_CONSUME = 1 << 18, ITEM_CAP_CAN_SPELLBOOK_PAGE = 1 << 19, // IT'S A VERB OKAY ITEM_CAP_HAS_SLOTS = 1 << 20, ITEM_CAP_DUCK_UPGRADABLE = 1 << 21, ITEM_CAP_CAN_UNUSUALIFY = 1 << 22, NUM_ITEM_CAPS = 23, }; enum { ITEM_CAP_DEFAULT = ITEM_CAP_CAN_CRAFT_MARK | ITEM_CAP_CAN_BE_RESTORED | ITEM_CAP_CAN_USE_STRANGE_PARTS | ITEM_CAP_CAN_CARD_UPGRADE | ITEM_CAP_CAN_STRANGIFY | ITEM_CAP_CAN_KILLSTREAKIFY | ITEM_CAP_CAN_CONSUME | ITEM_CAP_CAN_GIFT_WRAP }; // what are the default capabilities on an item? enum { ITEM_CAP_TOOL_DEFAULT = ITEM_CAP_NONE }; // what are the default capabilities of a tool? struct bundleinfo_t { CUtlVector vecItemDefs; }; #ifdef GC_DLL enum EPaymentRuleType { kPaymentRule_SteamWorkshopFileID = 0x01, kPaymentRule_PartnerSteamID = 0x02, kPaymentRule_Bundle = 0x04, }; struct econ_item_payment_rule_t { double m_RevenueShare; EPaymentRuleType m_eRuleType; CCopyableUtlVector m_vecValues; }; #endif // GC_DLL #ifdef CLIENT_DLL namespace vgui { class Panel; } #endif // CLIENT_DLL class IEconTool { friend class CEconSharedToolSupport; public: IEconTool( const char *pszTypeName, const char *pszUseString, const char *pszUsageRestriction, item_capabilities_t unCapabilities ) : m_pszTypeName( pszTypeName ) , m_pszUseString( pszUseString ) , m_pszUsageRestriction( pszUsageRestriction ) , m_unCapabilities( unCapabilities ) { // } virtual ~IEconTool() { } // Shared code. const char *GetUsageRestriction() const { return m_pszUsageRestriction; } item_capabilities_t GetCapabilities() const { return m_unCapabilities; } virtual bool CanApplyTo( const IEconItemInterface *pTool, const IEconItemInterface *pToolSubject ) const { Assert( pTool ); Assert( pToolSubject ); return true; } virtual bool ShouldDisplayQuantity( const IEconItemInterface *pTool ) const; virtual bool RequiresToolEscrowPeriod() const { return false; } // We don't support throwing exceptions from tool construction so this is intended to be checked afterwards // whenever a new tool is created. (See CreateEconToolImpl().) virtual bool BFinishInitialization() { return true; } // Used by the GC only for WebAPI responses and for some weird internal code. const char *GetTypeName() const { return m_pszTypeName; } // would like to disable on the client so we aren't tempted to check against it, but used for building a unique tool list const char *GetUseString() const { return m_pszUseString; } #ifdef CLIENT_DLL virtual bool CanBeUsedNow( const IEconItemInterface *pItem ) const { return true; } virtual bool ShouldShowContainedItemPanel( const IEconItemInterface *pItem ) const { Assert( !"IEconTool::ShouldShowContainedItemPanel(): we don't expect this to be called on anything besides gifts!" ); return false; } virtual bool ShouldDisplayAsUseableOnItemsInArmory() const { return true; } virtual const char *GetUseCommandLocalizationToken( const IEconItemInterface *pItem, int i = 0 ) const; virtual int GetUseCommandCount( const IEconItemInterface *pItem ) const { return 1; } virtual const char* GetUseCommand( const IEconItemInterface *pItem, int i = 0 ) const; // Client "do something" interface. At least one of these functions must be implemented or your tool // won't do anything on the client. Some tools (ie., collections) will implement both because they // have one application behavior and one client-UI behavior. // When the client attempts to use a consumable item of any kind, this function will be called. This // is called from the UI in response to things like using dueling pistols, using a noisemaker, etc. // Usually this opens up some UI, sends off a GC message, etc. // // There is a "default" implementation of this function in ClientConsumableTool_Generic() that can // be called if specific behavior isn't needed. virtual void OnClientUseConsumable( class C_EconItemView *pItem, vgui::Panel *pParent ) const { Assert( !"IEconTool::OnClientUseConsumable(): unimplemented call!" ); } // When the client attempts to apply a tool to a specific other item in their inventory, this function // will be called. This is called from the UI is response to things like putting paint on an item, // using a key to unlock a crate, etc. virtual void OnClientApplyTool( class C_EconItemView *pTool, class C_EconItemView *pSubject, vgui::Panel *pParent ) const { Assert( !"IEconTool::OnClientApplyTool(): unimplemented call!" ); } #endif // CLIENT_DLL #ifdef GC_DLL virtual class CGCEconConsumableBehavior *CreateGCConsumableBehavior() const; virtual bool BGenerateDynamicAttributes( CEconItem* pItem, const CEconGameAccount *pGameAccount ) const { return true; } #endif // GC_DLL private: const char *m_pszTypeName; const char *m_pszUseString; const char *m_pszUsageRestriction; item_capabilities_t m_unCapabilities; }; //----------------------------------------------------------------------------- // CQuestObjectiveDefinition //----------------------------------------------------------------------------- class CQuestObjectiveDefinition { public: CQuestObjectiveDefinition( void ); virtual ~CQuestObjectiveDefinition( void ); virtual bool BInitFromKV( KeyValues *pKVItem, CUtlVector *pVecErrors = NULL ); uint32 GetDefinitionIndex( void ) const { return m_nDefIndex; } const char *GetDescriptionToken( void ) const { return m_pszDescriptionToken; } bool IsOptional() const { return m_bOptional; } bool IsAdvanced() const { return m_bAdvanced; } uint32 GetPoints() const { return m_nPoints; } // TODO: change to a float private: const char *m_pszDescriptionToken; uint32 m_nDefIndex; uint32 m_nPoints; bool m_bOptional; bool m_bAdvanced; }; //----------------------------------------------------------------------------- // CEconItemDefinition // Template Definition of a randomly created item //----------------------------------------------------------------------------- class CEconItemDefinition { public: CEconItemDefinition( void ); virtual ~CEconItemDefinition( void ); // BInitFromKV can be implemented on subclasses to parse additional values. virtual bool BInitFromKV( KeyValues *pKVItem, CUtlVector *pVecErrors = NULL ); #if defined(CLIENT_DLL) || defined(GAME_DLL) virtual bool BInitFromTestItemKVs( int iNewDefIndex, KeyValues *pKVItem, CUtlVector* pVecErrors = NULL ); virtual void GeneratePrecacheModelStrings( bool bDynamicLoad, CUtlVector *out_pVecModelStrings ) const; virtual void GeneratePrecacheSoundStrings( bool bDynamicLoad, CUtlVector *out_pVecSoundStrings ) const; virtual void CopyPolymorphic( const CEconItemDefinition *pSourceDef ) { *this = *pSourceDef; } #endif bool BInitItemMappings( CUtlVector *pVecErrors ); void BInitVisualBlockFromKV( KeyValues *pKVItem, CUtlVector *pVecErrors = NULL ); void BInitStylesBlockFromKV( KeyValues *pKVStyles, perteamvisuals_t *pVisData, CUtlVector *pVecErrors ); item_definition_index_t GetDefinitionIndex( void ) const { return m_nDefIndex; } bool BEnabled( void ) const { return m_bEnabled; } bool BLoadOnDemand( void ) const { return m_bLoadOnDemand; } bool BHasBeenLoaded( void ) const { return m_bHasBeenLoaded; } const char *GetDefinitionName( void ) const { return m_pszDefinitionName; } const char *GetItemDefinitionName( void ) const { return m_pszDefinitionName; } const char *GetItemClass( void ) const { return m_pszItemClassname; } const char *GetItemBaseName( void ) const { return m_pszItemBaseName; } const char *GetBrassModelOverride( void ) const{ return m_pszBrassModelOverride; } const char *GetItemTypeName( void ) const { return m_pszItemTypeName; } uint8 GetMinLevel( void ) const { return m_unMinItemLevel; } uint8 GetMaxLevel( void ) const { return m_unMaxItemLevel; } uint8 GetItemSeries( void ) const { return m_unItemSeries; } uint8 GetQuality( void ) const { return m_nItemQuality; } void SetRarity( uint8 nRarity ) { Assert( m_nItemRarity == k_unItemRarity_Any ); m_nItemRarity = nRarity; } uint8 GetRarity( void ) const { return m_nItemRarity; } uint8 GetForcedQuality( void ) const { return m_nForcedItemQuality; } uint16 GetDefaultDropQuantity( void ) const { return m_nDefaultDropQuantity; } KeyValues *GetRawDefinition( void ) const { return m_pKVItem; } const char *GetDefinitionString( const char *pszKeyName, const char *pszDefaultValue = "" ) const; KeyValues *GetDefinitionKey( const char *pszKeyName ) const; const CUtlVector &GetStaticAttributes( void ) const { return m_vecStaticAttributes; } #ifdef TF_CLIENT_DLL uint32 GetNumConcreteItems() const { return m_unNumConcreteItems; } #endif // TF_CLIENT_DLL // Data accessing bool IsHidden( void ) const { return m_bHidden; } bool IsImported( void ) const { return m_bImported; } bool IsAllowedInMatch( void ) const { return m_bAllowedInThisMatch; } bool IsBaseItem( void ) const { return m_bBaseItem; } bool IsBundle( void ) const { return m_BundleInfo != NULL; } bool HasProperName( void ) const { return m_bProperName; } const char *GetClassToken( void ) const { return m_pszClassToken; } const char *GetSlotToken( void ) const { return m_pszSlotToken; } bool ShouldAttachToHands( void ) const { return m_bAttachToHands; } bool ShouldAttachToHandsVMOnly( void ) const { return m_bAttachToHandsVMOnly; } bool ShouldFlipViewmodels( void ) const { return m_bFlipViewModel; } int GetInventoryImagePosition( int iIndex ) const { Assert( iIndex >= 0 && iIndex < 2); return m_iInventoryImagePosition[iIndex]; } int GetInventoryImageSize( int iIndex ) const { Assert( iIndex >= 0 && iIndex < 2); return m_iInventoryImageSize[iIndex]; } int GetDropType( void ) const { return m_iDropType; } const char *GetHolidayRestriction( void ) const { return m_pszHolidayRestriction; } int GetVisionFilterFlags( void ) const { return m_nVisionFilterFlags; } int GetSubType( void ) const { return m_iSubType; } item_capabilities_t GetCapabilities( void ) const { return m_iCapabilities; } int GetArmoryRemap( void ) const { return m_iArmoryRemap; } int GetStoreRemap( void ) const { return m_iStoreRemap; } item_definition_index_t GetSetItemRemap() const { return m_unSetItemRemapDefIndex; } // what def index do we consider ourself for purposes of determining "is an item equipped that satisfies this set slot?" (ie., Festive Huntsman -> Huntsman); default is to point to itself const char *GetXifierRemapClass() const { return m_pszXifierRemapClass; } const char *GetBaseFunctionalItemName() const { return m_pszBaseFunctionalItemName; } const char *GetParticleSuffix() const { return m_pszParticleSuffix; } const CEconItemSetDefinition *GetItemSetDefinition( void ) const { return m_pItemSetDef; } void SetItemSetDefinition( const CEconItemSetDefinition *pItemSetDef ) { Assert( !m_pItemSetDef ); m_pItemSetDef = pItemSetDef; } const CEconItemCollectionDefinition *GetItemCollectionDefinition( void ) const { return m_pItemCollectionDef; } void SetItemCollectionDefinition( const CEconItemCollectionDefinition *pItemCollectionDef ) { Assert( !m_pItemCollectionDef ); m_pItemCollectionDef = pItemCollectionDef; } CEconItemPaintKitDefinition *GetCustomPainkKitDefinition( void ) const { return m_pItemPaintKitDef; } void SetItemPaintKitDefinition( CEconItemPaintKitDefinition *pItemPaintKitDef ) { Assert( !m_pItemPaintKitDef ); m_pItemPaintKitDef = pItemPaintKitDef; } perteamvisuals_t *GetPerTeamVisual( int iTeam ) const { return m_PerTeamVisuals[iTeam]; } bool IsTool() const { return m_bIsTool; } const IEconTool *GetEconTool() const { return m_pTool; } template < class T > const T *GetTypedEconTool() const { return dynamic_cast( GetEconTool() ); } const bundleinfo_t *GetBundleInfo( void ) const { return m_BundleInfo; } virtual int GetBundleItemCount( void ) const { return m_BundleInfo ? m_BundleInfo->vecItemDefs.Count() : 0; } virtual int GetBundleItem( int iIndex ) const { return m_BundleInfo ? m_BundleInfo->vecItemDefs[iIndex]->GetDefinitionIndex() : -1; } // Is this item contained in any bundles? GetContainingBundles() gets the CEconItemDefinitions for those bundles. const CUtlVector< const CEconItemDefinition * > &GetContainingBundles() const { return m_vecContainingBundleItemDefs; } uint32 GetContainingBundleCount() const { return m_vecContainingBundleItemDefs.Count(); } void AddSteamWorkshopContributor( uint32 unAccountID ) { if ( m_vecSteamWorkshopContributors.InvalidIndex() == m_vecSteamWorkshopContributors.Find( unAccountID ) ) { m_vecSteamWorkshopContributors.AddToTail( unAccountID ); } } const CUtlVector< uint32 > &GetSteamWorkshopContributors() const { return m_vecSteamWorkshopContributors; } bool BIsSteamWorkshopItem() const { return m_vecSteamWorkshopContributors.Count() > 0; } const char *GetIconClassname( void ) const { return m_pszItemIconClassname; } const char *GetLogClassname( void ) const { return m_pszItemLogClassname; } const char *GetInventoryModel( void ) const { return m_pszInventoryModel; } const char *GetInventoryImage( void ) const { return m_pszInventoryImage; } const char *GetInventoryOverlayImage( int idx ) const { if ( m_pszInventoryOverlayImages.IsValidIndex( idx ) ) return m_pszInventoryOverlayImages[idx]; else return NULL; } int GetInventoryOverlayImageCount( void ) const { return m_pszInventoryOverlayImages.Count(); } int GetInspectPanelDistance( void ) const { return m_iInspectPanelDistance; } const char *GetIconURLSmall() const { return GetIconURL( "s" ); } // Plain small const char *GetIconURLLarge() const { return GetIconURL( "l" ); } // Plain large void SetIconURL( const char* pszKey, const char *szURL ) { m_pDictIcons->Insert( pszKey, CUtlString( szURL ) ); } const char *GetIconURL( const char* pszKey ) const; const char *GetBasePlayerDisplayModel() const { return m_pszBaseDisplayModel; } int GetDefaultSkin() const { return m_iDefaultSkin; } const char *GetWorldDisplayModel() const { return m_pszWorldDisplayModel; } const char *GetCollectionReference() const { return m_pszCollectionReference; } // Some weapons need a custom model for icon generation. If this value is not present, the world model is used. virtual const char *GetIconDisplayModel() const; const char *GetExtraWearableModel( void ) const { return m_pszWorldExtraWearableModel; } const char *GetExtraWearableViewModel( void ) const { return m_pszWorldExtraWearableViewModel; } const char *GetVisionFilteredDisplayModel() const { return m_pszVisionFilteredDisplayModel; } const char *GetItemDesc( void ) const { return m_pszItemDesc; } const char *GetArmoryDescString( void ) const { return m_pszArmoryDesc; } RTime32 GetExpirationDate( void ) const { return m_rtExpiration; } bool ShouldShowInArmory( void ) const { return m_bShouldShowInArmory; } bool IsActingAsAWearable( void ) const { return m_bActAsWearable; } bool IsActingAsAWeapon( void ) const { return m_bActAsWeapon; } bool GetHideBodyGroupsDeployedOnly( void ) const { return m_bHideBodyGroupsDeployedOnly; } bool IsPackBundle( void ) const { return m_bIsPackBundle; } bool IsPackItem( void ) const { return m_bIsPackItem; } CEconItemDefinition *GetOwningPackBundle() { return m_pOwningPackBundle; } const CEconItemDefinition *GetOwningPackBundle() const { return m_pOwningPackBundle; } const char *GetDatabaseAuditTableName( void ) const { return m_pszDatabaseAuditTable; } void SetIsPackItem( bool bIsPackItem ) { m_bIsPackItem = bIsPackItem; } equip_region_mask_t GetEquipRegionMask( void ) const { return m_unEquipRegionMask; } equip_region_mask_t GetEquipRegionConflictMask( void ) const { return m_unEquipRegionConflictMask; } // Dynamic modification during gameplay void SetAllowedInMatch( bool bAllowed ) { m_bAllowedInThisMatch = bAllowed; } void SetHasBeenLoaded( bool bLoaded ) { m_bHasBeenLoaded = bLoaded; } // Generate and return a random level according to whatever leveling curve this definition uses. uint32 RollItemLevel( void ) const; const char *GetFirstSaleDate( void ) const; void IterateAttributes( class IEconItemAttributeIterator *pIterator ) const; #if defined(CLIENT_DLL) || defined(GAME_DLL) // Visuals // Attached models int GetNumAttachedModels( int iTeam ) const; attachedmodel_t *GetAttachedModelData( int iTeam, int iIdx ) const; int GetNumAttachedModelsFestivized( int iTeam ) const; attachedmodel_t *GetAttachedModelDataFestivized( int iTeam, int iIdx ) const; // Attached particle systems int GetNumAttachedParticles( int iTeam ) const; attachedparticlesystem_t *GetAttachedParticleData( int iTeam, int iIdx ) const; // Activities int GetNumPlaybackActivities( int iTeam ) const; activity_on_wearable_t *GetPlaybackActivityData( int iTeam, int iIdx ) const; // Animations int GetNumAnimations( int iTeam ) const; animation_on_wearable_t *GetAnimationData( int iTeam, int iIdx ) const; // Animation Overrides Activity GetActivityOverride( int iTeam, Activity baseAct ) const; const char *GetActivityOverride( int iTeam, const char *pszActivity ) const; const char *GetReplacementForActivityOverride( int iTeam, Activity baseAct ) const; // Should the content (meshes, etc.) for this be streamed or preloaded? virtual bool IsContentStreamable() const; #endif // defined(CLIENT_DLL) || defined(GAME_DLL) // FX Overrides const char *GetMuzzleFlash( int iTeam ) const; const char *GetTracerEffect( int iTeam ) const; const char *GetParticleEffect( int iTeam ) const; // Materials const char *GetMaterialOverride( int iTeam ) const; // Sounds const char *GetCustomSound( int iTeam, int iSound ) const; const char *GetWeaponReplacementSound( int iTeam, /*WeaponSound_t*/ int iSound ) const; // Bodygroups int GetHiddenParentBodygroup( int iTeam ) const; int GetNumModifiedBodyGroups( int iTeam ) const; const char* GetModifiedBodyGroup( int iTeam, int i, int& body ) const; bool UsesPerClassBodygroups( int iTeam ) const; int GetNumCodeControlledBodyGroups( int iTeam ) const; const char* GetCodeControlledBodyGroup( int iIteam, int i, struct codecontrolledbodygroupdata_t &ccbgd ) const; style_index_t GetNumStyles() const; style_index_t GetNumSelectableStyles() const; const CEconStyleInfo *GetStyleInfo( style_index_t unStyle ) const; int GetViewmodelBodygroupOverride( int iTeam ) const; int GetViewmodelBodygroupStateOverride( int iTeam ) const; int GetWorldmodelBodygroupOverride( int iTeam ) const; int GetWorldmodelBodygroupStateOverride( int iTeam ) const; int GetPopularitySeed() const { return m_nPopularitySeed; } bool HasEconTag( econ_tag_handle_t tag ) const { return m_vecTags.IsValidIndex( m_vecTags.Find( tag ) ); } bool BValidForShuffle( void ) const { return m_bValidForShuffle; } bool BValidForSelfMade( void ) const { return m_bValidForSelfMade; } #ifdef GC_DLL private: MUST_CHECK_RETURN bool BInitializeEconItemGenerators( KeyValues *pKV, CUtlVector *pVecErrors ); public: // If this returns true, all relevant property generators were applied to the item instance // passed in. If this returns false, some or none of the generators may have been applied, // but there are no guarantees about the item state. MUST_CHECK_RETURN bool BApplyPropertyGenerators( CEconItem *pItem ) const; const CUtlVector& GetEconTags() const { return m_vecTags; } // meant for internal/debug use only, not for runtime iteration const CUtlVector& GetPaymentRules() const { return m_vecPaymentRules; } private: int AddPaymentRule( const econ_item_payment_rule_t& newRule ); // returns which payment rule number was just created public: #endif // GC_DLL #if defined(CLIENT_DLL) || defined(GAME_DLL) int GetStyleSkin( style_index_t unStyle, int iTeam, bool bViewmodel ) const; const char* GetStyleInventoryImage( style_index_t unStyle ) const; int GetBestVisualTeamData( int iTeam ) const; #endif // defined(CLIENT_DLL) || defined(GAME_DLL) #ifdef DBGFLAG_VALIDATE void Validate( CValidator &validator, const char *pchName ) { VALIDATE_SCOPE(); ValidateObj( m_vecStaticAttributes ); ValidatePtr( m_pKVItem ); ValidatePtr( m_pProxyCriteria ); } #endif // DBGFLAG_VALIDATE private: // Pointer to the raw KeyValue definition of the item KeyValues * m_pKVItem; // Required values from m_pKVItem: // The number used to refer to this definition in the DB item_definition_index_t m_nDefIndex; // False if this definition has been turned off and we're not using it to generate items bool m_bEnabled; // These values specify the range of item levels that an item based off this definition can be generated within. uint8 m_unMinItemLevel; uint8 m_unMaxItemLevel; // This specifies an item quality that items from this definition must be set to. Used mostly to specify unique item definitions. uint8 m_nItemQuality; uint8 m_nForcedItemQuality; uint8 m_nItemRarity; // Default drop quantity uint16 m_nDefaultDropQuantity; // Item Series uint8 m_unItemSeries; // Static attributes (ones that are always on these items) CUtlVector m_vecStaticAttributes; // Seeds the popular item list with this number of the item when the list is reset. uint8 m_nPopularitySeed; // --------------------------------------------- // Display related data // --------------------------------------------- // The base name of this item. i.e. "The Kritz-Krieg". const char *m_pszItemBaseName; bool m_bProperName; // If set, the name will have "The" prepended to it, unless it's got a non-unique quality // in which case it'll have "A" prepended to the quality. i.e. A Community Kritzkrieg // The base type of this item. i.e. "Rocket Launcher" or "Shotgun". // This is often the same as the base name, but not always. const char *m_pszItemTypeName; // The item's non-attribute description. const char *m_pszItemDesc; // expiration time RTime32 m_rtExpiration; // The .mdl file used for this item when it's displayed in inventory-style boxes. const char *m_pszInventoryModel; // Alternatively, the image used for this item when it's displayed in inventory-style boxes. If specified, it's used over the model. const char *m_pszInventoryImage; // An optional image that's overlayed over the top of the base inventory image. It'll be RGB colored by the tint color of the item. CUtlVector m_pszInventoryOverlayImages; int m_iInventoryImagePosition[2]; int m_iInventoryImageSize[2]; int m_iInspectPanelDistance; const char *m_pszBaseDisplayModel; int m_iDefaultSkin; bool m_bLoadOnDemand; bool m_bHasBeenLoaded; bool m_bHideBodyGroupsDeployedOnly; // The .mdl file used for the world view. // This is inferior to using a c_model, but because the geometry of the sticky bomb launcher's // world model is significantly different from the view model the demoman pack requires // using two separate models for now. const char *m_pszWorldDisplayModel; const char *m_pszWorldExtraWearableModel; // Some weapons attach an extra wearable item to the player const char *m_pszWorldExtraWearableViewModel; // Some weapons attach an extra wearable view model item to the player const char *m_pszVisionFilteredDisplayModel; // Some weapons display differently depending on the viewer's filters const char *m_pszCollectionReference; // Reference a colletion // If set, we use the base hands model for a viewmodel, and bonemerge the above player model bool m_bAttachToHands; bool m_bAttachToHandsVMOnly; // If set, we will force the view model to render flipped. Good for models built left handed. bool m_bFlipViewModel; // This is a wearable that sits in a non-wearable loadout slot bool m_bActAsWearable; // This is a weapon that sits in a wearable slot (Action) bool m_bActAsWeapon; // Is this Item a tool bool m_bIsTool; // The set this item is a member of const CEconItemSetDefinition *m_pItemSetDef; const CEconItemCollectionDefinition *m_pItemCollectionDef; CEconItemPaintKitDefinition *m_pItemPaintKitDef; // A list of per-team visual data used to modify base model for visual recognition perteamvisuals_t *m_PerTeamVisuals[TEAM_VISUAL_SECTIONS]; // Optional override for specifying a custom shell ejection model const char *m_pszBrassModelOverride; IEconTool *m_pTool; bundleinfo_t *m_BundleInfo; item_capabilities_t m_iCapabilities; #ifdef TF_CLIENT_DLL uint32 m_unNumConcreteItems; // This is the number of items that will actually end up in a user's inventory - this can be 0 for some items (e.g. map stamps in TF), 1 for a "regular" item, or many for bundles, etc. #endif // TF_CLIENT_DLL CUtlDict< CUtlString >* m_pDictIcons; // --------------------------------------------- // Creation related data // --------------------------------------------- // The entity classname for this item. const char *m_pszItemClassname; // The entity name that will be displayed in log files. const char *m_pszItemLogClassname; // The name of the icon used in the death notices. const char *m_pszItemIconClassname; // This is the script file name of this definition. Used to generate items by script name. const char *m_pszDefinitionName; // This is used for auditing purposes const char *m_pszDatabaseAuditTable; bool m_bHidden; bool m_bShouldShowInArmory; bool m_bBaseItem; bool m_bImported; // A pack bundle is a bundle that contains items that are not for sale individually bool m_bIsPackBundle; // A pack item is an item which is not for sale individually and is only for sale as part of a pack bundle. A 'regular' bundle can only include a pack bundle by explicitly including all of the pack bundle's items individually. // If this pointer is non-NULL, this item is considered to be a pack item (see CEconItemDefinition::IsPackItem()). CEconItemDefinition *m_pOwningPackBundle; bool m_bIsPackItem; // Contains information on how to describe items with this attribute in the Armory const char *m_pszArmoryDesc; // Temporary(?) solution to allow xifiers to work on botkiller and festive variants of weapons const char *m_pszXifierRemapClass; // Base item name -- used for grouping weapon functionality const char *m_pszBaseFunctionalItemName; // For particle effects that have derivatives, what is the suffix for this item const char *m_pszParticleSuffix; // --------------------------------------------- // Remapping data for armory/store // --------------------------------------------- int m_iArmoryRemap; int m_iStoreRemap; const char *m_pszArmoryRemap; const char *m_pszStoreRemap; // --------------------------------------------- // Crafting related data // --------------------------------------------- const char *m_pszClassToken; const char *m_pszSlotToken; // --------------------------------------------- // Gameplay related data // --------------------------------------------- // How to behave when the player wearing the item dies. int m_iDropType; // Holiday restriction. Item only has an appearance when the holiday is in effect. const char *m_pszHolidayRestriction; // Meet the pyro makes some items invisible unless you're wearing Pyro Goggles int m_nVisionFilterFlags; // Temporary. Revisit this in the engineer update. Enables an additional buildable. int m_iSubType; // Whitelist support for tournament mode bool m_bAllowedInThisMatch; equip_region_mask_t m_unEquipRegionMask; // which equip regions does this item cover directly equip_region_mask_t m_unEquipRegionConflictMask; // which equip regions does equipping this item prevent from having something in them item_definition_index_t m_unSetItemRemapDefIndex; // reference to the definition index we want to consider this item for set matching purposes; see GetSetItemRemap() #ifdef GC_DLL CUtlVector m_vecPropertyGenerators; CUtlVector m_vecPaymentRules; #endif // GC_DLL // False if this definition is not allowed to be part of a shuffled crate's contents bool m_bValidForShuffle; // False if this definition should not grant self-made items bool m_bValidForSelfMade; protected: // Protected to allow subclasses to add/remove game-specific tags. CUtlVector m_vecTags; CUtlVector m_vecContainingBundleItemDefs; // Item definition indices for any bundles which contain this item CUtlVector m_vecSteamWorkshopContributors; friend class CEconItemSchema; }; //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline style_index_t CEconItemDefinition::GetNumStyles() const { const perteamvisuals_t *pVisData = GetPerTeamVisual( 0 ); if ( !pVisData ) return 0; // Bad things will happen if we ever get more styles than will fit in our // style index type. Not Very Bad things, but bad things. Mostly we'll fail // to iterate over all our styles. return pVisData->m_Styles.Count(); } //----------------------------------------------------------------------------- // Purpose: Similar to GetNumStyles, but only the selectable styles //----------------------------------------------------------------------------- inline style_index_t CEconItemDefinition::GetNumSelectableStyles() const { const perteamvisuals_t *pVisData = GetPerTeamVisual(0); if (!pVisData) return 0; style_index_t nCount = 0; FOR_EACH_VEC( pVisData->m_Styles, i ) { if( pVisData->m_Styles[i]->IsSelectable() ) { ++nCount; } } return nCount; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline const CEconStyleInfo *CEconItemDefinition::GetStyleInfo( style_index_t unStyle ) const { const perteamvisuals_t *pBaseVisuals = GetPerTeamVisual( 0 ); if ( !pBaseVisuals || !pBaseVisuals->m_Styles.IsValidIndex( unStyle ) ) return NULL; return pBaseVisuals->m_Styles[unStyle]; } #if defined(CLIENT_DLL) || defined(GAME_DLL) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetNumAttachedModels( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return 0; return GetPerTeamVisual(iTeam)->m_AttachedModels.Count(); #else return 0; #endif } //----------------------------------------------------------------------------- inline attachedmodel_t *CEconItemDefinition::GetAttachedModelData( int iTeam, int iIdx ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); perteamvisuals_t *pVisuals = GetPerTeamVisual(iTeam); Assert( pVisuals ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !pVisuals ) return NULL; Assert( iIdx < pVisuals->m_AttachedModels.Count() ); if ( iIdx >= pVisuals->m_AttachedModels.Count() ) return NULL; return &pVisuals->m_AttachedModels[iIdx]; #else return NULL; #endif } //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetNumAttachedModelsFestivized( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); perteamvisuals_t *pVisuals = GetPerTeamVisual(iTeam); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !pVisuals ) return 0; return pVisuals->m_AttachedModelsFestive.Count(); #else return 0; #endif } //----------------------------------------------------------------------------- inline attachedmodel_t *CEconItemDefinition::GetAttachedModelDataFestivized( int iTeam, int iIdx ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); perteamvisuals_t *pVisuals = GetPerTeamVisual(iTeam); Assert( pVisuals ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !pVisuals ) return NULL; Assert( iIdx < pVisuals->m_AttachedModelsFestive.Count() ); if ( iIdx >= pVisuals->m_AttachedModelsFestive.Count() ) return NULL; return &pVisuals->m_AttachedModelsFestive[iIdx]; #else return NULL; #endif } //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetNumPlaybackActivities( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return 0; return GetPerTeamVisual(iTeam)->m_Activities.Count(); #else return 0; #endif } inline activity_on_wearable_t *CEconItemDefinition::GetPlaybackActivityData( int iTeam, int iIdx ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); Assert( GetPerTeamVisual(iTeam) ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; Assert( iIdx < GetPerTeamVisual(iTeam)->m_Activities.Count() ); if ( iIdx >= GetPerTeamVisual(iTeam)->m_Activities.Count() ) return NULL; return &GetPerTeamVisual(iTeam)->m_Activities[iIdx]; #else return NULL; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetNumAnimations( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return 0; return GetPerTeamVisual(iTeam)->m_Animations.Count(); #else return 0; #endif } inline animation_on_wearable_t *CEconItemDefinition::GetAnimationData( int iTeam, int iIdx ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); Assert( GetPerTeamVisual(iTeam) ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; Assert( iIdx < GetPerTeamVisual(iTeam)->m_Animations.Count() ); if ( iIdx >= GetPerTeamVisual(iTeam)->m_Animations.Count() ) return NULL; return &GetPerTeamVisual(iTeam)->m_Animations[iIdx]; #else return NULL; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetNumAttachedParticles( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return 0; return GetPerTeamVisual(iTeam)->m_AttachedParticles.Count(); #else return 0; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline attachedparticlesystem_t *CEconItemDefinition::GetAttachedParticleData( int iTeam, int iIdx ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); Assert( GetPerTeamVisual(iTeam) ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; Assert( iIdx < GetPerTeamVisual(iTeam)->m_AttachedParticles.Count() ); if ( iIdx >= GetPerTeamVisual(iTeam)->m_AttachedParticles.Count() ) return NULL; return &GetPerTeamVisual(iTeam)->m_AttachedParticles[iIdx]; #else return NULL; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline const char *CEconItemDefinition::GetMaterialOverride( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; return GetPerTeamVisual(iTeam)->pszMaterialOverride; #else return NULL; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline const char *CEconItemDefinition::GetMuzzleFlash( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; return GetPerTeamVisual(iTeam)->pszMuzzleFlash; #else return NULL; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline const char *CEconItemDefinition::GetTracerEffect( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; return GetPerTeamVisual(iTeam)->pszTracerEffect; #else return NULL; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline const char *CEconItemDefinition::GetParticleEffect( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; return GetPerTeamVisual(iTeam)->pszParticleEffect; #else return NULL; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetHiddenParentBodygroup( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return -1; return GetPerTeamVisual(iTeam)->iHideParentBodyGroup; #else return -1; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetNumModifiedBodyGroups( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return -1; return GetPerTeamVisual(iTeam)->m_Maps.m_ModifiedBodyGroupNames.Count(); #else return -1; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline const char* CEconItemDefinition::GetModifiedBodyGroup( int iTeam, int i, int& body ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; body = GetPerTeamVisual(iTeam)->m_Maps.m_ModifiedBodyGroupNames[i]; return GetPerTeamVisual(iTeam)->m_Maps.m_ModifiedBodyGroupNames.Key(i); #else return NULL; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetNumCodeControlledBodyGroups( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return -1; return GetPerTeamVisual(iTeam)->m_Maps.m_CodeControlledBodyGroupNames.Count(); #else return -1; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline const char* CEconItemDefinition::GetCodeControlledBodyGroup( int iTeam, int i, codecontrolledbodygroupdata_t &ccbgd ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; ccbgd = GetPerTeamVisual(iTeam)->m_Maps.m_CodeControlledBodyGroupNames[i]; return GetPerTeamVisual(iTeam)->m_Maps.m_CodeControlledBodyGroupNames.Key(i); #else return NULL; #endif } #if defined(CLIENT_DLL) || defined(GAME_DLL) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetStyleSkin( style_index_t unStyle, int iTeam, bool bViewmodel ) const { const CEconStyleInfo *pStyle = GetStyleInfo( unStyle ); // Return our skin if we have a style or our default skin of -1 otherwise. return pStyle ? pStyle->GetSkin( iTeam, bViewmodel ) : GetDefaultSkin(); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline const char* CEconItemDefinition::GetStyleInventoryImage( style_index_t unStyle ) const { const CEconStyleInfo *pStyle = GetStyleInfo( unStyle ); return pStyle ? pStyle->GetInventoryImage() : NULL; } #endif // defined(CLIENT_DLL) || defined(GAME_DLL) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetViewmodelBodygroupOverride( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return 0; return GetPerTeamVisual(iTeam)->m_iViewModelBodyGroupOverride; #else return 0; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetViewmodelBodygroupStateOverride( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return 0; return GetPerTeamVisual(iTeam)->m_iViewModelBodyGroupStateOverride; #else return 0; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetWorldmodelBodygroupOverride( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return 0; return GetPerTeamVisual(iTeam)->m_iWorldModelBodyGroupOverride; #else return 0; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetWorldmodelBodygroupStateOverride( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return 0; return GetPerTeamVisual(iTeam)->m_iWorldModelBodyGroupStateOverride; #else return 0; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline bool CEconItemDefinition::UsesPerClassBodygroups( int iTeam ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return false; return GetPerTeamVisual(iTeam)->bUsePerClassBodygroups; #else return false; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline const char *CEconItemDefinition::GetCustomSound( int iTeam, int iSound ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; if ( iSound < 0 || iSound >= MAX_VISUALS_CUSTOM_SOUNDS ) return NULL; return GetPerTeamVisual(iTeam)->pszCustomSounds[iSound]; #else return NULL; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline const char *CEconItemDefinition::GetWeaponReplacementSound( int iTeam, /* WeaponSound_t */ int iSound ) const { #ifndef CSTRIKE_DLL iTeam = GetBestVisualTeamData( iTeam ); if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS || !GetPerTeamVisual(iTeam) ) return NULL; if ( iSound < 0 || iSound >= NUM_SHOOT_SOUND_TYPES ) return NULL; return GetPerTeamVisual(iTeam)->pszWeaponSoundReplacements[iSound]; #else return NULL; #endif } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- inline int CEconItemDefinition::GetBestVisualTeamData( int iTeam ) const { #ifndef CSTRIKE_DLL Assert( iTeam >= 0 && iTeam < TEAM_VISUAL_SECTIONS ); // If we don't have data for the specified team, try to fall back to the base // if ( !GetStaticData() ) // return 0; if ( (iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS) || (iTeam > 0 && !GetPerTeamVisual(iTeam)) ) return 0; return iTeam; #else return 0; #endif } #endif // defined(CLIENT_DLL) || defined(GAME_DLL) //----------------------------------------------------------------------------- // CTimedItemRewardDefinition // Describes a periodic item reward //----------------------------------------------------------------------------- class CTimedItemRewardDefinition { public: CTimedItemRewardDefinition( void ); CTimedItemRewardDefinition( const CTimedItemRewardDefinition &that ); CTimedItemRewardDefinition &operator=( const CTimedItemRewardDefinition& rhs ); ~CTimedItemRewardDefinition( void ) { } bool BInitFromKV( KeyValues *pKVTimedReward, CUtlVector *pVecErrors = NULL ); uint32 GetRandomFrequency( void ) const { return RandomFloat( m_unMinFreq, m_unMaxFreq ); } uint32 GetMinFrequency( void ) const { return m_unMinFreq; } uint32 GetMaxFrequency( void ) const { return m_unMaxFreq; } float GetChance( void ) const { return m_flChance; } const CItemSelectionCriteria &GetCriteria( void ) const { return m_criteria; } const CEconLootListDefinition *GetLootList( void ) const { return m_pLootList; } bool BHasRequiredItem() const { return m_iRequiredItemDef != INVALID_ITEM_DEF_INDEX; } item_definition_index_t GetRequiredItem() const { return m_iRequiredItemDef; } #ifdef DBGFLAG_VALIDATE void Validate( CValidator &validator, const char *pchName ) { VALIDATE_SCOPE(); ValidateObj( m_criteria ); } #endif // DBGFLAG_VALIDATE private: // Frequency of how often the item is awarded uint32 m_unMinFreq; uint32 m_unMaxFreq; // The chance, between 0 and 1, that the item is rewarded float m_flChance; // The criteria to use to select the item to reward CItemSelectionCriteria m_criteria; // Alternatively, the loot_list to use instead const CEconLootListDefinition *m_pLootList; item_definition_index_t m_iRequiredItemDef; }; #ifdef GC_DLL //----------------------------------------------------------------------------- // CExperimentDefinition //----------------------------------------------------------------------------- struct experiment_group_t { const char* m_pName; uint32 m_unNumParticipants; uint32 m_unMaxParticipants; KeyValues *m_pKeyValues; }; class CExperimentDefinition { public: CExperimentDefinition( void ); ~CExperimentDefinition( void ); bool BInitFromKV( KeyValues *pKVExperiment, CUtlVector *pVecErrors = NULL ); CUtlVector< experiment_group_t > &GetGroups() { return m_vecGroups; } uint32 GetID() const { return m_unExperimentID; } const char *GetName( void ) const { return m_pKeyValues->GetString( "name", "unknown" ); } const char *GetDescription( void ) const { return m_pKeyValues->GetString( "description", "unknown" ); } bool IsEnabled() const { return m_bEnabled; } bool IsFull() const { return m_unNumParticipants >= m_unMaxParticipants; } uint32 GetNumParticipants() const { return m_unNumParticipants; } void SetNumParticipants( uint32 unNumParticipants ) { m_unNumParticipants = unNumParticipants; } uint32 GetMaxParticipants() const { return m_unMaxParticipants; } bool ChooseGroup( uint32 &unGroup ); private: bool m_bEnabled; uint32 m_unExperimentID; uint32 m_unNumParticipants; uint32 m_unMaxParticipants; KeyValues *m_pKeyValues; CUtlVector< experiment_group_t > m_vecGroups; }; #endif //----------------------------------------------------------------------------- // CItemLevelingDefinition //----------------------------------------------------------------------------- class CItemLevelingDefinition { public: CItemLevelingDefinition( void ); CItemLevelingDefinition( const CItemLevelingDefinition &that ); CItemLevelingDefinition &operator=( const CItemLevelingDefinition& rhs ); ~CItemLevelingDefinition( void ); bool BInitFromKV( KeyValues *pKVItemLevel, const char *pszLevelBlockName, CUtlVector *pVecErrors = NULL ); uint32 GetLevel( void ) const { return m_unLevel; } uint32 GetRequiredScore( void ) const { return m_unRequiredScore; } const char *GetNameLocalizationKey( void ) const { return m_pszLocalizedName_LocalStorage; } private: uint32 m_unLevel; uint32 m_unRequiredScore; char *m_pszLocalizedName_LocalStorage; }; //----------------------------------------------------------------------------- // AchievementAward_t // Holds the item to give away and the Data value to audit it with ( for cross // game achievements) //----------------------------------------------------------------------------- struct AchievementAward_t { AchievementAward_t( const AchievementAward_t & rhs ) : m_sNativeName( rhs.m_sNativeName ), m_unSourceAppId( rhs.m_unSourceAppId ), m_unAuditData( rhs.m_unAuditData ) { m_vecDefIndex.CopyArray( rhs.m_vecDefIndex.Base(), rhs.m_vecDefIndex.Count() ); } AchievementAward_t( ) {} CUtlString m_sNativeName; AppId_t m_unSourceAppId; uint32 m_unAuditData; CUtlVector m_vecDefIndex; }; enum eTimedRewardType { kTimedRewards_RegularDrop, kTimedRewards_SupplyCrate, kTimedRewards_FreeTrialDrop, kTimedRewards_RecipeDrop, kTimedRewards_EventDrop02, kNumTimedRewards }; struct kill_eater_score_type_t { const char *m_pszTypeString; const char *m_pszLevelBlockName; bool m_bAllowBotVictims; // if true, we don't check for a valid Steam ID on the client before sending or a valid session on the GC before incrementing #ifdef GC_DLL bool m_bGCUpdateOnly; bool m_AllowIncrementValues; // if true, clients are allowed to send up the amount to increment by (ie., "did 100 damage") rather than implicitly assuming a value of 1 bool m_bIsBaseKillType; // if true, when clients send up a notification of this type we'll also look for other relevant things on the GC, like whether the victim was a friend, etc. #endif }; // Index-to-string table, currently used for attribute value string lookups. struct schema_string_table_entry_t { int m_iIndex; const char *m_pszStr; }; //----------------------------------------------------------------------------- // CForeignAppImports // Defines the way a single foreign app's items are mapped into this app //----------------------------------------------------------------------------- class CForeignAppImports { public: CForeignAppImports() : m_mapDefinitions( DefLessFunc( uint16 ) ) {} void AddMapping( uint16 unForeignDefIndex, const CEconItemDefinition *pDefn ); const CEconItemDefinition *FindMapping( uint16 unForeignDefIndex ) const; private: CUtlMap< uint16, const CEconItemDefinition *> m_mapDefinitions; }; //----------------------------------------------------------------------------- // ISchemaAttributeType //----------------------------------------------------------------------------- #ifdef GC_DLL namespace GCSDK { class CColumnSet; class CRecordBase; class CWebAPIValues; }; #endif // GC_DLL // ISchemaAttributeType is the base interface for a "type" of attribute, where "type" is defined as // "something that describes the memory layout, the DB layout, how to convert between them, etc.". // Most of the low-level work done with attributes, including DB reading/writing, packing/unpacking // for wire traffic, and other leaf code works exclusively through this interface. // // The class hierarchy looks like: // // ISchemaAttributeTypeBase< TAttribInMemoryType >: // // This describes a specific in-memory format for an attribute, without any association to // a particular DB, wire format, etc. We can't template the base class because it's an // interface. This implements about half of ISchemaAttributeType and has its own mini // interface consisting of ConvertTypedValueToByteStream() and ConvertByteStreamToTypedValue(), // both of which do work on statically-typed values that don't exist at higher levels. // // CSchemaAttributeTypeBase< TAttribSchType, TAttribInMemoryType >: // // This handles the schema-related functions on ISchemaAttributeType. These exist at a lower // inheritance level than ISchemaAttributeTypeBase to allow code that needs to work type-safely // on attributes in memory, but that doesn't know or need to know anything about databases, // to exist. Examples of this include code that calls CEconItem::SetDynamicAttributeValue(). // // Individual implementations of custom attribute type start making sense immediately as // subclasses of CSchemaAttributeTypeBase, for example CSchemaAttributeType_Default, which // implements all of the old, untyped attribute system logic. // // CSchemaAttributeTypeProtobufBase< TAttribSchType, TProtobufValueType > // // An easy way of automating most of the work for making a new attribute type is to have // the in-memory format be a protobuf object, allowing reflection, automatic network support, // etc. // // Creating a new custom protobuf attribute consists of three steps: // // - create a new DB table that will hold your attribute data. This needs an itemid_t-sized item ID // column named "ItemID", an attrib_definition_index_t-sized definition index column named "AttrDefIndex", // and then whatever data you want to store. // // - create a new protobuf message type that will hold your custom attribute contents. This exists // on the client and the GC in the same format. // // - implement a subclass of CSchemaAttributeTypeProtobufBase<>, for example: // // class CSchemaAttributeType_StrangeScore : public CSchemaAttributeTypeProtobufBase< GC_SCH_REFERENCE( CSchItemAttributeStrangeScore ) CAttribute_StrangeScore > // { // virtual void ConvertEconAttributeValueToSch( itemid_t unItemId, const CEconItemAttributeDefinition *pAttrDef, const union attribute_data_union_t& value, GCSDK::CRecordBase *out_pSchRecord ) const OVERRIDE; // virtual void LoadSchToEconAttributeValue( CEconItem *pTargetItem, const CEconItemAttributeDefinition *pAttrDef, const GCSDK::CRecordBase *pSchRecord ) const OVERRIDE; // }; // // Implement these two GC-only functions to convert from the in-memory format to the DB format and // vice versa and you're good to go. // // - register the new type in CEconItemSchema::BInitAttributeTypes(). // // If the attribute type can't be silently converted to an already-existing attribute value type, a few other // places will also fail to compile -- things like typed iteration, or compile-time type checking. // // Functions that start with "Convert" change the format of an attribute value (in a type-safe way wherever // possible), copying the value from one of the passed-in parameters to the other. Functions that start with // "Load" do a format conversion, but also add the post-conversion value to the passed-in CEconItem. This // comes up most often when generating new items, either from the DB (LoadSch), the network (LoadByteSteam), // or creation of a new item on the GC (LoadOrGenerate). class ISchemaAttributeType { public: virtual ~ISchemaAttributeType() { } // Returns a unique integer describing the C++-in-memory-layout type used by this attribute type. // For example, something that stores "int" might return 0 and "CSomeFancyWideAttributeType" might // return 1. The actual values don't matter and can even differ between different runs of the game/GC. // The only important thing is that during a single run the value for a single type is consistent. virtual unsigned int GetTypeUniqueIdentifier() const = 0; #ifdef GC_DLL // What's the whole column set (and associated DB table) that this attribute uses? Meant to be // implemented by subclasses that have DB type information. virtual const GCSDK::CColumnSet& GetFullColumnSet() const = 0; // Create an instance of a schema row. Mananging the memory is the responsibility of the caller. // Meant to be implemented by subclasses that have DB type information. virtual GCSDK::CRecordBase *CreateTypedSchRecord() const = 0; // ... virtual bool BAssetClassExportedAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const attribute_data_union_t& value ) const { return true; } // Prepare a DB row describing an instance of this attribute for writing. virtual void ConvertEconAttributeValueToSch( itemid_t unItemId, const CEconItemAttributeDefinition *pAttrDef, const union attribute_data_union_t& value, GCSDK::CRecordBase *out_pSchRecord ) const = 0; // We have a row read from the database and an item to add it as an attribute for. This // does the opposite work of ConvertEconAttributeValueToSch() and also adds it to the CEconItem. virtual void LoadSchToEconAttributeValue( CEconItem *pTargetItem, const CEconItemAttributeDefinition *pAttrDef, const GCSDK::CRecordBase *pSchRecord ) const = 0; // Have this attribute type either copy the data straight out of the value union, or run the logic // described by pszCustomLogicDesc to generate a new value. Either way, some correctly-typed data // will wind up in an attribute on the target item. This is intended to call through to LoadEconAttributeValue() // to do the actual assignment. This is only accessible on the GC. virtual void LoadOrGenerateEconAttributeValue( CEconItem *pTargetItem, const CEconItemAttributeDefinition *pAttrDef, const static_attrib_t& staticAttrib, const CEconGameAccount *pGameAccount ) const = 0; virtual void GenerateEconAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const static_attrib_t& staticAttrib, const CEconGameAccount *pGameAccount, attribute_data_union_t* out_pValue ) const = 0; #endif // GC_DLL // Have this attribute type copy the data out of the value union and type-copy it onto the item. This // is accessible on clients as well as the GC. virtual void LoadEconAttributeValue( CEconItem *pTargetItem, const CEconItemAttributeDefinition *pAttrDef, const union attribute_data_union_t& value ) const = 0; // ... virtual void ConvertEconAttributeValueToByteStream( const union attribute_data_union_t& value, std::string *out_psBytes ) const = 0; // ... virtual bool BConvertStringToEconAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const char *pszValue, union attribute_data_union_t *out_pValue, bool bEnableTerribleBackwardsCompatibilitySchemaParsingCode = false ) const = 0; // ... virtual void ConvertEconAttributeValueToString( const CEconItemAttributeDefinition *pAttrDef, const attribute_data_union_t& value, std::string *out_ps ) const = 0; // Used to deserialize a byte stream, probably from an on-wire protobuf message, instead an instance // of the attribute in memory. See ConvertByteStreamToTypedValue() for example implementation, or // ConvertTypedValueToByteStream() for an example of the byte-stream generator code. virtual void LoadByteStreamToEconAttributeValue( CEconItem *pTargetItem, const CEconItemAttributeDefinition *pAttrDef, const std::string& sBytes ) const = 0; // Give the subclass a chance to default-initialize a new value. For larger types, this may hit the // heap. This must be called before otherwise manipulating [out_pValue] through Convert*() functions. virtual void InitializeNewEconAttributeValue( attribute_data_union_t *out_pValue ) const = 0; // Free any heap-allocated memory from this attribute value. Is not responsible for zeroing out // pointers, etc. virtual void UnloadEconAttributeValue( union attribute_data_union_t *out_pValue ) const = 0; // ... virtual bool OnIterateAttributeValue( class IEconItemAttributeIterator *pIterator, const CEconItemAttributeDefinition *pAttrDef, const attribute_data_union_t& value ) const = 0; // This could also be called "BIsHackyMessyOldAttributeType()". This determines whether the attribute // can be set at runtime on a CEconItemView instance, whether the gameserver can replicate the value to // game clients, etc. It really only makes sense for value types 32 bits or smaller. virtual bool BSupportsGameplayModificationAndNetworking() const { return false; } }; //----------------------------------------------------------------------------- // CEconItemSchema // Defines the way econ items can be used in a game //----------------------------------------------------------------------------- typedef CUtlDict ArmoryStringDict_t; typedef CUtlDict< CUtlVector * > LevelBlockDict_t; typedef CUtlMap KillEaterScoreMap_t; typedef CUtlDict< CUtlVector< schema_string_table_entry_t > * > SchemaStringTableDict_t; struct attr_type_t { CUtlConstString m_sName; const ISchemaAttributeType *m_pAttrType; attr_type_t( const char *pszName, const ISchemaAttributeType *pAttrType ) : m_sName( pszName ) , m_pAttrType( pAttrType ) { } }; #if defined(CLIENT_DLL) || defined(GAME_DLL) class IDelayedSchemaData { public: virtual ~IDelayedSchemaData() {} virtual bool InitializeSchema( CEconItemSchema *pItemSchema ) = 0; protected: // Passing '0' as the expected version means "we weren't expecting any version in particular" and will // skip the sanity checking. bool InitializeSchemaInternal( CEconItemSchema *pItemSchema, CUtlBuffer& bufRawData, bool bInitAsBinary, uint32 nExpectedVersion ); }; #endif // defined(CLIENT_DLL) || defined(GAME_DLL) class CEconStorePriceSheet; class CEconItemSchema { public: CEconItemSchema( ); private: CEconItemSchema( const CEconItemSchema & rhs ); CEconItemSchema &operator=( CEconItemSchema & rhs ); public: virtual ~CEconItemSchema( void ) { Reset(); }; // Setup & parse in the item data files. virtual bool BInit( const char *fileName, const char *pathID, CUtlVector *pVecErrors = NULL ); bool BInitBinaryBuffer( CUtlBuffer &buffer, CUtlVector *pVecErrors = NULL ); bool BInitTextBuffer( CUtlBuffer &buffer, CUtlVector *pVecErrors = NULL ); #ifdef GC_DLL virtual bool DoPostPriceSheetLoadInit( CEconStorePriceSheet *pPriceSheet ); // Called once the price sheet's been loaded #endif uint32 GetVersion() const { return m_unVersion; } CSHA GetSchemaSHA() const { return m_schemaSHA; } uint32 GetResetCount() const { return m_unResetCount; } // Dump the schema for debug purposes bool DumpItems ( const char *fileName, const char *pathID = NULL ); // Perform the computation used to calculate the schema version static uint32 CalculateKeyValuesVersion( KeyValues *pKV ); #if defined(CLIENT_DLL) || defined(GAME_DLL) // This function will immediately reinitialize the schema if it's safe to do so, or store off the data // if it isn't safe to update at the moment. bool MaybeInitFromBuffer( IDelayedSchemaData *pDelayedSchemaData ); // If there is saved schema initialization data, initialize it now. If there is no saved data, this // will return success. bool BInitFromDelayedBuffer(); #endif // defined(CLIENT_DLL) || defined(GAME_DLL) // Accessors to the base properties EEquipType_t GetEquipTypeFromClassIndex( int iClass ) const; equipped_class_t GetAccountIndex() const { return m_unAccoutClassIndex; } equipped_class_t GetFirstValidClass() const { return m_unFirstValidClass; } equipped_class_t GetLastValidClass() const { return m_unLastValidClass; } bool IsValidClass( equipped_class_t unClass ) { return ( unClass >= m_unFirstValidClass && unClass <= m_unLastValidClass ) || unClass == GetAccountIndex(); } bool IsValidItemSlot( equipped_slot_t unSlot, equipped_class_t unClass ) const { return IsValidItemSlot( unSlot, unClass == m_unAccoutClassIndex ? EQUIP_TYPE_ACCOUNT : EQUIP_TYPE_CLASS ); } bool IsValidItemSlot( equipped_slot_t unSlot, EEquipType_t eType ) const { return eType == EQUIP_TYPE_ACCOUNT ? unSlot >= m_unFirstValidAccountItemSlot && unSlot <= m_unLastValidAccountItemSlot : unSlot >= m_unFirstValidClassItemSlot && unSlot <= m_unLastValidClassItemSlot; } enum { kMaxItemPresetCount = 4 }; uint32 GetNumAllowedItemPresets() const { return kMaxItemPresetCount; } bool IsValidPreset( equipped_preset_t unPreset ) const { return unPreset <= GetNumAllowedItemPresets(); } uint32 GetMinLevel() const { return m_unMinLevel; } uint32 GetMaxLevel() const { return m_unMaxLevel; } // Accessors to the underlying sections typedef CUtlHashMapLarge ItemDefinitionMap_t; const ItemDefinitionMap_t &GetItemDefinitionMap() const { return m_mapItems; } typedef CUtlMap SortedItemDefinitionMap_t; const SortedItemDefinitionMap_t &GetSortedItemDefinitionMap() const { return m_mapItemsSorted; } typedef CUtlMap ToolsItemDefinitionMap_t; const ToolsItemDefinitionMap_t &GetToolsItemDefinitionMap() const { return m_mapToolsItems; } typedef CUtlMap BaseItemDefinitionMap_t; const BaseItemDefinitionMap_t &GetBaseItemDefinitionMap() const { return m_mapBaseItems; } typedef CUtlMap LootListDefinitionMap_t; const LootListDefinitionMap_t &GetLootLists() const { return m_mapLootLists; } typedef CUtlMap RevolvingLootListDefinitionMap_t; const RevolvingLootListDefinitionMap_t &GetRevolvingLootLists() const { return m_mapRevolvingLootLists; } typedef CUtlMap BodygroupStateMap_t; const BodygroupStateMap_t &GetDefaultBodygroupStateMap() const { return m_mapDefaultBodygroupState; } typedef CUtlVector ColorDefinitionsList_t; typedef CUtlMap PrefabMap_t; #ifdef GC_DLL struct periodic_score_t { eEconPeriodicScoreEvents m_eEventType; bool m_bGCUpdateOnly; // if set, only code that runs on the GC can initiate a change of this stat (ie., counting gifts -> true; bots killed -> false) uint32 m_unTimePeriodLengthInSeconds; CEconItemDefinition *m_pRewardItemDefinition; }; typedef CUtlVector PeriodicScoreTypeList_t; #endif // GC_DLL #if defined(CLIENT_DLL) || defined(GAME_DLL) CEconItemDefinition *GetDefaultItemDefinition() { return m_pDefaultItemDefinition; } bool SetupPreviewItemDefinition( KeyValues *pKV ); #endif const CUtlMap &GetQualityDefinitionMap() const { return m_mapQualities; } const CUtlMap &GetAttributeDefinitionMap() const { return m_mapAttributes; } typedef CUtlMap RecipeDefinitionMap_t; const RecipeDefinitionMap_t &GetRecipeDefinitionMap() const { return m_mapRecipes; } typedef CUtlMap ItemSetMap_t; const ItemSetMap_t &GetItemSets() const { return m_mapItemSets; } typedef CUtlMap ItemCollectionMap_t; const ItemCollectionMap_t &GetItemCollections() const { return m_mapItemCollections; } typedef CUtlVector< int > ItemCollectionCrateMap_t; const ItemCollectionCrateMap_t &GetItemCollectionCrates() const { return m_vecItemCollectionCrates; } typedef CUtlMap ItemPaintKitMap_t; const ItemPaintKitMap_t &GetItemPaintKits() const { return m_mapItemPaintKits; } typedef CUtlMap OperationDefinitionMap_t; const OperationDefinitionMap_t &GetOperationDefinitions() const { return m_mapOperationDefinitions; } #if defined(CLIENT_DLL) || defined(GAME_DLL) const ArmoryStringDict_t &GetArmoryDataItemClasses() const { return m_dictArmoryItemClassesDataStrings; } const ArmoryStringDict_t &GetArmoryDataItemTypes() const { return m_dictArmoryItemTypesDataStrings; } const ArmoryStringDict_t &GetArmoryDataItems() const { return m_dictArmoryItemDataStrings; } const ArmoryStringDict_t &GetArmoryDataAttributes() const { return m_dictArmoryAttributeDataStrings; } #elif defined(GC_DLL) CUtlVector< CExperimentDefinition > &GetExperiments() { return m_vecExperiments; } const CUtlVector< AppId_t > & GetForeignApps() const { return m_vecForeignApps; } const CEconItemDefinition *GetAppItemImport( AppId_t unAppID, uint16 usDefIndex ) const; #endif const CTimedItemRewardDefinition* GetTimedReward( eTimedRewardType type ) const; const CEconLootListDefinition* GetLootListByName( const char* pListName, int *out_piIndex = NULL ) const; const CEconLootListDefinition* GetLootListByIndex( int iIdx ) const { return m_mapLootLists.IsValidIndex(iIdx) ? m_mapLootLists[iIdx] : NULL; } const CQuestObjectiveDefinition* GetQuestObjectiveByDefIndex( int iIdx ) const; const CUtlMap& GetQuestObjectives() const { return m_mapQuestObjectives; } uint8 GetDefaultQuality() const { return AE_UNIQUE; } void AssignDefaultBodygroupState( const char *pszBodygroupName, int iValue ); equip_region_mask_t GetEquipRegionMaskByName( const char *pRegionName ) const; struct EquipRegion { CUtlConstString m_sName; unsigned int m_unBitIndex; // which bit are we claiming ownership over? there might be multiple equip regions with the same bit if we're in a "shared" block equip_region_mask_t m_unMask; // full region conflict mask }; typedef CUtlVector EquipRegionsList_t; const EquipRegionsList_t& GetEquipRegionsList() const { return m_vecEquipRegionsList; } equip_region_mask_t GetEquipRegionBitMaskByName( const char *pRegionName ) const; KeyValues *FindDefinitionPrefabByName( const char *pszPrefabName ) const; const PrefabMap_t& GetPrefabMap() const { return m_mapDefinitionPrefabs; } CUtlVector< CEconItemDefinition * > &GetBundles() { return m_vecBundles; } // Retrieve a cached list of all bundles const char *FindStringTableEntry( const char *pszTableName, int iIndex ) const; private: void SetEquipRegionConflict( int iRegion, unsigned int unBit ); int GetEquipRegionIndexByName( const char *pRegionName ) const; public: // Common lookup methods bool BGetItemQualityFromName( const char *pchName, uint8 *nQuality ) const; const CEconItemQualityDefinition *GetQualityDefinition( int nQuality ) const; const CEconItemQualityDefinition *GetQualityDefinitionByName( const char *pszDefName ) const; bool BGetItemRarityFromName( const char* pchName, uint8 *nRarity ) const; const CEconItemRarityDefinition *GetRarityDefinitionByMapIndex( int nRarityIndex ) const; const CEconItemRarityDefinition *GetRarityDefinition( int nRarity ) const; const CEconItemRarityDefinition *GetRarityDefinitionByName( const char *pszDefName ) const; virtual int GetRarityDefinitionCount( void ) const { return m_mapRarities.Count(); } virtual const char* GetRarityName( uint8 iRarity ); virtual const char* GetRarityLocKey( uint8 iRarity ); virtual const char* GetRarityColor( uint8 iRarity ); virtual int GetRarityIndex( const char* pszRarity ); const CEconItemCollectionDefinition *GetCollectionByName( const char* pCollectionName ); virtual int GetItemSeriesDefinitionCount( void ) const { return m_mapItemSeries.Count(); } bool BGetItemSeries( const char* pchName, uint8 *nItemSeries ) const; const CEconItemSeriesDefinition *GetItemSeriesDefinition( int nRarity ) const; CEconItemDefinition *GetItemDefinition( int iItemIndex ); const CEconItemDefinition *GetItemDefinition( int iItemIndex ) const; CEconItemAttributeDefinition *GetAttributeDefinition( int iAttribIndex ); const CEconItemAttributeDefinition *GetAttributeDefinition( int iAttribIndex ) const; CEconItemAttributeDefinition *GetAttributeDefinitionByName( const char *pszDefName ); const CEconItemAttributeDefinition *GetAttributeDefinitionByName( const char *pszDefName ) const; CEconCraftingRecipeDefinition *GetRecipeDefinition( int iRecipeIndex ); CEconColorDefinition *GetColorDefinitionByName( const char *pszDefName ); const CEconColorDefinition *GetColorDefinitionByName( const char *pszDefName ) const; #ifdef CLIENT_DLL const char *GetSteamPackageLocalizationToken( uint32 unPackageId ) const; #endif // CLIENT_DLL bool BCanGSCreateItems( uint32 unIP ) const; #ifdef GC_DLL const AchievementAward_t *GetAchievementReward( const char *pchAchievementName, AppId_t unAppID ) const; const AchievementAward_t *GetAchievementRewardByData( uint32 unData ) const; #endif const AchievementAward_t *GetAchievementRewardByDefIndex( uint16 usDefIndex ) const; bool BHasAchievementRewards( void ) const { return (m_dictAchievementRewards.Count() > 0); } static CUtlString ComputeAchievementName( AppId_t unAppID, const char *pchNativeAchievementName ); // Iterating over the item definitions. Game needs this to precache data. CEconItemDefinition *GetItemDefinitionByName( const char *pszDefName ); const CEconItemDefinition *GetItemDefinitionByName( const char *pszDefName ) const; #ifdef GC_DLL random_attrib_t *GetRandomAttributeTemplateByName( const char *pszAttrTemplateName ) const; #endif // GC_DLL attachedparticlesystem_t* GetAttributeControlledParticleSystem( int id ); attachedparticlesystem_t* FindAttributeControlledParticleSystem( const char *pchSystemName ); typedef CUtlMap ParticleDefinitionMap_t; const ParticleDefinitionMap_t& GetAttributeControlledParticleSystems() const { return m_mapAttributeControlledParticleSystems; } const CUtlVector< int > *GetWeaponUnusualParticleIndexes() const { return &m_vecAttributeControlledParticleSystemsWeapons; } const CUtlVector< int > *GetCosmeticUnusualParticleIndexes() const { return &m_vecAttributeControlledParticleSystemsCosmetics; } const CUtlVector< int > *GetTauntUnusualParticleIndexes() const { return &m_vecAttributeControlledParticleSystemsTaunts; } #ifdef CLIENT_DLL locchar_t *GetParticleSystemLocalizedName( int index ) const; #endif // CLIENT_DLL #ifdef GC_DLL const PeriodicScoreTypeList_t& GetPeriodicScoreTypeList() const { return m_vecPeriodicScoreTypes; } int GetPeriodicScoreTypeCount() const { return GetPeriodicScoreTypeList().Count(); } // how many types of events are we tracking? the range goes from 0 through this return value const periodic_score_t& GetPeriodicScoreInfo( int iPeriodicScoreIndex ) const; // get the full info block for this periodic score -- event type, time period, etc. // Only intended to be used for generating data for the WebAPI. const KillEaterScoreMap_t& GetKillEaterScoreTypes() const { return m_mapKillEaterScoreTypes; } const SchemaStringTableDict_t& GetStringTables() const { return m_dictStringTable; } #endif // GC_DLL item_definition_index_t GetCommunityMarketRemappedDefinitionIndex( item_definition_index_t unSearchItemDef ) const; const CUtlVector& GetAttributeTypes() const { return m_vecAttributeTypes; } const ISchemaAttributeType *GetAttributeType( const char *pszAttrTypeName ) const; const LevelBlockDict_t& GetItemLevelingDataDict() const { return m_vecItemLevelingData; } const CUtlVector *GetItemLevelingData( const char *pszLevelBlockName ) const { LevelBlockDict_t::IndexType_t i = m_vecItemLevelingData.Find( pszLevelBlockName ); if ( i == LevelBlockDict_t::InvalidIndex() ) return NULL; return m_vecItemLevelingData[i]; } const CItemLevelingDefinition *GetItemLevelForScore( const char *pszLevelBlockName, uint32 unScore ) const; const char *GetKillEaterScoreTypeLocString( uint32 unScoreType ) const; const char *GetKillEaterScoreTypeLevelingDataName( uint32 unScoreType ) const; bool GetKillEaterScoreTypeAllowsBotVictims( uint32 unScoreType ) const; #ifdef GC_DLL bool GetKillEaterScoreTypeGCOnlyUpdate( uint32 unScoreType ) const; bool GetKillEaterScoreTypeAllowsIncrementValues( uint32 unScoreType ) const; #endif #if defined(CLIENT_DLL) || defined(GAME_DLL) void ItemTesting_CreateTestDefinition( int iCloneFromItemDef, int iNewDef, KeyValues *pNewKV ); void ItemTesting_DiscardTestDefinition( int iDef ); #endif #ifdef DBGFLAG_VALIDATE void Validate( CValidator &validator, const char *pchName ); #endif // DBGFLAG_VALIDATE econ_tag_handle_t GetHandleForTag( const char *pszTagName ); // non-const because it may create a new tag handle typedef CUtlDict EconTagDict_t; #ifdef GC_DLL const EconTagDict_t& GetEconTagDict() const { return m_dictTags; } // meant for internal/debug use only, not for runtime iteration #endif // GC_DLL virtual RTime32 GetCustomExpirationDate( const char *pszExpirationDate ) const { return k_RTime32Nil; } public: // Subclass interface. virtual CEconItemDefinition *CreateEconItemDefinition() { return new CEconItemDefinition; } virtual CEconCraftingRecipeDefinition *CreateCraftingRecipeDefinition() { return new CEconCraftingRecipeDefinition; } virtual CEconStyleInfo *CreateEconStyleInfo() { return new CEconStyleInfo; } virtual CQuestObjectiveDefinition *CreateQuestDefinition() { return new CQuestObjectiveDefinition; } virtual IEconTool *CreateEconToolImpl( const char *pszToolType, const char *pszUseString, const char *pszUsageRestriction, item_capabilities_t unCapabilities, KeyValues *pUsageKV ); #ifdef GC_DLL virtual random_attrib_t *CreateRandomAttribute( const char *pszContext, KeyValues *pRandomAttributesKV, CUtlVector *pVecErrors = NULL ); #endif // GC_DLL virtual bool BCanStrangeFilterApplyToStrangeSlotInItem( uint32 /*strange_event_restriction_t*/ unRestrictionType, uint32 unRestrictionValue, const IEconItemInterface *pItem, int iStrangeSlot, uint32 *out_pOptionalScoreType ) const; bool AddQuestObjective( const CQuestObjectiveDefinition **ppQuestObjective, KeyValues *pKVObjective, CUtlVector *pVecErrors ); bool BInsertLootlist( const char *pListName, KeyValues *pKVLootList, CUtlVector *pVecErrors ); #ifdef GC_DLL void PerformCaseBehaviorCheck(); #endif protected: virtual void Reset( void ); virtual bool BInitSchema( KeyValues *pKVRawDefinition, CUtlVector *pVecErrors = NULL ); #ifdef TF_CLIENT_DLL virtual int CalculateNumberOfConcreteItems( const CEconItemDefinition *pItemDef ); // Let derived classes handle custom item types #endif // TF_CLIENT_DLL private: bool BInitGameInfo( KeyValues *pKVGameInfo, CUtlVector *pVecErrors ); bool BInitAttributeTypes( CUtlVector *pVecErrors ); #ifdef GC_DLL bool BInitPeriodicScoring( KeyValues *pKVGameInfo, CUtlVector *pVecErrors ); #endif // GC_DLL bool BInitDefinitionPrefabs( KeyValues *pKVPrefabs, CUtlVector *pVecErrors ); bool BInitItemSeries( KeyValues *pKVSeries, CUtlVector *pVecErrors ); bool BVerifyBaseItemNames( CUtlVector *pVecErrors ); bool BInitRarities( KeyValues *pKVRarities, KeyValues *pKVRarityWeights, CUtlVector *pVecErrors ); bool BInitQualities( KeyValues *pKVAttributes, CUtlVector *pVecErrors ); bool BInitColors( KeyValues *pKVColors, CUtlVector *pVecErrors ); bool BInitAttributes( KeyValues *pKVAttributes, CUtlVector *pVecErrors ); bool BInitEquipRegions( KeyValues *pKVEquipRegions, CUtlVector *pVecErrors ); bool BInitEquipRegionConflicts( KeyValues *pKVEquipRegions, CUtlVector *pVecErrors ); bool BInitItems( KeyValues *pKVAttributes, CUtlVector *pVecErrors ); bool BInitItemSets( KeyValues *pKVItemSets, CUtlVector *pVecErrors ); bool BInitTimedRewards( KeyValues *pKVTimeRewards, CUtlVector *pVecErrors ); bool BInitAchievementRewards( KeyValues *pKVTimeRewards, CUtlVector *pVecErrors ); #ifdef GC_DLL bool BInitRandomAttributeTemplates( KeyValues *pKVRandomAttributeTemplates, CUtlVector *pVecErrors ); #endif // GC_DLL bool BInitRecipes( KeyValues *pKVRecipes, CUtlVector *pVecErrors ); bool BInitLootLists( KeyValues *pKVLootLists, CUtlVector *pVecErrors ); bool BInitRevolvingLootLists( KeyValues *pKVRevolvingLootLists, CUtlVector *pVecErrors ); bool BInitItemCollections( KeyValues *pKVItemSets, CUtlVector *pVecErrors ); bool BInitCollectionReferences( CUtlVector *pVecErrors ); bool BInitItemPaintKitDefinitions( KeyValues *pKVPaintKits, CUtlVector *pVecErrors ); bool BInitOperationDefinitions( KeyValues *pKVGameInfo, KeyValues *pOperations, CUtlVector *pVecErrors ); #ifdef TF_CLIENT_DLL bool BInitConcreteItemCounts( CUtlVector *pVecErrors ); bool BInitSteamPackageLocalizationToken( KeyValues *pKVSteamPackages, CUtlVector *pVecErrors ); #endif // TF_CLIENT_DLL bool BInitItemLevels( KeyValues *pKVItemLevels, CUtlVector *pVecErrors ); bool BInitKillEaterScoreTypes( KeyValues *pKVItemLevels, CUtlVector *pVecErrors ); bool BInitStringTables( KeyValues *pKVStringTables, CUtlVector *pVecErrors ); bool BInitCommunityMarketRemaps( KeyValues *pKVCommunityMarketRemaps, CUtlVector *pVecErrors ); bool BPostSchemaInit( CUtlVector *pVecErrors ) const; bool BInitAttributeControlledParticleSystems( KeyValues *pKVParticleSystems, CUtlVector *pVecErrors ); #if defined(CLIENT_DLL) || defined(GAME_DLL) bool BInitArmoryData( KeyValues *pKVArmoryData, CUtlVector *pVecErrors ); #else bool BInitExperiements( KeyValues *pKVExperiments, CUtlVector *pVecErrors ); bool BInitForeignImports( CUtlVector *pVecErrors ); CForeignAppImports *FindOrAddAppImports( AppId_t unAppID ); #endif bool BVerifyLootListItemDropDates( const CEconLootListDefinition* pLootList, CUtlVector *pVecErrors ) const; bool BRecurseiveVerifyLootListItemDropDates( const CEconLootListDefinition* pLootList, const CEconLootListDefinition* pRootLootList, CUtlVector *pVecErrors ) const; // Note: this returns pointers to the inside of a vector and/or NULL. Pointers are not intended to be // saved off and used later. const kill_eater_score_type_t *FindKillEaterScoreType( uint32 unScoreType ) const; uint32 m_unResetCount; KeyValues *m_pKVRawDefinition; uint32 m_unVersion; CSHA m_schemaSHA; // Class range equipped_class_t m_unFirstValidClass; equipped_class_t m_unLastValidClass; equipped_class_t m_unAccoutClassIndex; // Item slot range equipped_slot_t m_unFirstValidClassItemSlot; equipped_slot_t m_unLastValidClassItemSlot; equipped_slot_t m_unFirstValidAccountItemSlot; equipped_slot_t m_unLastValidAccountItemSlot; // Number of allowed presets uint32 m_unNumItemPresets; // Allowable range of item levels for this app uint32 m_unMinLevel; uint32 m_unMaxLevel; // Total value of all the weights of the qualities uint32 m_unSumQualityWeights; // Name-to-implementation list of all unique attribute types (ie., "wide strange score"). CUtlVector m_vecAttributeTypes; // Contains the list of rarity definitions CUtlMap m_mapItemSeries; // Contains the list of rarity definitions CUtlMap m_mapRarities; // Contains the list of item definitions read in from all data files. CUtlMap m_mapQualities; // Contains the list of item definitions read in from all data files. ItemDefinitionMap_t m_mapItems; CUtlMap m_mapQuestObjectives; // A sorted version of the same map, for instances where we really want sorted data SortedItemDefinitionMap_t m_mapItemsSorted; // List of all the tool items, is a sublist of mapItems ToolsItemDefinitionMap_t m_mapToolsItems; // List of all base items, is a sublist of mapItems BaseItemDefinitionMap_t m_mapBaseItems; #if defined(CLIENT_DLL) || defined(GAME_DLL) // What is the default item definition we'll return in the client code if we can't find the correct one? CEconItemDefinition *m_pDefaultItemDefinition; #endif // Contains the list of attribute definitions read in from all data files. CUtlMap m_mapAttributes; // Contains the list of item recipes read in from all data files. RecipeDefinitionMap_t m_mapRecipes; // Contains the list of item sets. ItemSetMap_t m_mapItemSets; ItemCollectionMap_t m_mapItemCollections; ItemCollectionCrateMap_t m_vecItemCollectionCrates; OperationDefinitionMap_t m_mapOperationDefinitions; // Paint Kit defintions ItemPaintKitMap_t m_mapItemPaintKits; // Revolving loot lists. CUtlMap m_mapRevolvingLootLists; // Contains the list of loot lists. LootListDefinitionMap_t m_mapLootLists; // List of events that award items based on time played CUtlVector m_vecTimedRewards; // list of items that will be awarded from achievements CUtlDict< AchievementAward_t *, int > m_dictAchievementRewards; CUtlMap< uint32, AchievementAward_t * > m_mapAchievementRewardsByData; #ifdef GC_DLL // list of random attribute templates CUtlDict< random_attrib_t * > m_dictRandomAttributeTemplates; #endif // GC_DLL // Contains information for attribute attached particle systems CUtlMap m_mapAttributeControlledParticleSystems; CUtlVector< int > m_vecAttributeControlledParticleSystemsCosmetics; CUtlVector< int > m_vecAttributeControlledParticleSystemsWeapons; CUtlVector< int > m_vecAttributeControlledParticleSystemsTaunts; // Contains information on which equip regions conflict with each other regions and how to // test for overlap. EquipRegionsList_t m_vecEquipRegionsList; // Contains information about prefab KeyValues blocks that be can referenced elsewhere // in the schema. PrefabMap_t m_mapDefinitionPrefabs; // Contains runtime color information, looked-up by name. ColorDefinitionsList_t m_vecColorDefs; // Contains information about: a) every bodygroup that appears anywhere in the schema, and // b) whether they default to on or off. BodygroupStateMap_t m_mapDefaultBodygroupState; // Various definitions can have any number of unique tags associated with them. EconTagDict_t m_dictTags; #ifdef GC_DLL // Information about our periodic score accumulators. PeriodicScoreTypeList_t m_vecPeriodicScoreTypes; #endif // GC_DLL // List of item leveling data. KillEaterScoreMap_t m_mapKillEaterScoreTypes; SchemaStringTableDict_t m_dictStringTable; typedef CUtlMap< item_definition_index_t, item_definition_index_t, item_definition_index_t > CommunityMarketDefinitionRemapMap_t; CommunityMarketDefinitionRemapMap_t m_mapCommunityMarketDefinitionIndexRemap; #ifdef CLIENT_DLL // Steam-package-ID-to-localization-token map, used for modifying tooltips in the store. typedef CUtlMap< uint32, const char * > SteamPackageLocalizationTokenMap_t; SteamPackageLocalizationTokenMap_t m_mapSteamPackageLocalizationTokens; #endif // CLIENT_DLL LevelBlockDict_t m_vecItemLevelingData; #if defined(CLIENT_DLL) || defined(GAME_DLL) // Contains Armory data key->localization string mappings ArmoryStringDict_t m_dictArmoryItemTypesDataStrings; ArmoryStringDict_t m_dictArmoryItemClassesDataStrings; ArmoryStringDict_t m_dictArmoryAttributeDataStrings; ArmoryStringDict_t m_dictArmoryItemDataStrings; // Used for delaying the parsing of the item schema until its safe to swap out the back end data. IDelayedSchemaData *m_pDelayedSchemaData; #elif defined(GC_DLL) // GC only CUtlVector< CExperimentDefinition > m_vecExperiments; CUtlMap< AppId_t, CForeignAppImports *> m_mapForeignImports; CUtlVector< AppId_t > m_vecForeignApps; #endif CUtlVector< CEconItemDefinition * > m_vecBundles; // A cached list of all bundles }; #ifdef GC_DLL void PerformIncrementKillEaterAttributeScore( CEconUserSession *pLockedOwnerSession, CEconItem *pItem, uint32 unEventType, uint32 unIncrementCount, bool bGCOrigination, GCSDK::CSharedObjectTransactionEx *pTransaction ); #endif // GC_DLL extern CEconItemSchema & GEconItemSchema(); //----------------------------------------------------------------------------- // CSchemaFieldHandle //----------------------------------------------------------------------------- template < class T > class CSchemaFieldHandle { public: explicit CSchemaFieldHandle( const char *szName ) : m_szName( szName ) { m_pRef = GetTypedRef(); m_unSchemaGeneration = GEconItemSchema().GetResetCount(); #if _DEBUG m_unVersion_Debug = GEconItemSchema().GetVersion(); #endif } operator const T *( void ) const { uint32 unSchemaGeneration = GEconItemSchema().GetResetCount(); if ( m_unSchemaGeneration != unSchemaGeneration ) { m_pRef = GetTypedRef(); m_unSchemaGeneration = unSchemaGeneration; #if _DEBUG m_unVersion_Debug = GEconItemSchema().GetVersion(); #endif } #if _DEBUG Assert( m_unVersion_Debug == GEconItemSchema().GetVersion() ); #endif return m_pRef; } const T *operator->( void ) const { return static_cast( *this ); } const char *GetName( void ) const { return m_szName; } private: const T *GetTypedRef() const; private: const char *m_szName; mutable const T *m_pRef; mutable uint32 m_unSchemaGeneration; #if _DEBUG mutable uint32 m_unVersion_Debug; #endif }; template < > inline const CEconColorDefinition *CSchemaFieldHandle::GetTypedRef( void ) const { return GEconItemSchema().GetColorDefinitionByName( m_szName ); } template < > inline const CEconItemAttributeDefinition *CSchemaFieldHandle::GetTypedRef( void ) const { return GEconItemSchema().GetAttributeDefinitionByName( m_szName ); } template < > inline const CEconItemDefinition *CSchemaFieldHandle::GetTypedRef( void ) const { return GEconItemSchema().GetItemDefinitionByName( m_szName ); } template < > inline const CEconLootListDefinition *CSchemaFieldHandle::GetTypedRef( void ) const { return GEconItemSchema().GetLootListByName( m_szName ); } template < > inline const attachedparticlesystem_t *CSchemaFieldHandle::GetTypedRef( void ) const { return GEconItemSchema().FindAttributeControlledParticleSystem( m_szName ); } typedef CSchemaFieldHandle CSchemaColorDefHandle; typedef CSchemaFieldHandle CSchemaAttributeDefHandle; typedef CSchemaFieldHandle CSchemaItemDefHandle; typedef CSchemaFieldHandle CSchemaLootListDefHandle; typedef CSchemaFieldHandle CSchemaParticleHandle; struct steam_market_gc_identifier_t { item_definition_index_t m_unDefIndex; uint8 m_unQuality; bool operator<( const struct steam_market_gc_identifier_t& b ) const { return (m_unDefIndex < b.m_unDefIndex) || ((m_unDefIndex == b.m_unDefIndex) && (m_unQuality < b.m_unQuality)); } }; // Implementation reliant on earlier class content. inline const CEconItemAttributeDefinition *static_attrib_t::GetAttributeDefinition() const { return GEconItemSchema().GetAttributeDefinition( iDefIndex ); } inline const ISchemaAttributeType *static_attrib_t::GetAttributeType() const { const CEconItemAttributeDefinition *pAttrDef = GetAttributeDefinition(); if ( !pAttrDef ) return NULL; return pAttrDef->GetAttributeType(); } // Utility function to convert datafile strings to ints. int StringFieldToInt( const char *szValue, const char **pValueStrings, int iNumStrings, bool bDontAssert = false ); int StringFieldToInt( const char *szValue, const CUtlVector& vecValueStrings, bool bDontAssert = false ); #ifdef GC_DLL // Global econ-level helper functionality. EUniverse GetUniverse(); bool BYieldingGetChangedItemDefinitions( int iComparisonColumn, CUtlVector& out_vecChangedDefIndices ); bool BYieldingUpdateItemDefinitionStateHashValue( GCSDK::CSQLAccess& sqlAccess, item_definition_index_t unItemDef, int iUpdatedColumn ); #endif // GC_DLL //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- class CAttributeLineItemLootList : public IEconLootList { public: static CSchemaAttributeDefHandle s_pAttrDef_RandomDropLineItems[4]; #ifdef GC_DLL static CSchemaAttributeDefHandle s_pAttrDef_RandomDropLineItemUnusualChance; static CSchemaAttributeDefHandle s_pAttrDef_RandomDropLineItemUnusualList; #endif // GC_DLL static CSchemaAttributeDefHandle s_pAttrDef_RandomDropLineItemFooterDesc; public: CAttributeLineItemLootList( const IEconItemInterface *pEconItem ) : m_pEconItem( pEconItem ) { // } virtual void EnumerateUserFacingPotentialDrops( IEconLootListIterator *pIt ) const OVERRIDE; virtual bool BPublicListContents() const OVERRIDE { return true; } // any attribute data that clients have is public to them virtual const char *GetLootListHeaderLocalizationKey() const OVERRIDE; virtual const char *GetLootListFooterLocalizationKey() const OVERRIDE; virtual const char *GetLootListCollectionReference() const OVERRIDE; #ifdef GC_DLL MUST_CHECK_RETURN virtual bool BGenerateSingleRollRandomItems( const CEconGameAccount *pGameAccount, bool bFreeAccount, CUtlVector *out_pvecItems, const CUtlVector< item_definition_index_t > *pVecAvoidItemDefs = NULL ) const OVERRIDE; #endif // GC_DLL private: const IEconItemInterface *m_pEconItem; }; void MergeDefinitionPrefab( KeyValues *pKVWriteItem, KeyValues *pKVSourceItem ); #endif //ECONITEMSCHEMA_H