core/HalfLife2.cpp
author Scott Ehlert <ds@alliedmods.net>
Sun Mar 30 07:00:22 2008 +0000 (2008-03-30)
changeset 1952 b7aa2b626807
child 2162 59c5dc056c69
permissions -rw-r--r--
Spring Cleaning, Part Ichi (1)
Various minor things done to project files
Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way)
Updated regex project file and makefile
ds@1952
     1
/**
ds@1952
     2
 * vim: set ts=4 :
ds@1952
     3
 * =============================================================================
ds@1952
     4
 * SourceMod
ds@1952
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
ds@1952
     6
 * =============================================================================
ds@1952
     7
 *
ds@1952
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1952
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1952
    10
 * Free Software Foundation.
ds@1952
    11
 * 
ds@1952
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1952
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1952
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1952
    15
 * details.
ds@1952
    16
 *
ds@1952
    17
 * You should have received a copy of the GNU General Public License along with
ds@1952
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
ds@1952
    19
 *
ds@1952
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1952
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1952
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1952
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1952
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1952
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1952
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1952
    27
 * or <http://www.sourcemod.net/license.php>.
ds@1952
    28
 *
ds@1952
    29
 * Version: $Id$
ds@1952
    30
 */
ds@1952
    31
ds@1952
    32
#include "HalfLife2.h"
ds@1952
    33
#include "sourcemod.h"
ds@1952
    34
#include "sourcemm_api.h"
ds@1952
    35
#include "UserMessages.h"
ds@1952
    36
#include "PlayerManager.h"
ds@1952
    37
#include "sm_stringutil.h"
ds@1952
    38
#include "GameConfigs.h"
ds@1952
    39
#include <compat_wrappers.h>
ds@1952
    40
ds@1952
    41
CHalfLife2 g_HL2;
ds@1952
    42
ConVar *sv_lan = NULL;
ds@1952
    43
ds@1952
    44
namespace SourceHook
ds@1952
    45
{
ds@1952
    46
	template<>
ds@1952
    47
	int HashFunction<datamap_t *>(datamap_t * const &k)
ds@1952
    48
	{
ds@1952
    49
		return reinterpret_cast<int>(k);
ds@1952
    50
	}
ds@1952
    51
ds@1952
    52
	template<>
ds@1952
    53
	int Compare<datamap_t *>(datamap_t * const &k1, datamap_t * const &k2)
ds@1952
    54
	{
ds@1952
    55
		return (k1-k2);
ds@1952
    56
	}
ds@1952
    57
}
ds@1952
    58
ds@1952
    59
CHalfLife2::CHalfLife2()
ds@1952
    60
{
ds@1952
    61
	m_pClasses = sm_trie_create();
ds@1952
    62
}
ds@1952
    63
ds@1952
    64
CHalfLife2::~CHalfLife2()
ds@1952
    65
{
ds@1952
    66
	sm_trie_destroy(m_pClasses);
ds@1952
    67
ds@1952
    68
	List<DataTableInfo *>::iterator iter;
ds@1952
    69
	DataTableInfo *pInfo;
ds@1952
    70
	for (iter=m_Tables.begin(); iter!=m_Tables.end(); iter++)
ds@1952
    71
	{
ds@1952
    72
		pInfo = (*iter);
ds@1952
    73
		delete pInfo;
ds@1952
    74
	}
ds@1952
    75
ds@1952
    76
	m_Tables.clear();
ds@1952
    77
ds@1952
    78
	THash<datamap_t *, DataMapTrie>::iterator h_iter;
ds@1952
    79
	for (h_iter=m_Maps.begin(); h_iter!=m_Maps.end(); h_iter++)
ds@1952
    80
	{
ds@1952
    81
		if (h_iter->val.trie)
ds@1952
    82
		{
ds@1952
    83
			sm_trie_destroy(h_iter->val.trie);
ds@1952
    84
			h_iter->val.trie = NULL;
ds@1952
    85
		}
ds@1952
    86
	}
ds@1952
    87
ds@1952
    88
	m_Maps.clear();
ds@1952
    89
}
ds@1952
    90
ds@1952
    91
CSharedEdictChangeInfo *g_pSharedChangeInfo = NULL;
ds@1952
    92
bool is_original_engine = false;
ds@1952
    93
ds@1952
    94
void CHalfLife2::OnSourceModStartup(bool late)
ds@1952
    95
{
ds@1952
    96
	/* The Ship currently is the only known game to use an older version of the engine */
ds@1952
    97
#if defined METAMOD_PLAPI_VERSION
ds@1952
    98
	if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL)
ds@1952
    99
#else
ds@1952
   100
	if (strcasecmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
ds@1952
   101
#endif
ds@1952
   102
	{
ds@1952
   103
		is_original_engine = true;
ds@1952
   104
	}
ds@1952
   105
	else if (g_pSharedChangeInfo == NULL)
ds@1952
   106
	{
ds@1952
   107
		g_pSharedChangeInfo = engine->GetSharedEdictChangeInfo();
ds@1952
   108
	}
ds@1952
   109
}
ds@1952
   110
ds@1952
   111
void CHalfLife2::OnSourceModAllInitialized()
ds@1952
   112
{
ds@1952
   113
	m_MsgTextMsg = g_UserMsgs.GetMessageIndex("TextMsg");
ds@1952
   114
	m_HinTextMsg = g_UserMsgs.GetMessageIndex("HintText");
ds@1952
   115
	m_VGUIMenu = g_UserMsgs.GetMessageIndex("VGUIMenu");
ds@1952
   116
	g_ShareSys.AddInterface(NULL, this);
ds@1952
   117
}
ds@1952
   118
ds@1952
   119
#if !defined METAMOD_PLAPI_VERSION
ds@1952
   120
bool CHalfLife2::IsOriginalEngine()
ds@1952
   121
{
ds@1952
   122
	return is_original_engine;
ds@1952
   123
}
ds@1952
   124
#endif
ds@1952
   125
ds@1952
   126
IChangeInfoAccessor *CBaseEdict::GetChangeAccessor()
ds@1952
   127
{
ds@1952
   128
	return engine->GetChangeAccessor( (const edict_t *)this );
ds@1952
   129
}
ds@1952
   130
ds@1952
   131
bool UTIL_FindInSendTable(SendTable *pTable, 
ds@1952
   132
						  const char *name,
ds@1952
   133
						  sm_sendprop_info_t *info,
ds@1952
   134
						  unsigned int offset)
ds@1952
   135
{
ds@1952
   136
	const char *pname;
ds@1952
   137
	int props = pTable->GetNumProps();
ds@1952
   138
	SendProp *prop;
ds@1952
   139
ds@1952
   140
	for (int i=0; i<props; i++)
ds@1952
   141
	{
ds@1952
   142
		prop = pTable->GetProp(i);
ds@1952
   143
		pname = prop->GetName();
ds@1952
   144
		if (pname && strcmp(name, pname) == 0)
ds@1952
   145
		{
ds@1952
   146
			info->prop = prop;
ds@1952
   147
			info->actual_offset = offset + info->prop->GetOffset();
ds@1952
   148
			return true;
ds@1952
   149
		}
ds@1952
   150
		if (prop->GetDataTable())
ds@1952
   151
		{
ds@1952
   152
			if (UTIL_FindInSendTable(prop->GetDataTable(), 
ds@1952
   153
				name,
ds@1952
   154
				info,
ds@1952
   155
				offset + prop->GetOffset())
ds@1952
   156
				)
ds@1952
   157
			{
ds@1952
   158
				return true;
ds@1952
   159
			}
ds@1952
   160
		}
ds@1952
   161
	}
ds@1952
   162
ds@1952
   163
	return false;
ds@1952
   164
}
ds@1952
   165
ds@1952
   166
typedescription_t *UTIL_FindInDataMap(datamap_t *pMap, const char *name)
ds@1952
   167
{
ds@1952
   168
	while (pMap)
ds@1952
   169
	{
ds@1952
   170
		for (int i=0; i<pMap->dataNumFields; i++)
ds@1952
   171
		{
ds@1952
   172
			if (pMap->dataDesc[i].fieldName == NULL)
ds@1952
   173
			{
ds@1952
   174
				continue;
ds@1952
   175
			}
ds@1952
   176
			if (strcmp(name, pMap->dataDesc[i].fieldName) == 0)
ds@1952
   177
			{
ds@1952
   178
				return &(pMap->dataDesc[i]);
ds@1952
   179
			}
ds@1952
   180
			if (pMap->dataDesc[i].td)
ds@1952
   181
			{
ds@1952
   182
				typedescription_t *_td;
ds@1952
   183
				if ((_td=UTIL_FindInDataMap(pMap->dataDesc[i].td, name)) != NULL)
ds@1952
   184
				{
ds@1952
   185
					return _td;
ds@1952
   186
				}
ds@1952
   187
			}
ds@1952
   188
		}
ds@1952
   189
		pMap = pMap->baseMap;
ds@1952
   190
	}
ds@1952
   191
ds@1952
   192
	return NULL; 
ds@1952
   193
}
ds@1952
   194
ds@1952
   195
ServerClass *CHalfLife2::FindServerClass(const char *classname)
ds@1952
   196
{
ds@1952
   197
	DataTableInfo *pInfo = _FindServerClass(classname);
ds@1952
   198
ds@1952
   199
	if (!pInfo)
ds@1952
   200
	{
ds@1952
   201
		return NULL;
ds@1952
   202
	}
ds@1952
   203
ds@1952
   204
	return pInfo->sc;
ds@1952
   205
}
ds@1952
   206
ds@1952
   207
DataTableInfo *CHalfLife2::_FindServerClass(const char *classname)
ds@1952
   208
{
ds@1952
   209
	DataTableInfo *pInfo = NULL;
ds@1952
   210
ds@1952
   211
	if (!sm_trie_retrieve(m_pClasses, classname, (void **)&pInfo))
ds@1952
   212
	{
ds@1952
   213
		ServerClass *sc = gamedll->GetAllServerClasses();
ds@1952
   214
		while (sc)
ds@1952
   215
		{
ds@1952
   216
			if (strcmp(classname, sc->GetName()) == 0)
ds@1952
   217
			{
ds@1952
   218
				pInfo = new DataTableInfo;
ds@1952
   219
				pInfo->sc = sc;
ds@1952
   220
				sm_trie_insert(m_pClasses, classname, pInfo);
ds@1952
   221
				m_Tables.push_back(pInfo);
ds@1952
   222
				break;
ds@1952
   223
			}
ds@1952
   224
			sc = sc->m_pNext;
ds@1952
   225
		}
ds@1952
   226
		if (!pInfo)
ds@1952
   227
		{
ds@1952
   228
			return NULL;
ds@1952
   229
		}
ds@1952
   230
	}
ds@1952
   231
ds@1952
   232
	return pInfo;
ds@1952
   233
}
ds@1952
   234
ds@1952
   235
bool CHalfLife2::FindSendPropInfo(const char *classname, const char *offset, sm_sendprop_info_t *info)
ds@1952
   236
{
ds@1952
   237
	DataTableInfo *pInfo;
ds@1952
   238
	sm_sendprop_info_t *prop;
ds@1952
   239
ds@1952
   240
	if ((pInfo = _FindServerClass(classname)) == NULL)
ds@1952
   241
	{
ds@1952
   242
		return false;
ds@1952
   243
	}
ds@1952
   244
ds@1952
   245
	if ((prop = pInfo->lookup.retrieve(offset)) == NULL)
ds@1952
   246
	{
ds@1952
   247
		sm_sendprop_info_t temp_info;
ds@1952
   248
ds@1952
   249
		if (!UTIL_FindInSendTable(pInfo->sc->m_pTable, offset, &temp_info, 0))
ds@1952
   250
		{
ds@1952
   251
			return false;
ds@1952
   252
		}
ds@1952
   253
ds@1952
   254
		pInfo->lookup.insert(offset, temp_info);
ds@1952
   255
		*info = temp_info;
ds@1952
   256
	}
ds@1952
   257
	else
ds@1952
   258
	{
ds@1952
   259
		*info = *prop;
ds@1952
   260
	}
ds@1952
   261
	
ds@1952
   262
	return true;
ds@1952
   263
}
ds@1952
   264
ds@1952
   265
SendProp *CHalfLife2::FindInSendTable(const char *classname, const char *offset)
ds@1952
   266
{
ds@1952
   267
	sm_sendprop_info_t info;
ds@1952
   268
ds@1952
   269
	if (!FindSendPropInfo(classname, offset, &info))
ds@1952
   270
	{
ds@1952
   271
		return NULL;
ds@1952
   272
	}
ds@1952
   273
ds@1952
   274
	return info.prop;
ds@1952
   275
}
ds@1952
   276
ds@1952
   277
typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset)
ds@1952
   278
{
ds@1952
   279
	typedescription_t *td = NULL;
ds@1952
   280
	DataMapTrie &val = m_Maps[pMap];
ds@1952
   281
ds@1952
   282
	if (!val.trie)
ds@1952
   283
	{
ds@1952
   284
		val.trie = sm_trie_create();
ds@1952
   285
	}
ds@1952
   286
	if (!sm_trie_retrieve(val.trie, offset, (void **)&td))
ds@1952
   287
	{
ds@1952
   288
		if ((td = UTIL_FindInDataMap(pMap, offset)) != NULL)
ds@1952
   289
		{
ds@1952
   290
			sm_trie_insert(val.trie, offset, td);
ds@1952
   291
		}
ds@1952
   292
	}
ds@1952
   293
ds@1952
   294
	return td;
ds@1952
   295
}
ds@1952
   296
ds@1952
   297
void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset)
ds@1952
   298
{
ds@1952
   299
	if (g_pSharedChangeInfo != NULL)
ds@1952
   300
	{
ds@1952
   301
		if (offset)
ds@1952
   302
		{
ds@1952
   303
			pEdict->StateChanged(offset);
ds@1952
   304
		}
ds@1952
   305
		else
ds@1952
   306
		{
ds@1952
   307
			pEdict->StateChanged();
ds@1952
   308
		}
ds@1952
   309
	}
ds@1952
   310
	else
ds@1952
   311
	{
ds@1952
   312
		pEdict->m_fStateFlags |= FL_EDICT_CHANGED;
ds@1952
   313
	}
ds@1952
   314
}
ds@1952
   315
ds@1952
   316
bool CHalfLife2::TextMsg(int client, int dest, const char *msg)
ds@1952
   317
{
ds@1952
   318
	bf_write *pBitBuf = NULL;
ds@1952
   319
	cell_t players[] = {client};
ds@1952
   320
ds@1952
   321
	if ((pBitBuf = g_UserMsgs.StartMessage(m_MsgTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
ds@1952
   322
	{
ds@1952
   323
		return false;
ds@1952
   324
	}
ds@1952
   325
ds@1952
   326
	pBitBuf->WriteByte(dest);
ds@1952
   327
	pBitBuf->WriteString(msg);
ds@1952
   328
	g_UserMsgs.EndMessage();
ds@1952
   329
ds@1952
   330
	return true;
ds@1952
   331
}
ds@1952
   332
ds@1952
   333
bool CHalfLife2::HintTextMsg(int client, const char *msg)
ds@1952
   334
{
ds@1952
   335
	bf_write *pBitBuf = NULL;
ds@1952
   336
	cell_t players[] = {client};
ds@1952
   337
ds@1952
   338
	if ((pBitBuf = g_UserMsgs.StartMessage(m_HinTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
ds@1952
   339
	{
ds@1952
   340
		return false;
ds@1952
   341
	}
ds@1952
   342
ds@1952
   343
	const char *pre_byte = g_pGameConf->GetKeyValue("HintTextPreByte");
ds@1952
   344
	if (pre_byte != NULL && strcmp(pre_byte, "yes") == 0)
ds@1952
   345
	{
ds@1952
   346
		pBitBuf->WriteByte(1);
ds@1952
   347
	}
ds@1952
   348
	pBitBuf->WriteString(msg);
ds@1952
   349
	g_UserMsgs.EndMessage();
ds@1952
   350
ds@1952
   351
	return true;
ds@1952
   352
}
ds@1952
   353
ds@1952
   354
bool CHalfLife2::ShowVGUIMenu(int client, const char *name, KeyValues *data, bool show)
ds@1952
   355
{
ds@1952
   356
	bf_write *pBitBuf = NULL;
ds@1952
   357
	KeyValues *SubKey = NULL;
ds@1952
   358
	int count = 0;
ds@1952
   359
	cell_t players[] = {client};
ds@1952
   360
ds@1952
   361
	if ((pBitBuf = g_UserMsgs.StartMessage(m_VGUIMenu, players, 1, USERMSG_RELIABLE)) == NULL)
ds@1952
   362
	{
ds@1952
   363
		return false;
ds@1952
   364
	}
ds@1952
   365
ds@1952
   366
	if (data)
ds@1952
   367
	{
ds@1952
   368
		SubKey = data->GetFirstSubKey();
ds@1952
   369
		while (SubKey)
ds@1952
   370
		{
ds@1952
   371
			count++;
ds@1952
   372
			SubKey = SubKey->GetNextKey();
ds@1952
   373
		}
ds@1952
   374
		SubKey = data->GetFirstSubKey();
ds@1952
   375
	}
ds@1952
   376
ds@1952
   377
	pBitBuf->WriteString(name);
ds@1952
   378
	pBitBuf->WriteByte((show) ? 1 : 0);
ds@1952
   379
	pBitBuf->WriteByte(count);
ds@1952
   380
	while (SubKey)
ds@1952
   381
	{
ds@1952
   382
		pBitBuf->WriteString(SubKey->GetName());
ds@1952
   383
		pBitBuf->WriteString(SubKey->GetString());
ds@1952
   384
		SubKey = SubKey->GetNextKey();
ds@1952
   385
	}
ds@1952
   386
	g_UserMsgs.EndMessage();
ds@1952
   387
ds@1952
   388
	return true;
ds@1952
   389
}
ds@1952
   390
ds@1952
   391
void CHalfLife2::AddToFakeCliCmdQueue(int client, int userid, const char *cmd)
ds@1952
   392
{
ds@1952
   393
	DelayedFakeCliCmd *pFake;
ds@1952
   394
ds@1952
   395
	if (m_FreeCmds.empty())
ds@1952
   396
	{
ds@1952
   397
		pFake = new DelayedFakeCliCmd;
ds@1952
   398
	} else {
ds@1952
   399
		pFake = m_FreeCmds.front();
ds@1952
   400
		m_FreeCmds.pop();
ds@1952
   401
	}
ds@1952
   402
ds@1952
   403
	pFake->client = client;
ds@1952
   404
	pFake->userid = userid;
ds@1952
   405
	pFake->cmd.assign(cmd);
ds@1952
   406
ds@1952
   407
	m_CmdQueue.push(pFake);
ds@1952
   408
}
ds@1952
   409
ds@1952
   410
void CHalfLife2::ProcessFakeCliCmdQueue()
ds@1952
   411
{
ds@1952
   412
	while (!m_CmdQueue.empty())
ds@1952
   413
	{
ds@1952
   414
		DelayedFakeCliCmd *pFake = m_CmdQueue.first();
ds@1952
   415
ds@1952
   416
		if (g_Players.GetClientOfUserId(pFake->userid) == pFake->client)
ds@1952
   417
		{
ds@1952
   418
			CPlayer *pPlayer = g_Players.GetPlayerByIndex(pFake->client);
ds@1952
   419
			serverpluginhelpers->ClientCommand(pPlayer->GetEdict(), pFake->cmd.c_str());
ds@1952
   420
		}
ds@1952
   421
ds@1952
   422
		m_CmdQueue.pop();
ds@1952
   423
	}
ds@1952
   424
}
ds@1952
   425
ds@1952
   426
bool CHalfLife2::IsLANServer()
ds@1952
   427
{
ds@1952
   428
	sv_lan = icvar->FindVar("sv_lan");
ds@1952
   429
ds@1952
   430
	if (!sv_lan)
ds@1952
   431
	{
ds@1952
   432
		return false;
ds@1952
   433
	}
ds@1952
   434
ds@1952
   435
	return (sv_lan->GetInt() != 0);
ds@1952
   436
}
ds@1952
   437
ds@1952
   438
bool CHalfLife2::KVLoadFromFile(KeyValues *kv, IBaseFileSystem *filesystem, const char *resourceName, const char *pathID)
ds@1952
   439
{
ds@1952
   440
#if defined METAMOD_PLAPI_VERSION
ds@1952
   441
	if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL)
ds@1952
   442
#else
ds@1952
   443
	if (strcasecmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
ds@1952
   444
#endif
ds@1952
   445
	{
ds@1952
   446
		Assert(filesystem);
ds@1952
   447
#ifdef _MSC_VER
ds@1952
   448
		Assert(_heapchk() == _HEAPOK);
ds@1952
   449
#endif
ds@1952
   450
ds@1952
   451
		FileHandle_t f = filesystem->Open(resourceName, "rb", pathID);
ds@1952
   452
		if (!f)
ds@1952
   453
			return false;
ds@1952
   454
ds@1952
   455
		// load file into a null-terminated buffer
ds@1952
   456
		int fileSize = filesystem->Size(f);
ds@1952
   457
		char *buffer = (char *)MemAllocScratch(fileSize + 1);
ds@1952
   458
ds@1952
   459
		Assert(buffer);
ds@1952
   460
ds@1952
   461
		filesystem->Read(buffer, fileSize, f); // read into local buffer
ds@1952
   462
ds@1952
   463
		buffer[fileSize] = 0; // null terminate file as EOF
ds@1952
   464
ds@1952
   465
		filesystem->Close( f );	// close file after reading
ds@1952
   466
ds@1952
   467
		bool retOK = kv->LoadFromBuffer( resourceName, buffer, filesystem );
ds@1952
   468
ds@1952
   469
		MemFreeScratch();
ds@1952
   470
ds@1952
   471
		return retOK;
ds@1952
   472
	}
ds@1952
   473
	else
ds@1952
   474
	{
ds@1952
   475
		return kv->LoadFromFile(filesystem, resourceName, pathID);
ds@1952
   476
	}
ds@1952
   477
}
ds@1952
   478
ds@1952
   479
void CHalfLife2::PushCommandStack(const CCommand *cmd)
ds@1952
   480
{
ds@1952
   481
	CachedCommandInfo info;
ds@1952
   482
ds@1952
   483
	info.args = cmd;
ds@1952
   484
#if !defined ORANGEBOX_BUILD
ds@1952
   485
	strncopy(info.cmd, cmd->Arg(0), sizeof(info.cmd));
ds@1952
   486
#endif
ds@1952
   487
ds@1952
   488
	m_CommandStack.push(info);
ds@1952
   489
}
ds@1952
   490
ds@1952
   491
const CCommand *CHalfLife2::PeekCommandStack()
ds@1952
   492
{
ds@1952
   493
	if (m_CommandStack.empty())
ds@1952
   494
	{
ds@1952
   495
		return NULL;
ds@1952
   496
	}
ds@1952
   497
ds@1952
   498
	return m_CommandStack.front().args;
ds@1952
   499
}
ds@1952
   500
ds@1952
   501
void CHalfLife2::PopCommandStack()
ds@1952
   502
{
ds@1952
   503
	m_CommandStack.pop();
ds@1952
   504
}
ds@1952
   505
ds@1952
   506
const char *CHalfLife2::CurrentCommandName()
ds@1952
   507
{
ds@1952
   508
#if defined ORANGEBOX_BUILD
ds@1952
   509
	return m_CommandStack.front().args->Arg(0);
ds@1952
   510
#else
ds@1952
   511
	return m_CommandStack.front().cmd;
ds@1952
   512
#endif
ds@1952
   513
}