Mapbase v3.0

- Overhauled matcher system and added expanded wildcard support, meaning "text", "te?t", "blah_test", etc. are now supported instead of only trailing *
- Added support for regular expression matching
- Added the missing matrixinvert.h file, which prevented programmers from compiling vbsp
- Fixed env_global_light brightness
- Added info_player_view_proxy, an entity which mimics a player's view (created for script_intro)
- New UnZoomWithRate and SetZoomRate inputs on env_zoom
- New "Don't change target's angles" flag on logic_measure_movement
- Fixed logic_measure_movement not using ignore origin flags correctly
- Fixed filter_damage_mod secondary filter not recognizing mode correctly
- Fixed DisableGeigerCounter causing NPCs to ignore player, and possibly fixed other adverse effects in similar code
- Added SetEntityName input for setting an entity's targetname
- Added "SetTarget" support to point_posecontroller
- Added "sk_alyx_health" convar for adjustable npc_alyx health, restored/fixed "sk_barney_health" for adjustable npc_barney health
- Added ignore flags and several direction-related inputs to math_vector
- Added pose parameter stuff to logic_modelinfo
- Fixed ChangeWeapon not changing during combat
- Fixed holster/unholster on NPCs without holster/unholster animations
- Fixed func_tank and other "player in the way" code ignoring notarget
- Added SetPoseParameter input to animating entities
- Introduced an experimental chapter system which allows for custom chapter title/restriction management
- Added SetChapterTitle input to worldspawn for dynamic title changing
- Fixed func_tankairboatgun damage credit, added ability to use its damage keyvalues
- Fixed mapbase_rpc_enabled not actually affecting RPC
- Moved some newly found Combine soldier grenade code to ai_grenade for other grenade users
- Fixed some problems with the new shared activities
- Restored an old Mapbase entity as "prop_interactable", an entity which contains all of the functionality of a func_button/func_door in a prop entity
- Added env_microphone pitch scale for scaling the pitch of transmitted sounds
- Added experimental, long-overdue code for scenes to be able to access !target#'s and other scene-related names through AI_INPUT
- Added "mat_specular_disable_on_missing", which "disables" specular reflections when the cubemap texture is missing
- Fixed $envmapmasktransform and $bumptransform on VertexLitGeneric and related shaders
- Areaportal leaks now stop compilation in leaktest
- Replaced "-nodefaultcubemap" with "-defaultcubemap" as the shader changes allow maps to compile without default cubemaps by default with little effect
This commit is contained in:
Blixibon
2020-02-05 19:08:49 +00:00
parent b8611071c5
commit c5f3fa0778
63 changed files with 1909 additions and 335 deletions

View File

@@ -301,6 +301,10 @@ static void HandleDiscordJoinRequest(const DiscordUser* request)
void MapbaseRPC_Init()
{
// Only init if RPC is enabled
if (mapbase_rpc_enabled.GetInt() <= 0)
return;
// First, load the config
// (we need its values immediately)
KeyValues *pKV = new KeyValues( "MapbaseRPC" );
@@ -463,15 +467,20 @@ void MapbaseRPC_GetDiscordMapInfo( char *pDetails, size_t iSize, const char *pMa
}
else
{
// Show the chapter title first
const char *szChapterTitle = NULL;
C_World *pWorld = GetClientWorldEntity();
if ( pWorld && pWorld->m_iszChapterTitle[0] != '\0' )
{
// Show the chapter title first
const char *pChapterTitle = g_pVGuiLocalize->FindAsUTF8( pWorld->m_iszChapterTitle );
if (!pChapterTitle || pChapterTitle[0] == '\0')
pChapterTitle = pWorld->m_iszChapterTitle;
szChapterTitle = g_pVGuiLocalize->FindAsUTF8( pWorld->m_iszChapterTitle );
if (!szChapterTitle || szChapterTitle[0] == '\0')
szChapterTitle = pWorld->m_iszChapterTitle;
}
Q_snprintf( pDetails, iSize, "%s (%s)", pChapterTitle, pMapName );
if (szChapterTitle)
{
Q_snprintf( pDetails, iSize, "%s (%s)", szChapterTitle, pMapName );
}
else
{

View File

@@ -24,6 +24,7 @@
#include "soundscape_system.h"
#include "AI_ResponseSystem.h"
#include "mapbase/SystemConvarMod.h"
#include "gameinterface.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
@@ -170,7 +171,11 @@ public:
if (!gameinfo->GetBool("hide_mod_name", false))
{
// Store the game's name
Q_strncpy(g_iszGameName, gameinfo->GetString("game"), sizeof(g_iszGameName));
const char *pszGameName = gameinfo->GetString("game_rpc", NULL);
if (pszGameName == NULL)
pszGameName = gameinfo->GetString("game");
Q_strncpy(g_iszGameName, pszGameName, sizeof(g_iszGameName));
}
}
gameinfo->deleteThis();
@@ -370,6 +375,51 @@ BEGIN_DATADESC_NO_BASE( CMapbaseSystem )
END_DATADESC()
#ifdef GAME_DLL
static CUtlVector<MODTITLECOMMENT> g_MapbaseChapterMaps;
static CUtlVector<MODCHAPTER> g_MapbaseChapterList;
CUtlVector<MODTITLECOMMENT> *Mapbase_GetChapterMaps()
{
if (g_MapbaseChapterMaps.Count() == 0)
{
// Check the chapter list
KeyValues *chapterlist = new KeyValues("ChapterList");
if (chapterlist->LoadFromFile(filesystem, "scripts/chapters.txt", "MOD"))
{
KeyValues *pKey = chapterlist->GetFirstSubKey();
if (pKey)
{
if (Q_stricmp( pKey->GetName(), "Chapters" ) == 0)
{
for (KeyValues *pChapters = pKey->GetFirstSubKey(); pChapters; pChapters = pChapters->GetNextKey())
{
int index = g_MapbaseChapterList.AddToTail();
g_MapbaseChapterList[index].iChapter = atoi(pChapters->GetName());
Q_strncpy(g_MapbaseChapterList[index].pChapterName, pChapters->GetString(), sizeof(g_MapbaseChapterList[index]));
}
}
for (pKey = pKey->GetNextKey(); pKey; pKey = pKey->GetNextKey())
{
int index = g_MapbaseChapterMaps.AddToTail();
Q_strncpy(g_MapbaseChapterMaps[index].pBSPName, pKey->GetName(), sizeof(g_MapbaseChapterMaps[index].pBSPName));
Q_strncpy(g_MapbaseChapterMaps[index].pTitleName, pKey->GetString(), sizeof(g_MapbaseChapterMaps[index].pTitleName));
//comment.pBSPName = pKey->GetName();
//comment.pTitleName = pKey->GetString();
}
}
}
chapterlist->deleteThis();
}
return &g_MapbaseChapterMaps;
}
CUtlVector<MODCHAPTER> *Mapbase_GetChapterList()
{
return &g_MapbaseChapterList;
}
ThreeState_t Flashlight_GetLegacyVersionKey()
{
KeyValues *gameinfo = new KeyValues( "GameInfo" );

View File

@@ -0,0 +1,234 @@
//========= Copyright Valve Corporation, All rights reserved. =================
//
// Purpose: General matching functions for things like wildcards and !=.
//
// $NoKeywords: $
//=============================================================================
#include "cbase.h"
#include "matchers.h"
#include "fmtstr.h"
#include <regex>
ConVar mapbase_wildcards_enabled("mapbase_wildcards_enabled", "1", FCVAR_NONE, "Toggles Mapbase's '?' wildcard and true '*' features. Useful for maps that have '?' in their targetnames.");
ConVar mapbase_regex_enabled("mapbase_regex_enabled", "1", FCVAR_NONE, "Toggles Mapbase's regex matching handover.");
#ifdef CLIENT_DLL
// FIXME: There is no clientside equivalent to the RS code
bool ResponseSystemCompare(const char *criterion, const char *value) { return Matcher_NamesMatch(criterion, value); }
#else
extern bool ResponseSystemCompare(const char *criterion, const char *value);
#endif
//=============================================================================
// These are the "matchers" that compare with wildcards ("any*" for text starting with "any")
// and operators (<3 for numbers less than 3).
//
// Matcher_Match - Matching function using RS operators and NamesMatch wildcards/regex.
// Matcher_Regex - Uses regex functions from the std library.
// Matcher_NamesMatch - Based on Valve's original NamesMatch function, using wildcards and regex.
//
// AppearsToBeANumber - Response System-based function which checks if the string might be a number.
//=============================================================================
inline bool Matcher_Match(const char *pszQuery, const char *szValue)
{
// I wasn't kidding when I said all this did was hijack response system matching.
return ResponseSystemCompare(pszQuery, szValue);
}
inline bool Matcher_Match(const char *pszQuery, int iValue) { return Matcher_Match(pszQuery, CNumStr(iValue)); }
inline bool Matcher_Match(const char *pszQuery, float flValue) { return Matcher_Match(pszQuery, CNumStr(flValue)); }
// -------------------------------------------------------------------------------
// -------------------------------------------------------------------------------
// The recursive part of Mapbase's modified version of Valve's NamesMatch().
// This part is no longer inlined since it's recursive.
/*FORCEINLINE*/ bool Matcher_RunCharCompare(const char *pszQuery, const char *szValue)
{
// This matching model is based off of the ASW SDK
while ( *szValue && *pszQuery )
{
char cName = *szValue;
char cQuery = *pszQuery;
if ( cName != cQuery && tolower(cName) != tolower(cQuery) ) // people almost always use lowercase, so assume that first
{
// Now we'll try the new and improved Mapbase wildcards!
switch (*pszQuery)
{
case '*':
{
// Return true at classic trailing *
if ( *(pszQuery+1) == 0 )
return true;
if (mapbase_wildcards_enabled.GetBool())
{
// There's text after this * which we need to test.
// This recursion allows for multiple wildcards
int vlen = Q_strlen(szValue);
++pszQuery;
for (int i = 0; i < vlen; i++)
{
if (Matcher_RunCharCompare(pszQuery, szValue + i))
return true;
}
}
return false;
} break;
case '?':
// Just skip if we're capable of lazy wildcards
if (mapbase_wildcards_enabled.GetBool())
break;
default:
return false;
}
}
++szValue;
++pszQuery;
}
// Include a classic trailing * check for when szValue is something like "value" and pszQuery is "value*"
return ( ( *pszQuery == 0 && *szValue == 0 ) || *pszQuery == '*' );
}
// Regular expressions based off of the std library.
// The C++ is strong in this one.
bool Matcher_Regex(const char *pszQuery, const char *szValue)
{
std::regex regex;
// Since I can't find any other way to check for valid regex,
// use a try-catch here to see if it throws an exception.
try { regex = std::regex(pszQuery); }
catch (std::regex_error &e)
{
Msg("Invalid regex \"%s\" (%s)\n", pszQuery, e.what());
return false;
}
std::match_results<const char*> results;
bool bMatch = std::regex_match( szValue, results, regex );
if (!bMatch)
return false;
// Only match the *whole* string
return Q_strlen(results.str(0).c_str()) == Q_strlen(szValue);
}
// The entry point for Mapbase's modified version of Valve's NamesMatch().
FORCEINLINE bool Matcher_NamesMatch(const char *pszQuery, const char *szValue)
{
if ( szValue == NULL )
return (*pszQuery == 0 || *pszQuery == '*');
// If the pointers are identical, we're identical
if ( szValue == pszQuery )
return true;
// Check for regex
if ( *pszQuery == '@' && mapbase_regex_enabled.GetBool() )
{
// Make sure it has a forward slash
// (prevents confusion with instance fixup escape)
if (*(pszQuery+1) == '/')
{
return Matcher_Regex( pszQuery+2, szValue );
}
}
return Matcher_RunCharCompare( pszQuery, szValue );
}
FORCEINLINE bool Matcher_NamesMatch_Classic(const char *pszQuery, const char *szValue)
{
if ( szValue == NULL )
return (!pszQuery || *pszQuery == 0 || *pszQuery == '*');
// If the pointers are identical, we're identical
if ( szValue == pszQuery )
return true;
while ( *szValue && *pszQuery )
{
unsigned char cName = *szValue;
unsigned char cQuery = *pszQuery;
// simple ascii case conversion
if ( cName == cQuery )
;
else if ( cName - 'A' <= (unsigned char)'Z' - 'A' && cName - 'A' + 'a' == cQuery )
;
else if ( cName - 'a' <= (unsigned char)'z' - 'a' && cName - 'a' + 'A' == cQuery )
;
else
break;
++szValue;
++pszQuery;
}
if ( *pszQuery == 0 && *szValue == 0 )
return true;
// @TODO (toml 03-18-03): Perhaps support real wildcards. Right now, only thing supported is trailing *
if ( *pszQuery == '*' )
return true;
return false;
}
FORCEINLINE bool Matcher_NamesMatch_MutualWildcard(const char *pszQuery, const char *szValue)
{
if ( szValue == NULL )
return (!pszQuery || *pszQuery == 0 || *pszQuery == '*');
if ( pszQuery == NULL )
return (!szValue || *szValue == 0 || *szValue == '*');
// If the pointers are identical, we're identical
if ( szValue == pszQuery )
return true;
while ( *szValue && *pszQuery )
{
unsigned char cName = *szValue;
unsigned char cQuery = *pszQuery;
// simple ascii case conversion
if ( cName == cQuery )
;
else if ( cName - 'A' <= (unsigned char)'Z' - 'A' && cName - 'A' + 'a' == cQuery )
;
else if ( cName - 'a' <= (unsigned char)'z' - 'a' && cName - 'a' + 'A' == cQuery )
;
else
break;
++szValue;
++pszQuery;
}
if ( *pszQuery == 0 && *szValue == 0 )
return true;
// @TODO (toml 03-18-03): Perhaps support real wildcards. Right now, only thing supported is trailing *
if ( *pszQuery == '*' || *szValue == '*' )
return true;
return false;
}
// Matcher_Compare is a deprecated alias originally used when Matcher_Match didn't support wildcards.
/*
inline bool Matcher_Compare(const char *pszQuery, const char *szValue)
{
return Matcher_Match(pszQuery, szValue);
#if 0
// I have to do this so wildcards could test *before* the response system comparison.
// I know it removes the operators twice, but I won't worry about it.
bool match = Matcher_NamesMatch(Matcher_RemoveOperators(pszQuery), szValue);
if (match)
return Matcher_Match(pszQuery, szValue);
return false;
#endif
}
*/

View File

@@ -0,0 +1,59 @@
//========= Copyright Valve Corporation, All rights reserved. =================
//
// Purpose: General matching functions for things like wildcards and !=.
//
// $NoKeywords: $
//=============================================================================
#define MAPBASE_MATCHERS 1
// Compares with != and the like. Basically hijacks the response system matching.
// This also loops back around to Matcher_NamesMatch.
// pszQuery = The value that should have the operator(s) at the beginning.
// szValue = The value tested against the criterion.
extern bool Matcher_Match( const char *pszQuery, const char *szValue );
extern bool Matcher_Match( const char *pszQuery, int iValue );
extern bool Matcher_Match( const char *pszQuery, float flValue );
// Regular expressions based off of the std library.
// pszQuery = The regex text.
// szValue = The value that should be matched.
extern bool Matcher_Regex( const char *pszQuery, const char *szValue );
// Compares two strings with support for wildcards or regex. This code is an expanded version of baseentity.cpp's NamesMatch().
// pszQuery = The value that should have the wildcard.
// szValue = The value tested against the query.
// Use Matcher_Match if you want <, !=, etc. as well.
extern bool Matcher_NamesMatch( const char *pszQuery, const char *szValue );
// Identical to baseentity.cpp's original NamesMatch().
// pszQuery = The value that should have the wildcard.
// szValue = The value tested against the query.
extern bool Matcher_NamesMatch_Classic( const char *pszQuery, const char *szValue );
// Identical to Matcher_NamesMatch_Classic(), but either value could use a wildcard.
// pszQuery = The value that serves as the query. This value can use wildcards.
// szValue = The value tested against the query. This value can use wildcards as well.
extern bool Matcher_NamesMatch_MutualWildcard( const char *pszQuery, const char *szValue );
// Deprecated; do not use
inline bool Matcher_Compare( const char *pszQuery, const char *szValue ) { return Matcher_Match( pszQuery, szValue ); }
// Taken from the Response System.
// Checks if the specified string appears to be a number of some sort.
static bool AppearsToBeANumber( char const *token )
{
if ( atof( token ) != 0.0f )
return true;
char const *p = token;
while ( *p )
{
if ( *p != '0' )
return false;
p++;
}
return true;
}