Added support for "fuzzy" map names in L4D and later (bug 5599, r=asherkin).

This commit is contained in:
Nicholas Hastings 2013-02-14 19:28:12 -05:00
parent 6a361e3045
commit 7346b0c081
6 changed files with 58 additions and 4 deletions

View File

@ -1131,3 +1131,44 @@ const char *CHalfLife2::GetEntityClassname(CBaseEntity *pEntity)
return *(const char **)(((unsigned char *)pEntity) + offset);
}
#if SOURCE_ENGINE >= SE_LEFT4DEAD
static bool ResolveFuzzyMapName(const char *fuzzyName, char *outFullname, int size)
{
static ConCommand *pHelperCmd = g_pCVar->FindCommand("changelevel");
if (!pHelperCmd || !pHelperCmd->CanAutoComplete())
return false;
static size_t helperCmdLen = strlen(pHelperCmd->GetName());
CUtlVector<CUtlString> results;
pHelperCmd->AutoCompleteSuggest(fuzzyName, results);
if (results.Count() == 0)
return false;
// Results come back as you'd see in autocomplete. (ie. "changelevel fullmapnamehere"),
// so skip ahead to start of map path/name
// Like the engine, we're only going to deal with the first match.
strncopy(outFullname, &results[0][helperCmdLen + 1], size);
return true;
}
#endif
bool CHalfLife2::IsMapValid(const char *map)
{
bool ret = engine->IsMapValid(map);
#if SOURCE_ENGINE >= SE_LEFT4DEAD
if (!ret)
{
static char szFuzzyName[PLATFORM_MAX_PATH];
if (ResolveFuzzyMapName(map, szFuzzyName, sizeof(szFuzzyName)))
{
ret = engine->IsMapValid(szFuzzyName);
}
}
#endif
return ret;
}

View File

@ -148,6 +148,7 @@ public: //IGameHelpers
ICommandLine *GetValveCommandLine();
const char *GetEntityClassname(edict_t *pEdict);
const char *GetEntityClassname(CBaseEntity *pEntity);
bool IsMapValid(const char *map);
public:
void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
void ProcessFakeCliCmdQueue();

View File

@ -31,6 +31,7 @@
#include "NextMap.h"
#include "Logger.h"
#include "HalfLife2.h"
#include "sourcemm_api.h"
#include "sm_stringutil.h"
#include "sourcehook.h"
@ -109,7 +110,7 @@ const char *NextMapManager::GetNextMap()
bool NextMapManager::SetNextMap(const char *map)
{
if (!engine->IsMapValid(map))
if (!g_HL2.IsMapValid(map))
{
return false;
}
@ -133,7 +134,7 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const
const char *newmap = sm_nextmap.GetString();
if (newmap[0] == 0 || !engine->IsMapValid(newmap))
if (newmap[0] == 0 || !g_HL2.IsMapValid(newmap))
{
RETURN_META(MRES_IGNORED);
}

View File

@ -33,6 +33,7 @@
#include <sm_trie_tpl.h>
#include "common_logic.h"
#include "CellArray.h"
#include <IGameHelpers.h>
#include <ILibrarySys.h>
#include <ITextParsers.h>
#include <ISourceMod.h>
@ -524,7 +525,7 @@ private:
{
continue;
}
if (!engine->IsMapValid(ptr))
if (!gamehelpers->IsMapValid(ptr))
{
continue;
}

View File

@ -63,7 +63,7 @@ static cell_t IsMapValid(IPluginContext *pContext, const cell_t *params)
char *map;
pContext->LocalToString(params[1], &map);
return engine->IsMapValid(map);
return g_HL2.IsMapValid(map);
}
static cell_t IsDedicatedServer(IPluginContext *pContext, const cell_t *params)

View File

@ -308,6 +308,16 @@ namespace SourceMod
* @return Pointer to the string, or NULL if bad pointer.
*/
virtual const char *GetEntityClassname(CBaseEntity *pEntity) =0;
/**
* @brief Returns whether or not a map name is valid to use with the
* engine's Changelevel functionality. It need not be an exact filename on
* some engines. For a check on the exact name, use IVEngineServer::IsMapValid.
*
* @param map Map name.
* @return True if valid, otherwise false.
*/
virtual bool IsMapValid(const char *map) =0;
};
}