Added support for "fuzzy" map names in L4D and later (bug 5599, r=asherkin).
authorNicholas Hastings <skamonkey@gmail.com>
Thu Feb 14 19:28:12 2013 -0500 (2013-02-14)
changeset 378942e367aa4a00
parent 3788 a05d763d049f
child 3790 98b099a406d2
Added support for "fuzzy" map names in L4D and later (bug 5599, r=asherkin).
core/HalfLife2.cpp
core/HalfLife2.h
core/NextMap.cpp
core/logic/smn_maplists.cpp
core/smn_halflife.cpp
public/IGameHelpers.h
     1.1 --- a/core/HalfLife2.cpp	Wed Feb 13 22:25:15 2013 -0500
     1.2 +++ b/core/HalfLife2.cpp	Thu Feb 14 19:28:12 2013 -0500
     1.3 @@ -1131,3 +1131,44 @@
     1.4  
     1.5  	return *(const char **)(((unsigned char *)pEntity) + offset);
     1.6  }
     1.7 +
     1.8 +#if SOURCE_ENGINE >= SE_LEFT4DEAD
     1.9 +static bool ResolveFuzzyMapName(const char *fuzzyName, char *outFullname, int size)
    1.10 +{
    1.11 +	static ConCommand *pHelperCmd = g_pCVar->FindCommand("changelevel");
    1.12 +	if (!pHelperCmd || !pHelperCmd->CanAutoComplete())
    1.13 +		return false;
    1.14 +
    1.15 +	static size_t helperCmdLen = strlen(pHelperCmd->GetName());
    1.16 +
    1.17 +	CUtlVector<CUtlString> results;
    1.18 +	pHelperCmd->AutoCompleteSuggest(fuzzyName, results);
    1.19 +	if (results.Count() == 0)
    1.20 +		return false;
    1.21 +
    1.22 +	// Results come back as you'd see in autocomplete. (ie. "changelevel fullmapnamehere"),
    1.23 +	// so skip ahead to start of map path/name
    1.24 +
    1.25 +	// Like the engine, we're only going to deal with the first match.
    1.26 +
    1.27 +	strncopy(outFullname, &results[0][helperCmdLen + 1], size);
    1.28 +
    1.29 +	return true;
    1.30 +}
    1.31 +#endif
    1.32 +
    1.33 +bool CHalfLife2::IsMapValid(const char *map)
    1.34 +{
    1.35 +	bool ret = engine->IsMapValid(map);
    1.36 +#if SOURCE_ENGINE >= SE_LEFT4DEAD
    1.37 +	if (!ret)
    1.38 +	{
    1.39 +		static char szFuzzyName[PLATFORM_MAX_PATH];
    1.40 +		if (ResolveFuzzyMapName(map, szFuzzyName, sizeof(szFuzzyName)))
    1.41 +		{
    1.42 +			ret = engine->IsMapValid(szFuzzyName);
    1.43 +		}
    1.44 +	}
    1.45 +#endif
    1.46 +	return ret;
    1.47 +}
     2.1 --- a/core/HalfLife2.h	Wed Feb 13 22:25:15 2013 -0500
     2.2 +++ b/core/HalfLife2.h	Thu Feb 14 19:28:12 2013 -0500
     2.3 @@ -148,6 +148,7 @@
     2.4  	ICommandLine *GetValveCommandLine();
     2.5  	const char *GetEntityClassname(edict_t *pEdict);
     2.6  	const char *GetEntityClassname(CBaseEntity *pEntity);
     2.7 +	bool IsMapValid(const char *map);
     2.8  public:
     2.9  	void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
    2.10  	void ProcessFakeCliCmdQueue();
     3.1 --- a/core/NextMap.cpp	Wed Feb 13 22:25:15 2013 -0500
     3.2 +++ b/core/NextMap.cpp	Thu Feb 14 19:28:12 2013 -0500
     3.3 @@ -31,6 +31,7 @@
     3.4  
     3.5  #include "NextMap.h"
     3.6  #include "Logger.h"
     3.7 +#include "HalfLife2.h"
     3.8  #include "sourcemm_api.h"
     3.9  #include "sm_stringutil.h"
    3.10  #include "sourcehook.h"
    3.11 @@ -109,7 +110,7 @@
    3.12  
    3.13  bool NextMapManager::SetNextMap(const char *map)
    3.14  {
    3.15 -	if (!engine->IsMapValid(map))
    3.16 +	if (!g_HL2.IsMapValid(map))
    3.17  	{
    3.18  		return false;
    3.19  	}
    3.20 @@ -133,7 +134,7 @@
    3.21  
    3.22  	const char *newmap = sm_nextmap.GetString();
    3.23  
    3.24 -	if (newmap[0] == 0 || !engine->IsMapValid(newmap))
    3.25 +	if (newmap[0] == 0 || !g_HL2.IsMapValid(newmap))
    3.26  	{
    3.27  		RETURN_META(MRES_IGNORED);
    3.28  	}
     4.1 --- a/core/logic/smn_maplists.cpp	Wed Feb 13 22:25:15 2013 -0500
     4.2 +++ b/core/logic/smn_maplists.cpp	Thu Feb 14 19:28:12 2013 -0500
     4.3 @@ -33,6 +33,7 @@
     4.4  #include <sm_trie_tpl.h>
     4.5  #include "common_logic.h"
     4.6  #include "CellArray.h"
     4.7 +#include <IGameHelpers.h>
     4.8  #include <ILibrarySys.h>
     4.9  #include <ITextParsers.h>
    4.10  #include <ISourceMod.h>
    4.11 @@ -524,7 +525,7 @@
    4.12  				{
    4.13  					continue;
    4.14  				}
    4.15 -				if (!engine->IsMapValid(ptr))
    4.16 +				if (!gamehelpers->IsMapValid(ptr))
    4.17  				{
    4.18  					continue;
    4.19  				}
     5.1 --- a/core/smn_halflife.cpp	Wed Feb 13 22:25:15 2013 -0500
     5.2 +++ b/core/smn_halflife.cpp	Thu Feb 14 19:28:12 2013 -0500
     5.3 @@ -63,7 +63,7 @@
     5.4  	char *map;
     5.5  	pContext->LocalToString(params[1], &map);
     5.6  
     5.7 -	return engine->IsMapValid(map);
     5.8 +	return g_HL2.IsMapValid(map);
     5.9  }
    5.10  
    5.11  static cell_t IsDedicatedServer(IPluginContext *pContext, const cell_t *params)
     6.1 --- a/public/IGameHelpers.h	Wed Feb 13 22:25:15 2013 -0500
     6.2 +++ b/public/IGameHelpers.h	Thu Feb 14 19:28:12 2013 -0500
     6.3 @@ -308,6 +308,16 @@
     6.4  		 * @return				Pointer to the string, or NULL if bad pointer.
     6.5  		 */
     6.6  		virtual const char *GetEntityClassname(CBaseEntity *pEntity) =0;
     6.7 +
     6.8 +		/**
     6.9 +		 * @brief Returns whether or not a map name is valid to use with the
    6.10 +		 * engine's Changelevel functionality. It need not be an exact filename on
    6.11 +		 * some engines. For a check on the exact name, use IVEngineServer::IsMapValid.
    6.12 +		 *
    6.13 +		 * @param map			Map name.
    6.14 +		 * @return				True if valid, otherwise false.
    6.15 +		 */
    6.16 +		virtual bool IsMapValid(const char *map) =0;
    6.17  	};
    6.18  }
    6.19