diff options
Diffstat (limited to 'game/shared/tf/tf_item_schema.h')
| -rw-r--r-- | game/shared/tf/tf_item_schema.h | 946 |
1 files changed, 946 insertions, 0 deletions
diff --git a/game/shared/tf/tf_item_schema.h b/game/shared/tf/tf_item_schema.h new file mode 100644 index 0000000..cf993ce --- /dev/null +++ b/game/shared/tf/tf_item_schema.h @@ -0,0 +1,946 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + + +#ifndef TFITEMSCHEMA_H +#define TFITEMSCHEMA_H +#ifdef _WIN32 +#pragma once +#endif + +#include "econ_item_schema.h" +#include "tf_item_constants.h" +#include "tf_shareddefs.h" +#include "tf_matchmaking_shared.h" + +#ifndef GC_DLL +#include "util_shared.h" +#endif + +const int k_iMvmMissionIndex_Any = -1; +const int k_iMvmMissionIndex_NotInSchema = -2; + +//#ifndef STAGING_ONLY +#define USE_MVM_TOUR 1 +//#endif // !STAGING_ONLY + +const int k_iMvmTourIndex_Empty = -1; // empty tour name +const int k_iMvmTourIndex_NotInSchema = -2; +const int k_iMvmTourIndex_NotMannedUp = -3; // special value used when asking for the selected tour when not manned up + +const uint32 k_unMvMMaxPointsPerBadgeLevel = 3; // require 3 missions to level up a badge + +class CRandomChanceString +{ +public: + CRandomChanceString(); + + void AddString( const char *pszString, int nChance ); + const char *GetRandomString() const; + +private: + CUtlVector< std::pair< const char *, int > > m_vecChoices; + int m_unTotalChance; +}; + +class CTFTauntInfo +{ +public: + CTFTauntInfo(); + + bool BInitFromKV( KeyValues *pKV, CUtlVector<CUtlString> *pVecErrors ); + + int GetIntroSceneCount( int iClass ) const { Assert( iClass >= 0 && iClass < LOADOUT_COUNT ); return m_vecIntroScenes[iClass].Count(); } + const char *GetIntroScene( int iClass, int iSceneIndex ) const + { + Assert( iSceneIndex >= 0 && iSceneIndex < GetIntroSceneCount( iClass ) ); + return m_vecIntroScenes[iClass][iSceneIndex]; + } + + int GetOutroSceneCount( int iClass ) const { Assert( iClass >= 0 && iClass < LOADOUT_COUNT ); return m_vecOutroScenes[iClass].Count(); } + const char *GetOutroScene( int iClass, int iSceneIndex ) const + { + Assert( iSceneIndex >= 0 && iSceneIndex < GetOutroSceneCount( iClass ) ); + return m_vecOutroScenes[iClass][iSceneIndex]; + } + + int GetPartnerTauntInitiatorSceneCount( int iClass ) const { Assert( iClass >= 0 && iClass < LOADOUT_COUNT ); return m_vecPartnerTauntInitiatorScenes[iClass].Count(); } + const char *GetPartnerTauntInitiatorScene( int iClass, int iSceneIndex ) const + { + Assert( iSceneIndex >= 0 && iSceneIndex < GetPartnerTauntInitiatorSceneCount( iClass ) ); + return m_vecPartnerTauntInitiatorScenes[iClass][iSceneIndex]; + } + + int GetPartnerTauntReceiverSceneCount( int iClass ) const { Assert( iClass >= 0 && iClass < LOADOUT_COUNT ); return m_vecPartnerTauntReceiverScenes[iClass].Count(); } + const char *GetPartnerTauntReceiverScene( int iClass, int iSceneIndex ) const + { + Assert( iSceneIndex >= 0 && iSceneIndex < GetPartnerTauntReceiverSceneCount( iClass ) ); + return m_vecPartnerTauntReceiverScenes[iClass][iSceneIndex]; + } + + const char *GetProp( int iClass ) const { Assert( iClass >= 0 && iClass < LOADOUT_COUNT ); return m_pszProp[iClass]; } + const char *GetPropIntroScene( int iClass ) const { Assert( iClass >= 0 && iClass < LOADOUT_COUNT ); return m_pszPropIntroScene[iClass]; } + const char *GetPropOutroScene( int iClass ) const { Assert( iClass >= 0 && iClass < LOADOUT_COUNT ); return m_pszPropOutroScene[iClass]; } + + float GetTauntSeparationForwardDistance() const { return m_flTauntSeparationForwardDistance; } + float GetTauntSeparationRightDistance() const { return m_flTauntSeparationRightDistance; } + float GetMinTauntTime() const { return m_flMinTauntTime; } + + bool IsPartnerTaunt() const { return m_bIsPartnerTaunt; } + bool ShouldStopTauntIfMoved() const { return m_bStopTauntIfMoved; } + + int GetFOV() const { return m_nFOV; } + float GetCameraDist() const { return m_flCameraDist; } + float GetCameraDistUp() const { return m_flCameraDistUp; } + + const char *GetParticleAttachment() const { return m_pszParticleAttachment; } + + struct TauntInputRemap_t + { + TauntInputRemap_t() + { + m_iButton = 0; + } + int m_iButton; + CUtlVector< const char* > m_vecButtonPressedScenes[LOADOUT_COUNT]; + CUtlVector< const char* > m_vecButtonReleasedScenes[LOADOUT_COUNT]; + }; + int GetTauntInputRemapCount() const { return m_vecTauntInputRemap.Count(); } + const TauntInputRemap_t &GetTauntInputRemapScene( int iButtonIndex ) const + { + return m_vecTauntInputRemap[iButtonIndex]; + } + +private: + + bool InitTauntInputRemap( KeyValues *pKV, CUtlVector<CUtlString> *pVecErrors ); + + CUtlVector< const char* > m_vecIntroScenes[LOADOUT_COUNT]; + CUtlVector< const char* > m_vecOutroScenes[LOADOUT_COUNT]; + CUtlVector< const char* > m_vecPartnerTauntInitiatorScenes[LOADOUT_COUNT]; + CUtlVector< const char* > m_vecPartnerTauntReceiverScenes[LOADOUT_COUNT]; + CUtlVector< TauntInputRemap_t > m_vecTauntInputRemap; + const char *m_pszProp[LOADOUT_COUNT]; + const char *m_pszPropIntroScene[LOADOUT_COUNT]; + const char *m_pszPropOutroScene[LOADOUT_COUNT]; + const char *m_pszParticleAttachment; + float m_flTauntSeparationForwardDistance; + float m_flTauntSeparationRightDistance; + float m_flMinTauntTime; + bool m_bIsPartnerTaunt; + bool m_bStopTauntIfMoved; + + int m_nFOV; + float m_flCameraDist; + float m_flCameraDistUp; +}; + +class CQuestThemeDefinition +{ +public: + + CQuestThemeDefinition( void ); + virtual ~CQuestThemeDefinition( void ); + + bool BInitFromKV( KeyValues *pKVItem, CUtlVector<CUtlString> *pVecErrors = NULL ); + + const char *GetName() const { return m_pszName; } + + const char *GetNotificationResFile() const { return m_pszNotificationRes; } + const char *GetQuestItemResFile() const { return m_pszQuestItemRes; } + const char *GetInGameTrackerResFile() const { return m_pszInGameTrackerRes; } + unacknowledged_item_inventory_positions_t GetUnackPos() const { return m_eUnackPos; } + +#ifndef GC_DLL + const char *GetGiveSoundForClass( int iClass ) const { return UTIL_GetRandomSoundFromEntry( m_vecGiveStrings[ iClass ].GetRandomString() ); } + const char *GetCompleteSoundForClass( int iClass ) const { return UTIL_GetRandomSoundFromEntry( m_vecCompleteStrings[ iClass ].GetRandomString() ); } + const char *GetFullyCompleteSoundForClass( int iClass ) const { return UTIL_GetRandomSoundFromEntry( m_vecFullyCompleteStrings[ iClass ].GetRandomString() ); } + const char *GetDiscardSound() const { return UTIL_GetRandomSoundFromEntry( m_pszDiscardString ); } + const char *GetRewardSound() const { return UTIL_GetRandomSoundFromEntry( m_pszRewardString ); } + const char *GetRevealSound() const { return UTIL_GetRandomSoundFromEntry( m_pszOnRevealText ); } +#endif + +private: + + KeyValues *m_pRawKVs; + + const char *m_pszName; + + // UI + const char* m_pszNotificationRes; + const char* m_pszQuestItemRes; + const char* m_pszInGameTrackerRes; + unacknowledged_item_inventory_positions_t m_eUnackPos; + + // Sounds + CRandomChanceString m_vecGiveStrings[LOADOUT_COUNT]; // Per class + CRandomChanceString m_vecCompleteStrings[LOADOUT_COUNT]; // Per class + CRandomChanceString m_vecFullyCompleteStrings[LOADOUT_COUNT]; // Per class + const char* m_pszRewardString; + const char* m_pszDiscardString; + const char* m_pszOnRevealText; +}; + +typedef CUtlVector< const class CTFQuestObjectiveDefinition* > QuestObjectiveDefVec_t; +typedef CUtlVector< const char * > QuestDescriptionVec_t; +typedef CUtlVector< const char * > QuestNameVec_t; + +//----------------------------------------------------------------------------- +// CTFRequiredQuestItemsSet +//----------------------------------------------------------------------------- +class CTFRequiredQuestItemsSet +{ +public: + CTFRequiredQuestItemsSet( void ) {} + + bool BInitFromKV( KeyValues *pKV, CUtlVector<CUtlString> *pVecErrors = NULL ); + bool BPostInit( CUtlVector<CUtlString> *pVecErrors = NULL ); + + bool OwnsRequiredItems( const CUtlVector< item_definition_index_t >& vecOwnedItemDefs ) const; + const item_definition_index_t& GetLoanerItemDef() const { return m_LoanerItemDef; } + +private: + CUtlVector< item_definition_index_t > m_vecQualifyingItemDefs; + item_definition_index_t m_LoanerItemDef; +}; + +//----------------------------------------------------------------------------- +// CQuestDefinition +//----------------------------------------------------------------------------- +class CQuestDefinition +{ +public: + + CQuestDefinition( void ); + + bool BInitFromKV( KeyValues *pKVItem, CUtlVector<CUtlString> *pVecErrors = NULL ); + + uint32 GetMaxStandardPoints() const { return m_nMaxStandardPoints; } + uint32 GetMaxBonusPoints() const { return m_nMaxBonusPoints; } + const char *GetRewardLootlistName() const { return m_pszRewardLootlistName; } + const char *GetQuickplayMapName() const { return m_pszQuickplayMapName; } + + const char *GetMatchmakingGroupName() const { return m_strMatchmakingGroupName.Get(); } + const char *GetMatchmakingCategoryName() const { return m_strMatchmakingCategoryName.Get(); } + const char *GetMatchmakingMapName() const { return m_strMatchmakingMapName.Get(); } + + const QuestObjectiveDefVec_t& GetObjectives() const { return m_vecObjectiveDefinitions; } + void GetRolledObjectivesForItem( QuestObjectiveDefVec_t& vecRolledObjectives, const CEconItem* pItem ) const; + const CQuestThemeDefinition *GetQuestTheme() const; + const char *GetRolledDescriptionForItem( const CEconItem* pItem ) const; + const char *GetRolledNameForItem( const CEconItem* pItem ) const; + const char *GetCorrespondingOperationName() const { return m_pszCorrespondingOperationName; } + + const CUtlVector< CTFRequiredQuestItemsSet >& GetRequiredItemSets() const { return m_vecRequiredItemSets; } + +private: + + QuestObjectiveDefVec_t m_vecObjectiveDefinitions; + uint32 m_nMaxStandardPoints; + uint32 m_nMaxBonusPoints; + const char *m_pszRewardLootlistName; + uint16 m_nNumObjectivesToRoll; + const char *m_pszQuestThemeName; + const char *m_pszCorrespondingOperationName; + const char *m_pszQuickplayMapName; + + CUtlString m_strMatchmakingGroupName; + CUtlString m_strMatchmakingCategoryName; + CUtlString m_strMatchmakingMapName; + + QuestDescriptionVec_t m_vecQuestDescriptions; + QuestNameVec_t m_vecQuestNames; + CEconItemDefinition *m_pOperationBadgeDef; + + // loaner items for this quest + CUtlVector< CTFRequiredQuestItemsSet > m_vecRequiredItemSets; +}; + +//----------------------------------------------------------------------------- +// Wars +//----------------------------------------------------------------------------- +class CWarDefinition +{ +public: + + CWarDefinition(); + + bool BInitFromKV( KeyValues *pKV, CUtlVector<CUtlString> *pVecErrors ); + + struct CWarSideDefinition_t + { + CWarSideDefinition_t() + : m_pszLeaderboardName( NULL ) + , m_pszLocalizedName( NULL ) + , m_nSideIndex( INVALID_WAR_SIDE ) + {} + + bool BInitFromKV( const char* pszContainingWarName, KeyValues *pKVSide, CUtlVector<CUtlString> *pVecErrors ); + + const char* m_pszLocalizedName; + const char* m_pszLeaderboardName; + war_side_t m_nSideIndex; + }; + typedef CUtlMap< war_side_t, CWarSideDefinition_t > SidesMap_t; + + const SidesMap_t& GetSides() const { return m_mapSides; } + const CWarSideDefinition_t* GetSide( war_side_t nSide ) const; + war_definition_index_t GetDefIndex() const { return m_nDefIndex; } + const char* GetDefName() const { return m_pszDefName; } + bool IsActive() const; + bool IsValidSide( war_side_t nSide ) const; + RTime32 GetStartDate() const { return m_rtTimeStart; } + RTime32 GetEndDate() const { return m_rtTimeEnd; } +private: + + const char* m_pszLocalizedWarname; + const char* m_pszDefName; + SidesMap_t m_mapSides; + RTime32 m_rtTimeStart; + RTime32 m_rtTimeEnd; + war_definition_index_t m_nDefIndex; +}; +typedef CUtlMap< war_definition_index_t, CWarDefinition* > WarDefinitionMap_t; + +const char *GetPlayerClassName( int iClass ); +const char *GetPlayerClassLocalizationKey( int iClass ); +itemid_t GetAssociatedQuestItemID( const IEconItemInterface *pEconItem ); + +class CTFItemDefinition : public CEconItemDefinition +{ +public: + + CTFItemDefinition() + { + InternalInitialize(); + } + + ~CTFItemDefinition() + { + if ( m_pTauntData ) + { + delete m_pTauntData; + m_pTauntData = NULL; + } + } + + // CEconItemDefinition interface. + virtual bool BInitFromKV( KeyValues *pKVItem, CUtlVector<CUtlString> *pVecErrors = NULL ) OVERRIDE; +#if defined(CLIENT_DLL) || defined(GAME_DLL) + virtual bool BInitFromTestItemKVs( int iNewDefIndex, KeyValues *pKVItem, CUtlVector<CUtlString>* pVecErrors = NULL ) OVERRIDE; + virtual void CopyPolymorphic( const CEconItemDefinition *pSourceDef ); + virtual void GeneratePrecacheModelStrings( bool bDynamicLoad, CUtlVector<const char *> *out_pVecModelStrings ) const; +#endif // defined(CLIENT_DLL) || defined(GAME_DLL) + + int GetAnimSlot( void ) const { return m_iAnimationSlot; } + + // Class & Slot handling + int GetDefaultLoadoutSlot( void ) const { return m_iDefaultLoadoutSlot; } + int GetAccountLoadoutSlot( void ) const { return m_iDefaultLoadoutSlot; } + const CBitVec<LOADOUT_COUNT> *GetClassUsability( void ) const { return &m_vbClassUsability; } + void FilloutSlotUsage( CBitVec<LOADOUT_COUNT> *pBV ) const; + bool CanBeUsedByClass( int iClass ) const { return iClass == GEconItemSchema().GetAccountIndex() ? m_eEquipType == EQUIP_TYPE_ACCOUNT : m_vbClassUsability.IsBitSet( iClass ); } + bool CanBeUsedByAllClasses( void ) const; + EEquipType_t GetEquipType( void ) const { return m_eEquipType; } + bool CanBePlacedInSlot( int nSlot ) const; + const char *GetPlayerDisplayModel( int iClass ) const { Assert( iClass >= 0 && iClass < LOADOUT_COUNT ); return m_pszPlayerDisplayModel[iClass]; } + virtual const char *GetPlayerDisplayModelAlt( int iClass = 0 ) const { Assert( iClass >= 0 && iClass < LOADOUT_COUNT ); return m_pszPlayerDisplayModelAlt[iClass]; } + + int GetLoadoutSlot( int iLoadoutClass ) const; +#ifndef GC_DLL + bool IsAWearable() const; + bool IsContentStreamable() const; + const char* GetAdTextToken() const { return m_pszAdText; } + const char* GetAdResFile() const { return m_pszAdResFile; } +#endif // !GC_DLL + + CTFTauntInfo *GetTauntData() const { return m_pTauntData; } + + const CQuestDefinition *GetQuestDef() const { return m_pQuestData; } + + KeyValues *GetPaintKitWearDefinition( int nWear ) const; + const char *GetPaintKitName( ) const; + +#ifdef CLIENT_DLL + bool HasDetailedIcon() const { return m_bHasDetailedIcon; } +#endif // CLIENT_DLL + +private: + void InternalInitialize(); + + // The load-out slot that this item can be placed into. + int m_iDefaultLoadoutSlot; + int m_iAnimationSlot; + + // taunt item data + CTFTauntInfo *m_pTauntData; + + // Quest data + CQuestDefinition *m_pQuestData; + + // The .mdl file used for this item when it's being carried by a player. + const char *m_pszPlayerDisplayModel[LOADOUT_COUNT]; + const char *m_pszPlayerDisplayModelAlt[LOADOUT_COUNT]; + +#ifndef GC_DLL + const char* m_pszAdText; + const char* m_pszAdResFile; +#endif + + // Specifies which class can use this item. + CBitVec<LOADOUT_COUNT> m_vbClassUsability; + int m_iLoadoutSlots[LOADOUT_COUNT]; // Slot that each class places the item into. + EEquipType_t m_eEquipType; + +#ifdef CLIENT_DLL + bool m_bHasDetailedIcon; +#endif // CLIENT_DLL +}; + +class CTFStyleInfo : public CEconStyleInfo +{ +public: + CTFStyleInfo() + { + for ( int i = 0; i < ARRAYSIZE( m_pszPlayerDisplayModel ); i++ ) + { + for ( int j = 0; j < ARRAYSIZE( m_pszPlayerDisplayModel[i] ); j++ ) + { + m_pszPlayerDisplayModel[i][j] = NULL; + } + } + } + + virtual void BInitFromKV( KeyValues *pKVItem, CUtlVector<CUtlString> *pVecErrors ) OVERRIDE; +#if defined(CLIENT_DLL) || defined(GAME_DLL) + virtual void GeneratePrecacheModelStringsForStyle( CUtlVector<const char *> *out_pVecModelStrings ) const OVERRIDE; +#endif + + const char *GetPlayerDisplayModel( int iClass, int iTeam ) const; + +private: + // The .mdl file used for this item when it's being carried by a player. + const char *m_pszPlayerDisplayModel[2][LOADOUT_COUNT]; +}; + +class CTFCraftingRecipeDefinition : public CEconCraftingRecipeDefinition +{ +public: + virtual bool ItemListMatchesInputs( CUtlVector<CEconItem*> *vecCraftingItems, KeyValues *out_pkvCraftParams, bool bIgnoreSlop, CUtlVector<uint64> *vecChosenItems ) const OVERRIDE; + + // A client function for testing to see if the contents of the player's backpack can match against this recipe. + // Broken out into a separate function so we don't run the risk of its thorny logic introducing bugs into the backend crafting logic. + bool CanMatchAgainstBackpack( CUtlVector<CEconItem*> *vecAllItems, CUtlVector<CEconItem*> vecItemsByClass[LOADOUT_COUNT], CUtlVector<CEconItem*> vecItemsBySlot[ CLASS_LOADOUT_POSITION_COUNT ], CUtlVector<uint64> *vecChosenItems ) const; + +private: + bool CheckSubItemListAgainstBackpack( CUtlVector<CEconItem*> *vecCraftingItems, CUtlVector<uint64> *vecChosenItems ) const; +}; + +typedef uint32 ObjectiveConditionDefIndex_t; +const ObjectiveConditionDefIndex_t INVALID_QUEST_OBJECTIVE_CONDITIONS_INDEX = ObjectiveConditionDefIndex_t(-1); + +//----------------------------------------------------------------------------- +// CTFQuestObjectiveConditionsDefinition +// These contain the actual logic that can be used by multiple objectives. +//----------------------------------------------------------------------------- +class CTFQuestObjectiveConditionsDefinition +{ +public: + CTFQuestObjectiveConditionsDefinition( void ); + virtual ~CTFQuestObjectiveConditionsDefinition( void ); + + virtual bool BInitFromKV( KeyValues *pKVItem, CUtlVector<CUtlString> *pVecErrors = NULL ); + bool BPostInit( CUtlVector<CUtlString> *pVecErrors = NULL ); + + ObjectiveConditionDefIndex_t GetDefIndex() const { return m_nDefIndex; } +#ifndef GC_DLL + KeyValues *GetKeyValues() const { return m_pConditionsKey; } +#endif + + const CUtlVector< CTFRequiredQuestItemsSet >& GetRequiredItemSets() const { return m_vecRequiredItemSets; } + +private: + ObjectiveConditionDefIndex_t m_nDefIndex; +#ifndef GC_DLL + KeyValues *m_pConditionsKey; +#endif + + CUtlVector< CTFRequiredQuestItemsSet > m_vecRequiredItemSets; +}; + + +//----------------------------------------------------------------------------- +// CQuestObjectiveDefinition +//----------------------------------------------------------------------------- +class CTFQuestObjectiveDefinition : public CQuestObjectiveDefinition +{ +public: + + CTFQuestObjectiveDefinition( void ); + virtual ~CTFQuestObjectiveDefinition( void ); + + virtual bool BInitFromKV( KeyValues *pKVItem, CUtlVector<CUtlString> *pVecErrors = NULL ) OVERRIDE; + +#ifndef GC_DLL + KeyValues *GetConditionsKeyValues() const; +#endif + const CTFQuestObjectiveConditionsDefinition* GetConditions() const; + +private: + ObjectiveConditionDefIndex_t m_nConditionDefIndex; +}; + + +//----------------------------------------------------------------------------- +// MvMMap_t +//----------------------------------------------------------------------------- +struct MvMMap_t +{ + CUtlConstString m_sMap; // name of the map file + CUtlConstString m_sDisplayName; // Localization tag starting with '#' + CUtlVector<int> m_vecMissions; // indexes into the schema's challenge list +}; + +enum EMvMChallengeDifficulty +{ + k_EMvMChallengeDifficulty_Invalid = -1, + k_EMvMChallengeDifficulty_Normal = 1, + k_EMvMChallengeDifficulty_Intermediate = 2, + k_EMvMChallengeDifficulty_Advanced = 3, + k_EMvMChallengeDifficulty_Expert = 4, + k_EMvMChallengeDifficulty_Haunted = 5, + + k_EMvMChallengeDifficultyFirstValid = k_EMvMChallengeDifficulty_Normal, + k_EMvMChallengeDifficultyLastValid = k_EMvMChallengeDifficulty_Haunted +}; + +extern EMvMChallengeDifficulty GetMvMChallengeDifficultyByInternalName( const char *pszEnglishID ); +extern const char *GetMvMChallengeDifficultyLocName( EMvMChallengeDifficulty eDifficulty ); + +//----------------------------------------------------------------------------- +// MvMMission_t +//----------------------------------------------------------------------------- +struct MvMMission_t +{ + int m_iDisplayMapIndex; // Index into the schema's map list, for UI purposes + CUtlConstString m_sPop; // name of the pop file + CUtlConstString m_sDisplayName; // Localization tag starting with '#' + CUtlConstString m_sMode; // Localization tag starting with '#' + CUtlConstString m_sMapNameActual; // name of the map file to really load + EMvMChallengeDifficulty m_eDifficulty; + uint32 m_unMannUpPoints; // points for completing mission +}; + +//----------------------------------------------------------------------------- +// MvMTour_t +//----------------------------------------------------------------------------- +struct MvMTourMission_t +{ + int m_iMissionIndex; // index to the schema's challenge list + int m_iBadgeSlot; // *index* (0...31) of the slot on the badge. -1 if not assigned a slot. (No bragging rights for this challenge.) +}; + +struct MvMTour_t +{ + CUtlConstString m_sTourInternalName; + CUtlConstString m_sTourNameLocalizationToken; // Localization tag starting with '#', shown to clients + CUtlConstString m_sLootImageName; + const CEconItemDefinition *m_pBadgeItemDef; // can be NULL if there is no badge reward. Implies all badge slots will be -1. Only really valid for practice tours. +#ifdef GC + const CEconLootListDefinition *m_pMissionCompleteLootList; // can be NULL, but really only makes sense if there is no badge reward. + const CEconLootListDefinition *m_pTourCompleteLootList; // can be NULL, but really only makes sense if there is no badge reward. +#endif + CCopyableUtlVector<MvMTourMission_t> m_vecMissions; // indexes into the schema's challenge list + uint32 m_nAllChallengesBits; + EMvMChallengeDifficulty m_eDifficulty; + bool m_bIsNew; +}; + +//----------------------------------------------------------------------------- +// Maps +//----------------------------------------------------------------------------- + +enum EGameCategory +{ + kGameCategory_Escort = 0, + kGameCategory_CTF, + kGameCategory_AttackDefense, + kGameCategory_Koth, + kGameCategory_CP, + kGameCategory_EscortRace, + kGameCategory_EventMix, + kGameCategory_SD, + kGameCategory_Quickplay, + kGameCategory_Event247, + kGameCategory_Arena, + kGameCategory_RobotDestruction, + kGameCategory_Powerup, + kGameCategory_Featured, + kGameCategory_Passtime, + kGameCategory_Community_Update, + kGameCategory_Misc, + kGameCategory_Competitive_6v6, + kGameCategory_Other, + kGameCategory_Halloween, + + // Note: Don't reorder this list. Only add to the end + + eNumGameCategories, +}; + +typedef uint32 map_identifier_t; + +enum eQuickplayMatchType +{ + kQuickplay_AdvancedUsersOnly, + kQuickplay_AllUsers, // everyone + kQuickplay_Disabled, // no-one + + kQuickplayTypeCount +}; + +enum EMatchmakingGroupType +{ + kMatchmakingType_None = -1, + + kMatchmakingType_SpecialEvents, + kMatchmakingType_Core, + kMatchmakingType_Alternative, + kMatchmakingType_Competitive_6v6, + + kMatchmakingTypeCount +}; + +enum EMatchmakingGameModeRestrictionType +{ + kMatchmakingGameModeRestrictionType_None = -1, + + kMatchmakingGameModeRestrictionType_Holiday, + kMatchmakingGameModeRestrictionType_Operation, + + kMatchmakingGameModeRestrictionTypeCount +}; + +typedef uint32 MapDefIndex_t; + +struct MapDef_t +{ + MapDef_t( const char* pszMapStampDefName ) + : mapStampDef( pszMapStampDefName ) + , m_nStatsIdentifier( (MapDefIndex_t)-1 ) + {} + + CSchemaItemDefHandle mapStampDef; + MapDefIndex_t m_nDefIndex; + const char* pszMapName; + const char* pszMapNameLocKey; + const char* pszAuthorsLocKey; // if set, will be considered a community map in the UI + const char* pszStrangePrefixLocKey; + + // The m_nStatsIdentifier field is used when looking up a map in a user's gamestats. + // It's a relic from the quickplay days and how the maps were defined in the schema back then. + // We've since switched to using a map defindex, which is easier to read and manage, but this + // field still needs to be used to lookup map gamestats because millions of customers + // have these maps identified by those numbers in their gamestats. The old numbers for existing + // maps is already defined in _maps.txt newly defined maps don't need to specify a "statsidentifier" + // field, because they will generate their own unique identifier. + map_identifier_t m_nStatsIdentifier; + map_identifier_t GetStatsIdentifier() const { return m_nStatsIdentifier == -1 ? (m_nDefIndex << 16) : m_nStatsIdentifier; } + bool IsCommunityMap() const { return pszAuthorsLocKey != NULL; } + CUtlVector< EGameCategory > m_vecAssociatedGameCategories; + CUtlVector<econ_tag_handle_t> vecTags; + // The rolling match tags for this map. When a rolling match vote happens, only allow voting on + // maps that have at least one matching tag with this map. + struct WeightedNextMapCandidates_t + { + MapDefIndex_t m_nDefIndex; + float m_flWeight; + }; + CUtlVector< WeightedNextMapCandidates_t > m_vecRollingMatchMaps; + void AddMapAsTargetWithWeight( const WeightedNextMapCandidates_t& target ) + { + FOR_EACH_VEC( m_vecRollingMatchMaps, i ) + { + if ( m_vecRollingMatchMaps[ i ].m_nDefIndex == target.m_nDefIndex ) + { + m_vecRollingMatchMaps[ i ].m_flWeight = Max( m_vecRollingMatchMaps[ i ].m_flWeight, target.m_flWeight ); + return; + } + } + + m_vecRollingMatchMaps.AddToTail( target ); + } + + CUtlVector< econ_tag_handle_t > m_vecRollingMatchTags; + bool BHasRollingMatchTag( econ_tag_handle_t tag ) const + { + FOR_EACH_VEC( m_vecRollingMatchTags, i ) + { + if ( m_vecRollingMatchTags[ i ] == tag ) + return true; + } + + return false; + } + + struct WeightedNextMapTargets_t + { + econ_tag_handle_t m_tag; + float m_flWeight; + }; + CUtlVector< WeightedNextMapTargets_t > m_vecRollingMatchTargets; + +}; + +struct SchemaMMGameModeRestriction_t +{ + SchemaMMGameModeRestriction_t() + { + m_eType = kMatchmakingGameModeRestrictionType_None; + m_nValue = -1; + } + + EMatchmakingGameModeRestrictionType m_eType; + int m_nValue; + CUtlString m_strValue; +}; + +struct SchemaMMGroup_t; +struct SchemaGameCategory_t +{ + SchemaGameCategory_t() + : m_eGameCategory( eNumGameCategories ) + , m_pszLocalizedName( NULL ) + , m_pMMGroup( NULL ) + , m_pszLocalizedDesc( NULL ) + , m_pszListImage( NULL ) + {} + + SchemaGameCategory_t( const SchemaGameCategory_t& other ) + { + m_eGameCategory = other.m_eGameCategory; + m_pMMGroup = other.m_pMMGroup; + m_pszLocalizedName = other.m_pszLocalizedName; + m_pszLocalizedDesc = other.m_pszLocalizedDesc; + m_pszListImage = other.m_pszListImage; + m_vecMaps.Purge(); + m_vecMaps.CopyArray( other.m_vecMaps.Base(), other.m_vecMaps.Count() ); + m_vecRestrictions.Purge(); + m_vecRestrictions.CopyArray( other.m_vecRestrictions.Base(), other.m_vecRestrictions.Count() ); + } + + ~SchemaGameCategory_t() + {} + + void AddMap( const MapDef_t *pMap, bool bEnabled ) + { + if ( !pMap ) + return; + + m_vecMaps.AddToTail( pMap ); + + if ( bEnabled ) + { + m_vecEnabledMaps.AddToTail( pMap ); + } + } + + const MapDef_t *GetRandomMap( void ) const + { + Assert( m_vecEnabledMaps.Count() ); + return m_vecEnabledMaps[RandomInt( 0, m_vecEnabledMaps.Count() - 1 )]; + } + + bool PassesRestrictions() const; + + //void SerializeToKVs( KeyValues* pKV ); + + EGameCategory m_eGameCategory; + const SchemaMMGroup_t* m_pMMGroup; + const char* m_pszName; + const char* m_pszLocalizedName; + const char* m_pszLocalizedDesc; + const char* m_pszListImage; + const char* m_pszMMType; + CUtlVector< const MapDef_t* > m_vecEnabledMaps; + CUtlVector< SchemaMMGameModeRestriction_t > m_vecRestrictions; + CUtlVector< const MapDef_t* > m_vecMaps; +}; +typedef CUtlMap< EGameCategory, SchemaGameCategory_t* > GameCategoryMap_t; + +struct SchemaMMGroup_t +{ + SchemaMMGroup_t() + : m_eMMGroup( kMatchmakingType_None ) + , m_pszLocalizedName( NULL ) + , m_nMaxExcludes( 0 ) + {} + + SchemaMMGroup_t( const SchemaMMGroup_t& other ) + { + m_eMMGroup = other.m_eMMGroup; + m_pszLocalizedName = other.m_pszLocalizedName; + m_nMaxExcludes = other.m_nMaxExcludes; + m_vecModes.Purge(); + m_vecModes.CopyArray( other.m_vecModes.Base(), other.m_vecModes.Count() ); + } + + bool IsCategoryValid() const; + + ~SchemaMMGroup_t() + {} + + EMatchmakingGroupType m_eMMGroup; + const char* m_pszName; + const char* m_pszLocalizedName; + int m_nMaxExcludes; + CBitVec<k_nMatchGroup_Count> m_bitsValidMMGroups; + CUtlVector< const SchemaGameCategory_t* > m_vecModes; +}; +typedef CUtlMap< EMatchmakingGroupType, SchemaMMGroup_t* > MMGroupMap_t; + + +//----------------------------------------------------------------------------- +// CTFItemSchema +//----------------------------------------------------------------------------- +class CTFItemSchema : public CEconItemSchema +{ +public: + CTFItemSchema(); + + virtual void Reset(); + + CTFItemDefinition *GetTFItemDefinition( int iItemIndex ) + { + return (CTFItemDefinition *)GetItemDefinition( iItemIndex ); + } + + CTFCraftingRecipeDefinition *GetTFCraftingRecipeDefinition( int iRecipeIndex ) + { + return (CTFCraftingRecipeDefinition *)GetRecipeDefinition( iRecipeIndex ); + } + + const CQuestThemeDefinition *GetQuestThemeByName( const char *pszDefName ) const; + const CUtlMap<const char*, CQuestThemeDefinition*, int >& GetQuestThemes() const { return m_mapQuestThemes; } + const CTFQuestObjectiveConditionsDefinition* GetQuestObjectiveConditionByDefIndex( ObjectiveConditionDefIndex_t nDefIndex ); + + const CWarDefinition *GetWarDefinitionByIndex( war_definition_index_t nDefIndex ) const; + const CWarDefinition *GetWarDefinitionByName( const char* pszDefName ) const; + const WarDefinitionMap_t& GetWarDefinitions() const { return m_mapWars; } + + const CUtlVector<const char *>& GetClassUsabilityStrings() const { return m_vecClassUsabilityStrings; } + const CUtlVector<const char *>& GetLoadoutStrings( EEquipType_t eType ) const { return eType == EQUIP_TYPE_CLASS ? m_vecClassLoadoutStrings : m_vecAccountLoadoutStrings; } + const CUtlVector<const char *>& GetLoadoutStringsForDisplay( EEquipType_t eType ) const { return eType == EQUIP_TYPE_CLASS ? m_vecClassLoadoutStringsForDisplay : m_vecAccountLoadoutStringsForDisplay; } + const CUtlVector<const char *>& GetWeaponTypeSubstrings() const { return m_vecWeaponTypeSubstrings; } + + static const char k_rchOverrideItemLevelDescStringAttribName[]; + + static const char k_rchMvMTicketItemDefName[]; + static const char k_rchMvMSquadSurplusVoucherItemDefName[]; + static const char k_rchMvMPowerupBottleItemDefName[]; + static const char k_rchMvMChallengeCompletedMaskAttribName[]; + static const char k_rchLadderPassItemDefName[]; + + static const char *GetMvMBadgeContractPointsAttributeName( EMvMChallengeDifficulty difficulty ); + static const char *GetMvMBadgeContractLevelAttributeName( EMvMChallengeDifficulty difficulty ); + + const CUtlVector<MvMMap_t>& GetMvmMaps() const { return m_vecMvMMaps; } + const CUtlVector<MvMMission_t>& GetMvmMissions() const { return m_vecMvMMissions; } + const CUtlVector<MvMTour_t>& GetMvmTours() const { return m_vecMvMTours; } +// + /// Return index into mission list, or one of these special values: + /// k_iMvmMissionIndex_Any if empty string is passed + /// k_iMvmMissionIndex_NotInSchema if not found + /// + /// Input is the full pop filename, but without the directory or extension + int FindMvmMissionByName( const char *pszChallengeName ) const; + + /// Get pop filename (without extension) given the challenge index. + /// Handles k_iMvmMissionIndex_Any and k_iMvmMissionIndex_NotInSchema + const char *GetMvmMissionName( int iChallengeIndex ) const; + + /// Return index into tour list, or one of these special values: + /// k_iMvmTourIndex_Any if empty string is passed + /// k_iMvmTourIndex_NotInSchema if not found + /// + /// Input is the value of MvMTour_t::m_sTourInternalName + int FindMvmTourByName( const char *pszTourName ) const; + + /// Find mission within a particular tour, and return index into MvMTour_t::m_vecMissions. + /// Returns -1 if invalid tour index or mission is not part of the tour + int FindMvmMissionInTour( int idxTour, int idxMissionInSchema ) const; + + /// Get badge slot corresponding to particular mission, for a given tour. + /// Returns bit index MvMTourMission_t::m_iBadgeSlot (NOT BITMASK), or -1 if + /// invalid tour index of mission is not part of the tour + int GetMvmMissionBadgeSlotForTour( int idxTour, int idxMissionInSchema ) const; + + int GetMapCount() const { return m_vecMasterListOfMaps.Count(); } + const MapDef_t *GetMasterMapDefByName( const char *pszSearchName ) const; + const MapDef_t *GetMasterMapDefByIndex( MapDefIndex_t unIndex ) const; + const CUtlVector<MapDef_t*>& GetMasterMapsList() const { return m_vecMasterListOfMaps; } + const GameCategoryMap_t& GetGameCategoryMap() const { return m_mapGameCategories; } + const SchemaGameCategory_t* GetGameCategory( EGameCategory eType ) const; + const MMGroupMap_t& GetMMGroupMap() const { return m_mapMMGroups; } + const SchemaMMGroup_t* GetMMGroup( EMatchmakingGroupType eCat ) const; + +public: + // CEconItemSchema interface. + virtual CEconItemDefinition *CreateEconItemDefinition() { return new CTFItemDefinition; } + virtual CEconCraftingRecipeDefinition *CreateCraftingRecipeDefinition() { return new CTFCraftingRecipeDefinition; } + virtual CEconStyleInfo *CreateEconStyleInfo() { return new CTFStyleInfo; } + virtual CQuestObjectiveDefinition *CreateQuestDefinition() { return new CTFQuestObjectiveDefinition; } + + virtual bool BCanStrangeFilterApplyToStrangeSlotInItem( uint32 /*strange_event_restriction_t*/ unRestrictionType, uint32 unRestrictionValue, const IEconItemInterface *pItem, int iStrangeSlot, uint32 *out_pOptionalScoreType ) const; + + virtual IEconTool *CreateEconToolImpl( const char *pszToolType, const char *pszUseString, const char *pszUsageRestriction, item_capabilities_t unCapabilities, KeyValues *pUsageKV ) OVERRIDE; + + virtual bool BInitSchema( KeyValues *pKVRawDefinition, CUtlVector<CUtlString> *pVecErrors = NULL ); + + virtual RTime32 GetCustomExpirationDate( const char *pszExpirationDate ) const OVERRIDE; + +protected: +#ifdef TF_CLIENT_DLL + virtual int CalculateNumberOfConcreteItems( const CEconItemDefinition *pItemDef ); +#endif // TF_CLIENT_DLL + +private: + void InitializeStringTable( const char **ppStringTable, unsigned int unStringCount, CUtlVector<const char *> *out_pvecStringTable ); + + bool BInitMvmMissions( KeyValues *pKVMvmMaps, CUtlVector<CUtlString> *pVecErrors ); + bool BInitMvmTours( KeyValues *pKVMvmTours, CUtlVector<CUtlString> *pVecErrors ); + bool BInitGameModes( KeyValues *pKVMaps, CUtlVector<CUtlString> *pVecErrors ); + bool BInitMaps( KeyValues *pKVMaps, CUtlVector<CUtlString> *pVecErrors ); + bool BInitMMCategories( KeyValues *pKVCategories, CUtlVector<CUtlString> *pVecErrors ); + bool BInitQuestThemes( KeyValues *pKVThemes, CUtlVector<CUtlString> *pVecErrors ); + bool BInitQuestObjectiveConditions( KeyValues *pKVConditionsBlock, CUtlVector<CUtlString> *pVecErrors ); + bool BObjectiveConditionsPostInit( CUtlVector<CUtlString> *pVecErrors ); + bool BInitWarDefs( KeyValues *pKVWarDefs, CUtlVector<CUtlString> *pVecErrors ); + + bool BPostInitMaps( CUtlVector<CUtlString> *pVecErrors ); + + CUtlVector<const char *> m_vecClassUsabilityStrings; + CUtlVector<const char *> m_vecClassLoadoutStrings; + CUtlVector<const char *> m_vecClassLoadoutStringsForDisplay; + CUtlVector<const char *> m_vecAccountLoadoutStrings; + CUtlVector<const char *> m_vecAccountLoadoutStringsForDisplay; + CUtlVector<const char *> m_vecWeaponTypeSubstrings; + + CUtlVector<MvMMap_t> m_vecMvMMaps; + CUtlVector<MvMMission_t> m_vecMvMMissions; + CUtlVector<MvMTour_t> m_vecMvMTours; + // Contains the list of the quest themes + CUtlMap<const char*, CQuestThemeDefinition*, int > m_mapQuestThemes; + CUtlMap< ObjectiveConditionDefIndex_t, CTFQuestObjectiveConditionsDefinition* > m_mapQuestObjectiveConditions; + + CUtlVector<MapDef_t*> m_vecMasterListOfMaps; + GameCategoryMap_t m_mapGameCategories; + MMGroupMap_t m_mapMMGroups; + WarDefinitionMap_t m_mapWars; +}; + +#endif // TFITEMSCHEMA_H |