Merge branch 'ValveSoftware:master' into master
This commit is contained in:
commit
d64a531377
|
|
@ -0,0 +1,13 @@
|
|||
<!--
|
||||
Thanks for your interest in Source SDK 2013! When you make a contribution to the Source SDK 2013, either by creating an Issue or submitting a Pull Request (a "Contribution"), Valve wants to be able to use your Contribution to improve the Source 2013 SDK and other Valve products.
|
||||
1. Contributions: When you provide a Contribution, please ensure it is your original creation. You agree to the following license and warranty for any Contributions you provide:
|
||||
1.1 You grant Valve a non-exclusive, perpetual, irrevocable, royalty-free, sublicensable, and worldwide license to make, use, sell, reproduce, modify, create derivate works, directly and indirectly distribute, publicly display, publish, transmit and perform the Contribution, and any derivative works thereof. .
|
||||
1.2 You represent and warrant that you are either the owner or authorized licensee of the Contribution, that you have all necessary consents to grant this license to the Contribution to Valve, and that the Contribution does not violate any third-party intellectual property rights.
|
||||
1.3 Except as set forth in (2) above, you provide your Contribution "as is" without warranties of any kind.
|
||||
2. Other Materials or Suggestions: If you want to submit any materials or suggestions that are not your original work, you agree to do the following:
|
||||
2.1 You may submit other materials or suggestions to Valve separate from any Contributions;
|
||||
2.2 You will explicitly identify them as sourced from a third party and state the details of its origin; and
|
||||
2.3 You will include Valve with any third party licenses, terms, or other restrictions that apply, if you are aware of any.
|
||||
-->
|
||||
|
||||
# Description
|
||||
47
CONTRIBUTING
47
CONTRIBUTING
|
|
@ -1,38 +1,9 @@
|
|||
Thanks for your interest in the Source SDK 2013 project. When you make a
|
||||
contribution to the project (e.g. create an Issue or submit a Pull Request)
|
||||
(a "Contribution"), Valve wants to be able to use your Contribution to improve
|
||||
the SDK and other Valve products.
|
||||
|
||||
As a condition of providing a Contribution, you agree that:
|
||||
- You grant Valve a non-exclusive, irrevocable, royalty-free, worldwide license
|
||||
to make, use, sell, reproduce, modify, distribute (directly and indirectly),
|
||||
and publicly display and perform the Contribution, and any derivative works
|
||||
that Valve may make from the Contribution, under any intellectual property you
|
||||
own or have the right to license.
|
||||
- You warrant and represent that the Contribution is your original creation,
|
||||
that you have the authority to grant this license to Valve, and that this
|
||||
license does not require the permission of any third party. Otherwise, you
|
||||
provide your Contribution "as is" without warranties.
|
||||
|
||||
Should you wish to submit a suggestion or work that is not your original
|
||||
creation, you may submit it to Valve separate from any Contribution,
|
||||
explicitly identifying it as sourced from a third party, stating the details
|
||||
of its origin, and informing Valve of any license or other restriction of
|
||||
which you are personally aware.
|
||||
|
||||
|
||||
Valve is happy to accept pull requests and issues in the source-sdk-2013
|
||||
repository in these cases:
|
||||
* Changes that fix bugs in the SDK deployment process itself. The repository
|
||||
should build out of the box, and anything that prevents that is a pull
|
||||
request we want.
|
||||
* High priority bugs in HL2, the Episodes, or HL2MP that can be fixed in
|
||||
client.dll or server.dll.
|
||||
|
||||
For other changes we suggest that you issue a pull request to one of these
|
||||
fine community-maintained repositories instead:
|
||||
https://developer.valvesoftware.com/wiki/Source-sdk-2013-community-repos
|
||||
|
||||
If you are going to make a pull request, please keep them as granular as
|
||||
possible. Pull requests with 3-4 unrelated changes in them aren't going to
|
||||
be accepted.
|
||||
Thanks for your interest in Source SDK 2013! When you make a contribution to the Source SDK 2013, either by creating an Issue or submitting a Pull Request (a "Contribution"), Valve wants to be able to use your Contribution to improve the Source 2013 SDK and other Valve products.
|
||||
1. Contributions: When you provide a Contribution, please ensure it is your original creation. You agree to the following license and warranty for any Contributions you provide:
|
||||
1.1 You grant Valve a non-exclusive, perpetual, irrevocable, royalty-free, sublicensable, and worldwide license to make, use, sell, reproduce, modify, create derivate works, directly and indirectly distribute, publicly display, publish, transmit and perform the Contribution, and any derivative works thereof. .
|
||||
1.2 You represent and warrant that you are either the owner or authorized licensee of the Contribution, that you have all necessary consents to grant this license to the Contribution to Valve, and that the Contribution does not violate any third-party intellectual property rights.
|
||||
1.3 Except as set forth in (2) above, you provide your Contribution "as is" without warranties of any kind.
|
||||
2. Other Materials or Suggestions: If you want to submit any materials or suggestions that are not your original work, you agree to do the following:
|
||||
2.1 You may submit other materials or suggestions to Valve separate from any Contributions;
|
||||
2.2 You will explicitly identify them as sourced from a third party and state the details of its origin; and
|
||||
2.3 You will include Valve with any third party licenses, terms, or other restrictions that apply, if you are aware of any.
|
||||
|
|
|
|||
2
LICENSE
2
LICENSE
|
|
@ -18,6 +18,6 @@ WARRANTY OF ANY KIND. VALVE EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS O
|
|||
INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, TITLE AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
LIMITATION OF LIABILITY. VALVE AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
|
||||
OR CONSEQUENTIAL DAMAGES WHATSOEVER ) THAT MAY BE INCURRED BY YOU EVEN IF VALVE HAS BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
OR CONSEQUENTIAL DAMAGES WHATSOEVER THAT MAY BE INCURRED BY YOU EVEN IF VALVE HAS BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
|
||||
|
|
@ -16,7 +16,11 @@ Clone the repository using the following command:
|
|||
|
||||
Requirements:
|
||||
- Source SDK 2013 Multiplayer installed via Steam
|
||||
- Visual Studio 2022
|
||||
- Visual Studio 2022 with the following workload and components:
|
||||
- Desktop development with C++:
|
||||
- MSVC v143 - VS 2022 C++ x64/x86 build tools (Latest)
|
||||
- Windows 11 SDK (10.0.22621.0) or Windows 10 SDK (10.0.19041.1)
|
||||
- Python 3.13 or later
|
||||
|
||||
Inside the cloned directory, navigate to `src`, run:
|
||||
```bat
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -441,10 +441,10 @@ void CHudCommentary::Paint()
|
|||
// Draw the speaker names
|
||||
// Get our scheme and font information
|
||||
vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
|
||||
vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" );
|
||||
vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault", true );
|
||||
if ( !hFont )
|
||||
{
|
||||
hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" );
|
||||
hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default", true );
|
||||
}
|
||||
vgui::surface()->DrawSetTextFont( hFont );
|
||||
vgui::surface()->DrawSetTextColor( clr );
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ void C_SlideshowDisplay::BuildSlideShowImagesList( void )
|
|||
char szFullFileName[_MAX_PATH];
|
||||
Q_snprintf( szFullFileName, sizeof( szFullFileName ), "materials/vgui/%s/%s", m_szSlideshowDirectory, szMatFileName );
|
||||
|
||||
KeyValues *pMaterialKeys = new KeyValues( "material" );
|
||||
KeyValuesAD pMaterialKeys( "material" );
|
||||
bool bLoaded = pMaterialKeys->LoadFromFile( g_pFullFileSystem, szFullFileName, NULL );
|
||||
|
||||
if ( bLoaded )
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ inline ClientThinkHandle_t CClientThinkList::GetInvalidThinkHandle()
|
|||
|
||||
inline CClientThinkList::ThinkEntry_t* CClientThinkList::GetThinkEntry( ClientThinkHandle_t hThink )
|
||||
{
|
||||
return &m_ThinkEntries[ (unsigned long)hThink ];
|
||||
return &m_ThinkEntries[ (uintp)hThink ];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -837,23 +837,26 @@ void ClientModeShared::StartMessageMode( int iMessageModeType )
|
|||
}
|
||||
|
||||
#if defined( TF_CLIENT_DLL )
|
||||
bool bSuspensionInMatch = GTFGCClientSystem() && GTFGCClientSystem()->BHaveChatSuspensionInCurrentMatch();
|
||||
if ( !cl_enable_text_chat.GetBool() || bSuspensionInMatch )
|
||||
if ( iMessageModeType == MM_SAY || iMessageModeType == MM_SAY_TEAM )
|
||||
{
|
||||
CBaseHudChat *pHUDChat = ( CBaseHudChat * ) GET_HUDELEMENT( CHudChat );
|
||||
if ( pHUDChat )
|
||||
bool bSuspensionInMatch = GTFGCClientSystem() && GTFGCClientSystem()->BHaveChatSuspensionInCurrentMatch();
|
||||
if ( !cl_enable_text_chat.GetBool() || bSuspensionInMatch )
|
||||
{
|
||||
const char *pszReason = "#TF_Chat_Disabled";
|
||||
if ( bSuspensionInMatch )
|
||||
CBaseHudChat *pHUDChat = ( CBaseHudChat * ) GET_HUDELEMENT( CHudChat );
|
||||
if ( pHUDChat )
|
||||
{
|
||||
pszReason = "#TF_Chat_Unavailable";
|
||||
}
|
||||
const char *pszReason = "#TF_Chat_Disabled";
|
||||
if ( bSuspensionInMatch )
|
||||
{
|
||||
pszReason = "#TF_Chat_Unavailable";
|
||||
}
|
||||
|
||||
char szLocalized[100];
|
||||
g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( pszReason ), szLocalized, sizeof( szLocalized ) );
|
||||
pHUDChat->ChatPrintf( 0, CHAT_FILTER_NONE, "%s ", szLocalized );
|
||||
char szLocalized[100];
|
||||
g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( pszReason ), szLocalized, sizeof( szLocalized ) );
|
||||
pHUDChat->ChatPrintf( 0, CHAT_FILTER_NONE, "%s ", szLocalized );
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif // TF_CLIENT_DLL
|
||||
|
||||
|
|
|
|||
|
|
@ -1596,7 +1596,7 @@ void CHudCloseCaption::CreateFonts( void )
|
|||
{
|
||||
vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
|
||||
|
||||
m_hFonts[CCFONT_NORMAL] = pScheme->GetFont( "CloseCaption_Normal", true );
|
||||
m_hFonts[CCFONT_NORMAL] = pScheme->GetFont( "CloseCaption", true );
|
||||
|
||||
if ( IsPC() )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -191,12 +191,12 @@ void CMoveHelperClient::ProcessImpacts( void )
|
|||
}
|
||||
|
||||
// misyl: Debug
|
||||
if ( vOldLocalVel != vOldAbsVel )
|
||||
{
|
||||
Msg( "%d\n", gpGlobals->tickcount );
|
||||
Msg( "vOldLocalVel: %f %f %f\n", vOldLocalVel.x, vOldLocalVel.y, vOldLocalVel.z );
|
||||
Msg( "vOldAbsVel: %f %f %f\n", vOldAbsVel.x, vOldAbsVel.y, vOldAbsVel.z );
|
||||
}
|
||||
// if ( vOldLocalVel != vOldAbsVel )
|
||||
// {
|
||||
// Msg( "%d\n", gpGlobals->tickcount );
|
||||
// Msg( "vOldLocalVel: %f %f %f\n", vOldLocalVel.x, vOldLocalVel.y, vOldLocalVel.z );
|
||||
// Msg( "vOldAbsVel: %f %f %f\n", vOldAbsVel.x, vOldAbsVel.y, vOldAbsVel.z );
|
||||
// }
|
||||
// Restore the velocity
|
||||
m_pHost->SetAbsVelocity( vOldAbsVel );
|
||||
//m_pHost->SetLocalVelocity( vOldLocalVel );
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ CParticleEffectBinding::CParticleEffectBinding()
|
|||
m_LastMin = m_Min;
|
||||
m_LastMax = m_Max;
|
||||
|
||||
m_flParticleCullRadius = -1.f; // dummy value, is overwritten below
|
||||
SetParticleCullRadius( 0.0f );
|
||||
m_nActiveParticles = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -6050,7 +6050,7 @@ void C_TFPlayer::ClientThink()
|
|||
//
|
||||
// Passtime ask for ball button
|
||||
//
|
||||
if ( m_nButtons & IN_ATTACK3 )
|
||||
if ( m_afButtonPressed & IN_ATTACK3 )
|
||||
{
|
||||
engine->ClientCmd("voicemenu 1 8");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -531,6 +531,7 @@ void ClientModeTFNormal::Shutdown()
|
|||
{
|
||||
RemoveFilesInPath( "materials/temp" );
|
||||
RemoveFilesInPath( "download/user_custom" );
|
||||
RemoveFilesInPath( "sound/temp" );
|
||||
}
|
||||
|
||||
DestroyStatsSummaryPanel();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ void CTFAutoRP::ParseDataFile( void )
|
|||
Assert( !m_pDataFileKV );
|
||||
|
||||
// Load & parse the word files
|
||||
KeyValues *pFileKV = new KeyValues( "AutoRPFile" );
|
||||
KeyValuesAD pFileKV( "AutoRPFile" );
|
||||
if ( pFileKV->LoadFromFile( filesystem, "scripts/autorp.txt", "MOD" ) == false )
|
||||
return;
|
||||
|
||||
|
|
@ -547,7 +547,7 @@ void CTFAutoRP::ModifySpeech( const char *pszInText, char *pszOutText, int iOutL
|
|||
{
|
||||
szStoredWord[0] = toupper( szStoredWord[0] );
|
||||
}
|
||||
else if ( pszCurWord[0] >= 'a' && pszCurWord[0] <= 'a' )
|
||||
else if ( pszCurWord[0] >= 'a' && pszCurWord[0] <= 'z' )
|
||||
{
|
||||
szStoredWord[0] = tolower( szStoredWord[0] );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -777,7 +777,7 @@ void CHudMainMenuOverride::LoadCharacterImageFile( void )
|
|||
//-----------------------------------------------------------------------------
|
||||
void CHudMainMenuOverride::LoadMenuEntries( void )
|
||||
{
|
||||
KeyValues *datafile = new KeyValues("GameMenu");
|
||||
KeyValuesAD datafile("GameMenu");
|
||||
datafile->UsesEscapeSequences( true ); // VGUI uses escape sequences
|
||||
bool bLoaded = datafile->LoadFromFile( g_pFullFileSystem, "Resource/GameMenu.res", "custom_mod" );
|
||||
if ( !bLoaded )
|
||||
|
|
@ -2274,7 +2274,7 @@ public:
|
|||
|
||||
//V_strcpy_safe( uilanguage, "german" );
|
||||
|
||||
KeyValues *pEntriesKV = new KeyValues( "motd_entries");
|
||||
KeyValuesAD pEntriesKV( "motd_entries");
|
||||
|
||||
// Try and load the cache file. If we fail, we'll just create a new one.
|
||||
if ( !pMMPanel->ReloadedAllMOTDs() )
|
||||
|
|
|
|||
|
|
@ -851,7 +851,14 @@ void CWaveStatusPanel::UpdateEnemyCounts( void )
|
|||
|
||||
if ( pPanel->m_pEnemyCountImageBG )
|
||||
{
|
||||
pPanel->m_pEnemyCountImageBG->SetBgColor( m_clrNormal );
|
||||
if ( support[i].iFlags & MVM_CLASS_FLAG_MINIBOSS )
|
||||
{
|
||||
pPanel->m_pEnemyCountImageBG->SetBgColor( m_clrMiniBoss );
|
||||
}
|
||||
else
|
||||
{
|
||||
pPanel->m_pEnemyCountImageBG->SetBgColor( m_clrNormal );
|
||||
}
|
||||
}
|
||||
|
||||
if ( pPanel->m_pEnemyCountCritBG )
|
||||
|
|
|
|||
|
|
@ -574,6 +574,23 @@ void CTFHudMatchStatus::FireGameEvent( IGameEvent * event )
|
|||
}
|
||||
|
||||
const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() );
|
||||
|
||||
// FIX: Refresh versus doors so late-joiners do not see the wrong skin
|
||||
int nSkin = 0;
|
||||
int nSubModel = 0;
|
||||
if (pMatchDesc->BGetRoundDoorParameters(nSkin, nSubModel))
|
||||
{
|
||||
// Is VS doors model not initialized yet?
|
||||
if (m_pMatchStartModelPanel->m_hModel == NULL)
|
||||
{
|
||||
m_pMatchStartModelPanel->UpdateModel();
|
||||
}
|
||||
|
||||
m_pMatchStartModelPanel->SetBodyGroup( "logos", nSubModel );
|
||||
m_pMatchStartModelPanel->UpdateModel();
|
||||
m_pMatchStartModelPanel->SetSkin( nSkin );
|
||||
}
|
||||
|
||||
bool bForceDoors = false;
|
||||
if ( bForceDoors || ( pMatchDesc && pMatchDesc->BUsesPostRoundDoors() ) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ protected:
|
|||
virtual void ApplySchemeSettings(vgui::IScheme *scheme);
|
||||
virtual void Paint( void );
|
||||
virtual bool ShouldDraw( void );
|
||||
virtual bool CanAnimate() const OVERRIDE { return false; }
|
||||
|
||||
private:
|
||||
int m_iScopeTexture[4];
|
||||
|
|
|
|||
|
|
@ -385,14 +385,6 @@ void CTFMapInfoMenu::LoadMapPage()
|
|||
{
|
||||
m_pMapInfo->SetText( wszMapDescription );
|
||||
}
|
||||
else if ( StringHasPrefix( m_szMapName, "vsh_" ) )
|
||||
{
|
||||
m_pMapInfo->SetText( "#default_vsh_description" );
|
||||
}
|
||||
else if ( StringHasPrefix( m_szMapName, "zi_" ) )
|
||||
{
|
||||
m_pMapInfo->SetText( "#default_zi_description" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// try loading map descriptions from .txt files first
|
||||
|
|
@ -497,7 +489,15 @@ void CTFMapInfoMenu::LoadMapPage()
|
|||
|
||||
if( !g_pVGuiLocalize->Find( mapInfoKey ) )
|
||||
{
|
||||
if ( TFGameRules() )
|
||||
if ( StringHasPrefix( m_szMapName, "vsh_" ) )
|
||||
{
|
||||
pszDescription = "#default_vsh_description";
|
||||
}
|
||||
else if ( StringHasPrefix( m_szMapName, "zi_" ) )
|
||||
{
|
||||
pszDescription = "#default_zi_description";
|
||||
}
|
||||
else if ( TFGameRules() )
|
||||
{
|
||||
if ( TFGameRules()->IsMannVsMachineMode() )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
static int g_ActiveVoiceMenu = 0;
|
||||
|
||||
#if defined( TF_CLIENT_DLL )
|
||||
extern ConVar tf_voice_command_suspension_mode;
|
||||
#endif
|
||||
|
||||
void OpenVoiceMenu( int index )
|
||||
{
|
||||
// do not show the menu if the player is dead or is an observer
|
||||
|
|
@ -28,7 +32,7 @@ void OpenVoiceMenu( int index )
|
|||
return;
|
||||
|
||||
#if defined ( TF_CLIENT_DLL )
|
||||
if ( GTFGCClientSystem() && GTFGCClientSystem()->BHaveChatSuspensionInCurrentMatch() )
|
||||
if ( GTFGCClientSystem() && GTFGCClientSystem()->BHaveChatSuspensionInCurrentMatch() && tf_voice_command_suspension_mode.GetInt() == 1 )
|
||||
{
|
||||
CBaseHudChat *pHUDChat = ( CBaseHudChat * ) GET_HUDELEMENT( CHudChat );
|
||||
if ( pHUDChat )
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public:
|
|||
virtual Vector EyePosition( void );
|
||||
|
||||
virtual INextBot *MyNextBotPointer( void ) { return this; }
|
||||
virtual bool IsNextBot(void) const { return true; }
|
||||
|
||||
// Event hooks into NextBot system ---------------------------------------
|
||||
virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
|
||||
|
|
|
|||
|
|
@ -146,4 +146,10 @@ void CSkyCamera::Activate( )
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// matches the behavior of fog controller
|
||||
if ( GameRules()->IsOfficialMap() )
|
||||
{
|
||||
m_skyboxData.fog.radial = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -996,6 +996,9 @@ public:
|
|||
void TraceBleed( float flDamage, const Vector &vecDir, trace_t *ptr, int bitsDamageType );
|
||||
virtual bool IsTriggered( CBaseEntity *pActivator ) {return true;}
|
||||
virtual bool IsNPC( void ) const { return false; }
|
||||
#ifdef NEXT_BOT
|
||||
virtual bool IsNextBot(void) const { return false; }
|
||||
#endif
|
||||
CAI_BaseNPC *MyNPCPointer( void );
|
||||
virtual CBaseCombatCharacter *MyCombatCharacterPointer( void ) { return NULL; }
|
||||
virtual INextBot *MyNextBotPointer( void ) { return NULL; }
|
||||
|
|
|
|||
|
|
@ -95,9 +95,9 @@ ConVar spec_freeze_traveltime( "spec_freeze_traveltime", "0.4", FCVAR_CHEAT | FC
|
|||
|
||||
ConVar sv_bonus_challenge( "sv_bonus_challenge", "0", FCVAR_REPLICATED, "Set to values other than 0 to select a bonus map challenge type." );
|
||||
|
||||
ConVar sv_chat_bucket_size_tier1( "sv_chat_bucket_size_tier1", "4", FCVAR_NONE, "The maxmimum size of the short term chat msg bucket." );
|
||||
ConVar sv_chat_bucket_size_tier1( "sv_chat_bucket_size_tier1", "4", FCVAR_NONE, "The maximum size of the short term chat msg bucket." );
|
||||
ConVar sv_chat_seconds_per_msg_tier1( "sv_chat_seconds_per_msg_tier1", "3", FCVAR_NONE, "The number of seconds to accrue an additional short term chat msg." );
|
||||
ConVar sv_chat_bucket_size_tier2( "sv_chat_bucket_size_tier2", "30", FCVAR_NONE, "The maxmimum size of the long term chat msg bucket." );
|
||||
ConVar sv_chat_bucket_size_tier2( "sv_chat_bucket_size_tier2", "30", FCVAR_NONE, "The maximum size of the long term chat msg bucket." );
|
||||
ConVar sv_chat_seconds_per_msg_tier2( "sv_chat_seconds_per_msg_tier2", "10", FCVAR_NONE, "The number of seconds to accrue an additional long term chat msg." );
|
||||
|
||||
static ConVar sv_maxusrcmdprocessticks( "sv_maxusrcmdprocessticks", "24", FCVAR_NOTIFY, "Maximum number of client-issued usrcmd ticks that can be replayed in packet loss conditions, 0 to allow no restrictions" );
|
||||
|
|
@ -8102,13 +8102,6 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data)
|
|||
}
|
||||
|
||||
|
||||
void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID)
|
||||
{
|
||||
int mask = (1<<PLAYER_FLAG_BITS) - 1;
|
||||
int data = *(int *)pVarData;
|
||||
|
||||
pOut->m_Int = ( data & mask );
|
||||
}
|
||||
// -------------------------------------------------------------------------------- //
|
||||
// SendTable for CPlayerState.
|
||||
// -------------------------------------------------------------------------------- //
|
||||
|
|
@ -8187,7 +8180,7 @@ void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const voi
|
|||
SendPropInt (SENDINFO(m_iBonusProgress), 15 ),
|
||||
SendPropInt (SENDINFO(m_iBonusChallenge), 4 ),
|
||||
SendPropFloat (SENDINFO(m_flMaxspeed), 12, SPROP_ROUNDDOWN, 0.0f, 2048.0f ), // CL
|
||||
SendPropInt (SENDINFO(m_fFlags), PLAYER_FLAG_BITS, SPROP_UNSIGNED|SPROP_CHANGES_OFTEN, SendProxy_CropFlagsToPlayerFlagBitsLength ),
|
||||
SendPropInt (SENDINFO(m_fFlags), 0, SPROP_UNSIGNED|SPROP_CHANGES_OFTEN ),
|
||||
SendPropInt (SENDINFO(m_iObserverMode), 3, SPROP_UNSIGNED ),
|
||||
SendPropEHandle (SENDINFO(m_hObserverTarget) ),
|
||||
SendPropInt (SENDINFO(m_iFOV), 8, SPROP_UNSIGNED ),
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ void CSlideshowDisplay::BuildSlideShowImagesList( void )
|
|||
char szFullFileName[_MAX_PATH];
|
||||
Q_snprintf( szFullFileName, sizeof( szFullFileName ), "materials/vgui/%s/%s", m_szSlideshowDirectory.Get(), szMatFileName );
|
||||
|
||||
KeyValues *pMaterialKeys = new KeyValues( "material" );
|
||||
KeyValuesAD pMaterialKeys( "material" );
|
||||
bool bLoaded = pMaterialKeys->LoadFromFile( g_pFullFileSystem, szFullFileName, NULL );
|
||||
|
||||
if ( bLoaded )
|
||||
|
|
|
|||
|
|
@ -1156,6 +1156,9 @@ int CTeamControlPointMaster::GetNumPointsOwnedByTeam( int iTeam )
|
|||
//-----------------------------------------------------------------------------
|
||||
int CTeamControlPointMaster::CalcNumRoundsRemaining( int iTeam )
|
||||
{
|
||||
if ( m_ControlPointRounds.IsEmpty() )
|
||||
return 0;
|
||||
|
||||
// To determine how many rounds remain for a given team if it consistently wins mini-rounds, we have to
|
||||
// simulate forward each mini-round and track the control point ownership that would result
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ ActionResult< CTFBot > CTFBotEngineerBuildTeleportEntrance::OnStart( CTFBot *me,
|
|||
ActionResult< CTFBot > CTFBotEngineerBuildTeleportEntrance::Update( CTFBot *me, float interval )
|
||||
{
|
||||
CTeamControlPoint *point = me->GetMyControlPoint();
|
||||
if ( !point )
|
||||
CCaptureZone *zone = me->GetFlagCaptureZone();
|
||||
if ( !point && !zone )
|
||||
{
|
||||
// wait until a control point becomes available
|
||||
return Continue();
|
||||
|
|
@ -64,7 +65,14 @@ ActionResult< CTFBot > CTFBotEngineerBuildTeleportEntrance::Update( CTFBot *me,
|
|||
if ( !m_path.IsValid() )
|
||||
{
|
||||
CTFBotPathCost cost( me, FASTEST_ROUTE );
|
||||
m_path.Compute( me, point->GetAbsOrigin(), cost );
|
||||
if ( point )
|
||||
{
|
||||
m_path.Compute( me, point->GetAbsOrigin(), cost );
|
||||
}
|
||||
else if ( zone )
|
||||
{
|
||||
m_path.Compute( me, zone->WorldSpaceCenter(), cost );
|
||||
}
|
||||
}
|
||||
|
||||
m_path.Update( me );
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ ActionResult< CTFBot > CTFBotDeliverFlag::Update( CTFBot *me, float interval )
|
|||
|
||||
m_flTotalTravelDistance = NavAreaTravelDistance( me->GetLastKnownArea(), TheNavMesh->GetNavArea( zone->WorldSpaceCenter() ), cost );
|
||||
|
||||
if ( flOldTravelDistance != -1.0f && m_flTotalTravelDistance - flOldTravelDistance > 2000.0f )
|
||||
if ( TFGameRules()->IsMannVsMachineMode() && flOldTravelDistance != -1.0f && m_flTotalTravelDistance - flOldTravelDistance > 2000.0f )
|
||||
{
|
||||
TFGameRules()->BroadcastSound( 255, "Announcer.MVM_Bomb_Reset" );
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,14 @@ ActionResult< CTFBot > CTFBotSpyHide::Update( CTFBot *me, float interval )
|
|||
if ( m_talkTimer.IsElapsed() )
|
||||
{
|
||||
m_talkTimer.Start( RandomFloat( 5.0f, 10.0f ) );
|
||||
me->EmitSound( "Spy.TeaseVictim" );
|
||||
if ( TFGameRules()->IsMannVsMachineMode() && me->GetTeamNumber() == TF_TEAM_PVE_INVADERS )
|
||||
{
|
||||
me->EmitSound( "Spy.MVM_TeaseVictim" );
|
||||
}
|
||||
else
|
||||
{
|
||||
me->EmitSound( "Spy.TeaseVictim" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_isAtGoal )
|
||||
|
|
|
|||
|
|
@ -704,9 +704,9 @@ DEFINE_SCRIPTFUNC( IsOnAnyMission, "Return true if this bot has a current missio
|
|||
DEFINE_SCRIPTFUNC_WRAPPED( SetMissionTarget, "Set this bot's mission target to the given entity" )
|
||||
DEFINE_SCRIPTFUNC_WRAPPED( GetMissionTarget, "Get this bot's current mission target" )
|
||||
|
||||
DEFINE_SCRIPTFUNC( SetBehaviorFlag, "Set the given behavior flag(s) for this bot" )
|
||||
DEFINE_SCRIPTFUNC( ClearBehaviorFlag, "Clear the given behavior flag(s) for this bot" )
|
||||
DEFINE_SCRIPTFUNC( IsBehaviorFlagSet, "Return true if the given behavior flag(s) are set for this bot" )
|
||||
DEFINE_SCRIPTFUNC_WRAPPED( SetBehaviorFlag, "Set the given behavior flag(s) for this bot" )
|
||||
DEFINE_SCRIPTFUNC_WRAPPED( ClearBehaviorFlag, "Clear the given behavior flag(s) for this bot" )
|
||||
DEFINE_SCRIPTFUNC_WRAPPED( IsBehaviorFlagSet, "Return true if the given behavior flag(s) are set for this bot" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_WRAPPED( SetActionPoint, "Set the given action point for this bot" )
|
||||
DEFINE_SCRIPTFUNC_WRAPPED( GetActionPoint, "Get the given action point for this bot" )
|
||||
|
|
|
|||
|
|
@ -331,6 +331,9 @@ public:
|
|||
void SetBehaviorFlag( unsigned int flags );
|
||||
void ClearBehaviorFlag( unsigned int flags );
|
||||
bool IsBehaviorFlagSet( unsigned int flags ) const;
|
||||
void ScriptSetBehaviorFlag( int flags ) { this->SetBehaviorFlag( (unsigned int)flags ); }
|
||||
void ScriptClearBehaviorFlag( int flags ) { this->ClearBehaviorFlag( (unsigned int)flags ); }
|
||||
bool ScriptIsBehaviorFlagSet( int flags ) const { return this->IsBehaviorFlagSet( (unsigned int)flags ); }
|
||||
|
||||
bool FindSplashTarget( CBaseEntity *target, float maxSplashRadius, Vector *splashTarget ) const;
|
||||
|
||||
|
|
@ -358,11 +361,11 @@ public:
|
|||
CBaseEntity *GetMissionTarget( void ) const;
|
||||
void SetMissionString( CUtlString string );
|
||||
CUtlString *GetMissionString( void );
|
||||
void ScriptSetMission( unsigned int mission, bool resetBehaviorSystem = true ) { this->SetMission( (MissionType)mission, resetBehaviorSystem ); }
|
||||
void ScriptSetPrevMission( unsigned int mission ) { this->SetPrevMission( (MissionType)mission ); }
|
||||
unsigned int ScriptGetMission( void ) const { return (unsigned int)this->GetMission(); }
|
||||
unsigned int ScriptGetPrevMission( void ) const { return (unsigned int)this->GetPrevMission(); }
|
||||
bool ScriptHasMission( unsigned int mission ) const { return this->HasMission( (MissionType)mission ); }
|
||||
void ScriptSetMission( int mission, bool resetBehaviorSystem = true ) { this->SetMission( (MissionType)mission, resetBehaviorSystem ); }
|
||||
void ScriptSetPrevMission( int mission ) { this->SetPrevMission( (MissionType)mission ); }
|
||||
int ScriptGetMission( void ) const { return (int)this->GetMission(); }
|
||||
int ScriptGetPrevMission( void ) const { return (int)this->GetPrevMission(); }
|
||||
bool ScriptHasMission( int mission ) const { return this->HasMission( (MissionType)mission ); }
|
||||
void ScriptSetMissionTarget( HSCRIPT hTarget ) { this->SetMissionTarget( ToEnt( hTarget ) ); }
|
||||
HSCRIPT ScriptGetMissionTarget( void ) const { return ToHScript( this->GetMissionTarget() ); }
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "particle_parse.h"
|
||||
#include "player_vs_environment/tf_population_manager.h"
|
||||
#include "collisionutils.h"
|
||||
#include "func_respawnroom.h"
|
||||
#include "tf_objective_resource.h"
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -209,6 +210,21 @@ void CCurrencyPack::ComeToRest( void )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Or a func_respawnroom (robots can drop money in their own spawn)
|
||||
for ( int i = 0; i < IFuncRespawnRoomAutoList::AutoList().Count(); i++ )
|
||||
{
|
||||
CFuncRespawnRoom *pRespawnRoom = static_cast<CFuncRespawnRoom *>( IFuncRespawnRoomAutoList::AutoList()[ i ] );
|
||||
Vector vecMins, vecMaxs;
|
||||
pRespawnRoom->GetCollideable()->WorldSpaceSurroundingBounds( &vecMins, &vecMaxs );
|
||||
if ( IsPointInBox( GetCollideable()->GetCollisionOrigin(), vecMins, vecMaxs ) )
|
||||
{
|
||||
TFGameRules()->DistributeCurrencyAmount( m_nAmount );
|
||||
|
||||
m_bTouched = true;
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -2626,7 +2626,7 @@ void CPopulationManager::AllocateBots()
|
|||
Warning( "%d bots were already allocated some how before CPopulationManager::AllocateBots was called\n", botVector.Count() );
|
||||
}
|
||||
|
||||
for ( int i = nNumEnemyBots; i < MVM_INVADERS_TEAM_SIZE; ++i )
|
||||
for ( int i = nNumEnemyBots; i < tf_mvm_max_invaders.GetInt(); ++i )
|
||||
{
|
||||
CTFBot* newBot = NextBotCreatePlayerBot< CTFBot >( "TFBot", false );
|
||||
if ( newBot )
|
||||
|
|
|
|||
|
|
@ -137,8 +137,6 @@ public:
|
|||
bool IsBonusRound() const { return m_bBonusRound; }
|
||||
CBaseCombatCharacter* GetBonusBoss() const { return m_hBonusBoss; }
|
||||
|
||||
enum { MVM_INVADERS_TEAM_SIZE = 22 };
|
||||
|
||||
static bool GetWavesUseReadyBetween() { return true; }
|
||||
|
||||
void SetDefaultEventChangeAttributesName( const char* pszDefaultEventChangeAttributesName ) { m_defaultEventChangeAttributesName = pszDefaultEventChangeAttributesName; }
|
||||
|
|
|
|||
|
|
@ -1014,7 +1014,7 @@ bool CTFBotSpawner::Spawn( const Vector &rawHere, EntityHandleVector_t *result )
|
|||
|
||||
nNumEnemyBots = botVector.Count();
|
||||
|
||||
if ( nNumEnemyBots >= CPopulationManager::MVM_INVADERS_TEAM_SIZE )
|
||||
if ( nNumEnemyBots >= tf_mvm_max_invaders.GetInt() )
|
||||
{
|
||||
// no room for more
|
||||
if ( tf_populator_debug.GetBool() )
|
||||
|
|
@ -1023,10 +1023,10 @@ bool CTFBotSpawner::Spawn( const Vector &rawHere, EntityHandleVector_t *result )
|
|||
}
|
||||
|
||||
// extra guard if we're over full on bots
|
||||
if ( nNumEnemyBots > CPopulationManager::MVM_INVADERS_TEAM_SIZE )
|
||||
if ( nNumEnemyBots > tf_mvm_max_invaders.GetInt() )
|
||||
{
|
||||
// Kick bots until we are at the proper number starting with spectator bots
|
||||
int iNumberToKick = nNumEnemyBots - CPopulationManager::MVM_INVADERS_TEAM_SIZE;
|
||||
int iNumberToKick = nNumEnemyBots - tf_mvm_max_invaders.GetInt();
|
||||
int iKickedBots = 0;
|
||||
|
||||
// loop through spectators and invaders in that order
|
||||
|
|
|
|||
|
|
@ -741,7 +741,7 @@ bool CMissionPopulator::UpdateMission( CTFBot::MissionType mission )
|
|||
// are there enough free slots?
|
||||
int currentEnemyCount = GetGlobalTeam( TF_TEAM_PVE_INVADERS )->GetNumPlayers();
|
||||
|
||||
if ( currentEnemyCount + m_desiredCount > CPopulationManager::MVM_INVADERS_TEAM_SIZE )
|
||||
if ( currentEnemyCount + m_desiredCount > tf_mvm_max_invaders.GetInt() )
|
||||
{
|
||||
// not enough slots yet
|
||||
if ( tf_populator_debug.GetBool() )
|
||||
|
|
@ -1578,7 +1578,7 @@ void CWaveSpawnPopulator::Update( void )
|
|||
|
||||
int currentEnemyCount = GetGlobalTeam( TF_TEAM_PVE_INVADERS )->GetNumPlayers();
|
||||
|
||||
if ( currentEnemyCount + m_spawnCount + m_reservedPlayerSlotCount > CPopulationManager::MVM_INVADERS_TEAM_SIZE )
|
||||
if ( currentEnemyCount + m_spawnCount + m_reservedPlayerSlotCount > tf_mvm_max_invaders.GetInt() )
|
||||
{
|
||||
// no space right now
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -126,7 +126,6 @@
|
|||
#include "tf_revive.h"
|
||||
#include "tf_logic_halloween_2014.h"
|
||||
#include "tf_logic_player_destruction.h"
|
||||
#include "tf_weapon_rocketpack.h"
|
||||
#include "tf_weapon_slap.h"
|
||||
#include "func_croc.h"
|
||||
#include "tf_weapon_bonesaw.h"
|
||||
|
|
@ -278,6 +277,7 @@ extern ConVar sv_vote_allow_spectators;
|
|||
ConVar sv_vote_late_join_time( "sv_vote_late_join_time", "90", FCVAR_NONE, "Grace period after the match starts before players who join the match receive a vote-creation cooldown" );
|
||||
ConVar sv_vote_late_join_cooldown( "sv_vote_late_join_cooldown", "300", FCVAR_NONE, "Length of the vote-creation cooldown when joining the server after the grace period has expired" );
|
||||
|
||||
extern ConVar tf_voice_command_suspension_mode;
|
||||
extern ConVar tf_feign_death_duration;
|
||||
extern ConVar spec_freeze_time;
|
||||
extern ConVar spec_freeze_traveltime;
|
||||
|
|
@ -997,7 +997,6 @@ CTFPlayer::CTFPlayer()
|
|||
m_flNextChangeClassTime = 0.0f;
|
||||
m_flNextChangeTeamTime = 0.0f;
|
||||
|
||||
m_bScattergunJump = false;
|
||||
m_iOldStunFlags = 0;
|
||||
m_iLastWeaponSlot = 1;
|
||||
m_iNumberofDominations = 0;
|
||||
|
|
@ -1453,35 +1452,6 @@ void CTFPlayer::TFPlayerThink()
|
|||
else
|
||||
{
|
||||
m_iLeftGroundHealth = -1;
|
||||
if ( GetFlags() & FL_ONGROUND )
|
||||
{
|
||||
// Airborne conditions end on ground contact
|
||||
m_Shared.RemoveCond( TF_COND_KNOCKED_INTO_AIR );
|
||||
m_Shared.RemoveCond( TF_COND_AIR_CURRENT );
|
||||
|
||||
if ( m_Shared.InCond( TF_COND_ROCKETPACK ) )
|
||||
{
|
||||
// Make sure we're still not dealing with launch, where it's possible
|
||||
// to hit your head and fall to the ground before the second stage.
|
||||
CTFWeaponBase *pRocketPack = Weapon_OwnsThisID( TF_WEAPON_ROCKETPACK );
|
||||
if ( pRocketPack )
|
||||
{
|
||||
if ( gpGlobals->curtime > ( static_cast< CTFRocketPack* >( pRocketPack )->GetRefireTime() ) )
|
||||
{
|
||||
EmitSound( "Weapon_RocketPack.BoostersShutdown" );
|
||||
EmitSound( "Weapon_RocketPack.Land" );
|
||||
m_Shared.RemoveCond( TF_COND_ROCKETPACK );
|
||||
|
||||
IGameEvent *pEvent = gameeventmanager->CreateEvent( "rocketpack_landed" );
|
||||
if ( pEvent )
|
||||
{
|
||||
pEvent->SetInt( "userid", GetUserID() );
|
||||
gameeventmanager->FireEvent( pEvent );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_iBlastJumpState )
|
||||
{
|
||||
|
|
@ -2833,6 +2803,7 @@ void CTFPlayer::PrecacheMvM()
|
|||
PrecacheScriptSound( "MVM.DeployBombGiant" );
|
||||
PrecacheScriptSound( "Weapon_Upgrade.ExplosiveHeadshot" );
|
||||
PrecacheScriptSound( "Spy.MVM_Chuckle" );
|
||||
PrecacheScriptSound( "Spy.MVM_TeaseVictim" );
|
||||
PrecacheScriptSound( "MVM.Robot_Engineer_Spawn" );
|
||||
PrecacheScriptSound( "MVM.Robot_Teleporter_Deliver" );
|
||||
PrecacheScriptSound( "MVM.MoneyPickup" );
|
||||
|
|
@ -3781,7 +3752,6 @@ void CTFPlayer::Spawn()
|
|||
|
||||
m_Shared.SetFeignDeathReady( false );
|
||||
|
||||
m_bScattergunJump = false;
|
||||
m_iOldStunFlags = 0;
|
||||
|
||||
m_flAccumulatedHealthRegen = 0;
|
||||
|
|
@ -9127,44 +9097,40 @@ int CTFPlayer::OnTakeDamage( const CTakeDamageInfo &inputInfo )
|
|||
}
|
||||
}
|
||||
|
||||
if ( pTFAttacker && pTFAttacker->IsPlayerClass( TF_CLASS_MEDIC ) )
|
||||
if ( pTFAttacker && pTFAttacker->IsPlayerClass( TF_CLASS_MEDIC ) && pWeapon && pWeapon->GetWeaponID() == TF_WEAPON_BONESAW )
|
||||
{
|
||||
CTFWeaponBase *pAttackerWeapon = pTFAttacker->GetActiveTFWeapon();
|
||||
if ( pAttackerWeapon && pAttackerWeapon->GetWeaponID() == TF_WEAPON_BONESAW )
|
||||
CTFBonesaw *pBoneSaw = static_cast< CTFBonesaw* >( pWeapon );
|
||||
if ( pBoneSaw->GetBonesawType() == BONESAW_UBER_SAVEDONDEATH )
|
||||
{
|
||||
CTFBonesaw *pBoneSaw = static_cast< CTFBonesaw* >( pAttackerWeapon );
|
||||
if ( pBoneSaw->GetBonesawType() == BONESAW_UBER_SAVEDONDEATH )
|
||||
// Spawn their spleen
|
||||
CPhysicsProp *pRandomInternalOrgan = dynamic_cast< CPhysicsProp* >( CreateEntityByName( "prop_physics_override" ) );
|
||||
if ( pRandomInternalOrgan )
|
||||
{
|
||||
// Spawn their spleen
|
||||
CPhysicsProp *pRandomInternalOrgan = dynamic_cast< CPhysicsProp* >( CreateEntityByName( "prop_physics_override" ) );
|
||||
if ( pRandomInternalOrgan )
|
||||
{
|
||||
pRandomInternalOrgan->SetCollisionGroup( COLLISION_GROUP_DEBRIS );
|
||||
pRandomInternalOrgan->AddFlag( FL_GRENADE );
|
||||
char buf[512];
|
||||
Q_snprintf( buf, sizeof( buf ), "%.10f %.10f %.10f", GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z );
|
||||
pRandomInternalOrgan->KeyValue( "origin", buf );
|
||||
Q_snprintf( buf, sizeof( buf ), "%.10f %.10f %.10f", GetAbsAngles().x, GetAbsAngles().y, GetAbsAngles().z );
|
||||
pRandomInternalOrgan->KeyValue( "angles", buf );
|
||||
pRandomInternalOrgan->KeyValue( "model", "models/player/gibs/random_organ.mdl" );
|
||||
pRandomInternalOrgan->KeyValue( "fademindist", "-1" );
|
||||
pRandomInternalOrgan->KeyValue( "fademaxdist", "0" );
|
||||
pRandomInternalOrgan->KeyValue( "fadescale", "1" );
|
||||
pRandomInternalOrgan->KeyValue( "inertiaScale", "1.0" );
|
||||
pRandomInternalOrgan->KeyValue( "physdamagescale", "0.1" );
|
||||
DispatchSpawn( pRandomInternalOrgan );
|
||||
pRandomInternalOrgan->m_takedamage = DAMAGE_YES; // Take damage, otherwise this can block trains
|
||||
pRandomInternalOrgan->SetHealth( 100 );
|
||||
pRandomInternalOrgan->Activate();
|
||||
pRandomInternalOrgan->SetCollisionGroup( COLLISION_GROUP_DEBRIS );
|
||||
pRandomInternalOrgan->AddFlag( FL_GRENADE );
|
||||
char buf[512];
|
||||
Q_snprintf( buf, sizeof( buf ), "%.10f %.10f %.10f", GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z );
|
||||
pRandomInternalOrgan->KeyValue( "origin", buf );
|
||||
Q_snprintf( buf, sizeof( buf ), "%.10f %.10f %.10f", GetAbsAngles().x, GetAbsAngles().y, GetAbsAngles().z );
|
||||
pRandomInternalOrgan->KeyValue( "angles", buf );
|
||||
pRandomInternalOrgan->KeyValue( "model", "models/player/gibs/random_organ.mdl" );
|
||||
pRandomInternalOrgan->KeyValue( "fademindist", "-1" );
|
||||
pRandomInternalOrgan->KeyValue( "fademaxdist", "0" );
|
||||
pRandomInternalOrgan->KeyValue( "fadescale", "1" );
|
||||
pRandomInternalOrgan->KeyValue( "inertiaScale", "1.0" );
|
||||
pRandomInternalOrgan->KeyValue( "physdamagescale", "0.1" );
|
||||
DispatchSpawn( pRandomInternalOrgan );
|
||||
pRandomInternalOrgan->m_takedamage = DAMAGE_YES; // Take damage, otherwise this can block trains
|
||||
pRandomInternalOrgan->SetHealth( 100 );
|
||||
pRandomInternalOrgan->Activate();
|
||||
|
||||
Vector vecImpulse = RandomVector( -1.f, 1.f );
|
||||
vecImpulse.z = 1.f;
|
||||
VectorNormalize( vecImpulse );
|
||||
Vector vecVelocity = vecImpulse * 250.0;
|
||||
pRandomInternalOrgan->ApplyAbsVelocityImpulse( vecVelocity );
|
||||
Vector vecImpulse = RandomVector( -1.f, 1.f );
|
||||
vecImpulse.z = 1.f;
|
||||
VectorNormalize( vecImpulse );
|
||||
Vector vecVelocity = vecImpulse * 250.0;
|
||||
pRandomInternalOrgan->ApplyAbsVelocityImpulse( vecVelocity );
|
||||
|
||||
pRandomInternalOrgan->ThinkSet( &CBaseEntity::SUB_Remove, gpGlobals->curtime + 5.f, "DieContext" );
|
||||
}
|
||||
pRandomInternalOrgan->ThinkSet( &CBaseEntity::SUB_Remove, gpGlobals->curtime + 5.f, "DieContext" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20028,7 +19994,20 @@ bool CTFPlayer::ShouldShowVoiceSubtitleToEnemy( void )
|
|||
//-----------------------------------------------------------------------------
|
||||
bool CTFPlayer::CanSpeakVoiceCommand( void )
|
||||
{
|
||||
return ( gpGlobals->curtime > m_flNextVoiceCommandTime );
|
||||
if ( tf_voice_command_suspension_mode.GetInt() == 1 )
|
||||
return false;
|
||||
|
||||
if ( gpGlobals->curtime <= m_flNextVoiceCommandTime )
|
||||
return false;
|
||||
|
||||
// misyl: New F2P voice command rate-limiting path.
|
||||
if ( BHaveChatSuspensionInCurrentMatch() && tf_voice_command_suspension_mode.GetInt() == 2 )
|
||||
{
|
||||
if ( !m_RateLimitedVoiceCommandTokenBucket.BTakeToken( gpGlobals->curtime ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -66,6 +66,46 @@ enum EAmmoSource
|
|||
kAmmoSource_ResourceMeter, // it regenerated after a cooldown
|
||||
};
|
||||
|
||||
extern ConVar tf_voice_command_suspension_rate_limit_bucket_count;
|
||||
extern ConVar tf_voice_command_suspension_rate_limit_bucket_refill_rate;
|
||||
|
||||
class CVoiceCommandBucketSizer
|
||||
{
|
||||
public:
|
||||
int GetBucketSize() const { return tf_voice_command_suspension_rate_limit_bucket_count.GetInt(); }
|
||||
float GetBucketRefillRate() const { return tf_voice_command_suspension_rate_limit_bucket_refill_rate.GetFloat(); }
|
||||
};
|
||||
|
||||
template <typename TBucketSizer>
|
||||
class CRateLimitingTokenBucket : public TBucketSizer
|
||||
{
|
||||
public:
|
||||
CRateLimitingTokenBucket()
|
||||
: m_nBucket( this->GetBucketSize() )
|
||||
{
|
||||
}
|
||||
|
||||
bool BTakeToken( float flNow )
|
||||
{
|
||||
// misyl: This token bucket doesn't go negative, so you don't ever dig yourself into a hole by spamming.
|
||||
// You might want that if you use this class, feel free to add something to the BucketSizer.
|
||||
|
||||
int nNewBucket = MIN( m_nBucket + ( flNow - m_flLastTokenTaken ) / this->GetBucketRefillRate(), this->GetBucketSize() ) - 1;
|
||||
if ( nNewBucket <= 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nBucket = nNewBucket;
|
||||
m_flLastTokenTaken = flNow;
|
||||
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
float m_flLastTokenTaken = 0.0f;
|
||||
int m_nBucket = 0;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// TF Player
|
||||
|
|
@ -483,6 +523,8 @@ public:
|
|||
float m_flNextVoiceCommandTime;
|
||||
int m_iVoiceSpamCounter;
|
||||
|
||||
CRateLimitingTokenBucket<CVoiceCommandBucketSizer> m_RateLimitedVoiceCommandTokenBucket;
|
||||
|
||||
float m_flNextSpeakWeaponFire;
|
||||
|
||||
virtual int CalculateTeamBalanceScore( void );
|
||||
|
|
@ -938,7 +980,6 @@ public:
|
|||
|
||||
bool m_bSuicideExplode;
|
||||
|
||||
bool m_bScattergunJump;
|
||||
int m_iOldStunFlags;
|
||||
|
||||
bool m_bFlipViewModels;
|
||||
|
|
|
|||
|
|
@ -801,7 +801,7 @@ void CAchievementMgr::LoadGlobalState()
|
|||
// HPE_END
|
||||
//=============================================================================
|
||||
|
||||
KeyValues *pKV = new KeyValues("GameState" );
|
||||
KeyValuesAD pKV("GameState" );
|
||||
if ( pKV->LoadFromFile( filesystem, szFilename, "MOD" ) )
|
||||
{
|
||||
KeyValues *pNode = pKV->GetFirstSubKey();
|
||||
|
|
|
|||
|
|
@ -2607,7 +2607,7 @@ void UTIL_LoadActivityRemapFile( const char *filename, const char *section, CUtl
|
|||
return;
|
||||
}
|
||||
|
||||
KeyValues *pkvFile = new KeyValues( section );
|
||||
KeyValuesAD pkvFile( section );
|
||||
|
||||
if ( pkvFile->LoadFromFile( filesystem, filename, NULL ) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,8 +54,6 @@ BEGIN_DATADESC( CBaseGrenade )
|
|||
|
||||
END_DATADESC()
|
||||
|
||||
void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID);
|
||||
|
||||
#endif
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( BaseGrenade, DT_BaseGrenade )
|
||||
|
|
@ -70,7 +68,7 @@ BEGIN_NETWORK_TABLE( CBaseGrenade, DT_BaseGrenade )
|
|||
|
||||
SendPropVector( SENDINFO( m_vecVelocity ), 0, SPROP_NOSCALE ),
|
||||
// HACK: Use same flag bits as player for now
|
||||
SendPropInt ( SENDINFO(m_fFlags), PLAYER_FLAG_BITS, SPROP_UNSIGNED, SendProxy_CropFlagsToPlayerFlagBitsLength ),
|
||||
SendPropInt ( SENDINFO(m_fFlags), 0, SPROP_UNSIGNED ),
|
||||
#else
|
||||
RecvPropFloat( RECVINFO( m_flDamage ) ),
|
||||
RecvPropFloat( RECVINFO( m_DmgRadius ) ),
|
||||
|
|
|
|||
|
|
@ -177,10 +177,14 @@ void CEconItemSystem::ReloadWhitelist( void )
|
|||
|
||||
// If we didn't find a file, we're done.
|
||||
if ( !bFoundWhitelist )
|
||||
{
|
||||
pWhitelistKV->deleteThis();
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, go through the KVs and turn on the matching items.
|
||||
Msg("Parsing item whitelist (default: %s)\n", bDefault ? "allowed" : "disallowed" );
|
||||
KeyValues* ownerWhitelistKV = pWhitelistKV;
|
||||
pWhitelistKV = pWhitelistKV->GetFirstSubKey();
|
||||
while ( pWhitelistKV )
|
||||
{
|
||||
|
|
@ -204,6 +208,8 @@ void CEconItemSystem::ReloadWhitelist( void )
|
|||
pWhitelistKV = pWhitelistKV->GetNextKey();
|
||||
}
|
||||
Msg("Finished.\n");
|
||||
|
||||
ownerWhitelistKV->deleteThis();
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_hl2mp_player.h"
|
||||
#include <prediction.h>
|
||||
#else
|
||||
#include "hl2mp_player.h"
|
||||
#endif
|
||||
|
|
@ -133,16 +134,18 @@ void CWeapon357::PrimaryAttack( void )
|
|||
// Fire the bullets, and force the first shot to be perfectly accuracy
|
||||
pPlayer->FireBullets( info );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
//Disorient the player
|
||||
QAngle angles = pPlayer->GetLocalAngles();
|
||||
|
||||
angles.x += random->RandomInt( -1, 1 );
|
||||
angles.y += random->RandomInt( -1, 1 );
|
||||
angles.z = 0;
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
pPlayer->SnapEyeAngles( angles );
|
||||
#endif
|
||||
if ( prediction->IsFirstTimePredicted() )
|
||||
{
|
||||
QAngle angles;
|
||||
engine->GetViewAngles( angles );
|
||||
angles.x += random->RandomInt( -1, 1 );
|
||||
angles.y += random->RandomInt( -1, 1 );
|
||||
angles.z += 0.0f;
|
||||
engine->SetViewAngles( angles );
|
||||
}
|
||||
#endif // CLIENT_DLL
|
||||
|
||||
pPlayer->ViewPunch( QAngle( -8, random->RandomFloat( -2, 2 ), 0 ) );
|
||||
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ void ParseParticleEffectsMap( const char *pMapName, bool bLoadSheets )
|
|||
V_snprintf( szMapManifestFilename, sizeof( szMapManifestFilename ), "maps/%s_particles.txt", pMapName );
|
||||
}
|
||||
|
||||
KeyValues *manifest = new KeyValues( szMapManifestFilename );
|
||||
KeyValuesAD manifest( szMapManifestFilename );
|
||||
|
||||
// In order:
|
||||
// - particles.txt within the map BSP
|
||||
|
|
|
|||
|
|
@ -325,6 +325,7 @@ void CSave::Log( const char *pName, fieldtype_t fieldType, void *value, int coun
|
|||
char chValue = pValue[iCount];
|
||||
Q_snprintf( szTempBuf, sizeof( szTempBuf ), "%c", chValue );
|
||||
Q_strncat( szBuf, szTempBuf, sizeof( szTempBuf ), COPY_ALL_CHARACTERS );
|
||||
break;
|
||||
}
|
||||
case FIELD_COLOR32:
|
||||
{
|
||||
|
|
@ -332,6 +333,7 @@ void CSave::Log( const char *pName, fieldtype_t fieldType, void *value, int coun
|
|||
byte *pColor = &pValue[iCount*4];
|
||||
Q_snprintf( szTempBuf, sizeof( szTempBuf ), "(%d %d %d %d)", ( int )pColor[0], ( int )pColor[1], ( int )pColor[2], ( int )pColor[3] );
|
||||
Q_strncat( szBuf, szTempBuf, sizeof( szTempBuf ), COPY_ALL_CHARACTERS );
|
||||
break;
|
||||
}
|
||||
case FIELD_EMBEDDED:
|
||||
case FIELD_CUSTOM:
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ ConVar tf_max_charge_speed( "tf_max_charge_speed", "750", FCVAR_NOTIFY | FCVAR_R
|
|||
ConVar tf_parachute_gravity( "tf_parachute_gravity", "0.2f", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Gravity while parachute is deployed" );
|
||||
ConVar tf_parachute_maxspeed_xy( "tf_parachute_maxspeed_xy", "300.0f", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Max XY Speed while Parachute is deployed" );
|
||||
ConVar tf_parachute_maxspeed_z( "tf_parachute_maxspeed_z", "-100.0f", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Max Z Speed while Parachute is deployed" );
|
||||
ConVar tf_parachute_maxspeed_onfire_z( "tf_parachute_maxspeed_onfire_z", "10.0f", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Max Z Speed when on Fire and Parachute is deployed" );
|
||||
ConVar tf_parachute_maxspeed_onfire_z( "tf_parachute_maxspeed_onfire_z", "-100.0f", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Max Z Speed when on Fire and Parachute is deployed" );
|
||||
ConVar tf_parachute_aircontrol( "tf_parachute_aircontrol", "2.5f", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Multiplier for how much air control players have when Parachute is deployed" );
|
||||
ConVar tf_parachute_deploy_toggle_allowed( "tf_parachute_deploy_toggle_allowed", "0", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY );
|
||||
|
||||
|
|
@ -1115,12 +1115,6 @@ void CTFGameMovement::PreventBunnyJumping()
|
|||
//-----------------------------------------------------------------------------
|
||||
void CTFGameMovement::ToggleParachute()
|
||||
{
|
||||
if ( ( m_pTFPlayer->GetFlags() & FL_ONGROUND ) )
|
||||
{
|
||||
m_pTFPlayer->m_Shared.RemoveCond( TF_COND_PARACHUTE_DEPLOYED );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mv->m_nOldButtons & IN_JUMP )
|
||||
return;
|
||||
|
||||
|
|
@ -1147,9 +1141,10 @@ void CTFGameMovement::ToggleParachute()
|
|||
}
|
||||
else
|
||||
{
|
||||
bool bOnGround = ( m_pTFPlayer->GetFlags() & FL_ONGROUND );
|
||||
int iParachuteDisabled = 0;
|
||||
CALL_ATTRIB_HOOK_INT_ON_OTHER( m_pTFPlayer, iParachuteDisabled, parachute_disabled );
|
||||
if ( !iParachuteDisabled && ( tf_parachute_deploy_toggle_allowed.GetBool() || !m_pTFPlayer->m_Shared.InCond( TF_COND_PARACHUTE_DEPLOYED ) ) )
|
||||
if ( !bOnGround && !iParachuteDisabled && ( tf_parachute_deploy_toggle_allowed.GetBool() || !m_pTFPlayer->m_Shared.InCond( TF_COND_PARACHUTE_DEPLOYED ) ) )
|
||||
{
|
||||
m_pTFPlayer->m_Shared.AddCond( TF_COND_PARACHUTE_ACTIVE );
|
||||
m_pTFPlayer->m_Shared.AddCond( TF_COND_PARACHUTE_DEPLOYED );
|
||||
|
|
@ -1381,7 +1376,7 @@ int CTFGameMovement::CheckStuck( void )
|
|||
m_pTFPlayer->GetTeam()->GetName(),
|
||||
m_pTFPlayer->GetAbsOrigin().x, m_pTFPlayer->GetAbsOrigin().y, m_pTFPlayer->GetAbsOrigin().z );
|
||||
|
||||
m_pTFPlayer->TakeDamage( CTakeDamageInfo( m_pTFPlayer, m_pTFPlayer, vec3_origin, m_pTFPlayer->WorldSpaceCenter(), 999999.9f, DMG_CRUSH ) );
|
||||
m_pTFPlayer->CommitSuicide( false, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2629,8 +2624,8 @@ void CTFGameMovement::FullWalkMove()
|
|||
{
|
||||
if ( m_pTFPlayer->m_Shared.InCond( TF_COND_PARACHUTE_ACTIVE ) && mv->m_vecVelocity[2] < 0 )
|
||||
{
|
||||
mv->m_vecVelocity[2] = Max( mv->m_vecVelocity[2], tf_parachute_maxspeed_z.GetFloat() );
|
||||
|
||||
mv->m_vecVelocity[2] = Max( mv->m_vecVelocity[2], m_pTFPlayer->m_Shared.InCond( TF_COND_BURNING ) ? tf_parachute_maxspeed_onfire_z.GetFloat() : tf_parachute_maxspeed_z.GetFloat() );
|
||||
|
||||
float flDrag = tf_parachute_maxspeed_xy.GetFloat();
|
||||
// Instead of clamping, we'll dampen
|
||||
float flSpeedX = abs( mv->m_vecVelocity[0] );
|
||||
|
|
@ -2956,9 +2951,9 @@ void CTFGameMovement::SetGroundEntity( trace_t *pm )
|
|||
{
|
||||
m_pTFPlayer->SpeakConceptIfAllowed( MP_CONCEPT_DOUBLE_JUMP, "started_jumping:0" );
|
||||
}
|
||||
m_pTFPlayer->m_Shared.SetWeaponKnockbackID( -1 );
|
||||
m_pTFPlayer->m_bScattergunJump = false;
|
||||
#endif // GAME_DLL
|
||||
m_pTFPlayer->m_Shared.SetWeaponKnockbackID( -1 );
|
||||
m_pTFPlayer->m_Shared.m_bScattergunJump = false;
|
||||
m_pTFPlayer->m_Shared.SetAirDash( 0 );
|
||||
m_pTFPlayer->m_Shared.SetAirDucked( 0 );
|
||||
|
||||
|
|
|
|||
|
|
@ -875,6 +875,7 @@ ConVar tf_raid_allow_overtime( "tf_raid_allow_overtime", "0"/*, FCVAR_CHEAT*/ );
|
|||
|
||||
ConVar tf_mvm_defenders_team_size( "tf_mvm_defenders_team_size", "6", FCVAR_REPLICATED | FCVAR_NOTIFY, "Maximum number of defenders in MvM" );
|
||||
ConVar tf_mvm_max_connected_players( "tf_mvm_max_connected_players", "10", FCVAR_GAMEDLL, "Maximum number of connected real players in MvM" );
|
||||
ConVar tf_mvm_max_invaders( "tf_mvm_max_invaders", "22", FCVAR_GAMEDLL, "Maximum number of invaders in MvM" );
|
||||
|
||||
ConVar tf_mvm_min_players_to_start( "tf_mvm_min_players_to_start", "3", FCVAR_REPLICATED | FCVAR_NOTIFY, "Minimum number of players connected to start a countdown timer" );
|
||||
ConVar tf_mvm_respec_enabled( "tf_mvm_respec_enabled", "1", FCVAR_CHEAT | FCVAR_REPLICATED, "Allow players to refund credits spent on player and item upgrades." );
|
||||
|
|
@ -1106,7 +1107,13 @@ ConVar tf_competitive_required_late_join_confirm_timeout( "tf_competitive_requir
|
|||
|
||||
ConVar tf_gamemode_community ( "tf_gamemode_community", "0", FCVAR_REPLICATED | FCVAR_NOTIFY | FCVAR_DEVELOPMENTONLY );
|
||||
|
||||
ConVar tf_voice_command_suspension_mode( "tf_voice_command_suspension_mode", "2", FCVAR_REPLICATED, "0 = None | 1 = No Voice Commands | 2 = Rate Limited" );
|
||||
|
||||
#ifdef GAME_DLL
|
||||
|
||||
ConVar tf_voice_command_suspension_rate_limit_bucket_count( "tf_voice_command_suspension_rate_limit_bucket_count", "5" ); // Bucket size of 5.
|
||||
ConVar tf_voice_command_suspension_rate_limit_bucket_refill_rate( "tf_voice_command_suspension_rate_limit_bucket_refill_rate", "6" ); // 6s
|
||||
|
||||
void cc_powerup_mode( IConVar *pConVar, const char *pOldString, float flOldValue )
|
||||
{
|
||||
ConVarRef var( pConVar );
|
||||
|
|
@ -10126,7 +10133,12 @@ VoiceCommandMenuItem_t *CTFGameRules::VoiceCommand( CBaseMultiplayerPlayer *pPla
|
|||
if ( pTFPlayer )
|
||||
{
|
||||
if ( pTFPlayer->BHaveChatSuspensionInCurrentMatch() )
|
||||
return NULL;
|
||||
{
|
||||
if ( tf_voice_command_suspension_mode.GetInt() == 1 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pTFPlayer->m_Shared.InCond( TF_COND_HALLOWEEN_GHOST_MODE ) )
|
||||
{
|
||||
|
|
@ -16966,7 +16978,7 @@ int CTFGameRules::CalcPlayerScore( RoundStats_t *pRoundStats, CTFPlayer *pPlayer
|
|||
( pRoundStats->m_iStat[TFSTAT_TELEPORTS] / TF_SCORE_TELEPORTS_PER_POINT ) +
|
||||
( pRoundStats->m_iStat[TFSTAT_INVULNS] / TF_SCORE_INVULN ) +
|
||||
( pRoundStats->m_iStat[TFSTAT_REVENGE] / TF_SCORE_REVENGE ) +
|
||||
( pRoundStats->m_iStat[TFSTAT_BONUS_POINTS] / TF_SCORE_BONUS_POINT_DIVISOR );
|
||||
( pRoundStats->m_iStat[TFSTAT_BONUS_POINTS] / TF_SCORE_BONUS_POINT_DIVISOR ) +
|
||||
( pRoundStats->m_iStat[TFSTAT_CURRENCY_COLLECTED] / TF_SCORE_CURRENCY_COLLECTED );
|
||||
|
||||
if ( pPlayer )
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ class CMannVsMachineUpgrades;
|
|||
//extern ConVar tf_populator_damage_multiplier;
|
||||
|
||||
extern ConVar tf_mvm_defenders_team_size;
|
||||
extern ConVar tf_mvm_max_invaders;
|
||||
|
||||
const int kLadder_TeamSize_6v6 = 6;
|
||||
const int kLadder_TeamSize_9v9 = 9;
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ void CTFPowerupBottle::ReapplyProvision( void )
|
|||
// Refill weapon clips
|
||||
for ( int i = 0; i < MAX_WEAPONS; i++ )
|
||||
{
|
||||
CBaseCombatWeapon *pWeapon = pTFPlayer->GetWeapon(i);
|
||||
CTFWeaponBase *pWeapon = dynamic_cast<CTFWeaponBase *>( pTFPlayer->GetWeapon( i ) );
|
||||
if ( !pWeapon )
|
||||
continue;
|
||||
|
||||
|
|
@ -287,7 +287,8 @@ void CTFPowerupBottle::ReapplyProvision( void )
|
|||
if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
|
||||
{
|
||||
if ( ( pWeapon->UsesPrimaryAmmo() && !pWeapon->HasPrimaryAmmo() ) ||
|
||||
( pWeapon->UsesSecondaryAmmo() && !pWeapon->HasSecondaryAmmo() ) )
|
||||
( pWeapon->UsesSecondaryAmmo() && !pWeapon->HasSecondaryAmmo() ) ||
|
||||
( pWeapon->IsEnergyWeapon() && !pWeapon->Energy_HasEnergy() ) )
|
||||
{
|
||||
pTFPlayer->AwardAchievement( ACHIEVEMENT_TF_MVM_USE_AMMO_BOTTLE );
|
||||
}
|
||||
|
|
@ -297,7 +298,7 @@ void CTFPowerupBottle::ReapplyProvision( void )
|
|||
|
||||
if ( iShareBottle && pHealTarget )
|
||||
{
|
||||
CBaseCombatWeapon *pPatientWeapon = pHealTarget->GetWeapon(i);
|
||||
CTFWeaponBase *pPatientWeapon = dynamic_cast<CTFWeaponBase *>( pHealTarget->GetWeapon( i ) );
|
||||
if ( !pPatientWeapon )
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "tf_mapinfo.h"
|
||||
#include "tf_dropped_weapon.h"
|
||||
#include "tf_weapon_passtime_gun.h"
|
||||
#include "tf_weapon_rocketpack.h"
|
||||
#include <functional>
|
||||
|
||||
// Client specific.
|
||||
|
|
@ -471,7 +472,10 @@ BEGIN_PREDICTION_DATA_NO_BASE( CTFPlayerShared )
|
|||
DEFINE_PRED_FIELD( m_bHasPasstimeBall, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_bIsTargetedForPasstimePass, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), // does this belong here?
|
||||
DEFINE_PRED_FIELD( m_askForBallTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_flHolsterAnimTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_ARRAY( m_flItemChargeMeter, FIELD_FLOAT, LAST_LOADOUT_SLOT_WITH_CHARGE_METER, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_iStunIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_bScattergunJump, FIELD_BOOLEAN, 0 ),
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
// Server specific.
|
||||
|
|
@ -784,6 +788,8 @@ CTFPlayerShared::CTFPlayerShared()
|
|||
m_flPrevInvisibility = 0.f;
|
||||
m_flTmpDamageBonusAmount = 1.0f;
|
||||
|
||||
m_bScattergunJump = false;
|
||||
|
||||
m_bFeignDeathReady = false;
|
||||
|
||||
m_fCloakConsumeRate = tf_spy_cloak_consume_rate.GetFloat();
|
||||
|
|
@ -1005,7 +1011,6 @@ void CTFPlayerShared::Spawn( void )
|
|||
SetRevengeCrits( 0 );
|
||||
|
||||
m_PlayerStuns.RemoveAll();
|
||||
m_iStunIndex = -1;
|
||||
|
||||
m_iPasstimeThrowAnimState = PASSTIME_THROW_ANIM_NONE;
|
||||
m_bHasPasstimeBall = false;
|
||||
|
|
@ -1014,6 +1019,7 @@ void CTFPlayerShared::Spawn( void )
|
|||
#else
|
||||
m_bSyncingConditions = false;
|
||||
#endif
|
||||
m_iStunIndex = -1;
|
||||
m_bKingRuneBuffActive = false;
|
||||
|
||||
// Reset our assist here incase something happens before we get killed
|
||||
|
|
@ -3090,9 +3096,46 @@ void CTFPlayerShared::ConditionThink( void )
|
|||
|
||||
VehicleThink();
|
||||
|
||||
if ( m_pOuter->GetFlags() & FL_ONGROUND && InCond( TF_COND_PARACHUTE_ACTIVE ) )
|
||||
if ( m_pOuter->GetFlags() & FL_ONGROUND )
|
||||
{
|
||||
// Airborne conditions end on ground contact
|
||||
RemoveCond( TF_COND_KNOCKED_INTO_AIR );
|
||||
RemoveCond( TF_COND_AIR_CURRENT );
|
||||
|
||||
RemoveCond( TF_COND_PARACHUTE_ACTIVE );
|
||||
RemoveCond( TF_COND_PARACHUTE_DEPLOYED );
|
||||
|
||||
if ( InCond( TF_COND_ROCKETPACK ) )
|
||||
{
|
||||
// Make sure we're still not dealing with launch, where it's possible
|
||||
// to hit your head and fall to the ground before the second stage.
|
||||
CTFWeaponBase *pRocketPack = m_pOuter->Weapon_OwnsThisID( TF_WEAPON_ROCKETPACK );
|
||||
if ( pRocketPack )
|
||||
{
|
||||
if ( gpGlobals->curtime > ( static_cast< CTFRocketPack* >( pRocketPack )->GetRefireTime() ) )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
if ( prediction->IsFirstTimePredicted() )
|
||||
#endif
|
||||
{
|
||||
CPASAttenuationFilter filter( m_pOuter );
|
||||
filter.UsePredictionRules();
|
||||
m_pOuter->EmitSound( filter, m_pOuter->entindex(), "Weapon_RocketPack.BoostersShutdown" );
|
||||
m_pOuter->EmitSound( filter, m_pOuter->entindex(), "Weapon_RocketPack.Land" );
|
||||
}
|
||||
RemoveCond( TF_COND_ROCKETPACK );
|
||||
|
||||
#ifdef GAME_DLL
|
||||
IGameEvent *pEvent = gameeventmanager->CreateEvent( "rocketpack_landed" );
|
||||
if ( pEvent )
|
||||
{
|
||||
pEvent->SetInt( "userid", m_pOuter->GetUserID() );
|
||||
gameeventmanager->FireEvent( pEvent );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if we should be pulsing our radius heal
|
||||
|
|
@ -7301,6 +7344,8 @@ void CTFPlayerShared::OnRemoveStunned( void )
|
|||
m_iStunFlags = 0;
|
||||
m_hStunner = NULL;
|
||||
|
||||
m_iStunIndex = -1;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
if ( m_pOuter->m_pStunnedEffect )
|
||||
{
|
||||
|
|
@ -7310,7 +7355,6 @@ void CTFPlayerShared::OnRemoveStunned( void )
|
|||
m_pOuter->m_pStunnedEffect = NULL;
|
||||
}
|
||||
#else
|
||||
m_iStunIndex = -1;
|
||||
m_PlayerStuns.RemoveAll();
|
||||
#endif
|
||||
|
||||
|
|
@ -9624,15 +9668,16 @@ bool CTFPlayerShared::AddToSpyCloakMeter( float val, bool bForce )
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef GAME_DLL
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Stun & Snare Application
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFPlayerShared::StunPlayer( float flTime, float flReductionAmount, int iStunFlags, CTFPlayer* pAttacker )
|
||||
{
|
||||
#ifdef GAME_DLL
|
||||
// Insanity prevention
|
||||
if ( ( m_PlayerStuns.Count() + 1 ) >= 250 )
|
||||
return;
|
||||
#endif
|
||||
|
||||
if ( InCond( TF_COND_PHASE ) || InCond( TF_COND_PASSTIME_INTERCEPTION ) )
|
||||
return;
|
||||
|
|
@ -9643,15 +9688,19 @@ void CTFPlayerShared::StunPlayer( float flTime, float flReductionAmount, int iSt
|
|||
if ( InCond( TF_COND_INVULNERABLE_HIDE_UNLESS_DAMAGED ) && !InCond( TF_COND_MVM_BOT_STUN_RADIOWAVE ) )
|
||||
return;
|
||||
|
||||
#ifdef GAME_DLL
|
||||
if ( pAttacker && TFGameRules() && TFGameRules()->IsTruceActive() && pAttacker->IsTruceValidForEnt() )
|
||||
{
|
||||
if ( ( pAttacker->GetTeamNumber() == TF_TEAM_RED ) || ( pAttacker->GetTeamNumber() == TF_TEAM_BLUE ) )
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
float flRemapAmount = RemapValClamped( flReductionAmount, 0.0, 1.0, 0, 255 );
|
||||
|
||||
#ifdef GAME_DLL
|
||||
int iOldStunFlags = GetStunFlags();
|
||||
#endif
|
||||
|
||||
// Already stunned
|
||||
bool bStomp = false;
|
||||
|
|
@ -9674,10 +9723,13 @@ void CTFPlayerShared::StunPlayer( float flTime, float flReductionAmount, int iSt
|
|||
}
|
||||
else if ( GetActiveStunInfo() )
|
||||
{
|
||||
#ifdef GAME_DLL
|
||||
// Something yanked our TF_COND_STUNNED in an unexpected way
|
||||
if ( !HushAsserts() )
|
||||
Assert( !"Something yanked out TF_COND_STUNNED." );
|
||||
m_PlayerStuns.RemoveAll();
|
||||
#endif
|
||||
m_iStunIndex = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -9699,7 +9751,16 @@ void CTFPlayerShared::StunPlayer( float flTime, float flReductionAmount, int iSt
|
|||
// This can happen when stuns use TF_STUN_CONTROLS or TF_STUN_LOSER_STATE.
|
||||
float flOldStun = GetActiveStunInfo() ? GetActiveStunInfo()->flStunAmount : 0.f;
|
||||
|
||||
#ifdef GAME_DLL
|
||||
m_iStunIndex = m_PlayerStuns.AddToTail( stunEvent );
|
||||
#else
|
||||
m_iStunIndex = 0;
|
||||
|
||||
if ( prediction->IsFirstTimePredicted() )
|
||||
{
|
||||
m_ActiveStunInfo = stunEvent;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( flOldStun > flRemapAmount )
|
||||
{
|
||||
|
|
@ -9709,10 +9770,18 @@ void CTFPlayerShared::StunPlayer( float flTime, float flReductionAmount, int iSt
|
|||
else
|
||||
{
|
||||
// Done for now
|
||||
#ifdef GAME_DLL
|
||||
m_PlayerStuns.AddToTail( stunEvent );
|
||||
#else
|
||||
if ( prediction->IsFirstTimePredicted() )
|
||||
{
|
||||
m_ActiveStunInfo = stunEvent;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
// Add in extra time when TF_STUN_CONTROLS
|
||||
if ( GetActiveStunInfo()->iStunFlags & TF_STUN_CONTROLS )
|
||||
{
|
||||
|
|
@ -9766,10 +9835,10 @@ void CTFPlayerShared::StunPlayer( float flTime, float flReductionAmount, int iSt
|
|||
m_pOuter->ClearExpression();
|
||||
m_pOuter->ClearWeaponFireScene();
|
||||
}
|
||||
#endif
|
||||
|
||||
AddCond( TF_COND_STUNNED, -1.f, pAttacker );
|
||||
}
|
||||
#endif // GAME_DLL
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns the intensity of the current stun effect, if we have the type of stun indicated.
|
||||
|
|
@ -12110,6 +12179,13 @@ bool CTFPlayer::CanJump() const
|
|||
if ( m_Shared.InCond( TF_COND_TAUNTING ) )
|
||||
return false;
|
||||
|
||||
CTFWeaponBase *pActiveWeapon = m_Shared.GetActiveTFWeapon();
|
||||
if ( pActiveWeapon )
|
||||
{
|
||||
if ( !pActiveWeapon->OwnerCanJump() )
|
||||
return false;
|
||||
}
|
||||
|
||||
int iNoJump = 0;
|
||||
CALL_ATTRIB_HOOK_INT( iNoJump, no_jump );
|
||||
|
||||
|
|
|
|||
|
|
@ -560,9 +560,7 @@ public:
|
|||
|
||||
// Stuns
|
||||
stun_struct_t *GetActiveStunInfo( void ) const;
|
||||
#ifdef GAME_DLL
|
||||
void StunPlayer( float flTime, float flReductionAmount, int iStunFlags = TF_STUN_MOVEMENT, CTFPlayer* pAttacker = NULL );
|
||||
#endif // GAME_DLL
|
||||
float GetAmountStunned( int iStunFlags );
|
||||
bool IsLoserStateStunned( void ) const;
|
||||
bool IsControlStunned( void );
|
||||
|
|
@ -1218,6 +1216,8 @@ private:
|
|||
#endif
|
||||
|
||||
public:
|
||||
bool m_bScattergunJump;
|
||||
|
||||
float m_flStunFade;
|
||||
float m_flStunEnd;
|
||||
float m_flStunMid;
|
||||
|
|
|
|||
|
|
@ -1144,7 +1144,7 @@ protected:
|
|||
|
||||
int nNumJumps = pNonConstPlayer->GetGroundEntity() == NULL ? 1 : 0;
|
||||
nNumJumps += pPlayer->m_Shared.GetAirDash();
|
||||
nNumJumps += pPlayer->m_bScattergunJump;
|
||||
nNumJumps += pPlayer->m_Shared.m_bScattergunJump;
|
||||
|
||||
if ( m_eJumpingState == JUMPING_STATE_IS_NOT_JUMPING )
|
||||
{
|
||||
|
|
@ -3027,7 +3027,7 @@ bool CTFJumpStateQuestModifier::BPassesModifier( const CTFPlayer *pOwner, Invali
|
|||
#else
|
||||
int nNumJumps = const_cast< CTFPlayer* >( pOwner )->GetGroundEntity() == NULL ? 1 : 0;
|
||||
nNumJumps += pOwner->m_Shared.GetAirDash();
|
||||
nNumJumps += pOwner->m_bScattergunJump;
|
||||
nNumJumps += pOwner->m_Shared.m_bScattergunJump;
|
||||
|
||||
// If we want them on the ground, make sure they're on the ground
|
||||
if ( m_nJumpCount == 0 )
|
||||
|
|
|
|||
|
|
@ -654,19 +654,7 @@ void CTFCompoundBow::SetArrowAlight( bool bAlight )
|
|||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFCompoundBow::SetInternalChargeBeginTime( float flChargeBeginTime )
|
||||
bool CTFCompoundBow::OwnerCanJump( void )
|
||||
{
|
||||
#ifdef GAME_DLL
|
||||
float flCurrentChargeBeginTime = GetInternalChargeBeginTime();
|
||||
if ( flCurrentChargeBeginTime == 0.f && flChargeBeginTime > 0.f )
|
||||
{
|
||||
DisableJump();
|
||||
}
|
||||
else if ( flCurrentChargeBeginTime > 0.f && flChargeBeginTime == 0.f )
|
||||
{
|
||||
EnableJump();
|
||||
}
|
||||
#endif // GAME_DLL
|
||||
|
||||
BaseClass::SetInternalChargeBeginTime( flChargeBeginTime );
|
||||
return GetInternalChargeBeginTime() == 0.f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,8 +89,7 @@ public:
|
|||
|
||||
void SetArrowAlight( bool bAlight );
|
||||
|
||||
protected:
|
||||
virtual void SetInternalChargeBeginTime( float flChargeBeginTime ) OVERRIDE;
|
||||
bool OwnerCanJump( void );
|
||||
|
||||
private:
|
||||
#ifdef CLIENT_DLL
|
||||
|
|
|
|||
|
|
@ -2110,7 +2110,7 @@ bool CTFFlameThrower::EffectMeterShouldFlash( void )
|
|||
//-----------------------------------------------------------------------------
|
||||
Vector CTFFlameThrower::GetMuzzlePosHelper( bool bVisualPos )
|
||||
{
|
||||
Vector vecMuzzlePos;
|
||||
Vector vecMuzzlePos = vec3_origin;
|
||||
CTFPlayer *pOwner = GetTFPlayerOwner();
|
||||
if ( pOwner )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#ifdef CLIENT_DLL
|
||||
#include "c_tf_player.h"
|
||||
#include "c_rope.h"
|
||||
#include "prediction.h"
|
||||
// Server specific.
|
||||
#else
|
||||
#include "tf_player.h"
|
||||
|
|
@ -47,7 +48,10 @@ END_NETWORK_TABLE()
|
|||
#ifdef CLIENT_DLL
|
||||
BEGIN_PREDICTION_DATA( CTFRocketPack )
|
||||
DEFINE_PRED_FIELD( m_flInitLaunchTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_flLaunchTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_flToggleEndTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_flRefireTime, FIELD_FLOAT, 0 ),
|
||||
DEFINE_PRED_FIELD( m_bLaunchedFromGround, FIELD_BOOLEAN, 0 ),
|
||||
END_PREDICTION_DATA()
|
||||
#endif // CLIENT_DLL
|
||||
|
||||
|
|
@ -211,10 +215,13 @@ bool CTFRocketPack::InitiateLaunch( void )
|
|||
CTFPlayer *pOwner = GetTFPlayerOwner();
|
||||
if ( !pOwner->m_Shared.IsRocketPackReady() )
|
||||
{
|
||||
#ifdef GAME_DLL
|
||||
CPVSFilter filter( WorldSpaceCenter() );
|
||||
pOwner->EmitSound( filter, entindex(), "Weapon_RocketPack.BoostersNotReady" );
|
||||
#endif // GAME_DLL
|
||||
// note: this is never reached
|
||||
#ifdef CLIENT_DLL
|
||||
if ( prediction->IsFirstTimePredicted() )
|
||||
{
|
||||
pOwner->EmitSound( "Weapon_RocketPack.BoostersNotReady" );
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -224,16 +231,18 @@ bool CTFRocketPack::InitiateLaunch( void )
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
if ( pOwner->m_Shared.IsLoser() )
|
||||
#ifdef CLIENT_DLL
|
||||
if ( prediction->IsFirstTimePredicted() )
|
||||
#endif
|
||||
{
|
||||
pOwner->EmitSound( "Weapon_RocketPack.BoostersNotReady" );
|
||||
CPASAttenuationFilter filter( pOwner );
|
||||
filter.UsePredictionRules();
|
||||
pOwner->EmitSound(
|
||||
filter,
|
||||
entindex(),
|
||||
pOwner->m_Shared.IsLoser() ? "Weapon_RocketPack.BoostersNotReady" : "Weapon_RocketPack.BoostersCharge"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
pOwner->EmitSound( "Weapon_RocketPack.BoostersCharge" );
|
||||
}
|
||||
#endif // GAME_DLL
|
||||
|
||||
m_flInitLaunchTime = gpGlobals->curtime;
|
||||
|
||||
|
|
@ -369,7 +378,6 @@ bool CTFRocketPack::ShouldDraw()
|
|||
|
||||
#endif // CLIENT_DLL
|
||||
|
||||
#ifdef GAME_DLL
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -384,7 +392,7 @@ Vector CTFRocketPack::CalcRocketForceFromPlayer( CTFPlayer *pPlayer )
|
|||
const float flVertPushScale = ( bOnGround ) ? 0.7f : 0.25f; // Less vertical force while airborne
|
||||
|
||||
Vector vecForward, vecRight;
|
||||
QAngle angAim = ( bOnGround ) ? pPlayer->GetAbsAngles() : pPlayer->EyeAngles();
|
||||
QAngle angAim = pPlayer->EyeAngles();
|
||||
AngleVectors( angAim, &vecForward, &vecRight, NULL );
|
||||
bool bNone = !( pPlayer->m_nButtons & IN_FORWARD ) &&
|
||||
!( pPlayer->m_nButtons & IN_BACK ) /* &&
|
||||
|
|
@ -468,7 +476,6 @@ void CTFRocketPack::RocketLaunchPlayer( CTFPlayer *pPlayer, const Vector& vecFor
|
|||
|
||||
pPlayer->ApplyAbsVelocityImpulse( vecForce );
|
||||
}
|
||||
#endif // GAME_DLL
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
|
|
@ -482,7 +489,6 @@ bool CTFRocketPack::PreLaunch( void )
|
|||
pOwner->DoAnimationEvent( PLAYERANIMEVENT_CUSTOM, ACT_MP_ATTACK_STAND_PRIMARYFIRE );
|
||||
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
|
||||
|
||||
#ifdef GAME_DLL
|
||||
// Negate any fall
|
||||
Vector vecVel = pOwner->GetAbsVelocity();
|
||||
if ( vecVel.z < 0.f )
|
||||
|
|
@ -496,14 +502,15 @@ bool CTFRocketPack::PreLaunch( void )
|
|||
pOwner->ApplyAbsVelocityImpulse( vForward );
|
||||
pOwner->m_Shared.AddCond( TF_COND_PARACHUTE_ACTIVE );
|
||||
|
||||
#ifdef GAME_DLL
|
||||
const Vector &vecOrigin = pOwner->GetAbsOrigin();
|
||||
CPVSFilter filter( vecOrigin );
|
||||
TE_TFParticleEffect( filter, 0.f, "heavy_ring_of_fire", vecOrigin, vec3_angle );
|
||||
DispatchParticleEffect( "rocketjump_smoke", PATTACH_POINT_FOLLOW, pOwner, "foot_L" );
|
||||
DispatchParticleEffect( "rocketjump_smoke", PATTACH_POINT_FOLLOW, pOwner, "foot_R" );
|
||||
#endif // GAME_DLL
|
||||
|
||||
m_flLaunchTime = gpGlobals->curtime + tf_rocketpack_launch_delay.GetFloat();
|
||||
#endif // GAME_DLL
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -519,16 +526,20 @@ bool CTFRocketPack::Launch( void )
|
|||
|
||||
pOwner->StopSound( "Weapon_LooseCannon.Charge" );
|
||||
|
||||
#ifdef GAME_DLL
|
||||
m_flLaunchTime = 0.f;
|
||||
pOwner->m_Shared.RemoveCond( TF_COND_PARACHUTE_ACTIVE );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
Vector m_vecLaunchDir;
|
||||
#endif
|
||||
// Launch
|
||||
m_vecLaunchDir = CalcRocketForceFromPlayer( pOwner );
|
||||
RocketLaunchPlayer( pOwner, m_vecLaunchDir, false );
|
||||
|
||||
|
||||
|
||||
#ifdef GAME_DLL
|
||||
SetContextThink( &CTFRocketPack::PassengerDelayLaunchThink, gpGlobals->curtime + TF_ROCKETPACK_PASSENGER_DELAY_LAUNCH, "PassengerDelayLaunchThink" );
|
||||
#endif
|
||||
|
||||
m_flRefireTime = gpGlobals->curtime + 0.5f;
|
||||
|
||||
|
|
@ -536,6 +547,7 @@ bool CTFRocketPack::Launch( void )
|
|||
pOwner->m_Shared.SetRocketPackCharge( pOwner->m_Shared.GetRocketPackCharge() - tf_rocketpack_cost.GetFloat() );
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
// Knock-back nearby enemies
|
||||
float flRadius = 150.f;
|
||||
CUtlVector< CTFPlayer* > vecPushedPlayers;
|
||||
|
|
@ -594,6 +606,7 @@ bool CTFRocketPack::Launch( void )
|
|||
}
|
||||
|
||||
CPASAttenuationFilter filter( pOwner );
|
||||
filter.UsePredictionRules();
|
||||
pOwner->EmitSound( filter, pOwner->entindex(), "Weapon_RocketPack.BoostersFire" );
|
||||
|
||||
IGameEvent *pEvent = gameeventmanager->CreateEvent( "rocketpack_launch" );
|
||||
|
|
@ -610,7 +623,12 @@ bool CTFRocketPack::Launch( void )
|
|||
DispatchParticleEffect( ROCKET_PACK_LAUNCH_EFFECT, PATTACH_POINT_FOLLOW, pWearable, "charge_LA" );
|
||||
DispatchParticleEffect( ROCKET_PACK_LAUNCH_EFFECT, PATTACH_POINT_FOLLOW, pWearable, "charge_RA" );
|
||||
}
|
||||
#endif // GAME_DLL
|
||||
#else
|
||||
if ( prediction->IsFirstTimePredicted() )
|
||||
{
|
||||
pOwner->EmitSound( "Weapon_RocketPack.BoostersFire" );
|
||||
}
|
||||
#endif // CLIENT_DLL
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -748,7 +766,7 @@ void CTFRocketPack::ItemPostFrame( void )
|
|||
{
|
||||
ResetTransition();
|
||||
#ifdef CLIENT_DLL
|
||||
if ( pOwner == C_TFPlayer::GetLocalTFPlayer() )
|
||||
if ( pOwner == C_TFPlayer::GetLocalTFPlayer() && prediction->IsFirstTimePredicted() )
|
||||
{
|
||||
pOwner->EmitSound( "Weapon_RocketPack.BoostersReady" );
|
||||
}
|
||||
|
|
@ -757,7 +775,7 @@ void CTFRocketPack::ItemPostFrame( void )
|
|||
else if ( pOwner->m_afButtonPressed & IN_ATTACK2 )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
if ( pOwner == C_TFPlayer::GetLocalTFPlayer() )
|
||||
if ( pOwner == C_TFPlayer::GetLocalTFPlayer() && prediction->IsFirstTimePredicted() )
|
||||
{
|
||||
pOwner->EmitSound( "Player.DenyWeaponSelection" );
|
||||
}
|
||||
|
|
@ -841,14 +859,21 @@ const CEconItemView *CTFRocketPack::GetTauntItem() const
|
|||
//-----------------------------------------------------------------------------
|
||||
bool CTFRocketPack::Deploy( void )
|
||||
{
|
||||
#ifdef GAME_DLL
|
||||
CTFPlayer *pOwner = GetTFPlayerOwner();
|
||||
if ( pOwner )
|
||||
{
|
||||
EmitSound( "Weapon_RocketPack.BoostersExtend" );
|
||||
#ifdef CLIENT_DLL
|
||||
if ( prediction->IsFirstTimePredicted() )
|
||||
#endif
|
||||
{
|
||||
CPASAttenuationFilter filter( pOwner );
|
||||
filter.UsePredictionRules();
|
||||
EmitSound( filter, entindex(), "Weapon_RocketPack.BoostersExtend" );
|
||||
}
|
||||
#ifdef GAME_DLL
|
||||
SetEnabled( true );
|
||||
#endif
|
||||
}
|
||||
#endif // GAME_DLL
|
||||
|
||||
return BaseClass::Deploy();
|
||||
}
|
||||
|
|
@ -861,14 +886,21 @@ void CTFRocketPack::StartHolsterAnim( void )
|
|||
{
|
||||
BaseClass::StartHolsterAnim();
|
||||
|
||||
#ifdef GAME_DLL
|
||||
CTFPlayer *pOwner = GetTFPlayerOwner();
|
||||
if ( pOwner )
|
||||
{
|
||||
EmitSound( "Weapon_RocketPack.BoostersRetract" );
|
||||
#ifdef CLIENT_DLL
|
||||
if ( prediction->IsFirstTimePredicted() )
|
||||
#endif
|
||||
{
|
||||
CPASAttenuationFilter filter( pOwner );
|
||||
filter.UsePredictionRules();
|
||||
EmitSound( filter, entindex(), "Weapon_RocketPack.BoostersRetract" );
|
||||
}
|
||||
#ifdef GAME_DLL
|
||||
SetEnabled( false );
|
||||
#endif
|
||||
}
|
||||
#endif // GAME_DLL
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -890,7 +922,7 @@ void CTFRocketPack::OnResourceMeterFilled()
|
|||
{
|
||||
#ifdef CLIENT_DLL
|
||||
CBasePlayer *pPlayer = GetPlayerOwner();
|
||||
if ( pPlayer->IsLocalPlayer() )
|
||||
if ( pPlayer->IsLocalPlayer() && prediction->IsFirstTimePredicted() )
|
||||
{
|
||||
pPlayer->EmitSound( "TFPlayer.ReCharged" );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,14 +71,14 @@ private:
|
|||
bool IsTransitionCompleted( void ) const;
|
||||
void WaitToLaunch( void );
|
||||
|
||||
void RocketLaunchPlayer( CTFPlayer *pPlayer, const Vector& vecForce, bool bIsPassenger );
|
||||
Vector CalcRocketForceFromPlayer( CTFPlayer *pPlayer );
|
||||
#ifdef GAME_DLL
|
||||
void SetEnabled( bool bEnabled );
|
||||
void PassengerDelayLaunchThink( void );
|
||||
void RocketLaunchPlayer( CTFPlayer *pPlayer, const Vector& vecForce, bool bIsPassenger );
|
||||
Vector CalcRocketForceFromPlayer( CTFPlayer *pPlayer );
|
||||
#else
|
||||
void CleanupParticles( void );
|
||||
#endif // GAME_DLL
|
||||
#endif // CLIENT_DLL
|
||||
|
||||
CNetworkVar( float, m_flInitLaunchTime );
|
||||
CNetworkVar( float, m_flLaunchTime );
|
||||
|
|
|
|||
|
|
@ -316,7 +316,6 @@ extern float AirBurstDamageForce( const Vector &size, float damage, float scale
|
|||
//-----------------------------------------------------------------------------
|
||||
void CTFScatterGun::FireBullet( CTFPlayer *pPlayer )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
if ( HasKnockback() )
|
||||
{
|
||||
// Perform some knock back.
|
||||
|
|
@ -329,9 +328,9 @@ void CTFScatterGun::FireBullet( CTFPlayer *pPlayer )
|
|||
return;
|
||||
|
||||
// Knock the firer back!
|
||||
if ( !(pOwner->GetFlags() & FL_ONGROUND) && !pPlayer->m_bScattergunJump )
|
||||
if ( !(pOwner->GetFlags() & FL_ONGROUND) && !pPlayer->m_Shared.m_bScattergunJump )
|
||||
{
|
||||
pPlayer->m_bScattergunJump = true;
|
||||
pPlayer->m_Shared.m_bScattergunJump = true;
|
||||
|
||||
pOwner->m_Shared.StunPlayer( 0.3f, 1.f, TF_STUN_MOVEMENT | TF_STUN_MOVEMENT_FORWARD_ONLY );
|
||||
|
||||
|
|
@ -341,15 +340,15 @@ void CTFScatterGun::FireBullet( CTFPlayer *pPlayer )
|
|||
AngleVectors( pOwner->EyeAngles(), &vecForward );
|
||||
Vector vecForce = vecForward * -flForce;
|
||||
|
||||
EntityMatrix mtxPlayer;
|
||||
mtxPlayer.InitFromEntity( pOwner );
|
||||
VMatrix mtxPlayer;
|
||||
mtxPlayer.SetupMatrixOrgAngles( pOwner->GetAbsOrigin(), pOwner->EyeAngles() );
|
||||
Vector vecAbsVelocity = pOwner->GetAbsVelocity();
|
||||
Vector vecAbsVelocityAsPoint = vecAbsVelocity + pOwner->GetAbsOrigin();
|
||||
Vector vecLocalVelocity = mtxPlayer.WorldToLocal( vecAbsVelocityAsPoint );
|
||||
Vector vecLocalVelocity = mtxPlayer.VMul4x3Transpose( vecAbsVelocityAsPoint );
|
||||
|
||||
vecLocalVelocity.x = -300;
|
||||
|
||||
vecAbsVelocityAsPoint = mtxPlayer.LocalToWorld( vecLocalVelocity );
|
||||
vecAbsVelocityAsPoint = mtxPlayer.VMul4x3( vecLocalVelocity );
|
||||
vecAbsVelocity = vecAbsVelocityAsPoint - pOwner->GetAbsOrigin();
|
||||
pOwner->SetAbsVelocity( vecAbsVelocity );
|
||||
|
||||
|
|
@ -360,7 +359,6 @@ void CTFScatterGun::FireBullet( CTFPlayer *pPlayer )
|
|||
pOwner->RemoveFlag( FL_ONGROUND );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BaseClass::FireBullet( pPlayer );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -424,6 +424,19 @@ void CTFWeaponBase::Activate( void )
|
|||
GiveDefaultAmmo();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponBase::GiveDefaultAmmo( void )
|
||||
{
|
||||
BaseClass::GiveDefaultAmmo();
|
||||
|
||||
if ( IsEnergyWeapon() )
|
||||
{
|
||||
m_flEnergy = Energy_GetMaxEnergy();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -282,6 +282,7 @@ class CTFWeaponBase : public CBaseCombatWeapon, public IHasOwner, public IHasGen
|
|||
|
||||
virtual void Spawn();
|
||||
virtual void Activate( void );
|
||||
virtual void GiveDefaultAmmo( void );
|
||||
virtual void Precache();
|
||||
virtual bool IsPredicted() const { return true; }
|
||||
virtual void FallInit( void );
|
||||
|
|
@ -335,6 +336,7 @@ class CTFWeaponBase : public CBaseCombatWeapon, public IHasOwner, public IHasGen
|
|||
void EnableDuck();
|
||||
void DisableDuck();
|
||||
|
||||
virtual bool OwnerCanJump( void ) { return true; }
|
||||
virtual bool OwnerCanTaunt( void ) { return true; }
|
||||
virtual bool CanBeCritBoosted( void );
|
||||
bool CanHaveRevengeCrits( void );
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
|
@ -43,7 +43,7 @@ END
|
|||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
|
@ -43,7 +43,7 @@ END
|
|||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -155,7 +155,7 @@ float4 main( PS_INPUT i ) : COLOR
|
|||
if( bFlashlight )
|
||||
{
|
||||
float3 worldSpaceNormal;
|
||||
// Make the unbumped version not so fucking stupid and not need tangentSpaceTranspose you knob.
|
||||
// Make the unbumped version not need tangentSpaceTranspose
|
||||
worldSpaceNormal = mul( normal, i.tangentSpaceTranspose );
|
||||
|
||||
int nShadowSampleLevel = 0;
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@
|
|||
#define FL_INWATER (1<<9) // In water
|
||||
|
||||
// NOTE if you move things up, make sure to change this value
|
||||
#define PLAYER_FLAG_BITS 10
|
||||
#define PLAYER_FLAG_BITS 32
|
||||
|
||||
#define FL_FLY (1<<10) // Changes the SV_Movestep() behavior to not need to be on ground
|
||||
#define FL_SWIM (1<<11) // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)
|
||||
|
|
@ -163,7 +163,7 @@
|
|||
#define FL_INWATER (1<<10) // In water
|
||||
|
||||
// NOTE if you move things up, make sure to change this value
|
||||
#define PLAYER_FLAG_BITS 11
|
||||
#define PLAYER_FLAG_BITS 32
|
||||
|
||||
#define FL_FLY (1<<11) // Changes the SV_Movestep() behavior to not need to be on ground
|
||||
#define FL_SWIM (1<<12) // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public:
|
|||
|
||||
virtual ~CProtoBufMsgBase();
|
||||
|
||||
bool BIsInitialized() const;
|
||||
bool InitFromPacket( IMsgNetPacket * pNetPacket );
|
||||
bool BAsyncSend( IProtoBufSendHandler & pSender ) const;
|
||||
bool BAsyncSendWithPreSerializedBody( IProtoBufSendHandler & pSender, const byte *pubBody, uint32 cubBody ) const;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,11 @@ protected:
|
|||
virtual void PerformLayout();
|
||||
virtual void Paint();
|
||||
MESSAGE_FUNC( OnMenuClose, "MenuClose" );
|
||||
MESSAGE_FUNC_INT( OnCursorEnteredMenuButton, "CursorEnteredMenuButton", VPanel);
|
||||
#ifdef PLATFORM_64BITS
|
||||
MESSAGE_FUNC_PTR( OnCursorEnteredMenuButton, "CursorEnteredMenuButton", VPanel );
|
||||
#else
|
||||
MESSAGE_FUNC_INT( OnCursorEnteredMenuButton, "CursorEnteredMenuButton", VPanel );
|
||||
#endif
|
||||
|
||||
private:
|
||||
CUtlVector<MenuButton *> m_pMenuButtons;
|
||||
|
|
|
|||
|
|
@ -347,6 +347,8 @@ public:
|
|||
bool IsRightAligned(); // returns true if the settings are aligned to the right of the screen
|
||||
bool IsBottomAligned(); // returns true if the settings are aligned to the bottom of the screen
|
||||
|
||||
virtual bool CanAnimate() const { return true; } // If the panel can animate
|
||||
|
||||
// scheme access functions
|
||||
virtual HScheme GetScheme();
|
||||
virtual void SetScheme(const char *tag);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,727 @@
|
|||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#if defined(WIN32) && !defined( _X360 )
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "filesystem.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "appframework/IAppSystemGroup.h"
|
||||
#include "appframework/IAppSystem.h"
|
||||
#include "appframework/AppFramework.h"
|
||||
#include "filesystem_helpers.h"
|
||||
|
||||
#include "matsys_controls/QCGenerator.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier2/vconfig.h"
|
||||
#include "vgui_controls/ListPanel.h"
|
||||
#include "vgui_controls/TextEntry.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/FileOpenDialog.h"
|
||||
#include "vgui_controls/DirectorySelectDialog.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "vgui_controls/CheckButton.h"
|
||||
#include "vgui_controls/MessageBox.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/Cursor.h"
|
||||
#include "vgui_controls/KeyBoardEditorDialog.h"
|
||||
|
||||
#if defined( _X360 )
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#endif
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#define MAX_KEYVALUE 1024
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to the 'count' occurence of a character from the end of a string
|
||||
// returns 0 of there aren't 'count' number of the character in the string
|
||||
//-----------------------------------------------------------------------------
|
||||
char *strrchrcount(char *string, int character, int count )
|
||||
{
|
||||
int j = count;
|
||||
int numChars = V_strlen( string );
|
||||
for( int i = numChars; i > 0; i-- )
|
||||
{
|
||||
if( string[i-1] == character )
|
||||
{
|
||||
j--;
|
||||
}
|
||||
if( j == 0 )
|
||||
{
|
||||
return string + i-1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CModalPreserveMessageBox : public vgui::MessageBox
|
||||
{
|
||||
public:
|
||||
CModalPreserveMessageBox(const char *title, const char *text, vgui::Panel *parent)
|
||||
: vgui::MessageBox( title, text, parent )
|
||||
{
|
||||
m_PrevAppFocusPanel = vgui::input()->GetAppModalSurface();
|
||||
}
|
||||
|
||||
~CModalPreserveMessageBox()
|
||||
{
|
||||
vgui::input()->SetAppModalSurface( m_PrevAppFocusPanel );
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
vgui::VPANEL m_PrevAppFocusPanel;
|
||||
};
|
||||
|
||||
void VGUIMessageBox( vgui::Panel *pParent, const char *pTitle, const char *pMsg, ... )
|
||||
{
|
||||
char msg[4096];
|
||||
va_list marker;
|
||||
va_start( marker, pMsg );
|
||||
Q_vsnprintf( msg, sizeof( msg ), pMsg, marker );
|
||||
va_end( marker );
|
||||
|
||||
vgui::MessageBox *dlg = new CModalPreserveMessageBox( pTitle, msg, pParent );
|
||||
dlg->DoModal();
|
||||
dlg->Activate();
|
||||
dlg->RequestFocus();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Places all the info from the vgui controls into the QCInfo struct
|
||||
//-----------------------------------------------------------------------------
|
||||
void QCInfo::SyncFromControls()
|
||||
{
|
||||
char tempText[MAX_PATH];
|
||||
|
||||
vgui::Panel *pTargetField = pQCGenerator->FindChildByName( "staticPropCheck" );
|
||||
bStaticProp = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "mostlyOpaqueCheck" );
|
||||
bMostlyOpaque = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "disableCollisionsCheck" );
|
||||
bDisableCollision = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "referencePhysicsCheck" );
|
||||
bReferenceAsPhys = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "concaveCheck" );
|
||||
bConcave = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "automassCheck" );
|
||||
bAutomass = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "massField" );
|
||||
((TextEntry *)pTargetField)->GetText(tempText, MAX_PATH);
|
||||
fMass = atof(tempText);
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "scaleField" );
|
||||
((TextEntry *)pTargetField)->GetText(tempText, MAX_PATH);
|
||||
fScale = atof(tempText);
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "collisionSMDField" );
|
||||
((TextEntry *)pTargetField)->GetText( tempText, MAX_PATH );
|
||||
V_strcpy_safe( pszCollisionPath, tempText );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "surfacePropertyDropDown" );
|
||||
((ComboBox *)pTargetField)->GetText( tempText, MAX_PATH );
|
||||
V_strcpy_safe( pszSurfaceProperty, tempText );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "materialsField" );
|
||||
((TextEntry *)pTargetField)->GetText( tempText, MAX_PATH );
|
||||
V_strcpy_safe( pszMaterialPath, tempText );
|
||||
|
||||
LODs.RemoveAll();
|
||||
pTargetField = pQCGenerator->FindChildByName( "LODList" );
|
||||
int numLOD = ((ListPanel *)pTargetField)->GetItemCount();
|
||||
for ( int i = 0; i < numLOD; i++ )
|
||||
{
|
||||
KeyValues *key = ((ListPanel *)pTargetField)->GetItem( i );
|
||||
LODInfo newLOD;
|
||||
|
||||
V_strcpy_safe( newLOD.pszFilename, key->GetString( "SMD" ) );
|
||||
newLOD.iLOD = key->GetInt( "LOD" );
|
||||
LODs.AddToTail( newLOD );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called during intialization to setup the initial state of the VGUI controls
|
||||
//-----------------------------------------------------------------------------
|
||||
void QCInfo::SyncToControls()
|
||||
{
|
||||
char tempText[MAX_PATH];
|
||||
|
||||
vgui::Panel *pTargetField = pQCGenerator->FindChildByName( "staticPropCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bStaticProp );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "mostlyOpaqueCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bMostlyOpaque );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "disableCollisionsCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bDisableCollision );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "referencePhysicsCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bReferenceAsPhys );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "concaveCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bConcave );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "automassCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bAutomass );
|
||||
|
||||
Q_snprintf( tempText, 10, "%d", (int)fMass );
|
||||
pTargetField = pQCGenerator->FindChildByName( "massField" );
|
||||
((TextEntry *)pTargetField)->SetText( tempText );
|
||||
|
||||
Q_snprintf( tempText, 10, "%d", (int)fScale );
|
||||
pTargetField = pQCGenerator->FindChildByName( "scaleField" );
|
||||
((TextEntry *)pTargetField)->SetText( tempText );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "collisionSMDField" );
|
||||
((TextEntry *)pTargetField)->SetText( pszCollisionPath );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "materialsField" );
|
||||
((TextEntry *)pTargetField)->SetText( pszMaterialPath );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "surfacePropertyDropDown" );
|
||||
int numItems = ((ComboBox *)pTargetField)->GetItemCount();
|
||||
for( int i = 0; i < numItems; i++ )
|
||||
{
|
||||
((ComboBox *)pTargetField)->GetItemText( i, tempText, MAX_PATH );
|
||||
if ( !Q_strcmp( tempText, pszSurfaceProperty ) )
|
||||
{
|
||||
((ComboBox *)pTargetField)->SetItemEnabled( i, true );
|
||||
((ComboBox *)pTargetField)->SetText( tempText );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CBrowseButton::CBrowseButton( vgui::Panel *pParent ) : BaseClass( pParent, "Browse Button", "...", pParent, "browse" )
|
||||
{
|
||||
SetParent( pParent );
|
||||
pszStartingDirectory = NULL;
|
||||
pszFileFilter = NULL;
|
||||
pszTargetField = NULL;
|
||||
}
|
||||
|
||||
CBrowseButton::~CBrowseButton()
|
||||
{
|
||||
}
|
||||
|
||||
void CBrowseButton::SetCharVar( char **pVar, const char *pszNewText )
|
||||
{
|
||||
if ( *pVar && pszNewText && !Q_strcmp( *pVar, pszNewText ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( *pVar )
|
||||
{
|
||||
delete [] *pVar;
|
||||
*pVar = NULL;
|
||||
}
|
||||
|
||||
if ( pszNewText )
|
||||
{
|
||||
int len = Q_strlen( pszNewText ) + 1;
|
||||
*pVar = new char[ len ];
|
||||
Q_strncpy( *pVar, pszNewText, len );
|
||||
}
|
||||
}
|
||||
|
||||
void CBrowseButton::InitBrowseInfo( int x, int y, const char *pszName, const char *pszDir, const char *pszFilter, const char *pszField )
|
||||
{
|
||||
SetSize( 24, 24 );
|
||||
SetPos( x, y );
|
||||
SetName( pszName );
|
||||
SetCharVar( GetStartingDirectory(), pszDir );
|
||||
SetCharVar( GetFileFilter(), pszFilter );
|
||||
SetCharVar( GetTargetField(), pszField );
|
||||
SetActionMessage();
|
||||
}
|
||||
|
||||
void CBrowseButton::SetActionMessage()
|
||||
{
|
||||
KeyValues *newActionMessage = new KeyValues( "browse", "directory", pszStartingDirectory, "filter", pszFileFilter);
|
||||
newActionMessage->SetString( "targetField", pszTargetField );
|
||||
SetCommand( newActionMessage );
|
||||
}
|
||||
|
||||
const char *ParseKeyvalue( const char *pBuffer, char *key, char *value )
|
||||
{
|
||||
char com_token[1024];
|
||||
|
||||
pBuffer = (const char *)ParseFile( pBuffer, com_token, NULL );
|
||||
if ( Q_strlen( com_token ) < MAX_KEYVALUE )
|
||||
{
|
||||
Q_strncpy( key, com_token, MAX_KEYVALUE );
|
||||
Q_strlower( key );
|
||||
}
|
||||
// no value on a close brace
|
||||
if ( !Q_strcmp( key, "}" ) )
|
||||
{
|
||||
value[0] = 0;
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
pBuffer = (const char *)ParseFile( pBuffer, com_token, NULL );
|
||||
if ( Q_strlen( com_token ) < MAX_KEYVALUE )
|
||||
{
|
||||
Q_strncpy( value, com_token, MAX_KEYVALUE );
|
||||
Q_strlower( value );
|
||||
}
|
||||
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CQCGenerator::CQCGenerator( vgui::Panel *pParent, const char *pszPath, const char *pszScene ) : BaseClass( pParent, "QCGenerator" )
|
||||
{
|
||||
m_szTargetField[0] = 0;
|
||||
m_nSelectedSequence = 0;
|
||||
m_nSelectedColumn = 0;
|
||||
|
||||
m_QCInfo_t.Init( this );
|
||||
|
||||
SetMinimumSize(846, 770);
|
||||
|
||||
m_pLODPanel = new ListPanel(this, "LODList");
|
||||
m_pLODPanel->SetSelectIndividualCells( true );
|
||||
m_pLODPanel->AddColumnHeader(0, "SMD", "LOD SMD", 450, 0);
|
||||
m_pLODPanel->AddColumnHeader(1, "LOD", "LOD Distance", 50, 0);
|
||||
m_pLODPanel->AddActionSignalTarget( this );
|
||||
m_pLODPanel->SetMouseInputEnabled( true );
|
||||
|
||||
LoadControlSettings( "QCGenerator.res" );
|
||||
|
||||
m_pCollisionBrowseButton = new CBrowseButton( this );
|
||||
m_pCollisionBrowseButton->InitBrowseInfo( 808, 158, "collisionBrowseButton", pszPath, "*.smd", "collisionSMDField" );
|
||||
|
||||
char szTerminatedPath[1024] = "\0";
|
||||
sprintf( szTerminatedPath, "%s\\", pszPath );
|
||||
|
||||
InitializeSMDPaths( szTerminatedPath, pszScene );
|
||||
|
||||
char *pszMaterialsStart = strrchrcount( szTerminatedPath, '\\', 3 ) + 1;
|
||||
char *pszMaterialsEnd = strrchr( szTerminatedPath, '\\');
|
||||
Q_strncpy( m_QCInfo_t.pszMaterialPath, pszMaterialsStart, pszMaterialsEnd - pszMaterialsStart + 1 );
|
||||
|
||||
SetParent( pParent );
|
||||
|
||||
char szGamePath[1024] = "\0";
|
||||
char szSearchPath[1024] = "\0";
|
||||
|
||||
// Get the currently set game configuration
|
||||
GetVConfigRegistrySetting( GAMEDIR_TOKEN, szGamePath, sizeof( szGamePath ) );
|
||||
static const char *pSurfacePropFilename = "\\scripts\\surfaceproperties.txt";
|
||||
|
||||
sprintf( szSearchPath, "%s%s", szGamePath, pSurfacePropFilename );
|
||||
|
||||
FileHandle_t fp = g_pFullFileSystem->Open( szSearchPath, "rb" );
|
||||
|
||||
if ( !fp )
|
||||
{
|
||||
//the set game configuration didn't have a surfaceproperties file; we are grabbing it from hl2
|
||||
//TODO: This only works if they are in a subdirectory that is a peer to an hl2 directory
|
||||
// that contains the file. It potentially needs to search the entire drive or prompt for the location
|
||||
char *pszEndGamePath = Q_strrchr( szGamePath, '\\' );
|
||||
pszEndGamePath[0] = 0;
|
||||
V_strcat_safe( szGamePath, "\\hl2" );
|
||||
sprintf( szSearchPath, "%s%s", szGamePath, pSurfacePropFilename );
|
||||
fp = g_pFullFileSystem->Open( szSearchPath, "rb" );
|
||||
}
|
||||
|
||||
int len = g_pFullFileSystem->Size( fp );
|
||||
|
||||
const char *szSurfacePropContents = new char[len+1];
|
||||
g_pFullFileSystem->Read( (void *)szSurfacePropContents, len, fp );
|
||||
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
vgui::Panel *pSurfacePropDropDown = FindChildByName( "surfacePropertyDropDown" );
|
||||
|
||||
//filling up the surface property dropdown
|
||||
while ( szSurfacePropContents )
|
||||
{
|
||||
szSurfacePropContents = ParseKeyvalue( szSurfacePropContents, key, value );
|
||||
((ComboBox *)pSurfacePropDropDown)->AddItem( key, NULL );
|
||||
while ( szSurfacePropContents )
|
||||
{
|
||||
szSurfacePropContents = ParseKeyvalue( szSurfacePropContents, key, value );
|
||||
if (!stricmp( key, "}" ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_QCInfo_t.SyncToControls();
|
||||
|
||||
m_pLODEdit = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CQCGenerator::~CQCGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
void CQCGenerator::OnCommand( const char *command )
|
||||
{
|
||||
if ( Q_stricmp( command, "createQC" ) == 0 )
|
||||
{
|
||||
m_QCInfo_t.SyncFromControls();
|
||||
GenerateQCFile();
|
||||
}
|
||||
if ( Q_stricmp( command, "deleteSeq" ) == 0 )
|
||||
{
|
||||
//delete it
|
||||
DeleteLOD();
|
||||
}
|
||||
if ( Q_stricmp( command, "editSeq" ) == 0 )
|
||||
{
|
||||
//edit
|
||||
EditLOD();
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( command );
|
||||
}
|
||||
|
||||
|
||||
void CQCGenerator::OnKeyCodeTyped( KeyCode code )
|
||||
{
|
||||
switch ( code )
|
||||
{
|
||||
case KEY_ENTER:
|
||||
EditLOD();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CQCGenerator::OnBrowse( KeyValues *data )
|
||||
{
|
||||
V_strcpy_safe( m_szTargetField, data->GetString( "targetField" ) );
|
||||
const char *filter = data->GetString( "filter" );
|
||||
|
||||
if ( Q_strlen( filter ) == 0 )
|
||||
{
|
||||
// BrowseDirectory( data );
|
||||
}
|
||||
else
|
||||
{
|
||||
BrowseFile( data );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
//This function is no longer used in the current version of the program.
|
||||
void CQCGenerator::BrowseDirectory( KeyValues *data )
|
||||
{
|
||||
DirectorySelectDialog *pDialog = new DirectorySelectDialog( this, "Select Directory" );
|
||||
pDialog->AddActionSignalTarget( this );
|
||||
pDialog->DoModal();
|
||||
pDialog->SetStartDirectory( data->GetString( "directory" ) );
|
||||
}
|
||||
*/
|
||||
|
||||
void CQCGenerator::BrowseFile( KeyValues *data )
|
||||
{
|
||||
const char *filter = data->GetString( "filter" );
|
||||
|
||||
FileOpenDialog *pDialog = new FileOpenDialog( this, "Select File", true );
|
||||
pDialog->AddFilter( filter, filter, true );
|
||||
pDialog->AddActionSignalTarget(this);
|
||||
pDialog->SetStartDirectory( data->GetString( "directory" ) );
|
||||
pDialog->DoModal( true );
|
||||
}
|
||||
|
||||
void CQCGenerator::OnFileSelected( KeyValues *data )
|
||||
{
|
||||
if ( *m_szTargetField )
|
||||
{
|
||||
vgui::Panel *pTargetField = FindChildByName( m_szTargetField );
|
||||
((TextEntry *)pTargetField)->SetText( data->GetString( "fullpath" ) );
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void CQCGenerator::OnDirectorySelected( KeyValues *data )
|
||||
{
|
||||
if ( *m_szTargetField )
|
||||
{
|
||||
vgui::Panel *pTargetField = FindChildByName( m_szTargetField );
|
||||
((TextEntry *)pTargetField)->SetText( data->GetString( "dir" ) );
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
bool CQCGenerator::GenerateQCFile()
|
||||
{
|
||||
//TODO: clean this up. Consider creating a datatype that includes the string to write out when the QC file is created
|
||||
char *nameBegin = strrchr( m_QCInfo_t.pszSMDPath, '\\' );
|
||||
|
||||
char szPath[MAX_PATH];
|
||||
char szName[MAX_PATH];
|
||||
Q_strncpy( szPath, m_QCInfo_t.pszSMDPath, nameBegin - m_QCInfo_t.pszSMDPath + 2 );
|
||||
V_strcpy_safe( szName, szPath);
|
||||
V_strcat_safe( szName, m_QCInfo_t.pszSceneName);
|
||||
V_strcat_safe( szName, ".qc" );
|
||||
FileHandle_t pSaveFile = g_pFullFileSystem->Open( szName, "wt" );
|
||||
if (!pSaveFile)
|
||||
{
|
||||
char szSaveError[1024] = "";
|
||||
Q_snprintf( szSaveError, 1024, "Save failed: invalid file name '%s'\n\nDirectory '%s' must exist.", szName, szPath );
|
||||
VGUIMessageBox( this, "QC Generator error", szSaveError );
|
||||
return 0;
|
||||
}
|
||||
|
||||
//write qc header
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "//\n// .qc file version 1.0\n\n");
|
||||
//write out modelname info
|
||||
char szModelName[MAX_PATH];
|
||||
char *modelStart = strrchrcount( szName, '\\', 2) + 1;
|
||||
char *modelEnd = strrchr( szName, '.' );
|
||||
Q_strncpy( szModelName, modelStart, modelEnd - modelStart + 1 );
|
||||
V_strcat_safe( szModelName, ".mdl" );
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$modelname %s\n\n", szModelName );
|
||||
//write out scale info
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$scale %f\n", m_QCInfo_t.fScale );
|
||||
//write out body info
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$body \"Body\" \"%s\"\n", strrchr( m_QCInfo_t.pszSMDPath, '\\' ) + 1 );
|
||||
|
||||
if ( m_QCInfo_t.bStaticProp == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$staticprop\n" );
|
||||
}
|
||||
|
||||
if ( m_QCInfo_t.bMostlyOpaque == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$mostlyopaque\n" );
|
||||
}
|
||||
|
||||
//write out surfaceprop info
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$surfaceprop \"%s\"\n\n", m_QCInfo_t.pszSurfaceProperty );
|
||||
//write materials
|
||||
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$cdmaterials %s\n\n", m_QCInfo_t.pszMaterialPath);
|
||||
|
||||
if ( m_QCInfo_t.bStaticProp || m_QCInfo_t.bNoAnimation )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "// --------- Animation sequences -------\n");
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$sequence \"idle\" \"%s\" fps 30\n\n", strrchr(m_QCInfo_t.pszSMDPath, '\\')+1);
|
||||
}
|
||||
|
||||
//write out lod info
|
||||
for( int i = 0; i < m_QCInfo_t.LODs.Count(); i++ )
|
||||
{
|
||||
LODInfo thisLOD = m_QCInfo_t.LODs.Element( i );
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$lod %d\n{\n\treplacemodel \"%s\" \"%s\"\n}\n\n", thisLOD.iLOD, strrchr(m_QCInfo_t.pszSMDPath, '\\')+1, thisLOD.pszFilename );
|
||||
}
|
||||
|
||||
if ( m_QCInfo_t.bDisableCollision != true )
|
||||
{
|
||||
//write out collision header
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\n" );
|
||||
//write out collision info
|
||||
if ( m_QCInfo_t.bReferenceAsPhys == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$collisionmodel \"%s\"", strrchr( m_QCInfo_t.pszSMDPath, '\\' ) + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( Q_strcmp( m_QCInfo_t.pszCollisionPath, "" ) )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$collisionmodel \"%s\"", strrchr( m_QCInfo_t.pszCollisionPath, '\\' ) + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, " {\n\t// Mass in kilograms\n ");
|
||||
|
||||
if ( m_QCInfo_t.bAutomass == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\t$automass\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\t$mass %f\n", m_QCInfo_t.fMass );
|
||||
}
|
||||
|
||||
if ( m_QCInfo_t.bConcave == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\t$concave\n" );
|
||||
}
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "}\n\n");
|
||||
}
|
||||
|
||||
g_pFullFileSystem->Close( pSaveFile );
|
||||
|
||||
char szCommand[MAX_PATH];
|
||||
char szGamePath[MAX_PATH];
|
||||
|
||||
char studiomdlPath[512];
|
||||
g_pFullFileSystem->RelativePathToFullPath( "studiomdl.bat", NULL, studiomdlPath, sizeof( studiomdlPath ));
|
||||
|
||||
GetVConfigRegistrySetting( GAMEDIR_TOKEN, szGamePath, sizeof( szGamePath ) );
|
||||
|
||||
#ifdef WIN32
|
||||
STARTUPINFO startup;
|
||||
PROCESS_INFORMATION process;
|
||||
|
||||
|
||||
memset(&startup, 0, sizeof(startup));
|
||||
startup.cb = sizeof(startup);
|
||||
|
||||
|
||||
sprintf( szCommand, "%s -game %s %s", studiomdlPath, szGamePath, szName);
|
||||
bool bReturn = CreateProcess( NULL, szCommand, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &startup, &process);
|
||||
#else
|
||||
Assert( !"Implement me, why aren't we using a thread tool abstraction?" );
|
||||
bool bReturn = false;
|
||||
#endif
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
void CQCGenerator::InitializeSMDPaths( const char *pszPath, const char *pszScene )
|
||||
{
|
||||
V_strcpy_safe( m_QCInfo_t.pszSceneName, pszScene );
|
||||
|
||||
FileFindHandle_t *pFileHandle = new FileFindHandle_t();
|
||||
|
||||
g_pFullFileSystem->AddSearchPath( pszPath, "SMD_DIR" );
|
||||
|
||||
const char *filename = g_pFullFileSystem->FindFirst( "*.smd", pFileHandle );
|
||||
|
||||
bool bFoundReference = false;
|
||||
bool bFoundCollision = false;
|
||||
bool bFoundLOD = false;
|
||||
|
||||
//iterate through .smd files
|
||||
const char *startName = pszScene;
|
||||
|
||||
int nSearchLength = Q_strlen( pszScene );
|
||||
|
||||
int currentLOD = 1;
|
||||
|
||||
while( filename )
|
||||
{
|
||||
if ( !strncmp( startName, filename, nSearchLength ) )
|
||||
{
|
||||
const char *filenameEnd = filename + nSearchLength;
|
||||
if ( !strncmp( filenameEnd, "_ref", 4 ) || !strncmp( filenameEnd, ".smd", 4 ) )
|
||||
{
|
||||
bFoundReference = true;
|
||||
//we have found the reference smd.
|
||||
V_strcpy_safe( m_QCInfo_t.pszSMDPath, pszPath );
|
||||
V_strcat_safe( m_QCInfo_t.pszSMDPath, filename );
|
||||
}
|
||||
if ( !strncmp( filenameEnd, "_phy", 4) || !strncmp( filenameEnd, "_col", 4 ) )
|
||||
{
|
||||
bFoundCollision = true;
|
||||
//we have found the collision smd.
|
||||
V_strcpy_safe( m_QCInfo_t.pszCollisionPath, pszPath );
|
||||
V_strcat_safe( m_QCInfo_t.pszCollisionPath, filename );
|
||||
}
|
||||
if ( !strncmp( filenameEnd, "_lod", 4) )
|
||||
{
|
||||
bFoundLOD = true;
|
||||
//we found an LOD smd.
|
||||
char lodName[255];
|
||||
Q_snprintf( lodName, Q_strlen( lodName ), "lod%d", currentLOD );
|
||||
//we found an LOD
|
||||
KeyValues *newKv = new KeyValues( lodName, "SMD", filename, "LOD", "10" );
|
||||
m_pLODPanel->AddItem( newKv, currentLOD, false, false );
|
||||
currentLOD++;
|
||||
}
|
||||
}
|
||||
filename = g_pFullFileSystem->FindNext( *pFileHandle );
|
||||
}
|
||||
char pszMessage[2048] = "";
|
||||
char pszRefMessage[1024] = "";
|
||||
char pszColMessage[1024] = "";
|
||||
if (!bFoundReference )
|
||||
{
|
||||
V_strcat_safe( m_QCInfo_t.pszSMDPath, pszPath );
|
||||
V_strcat_safe( m_QCInfo_t.pszSMDPath, pszScene );
|
||||
V_strcat_safe( m_QCInfo_t.pszSMDPath, ".smd" );
|
||||
Q_snprintf( pszRefMessage, 1024, "Reference SMD not found.\n\nValid default reference SMDs are %s%s_ref*.smd and %s%s.smd\nUsing default of %s. Model will not compile.\n\n", pszPath, pszScene, pszPath, pszScene, m_QCInfo_t.pszSMDPath );
|
||||
}
|
||||
if ( !bFoundCollision )
|
||||
{
|
||||
Q_snprintf( pszColMessage, 1024, "Collision SMD not found.\n\nThe valid default collision SMD is %s%s_phy*.smd.\nUsing reference SMD as default.\n", pszPath, pszScene );
|
||||
V_strcpy_safe( m_QCInfo_t.pszCollisionPath, m_QCInfo_t.pszSMDPath );
|
||||
m_QCInfo_t.bReferenceAsPhys = true;
|
||||
}
|
||||
if ( !bFoundReference || !bFoundCollision)
|
||||
{
|
||||
V_strcpy_safe( pszMessage, pszRefMessage );
|
||||
V_strcat_safe( pszMessage, pszColMessage );
|
||||
VGUIMessageBox( this, "Error Initializing Paths", pszMessage );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CQCGenerator::DeleteLOD()
|
||||
{
|
||||
int numSelected = m_pLODPanel->GetSelectedItemsCount();
|
||||
int selected;
|
||||
for ( int i = numSelected-1; i >= 0; i-- )
|
||||
{
|
||||
selected = m_pLODPanel->GetSelectedItem( i );
|
||||
m_pLODPanel->RemoveItem( selected );
|
||||
}
|
||||
}
|
||||
|
||||
void CQCGenerator::EditLOD()
|
||||
{
|
||||
int numSelected = m_pLODPanel->GetSelectedItemsCount();
|
||||
if ( numSelected == 1 && !m_pLODPanel->IsInEditMode() )
|
||||
{
|
||||
if ( m_pLODEdit )
|
||||
{
|
||||
m_pLODEdit->MarkForDeletion();
|
||||
m_pLODEdit = NULL;
|
||||
}
|
||||
m_pLODEdit = new vgui::TextEntry( this, "Edit" );
|
||||
m_pLODEdit->SendNewLine( true );
|
||||
m_nSelectedSequence = m_pLODPanel->GetSelectedItem( 0 );
|
||||
m_nSelectedColumn = m_pLODPanel->GetSelectedColumn();
|
||||
m_pLODPanel->EnterEditMode( m_nSelectedSequence, m_nSelectedColumn, m_pLODEdit );
|
||||
}
|
||||
}
|
||||
|
||||
void CQCGenerator::OnNewLODText()
|
||||
{
|
||||
KeyValues *pEditItem = m_pLODPanel->GetItem( m_nSelectedSequence );
|
||||
KeyValues *pListItem = pEditItem;
|
||||
wchar_t szEditText[MAX_PATH];
|
||||
|
||||
pEditItem = pEditItem->GetFirstValue();
|
||||
const char *name = pEditItem->GetName();
|
||||
for( int i = 0; i < m_nSelectedColumn; i++ )
|
||||
{
|
||||
pEditItem = pEditItem->GetNextValue();
|
||||
name = pEditItem->GetName();
|
||||
}
|
||||
m_pLODEdit->GetText( szEditText, MAX_PATH );
|
||||
|
||||
pListItem->SetWString( name, szEditText );
|
||||
|
||||
m_pLODPanel->LeaveEditMode();
|
||||
m_pLODPanel->InvalidateLayout();
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/assetpicker.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Asset Picker with no preview
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAssetPicker::CAssetPicker( vgui::Panel *pParent, const char *pAssetType,
|
||||
const char *pExt, const char *pSubDir, const char *pTextType ) :
|
||||
BaseClass( pParent, pAssetType, pExt, pSubDir, pTextType )
|
||||
{
|
||||
CreateStandardControls( this );
|
||||
LoadControlSettingsAndUserConfig( "resource/assetpicker.res" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CAssetPickerFrame::CAssetPickerFrame( vgui::Panel *pParent, const char *pTitle,
|
||||
const char *pAssetType, const char *pExt, const char *pSubDir, const char *pTextType ) :
|
||||
BaseClass( pParent )
|
||||
{
|
||||
SetAssetPicker( new CAssetPicker( this, pAssetType, pExt, pSubDir, pTextType ) );
|
||||
LoadControlSettingsAndUserConfig( "resource/assetpickerframe.res" );
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,200 @@
|
|||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/curveeditorpanel.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/MouseCode.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CCurveEditorPanel::CCurveEditorPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
m_nSelectedPoint = -1;
|
||||
SetMouseInputEnabled( true );
|
||||
SetKeyBoardInputEnabled( true );
|
||||
m_nHighlightedPoint = -1;
|
||||
}
|
||||
|
||||
CCurveEditorPanel::~CCurveEditorPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Converts screen location to normalized values
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::ScreenToValue( int x, int y, float *pIn, float *pOut )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
*pIn = (float)x / (w-1);
|
||||
*pOut = 1.0f - ((float)y / (h-1));
|
||||
}
|
||||
|
||||
void CCurveEditorPanel::ValueToScreen( float flIn, float flOut, int *x, int *y )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
*x = (int)(flIn * (w-1) + 0.5f);
|
||||
*y = (h-1) - (int)(flOut * (h-1) + 0.5f);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle input
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::OnMousePressed( vgui::MouseCode code )
|
||||
{
|
||||
BaseClass::OnMousePressed( code );
|
||||
|
||||
int x, y;
|
||||
input()->GetCursorPos( x, y );
|
||||
ScreenToLocal( x, y );
|
||||
|
||||
if ( code == MOUSE_LEFT )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
float flIn, flOut;
|
||||
ScreenToValue( x, y, &flIn, &flOut );
|
||||
float flTolerance = 5.0f / (w-1); // +/- 3 pixels to select the point
|
||||
m_nSelectedPoint = FindOrAddControlPoint( flIn, flTolerance, flOut );
|
||||
}
|
||||
}
|
||||
|
||||
void CCurveEditorPanel::OnMouseReleased( vgui::MouseCode code )
|
||||
{
|
||||
BaseClass::OnMouseReleased( code );
|
||||
|
||||
if ( code == MOUSE_LEFT )
|
||||
{
|
||||
m_nSelectedPoint = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void CCurveEditorPanel::OnCursorMoved( int x, int y )
|
||||
{
|
||||
BaseClass::OnCursorMoved( x, y );
|
||||
|
||||
float flIn, flOut;
|
||||
ScreenToValue( x, y, &flIn, &flOut );
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
float flTolerance = 5.0f / (w-1); // +/- 3 pixels to select the point
|
||||
m_nHighlightedPoint = FindControlPoint( flIn, flTolerance );
|
||||
|
||||
if ( m_nSelectedPoint < 0 )
|
||||
return;
|
||||
m_nSelectedPoint = ModifyControlPoint( m_nSelectedPoint, flIn, flOut );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handles keypresses
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::OnKeyCodePressed( vgui::KeyCode code )
|
||||
{
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
|
||||
if ( m_nSelectedPoint >= 0 )
|
||||
{
|
||||
RemoveControlPoint( m_nSelectedPoint );
|
||||
m_nSelectedPoint = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This paints the grid behind the curves
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::PaintBackground( void )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
|
||||
vgui::surface()->DrawFilledRect( 0, 0, w, h );
|
||||
|
||||
vgui::surface()->DrawSetColor( 128, 128, 128, 255 );
|
||||
vgui::surface()->DrawLine( 0, h/4, w, h/4 );
|
||||
vgui::surface()->DrawLine( 0, h/2, w, h/2 );
|
||||
vgui::surface()->DrawLine( 0, 3*h/4, w, 3*h/4 );
|
||||
|
||||
vgui::surface()->DrawLine( w/4, 0, w/4, h );
|
||||
vgui::surface()->DrawLine( w/2, 0, w/2, h );
|
||||
vgui::surface()->DrawLine( 3*w/4, 0, 3*w/4, h );
|
||||
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
vgui::surface()->DrawLine( 0, 0, w, 0 );
|
||||
vgui::surface()->DrawLine( w, 0, w, h );
|
||||
vgui::surface()->DrawLine( w, h, 0, h );
|
||||
vgui::surface()->DrawLine( 0, h, 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the color curves operation to edit
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::Paint( void )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
int x0 = 0, y0 = 0;
|
||||
|
||||
// FIXME: Add method to draw multiple lines DrawPolyLine connects the 1st and last points... bleah
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
for ( int i = 0; i < w; ++i )
|
||||
{
|
||||
float flIn = (float)i / (w-1);
|
||||
float flOut = GetValue( flIn );
|
||||
int x = i;
|
||||
int y = (h-1) - (int)(flOut * (h-1) + 0.5f);
|
||||
y = clamp( y, 0, h-1 );
|
||||
|
||||
if ( i != 0 )
|
||||
{
|
||||
vgui::surface()->DrawLine( x0, y0, x, y );
|
||||
}
|
||||
|
||||
x0 = x; y0 = y;
|
||||
}
|
||||
|
||||
|
||||
// This will paint the control points
|
||||
// The currently selected one will be painted red and filled.
|
||||
for ( int i = ControlPointCount(); --i >= 0; )
|
||||
{
|
||||
float flIn, flOut;
|
||||
GetControlPoint( i, &flIn, &flOut );
|
||||
|
||||
int cx, cy;
|
||||
ValueToScreen( flIn, flOut, &cx, &cy );
|
||||
|
||||
if ( (i == m_nSelectedPoint) || ((m_nSelectedPoint == -1) && (i == m_nHighlightedPoint)) )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( 255, 0, 0, 255 );
|
||||
vgui::surface()->DrawFilledRect( cx-3, cy-3, cx+3, cy+3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
vgui::surface()->DrawOutlinedRect( cx-3, cy-3, cx+3, cy+3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#if defined(WIN32) && !defined( _X360 )
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#undef PropertySheet
|
||||
|
||||
#include "matsys_controls/gamefiletreeview.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/Cursor.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// list of all tree view icons
|
||||
//-----------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
IMAGE_FOLDER = 1,
|
||||
IMAGE_OPENFOLDER,
|
||||
IMAGE_FILE,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CGameFileTreeView::CGameFileTreeView( Panel *parent, const char *name, const char *pRootFolderName, const char *pRootDir, const char *pExtension ) : BaseClass(parent, name), m_Images( false )
|
||||
{
|
||||
m_RootDir = pRootDir;
|
||||
|
||||
m_Ext = pExtension;
|
||||
m_bUseExt = ( pExtension != NULL );
|
||||
|
||||
m_RootFolderName = pRootFolderName;
|
||||
|
||||
// build our list of images
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder", false ) );
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder_selected", false ) );
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_file", false ) );
|
||||
SetImageList( &m_Images, false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Refreshes the active file list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::RefreshFileList()
|
||||
{
|
||||
RemoveAll();
|
||||
SetFgColor(Color(216, 222, 211, 255));
|
||||
|
||||
// add the base node
|
||||
KeyValues *pkv = new KeyValues( "root" );
|
||||
pkv->SetString( "text", m_RootFolderName );
|
||||
pkv->SetInt( "root", 1 );
|
||||
pkv->SetInt( "expand", 1 );
|
||||
int iRoot = AddItem( pkv, GetRootItemIndex() );
|
||||
pkv->deleteThis();
|
||||
ExpandItem( iRoot, true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Selects the root folder
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::SelectRoot()
|
||||
{
|
||||
AddSelectedItem( GetRootItemIndex(), true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the number of root directories
|
||||
//-----------------------------------------------------------------------------
|
||||
int CGameFileTreeView::GetRootDirectoryCount()
|
||||
{
|
||||
return GetNumChildren( GetRootItemIndex() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the ith root directory
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CGameFileTreeView::GetRootDirectory( int nIndex )
|
||||
{
|
||||
int nItemIndex = GetChild( GetRootItemIndex(), nIndex );
|
||||
KeyValues *kv = GetItemData( nItemIndex );
|
||||
if ( !kv )
|
||||
return NULL;
|
||||
return kv->GetString( "path", NULL );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node (necessary since tree view can't have multiple roots)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::PopulateRootNode( int itemIndex )
|
||||
{
|
||||
AddDirectoriesOfNode( itemIndex, m_RootDir );
|
||||
|
||||
if ( m_bUseExt )
|
||||
{
|
||||
AddFilesOfNode( itemIndex, m_RootDir, m_Ext );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node with directories
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CGameFileTreeView::DoesDirectoryHaveSubdirectories( const char *pFilePath )
|
||||
{
|
||||
char pSearchString[MAX_PATH];
|
||||
Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pFilePath );
|
||||
|
||||
// get the list of files
|
||||
FileFindHandle_t findHandle;
|
||||
|
||||
// generate children
|
||||
// add all the items
|
||||
const char *pszFileName = g_pFullFileSystem->FindFirstEx( pSearchString, "GAME", &findHandle );
|
||||
while ( pszFileName )
|
||||
{
|
||||
bool bIsDirectory = g_pFullFileSystem->FindIsDirectory( findHandle );
|
||||
if ( bIsDirectory && Q_strnicmp( pszFileName, ".", 2 ) && Q_strnicmp( pszFileName, "..", 3 ) )
|
||||
return true;
|
||||
|
||||
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FindClose( findHandle );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node with directories
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::AddDirectoriesOfNode( int itemIndex, const char *pFilePath )
|
||||
{
|
||||
char pSearchString[MAX_PATH];
|
||||
Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pFilePath );
|
||||
|
||||
// get the list of files
|
||||
FileFindHandle_t findHandle;
|
||||
|
||||
// generate children
|
||||
// add all the items
|
||||
const char *pszFileName = g_pFullFileSystem->FindFirstEx( pSearchString, "GAME", &findHandle );
|
||||
while ( pszFileName )
|
||||
{
|
||||
bool bIsDirectory = g_pFullFileSystem->FindIsDirectory( findHandle );
|
||||
if ( bIsDirectory && Q_strnicmp( pszFileName, ".", 2 ) && Q_strnicmp( pszFileName, "..", 3 ) )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "node", "text", pszFileName );
|
||||
|
||||
char pFullPath[MAX_PATH];
|
||||
Q_snprintf( pFullPath, sizeof(pFullPath), "%s/%s", pFilePath, pszFileName );
|
||||
Q_FixSlashes( pFullPath );
|
||||
Q_strlower( pFullPath );
|
||||
bool bHasSubdirectories = DoesDirectoryHaveSubdirectories( pFullPath );
|
||||
kv->SetString( "path", pFullPath );
|
||||
|
||||
kv->SetInt( "expand", bHasSubdirectories );
|
||||
kv->SetInt( "dir", 1 );
|
||||
kv->SetInt( "image", IMAGE_FOLDER );
|
||||
|
||||
int itemID = AddItem(kv, itemIndex);
|
||||
kv->deleteThis();
|
||||
|
||||
// mark directories in orange
|
||||
SetItemColorForDirectories( itemID );
|
||||
}
|
||||
|
||||
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FindClose( findHandle );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node with files
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::AddFilesOfNode( int itemIndex, const char *pFilePath, const char *pExt )
|
||||
{
|
||||
char pSearchString[MAX_PATH];
|
||||
Q_snprintf( pSearchString, MAX_PATH, "%s\\*.%s", pFilePath, pExt );
|
||||
|
||||
// get the list of files
|
||||
FileFindHandle_t findHandle;
|
||||
|
||||
// generate children
|
||||
// add all the items
|
||||
const char *pszFileName = g_pFullFileSystem->FindFirst( pSearchString, &findHandle );
|
||||
while ( pszFileName )
|
||||
{
|
||||
if ( !g_pFullFileSystem->FindIsDirectory( findHandle ) )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "node", "text", pszFileName );
|
||||
|
||||
char pFullPath[MAX_PATH];
|
||||
Q_snprintf( pFullPath, MAX_PATH, "%s\\%s", pFilePath, pszFileName );
|
||||
kv->SetString( "path", pFullPath );
|
||||
kv->SetInt( "image", IMAGE_FILE );
|
||||
|
||||
AddItem(kv, itemIndex);
|
||||
kv->deleteThis();
|
||||
}
|
||||
|
||||
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FindClose( findHandle );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// override to incremental request and show p4 directories
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::GenerateChildrenOfNode(int itemIndex)
|
||||
{
|
||||
KeyValues *pkv = GetItemData(itemIndex);
|
||||
if ( pkv->GetInt("root") )
|
||||
{
|
||||
PopulateRootNode( itemIndex );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pkv->GetInt("dir"))
|
||||
return;
|
||||
|
||||
const char *pFilePath = pkv->GetString("path", "");
|
||||
if (!pFilePath[0])
|
||||
return;
|
||||
|
||||
surface()->SetCursor(dc_waitarrow);
|
||||
|
||||
AddDirectoriesOfNode( itemIndex, pFilePath );
|
||||
|
||||
if ( m_bUseExt )
|
||||
{
|
||||
AddFilesOfNode( itemIndex, pFilePath, m_Ext );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setup a context menu whenever a directory is clicked on
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::GenerateContextMenu( int itemIndex, int x, int y )
|
||||
{
|
||||
return;
|
||||
|
||||
/*
|
||||
KeyValues *pkv = GetItemData(itemIndex);
|
||||
const char *pFilePath = pkv->GetString("path", "");
|
||||
if (!pFilePath[0])
|
||||
return;
|
||||
|
||||
Menu *pContext = new Menu(this, "FileContext");
|
||||
pContext->AddMenuItem("Cloak folder", new KeyValues("CloakFolder", "item", itemIndex), GetParent(), NULL);
|
||||
|
||||
// show the context menu
|
||||
pContext->SetPos(x, y);
|
||||
pContext->SetVisible(true);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets an item to be colored as if its a menu
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::SetItemColorForDirectories( int itemID )
|
||||
{
|
||||
// mark directories in orange
|
||||
SetItemFgColor( itemID, Color(224, 192, 0, 255) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setup a smaller font
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::ApplySchemeSettings(IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
SetFont( pScheme->GetFont("DefaultSmall") );
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/manipulator.h"
|
||||
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/ISystem.h"
|
||||
#include "vgui/MouseCode.h"
|
||||
|
||||
#include "mathlib/vector.h"
|
||||
#include "mathlib/vmatrix.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// local helper functions
|
||||
//-----------------------------------------------------------------------------
|
||||
static float UpdateTime( float &flLastTime )
|
||||
{
|
||||
float flTime = vgui::system()->GetFrameTime();
|
||||
float dt = flTime - flLastTime;
|
||||
flLastTime = flTime;
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Base class for manipulators which operate on transforms
|
||||
//-----------------------------------------------------------------------------
|
||||
CTransformManipulator::CTransformManipulator( matrix3x4_t *pTransform ) :
|
||||
m_pTransform( pTransform )
|
||||
{
|
||||
}
|
||||
|
||||
void CTransformManipulator::SetTransform( matrix3x4_t *pTransform )
|
||||
{
|
||||
m_pTransform = pTransform;
|
||||
}
|
||||
|
||||
matrix3x4_t *CTransformManipulator::GetTransform( void )
|
||||
{
|
||||
return m_pTransform;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CPotteryWheelManip - nendo-style camera manipulator
|
||||
//-----------------------------------------------------------------------------
|
||||
CPotteryWheelManip::CPotteryWheelManip( matrix3x4_t *pTransform ) :
|
||||
CTransformManipulator( pTransform ),
|
||||
m_lastx( -1 ), m_lasty( -1 ),
|
||||
m_zoom( 100.0f ), m_altitude( 0.0f ), m_azimuth( 0.0f ),
|
||||
m_prevZoom( 100.0f ), m_prevAltitude( 0.0f ), m_prevAzimuth( 0.0f ),
|
||||
m_flLastMouseTime( 0.0f ), m_flLastTickTime( 0.0f ),
|
||||
m_flSpin( 0.0f ), m_bSpin( false )
|
||||
{
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnBeginManipulation( void )
|
||||
{
|
||||
m_prevZoom = m_zoom;
|
||||
m_prevAltitude = m_altitude;
|
||||
m_prevAzimuth = m_azimuth;
|
||||
m_flLastMouseTime = m_flLastTickTime = vgui::system()->GetFrameTime();
|
||||
m_flSpin = 0.0f;
|
||||
m_bSpin = false;
|
||||
}
|
||||
|
||||
// Sets the zoom level
|
||||
void CPotteryWheelManip::SetZoom( float flZoom )
|
||||
{
|
||||
m_prevZoom = m_zoom = flZoom;
|
||||
}
|
||||
|
||||
|
||||
void CPotteryWheelManip::OnAcceptManipulation( void )
|
||||
{
|
||||
m_flSpin = 0.0f;
|
||||
m_bSpin = false;
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnCancelManipulation( void )
|
||||
{
|
||||
m_zoom = m_prevZoom;
|
||||
m_altitude = m_prevAltitude;
|
||||
m_azimuth = m_prevAzimuth;
|
||||
m_flSpin = 0.0f;
|
||||
m_bSpin = false;
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
|
||||
void CPotteryWheelManip::OnTick( void )
|
||||
{
|
||||
float dt = UpdateTime( m_flLastTickTime );
|
||||
|
||||
if ( m_bSpin )
|
||||
{
|
||||
m_azimuth += dt * m_flSpin;
|
||||
UpdateTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnCursorMoved( int x, int y )
|
||||
{
|
||||
float dt = UpdateTime( m_flLastMouseTime );
|
||||
|
||||
if ( m_bSpin )
|
||||
{
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( input()->IsMouseDown( MOUSE_MIDDLE ) )
|
||||
{
|
||||
int dy = y - m_lasty;
|
||||
int dx = x - m_lastx;
|
||||
|
||||
if ( abs( dx ) < 2 * abs( dy ) )
|
||||
{
|
||||
UpdateZoom( 0.2f * dy );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flSpin = (dt != 0.0f) ? 0.002f * dx / dt : 0.0f;
|
||||
m_azimuth += 0.002f * dx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_azimuth += 0.002f * ( x - m_lastx );
|
||||
m_altitude -= 0.002f * ( y - m_lasty );
|
||||
m_altitude = max( (float)-M_PI/2, min( (float)M_PI/2, m_altitude ) );
|
||||
}
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnMousePressed( vgui::MouseCode code, int x, int y )
|
||||
{
|
||||
UpdateTime( m_flLastMouseTime );
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
m_bSpin = false;
|
||||
m_flSpin = 0.0f;
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnMouseReleased( vgui::MouseCode code, int x, int y )
|
||||
{
|
||||
UpdateTime( m_flLastMouseTime );
|
||||
|
||||
if ( code == MOUSE_MIDDLE )
|
||||
{
|
||||
m_bSpin = ( fabs( m_flSpin ) > 1.0f );
|
||||
}
|
||||
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnMouseWheeled( int delta )
|
||||
{
|
||||
UpdateTime( m_flLastMouseTime );
|
||||
|
||||
UpdateZoom( -10.0f * delta );
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::UpdateTransform()
|
||||
{
|
||||
if ( !m_pTransform )
|
||||
return;
|
||||
|
||||
float y = m_zoom * sin( m_altitude );
|
||||
float xz = m_zoom * cos( m_altitude );
|
||||
float x = xz * sin( m_azimuth );
|
||||
float z = xz * cos( m_azimuth );
|
||||
|
||||
Vector position(x, y, z);
|
||||
AngleMatrix( RadianEuler( -m_altitude, m_azimuth, 0 ), position, *m_pTransform );
|
||||
}
|
||||
|
||||
|
||||
void CPotteryWheelManip::UpdateZoom( float delta )
|
||||
{
|
||||
m_zoom *= pow( 1.01f, delta );
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// MATSYS_CONTROLS.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$macro SRCDIR "..\.."
|
||||
|
||||
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
|
||||
|
||||
$Project "matsys_controls"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "assetpicker.cpp"
|
||||
$File "baseassetpicker.cpp"
|
||||
$File "colorpickerpanel.cpp"
|
||||
$File "curveeditorpanel.cpp"
|
||||
$File "gamefiletreeview.cpp"
|
||||
$File "manipulator.cpp"
|
||||
$File "matsyscontrols.cpp"
|
||||
$File "mdlpanel.cpp"
|
||||
$File "mdlpicker.cpp"
|
||||
$File "mdlsequencepicker.cpp"
|
||||
$File "picker.cpp"
|
||||
$File "potterywheelpanel.cpp"
|
||||
$File "proceduraltexturepanel.cpp"
|
||||
$File "QCGenerator.cpp"
|
||||
$File "sequencepicker.cpp"
|
||||
$File "tgapreviewpanel.cpp"
|
||||
$File "vmtpicker.cpp"
|
||||
$File "vmtpreviewpanel.cpp"
|
||||
$File "vtfpicker.cpp"
|
||||
$File "vtfpreviewpanel.cpp"
|
||||
$File "vmtpanel.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\matsys_controls\assetpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\baseassetpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\colorpickerpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\gamefiletreeview.h"
|
||||
$File "$SRCDIR\public\matsys_controls\manipulator.h"
|
||||
$File "$SRCDIR\public\matsys_controls\matsyscontrols.h"
|
||||
$File "$SRCDIR\public\matsys_controls\mdlpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\mdlpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\mdlsequencepicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\picker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\potterywheelpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\proceduraltexturepanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\QCGenerator.h"
|
||||
$File "$SRCDIR\public\matsys_controls\sequencepicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\tgapreviewpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vmtpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vmtpreviewpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vtfpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vtfpreviewpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vmtpanel.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib bitmap [$WIN32]
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue