core/smn_halflife.cpp
author David Anderson <dvander@alliedmods.net>
Mon Oct 15 00:38:25 2007 +0000 (2007-10-15)
changeset 1568 ecbaee393b0b
parent 1330 ab94316bb52b
child 1581 2562512b4a44
permissions -rw-r--r--
extensions can now be built for multiple engines, and will autoload from auto.X.Y folders
dvander@530
     1
/**
ds@653
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
dvander@1231
     5
 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@530
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1231
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1231
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@530
    28
 *
dvander@530
    29
 * Version: $Id$
dvander@530
    30
 */
dvander@530
    31
dvander@530
    32
#include "sm_globals.h"
dvander@532
    33
#include "sourcemod.h"
dvander@530
    34
#include "sourcemm_api.h"
ds@873
    35
#include "HandleSys.h"
dvander@591
    36
#include "PlayerManager.h"
ds@873
    37
#include "HalfLife2.h"
ds@874
    38
faluco@682
    39
IServerPluginCallbacks *g_VSP = NULL;
faluco@682
    40
faluco@682
    41
class HalfLifeNatives : public SMGlobalClass
faluco@682
    42
{
faluco@682
    43
public: //SMGlobalClass
faluco@682
    44
	void OnSourceModVSPReceived(IServerPluginCallbacks *iface)
faluco@682
    45
	{
faluco@682
    46
		g_VSP = iface;
faluco@682
    47
	}
faluco@682
    48
};
dvander@530
    49
dvander@530
    50
static cell_t SetRandomSeed(IPluginContext *pContext, const cell_t *params)
dvander@530
    51
{
dvander@530
    52
	engrandom->SetSeed(params[1]);
dvander@530
    53
dvander@530
    54
	return 1;
dvander@530
    55
}
dvander@530
    56
dvander@530
    57
static cell_t GetRandomFloat(IPluginContext *pContext, const cell_t *params)
dvander@530
    58
{
dvander@530
    59
	float fMin = sp_ctof(params[1]);
dvander@530
    60
	float fMax = sp_ctof(params[2]);
dvander@530
    61
dvander@530
    62
	float fRandom = engrandom->RandomFloat(fMin, fMax);
dvander@530
    63
dvander@530
    64
	return sp_ftoc(fRandom);
dvander@530
    65
}
dvander@530
    66
dvander@530
    67
static cell_t GetRandomInt(IPluginContext *pContext, const cell_t *params)
dvander@530
    68
{
dvander@530
    69
	return engrandom->RandomInt(params[1], params[2]);
dvander@530
    70
}
dvander@530
    71
dvander@532
    72
static cell_t IsMapValid(IPluginContext *pContext, const cell_t *params)
dvander@532
    73
{
dvander@532
    74
	char *map;
dvander@532
    75
	pContext->LocalToString(params[1], &map);
dvander@532
    76
dvander@532
    77
	return engine->IsMapValid(map);
dvander@532
    78
}
dvander@532
    79
dvander@532
    80
static cell_t IsDedicatedServer(IPluginContext *pContext, const cell_t *params)
dvander@532
    81
{
dvander@532
    82
	return engine->IsDedicatedServer();
dvander@532
    83
}
dvander@532
    84
dvander@532
    85
static cell_t GetEngineTime(IPluginContext *pContext, const cell_t *params)
dvander@532
    86
{
dvander@532
    87
	float fTime = engine->Time();
dvander@532
    88
	return sp_ftoc(fTime);
dvander@532
    89
}
dvander@532
    90
dvander@532
    91
static cell_t GetGameTime(IPluginContext *pContext, const cell_t *params)
dvander@532
    92
{
dvander@532
    93
	return sp_ftoc(gpGlobals->curtime);
dvander@532
    94
}
dvander@532
    95
dvander@532
    96
static cell_t CreateFakeClient(IPluginContext *pContext, const cell_t *params)
dvander@532
    97
{
dvander@532
    98
	char *netname;
dvander@532
    99
dvander@532
   100
	pContext->LocalToString(params[1], &netname);
dvander@532
   101
dvander@532
   102
	edict_t *pEdict = engine->CreateFakeClient(netname);
dvander@532
   103
dvander@532
   104
	/* :TODO: does the engine fire forwards for us and whatnot? no idea... */
dvander@532
   105
dvander@532
   106
	if (!pEdict)
dvander@532
   107
	{
dvander@532
   108
		return 0;
dvander@532
   109
	}
dvander@532
   110
dvander@532
   111
	return engine->IndexOfEdict(pEdict);
dvander@532
   112
}
dvander@532
   113
dvander@532
   114
static cell_t SetFakeClientConVar(IPluginContext *pContext, const cell_t *params)
dvander@532
   115
{
dvander@532
   116
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
dvander@532
   117
dvander@532
   118
	if (!pPlayer)
dvander@532
   119
	{
ds@994
   120
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
dvander@532
   121
	}
dvander@532
   122
dvander@532
   123
	if (!pPlayer->IsConnected())
dvander@532
   124
	{
ds@994
   125
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
dvander@532
   126
	}
dvander@532
   127
dvander@532
   128
	if (!pPlayer->IsFakeClient())
dvander@532
   129
	{
ds@994
   130
		return pContext->ThrowNativeError("Client %d is not a fake client", params[1]);
dvander@532
   131
	}
dvander@532
   132
dvander@532
   133
	char *cvar, *value;
dvander@532
   134
dvander@532
   135
	pContext->LocalToString(params[2], &cvar);
dvander@532
   136
	pContext->LocalToString(params[3], &value);
dvander@532
   137
dvander@532
   138
	engine->SetFakeClientConVarValue(pPlayer->GetEdict(), cvar, value);
dvander@532
   139
dvander@532
   140
	return 1;
dvander@532
   141
}
dvander@532
   142
dvander@532
   143
static cell_t GetGameDescription(IPluginContext *pContext, const cell_t *params)
dvander@532
   144
{
dvander@532
   145
	const char *description;
dvander@532
   146
dvander@532
   147
	if (params[3])
dvander@532
   148
	{
dvander@532
   149
		description = gamedll->GetGameDescription();
dvander@532
   150
	} else {
dvander@532
   151
		description = SERVER_CALL(GetGameDescription)();
dvander@532
   152
	}
dvander@532
   153
dvander@532
   154
	size_t numBytes;
dvander@532
   155
	
dvander@532
   156
	pContext->StringToLocalUTF8(params[1], params[2], description, &numBytes);
dvander@532
   157
dvander@532
   158
	return numBytes;
dvander@532
   159
}
dvander@532
   160
ds@721
   161
static cell_t GetGameFolderName(IPluginContext *pContext, const cell_t *params)
ds@721
   162
{
ds@729
   163
	const char *name = g_SourceMod.GetGameFolderName();
ds@721
   164
	size_t numBytes;
ds@721
   165
ds@721
   166
	pContext->StringToLocalUTF8(params[1], params[2], name, &numBytes);
ds@721
   167
ds@721
   168
	return numBytes;
ds@721
   169
}
ds@721
   170
dvander@532
   171
static cell_t GetCurrentMap(IPluginContext *pContext, const cell_t *params)
dvander@532
   172
{
dvander@532
   173
	size_t bytes;
dvander@532
   174
	pContext->StringToLocalUTF8(params[1], params[2], STRING(gpGlobals->mapname), &bytes);
dvander@532
   175
	return bytes;
dvander@532
   176
}
dvander@532
   177
faluco@656
   178
static cell_t PrecacheModel(IPluginContext *pContext, const cell_t *params)
faluco@656
   179
{
faluco@656
   180
	char *model;
faluco@656
   181
	pContext->LocalToString(params[1], &model);
faluco@656
   182
faluco@656
   183
	return engine->PrecacheModel(model, params[2] ? true : false);
faluco@656
   184
}
faluco@656
   185
faluco@656
   186
static cell_t PrecacheSentenceFile(IPluginContext *pContext, const cell_t *params)
faluco@656
   187
{
faluco@656
   188
	char *sentencefile;
faluco@656
   189
	pContext->LocalToString(params[1], &sentencefile);
faluco@656
   190
faluco@656
   191
	return engine->PrecacheSentenceFile(sentencefile, params[2] ? true : false);
faluco@656
   192
}
faluco@656
   193
faluco@656
   194
static cell_t PrecacheDecal(IPluginContext *pContext, const cell_t *params)
faluco@656
   195
{
faluco@656
   196
	char *decal;
faluco@656
   197
	pContext->LocalToString(params[1], &decal);
faluco@656
   198
faluco@656
   199
	return engine->PrecacheDecal(decal, params[2] ? true : false);
faluco@656
   200
}
faluco@656
   201
faluco@656
   202
static cell_t PrecacheGeneric(IPluginContext *pContext, const cell_t *params)
faluco@656
   203
{
faluco@656
   204
	char *generic;
faluco@656
   205
	pContext->LocalToString(params[1], &generic);
faluco@656
   206
faluco@656
   207
	return engine->PrecacheGeneric(generic, params[2] ? true : false);
faluco@656
   208
}
faluco@656
   209
faluco@656
   210
static cell_t IsModelPrecached(IPluginContext *pContext, const cell_t *params)
faluco@656
   211
{
faluco@656
   212
	char *model;
faluco@656
   213
	pContext->LocalToString(params[1], &model);
faluco@656
   214
faluco@656
   215
	return engine->IsModelPrecached(model) ? 1 : 0;
faluco@656
   216
}
faluco@656
   217
faluco@656
   218
static cell_t IsDecalPrecached(IPluginContext *pContext, const cell_t *params)
faluco@656
   219
{
faluco@656
   220
	char *decal;
faluco@656
   221
	pContext->LocalToString(params[1], &decal);
faluco@656
   222
faluco@656
   223
	return engine->IsDecalPrecached(decal) ? 1 : 0;
faluco@656
   224
}
faluco@656
   225
faluco@656
   226
static cell_t IsGenericPrecached(IPluginContext *pContext, const cell_t *params)
faluco@656
   227
{
faluco@656
   228
	char *generic;
faluco@656
   229
	pContext->LocalToString(params[1], &generic);
faluco@656
   230
faluco@656
   231
	return engine->IsGenericPrecached(generic) ? 1 : 0;
faluco@656
   232
}
faluco@656
   233
faluco@656
   234
static cell_t PrecacheSound(IPluginContext *pContext, const cell_t *params)
faluco@656
   235
{
faluco@656
   236
	char *sample;
faluco@656
   237
	pContext->LocalToString(params[1], &sample);
faluco@656
   238
faluco@656
   239
	return enginesound->PrecacheSound(sample, params[2] ? true : false) ? 1 : 0;
faluco@656
   240
}
faluco@656
   241
faluco@656
   242
static cell_t IsSoundPrecached(IPluginContext *pContext, const cell_t *params)
faluco@656
   243
{
faluco@656
   244
	char *sample;
faluco@656
   245
	pContext->LocalToString(params[1], &sample);
faluco@656
   246
faluco@656
   247
	return enginesound->IsSoundPrecached(sample) ? 1 : 0;
faluco@656
   248
}
faluco@656
   249
faluco@682
   250
static cell_t smn_CreateDialog(IPluginContext *pContext, const cell_t *params)
faluco@682
   251
{
faluco@682
   252
	KeyValues *pKV;
faluco@682
   253
	HandleError herr;
faluco@682
   254
	Handle_t hndl = static_cast<Handle_t>(params[2]);
faluco@682
   255
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
faluco@682
   256
faluco@682
   257
	if (!pPlayer)
faluco@682
   258
	{
ds@994
   259
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
faluco@682
   260
	}
faluco@682
   261
ds@891
   262
	if (!pPlayer->IsInGame())
faluco@682
   263
	{
ds@891
   264
		return pContext->ThrowNativeError("Client %d is not in game", params[1]);
faluco@682
   265
	}
faluco@682
   266
faluco@682
   267
	pKV = g_SourceMod.ReadKeyValuesHandle(hndl, &herr, true);
faluco@682
   268
	if (herr != HandleError_None)
faluco@682
   269
	{
faluco@682
   270
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@682
   271
	}
faluco@682
   272
faluco@682
   273
	serverpluginhelpers->CreateMessage(pPlayer->GetEdict(), static_cast<DIALOG_TYPE>(params[3]), pKV, g_VSP);
faluco@682
   274
faluco@682
   275
	return 1;
faluco@682
   276
}
faluco@682
   277
ds@873
   278
static cell_t PrintToChat(IPluginContext *pContext, const cell_t *params)
ds@873
   279
{
ds@873
   280
	int client = params[1];
ds@873
   281
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
ds@873
   282
ds@873
   283
	if (!pPlayer)
ds@873
   284
	{
ds@994
   285
		return pContext->ThrowNativeError("Client index %d is invalid", client);
ds@873
   286
	}
ds@873
   287
ds@891
   288
	if (!pPlayer->IsInGame())
ds@873
   289
	{
ds@892
   290
		return pContext->ThrowNativeError("Client %d is not in game", client);
ds@873
   291
	}
ds@873
   292
dvander@1011
   293
	g_SourceMod.SetGlobalTarget(client);
dvander@1011
   294
ds@899
   295
	char buffer[192];
ds@873
   296
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
ds@873
   297
dvander@1017
   298
	/* Check for an error before printing to the client */
dvander@1017
   299
	if (pContext->GetContext()->n_err != SP_ERROR_NONE)
dvander@1017
   300
	{
dvander@1017
   301
		return 0;
dvander@1017
   302
	}
dvander@1017
   303
dvander@1132
   304
	if (!g_HL2.TextMsg(client, HUD_PRINTTALK, buffer))
dvander@1132
   305
	{
dvander@1132
   306
		return pContext->ThrowNativeError("Could not send a usermessage");
dvander@1132
   307
	}
ds@873
   308
ds@873
   309
	return 1;
ds@873
   310
}
ds@873
   311
ds@873
   312
static cell_t PrintCenterText(IPluginContext *pContext, const cell_t *params)
ds@873
   313
{
ds@873
   314
	int client = params[1];
ds@873
   315
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
ds@873
   316
ds@873
   317
	if (!pPlayer)
ds@873
   318
	{
ds@994
   319
		return pContext->ThrowNativeError("Client index %d is invalid", client);
ds@873
   320
	}
ds@873
   321
ds@891
   322
	if (!pPlayer->IsInGame())
ds@873
   323
	{
ds@892
   324
		return pContext->ThrowNativeError("Client %d is not in game", client);
ds@873
   325
	}
ds@873
   326
dvander@1011
   327
	g_SourceMod.SetGlobalTarget(client);
dvander@1011
   328
ds@899
   329
	char buffer[192];
ds@873
   330
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
ds@873
   331
dvander@1017
   332
	/* Check for an error before printing to the client */
dvander@1017
   333
	if (pContext->GetContext()->n_err != SP_ERROR_NONE)
dvander@1017
   334
	{
dvander@1017
   335
		return 0;
dvander@1017
   336
	}
dvander@1017
   337
dvander@1132
   338
	if (!g_HL2.TextMsg(client, HUD_PRINTCENTER, buffer))
dvander@1132
   339
	{
dvander@1132
   340
		return pContext->ThrowNativeError("Could not send a usermessage");
dvander@1132
   341
	}
ds@873
   342
ds@873
   343
	return 1;
ds@873
   344
}
ds@873
   345
faluco@1218
   346
static cell_t PrintHintText(IPluginContext *pContext, const cell_t *params)
faluco@1218
   347
{
faluco@1218
   348
	int client = params[1];
faluco@1218
   349
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
faluco@1218
   350
faluco@1218
   351
	if (!pPlayer)
faluco@1218
   352
	{
faluco@1218
   353
		return pContext->ThrowNativeError("Client index %d is invalid", client);
faluco@1218
   354
	}
faluco@1218
   355
faluco@1218
   356
	if (!pPlayer->IsInGame())
faluco@1218
   357
	{
faluco@1218
   358
		return pContext->ThrowNativeError("Client %d is not in game", client);
faluco@1218
   359
	}
faluco@1218
   360
faluco@1218
   361
	g_SourceMod.SetGlobalTarget(client);
faluco@1218
   362
faluco@1218
   363
	char buffer[192];
faluco@1218
   364
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
faluco@1218
   365
faluco@1218
   366
	/* Check for an error before printing to the client */
faluco@1218
   367
	if (pContext->GetContext()->n_err != SP_ERROR_NONE)
faluco@1218
   368
	{
faluco@1218
   369
		return 0;
faluco@1218
   370
	}
faluco@1218
   371
teame06@1264
   372
	if (!g_HL2.HintTextMsg(client, buffer))
faluco@1218
   373
	{
faluco@1218
   374
		return pContext->ThrowNativeError("Could not send a usermessage");
faluco@1218
   375
	}
faluco@1218
   376
faluco@1218
   377
	return 1;
faluco@1218
   378
}
faluco@1218
   379
faluco@1218
   380
static cell_t ShowVGUIPanel(IPluginContext *pContext, const cell_t *params)
faluco@1218
   381
{
faluco@1218
   382
	HandleError herr;
faluco@1218
   383
	char *name;
faluco@1218
   384
	KeyValues *pKV = NULL;
faluco@1218
   385
	int client = params[1];
faluco@1218
   386
	Handle_t hndl = static_cast<Handle_t>(params[3]);
faluco@1218
   387
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
faluco@1218
   388
faluco@1218
   389
	if (!pPlayer)
faluco@1218
   390
	{
faluco@1218
   391
		return pContext->ThrowNativeError("Client index %d is invalid", client);
faluco@1218
   392
	}
faluco@1218
   393
faluco@1218
   394
	if (!pPlayer->IsInGame())
faluco@1218
   395
	{
faluco@1218
   396
		return pContext->ThrowNativeError("Client %d is not in game", client);
faluco@1218
   397
	}
faluco@1218
   398
faluco@1218
   399
	if (hndl != BAD_HANDLE)
faluco@1218
   400
	{
faluco@1218
   401
		pKV = g_SourceMod.ReadKeyValuesHandle(hndl, &herr, true);
faluco@1218
   402
		if (herr != HandleError_None)
faluco@1218
   403
		{
faluco@1218
   404
			return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@1218
   405
		}
faluco@1218
   406
	}
faluco@1218
   407
faluco@1218
   408
	pContext->LocalToString(params[2], &name);
faluco@1218
   409
faluco@1218
   410
	if (!g_HL2.ShowVGUIMenu(client, name, pKV, (params[4]) ? true : false))
faluco@1218
   411
	{
faluco@1218
   412
		return pContext->ThrowNativeError("Could not send a usermessage");
faluco@1218
   413
	}
faluco@1218
   414
faluco@1218
   415
	return 1;
faluco@1218
   416
}
faluco@1218
   417
faluco@682
   418
static HalfLifeNatives s_HalfLifeNatives;
faluco@682
   419
dvander@530
   420
REGISTER_NATIVES(halflifeNatives)
dvander@530
   421
{
dvander@532
   422
	{"CreateFakeClient",		CreateFakeClient},
dvander@532
   423
	{"GetCurrentMap",			GetCurrentMap},
dvander@532
   424
	{"GetEngineTime",			GetEngineTime},
dvander@532
   425
	{"GetGameDescription",		GetGameDescription},
ds@721
   426
	{"GetGameFolderName",		GetGameFolderName},
dvander@532
   427
	{"GetGameTime",				GetGameTime},
dvander@530
   428
	{"GetRandomFloat",			GetRandomFloat},
dvander@530
   429
	{"GetRandomInt",			GetRandomInt},
dvander@532
   430
	{"IsDedicatedServer",		IsDedicatedServer},
dvander@532
   431
	{"IsMapValid",				IsMapValid},
dvander@532
   432
	{"SetFakeClientConVar",		SetFakeClientConVar},
dvander@532
   433
	{"SetRandomSeed",			SetRandomSeed},
faluco@656
   434
	{"PrecacheModel",			PrecacheModel},
faluco@656
   435
	{"PrecacheSentenceFile",	PrecacheSentenceFile},
faluco@656
   436
	{"PrecacheDecal",			PrecacheDecal},
faluco@656
   437
	{"PrecacheGeneric",			PrecacheGeneric},
faluco@656
   438
	{"IsModelPrecached",		IsModelPrecached},
faluco@656
   439
	{"IsDecalPrecached",		IsDecalPrecached},
faluco@656
   440
	{"IsGenericPrecached",		IsGenericPrecached},
faluco@656
   441
	{"PrecacheSound",			PrecacheSound},
faluco@656
   442
	{"IsSoundPrecached",		IsSoundPrecached},
faluco@682
   443
	{"CreateDialog",			smn_CreateDialog},
ds@873
   444
	{"PrintToChat",				PrintToChat},
ds@873
   445
	{"PrintCenterText",			PrintCenterText},
faluco@1218
   446
	{"PrintHintText",			PrintHintText},
faluco@1218
   447
	{"ShowVGUIPanel",			ShowVGUIPanel},
dvander@530
   448
	{NULL,						NULL},
dvander@530
   449
};