Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3375 lines
134 KiB

5 years ago
//========= 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 <string>
#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<CUtlString> *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<CUtlString> *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<CUtlString> *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<CUtlString> *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<CUtlString> *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<CUtlString> *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<CUtlString> *pVecErrors = NULL );
void IterateAttributes( class IEconItemAttributeIterator *pIterator ) const;
public:
const char *m_pszName;
const char *m_pszLocalizedName;
CUtlVector<item_definition_index_t> 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<itemset_attrib_t> m_iAttributes;
};
//-----------------------------------------------------------------------------
class CEconItemCollectionDefinition
{
public:
CEconItemCollectionDefinition( void );
~CEconItemCollectionDefinition( void ) {}
bool BInitFromKV( KeyValues *pKVItemCollection, CUtlVector<CUtlString> *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<item_definition_index_t> m_iItemDefs;
private:
bool m_bIsReferenceCollection;
uint8 m_iRarityMin;
uint8 m_iRarityMax;
};
//-----------------------------------------------------------------------------
class CEconItemPaintKitDefinition
{
public:
CEconItemPaintKitDefinition( void );
~CEconItemPaintKitDefinition( void );
bool BInitFromKV( KeyValues *pKVItemPaintKit, CUtlVector<CUtlString> *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<CUtlString> *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<CEconItem *> *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<CUtlString> *pVecErrors );
};
struct random_attrib_t
{
float m_flChanceOfRandomAttribute;
float m_flTotalAttributeWeight;
bool m_bPickAllAttributes;
CUtlVector<lootlist_attrib_t> 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<CUtlString> *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<drop_item_t>& GetLootListContents() const { return m_DropList; }
#ifdef GC_DLL
const CUtlVector<loot_list_additional_drop_t>& 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<CUtlString> *pVecErrors = NULL );
bool AddRandomAttributesFromTemplates( KeyValues *pRandomAttributesKV, CEconItemSchema &pschema, CUtlVector<CUtlString> *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<CEconItem *> *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<rolled_item_defs_t> *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<rolled_item_defs_t> *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<CUtlString> *pVecErrors );
#endif
private:
const char *m_pszName;
const char *m_pszLootListHeader;
const char *m_pszLootListFooter;
const char *m_pszCollectionReference;
CUtlVector<drop_item_t> 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<random_attrib_t*> m_RandomAttribs;
CUtlVector<loot_list_additional_drop_t> m_AdditionalDrops;
CUtlVector<const IEconItemPropertyGenerator *> 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<CUtlString> *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<CEconItem*> *vecCraftingItems, KeyValues *out_pCraftParams = NULL, bool bIgnoreSlop = false, CUtlVector<uint64> *vecChosenItems = NULL ) const;
const CUtlVector<CItemSelectionCriteria> *GetInputItems( void ) const { return &m_InputItemsCriteria; }
const CUtlVector<uint32> &GetInputItemDupeCounts( void ) const { return m_InputItemDupeCounts; }
const CUtlVector<CItemSelectionCriteria> &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<CItemSelectionCriteria> m_InputItemsCriteria;
CUtlVector<uint32> m_InputItemDupeCounts;
// The list of items that are generated by this recipe
CUtlVector<CItemSelectionCriteria> 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<CUtlString> *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<const char*, int> m_ModifiedBodyGroupNames; // Better method: hide multiple body groups by name.
CUtlMap<const char*, codecontrolledbodygroupdata_t> 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<CUtlString> *pVecErrors );
#if defined(CLIENT_DLL) || defined(GAME_DLL)
virtual void GeneratePrecacheModelStringsForStyle( CUtlVector<const char *> *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<const char *>& 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<const char *> 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<attachedmodel_t> m_AttachedModels;
CUtlVector<attachedmodel_t> m_AttachedModelsFestive; // Attr controlled Festive Attachments
CUtlVector<attachedparticlesystem_t> m_AttachedParticles;
CUtlVector<animation_on_wearable_t> m_Animations;
CUtlVector<activity_on_wearable_t> 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<CEconStyleInfo *> 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<CEconItemDefinition *> 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<uint64> 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<CUtlString> *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<CUtlString> *pVecErrors = NULL );
#if defined(CLIENT_DLL) || defined(GAME_DLL)
virtual bool BInitFromTestItemKVs( int iNewDefIndex, KeyValues *pKVItem, CUtlVector<CUtlString>* pVecErrors = NULL );
virtual void GeneratePrecacheModelStrings( bool bDynamicLoad, CUtlVector<const char *> *out_pVecModelStrings ) const;
virtual void GeneratePrecacheSoundStrings( bool bDynamicLoad, CUtlVector<const char *> *out_pVecSoundStrings ) const;
virtual void CopyPolymorphic( const CEconItemDefinition *pSourceDef ) { *this = *pSourceDef; }
#endif
bool BInitItemMappings( CUtlVector<CUtlString> *pVecErrors );
void BInitVisualBlockFromKV( KeyValues *pKVItem, CUtlVector<CUtlString> *pVecErrors = NULL );
void BInitStylesBlockFromKV( KeyValues *pKVStyles, perteamvisuals_t *pVisData, CUtlVector<CUtlString> *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<static_attrib_t> &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<const T *>( 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<CUtlString> *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<econ_tag_handle_t>& GetEconTags() const { return m_vecTags; } // meant for internal/debug use only, not for runtime iteration
const CUtlVector<econ_item_payment_rule_t>& 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<static_attrib_t> 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<const char*> 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<const IEconItemPropertyGenerator *> m_vecPropertyGenerators;
CUtlVector<econ_item_payment_rule_t> 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<econ_tag_handle_t> m_vecTags;
CUtlVector<const CEconItemDefinition *> m_vecContainingBundleItemDefs; // Item definition indices for any bundles which contain this item
CUtlVector<uint32> 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<CUtlString> *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<CUtlString> *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<CUtlString> *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<uint16> 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<T>().
//
// 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<CUtlConstString, int> ArmoryStringDict_t;
typedef CUtlDict< CUtlVector<CItemLevelingDefinition> * > LevelBlockDict_t;
typedef CUtlMap<unsigned int, kill_eater_score_type_t> 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<CUtlString> *pVecErrors = NULL );
bool BInitBinaryBuffer( CUtlBuffer &buffer, CUtlVector<CUtlString> *pVecErrors = NULL );
bool BInitTextBuffer( CUtlBuffer &buffer, CUtlVector<CUtlString> *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<int, CEconItemDefinition*> ItemDefinitionMap_t;
const ItemDefinitionMap_t &GetItemDefinitionMap() const { return m_mapItems; }
typedef CUtlMap<int, CEconItemDefinition*, int> SortedItemDefinitionMap_t;
const SortedItemDefinitionMap_t &GetSortedItemDefinitionMap() const { return m_mapItemsSorted; }
typedef CUtlMap<int, CEconItemDefinition*, int> ToolsItemDefinitionMap_t;
const ToolsItemDefinitionMap_t &GetToolsItemDefinitionMap() const { return m_mapToolsItems; }
typedef CUtlMap<int, CEconItemDefinition*, int> BaseItemDefinitionMap_t;
const BaseItemDefinitionMap_t &GetBaseItemDefinitionMap() const { return m_mapBaseItems; }
typedef CUtlMap<const char*, CEconLootListDefinition *, int> LootListDefinitionMap_t;
const LootListDefinitionMap_t &GetLootLists() const { return m_mapLootLists; }
typedef CUtlMap<int, const char*> RevolvingLootListDefinitionMap_t;
const RevolvingLootListDefinitionMap_t &GetRevolvingLootLists() const { return m_mapRevolvingLootLists; }
typedef CUtlMap<const char*, int> BodygroupStateMap_t;
const BodygroupStateMap_t &GetDefaultBodygroupStateMap() const { return m_mapDefaultBodygroupState; }
typedef CUtlVector<CEconColorDefinition *> ColorDefinitionsList_t;
typedef CUtlMap<const char *, KeyValues *, int> 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<periodic_score_t> PeriodicScoreTypeList_t;
#endif // GC_DLL
#if defined(CLIENT_DLL) || defined(GAME_DLL)
CEconItemDefinition *GetDefaultItemDefinition() { return m_pDefaultItemDefinition; }
bool SetupPreviewItemDefinition( KeyValues *pKV );
#endif
const CUtlMap<int, CEconItemQualityDefinition, int > &GetQualityDefinitionMap() const { return m_mapQualities; }
const CUtlMap<int, CEconItemAttributeDefinition, int > &GetAttributeDefinitionMap() const { return m_mapAttributes; }
typedef CUtlMap<int, CEconCraftingRecipeDefinition*, int > RecipeDefinitionMap_t;
const RecipeDefinitionMap_t &GetRecipeDefinitionMap() const { return m_mapRecipes; }
typedef CUtlMap<const char*, CEconItemSetDefinition*, int > ItemSetMap_t;
const ItemSetMap_t &GetItemSets() const { return m_mapItemSets; }
typedef CUtlMap<const char*, CEconItemCollectionDefinition*, int > 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<const char*, CEconItemPaintKitDefinition*, int > ItemPaintKitMap_t;
const ItemPaintKitMap_t &GetItemPaintKits() const { return m_mapItemPaintKits; }
typedef CUtlMap<const char*, CEconOperationDefinition*, int > 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<int, CQuestObjectiveDefinition*, int >& 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<EquipRegion> 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<int, attachedparticlesystem_t > 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<attr_type_t>& GetAttributeTypes() const { return m_vecAttributeTypes; }
const ISchemaAttributeType *GetAttributeType( const char *pszAttrTypeName ) const;
const LevelBlockDict_t& GetItemLevelingDataDict() const { return m_vecItemLevelingData; }
const CUtlVector<CItemLevelingDefinition> *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<econ_tag_handle_t> 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<CUtlString> *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<CUtlString> *pVecErrors );
bool BInsertLootlist( const char *pListName, KeyValues *pKVLootList, CUtlVector<CUtlString> *pVecErrors );
#ifdef GC_DLL
void PerformCaseBehaviorCheck();
#endif
protected:
virtual void Reset( void );
virtual bool BInitSchema( KeyValues *pKVRawDefinition, CUtlVector<CUtlString> *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<CUtlString> *pVecErrors );
bool BInitAttributeTypes( CUtlVector<CUtlString> *pVecErrors );
#ifdef GC_DLL
bool BInitPeriodicScoring( KeyValues *pKVGameInfo, CUtlVector<CUtlString> *pVecErrors );
#endif // GC_DLL
bool BInitDefinitionPrefabs( KeyValues *pKVPrefabs, CUtlVector<CUtlString> *pVecErrors );
bool BInitItemSeries( KeyValues *pKVSeries, CUtlVector<CUtlString> *pVecErrors );
bool BVerifyBaseItemNames( CUtlVector<CUtlString> *pVecErrors );
bool BInitRarities( KeyValues *pKVRarities, KeyValues *pKVRarityWeights, CUtlVector<CUtlString> *pVecErrors );
bool BInitQualities( KeyValues *pKVAttributes, CUtlVector<CUtlString> *pVecErrors );
bool BInitColors( KeyValues *pKVColors, CUtlVector<CUtlString> *pVecErrors );
bool BInitAttributes( KeyValues *pKVAttributes, CUtlVector<CUtlString> *pVecErrors );
bool BInitEquipRegions( KeyValues *pKVEquipRegions, CUtlVector<CUtlString> *pVecErrors );
bool BInitEquipRegionConflicts( KeyValues *pKVEquipRegions, CUtlVector<CUtlString> *pVecErrors );
bool BInitItems( KeyValues *pKVAttributes, CUtlVector<CUtlString> *pVecErrors );
bool BInitItemSets( KeyValues *pKVItemSets, CUtlVector<CUtlString> *pVecErrors );
bool BInitTimedRewards( KeyValues *pKVTimeRewards, CUtlVector<CUtlString> *pVecErrors );
bool BInitAchievementRewards( KeyValues *pKVTimeRewards, CUtlVector<CUtlString> *pVecErrors );
#ifdef GC_DLL
bool BInitRandomAttributeTemplates( KeyValues *pKVRandomAttributeTemplates, CUtlVector<CUtlString> *pVecErrors );
#endif // GC_DLL
bool BInitRecipes( KeyValues *pKVRecipes, CUtlVector<CUtlString> *pVecErrors );
bool BInitLootLists( KeyValues *pKVLootLists, CUtlVector<CUtlString> *pVecErrors );
bool BInitRevolvingLootLists( KeyValues *pKVRevolvingLootLists, CUtlVector<CUtlString> *pVecErrors );
bool BInitItemCollections( KeyValues *pKVItemSets, CUtlVector<CUtlString> *pVecErrors );
bool BInitCollectionReferences( CUtlVector<CUtlString> *pVecErrors );
bool BInitItemPaintKitDefinitions( KeyValues *pKVPaintKits, CUtlVector<CUtlString> *pVecErrors );
bool BInitOperationDefinitions( KeyValues *pKVGameInfo, KeyValues *pOperations, CUtlVector<CUtlString> *pVecErrors );
#ifdef TF_CLIENT_DLL
bool BInitConcreteItemCounts( CUtlVector<CUtlString> *pVecErrors );
bool BInitSteamPackageLocalizationToken( KeyValues *pKVSteamPackages, CUtlVector<CUtlString> *pVecErrors );
#endif // TF_CLIENT_DLL
bool BInitItemLevels( KeyValues *pKVItemLevels, CUtlVector<CUtlString> *pVecErrors );
bool BInitKillEaterScoreTypes( KeyValues *pKVItemLevels, CUtlVector<CUtlString> *pVecErrors );
bool BInitStringTables( KeyValues *pKVStringTables, CUtlVector<CUtlString> *pVecErrors );
bool BInitCommunityMarketRemaps( KeyValues *pKVCommunityMarketRemaps, CUtlVector<CUtlString> *pVecErrors );
bool BPostSchemaInit( CUtlVector<CUtlString> *pVecErrors ) const;
bool BInitAttributeControlledParticleSystems( KeyValues *pKVParticleSystems, CUtlVector<CUtlString> *pVecErrors );
#if defined(CLIENT_DLL) || defined(GAME_DLL)
bool BInitArmoryData( KeyValues *pKVArmoryData, CUtlVector<CUtlString> *pVecErrors );
#else
bool BInitExperiements( KeyValues *pKVExperiments, CUtlVector<CUtlString> *pVecErrors );
bool BInitForeignImports( CUtlVector<CUtlString> *pVecErrors );
CForeignAppImports *FindOrAddAppImports( AppId_t unAppID );
#endif
bool BVerifyLootListItemDropDates( const CEconLootListDefinition* pLootList, CUtlVector<CUtlString> *pVecErrors ) const;
bool BRecurseiveVerifyLootListItemDropDates( const CEconLootListDefinition* pLootList, const CEconLootListDefinition* pRootLootList, CUtlVector<CUtlString> *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<attr_type_t> m_vecAttributeTypes;
// Contains the list of rarity definitions
CUtlMap<int, CEconItemSeriesDefinition, int > m_mapItemSeries;
// Contains the list of rarity definitions
CUtlMap<int, CEconItemRarityDefinition, int > m_mapRarities;
// Contains the list of item definitions read in from all data files.
CUtlMap<int, CEconItemQualityDefinition, int > m_mapQualities;
// Contains the list of item definitions read in from all data files.
ItemDefinitionMap_t m_mapItems;
CUtlMap<int, CQuestObjectiveDefinition*, int > 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<int, CEconItemAttributeDefinition, int > 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<int, const char*> m_mapRevolvingLootLists;
// Contains the list of loot lists.
LootListDefinitionMap_t m_mapLootLists;
// List of events that award items based on time played
CUtlVector<CTimedItemRewardDefinition> 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<int, attachedparticlesystem_t > 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<const T *>( *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<CEconColorDefinition>::GetTypedRef( void ) const
{
return GEconItemSchema().GetColorDefinitionByName( m_szName );
}
template < >
inline const CEconItemAttributeDefinition *CSchemaFieldHandle<CEconItemAttributeDefinition>::GetTypedRef( void ) const
{
return GEconItemSchema().GetAttributeDefinitionByName( m_szName );
}
template < >
inline const CEconItemDefinition *CSchemaFieldHandle<CEconItemDefinition>::GetTypedRef( void ) const
{
return GEconItemSchema().GetItemDefinitionByName( m_szName );
}
template < >
inline const CEconLootListDefinition *CSchemaFieldHandle<CEconLootListDefinition>::GetTypedRef( void ) const
{
return GEconItemSchema().GetLootListByName( m_szName );
}
template < >
inline const attachedparticlesystem_t *CSchemaFieldHandle<attachedparticlesystem_t>::GetTypedRef( void ) const
{
return GEconItemSchema().FindAttributeControlledParticleSystem( m_szName );
}
typedef CSchemaFieldHandle<CEconColorDefinition> CSchemaColorDefHandle;
typedef CSchemaFieldHandle<CEconItemAttributeDefinition> CSchemaAttributeDefHandle;
typedef CSchemaFieldHandle<CEconItemDefinition> CSchemaItemDefHandle;
typedef CSchemaFieldHandle<CEconLootListDefinition> CSchemaLootListDefHandle;
typedef CSchemaFieldHandle<attachedparticlesystem_t> 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<const char *>& vecValueStrings, bool bDontAssert = false );
#ifdef GC_DLL
// Global econ-level helper functionality.
EUniverse GetUniverse();
bool BYieldingGetChangedItemDefinitions( int iComparisonColumn, CUtlVector<item_definition_index_t>& 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<CEconItem *> *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