3 * ================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * ================================================================
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License,
10 * version 3.0, as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to
21 * link the code of this program (as well as its derivative works) to
22 * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any
23 * Game MODs that run on software by the Valve Corporation. You must
24 * obey the GNU General Public License in all respects for all other
25 * code used. Additionally, AlliedModders LLC grants this exception
26 * to all derivative works. AlliedModders LLC defines further
27 * exceptions, found in LICENSE.txt (as of this writing, version
28 * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
33 #include "sm_globals.h"
34 #include "sourcemod.h"
35 #include "sourcemm_api.h"
36 #include "HandleSys.h"
37 #include "PlayerManager.h"
38 #include "HalfLife2.h"
40 IServerPluginCallbacks *g_VSP = NULL;
42 class HalfLifeNatives : public SMGlobalClass
44 public: //SMGlobalClass
45 void OnSourceModVSPReceived(IServerPluginCallbacks *iface)
51 static cell_t SetRandomSeed(IPluginContext *pContext, const cell_t *params)
53 engrandom->SetSeed(params[1]);
58 static cell_t GetRandomFloat(IPluginContext *pContext, const cell_t *params)
60 float fMin = sp_ctof(params[1]);
61 float fMax = sp_ctof(params[2]);
63 float fRandom = engrandom->RandomFloat(fMin, fMax);
65 return sp_ftoc(fRandom);
68 static cell_t GetRandomInt(IPluginContext *pContext, const cell_t *params)
70 return engrandom->RandomInt(params[1], params[2]);
73 static cell_t IsMapValid(IPluginContext *pContext, const cell_t *params)
76 pContext->LocalToString(params[1], &map);
78 return engine->IsMapValid(map);
81 static cell_t IsDedicatedServer(IPluginContext *pContext, const cell_t *params)
83 return engine->IsDedicatedServer();
86 static cell_t GetEngineTime(IPluginContext *pContext, const cell_t *params)
88 float fTime = engine->Time();
89 return sp_ftoc(fTime);
92 static cell_t GetGameTime(IPluginContext *pContext, const cell_t *params)
94 return sp_ftoc(gpGlobals->curtime);
97 static cell_t CreateFakeClient(IPluginContext *pContext, const cell_t *params)
101 pContext->LocalToString(params[1], &netname);
103 edict_t *pEdict = engine->CreateFakeClient(netname);
105 /* :TODO: does the engine fire forwards for us and whatnot? no idea... */
112 return engine->IndexOfEdict(pEdict);
115 static cell_t SetFakeClientConVar(IPluginContext *pContext, const cell_t *params)
117 CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
121 return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
124 if (!pPlayer->IsConnected())
126 return pContext->ThrowNativeError("Client %d is not connected", params[1]);
129 if (!pPlayer->IsFakeClient())
131 return pContext->ThrowNativeError("Client %d is not a fake client", params[1]);
136 pContext->LocalToString(params[2], &cvar);
137 pContext->LocalToString(params[3], &value);
139 engine->SetFakeClientConVarValue(pPlayer->GetEdict(), cvar, value);
144 static cell_t GetGameDescription(IPluginContext *pContext, const cell_t *params)
146 const char *description;
150 description = gamedll->GetGameDescription();
152 description = SERVER_CALL(GetGameDescription)();
157 pContext->StringToLocalUTF8(params[1], params[2], description, &numBytes);
162 static cell_t GetGameFolderName(IPluginContext *pContext, const cell_t *params)
164 const char *name = g_SourceMod.GetGameFolderName();
167 pContext->StringToLocalUTF8(params[1], params[2], name, &numBytes);
172 static cell_t GetCurrentMap(IPluginContext *pContext, const cell_t *params)
175 pContext->StringToLocalUTF8(params[1], params[2], STRING(gpGlobals->mapname), &bytes);
179 static cell_t PrecacheModel(IPluginContext *pContext, const cell_t *params)
182 pContext->LocalToString(params[1], &model);
184 return engine->PrecacheModel(model, params[2] ? true : false);
187 static cell_t PrecacheSentenceFile(IPluginContext *pContext, const cell_t *params)
190 pContext->LocalToString(params[1], &sentencefile);
192 return engine->PrecacheSentenceFile(sentencefile, params[2] ? true : false);
195 static cell_t PrecacheDecal(IPluginContext *pContext, const cell_t *params)
198 pContext->LocalToString(params[1], &decal);
200 return engine->PrecacheDecal(decal, params[2] ? true : false);
203 static cell_t PrecacheGeneric(IPluginContext *pContext, const cell_t *params)
206 pContext->LocalToString(params[1], &generic);
208 return engine->PrecacheGeneric(generic, params[2] ? true : false);
211 static cell_t IsModelPrecached(IPluginContext *pContext, const cell_t *params)
214 pContext->LocalToString(params[1], &model);
216 return engine->IsModelPrecached(model) ? 1 : 0;
219 static cell_t IsDecalPrecached(IPluginContext *pContext, const cell_t *params)
222 pContext->LocalToString(params[1], &decal);
224 return engine->IsDecalPrecached(decal) ? 1 : 0;
227 static cell_t IsGenericPrecached(IPluginContext *pContext, const cell_t *params)
230 pContext->LocalToString(params[1], &generic);
232 return engine->IsGenericPrecached(generic) ? 1 : 0;
235 static cell_t PrecacheSound(IPluginContext *pContext, const cell_t *params)
238 pContext->LocalToString(params[1], &sample);
240 return enginesound->PrecacheSound(sample, params[2] ? true : false) ? 1 : 0;
243 static cell_t IsSoundPrecached(IPluginContext *pContext, const cell_t *params)
246 pContext->LocalToString(params[1], &sample);
248 return enginesound->IsSoundPrecached(sample) ? 1 : 0;
251 static cell_t smn_CreateDialog(IPluginContext *pContext, const cell_t *params)
255 Handle_t hndl = static_cast<Handle_t>(params[2]);
256 CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
260 return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
263 if (!pPlayer->IsInGame())
265 return pContext->ThrowNativeError("Client %d is not in game", params[1]);
268 pKV = g_SourceMod.ReadKeyValuesHandle(hndl, &herr, true);
269 if (herr != HandleError_None)
271 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
274 serverpluginhelpers->CreateMessage(pPlayer->GetEdict(), static_cast<DIALOG_TYPE>(params[3]), pKV, g_VSP);
279 static cell_t PrintToChat(IPluginContext *pContext, const cell_t *params)
281 int client = params[1];
282 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
286 return pContext->ThrowNativeError("Client index %d is invalid", client);
289 if (!pPlayer->IsInGame())
291 return pContext->ThrowNativeError("Client %d is not in game", client);
294 g_SourceMod.SetGlobalTarget(client);
297 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
299 /* Check for an error before printing to the client */
300 if (pContext->GetContext()->n_err != SP_ERROR_NONE)
305 if (!g_HL2.TextMsg(client, HUD_PRINTTALK, buffer))
307 return pContext->ThrowNativeError("Could not send a usermessage");
313 static cell_t PrintCenterText(IPluginContext *pContext, const cell_t *params)
315 int client = params[1];
316 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
320 return pContext->ThrowNativeError("Client index %d is invalid", client);
323 if (!pPlayer->IsInGame())
325 return pContext->ThrowNativeError("Client %d is not in game", client);
328 g_SourceMod.SetGlobalTarget(client);
331 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
333 /* Check for an error before printing to the client */
334 if (pContext->GetContext()->n_err != SP_ERROR_NONE)
339 if (!g_HL2.TextMsg(client, HUD_PRINTCENTER, buffer))
341 return pContext->ThrowNativeError("Could not send a usermessage");
347 static cell_t PrintHintText(IPluginContext *pContext, const cell_t *params)
349 int client = params[1];
350 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
354 return pContext->ThrowNativeError("Client index %d is invalid", client);
357 if (!pPlayer->IsInGame())
359 return pContext->ThrowNativeError("Client %d is not in game", client);
362 g_SourceMod.SetGlobalTarget(client);
365 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
367 /* Check for an error before printing to the client */
368 if (pContext->GetContext()->n_err != SP_ERROR_NONE)
373 if (!g_HL2.HintTextMsg(client, buffer))
375 return pContext->ThrowNativeError("Could not send a usermessage");
381 static cell_t ShowVGUIPanel(IPluginContext *pContext, const cell_t *params)
385 KeyValues *pKV = NULL;
386 int client = params[1];
387 Handle_t hndl = static_cast<Handle_t>(params[3]);
388 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
392 return pContext->ThrowNativeError("Client index %d is invalid", client);
395 if (!pPlayer->IsInGame())
397 return pContext->ThrowNativeError("Client %d is not in game", client);
400 if (hndl != BAD_HANDLE)
402 pKV = g_SourceMod.ReadKeyValuesHandle(hndl, &herr, true);
403 if (herr != HandleError_None)
405 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
409 pContext->LocalToString(params[2], &name);
411 if (!g_HL2.ShowVGUIMenu(client, name, pKV, (params[4]) ? true : false))
413 return pContext->ThrowNativeError("Could not send a usermessage");
419 static HalfLifeNatives s_HalfLifeNatives;
421 REGISTER_NATIVES(halflifeNatives)
423 {"CreateFakeClient", CreateFakeClient},
424 {"GetCurrentMap", GetCurrentMap},
425 {"GetEngineTime", GetEngineTime},
426 {"GetGameDescription", GetGameDescription},
427 {"GetGameFolderName", GetGameFolderName},
428 {"GetGameTime", GetGameTime},
429 {"GetRandomFloat", GetRandomFloat},
430 {"GetRandomInt", GetRandomInt},
431 {"IsDedicatedServer", IsDedicatedServer},
432 {"IsMapValid", IsMapValid},
433 {"SetFakeClientConVar", SetFakeClientConVar},
434 {"SetRandomSeed", SetRandomSeed},
435 {"PrecacheModel", PrecacheModel},
436 {"PrecacheSentenceFile", PrecacheSentenceFile},
437 {"PrecacheDecal", PrecacheDecal},
438 {"PrecacheGeneric", PrecacheGeneric},
439 {"IsModelPrecached", IsModelPrecached},
440 {"IsDecalPrecached", IsDecalPrecached},
441 {"IsGenericPrecached", IsGenericPrecached},
442 {"PrecacheSound", PrecacheSound},
443 {"IsSoundPrecached", IsSoundPrecached},
444 {"CreateDialog", smn_CreateDialog},
445 {"PrintToChat", PrintToChat},
446 {"PrintCenterText", PrintCenterText},
447 {"PrintHintText", PrintHintText},
448 {"ShowVGUIPanel", ShowVGUIPanel},