//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //============================================================================= #include "cbase.h" #include "buy_preset_debug.h" #include "buy_presets.h" #include "weapon_csbase.h" #include "game/client/iviewport.h" #include "filesystem.h" #include #include #include "c_cs_player.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" BuyPresetManager *TheBuyPresets = NULL; #if USE_BUY_PRESETS //-------------------------------------------------------------------------------------------------------------- ConVar cl_buy_favorite_quiet( "cl_buy_favorite_quiet", "0", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Skips the prompt when saving a buy favorite in the buy menu" ); ConVar cl_buy_favorite_nowarn( "cl_buy_favorite_nowarn", "0", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Skips the error prompt when saving an invalid buy favorite" ); //-------------------------------------------------------------------------------------------------------------- static void PrintBuyPresetUsage( void ) { if ( TheBuyPresets->GetNumPresets() ) { Msg( "usage: cl_buy_favorite <1...%d>\n", TheBuyPresets->GetNumPresets() ); for ( int i=0; iGetNumPresets(); ++i ) { const BuyPreset *preset = TheBuyPresets->GetPreset( i ); if ( preset && preset->GetName() && preset->GetName()[0] ) { char buffer[64]; g_pVGuiLocalize->ConvertUnicodeToANSI( preset->GetName(), buffer, sizeof( buffer ) ); Msg( " %d. %s\n", i+1, buffer ); } } } else { Msg( "cl_buy_favorite: no favorites are defined\n" ); } } //-------------------------------------------------------------------------------------------------------------- /** * Callback function for handling the "cl_buy_favorite" command */ CON_COMMAND_F( cl_buy_favorite, "Purchase a favorite weapon/equipment loadout", FCVAR_CLIENTCMD_CAN_EXECUTE ) { if ( !engine->IsConnected() ) return; if ( !TheBuyPresets ) TheBuyPresets = new BuyPresetManager(); if ( args.ArgC() != 2 ) { PRESET_DEBUG( "cl_buy_favorite: no favorite specified\n" ); PrintBuyPresetUsage(); return; } int presetIndex = atoi( args[1] ) - 1; if ( presetIndex < 0 || presetIndex >= TheBuyPresets->GetNumPresets() ) { PRESET_DEBUG( "cl_buy_favorite: favorite %d doesn't exist\n", presetIndex ); PrintBuyPresetUsage(); return; } TheBuyPresets->PurchasePreset( presetIndex ); } //-------------------------------------------------------------------------------------------------------------- /** * Callback function for handling the "cl_buy_favorite_set" command */ CON_COMMAND_F( cl_buy_favorite_set, "Saves the current loadout as a favorite", FCVAR_CLIENTCMD_CAN_EXECUTE ) { if ( !engine->IsConnected() ) return; if ( !TheBuyPresets ) TheBuyPresets = new BuyPresetManager(); if ( args.ArgC() != 2 ) { PRESET_DEBUG( "cl_buy_favorite_set: no favorite specified\n" ); PrintBuyPresetUsage(); return; } int presetIndex = atoi( args[ 1 ] ) - 1; if ( presetIndex < 0 || presetIndex >= TheBuyPresets->GetNumPresets() ) { PRESET_DEBUG( "cl_buy_favorite_set: favorite %d doesn't exist\n", presetIndex ); PrintBuyPresetUsage(); return; } const BuyPreset *preset = TheBuyPresets->GetPreset( presetIndex ); if ( !preset ) { return; } WeaponSet ws; TheBuyPresets->GetCurrentLoadout( &ws ); BuyPreset newPreset( *preset ); newPreset.ReplaceSet( 0, ws ); TheBuyPresets->SetPreset( presetIndex, &newPreset ); TheBuyPresets->Save(); C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer(); if ( pPlayer ) { pPlayer->EmitSound( "BuyPreset.Updated" ); } } //-------------------------------------------------------------------------------------------------------------- /** * Callback function for handling the "cl_buy_favorite_reset" command */ void __CmdFunc_BuyPresetsReset(void) { if ( !engine->IsConnected() ) return; if ( !TheBuyPresets ) TheBuyPresets = new BuyPresetManager(); C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer(); if ( !pPlayer || ( pPlayer->GetTeamNumber() != TEAM_CT && pPlayer->GetTeamNumber() != TEAM_TERRORIST ) ) { return; } TheBuyPresets->ResetEditToDefaults(); TheBuyPresets->SetPresets( TheBuyPresets->GetEditPresets() ); TheBuyPresets->Save(); } ConCommand cl_buy_favorite_reset( "cl_buy_favorite_reset", __CmdFunc_BuyPresetsReset, "Reset favorite loadouts to the default", FCVAR_CLIENTCMD_CAN_EXECUTE ); #endif // USE_BUY_PRESETS //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- /** * Creates the BuyPresetManager singleton */ BuyPresetManager::BuyPresetManager() { m_loadedTeam = TEAM_UNASSIGNED; } //-------------------------------------------------------------------------------------------------------------- /** * Resets the BuyPresetManager, loading BuyPresets from disk. If no presets are defined, it loads the * default presets instead. */ void BuyPresetManager::VerifyLoadedTeam( void ) { #if USE_BUY_PRESETS C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer(); if ( !pPlayer ) return; int playerTeam = pPlayer->GetTeamNumber(); if ( playerTeam == m_loadedTeam ) return; if ( playerTeam != TEAM_CT && playerTeam != TEAM_TERRORIST ) return; m_presets.RemoveAll(); const char *filename = "cfg/BuyPresets_TER.vdf"; if ( playerTeam == TEAM_CT ) { filename = "cfg/BuyPresets_CT.vdf"; } KeyValues *data; KeyValues *presetKey; data = new KeyValues( "Presets" ); bool fileExists = data->LoadFromFile( filesystem, filename, NULL ); presetKey = data->GetFirstSubKey(); while ( presetKey ) { BuyPreset preset; preset.Parse( presetKey ); m_presets.AddToTail(preset); presetKey = presetKey->GetNextKey(); } if ( !m_presets.Count() ) { const char *filename = "cfg/BuyPresetsDefault_TER.vdf"; if ( playerTeam == TEAM_CT ) { filename = "cfg/BuyPresetsDefault_CT.vdf"; } KeyValues *data; KeyValues *presetKey; data = new KeyValues( "Presets" ); data->LoadFromFile( filesystem, filename, NULL ); presetKey = data->GetFirstSubKey(); while ( presetKey ) { BuyPreset preset; preset.Parse( presetKey ); m_presets.AddToTail(preset); presetKey = presetKey->GetNextKey(); } data->deleteThis(); } // Guarantee we have at least this many presets, even if they are blank while ( m_presets.Count() < NUM_PRESETS ) { BuyPreset preset; m_presets.AddToTail(preset); } data->deleteThis(); m_editPresets = m_presets; if ( !fileExists ) Save(); #endif // USE_BUY_PRESETS } //-------------------------------------------------------------------------------------------------------------- /** * Loads the default presets into the editing presets (e.g. when hitting the "Use Defaults" button) */ void BuyPresetManager::ResetEditToDefaults( void ) { #if USE_BUY_PRESETS VerifyLoadedTeam(); C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer(); if ( !pPlayer ) return; int playerTeam = pPlayer->GetTeamNumber(); if ( playerTeam != TEAM_CT && playerTeam != TEAM_TERRORIST ) return; m_editPresets.RemoveAll(); const char *filename = "cfg/BuyPresetsDefault_TER.vdf"; if ( playerTeam == TEAM_CT ) { filename = "cfg/BuyPresetsDefault_CT.vdf"; } KeyValues *data; KeyValues *presetKey; data = new KeyValues( "Presets" ); data->LoadFromFile( filesystem, filename, NULL ); presetKey = data->GetFirstSubKey(); while ( presetKey ) { BuyPreset preset; preset.Parse( presetKey ); m_editPresets.AddToTail(preset); presetKey = presetKey->GetNextKey(); } data->deleteThis(); #endif // USE_BUY_PRESETS } //-------------------------------------------------------------------------------------------------------------- /** * Saves the current BuyPresets to disk */ void BuyPresetManager::Save() { #if USE_BUY_PRESETS C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer(); if ( !pPlayer ) return; const char *filename = "cfg/BuyPresets_TER.vdf"; switch ( pPlayer->GetTeamNumber() ) { case TEAM_CT: filename = "cfg/BuyPresets_CT.vdf"; break; case TEAM_TERRORIST: filename = "cfg/BuyPresets_TER.vdf"; break; default: return; // don't bother saving presets unless we're on a team } KeyValues *data = new KeyValues( "Presets" ); for( int i=0; iSaveToFile( filesystem, filename, NULL ); data->deleteThis(); #endif // USE_BUY_PRESETS } //-------------------------------------------------------------------------------------------------------------- /** * Returns the specified "live" preset, or NULL if it doesn't exist */ const BuyPreset * BuyPresetManager::GetPreset( int index ) const { if ( index < 0 || index >= m_presets.Count() ) { return NULL; } return &(m_presets[index]); } //-------------------------------------------------------------------------------------------------------------- void BuyPresetManager::SetPreset( int index, const BuyPreset *preset ) { if ( index < 0 || index >= m_presets.Count() || !preset ) { return; } m_presets[index] = *preset; } //-------------------------------------------------------------------------------------------------------------- /** * Returns the specified editing preset, or NULL if it doesn't exist */ BuyPreset * BuyPresetManager::GetEditPreset( int index ) { if ( index < 0 || index >= m_editPresets.Count() ) { return NULL; } return &(m_editPresets[index]); } //-------------------------------------------------------------------------------------------------------------- /** * Generates and sends buy commands to buy a specific preset */ void BuyPresetManager::PurchasePreset( int presetIndex ) { if ( presetIndex >= 0 && presetIndex < m_presets.Count() ) { const BuyPreset *preset = &(m_presets[presetIndex]); int setIndex; for ( setIndex = 0; setIndex < preset->GetNumSets(); ++setIndex ) { // Try to buy this weapon set. const WeaponSet *itemSet = preset->GetSet( setIndex ); if ( itemSet ) { int currentCost; WeaponSet currentSet; itemSet->GetCurrent( currentCost, currentSet ); if ( currentCost > 0 ) { PRESET_DEBUG( "cl_buy_favorite: buying %ls for a total of $%d.\n", preset->GetName(), currentCost ); char buf[BUY_PRESET_COMMAND_LEN]; currentSet.GenerateBuyCommands( buf ); // Send completed string PRESET_DEBUG( "%s\n", buf ); engine->ClientCmd( buf ); return; } else if ( currentCost == 0 ) { C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer(); if ( pPlayer ) { pPlayer->EmitSound( "BuyPreset.AlreadyBought" ); } // We have everything already. Let the player know. if ( setIndex == 0 ) { PRESET_DEBUG( "cl_buy_favorite: already have a complete %ls set.\n", preset->GetName() ); } else { PRESET_DEBUG( "cl_buy_favorite: can't afford anything better from %ls.\n", preset->GetName() ); } return; } } } C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer(); if ( pPlayer ) { pPlayer->EmitSound( "BuyPreset.CantBuy" ); } PRESET_DEBUG( "cl_buy_favorite: can't afford anything better from %ls.\n", preset->GetName() ); return; } // We failed to buy anything. Let the player know. C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer(); if ( pPlayer ) { pPlayer->EmitSound( "BuyPreset.CantBuy" ); } PRESET_DEBUG( "cl_buy_favorite: preset %d doesn't exist.\n", presetIndex ); } //--------------------------------------------------------------------------------------------------------------