* Fixed a variety of server browser issues with mods based on this SDK
* Fixed many warnings on various platforms
* Added source code for fgdlib and raytrace
* Updated many source files with the latest shared source from TF2.

OSX:
* Added support for Xcode 4.6
* Switched OSX builds to use Xcode instead of makefiles
* Moved libs from src/lib/osx32 to src/lib/public/osx32 or src/lib/common/osx32 to match windows better.

Linux:
* Moved libs from src/lib/linux32 to src/lib/public/linux32 or src/lib/common/linux32 to match windows better.
This commit is contained in:
Joe Ludwig 2013-09-02 11:39:10 -07:00
parent d9ac276a95
commit a0c29e7dd6
358 changed files with 11612 additions and 1482 deletions

View File

@ -0,0 +1,46 @@
ALWAYS_SEARCH_USER_PATHS = YES
HEADER_SEARCH_PATHS = $(HEADER_SEARCH_PATHS) $(SDKROOT)/usr/include/malloc
ARCHS = i386
ONLY_ACTIVE_ARCH = NO
COPY_PHASE_STRIP = NO
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
DEAD_CODE_STRIPPING = YES
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES
GCC_C_LANGUAGE_STANDARD = gnu99
GCC_ENABLE_OBJC_EXCEPTIONS = YES
GCC_SYMBOLS_PRIVATE_EXTERN = YES
GCC_INLINES_ARE_PRIVATE_EXTERN = YES
GCC_REUSE_STRINGS = YES
// CPP11_NO_LIBCXX is used to gate some C++11 features that require that we
// switch to libc++. We haven't switched to libc++11 because we have been unable
// to find a clean way to build libcef_dll_wrapper with libc++.
// We currently build libcef for Steam which needs to run on 10.5, and Xcode
// does not support linking with libc++ and targeting 10.5.
// Once libcef_dll_wrapper has been built with libc++, and you rebuild protobuf
// with libc++ (which is trivial), you can remove CPP11_NO_LIBCXX and add the
// following line to the xcconfig:
// CLANG_CXX_LIBRARY = libc++
GCC_PREPROCESSOR_DEFINITIONS = _DLL_EXT=.dylib NO_MALLOC_OVERRIDE=1 VPROF_LEVEL=1 NO_HOOK_MALLOC=1 PNG_NO_PEDANTIC_WARNINGS CPP11_NO_LIBCXX
BASE_CFLAGS= -Usprintf -Ustrncpy -UPROTECTED_THINGS_ENABLE
GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO
WARNING_CFLAGS = -Wno-deprecated-writable-strings -Wno-switch-enum -Wno-switch -Wno-unused-value -Wno-parentheses -Wno-logical-op-parentheses -Wno-c++11-narrowing
// CLANG - and use the ccache wrapper
GCC_VERSION = com.apple.compilers.llvm.clang.1_0
CC = $(SOURCE_ROOT)/devtools/bin/osx32/xcode_ccache_wrapper
LDPLUSPLUS = $(DT_TOOLCHAIN_DIR)/usr/bin/clang++
CLANG_WARN_CXX0X_EXTENSIONS = NO
CLANG_CXX_LANGUAGE_STANDARD = gnu++11
// include <memory.h> gets confused, 'cause ivp has one, and the system has one, and only one
// gets into the header map, so sacrifice speed for corectness.
USE_HEADERMAP = NO
SDKROOT = macosx10.7
MACOSX_DEPLOYMENT_TARGET = 10.5
GCC_FAST_MATH = YES

View File

@ -0,0 +1,3 @@
#!/bin/bash
exec $(dirname $0)/ccache "${DT_TOOLCHAIN_DIR}"/usr/bin/clang -Qunused-arguments "$@"

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,4 @@
#include "base.xcconfig"
GCC_OPTIMIZATION_LEVEL = 0
OTHER_CFLAGS = $(derived) $(BASE_CFLAGS)

View File

@ -42,7 +42,7 @@ CFLAGS = $(ARCH_FLAGS) $(CPPFLAGS) $(WARN_FLAGS) -fvisibility=$(SymbolVisibility
# In -std=gnu++0x mode we get lots of errors about "error: narrowing conversion". -fpermissive
# turns these into warnings in gcc, and -Wno-c++11-narrowing suppresses them entirely in clang 3.1+.
ifeq ($(CXX),clang++)
CXXFLAGS = $(CFLAGS) -Wno-c++11-narrowing -Wno-dangling-else
CXXFLAGS = $(CFLAGS) -Wno-c++11-narrowing
else
CXXFLAGS = $(CFLAGS) -fpermissive
endif

View File

@ -0,0 +1,4 @@
#include "base.xcconfig"
GCC_OPTIMIZATION_LEVEL = 2
OTHER_CFLAGS = $(derived) $(BASE_CFLAGS) -ftree-vectorize -fpredictive-commoning -funswitch-loops

Binary file not shown.

40
mp/src/fgdlib/fgdlib.vpc Normal file
View File

@ -0,0 +1,40 @@
//-----------------------------------------------------------------------------
// FGDLIB.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR ".."
$Include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
$Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE,$SRCDIR\utils\common"
}
}
$Project "Fgdlib"
{
$Folder "Source Files"
{
$File "gamedata.cpp"
$File "gdclass.cpp"
$File "gdvar.cpp"
$File "inputoutput.cpp"
$File "wckeyvalues.cpp"
}
$Folder "Header Files"
{
$File "$SRCDIR\public\fgdlib\fgdlib.h"
$File "$SRCDIR\public\fgdlib\gamedata.h"
$File "$SRCDIR\public\fgdlib\gdclass.h"
$File "$SRCDIR\public\fgdlib\gdvar.h"
$File "$SRCDIR\public\fgdlib\helperinfo.h"
$File "$SRCDIR\public\fgdlib\ieditortexture.h"
$File "$SRCDIR\public\fgdlib\inputoutput.h"
$File "$SRCDIR\public\fgdlib\wckeyvalues.h"
}
}

886
mp/src/fgdlib/gamedata.cpp Normal file
View File

@ -0,0 +1,886 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=============================================================================
#include <windows.h>
#include <tier0/dbg.h>
#include <io.h>
#include <WorldSize.h>
#include "fgdlib/GameData.h"
#include "fgdlib/HelperInfo.h"
#include "KeyValues.h"
#include "filesystem_tools.h"
#include "tier1/strtools.h"
#include "utlmap.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#pragma warning(disable:4244)
const int MAX_ERRORS = 5;
static GameDataMessageFunc_t g_pMsgFunc = NULL;
//-----------------------------------------------------------------------------
// Sets the function used for emitting error messages while loading gamedata files.
//-----------------------------------------------------------------------------
void GDSetMessageFunc(GameDataMessageFunc_t pFunc)
{
g_pMsgFunc = pFunc;
}
//-----------------------------------------------------------------------------
// Purpose: Fetches the next token from the file.
// Input : tr -
// ppszStore - Destination buffer, one of the following:
// pointer to NULL - token will be placed in an allocated buffer
// pointer to non-NULL buffer - token will be placed in buffer
// ttexpecting -
// pszExpecting -
// Output :
//-----------------------------------------------------------------------------
static bool DoGetToken(TokenReader &tr, char **ppszStore, int nSize, trtoken_t ttexpecting, const char *pszExpecting)
{
trtoken_t ttype;
if (*ppszStore != NULL)
{
// Reads the token into the given buffer.
ttype = tr.NextToken(*ppszStore, nSize);
}
else
{
// Allocates a buffer to hold the token.
ttype = tr.NextTokenDynamic(ppszStore);
}
if (ttype == TOKENSTRINGTOOLONG)
{
GDError(tr, "unterminated string or string too long");
return false;
}
//
// Check for a bad token type.
//
char *pszStore = *ppszStore;
bool bBadTokenType = false;
if ((ttype != ttexpecting) && (ttexpecting != TOKENNONE))
{
//
// If we were expecting a string and got an integer, don't worry about it.
// We can translate from integer to string.
//
if (!((ttexpecting == STRING) && (ttype == INTEGER)))
{
bBadTokenType = true;
}
}
if (bBadTokenType && (pszExpecting == NULL))
{
//
// We didn't get the expected token type but no expected
// string was specified.
//
char *pszTokenName;
switch (ttexpecting)
{
case IDENT:
{
pszTokenName = "identifier";
break;
}
case INTEGER:
{
pszTokenName = "integer";
break;
}
case STRING:
{
pszTokenName = "string";
break;
}
case OPERATOR:
default:
{
pszTokenName = "symbol";
break;
}
}
GDError(tr, "expecting %s", pszTokenName);
return false;
}
else if (bBadTokenType || ((pszExpecting != NULL) && !IsToken(pszStore, pszExpecting)))
{
//
// An expected string was specified, and we got either the wrong type or
// the right type but the wrong string,
//
GDError(tr, "expecting '%s', but found '%s'", pszExpecting, pszStore);
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : tr -
// error -
// Output :
//-----------------------------------------------------------------------------
bool GDError(TokenReader &tr, const char *error, ...)
{
char szBuf[128];
va_list vl;
va_start(vl, error);
vsprintf(szBuf, error, vl);
va_end(vl);
if (g_pMsgFunc)
{
// HACK: should use an enumeration for error level
g_pMsgFunc(1, tr.Error(szBuf));
}
if (tr.GetErrorCount() >= MAX_ERRORS)
{
if (g_pMsgFunc)
{
// HACK: should use an enumeration for error level
g_pMsgFunc(1, " - too many errors; aborting.");
}
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Fetches the next token from the file.
// Input : tr - The token reader object with which to fetch the token.
// pszStore - Buffer in which to place the token, NULL to discard the token.
// ttexpecting - The token type that we are expecting. If this is not TOKENNONE
// and token type read is different, the operation will fail.
// pszExpecting - The token string that we are expecting. If this string
// is not NULL and the token string read is different, the operation will fail.
// Output : Returns TRUE if the operation succeeded, FALSE if there was an error.
// If there was an error, the error will be reported in the message window.
//-----------------------------------------------------------------------------
bool GDGetToken(TokenReader &tr, char *pszStore, int nSize, trtoken_t ttexpecting, const char *pszExpecting)
{
Assert(pszStore != NULL);
if (pszStore != NULL)
{
return DoGetToken(tr, &pszStore, nSize, ttexpecting, pszExpecting);
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Fetches the next token from the file.
// Input : tr - The token reader object with which to fetch the token.
// pszStore - Buffer in which to place the token, NULL to discard the token.
// ttexpecting - The token type that we are expecting. If this is not TOKENNONE
// and token type read is different, the operation will fail.
// pszExpecting - The token string that we are expecting. If this string
// is not NULL and the token string read is different, the operation will fail.
// Output : Returns TRUE if the operation succeeded, FALSE if there was an error.
// If there was an error, the error will be reported in the message window.
//-----------------------------------------------------------------------------
bool GDSkipToken(TokenReader &tr, trtoken_t ttexpecting, const char *pszExpecting)
{
//
// Read the next token into a buffer and discard it.
//
char szDiscardBuf[MAX_TOKEN];
char *pszDiscardBuf = szDiscardBuf;
return DoGetToken(tr, &pszDiscardBuf, sizeof(szDiscardBuf), ttexpecting, pszExpecting);
}
//-----------------------------------------------------------------------------
// Purpose: Fetches the next token from the file, allocating a buffer exactly
// large enough to hold the token.
// Input : tr -
// ppszStore -
// ttexpecting -
// pszExpecting -
// Output :
//-----------------------------------------------------------------------------
bool GDGetTokenDynamic(TokenReader &tr, char **ppszStore, trtoken_t ttexpecting, const char *pszExpecting)
{
if (ppszStore == NULL)
{
return false;
}
*ppszStore = NULL;
return DoGetToken(tr, ppszStore, -1, ttexpecting, pszExpecting);
}
//-----------------------------------------------------------------------------
// Purpose: Constructor.
//-----------------------------------------------------------------------------
GameData::GameData(void)
{
m_nMaxMapCoord = 8192;
m_nMinMapCoord = -8192;
m_InstanceClass = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor.
//-----------------------------------------------------------------------------
GameData::~GameData(void)
{
ClearData();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void GameData::ClearData(void)
{
// delete classes.
int nCount = m_Classes.Count();
for (int i = 0; i < nCount; i++)
{
GDclass *pm = m_Classes.Element(i);
delete pm;
}
m_Classes.RemoveAll();
}
//-----------------------------------------------------------------------------
// Purpose: Loads a gamedata (FGD) file into this object.
// Input : pszFilename -
// Output : Returns TRUE on success, FALSE on failure.
//-----------------------------------------------------------------------------
BOOL GameData::Load(const char *pszFilename)
{
TokenReader tr;
if(GetFileAttributes(pszFilename) == 0xffffffff)
return FALSE;
if(!tr.Open(pszFilename))
return FALSE;
trtoken_t ttype;
char szToken[128];
while (1)
{
if (tr.GetErrorCount() >= MAX_ERRORS)
{
break;
}
ttype = tr.NextToken(szToken, sizeof(szToken));
if(ttype == TOKENEOF)
break;
if(ttype != OPERATOR || !IsToken(szToken, "@"))
{
if(!GDError(tr, "expected @"))
return FALSE;
}
// check what kind it is, and parse a new object
if (tr.NextToken(szToken, sizeof(szToken)) != IDENT)
{
if(!GDError(tr, "expected identifier after @"))
return FALSE;
}
if (IsToken(szToken, "baseclass") || IsToken(szToken, "pointclass") || IsToken(szToken, "solidclass") || IsToken(szToken, "keyframeclass") ||
IsToken(szToken, "moveclass") || IsToken(szToken, "npcclass") || IsToken(szToken, "filterclass"))
{
//
// New class.
//
GDclass *pNewClass = new GDclass;
if (!pNewClass->InitFromTokens(tr, this))
{
tr.IgnoreTill(OPERATOR, "@"); // go to next section
delete pNewClass;
}
else
{
if (IsToken(szToken, "baseclass")) // Not directly available to user.
{
pNewClass->SetBaseClass(true);
}
else if (IsToken(szToken, "pointclass")) // Generic point class.
{
pNewClass->SetPointClass(true);
}
else if (IsToken(szToken, "solidclass")) // Tied to solids.
{
pNewClass->SetSolidClass(true);
}
else if (IsToken(szToken, "npcclass")) // NPC class - can be spawned by npc_maker.
{
pNewClass->SetPointClass(true);
pNewClass->SetNPCClass(true);
}
else if (IsToken(szToken, "filterclass")) // Filter class - can be used as a filter
{
pNewClass->SetPointClass(true);
pNewClass->SetFilterClass(true);
}
else if (IsToken(szToken, "moveclass")) // Animating
{
pNewClass->SetMoveClass(true);
pNewClass->SetPointClass(true);
}
else if (IsToken(szToken, "keyframeclass")) // Animation keyframes
{
pNewClass->SetKeyFrameClass(true);
pNewClass->SetPointClass(true);
}
// Check and see if this new class matches an existing one. If so we will override the previous definition.
int nExistingClassIndex = 0;
GDclass *pExistingClass = ClassForName(pNewClass->GetName(), &nExistingClassIndex);
if (NULL != pExistingClass)
{
m_Classes.InsertAfter(nExistingClassIndex, pNewClass);
m_Classes.Remove(nExistingClassIndex);
}
else
{
m_Classes.AddToTail(pNewClass);
}
}
}
else if (IsToken(szToken, "include"))
{
if (GDGetToken(tr, szToken, sizeof(szToken), STRING))
{
// Let's assume it's in the same directory.
char justPath[MAX_PATH], loadFilename[MAX_PATH];
if ( Q_ExtractFilePath( pszFilename, justPath, sizeof( justPath ) ) )
{
Q_snprintf( loadFilename, sizeof( loadFilename ), "%s%s", justPath, szToken );
}
else
{
Q_strncpy( loadFilename, szToken, sizeof( loadFilename ) );
}
// First try our fully specified directory
if (!Load(loadFilename))
{
// Failing that, try our start directory
if (!Load(szToken))
{
GDError(tr, "error including file: %s", szToken);
}
}
}
}
else if (IsToken(szToken, "mapsize"))
{
if (!ParseMapSize(tr))
{
// Error in map size specifier, skip to next @ sign.
tr.IgnoreTill(OPERATOR, "@");
}
}
else if ( IsToken( szToken, "materialexclusion" ) )
{
if ( !LoadFGDMaterialExclusions( tr ) )
{
// FGD exclusions not defined; skip to next @ sign.
tr.IgnoreTill(OPERATOR, "@");
}
}
else if ( IsToken( szToken, "autovisgroup" ) )
{
if ( !LoadFGDAutoVisGroups( tr ) )
{
// FGD AutoVisGroups not defined; skip to next @ sign.
tr.IgnoreTill(OPERATOR, "@");
}
}
else
{
GDError(tr, "unrecognized section name %s", szToken);
tr.IgnoreTill(OPERATOR, "@");
}
}
if (tr.GetErrorCount() > 0)
{
return FALSE;
}
tr.Close();
return TRUE;
}
//-----------------------------------------------------------------------------
// Purpose: Parses the "mapsize" specifier, which should be of the form:
//
// mapsize(min, max)
//
// ex: mapsize(-8192, 8192)
//
// Input : tr -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool GameData::ParseMapSize(TokenReader &tr)
{
if (!GDSkipToken(tr, OPERATOR, "("))
{
return false;
}
char szToken[128];
if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
{
return false;
}
int nMin = atoi(szToken);
if (!GDSkipToken(tr, OPERATOR, ","))
{
return false;
}
if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
{
return false;
}
int nMax = atoi(szToken);
if (nMin != nMax)
{
m_nMinMapCoord = min(nMin, nMax);
m_nMaxMapCoord = max(nMin, nMax);
}
if (!GDSkipToken(tr, OPERATOR, ")"))
{
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszName -
// piIndex -
// Output :
//-----------------------------------------------------------------------------
GDclass *GameData::ClassForName(const char *pszName, int *piIndex)
{
int nCount = m_Classes.Count();
for (int i = 0; i < nCount; i++)
{
GDclass *mp = m_Classes.Element(i);
if(!strcmp(mp->GetName(), pszName))
{
if(piIndex)
piIndex[0] = i;
return mp;
}
}
return NULL;
}
// These are 'standard' keys that every entity uses, but they aren't specified that way in the .fgd
static const char *RequiredKeys[] =
{
"Origin",
"Angles",
NULL
};
//-----------------------------------------------------------------------------
// Purpose: this function will set up the initial class about to be instanced
// Input : pszClassName - the class name of the entity to be instanced
// pszInstancePrefix - the prefix to be used for all name fields
// Origin - the origin offset of the instance
// Angles - the angle rotation of the instance
// Output : if successful, will return the game data class of the class name
//-----------------------------------------------------------------------------
GDclass *GameData::BeginInstanceRemap( const char *pszClassName, const char *pszInstancePrefix, Vector &Origin, QAngle &Angle )
{
m_InstanceOrigin = Origin;
m_InstanceAngle = Angle;
AngleMatrix( m_InstanceAngle, m_InstanceOrigin, m_InstanceMat );
strcpy( m_InstancePrefix, pszInstancePrefix );
if ( m_InstanceClass )
{
delete m_InstanceClass;
m_InstanceClass = NULL;
}
if ( strcmpi( pszClassName, "info_overlay_accessor" ) == 0 )
{ // yucky hack for a made up entity in the bsp process
pszClassName = "info_overlay";
}
GDclass *BaseClass = ClassForName( pszClassName );
if ( BaseClass )
{
m_InstanceClass = new GDclass();
m_InstanceClass->Parent = this;
m_InstanceClass->AddBase( BaseClass );
for( int i = 0; RequiredKeys[ i ]; i++ )
{
if ( m_InstanceClass->VarForName( RequiredKeys[ i ] ) == NULL )
{
BaseClass = ClassForName( RequiredKeys[ i ] );
if ( BaseClass )
{
m_InstanceClass->AddBase( BaseClass );
}
}
}
}
else
{
m_InstanceClass = NULL;
}
return m_InstanceClass;
}
enum tRemapOperation
{
REMAP_NAME = 0,
REMAP_POSITION,
REMAP_ANGLE,
REMAP_ANGLE_NEGATIVE_PITCH,
};
static CUtlMap< GDIV_TYPE, tRemapOperation > RemapOperation;
//-----------------------------------------------------------------------------
// Purpose: function to sort the class type for the RemapOperations map
// Input : type1 - the first type to compare against
// type2 - the second type to compare against
// Output : returns true if the first type is less than the second one
//-----------------------------------------------------------------------------
static bool CUtlType_LessThan( const GDIV_TYPE &type1, const GDIV_TYPE &type2 )
{
return ( type1 < type2 );
}
//-----------------------------------------------------------------------------
// Purpose: this function will attempt to remap a key's value
// Input : pszKey - the name of the key
// pszInvalue - the original value
// AllowNameRemapping - only do name remapping if this parameter is true.
// this is generally only false on the instance level.
// Output : returns true if the value changed
// pszOutValue - the new value if changed
//-----------------------------------------------------------------------------
bool GameData::RemapKeyValue( const char *pszKey, const char *pszInValue, char *pszOutValue, TNameFixup NameFixup )
{
if ( RemapOperation.Count() == 0 )
{
RemapOperation.SetLessFunc( &CUtlType_LessThan );
RemapOperation.Insert( ivAngle, REMAP_ANGLE );
RemapOperation.Insert( ivTargetDest, REMAP_NAME );
RemapOperation.Insert( ivTargetSrc, REMAP_NAME );
RemapOperation.Insert( ivOrigin, REMAP_POSITION );
RemapOperation.Insert( ivAxis, REMAP_ANGLE );
RemapOperation.Insert( ivAngleNegativePitch, REMAP_ANGLE_NEGATIVE_PITCH );
}
if ( !m_InstanceClass )
{
return false;
}
GDinputvariable *KVVar = m_InstanceClass->VarForName( pszKey );
if ( !KVVar )
{
return false;
}
GDIV_TYPE KVType = KVVar->GetType();
int KVRemapIndex = RemapOperation.Find( KVType );
if ( KVRemapIndex == RemapOperation.InvalidIndex() )
{
return false;
}
strcpy( pszOutValue, pszInValue );
switch( RemapOperation[ KVRemapIndex ] )
{
case REMAP_NAME:
if ( KVType != ivInstanceVariable )
{
RemapNameField( pszInValue, pszOutValue, NameFixup );
}
break;
case REMAP_POSITION:
{
Vector inPoint( 0.0f, 0.0f, 0.0f ), outPoint;
sscanf ( pszInValue, "%f %f %f", &inPoint.x, &inPoint.y, &inPoint.z );
VectorTransform( inPoint, m_InstanceMat, outPoint );
sprintf( pszOutValue, "%g %g %g", outPoint.x, outPoint.y, outPoint.z );
}
break;
case REMAP_ANGLE:
if ( m_InstanceAngle.x != 0.0f || m_InstanceAngle.y != 0.0f || m_InstanceAngle.z != 0.0f )
{
QAngle inAngles( 0.0f, 0.0f, 0.0f ), outAngles;
matrix3x4_t angToWorld, localMatrix;
sscanf ( pszInValue, "%f %f %f", &inAngles.x, &inAngles.y, &inAngles.z );
AngleMatrix( inAngles, angToWorld );
MatrixMultiply( m_InstanceMat, angToWorld, localMatrix );
MatrixAngles( localMatrix, outAngles );
sprintf( pszOutValue, "%g %g %g", outAngles.x, outAngles.y, outAngles.z );
}
break;
case REMAP_ANGLE_NEGATIVE_PITCH:
if ( m_InstanceAngle.x != 0.0f || m_InstanceAngle.y != 0.0f || m_InstanceAngle.z != 0.0f )
{
QAngle inAngles( 0.0f, 0.0f, 0.0f ), outAngles;
matrix3x4_t angToWorld, localMatrix;
sscanf ( pszInValue, "%f", &inAngles.x ); // just the pitch
inAngles.x = -inAngles.x;
AngleMatrix( inAngles, angToWorld );
MatrixMultiply( m_InstanceMat, angToWorld, localMatrix );
MatrixAngles( localMatrix, outAngles );
sprintf( pszOutValue, "%g", -outAngles.x ); // just the pitch
}
break;
}
return ( strcmpi( pszInValue, pszOutValue ) != 0 );
}
//-----------------------------------------------------------------------------
// Purpose: this function will attempt to remap a name field.
// Input : pszInvalue - the original value
// AllowNameRemapping - only do name remapping if this parameter is true.
// this is generally only false on the instance level.
// Output : returns true if the value changed
// pszOutValue - the new value if changed
//-----------------------------------------------------------------------------
bool GameData::RemapNameField( const char *pszInValue, char *pszOutValue, TNameFixup NameFixup )
{
strcpy( pszOutValue, pszInValue );
if ( pszInValue[ 0 ] && pszInValue[ 0 ] != '@' )
{ // ! at the start of a value means it is global and should not be remaped
switch( NameFixup )
{
case NAME_FIXUP_PREFIX:
sprintf( pszOutValue, "%s-%s", m_InstancePrefix, pszInValue );
break;
case NAME_FIXUP_POSTFIX:
sprintf( pszOutValue, "%s-%s", pszInValue, m_InstancePrefix );
break;
}
}
return ( strcmpi( pszInValue, pszOutValue ) != 0 );
}
//-----------------------------------------------------------------------------
// Purpose: Gathers any FGD-defined material directory exclusions
// Input :
// Output :
//-----------------------------------------------------------------------------
bool GameData::LoadFGDMaterialExclusions( TokenReader &tr )
{
if ( !GDSkipToken( tr, OPERATOR, "[" ) )
{
return false;
}
while ( 1 )
{
char szToken[128];
bool bMatchFound = false;
if ( tr.PeekTokenType( szToken, sizeof( szToken ) ) == OPERATOR )
{
break;
}
else if ( GDGetToken( tr, szToken, sizeof( szToken ), STRING ) )
{
// Make sure we haven't loaded this from another FGD
for ( int i = 0; i < m_FGDMaterialExclusions.Count(); i++ )
{
if ( !stricmp( szToken, m_FGDMaterialExclusions[i].szDirectory ) )
{
bMatchFound = true;
break;
}
}
// Parse the string
if ( bMatchFound == false )
{
int index = m_FGDMaterialExclusions.AddToTail();
Q_strncpy( m_FGDMaterialExclusions[index].szDirectory, szToken, sizeof( m_FGDMaterialExclusions[index].szDirectory ) );
m_FGDMaterialExclusions[index].bUserGenerated = false;
}
}
}
//
// Closing square brace.
//
if ( !GDSkipToken( tr, OPERATOR, "]" ) )
{
return( FALSE );
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Gathers any FGD-defined Auto VisGroups
// Input :
// Output :
//-----------------------------------------------------------------------------
bool GameData::LoadFGDAutoVisGroups( TokenReader &tr )
{
int gindex = 0; // Index of AutoVisGroups
int cindex = 0; // Index of Classes
char szToken[128];
// Handle the Parent -- World Geometry, Entities, World Detail
if ( GDSkipToken( tr, OPERATOR, "=" ) )
{
// We expect a name
if ( !GDGetToken( tr, szToken, sizeof( szToken ), STRING ) )
{
return( FALSE );
}
gindex = m_FGDAutoVisGroups.AddToTail();
Q_strncpy( m_FGDAutoVisGroups[gindex].szParent, szToken, sizeof( m_FGDAutoVisGroups[gindex].szParent ) );
// We expect a Class
if ( !GDSkipToken( tr, OPERATOR, "[" ) )
{
return( FALSE );
}
}
// Handle the Class(es) -- Brush Entities, Occluders, Lights
while ( 1 )
{
if ( GDGetToken( tr, szToken, sizeof( szToken ), STRING ) )
{
cindex = m_FGDAutoVisGroups[gindex].m_Classes.AddToTail();
Q_strncpy( m_FGDAutoVisGroups[gindex].m_Classes[cindex].szClass, szToken, sizeof( m_FGDAutoVisGroups[gindex].m_Classes[cindex].szClass ) );
if ( !GDSkipToken( tr, OPERATOR, "[" ) )
{
return( FALSE );
}
// Parse objects/entities -- func_detail, point_template, light_spot
while ( 1 )
{
if ( tr.PeekTokenType( szToken, sizeof( szToken ) ) == OPERATOR )
{
break;
}
if ( !GDGetToken( tr, szToken, sizeof( szToken ), STRING ) )
{
return( FALSE );
}
m_FGDAutoVisGroups[gindex].m_Classes[cindex].szEntities.CopyAndAddToTail( szToken );
}
if ( !GDSkipToken( tr, OPERATOR, "]" ) )
{
return( FALSE );
}
// See if we have another Class coming up
if ( tr.PeekTokenType( szToken, sizeof( szToken ) ) == STRING )
{
continue;
}
// If no more Classes, we now expect a terminating ']'
if ( !GDSkipToken( tr, OPERATOR, "]" ) )
{
return( FALSE );
}
// We're done
return true;
}
// We don't have another Class; look for a terminating brace
else
{
if ( !GDSkipToken( tr, OPERATOR, "]" ) )
{
return( FALSE );
}
}
}
// Safety net
GDError( tr, "Malformed AutoVisGroup -- Last processed: %s", szToken );
return( FALSE );
}
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgoff.h"

1041
mp/src/fgdlib/gdclass.cpp Normal file

File diff suppressed because it is too large Load Diff

729
mp/src/fgdlib/gdvar.cpp Normal file
View File

@ -0,0 +1,729 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=============================================================================
#include "fgdlib/fgdlib.h"
#include "fgdlib/GameData.h"
#include "fgdlib/WCKeyValues.h"
#include "fgdlib/gdvar.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
typedef struct
{
GDIV_TYPE eType; // The enumeration of this type.
char *pszName; // The name of this type.
trtoken_t eStoreAs; // How this type is stored (STRING, INTEGER, etc).
} TypeMap_t;
//-----------------------------------------------------------------------------
// Maps type names to type enums and parsing logic for values.
//-----------------------------------------------------------------------------
static TypeMap_t TypeMap[] =
{
{ ivAngle, "angle", STRING },
{ ivChoices, "choices", STRING },
{ ivColor1, "color1", STRING },
{ ivColor255, "color255", STRING },
{ ivDecal, "decal", STRING },
{ ivFlags, "flags", INTEGER },
{ ivInteger, "integer", INTEGER },
{ ivSound, "sound", STRING },
{ ivSprite, "sprite", STRING },
{ ivString, "string", STRING },
{ ivStudioModel, "studio", STRING },
{ ivTargetDest, "target_destination", STRING },
{ ivTargetSrc, "target_source", STRING },
{ ivTargetNameOrClass, "target_name_or_class", STRING }, // Another version of target_destination that accepts class names
{ ivVector, "vector", STRING },
{ ivNPCClass, "npcclass", STRING },
{ ivFilterClass, "filterclass", STRING },
{ ivFloat, "float", STRING },
{ ivMaterial, "material", STRING },
{ ivScene, "scene", STRING },
{ ivSide, "side", STRING },
{ ivSideList, "sidelist", STRING },
{ ivOrigin, "origin", STRING },
{ ivAxis, "axis", STRING },
{ ivVecLine, "vecline", STRING },
{ ivPointEntityClass, "pointentityclass", STRING },
{ ivNodeDest, "node_dest", INTEGER },
{ ivInstanceFile, "instance_file", STRING },
{ ivAngleNegativePitch, "angle_negative_pitch", STRING },
{ ivInstanceVariable, "instance_variable", STRING },
{ ivInstanceParm, "instance_parm", STRING },
};
char *GDinputvariable::m_pszEmpty = "";
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
GDinputvariable::GDinputvariable(void)
{
m_szDefault[0] = 0;
m_nDefault = 0;
m_szValue[0] = 0;
m_bReportable = FALSE;
m_bReadOnly = false;
m_pszDescription = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: construct generally used for creating a temp instance parm type
// Input : szType - the textual type of this variable
// szName - the name description of this variable
//-----------------------------------------------------------------------------
GDinputvariable::GDinputvariable( const char *szType, const char *szName )
{
m_szDefault[0] = 0;
m_nDefault = 0;
m_szValue[0] = 0;
m_bReportable = FALSE;
m_bReadOnly = false;
m_pszDescription = NULL;
m_eType = GetTypeFromToken( szType );
strcpy( m_szName, szName );
}
//-----------------------------------------------------------------------------
// Purpose: Destructor.
//-----------------------------------------------------------------------------
GDinputvariable::~GDinputvariable(void)
{
delete [] m_pszDescription;
m_Items.RemoveAll();
}
//-----------------------------------------------------------------------------
// Purpose: Implements the copy operator.
//-----------------------------------------------------------------------------
GDinputvariable &GDinputvariable::operator =(GDinputvariable &Other)
{
m_eType = Other.GetType();
strcpy(m_szName, Other.m_szName);
strcpy(m_szLongName, Other.m_szLongName);
strcpy(m_szDefault, Other.m_szDefault);
//
// Copy the description.
//
delete [] m_pszDescription;
if (Other.m_pszDescription != NULL)
{
m_pszDescription = new char[strlen(Other.m_pszDescription) + 1];
strcpy(m_pszDescription, Other.m_pszDescription);
}
else
{
m_pszDescription = NULL;
}
m_nDefault = Other.m_nDefault;
m_bReportable = Other.m_bReportable;
m_bReadOnly = Other.m_bReadOnly;
m_Items.RemoveAll();
int nCount = Other.m_Items.Count();
for (int i = 0; i < nCount; i++)
{
m_Items.AddToTail(Other.m_Items.Element(i));
}
return(*this);
}
//-----------------------------------------------------------------------------
// Purpose: Returns the storage format of a given variable type.
// Input : pszToken - Sting containing the token.
// Output : GDIV_TYPE corresponding to the token in the string, ivBadType if the
// string does not correspond to a valid type.
//-----------------------------------------------------------------------------
trtoken_t GDinputvariable::GetStoreAsFromType(GDIV_TYPE eType)
{
for (int i = 0; i < sizeof(TypeMap) / sizeof(TypeMap[0]); i++)
{
if (TypeMap[i].eType == eType)
{
return(TypeMap[i].eStoreAs);
}
}
Assert(FALSE);
return(STRING);
}
//-----------------------------------------------------------------------------
// Purpose: Returns the enumerated type of a string token.
// Input : pszToken - Sting containing the token.
// Output : GDIV_TYPE corresponding to the token in the string, ivBadType if the
// string does not correspond to a valid type.
//-----------------------------------------------------------------------------
GDIV_TYPE GDinputvariable::GetTypeFromToken(const char *pszToken)
{
for (int i = 0; i < sizeof(TypeMap) / sizeof(TypeMap[0]); i++)
{
if (IsToken(pszToken, TypeMap[i].pszName))
{
return(TypeMap[i].eType);
}
}
return(ivBadType);
}
//-----------------------------------------------------------------------------
// Purpose: Returns a string representing the type of this variable, eg. "integer".
//-----------------------------------------------------------------------------
const char *GDinputvariable::GetTypeText(void)
{
for (int i = 0; i < sizeof(TypeMap) / sizeof(TypeMap[0]); i++)
{
if (TypeMap[i].eType == m_eType)
{
return(TypeMap[i].pszName);
}
}
return("unknown");
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : tr -
// Output : Returns TRUE on success, FALSE on failure.
//-----------------------------------------------------------------------------
BOOL GDinputvariable::InitFromTokens(TokenReader& tr)
{
char szToken[128];
if (!GDGetToken(tr, m_szName, sizeof(m_szName), IDENT))
{
return FALSE;
}
if (!GDSkipToken(tr, OPERATOR, "("))
{
return FALSE;
}
// check for "reportable" marker
trtoken_t ttype = tr.NextToken(szToken, sizeof(szToken));
if (ttype == OPERATOR)
{
if (!strcmp(szToken, "*"))
{
m_bReportable = true;
}
}
else
{
tr.Stuff(ttype, szToken);
}
// get type
if (!GDGetToken(tr, szToken, sizeof(szToken), IDENT))
{
return FALSE;
}
if (!GDSkipToken(tr, OPERATOR, ")"))
{
return FALSE;
}
//
// Check for known variable types.
//
m_eType = GetTypeFromToken(szToken);
if (m_eType == ivBadType)
{
GDError(tr, "'%s' is not a valid variable type", szToken);
return FALSE;
}
//
// Look ahead at the next token.
//
ttype = tr.PeekTokenType(szToken,sizeof(szToken));
//
// Check for the "readonly" specifier.
//
if ((ttype == IDENT) && IsToken(szToken, "readonly"))
{
tr.NextToken(szToken, sizeof(szToken));
m_bReadOnly = true;
//
// Look ahead at the next token.
//
ttype = tr.PeekTokenType(szToken,sizeof(szToken));
}
//
// Check for the ':' indicating a long name.
//
if (ttype == OPERATOR && IsToken(szToken, ":"))
{
//
// Eat the ':'.
//
tr.NextToken(szToken, sizeof(szToken));
if (m_eType == ivFlags)
{
GDError(tr, "flag sets do not have long names");
return FALSE;
}
//
// Get the long name.
//
if (!GDGetToken(tr, m_szLongName, sizeof(m_szLongName), STRING))
{
return(FALSE);
}
//
// Look ahead at the next token.
//
ttype = tr.PeekTokenType(szToken,sizeof(szToken));
//
// Check for the ':' indicating a default value.
//
if (ttype == OPERATOR && IsToken(szToken, ":"))
{
//
// Eat the ':'.
//
tr.NextToken(szToken, sizeof(szToken));
//
// Look ahead at the next token.
//
ttype = tr.PeekTokenType(szToken,sizeof(szToken));
if (ttype == OPERATOR && IsToken(szToken, ":"))
{
//
// No default value provided, skip to the description.
//
}
else
{
//
// Determine how to parse the default value. If this is a choices field, the
// default could either be a string or an integer, so we must look ahead and
// use whichever is there.
//
trtoken_t eStoreAs = GetStoreAsFromType(m_eType);
if (eStoreAs == STRING)
{
if (!GDGetToken(tr, m_szDefault, sizeof(m_szDefault), STRING))
{
return(FALSE);
}
}
else if (eStoreAs == INTEGER)
{
if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
{
return(FALSE);
}
m_nDefault = atoi(szToken);
}
//
// Look ahead at the next token.
//
ttype = tr.PeekTokenType(szToken,sizeof(szToken));
}
}
//
// Check for the ':' indicating a description.
//
if (ttype == OPERATOR && IsToken(szToken, ":"))
{
//
// Eat the ':'.
//
tr.NextToken(szToken, sizeof(szToken));
//
// Read the description.
//
// If we've already read a description then free it to avoid memory leaks.
if ( m_pszDescription )
{
delete [] m_pszDescription;
m_pszDescription = NULL;
}
if (!GDGetTokenDynamic(tr, &m_pszDescription, STRING))
{
return(FALSE);
}
//
// Look ahead at the next token.
//
ttype = tr.PeekTokenType(szToken,sizeof(szToken));
}
}
else
{
//
// Default long name is short name.
//
strcpy(m_szLongName, m_szName);
}
//
// Check for the ']' indicating the end of the class definition.
//
if ((ttype == OPERATOR && IsToken(szToken, "]")) || ttype != OPERATOR)
{
if (m_eType == ivFlags || m_eType == ivChoices)
{
//
// Can't define a flags or choices variable without providing any flags or choices.
//
GDError(tr, "no %s specified", m_eType == ivFlags ? "flags" : "choices");
return(FALSE);
}
return(TRUE);
}
if (!GDSkipToken(tr, OPERATOR, "="))
{
return(FALSE);
}
if (m_eType != ivFlags && m_eType != ivChoices)
{
GDError(tr, "didn't expect '=' here");
return(FALSE);
}
// should be '[' to start flags/choices
if (!GDSkipToken(tr, OPERATOR, "["))
{
return(FALSE);
}
// get flags?
if (m_eType == ivFlags)
{
GDIVITEM ivi;
while (1)
{
ttype = tr.PeekTokenType();
if (ttype != INTEGER)
{
break;
}
// store bitflag value
GDGetToken(tr, szToken, sizeof(szToken), INTEGER);
sscanf( szToken, "%lu", &ivi.iValue );
// colon..
if (!GDSkipToken(tr, OPERATOR, ":"))
{
return FALSE;
}
// get description
if (!GDGetToken(tr, szToken, sizeof(szToken), STRING))
{
return FALSE;
}
strcpy(ivi.szCaption, szToken);
// colon..
if (!GDSkipToken(tr, OPERATOR, ":"))
{
return FALSE;
}
// get default setting
if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
{
return FALSE;
}
ivi.bDefault = atoi(szToken) ? TRUE : FALSE;
// add item to array of items
m_Items.AddToTail(ivi);
}
// Set the default value.
unsigned long nDefault = 0;
for (int i = 0; i < m_Items.Count(); i++)
{
if (m_Items[i].bDefault)
nDefault |= m_Items[i].iValue;
}
m_nDefault = (int)nDefault;
Q_snprintf( m_szDefault, sizeof( m_szDefault ), "%d", m_nDefault );
}
else if (m_eType == ivChoices)
{
GDIVITEM ivi;
while (1)
{
ttype = tr.PeekTokenType();
if ((ttype != INTEGER) && (ttype != STRING))
{
break;
}
// store choice value
GDGetToken(tr, szToken, sizeof(szToken), ttype);
ivi.iValue = 0;
strcpy(ivi.szValue, szToken);
// colon
if (!GDSkipToken(tr, OPERATOR, ":"))
{
return FALSE;
}
// get description
if (!GDGetToken(tr, szToken, sizeof(szToken), STRING))
{
return FALSE;
}
strcpy(ivi.szCaption, szToken);
m_Items.AddToTail(ivi);
}
}
if (!GDSkipToken(tr, OPERATOR, "]"))
{
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------------
// Purpose: Decodes a key value from a string.
// Input : pkv - Pointer to the key value object containing string encoded value.
//-----------------------------------------------------------------------------
void GDinputvariable::FromKeyValue(MDkeyvalue *pkv)
{
trtoken_t eStoreAs = GetStoreAsFromType(m_eType);
if (eStoreAs == STRING)
{
strcpy(m_szValue, pkv->szValue);
}
else if (eStoreAs == INTEGER)
{
m_nValue = atoi(pkv->szValue);
}
}
//-----------------------------------------------------------------------------
// Purpose: Determines whether the given flag is set (assuming this is an ivFlags).
// Input : uCheck - Flag to check.
// Output : Returns TRUE if flag is set, FALSE if not.
//-----------------------------------------------------------------------------
BOOL GDinputvariable::IsFlagSet(unsigned int uCheck)
{
Assert(m_eType == ivFlags);
return (((unsigned int)m_nValue & uCheck) == uCheck) ? TRUE : FALSE;
}
//-----------------------------------------------------------------------------
// Purpose: Combines the flags or choices items from another variable into our
// list of flags or choices. Ours take priority if collisions occur.
// Input : Other - The variable whose items are being merged with ours.
//-----------------------------------------------------------------------------
void GDinputvariable::Merge(GDinputvariable &Other)
{
//
// Only valid if we are of the same type.
//
if (Other.GetType() != GetType())
{
return;
}
//
// Add Other's items to this ONLY if there is no same-value entry
// for a specific item.
//
bool bFound = false;
int nOurItems = m_Items.Count();
for (int i = 0; i < Other.m_Items.Count(); i++)
{
GDIVITEM &TheirItem = Other.m_Items[i];
for (int j = 0; j < nOurItems; j++)
{
GDIVITEM &OurItem = m_Items[j];
if (TheirItem.iValue == OurItem.iValue)
{
bFound = true;
break;
}
}
if (!bFound)
{
//
// Not found in our list - add their item to our list.
//
m_Items.AddToTail(TheirItem);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Determines whether the given flag is set (assuming this is an ivFlags).
// Input : uFlags - Flags to set.
// bSet - TRUE to set the flags, FALSE to clear them.
//-----------------------------------------------------------------------------
void GDinputvariable::SetFlag(unsigned int uFlags, BOOL bSet)
{
Assert(m_eType == ivFlags);
if (bSet)
{
m_nValue |= uFlags;
}
else
{
m_nValue &= ~uFlags;
}
}
//-----------------------------------------------------------------------------
// Purpose: Sets this keyvalue to its default value.
//-----------------------------------------------------------------------------
void GDinputvariable::ResetDefaults(void)
{
if (m_eType == ivFlags)
{
m_nValue = 0;
//
// Run thru flags and set any default flags.
//
int nCount = m_Items.Count();
for (int i = 0; i < nCount; i++)
{
if (m_Items[i].bDefault)
{
m_nValue |= GetFlagMask(i);
}
}
}
else
{
m_nValue = m_nDefault;
strcpy(m_szValue, m_szDefault);
}
}
//-----------------------------------------------------------------------------
// Purpose: Encodes a key value as a string.
// Input : pkv - Pointer to the key value object to receive the encoded string.
//-----------------------------------------------------------------------------
void GDinputvariable::ToKeyValue(MDkeyvalue *pkv)
{
strcpy(pkv->szKey, m_szName);
trtoken_t eStoreAs = GetStoreAsFromType(m_eType);
if (eStoreAs == STRING)
{
strcpy(pkv->szValue, m_szValue);
}
else if (eStoreAs == INTEGER)
{
itoa(m_nValue, pkv->szValue, 10);
}
}
//-----------------------------------------------------------------------------
// Purpose: Returns the description string that corresponds to a value string
// for a choices list.
// Input : pszString - The choices value string.
// Output : Returns the description string.
//-----------------------------------------------------------------------------
const char *GDinputvariable::ItemStringForValue(const char *szValue)
{
int nCount = m_Items.Count();
for (int i = 0; i < nCount; i++)
{
if (!stricmp(m_Items[i].szValue, szValue))
{
return(m_Items[i].szCaption);
}
}
return(NULL);
}
//-----------------------------------------------------------------------------
// Purpose: Returns the value string that corresponds to a description string
// for a choices list.
// Input : pszString - The choices description string.
// Output : Returns the value string.
//-----------------------------------------------------------------------------
const char *GDinputvariable::ItemValueForString(const char *szString)
{
int nCount = m_Items.Count();
for (int i = 0; i < nCount; i++)
{
if (!strcmpi(m_Items[i].szCaption, szString))
{
return(m_Items[i].szValue);
}
}
return(NULL);
}
//-----------------------------------------------------------------------------
// Purpose: this function will let you iterate through the text names of the variable types
// Input : eType - the type to get the text of
// Output : returns the textual name
//-----------------------------------------------------------------------------
const char *GDinputvariable::GetVarTypeName( GDIV_TYPE eType )
{
return TypeMap[ eType ].pszName;
}

View File

@ -0,0 +1,171 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include <tier0/dbg.h>
#include "fgdlib/InputOutput.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
typedef struct
{
InputOutputType_t eType; // The enumeration of this type.
char *pszName; // The name of this type.
} TypeMap_t;
char *CClassInputOutputBase::g_pszEmpty = "";
//-----------------------------------------------------------------------------
// Maps type names to type enums for inputs and outputs.
//-----------------------------------------------------------------------------
static TypeMap_t TypeMap[] =
{
{ iotVoid, "void" },
{ iotInt, "integer" },
{ iotBool, "bool" },
{ iotString, "string" },
{ iotFloat, "float" },
{ iotVector, "vector" },
{ iotEHandle, "target_destination" },
{ iotColor, "color255" },
{ iotEHandle, "ehandle" }, // for backwards compatibility
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CClassInputOutputBase::CClassInputOutputBase(void)
{
m_eType = iotInvalid;
m_pszDescription = NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszName -
// eType -
//-----------------------------------------------------------------------------
CClassInputOutputBase::CClassInputOutputBase(const char *pszName, InputOutputType_t eType)
{
m_pszDescription = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor.
//-----------------------------------------------------------------------------
CClassInputOutputBase::~CClassInputOutputBase(void)
{
delete m_pszDescription;
m_pszDescription = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Returns a string representing the type of this I/O, eg. "integer".
//-----------------------------------------------------------------------------
const char *CClassInputOutputBase::GetTypeText(void)
{
for (int i = 0; i < sizeof(TypeMap) / sizeof(TypeMap[0]); i++)
{
if (TypeMap[i].eType == m_eType)
{
return(TypeMap[i].pszName);
}
}
return("unknown");
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : szType -
// Output : InputOutputType_t
//-----------------------------------------------------------------------------
InputOutputType_t CClassInputOutputBase::SetType(const char *szType)
{
for (int i = 0; i < sizeof(TypeMap) / sizeof(TypeMap[0]); i++)
{
if (!stricmp(TypeMap[i].pszName, szType))
{
m_eType = TypeMap[i].eType;
return(m_eType);
}
}
return(iotInvalid);
}
//-----------------------------------------------------------------------------
// Purpose: Assignment operator.
//-----------------------------------------------------------------------------
CClassInputOutputBase &CClassInputOutputBase::operator =(CClassInputOutputBase &Other)
{
strcpy(m_szName, Other.m_szName);
m_eType = Other.m_eType;
//
// Copy the description.
//
delete m_pszDescription;
if (Other.m_pszDescription != NULL)
{
m_pszDescription = new char[strlen(Other.m_pszDescription) + 1];
strcpy(m_pszDescription, Other.m_pszDescription);
}
else
{
m_pszDescription = NULL;
}
return(*this);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CClassInput::CClassInput(void)
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszName -
// eType -
//-----------------------------------------------------------------------------
CClassInput::CClassInput(const char *pszName, InputOutputType_t eType)
: CClassInputOutputBase(pszName, eType)
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CClassOutput::CClassOutput(void)
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszName -
// eType -
//-----------------------------------------------------------------------------
CClassOutput::CClassOutput(const char *pszName, InputOutputType_t eType)
: CClassInputOutputBase(pszName, eType)
{
}

View File

@ -0,0 +1,282 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "fgdlib/WCKeyValues.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//-----------------------------------------------------------------------------
// Purpose: Destructor.
//-----------------------------------------------------------------------------
MDkeyvalue::~MDkeyvalue(void)
{
}
//-----------------------------------------------------------------------------
// Purpose: Assignment operator.
//-----------------------------------------------------------------------------
MDkeyvalue &MDkeyvalue::operator =(const MDkeyvalue &other)
{
V_strcpy_safe(szKey, other.szKey);
V_strcpy_safe(szValue, other.szValue);
return(*this);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void WCKVBase_Vector::RemoveKeyAt(int nIndex)
{
Assert(nIndex >= 0);
Assert(nIndex < (int)m_KeyValues.Count());
if ((nIndex >= 0) && (nIndex < (int)m_KeyValues.Count()))
{
m_KeyValues.Remove(nIndex);
}
}
//-----------------------------------------------------------------------------
// Purpose: Adds the key to the keyvalue array. Allows duplicate keys.
//
// NOTE: This should only be used for keyvalue lists that do not require
// unique key names! If you use this function then you should use GetCount
// and GetKey/Value by index rather than GetValue by key name.
//-----------------------------------------------------------------------------
void WCKVBase_Vector::AddKeyValue(const char *pszKey, const char *pszValue)
{
if (!pszKey || !pszValue)
{
return;
}
char szTmpKey[KEYVALUE_MAX_KEY_LENGTH];
char szTmpValue[KEYVALUE_MAX_VALUE_LENGTH];
V_strcpy_safe(szTmpKey, pszKey);
V_strcpy_safe(szTmpValue, pszValue);
StripEdgeWhiteSpace(szTmpKey);
StripEdgeWhiteSpace(szTmpValue);
//
// Add the keyvalue to our list.
//
MDkeyvalue newkv;
V_strcpy_safe(newkv.szKey, szTmpKey);
V_strcpy_safe(newkv.szValue, szTmpValue);
m_KeyValues.AddToTail(newkv);
}
int WCKVBase_Vector::FindByKeyName( const char *pKeyName ) const
{
for ( int i=0; i < m_KeyValues.Count(); i++ )
{
if ( V_stricmp( m_KeyValues[i].szKey, pKeyName ) == 0 )
return i;
}
return GetInvalidIndex();
}
void WCKVBase_Vector::InsertKeyValue( const MDkeyvalue &kv )
{
m_KeyValues.AddToTail( kv );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void WCKVBase_Dict::RemoveKeyAt(int nIndex)
{
m_KeyValues.RemoveAt(nIndex);
}
int WCKVBase_Dict::FindByKeyName( const char *pKeyName ) const
{
return m_KeyValues.Find( pKeyName );
}
void WCKVBase_Dict::InsertKeyValue( const MDkeyvalue &kv )
{
m_KeyValues.Insert( kv.szKey, kv );
}
//-----------------------------------------------------------------------------
// Purpose: Constructor. Sets the initial size of the keyvalue array.
//-----------------------------------------------------------------------------
template<class Base>
WCKeyValuesT<Base>::WCKeyValuesT(void)
{
}
//-----------------------------------------------------------------------------
// Purpose: Destructor. Deletes the contents of this keyvalue array.
//-----------------------------------------------------------------------------
template<class Base>
WCKeyValuesT<Base>::~WCKeyValuesT(void)
{
//int i = 0;
//while (i < m_KeyValues.GetSize())
//{
// delete m_KeyValues.GetAt(i++);
//}
RemoveAll();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
template<class Base>
const char *WCKeyValuesT<Base>::GetValue(const char *pszKey, int *piIndex) const
{
int i = FindByKeyName( pszKey );
if ( i == GetInvalidIndex() )
{
return NULL;
}
else
{
if(piIndex)
piIndex[0] = i;
return m_KeyValues[i].szValue;
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
template<class Base>
void WCKeyValuesT<Base>::RemoveKey(const char *pszKey)
{
SetValue(pszKey, (const char *)NULL);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
template<class Base>
void WCKeyValuesT<Base>::SetValue(const char *pszKey, int iValue)
{
char szValue[100];
itoa(iValue, szValue, 10);
SetValue(pszKey, szValue);
}
//-----------------------------------------------------------------------------
// Purpose: Strips leading and trailing whitespace from the string.
// Input : psz -
//-----------------------------------------------------------------------------
void StripEdgeWhiteSpace(char *psz)
{
if (!psz || !*psz)
return;
char *pszBase = psz;
while (V_isspace(*psz))
{
psz++;
}
int iLen = strlen(psz) - 1;
if ( iLen >= 0 )
{
while (V_isspace(psz[iLen]))
{
psz[iLen--] = 0;
}
}
if (psz != pszBase)
{
memmove(pszBase, psz, iLen + 2);
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pszKey -
// pszValue -
//-----------------------------------------------------------------------------
template<class Base>
void WCKeyValuesT<Base>::SetValue(const char *pszKey, const char *pszValue)
{
char szTmpKey[KEYVALUE_MAX_KEY_LENGTH];
char szTmpValue[KEYVALUE_MAX_VALUE_LENGTH];
V_strcpy_safe(szTmpKey, pszKey);
if (pszValue != NULL)
{
V_strcpy_safe(szTmpValue, pszValue);
}
else
{
szTmpValue[0] = 0;
}
StripEdgeWhiteSpace(szTmpKey);
StripEdgeWhiteSpace(szTmpValue);
int i = FindByKeyName( szTmpKey );
if ( i == GetInvalidIndex() )
{
if ( pszValue )
{
//
// Add the keyvalue to our list.
//
MDkeyvalue newkv;
Q_strncpy( newkv.szKey, szTmpKey, sizeof( newkv.szKey ) );
Q_strncpy( newkv.szValue, szTmpValue, sizeof( newkv.szValue ) );
InsertKeyValue( newkv );
}
}
else
{
if (pszValue != NULL)
{
V_strncpy(m_KeyValues[i].szValue, szTmpValue, sizeof(m_KeyValues[i].szValue));
}
//
// If we are setting to a NULL value, delete the key.
//
else
{
RemoveKeyAt( i );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
template<class Base>
void WCKeyValuesT<Base>::RemoveAll(void)
{
m_KeyValues.RemoveAll();
}
// Explicit instantiations.
template class WCKeyValuesT<WCKVBase_Dict>;
template class WCKeyValuesT<WCKVBase_Vector>;

View File

@ -2462,27 +2462,36 @@ void C_BaseEntity::UnlinkFromHierarchy()
void C_BaseEntity::ValidateModelIndex( void )
{
#ifdef TF_CLIENT_DLL
if ( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_DEFAULT] > 0 )
if ( m_nModelIndexOverrides[VISION_MODE_NONE] > 0 )
{
if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_HALLOWEEN ) )
{
if ( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_HALLOWEEN] > 0 )
if ( m_nModelIndexOverrides[VISION_MODE_HALLOWEEN] > 0 )
{
SetModelByIndex( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_HALLOWEEN] );
SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_HALLOWEEN] );
return;
}
}
if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_PYRO ) )
{
if ( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_PYRO] > 0 )
if ( m_nModelIndexOverrides[VISION_MODE_PYRO] > 0 )
{
SetModelByIndex( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_PYRO] );
SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_PYRO] );
return;
}
}
SetModelByIndex( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_DEFAULT] );
if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_ROME ) )
{
if ( m_nModelIndexOverrides[VISION_MODE_ROME] > 0 )
{
SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_ROME] );
return;
}
}
SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_NONE] );
return;
}
@ -3597,6 +3606,48 @@ void C_BaseEntity::AddStudioDecal( const Ray_t& ray, int hitbox, int decalIndex,
}
}
//-----------------------------------------------------------------------------
void C_BaseEntity::AddColoredStudioDecal( const Ray_t& ray, int hitbox, int decalIndex,
bool doTrace, trace_t& tr, Color cColor, int maxLODToDecal )
{
if (doTrace)
{
enginetrace->ClipRayToEntity( ray, MASK_SHOT, this, &tr );
// Trace the ray against the entity
if (tr.fraction == 1.0f)
return;
// Set the trace index appropriately...
tr.m_pEnt = this;
}
// Exit out after doing the trace so any other effects that want to happen can happen.
if ( !r_drawmodeldecals.GetBool() )
return;
// Found the point, now lets apply the decals
CreateModelInstance();
// FIXME: Pass in decal up?
Vector up(0, 0, 1);
if (doTrace && (GetSolid() == SOLID_VPHYSICS) && !tr.startsolid && !tr.allsolid)
{
// Choose a more accurate normal direction
// Also, since we have more accurate info, we can avoid pokethru
Vector temp;
VectorSubtract( tr.endpos, tr.plane.normal, temp );
Ray_t betterRay;
betterRay.Init( tr.endpos, temp );
modelrender->AddColoredDecal( m_ModelInstance, betterRay, up, decalIndex, GetStudioBody(), cColor, true, maxLODToDecal );
}
else
{
modelrender->AddColoredDecal( m_ModelInstance, ray, up, decalIndex, GetStudioBody(), cColor, false, maxLODToDecal );
}
}
//-----------------------------------------------------------------------------
// This method works when we've got a brush model
@ -3647,6 +3698,56 @@ void C_BaseEntity::AddDecal( const Vector& rayStart, const Vector& rayEnd,
}
}
//-----------------------------------------------------------------------------
void C_BaseEntity::AddColoredDecal( const Vector& rayStart, const Vector& rayEnd,
const Vector& decalCenter, int hitbox, int decalIndex, bool doTrace, trace_t& tr, Color cColor, int maxLODToDecal )
{
Ray_t ray;
ray.Init( rayStart, rayEnd );
// FIXME: Better bloat?
// Bloat a little bit so we get the intersection
ray.m_Delta *= 1.1f;
int modelType = modelinfo->GetModelType( model );
if ( doTrace )
{
enginetrace->ClipRayToEntity( ray, MASK_SHOT, this, &tr );
switch ( modelType )
{
case mod_studio:
tr.m_pEnt = this;
break;
case mod_brush:
if ( tr.fraction == 1.0f )
return; // Explicitly end
default:
// By default, no collision
tr.fraction = 1.0f;
break;
}
}
switch ( modelType )
{
case mod_studio:
AddColoredStudioDecal( ray, hitbox, decalIndex, doTrace, tr, cColor, maxLODToDecal );
break;
case mod_brush:
{
color32 cColor32 = { cColor.r(), cColor.g(), cColor.b(), cColor.a() };
effects->DecalColorShoot( decalIndex, index, model, GetAbsOrigin(), GetAbsAngles(), decalCenter, 0, 0, cColor32 );
}
break;
default:
// By default, no collision
tr.fraction = 1.0f;
break;
}
}
//-----------------------------------------------------------------------------
// A method to remove all decals from an entity
//-----------------------------------------------------------------------------

View File

@ -770,6 +770,10 @@ public:
// A method to apply a decal to an entity
virtual void AddDecal( const Vector& rayStart, const Vector& rayEnd,
const Vector& decalCenter, int hitbox, int decalIndex, bool doTrace, trace_t& tr, int maxLODToDecal = ADDDECAL_TO_ALL_LODS );
virtual void AddColoredDecal( const Vector& rayStart, const Vector& rayEnd,
const Vector& decalCenter, int hitbox, int decalIndex, bool doTrace, trace_t& tr, Color cColor, int maxLODToDecal = ADDDECAL_TO_ALL_LODS );
// A method to remove all decals from an entity
void RemoveAllDecals( void );
@ -1317,7 +1321,7 @@ public:
short m_nModelIndex;
#ifdef TF_CLIENT_DLL
int m_nModelIndexOverrides[MAX_MODEL_INDEX_OVERRIDES];
int m_nModelIndexOverrides[MAX_VISION_MODES];
#endif
char m_takedamage;
@ -1464,6 +1468,7 @@ private:
// methods related to decal adding
void AddStudioDecal( const Ray_t& ray, int hitbox, int decalIndex, bool doTrace, trace_t& tr, int maxLODToDecal = ADDDECAL_TO_ALL_LODS );
void AddColoredStudioDecal( const Ray_t& ray, int hitbox, int decalIndex, bool doTrace, trace_t& tr, Color cColor, int maxLODToDecal );
void AddBrushModelDecal( const Ray_t& ray, const Vector& decalCenter, int decalIndex, bool doTrace, trace_t& tr );
void ComputePackedOffsets( void );

View File

@ -2178,7 +2178,7 @@ void C_BasePlayer::PlayPlayerJingle()
if ( !filesystem->FileExists( fullsoundname ) )
{
char custname[ 512 ];
Q_snprintf( custname, sizeof( custname ), "downloads/%s.dat", soundhex );
Q_snprintf( custname, sizeof( custname ), "download/user_custom/%c%c/%s.dat", soundhex[0], soundhex[1], soundhex );
// it may have been downloaded but not copied under materials folder
if ( !filesystem->FileExists( custname ) )
return; // not downloaded yet

View File

@ -116,6 +116,7 @@
#include "rtime.h"
#include "tf_hud_disconnect_prompt.h"
#include "../engine/audio/public/sound.h"
#include "tf_shared_content_manager.h"
#endif
#include "clientsteamcontext.h"
#include "renamed_recvtable_compat.h"
@ -1018,6 +1019,7 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi
#if defined( TF_CLIENT_DLL )
IGameSystem::Add( CustomTextureToolCacheGameSystem() );
IGameSystem::Add( TFSharedContentManager() );
#endif
#if defined( TF_CLIENT_DLL )

View File

@ -44,14 +44,18 @@ $Configuration "Release"
$Configuration
{
$General
{
$OutputDirectory ".\$GAMENAME" [$OSXALL]
}
$Compiler
{
$AdditionalIncludeDirectories ".\;$BASE;$SRCDIR\vgui2\include;$SRCDIR\vgui2\controls;$SRCDIR\game\shared;.\game_controls;$SRCDIR\thirdparty\sixensesdk\include"
$PreprocessorDefinitions "$BASE;NO_STRING_T;CLIENT_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead"
$PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;fopen=dont_use_fopen" [$WIN32]
$PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;" [$OSXALL]
$PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;" [$LINUX]
$PreprocessorDefinitions "$BASE;USE_WEBM_FOR_REPLAY" [$LINUX]
$PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;USE_WEBM_FOR_REPLAY;" [$LINUXALL]
$PreprocessorDefinitions "$BASE;CURL_STATICLIB" [$WIN32 && $BUILD_REPLAY]
$Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)"
$Create/UsePCHThroughFile "cbase.h"
@ -1232,55 +1236,7 @@ $Project
$File "game_controls\IconPanel.h"
}
$Folder "Link Libraries" [$WIN32]
{
$DynamicFile "$SRCDIR\lib\public\bitmap.lib"
$DynamicFile "$SRCDIR\lib\public\choreoobjects.lib"
$DynamicFile "$SRCDIR\lib\public\dmxloader.lib"
$DynamicFile "$SRCDIR\lib\public\mathlib.lib"
$DynamicFile "$SRCDIR\lib\public\matsys_controls.lib"
$DynamicFile "$SRCDIR\lib\public\particles.lib"
$DynamicFile "$SRCDIR\lib\public\tier1.lib"
$DynamicFile "$SRCDIR\lib\public\tier2.lib"
$DynamicFile "$SRCDIR\lib\public\tier3.lib"
$DynamicFile "$SRCDIR\lib\public\vgui_controls.lib"
$DynamicFile "$SRCDIR\lib\public\steam_api.lib"
$DynamicFile "$SRCDIR\lib\public\vtf.lib"
$DynamicFile "$SRCDIR\lib\win32\release\libcurl.lib" [$BUILD_REPLAY]
}
$Folder "Link Libraries" [$X360]
{
$DynamicFile "$SRCDIR\lib\public\bitmap_360.lib"
$DynamicFile "$SRCDIR\lib\public\choreoobjects_360.lib"
$DynamicFile "$SRCDIR\lib\public\dmxloader_360.lib"
$DynamicFile "$SRCDIR\lib\public\mathlib_360.lib"
$DynamicFile "$SRCDIR\lib\public\matsys_controls_360.lib"
$DynamicFile "$SRCDIR\lib\public\particles_360.lib"
$DynamicFile "$SRCDIR\lib\public\tier1_360.lib"
$DynamicFile "$SRCDIR\lib\public\tier2_360.lib"
$DynamicFile "$SRCDIR\lib\public\tier3_360.lib"
$DynamicFile "$SRCDIR\lib\public\vgui_controls_360.lib"
}
$Folder "Link Libraries" [$POSIX && !$LINUX]
{
$DynamicFile "$SRCDIR\lib\$PLATFORM\libcurl$_IMPLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\bitmap$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\choreoobjects$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\dmxloader$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\mathlib$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\matsys_controls$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\particles$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\tier1$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\tier2$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\tier3$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\vgui_controls$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXsteam_api$_IMPLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\vtf$_STATICLIB_EXT"
}
$Folder "Link Libraries" [$LINUX]
$Folder "Link Libraries"
{
$Lib bitmap
$Lib choreoobjects
@ -1292,12 +1248,20 @@ $Project
$Lib tier2
$Lib tier3
$Lib vgui_controls
$Lib vtf
$DynamicFile "$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXsteam_api$_IMPLIB_EXT"
$DynamicFile "$SRCDIR/lib/linux32/libcurl$_STATICLIB_EXT" [$DEDICATED]
$DynamicFile "$SRCDIR/lib/linux32/libcurlssl$_STATICLIB_EXT" [!$DEDICATED]
$DynamicFile "$SRCDIR/lib/linux32/libssl$_STATICLIB_EXT" [!$DEDICATED]
$DynamicFile "$SRCDIR/lib/linux32/release/libcrypto$_STATICLIB_EXT" [!$DEDICATED]
$Lib vtf
$ImpLib steam_api
$Lib $LIBCOMMON/libcrypto [$POSIX]
$ImpLib "$LIBCOMMON\curl" [$OSXALL]
$Lib "$LIBCOMMON\libcurl" [$WIN32]
$Lib "libz" [$WIN32]
$Libexternal libz [$LINUXALL]
$Libexternal "$LIBCOMMON/libcurl" [$LINUXALL]
$Libexternal "$LIBCOMMON/libcurlssl" [$LINUXALL]
$Libexternal "$LIBCOMMON/libssl" [$LINUXALL]
}
}

View File

@ -10,9 +10,6 @@ $Macro GAMENAME "mod_hl2mp" [$SOURCESDK]
$Include "$SRCDIR\game\client\client_base.vpc"
$macro VSLIBDIR "." [!$VS2010]
$macro VSLIBDIR "VS2010" [$VS2010]
$Configuration
{
$Compiler
@ -174,16 +171,4 @@ $Project "Client (HL2MP)"
}
}
}
$Folder "Libraries"
{
$File "$SRCDIR\lib\$PLATFORM\release\$VSLIBDIR\libprotobuf.lib" [$WINDOWS]
{
$Configuration "Debug" { $ExcludedFromBuild "Yes" }
}
$File "$SRCDIR\lib\$PLATFORM\debug\$VSLIBDIR\libprotobuf.lib" [$WINDOWS]
{
$Configuration "Release" { $ExcludedFromBuild "Yes" }
}
$File "$SRCDIR\lib\$PLATFORM\release\libprotobuf.a" [$POSIX]
}
}

View File

@ -289,7 +289,7 @@ void CHudDeathNotice::FireGameEvent( KeyValues * event)
if ( !strcmp( killedwith+2, "gauss" ) )
Q_strncpy( killedwith, "d_tau cannon", sizeof( killedwith ) );
Msg( killedwith+2 ); // skip over the "d_" part
Msg( "%s", killedwith+2 ); // skip over the "d_" part
}
Msg( "\n" );

View File

@ -6,25 +6,10 @@
$MacroRequired "PLATFORM"
$macro VSLIBDIR "." [!$VS2010]
$macro VSLIBDIR "VS2010" [$VS2010]
$Project
{
$Folder "Libraries"
{
// Always use the release version of libprotobuf.lib because the debug
// version uses iterator debugging, which is incompatible with the rest of
// the Valve world.
$File "$SRCDIR\lib\$PLATFORM\release\$VSLIBDIR\libprotobuf.lib" [$WINDOWS && $VS2010]
$File "$SRCDIR\lib\$PLATFORM\release\$VSLIBDIR\libprotobuf.lib" [$WINDOWS && !$VS2010]
{
$Configuration "Debug" { $ExcludedFromBuild "Yes" }
}
$File "$SRCDIR\lib\$PLATFORM\debug\$VSLIBDIR\libprotobuf.lib" [$WINDOWS && !$VS2010]
{
$Configuration "Release" { $ExcludedFromBuild "Yes" }
}
$File "$SRCDIR\lib\$PLATFORM\release\libprotobuf.a" [$POSIX]
$Libexternal libprotobuf
}
}

View File

@ -3,7 +3,8 @@
// Purpose:
//
//=============================================================================//
#undef strncpy // we use std::string below that needs a good strncpy define
#undef sprintf // "
#include "cbase.h"
#include "ai_behavior_lead.h"

View File

@ -48,7 +48,7 @@ inline void DebugConnectMsg( int node1, int node2, const char *pszFormat, ... )
Q_vsnprintf( string, sizeof(string), pszFormat, argptr );
va_end( argptr );
DevMsg( string );
DevMsg( "%s", string );
}
}

View File

@ -347,7 +347,7 @@ int CAI_TacticalServices::FindCoverNode(const Vector &vNearPos, const Vector &vT
MARK_TASK_EXPENSIVE();
DebugFindCover( g_AIDebugFindCoverNode, GetOuter()->EyePosition(), vThreatEyePos, 0, 255, 255 );
DebugFindCover( NO_NODE, GetOuter()->EyePosition(), vThreatEyePos, 0, 255, 255 );
int iMyNode = GetPathfinder()->NearestNodeToPoint( vNearPos );

View File

@ -653,7 +653,7 @@ void CBaseEntity::SetModelIndex( int index )
void CBaseEntity::ClearModelIndexOverrides( void )
{
#ifdef TF_DLL
for ( int index = 0 ; index < MAX_MODEL_INDEX_OVERRIDES ; index++ )
for ( int index = 0 ; index < MAX_VISION_MODES ; index++ )
{
m_nModelIndexOverrides.Set( index, 0 );
}
@ -663,7 +663,7 @@ void CBaseEntity::ClearModelIndexOverrides( void )
void CBaseEntity::SetModelIndexOverride( int index, int nValue )
{
#ifdef TF_DLL
if ( ( index >= MODEL_INDEX_OVERRIDE_DEFAULT ) && ( index < MAX_MODEL_INDEX_OVERRIDES ) )
if ( ( index >= VISION_MODE_NONE ) && ( index < MAX_VISION_MODES ) )
{
if ( nValue != m_nModelIndexOverrides[index] )
{
@ -1950,7 +1950,7 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity )
// DEFINE_FIELD( m_fDataObjectTypes, FIELD_INTEGER ),
#ifdef TF_DLL
DEFINE_ARRAY( m_nModelIndexOverrides, FIELD_INTEGER, MAX_MODEL_INDEX_OVERRIDES ),
DEFINE_ARRAY( m_nModelIndexOverrides, FIELD_INTEGER, MAX_VISION_MODES ),
#endif
END_DATADESC()
@ -7302,6 +7302,30 @@ void CC_Ent_Create( const CCommand& args )
{
MDLCACHE_CRITICAL_SECTION();
CBasePlayer *pPlayer = UTIL_GetCommandClient();
if (!pPlayer)
{
return;
}
// Don't allow regular users to create point_servercommand entities for the same reason as blocking ent_fire
if ( !Q_stricmp( args[1], "point_servercommand" ) )
{
if ( engine->IsDedicatedServer() )
{
// We allow people with disabled autokick to do it, because they already have rcon.
if ( pPlayer->IsAutoKickDisabled() == false )
return;
}
else if ( gpGlobals->maxClients > 1 )
{
// On listen servers with more than 1 player, only allow the host to create point_servercommand.
CBasePlayer *pHostPlayer = UTIL_GetListenServerHost();
if ( pPlayer != pHostPlayer )
return;
}
}
bool allowPrecache = CBaseEntity::IsPrecacheAllowed();
CBaseEntity::SetAllowPrecache( true );
@ -7322,7 +7346,6 @@ void CC_Ent_Create( const CCommand& args )
DispatchSpawn(entity);
// Now attempt to drop into the world
CBasePlayer* pPlayer = UTIL_GetCommandClient();
trace_t tr;
Vector forward;
pPlayer->EyeVectors( &forward );

View File

@ -792,7 +792,7 @@ public:
CNetworkVar( short, m_nModelIndex );
#ifdef TF_DLL
CNetworkArray( int, m_nModelIndexOverrides, MAX_MODEL_INDEX_OVERRIDES ); // used to override the base model index on the client if necessary
CNetworkArray( int, m_nModelIndexOverrides, MAX_VISION_MODES ); // used to override the base model index on the client if necessary
#endif
// was pev->rendercolor

View File

@ -798,6 +798,24 @@ CON_COMMAND( give, "Give item to player.\n\tArguments: <item_name>" )
Q_strncpy( item_to_give, args[1], sizeof( item_to_give ) );
Q_strlower( item_to_give );
// Don't allow regular users to create point_servercommand entities for the same reason as blocking ent_fire
if ( !Q_stricmp( item_to_give, "point_servercommand" ) )
{
if ( engine->IsDedicatedServer() )
{
// We allow people with disabled autokick to do it, because they already have rcon.
if ( pPlayer->IsAutoKickDisabled() == false )
return;
}
else if ( gpGlobals->maxClients > 1 )
{
// On listen servers with more than 1 player, only allow the host to create point_servercommand.
CBasePlayer *pHostPlayer = UTIL_GetListenServerHost();
if ( pPlayer != pHostPlayer )
return;
}
}
// Dirty hack to avoid suit playing it's pickup sound
if ( !Q_stricmp( item_to_give, "item_suit" ) )
{

View File

@ -340,12 +340,11 @@ void CBaseDoor::Spawn()
#ifdef TF_DLL
if ( TFGameRules() && TFGameRules()->IsMultiplayer() )
{
if ( !m_flBlockDamage )
{
// Never block doors in TF2 - to prevent various exploits.
m_flBlockDamage = 10.f;
}
// Never block doors in TF2 - to prevent various exploits.
m_bIgnoreNonPlayerEntsOnBlock = true;
}
#else
m_bIgnoreNonPlayerEntsOnBlock = false;
#endif // TF_DLL
}
@ -1207,6 +1206,11 @@ void CBaseDoor::Blocked( CBaseEntity *pOther )
pOther->TakeDamage( CTakeDamageInfo( this, this, m_flBlockDamage, DMG_CRUSH ) );
}
}
// If set, ignore non-player ents that block us. Mainly of use in multiplayer to prevent exploits.
else if ( pOther && !pOther->IsPlayer() && m_bIgnoreNonPlayerEntsOnBlock )
{
return;
}
// If we're set to force ourselves closed, keep going
if ( m_bForceClosed )

View File

@ -114,6 +114,7 @@ public:
bool m_bDoorGroup;
bool m_bLocked; // Whether the door is locked
bool m_bIgnoreDebris;
bool m_bIgnoreNonPlayerEntsOnBlock; // Non-player entities should never block. This variable needs more letters.
FuncDoorSpawnPos_t m_eSpawnPosition;

View File

@ -2199,7 +2199,7 @@ void CNPC_Hunter::PrescheduleThink()
if ( m_flPupilDilateTime < gpGlobals->curtime )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
if ( pPlayer && !pPlayer->IsIlluminatedByFlashlight( this, NULL ) || !PlayerFlashlightOnMyEyes( pPlayer ) )
if ( ( pPlayer && !pPlayer->IsIlluminatedByFlashlight( this, NULL ) ) || !PlayerFlashlightOnMyEyes( pPlayer ) )
{
//Msg( "NOT SHINING FLASHLIGHT ON ME\n" );
@ -6347,13 +6347,13 @@ void CNPC_Hunter::FootFX( const Vector &origin )
CBaseEntity *CNPC_Hunter::GetEnemyVehicle()
{
if ( GetEnemy() == NULL )
return false;
return NULL;
CBaseCombatCharacter *pCCEnemy = GetEnemy()->MyCombatCharacterPointer();
if ( pCCEnemy != NULL )
return pCCEnemy->GetVehicleEntity();
return false;
return NULL;
}

View File

@ -1810,7 +1810,10 @@ void CNPC_Barnacle::SwallowPrey( void )
#if HL2_EPISODIC
// digest poisonous things for just a moment before being killed by them (it looks wierd if it's instant)
m_flDigestFinish = gpGlobals->curtime + m_bSwallowingPoison ? 0.48f : 10.0f;
// Parentheses were probably intended around the ?: part of the expression, but putting them there now
// would change the behavior which is undesirable, so parentheses were placed around the '+' to suppress
// compiler warnings.
m_flDigestFinish = ( gpGlobals->curtime + m_bSwallowingPoison ) ? 0.48f : 10.0f;
#else
m_flDigestFinish = gpGlobals->curtime + 10.0;
#endif

View File

@ -571,7 +571,7 @@ void CNPC_Zombine::HandleAnimEvent( animevent_t *pEvent )
{
pNPC = ppAIs[i];
if( pNPC->Classify() == CLASS_PLAYER_ALLY || pNPC->Classify() == CLASS_PLAYER_ALLY_VITAL && pNPC->FVisible(this) )
if( pNPC->Classify() == CLASS_PLAYER_ALLY || ( pNPC->Classify() == CLASS_PLAYER_ALLY_VITAL && pNPC->FVisible(this) ) )
{
int priority;
Disposition_t disposition;

View File

@ -358,7 +358,7 @@ public:
bool IsHLTV( void ) const { return pl.hltv; }
bool IsReplay( void ) const { return pl.replay; }
virtual bool IsPlayer( void ) const { return true; } // Spectators return TRUE for this, use IsObserver to seperate cases
virtual bool IsPlayer( void ) const { return true; } // Spectators return TRUE for this, use IsObserver to separate cases
virtual bool IsNetClient( void ) const { return true; } // Bots should return FALSE for this, they can't receive NET messages
// Spectators should return TRUE for this
@ -1500,6 +1500,44 @@ int CollectPlayers( CUtlVector< T * > *playerVector, int team = TEAM_ANY, bool i
return playerVector->Count();
}
template < typename T >
int CollectHumanPlayers( CUtlVector< T * > *playerVector, int team = TEAM_ANY, bool isAlive = false, bool shouldAppend = false )
{
if ( !shouldAppend )
{
playerVector->RemoveAll();
}
for( int i=1; i<=gpGlobals->maxClients; ++i )
{
CBasePlayer *player = UTIL_PlayerByIndex( i );
if ( player == NULL )
continue;
if ( FNullEnt( player->edict() ) )
continue;
if ( !player->IsPlayer() )
continue;
if ( player->IsBot() )
continue;
if ( !player->IsConnected() )
continue;
if ( team != TEAM_ANY && player->GetTeamNumber() != team )
continue;
if ( isAlive && !player->IsAlive() )
continue;
playerVector->AddToTail( assert_cast< T * >( player ) );
}
return playerVector->Count();
}
enum
{

View File

@ -1937,6 +1937,18 @@ void CDynamicProp::Spawn( )
}
//m_debugOverlays |= OVERLAY_ABSBOX_BIT;
#ifdef TF_DLL
const char *pszModelName = modelinfo->GetModelName( GetModel() );
if ( pszModelName && pszModelName[0] )
{
if ( FStrEq( pszModelName, "models/bots/boss_bot/carrier_parts.mdl" ) )
{
SetModelIndexOverride( VISION_MODE_NONE, modelinfo->GetModelIndex( pszModelName ) );
SetModelIndexOverride( VISION_MODE_ROME, modelinfo->GetModelIndex( "models/bots/tw2/boss_bot/twcarrier_addon.mdl" ) );
}
}
#endif
}
//-----------------------------------------------------------------------------

View File

@ -44,6 +44,11 @@ $Configuration "Release"
$Configuration
{
$General
{
$OutputDirectory ".\$GAMENAME" [$OSXALL]
}
$Compiler
{
$AdditionalIncludeDirectories "$BASE;.\;$SRCDIR\game\shared;$SRCDIR\utils\common;$SRCDIR\game\shared\econ;$SRCDIR\game\server\NextBot"
@ -998,40 +1003,7 @@ $Project
$File "toolframework_server.h"
}
$Folder "Link Libraries" [$WIN32]
{
$DynamicFile "$SRCDIR\lib\public\choreoobjects.lib"
$DynamicFile "$SRCDIR\lib\public\dmxloader.lib"
$DynamicFile "$SRCDIR\lib\public\mathlib.lib"
$DynamicFile "$SRCDIR\lib\public\particles.lib"
$DynamicFile "$SRCDIR\lib\public\tier2.lib"
$DynamicFile "$SRCDIR\lib\public\tier3.lib"
$DynamicFile "$SRCDIR\lib\public\steam_api.lib"
}
$Folder "Link Libraries" [$X360]
{
$DynamicFile "$SRCDIR\lib\public\choreoobjects_360.lib"
$DynamicFile "$SRCDIR\lib\public\dmxloader_360.lib"
$DynamicFile "$SRCDIR\lib\public\mathlib_360.lib"
$DynamicFile "$SRCDIR\lib\public\particles_360.lib"
$DynamicFile "$SRCDIR\lib\public\tier2_360.lib"
$DynamicFile "$SRCDIR\lib\public\tier3_360.lib"
}
$Folder "Link Libraries" [$POSIX && !$LINUX]
{
$DynamicFile "$SRCDIR\lib\$PLATFORM\choreoobjects$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\dmxloader$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\mathlib$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\particles$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\tier2$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\tier3$_STATICLIB_EXT"
$DynamicFile "$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXsteam_api$_IMPLIB_EXT"
}
$Folder "Link Libraries" [$LINUX]
$Folder "Link Libraries"
{
$Lib choreoobjects
$Lib dmxloader
@ -1039,6 +1011,6 @@ $Project
$Lib particles
$Lib tier2
$Lib tier3
$DynamicFile "$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXsteam_api$_EXTERNAL_IMPLIB_EXT"
$ImpLibexternal steam_api
}
}

View File

@ -16,6 +16,14 @@
void Test_CreateEntity( const CCommand &args )
{
CBasePlayer *pPlayer = UTIL_GetCommandClient();
// Require a player entity or that the command was entered from the dedicated server console
if ( !pPlayer && UTIL_GetCommandClientIndex() > 0 )
{
return;
}
if ( args.ArgC() < 2 )
{
Error( "Test_CreateEntity: requires entity classname argument." );
@ -23,6 +31,24 @@ void Test_CreateEntity( const CCommand &args )
const char *pClassName = args[ 1 ];
// Don't allow regular users to create point_servercommand entities for the same reason as blocking ent_fire
if ( pPlayer && !Q_stricmp( pClassName, "point_servercommand" ) )
{
if ( engine->IsDedicatedServer() )
{
// We allow people with disabled autokick to do it, because they already have rcon.
if ( pPlayer->IsAutoKickDisabled() == false )
return;
}
else if ( gpGlobals->maxClients > 1 )
{
// On listen servers with more than 1 player, only allow the host to create point_servercommand.
CBasePlayer *pHostPlayer = UTIL_GetListenServerHost();
if ( pPlayer != pHostPlayer )
return;
}
}
if ( !CreateEntityByName( pClassName ) )
{
Error( "Test_CreateEntity( %s ) failed.", pClassName );

View File

@ -1892,7 +1892,8 @@ int DispatchSpawn( CBaseEntity *pEntity )
// Don't allow the PVS check to skip animation setup during spawning
pAnimating->SetBoneCacheFlags( BCF_IS_IN_SPAWN );
pEntity->Spawn();
pAnimating->ClearBoneCacheFlags( BCF_IS_IN_SPAWN );
if ( pEntSafe != NULL )
pAnimating->ClearBoneCacheFlags( BCF_IS_IN_SPAWN );
}
mdlcache->SetAsyncLoad( MDLCACHE_ANIMBLOCK, bAsyncAnims );

View File

@ -3,10 +3,8 @@
// Purpose:
//
//=============================================================================
#include "cbase.h"
#include "igamesystem.h"
#include "gamestats.h"
#include "tier1/utlstring.h"

View File

@ -77,10 +77,10 @@ struct fogplayerparams_t
{
m_hCtrl.Set( NULL );
m_flTransitionTime = -1.0f;
m_OldColor.r = m_OldColor.g = m_OldColor.g = m_OldColor.a = 0.0f;
m_OldColor.r = m_OldColor.g = m_OldColor.b = m_OldColor.a = 0;
m_flOldStart = 0.0f;
m_flOldEnd = 0.0f;
m_NewColor.r = m_NewColor.g = m_NewColor.g = m_NewColor.a = 0.0f;
m_NewColor.r = m_NewColor.g = m_NewColor.b = m_NewColor.a = 0;
m_flNewStart = 0.0f;
m_flNewEnd = 0.0f;
}

View File

@ -919,14 +919,17 @@ enum
#define TF_VISION_FILTER_NONE 0
#define TF_VISION_FILTER_PYRO (1<<0) // 1
#define TF_VISION_FILTER_HALLOWEEN (1<<1) // 2
#define TF_VISION_FILTER_ROME (1<<2) // 4
// THIS ENUM SHOULD MATCH THE ORDER OF THE FLAGS ABOVE
enum
{
MODEL_INDEX_OVERRIDE_DEFAULT = 0,
MODEL_INDEX_OVERRIDE_PYRO,
MODEL_INDEX_OVERRIDE_HALLOWEEN,
VISION_MODE_NONE = 0,
VISION_MODE_PYRO,
VISION_MODE_HALLOWEEN,
VISION_MODE_ROME,
MAX_MODEL_INDEX_OVERRIDES
MAX_VISION_MODES
};
#endif // TF_DLL || TF_CLIENT_DLL

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.

BIN
mp/src/lib/public/libz.lib Normal file

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.

Some files were not shown because too many files have changed in this diff Show More