Added support for Dark Messiah engine and game. (no bug, r=me).
The development of this feature would not be possible without the support of the following people from the game's community:
Dylan Riggs, Carl Pettengill, Ed Moreland, and Christian.
3 * =============================================================================
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "sm_globals.h"
33 #include "sourcemod.h"
34 #include "sourcemm_api.h"
35 #include "HandleSys.h"
36 #include "PlayerManager.h"
37 #include "HalfLife2.h"
39 static cell_t SetRandomSeed(IPluginContext *pContext, const cell_t *params)
41 engrandom->SetSeed(params[1]);
46 static cell_t GetRandomFloat(IPluginContext *pContext, const cell_t *params)
48 float fMin = sp_ctof(params[1]);
49 float fMax = sp_ctof(params[2]);
51 float fRandom = engrandom->RandomFloat(fMin, fMax);
53 return sp_ftoc(fRandom);
56 static cell_t GetRandomInt(IPluginContext *pContext, const cell_t *params)
58 return engrandom->RandomInt(params[1], params[2]);
61 static cell_t IsMapValid(IPluginContext *pContext, const cell_t *params)
64 pContext->LocalToString(params[1], &map);
66 return engine->IsMapValid(map);
69 static cell_t IsDedicatedServer(IPluginContext *pContext, const cell_t *params)
71 return engine->IsDedicatedServer();
74 static cell_t GetEngineTime(IPluginContext *pContext, const cell_t *params)
76 float fTime = engine->Time();
77 return sp_ftoc(fTime);
80 static cell_t GetGameTime(IPluginContext *pContext, const cell_t *params)
82 return sp_ftoc(gpGlobals->curtime);
85 static cell_t CreateFakeClient(IPluginContext *pContext, const cell_t *params)
89 pContext->LocalToString(params[1], &netname);
91 edict_t *pEdict = engine->CreateFakeClient(netname);
93 /* :TODO: does the engine fire forwards for us and whatnot? no idea... */
100 return IndexOfEdict(pEdict);
103 static cell_t SetFakeClientConVar(IPluginContext *pContext, const cell_t *params)
105 CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
109 return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
112 if (!pPlayer->IsConnected())
114 return pContext->ThrowNativeError("Client %d is not connected", params[1]);
117 if (!pPlayer->IsFakeClient())
119 return pContext->ThrowNativeError("Client %d is not a fake client", params[1]);
124 pContext->LocalToString(params[2], &cvar);
125 pContext->LocalToString(params[3], &value);
127 engine->SetFakeClientConVarValue(pPlayer->GetEdict(), cvar, value);
132 static cell_t GetGameDescription(IPluginContext *pContext, const cell_t *params)
134 const char *description;
138 description = gamedll->GetGameDescription();
140 description = SERVER_CALL(GetGameDescription)();
145 pContext->StringToLocalUTF8(params[1], params[2], description, &numBytes);
150 static cell_t GetGameFolderName(IPluginContext *pContext, const cell_t *params)
152 const char *name = g_SourceMod.GetGameFolderName();
155 pContext->StringToLocalUTF8(params[1], params[2], name, &numBytes);
160 /* Useless comment to bump the build */
161 static cell_t GetCurrentMap(IPluginContext *pContext, const cell_t *params)
164 pContext->StringToLocalUTF8(params[1], params[2], STRING(gpGlobals->mapname), &bytes);
168 static cell_t PrecacheModel(IPluginContext *pContext, const cell_t *params)
171 pContext->LocalToString(params[1], &model);
173 return engine->PrecacheModel(model, params[2] ? true : false);
176 static cell_t PrecacheSentenceFile(IPluginContext *pContext, const cell_t *params)
179 pContext->LocalToString(params[1], &sentencefile);
181 return engine->PrecacheSentenceFile(sentencefile, params[2] ? true : false);
184 static cell_t PrecacheDecal(IPluginContext *pContext, const cell_t *params)
187 pContext->LocalToString(params[1], &decal);
189 return engine->PrecacheDecal(decal, params[2] ? true : false);
192 static cell_t PrecacheGeneric(IPluginContext *pContext, const cell_t *params)
195 pContext->LocalToString(params[1], &generic);
197 return engine->PrecacheGeneric(generic, params[2] ? true : false);
200 static cell_t IsModelPrecached(IPluginContext *pContext, const cell_t *params)
203 pContext->LocalToString(params[1], &model);
205 return engine->IsModelPrecached(model) ? 1 : 0;
208 static cell_t IsDecalPrecached(IPluginContext *pContext, const cell_t *params)
211 pContext->LocalToString(params[1], &decal);
213 return engine->IsDecalPrecached(decal) ? 1 : 0;
216 static cell_t IsGenericPrecached(IPluginContext *pContext, const cell_t *params)
219 pContext->LocalToString(params[1], &generic);
221 return engine->IsGenericPrecached(generic) ? 1 : 0;
224 static cell_t PrecacheSound(IPluginContext *pContext, const cell_t *params)
227 pContext->LocalToString(params[1], &sample);
229 return enginesound->PrecacheSound(sample, params[2] ? true : false) ? 1 : 0;
232 static cell_t IsSoundPrecached(IPluginContext *pContext, const cell_t *params)
235 pContext->LocalToString(params[1], &sample);
237 return enginesound->IsSoundPrecached(sample) ? 1 : 0;
240 static cell_t smn_CreateDialog(IPluginContext *pContext, const cell_t *params)
244 Handle_t hndl = static_cast<Handle_t>(params[2]);
245 CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
249 return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
252 if (!pPlayer->IsInGame())
254 return pContext->ThrowNativeError("Client %d is not in game", params[1]);
257 pKV = g_SourceMod.ReadKeyValuesHandle(hndl, &herr, true);
258 if (herr != HandleError_None)
260 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
263 serverpluginhelpers->CreateMessage(pPlayer->GetEdict(),
264 static_cast<DIALOG_TYPE>(params[3]),
271 static cell_t PrintToChat(IPluginContext *pContext, const cell_t *params)
273 int client = params[1];
274 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
278 return pContext->ThrowNativeError("Client index %d is invalid", client);
281 if (!pPlayer->IsInGame())
283 return pContext->ThrowNativeError("Client %d is not in game", client);
286 g_SourceMod.SetGlobalTarget(client);
289 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
291 /* Check for an error before printing to the client */
292 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
297 if (!g_HL2.TextMsg(client, HUD_PRINTTALK, buffer))
299 return pContext->ThrowNativeError("Could not send a usermessage");
305 static cell_t PrintCenterText(IPluginContext *pContext, const cell_t *params)
307 int client = params[1];
308 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
312 return pContext->ThrowNativeError("Client index %d is invalid", client);
315 if (!pPlayer->IsInGame())
317 return pContext->ThrowNativeError("Client %d is not in game", client);
320 g_SourceMod.SetGlobalTarget(client);
323 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
325 /* Check for an error before printing to the client */
326 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
331 if (!g_HL2.TextMsg(client, HUD_PRINTCENTER, buffer))
333 return pContext->ThrowNativeError("Could not send a usermessage");
339 static cell_t PrintHintText(IPluginContext *pContext, const cell_t *params)
341 int client = params[1];
342 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
346 return pContext->ThrowNativeError("Client index %d is invalid", client);
349 if (!pPlayer->IsInGame())
351 return pContext->ThrowNativeError("Client %d is not in game", client);
354 g_SourceMod.SetGlobalTarget(client);
357 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
359 /* Check for an error before printing to the client */
360 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
365 if (!g_HL2.HintTextMsg(client, buffer))
367 return pContext->ThrowNativeError("Could not send a usermessage");
373 static cell_t ShowVGUIPanel(IPluginContext *pContext, const cell_t *params)
377 KeyValues *pKV = NULL;
378 int client = params[1];
379 Handle_t hndl = static_cast<Handle_t>(params[3]);
380 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
384 return pContext->ThrowNativeError("Client index %d is invalid", client);
387 if (!pPlayer->IsInGame())
389 return pContext->ThrowNativeError("Client %d is not in game", client);
392 if (hndl != BAD_HANDLE)
394 pKV = g_SourceMod.ReadKeyValuesHandle(hndl, &herr, true);
395 if (herr != HandleError_None)
397 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
401 pContext->LocalToString(params[2], &name);
403 if (!g_HL2.ShowVGUIMenu(client, name, pKV, (params[4]) ? true : false))
405 return pContext->ThrowNativeError("Could not send a usermessage");
411 static cell_t smn_IsPlayerAlive(IPluginContext *pContext, const cell_t *params)
413 CPlayer *player = g_Players.GetPlayerByIndex(params[1]);
416 return pContext->ThrowNativeError("Invalid client index %d", params[1]);
418 else if (!player->IsInGame())
420 return pContext->ThrowNativeError("Client %d is not in game", params[1]);
423 unsigned int state = player->GetLifeState();
425 if (state == PLAYER_LIFE_UNKNOWN)
427 return pContext->ThrowNativeError("\"IsPlayerAlive\" not supported by this mod");
429 else if (state == PLAYER_LIFE_ALIVE)
439 static cell_t GuessSDKVersion(IPluginContext *pContext, const cell_t *params)
441 #if defined METAMOD_PLAPI_VERSION
442 int version = g_SMAPI->GetSourceEngineBuild();
444 if (version == SOURCE_ENGINE_ORIGINAL)
448 else if (version == SOURCE_ENGINE_DARKMESSIAH)
452 else if (version == SOURCE_ENGINE_EPISODEONE)
456 else if (version == SOURCE_ENGINE_ORANGEBOX)
461 if (g_HL2.IsOriginalEngine())
474 REGISTER_NATIVES(halflifeNatives)
476 {"CreateFakeClient", CreateFakeClient},
477 {"GetCurrentMap", GetCurrentMap},
478 {"GetEngineTime", GetEngineTime},
479 {"GetGameDescription", GetGameDescription},
480 {"GetGameFolderName", GetGameFolderName},
481 {"GetGameTime", GetGameTime},
482 {"GetRandomFloat", GetRandomFloat},
483 {"GetRandomInt", GetRandomInt},
484 {"IsDedicatedServer", IsDedicatedServer},
485 {"IsMapValid", IsMapValid},
486 {"SetFakeClientConVar", SetFakeClientConVar},
487 {"SetRandomSeed", SetRandomSeed},
488 {"PrecacheModel", PrecacheModel},
489 {"PrecacheSentenceFile", PrecacheSentenceFile},
490 {"PrecacheDecal", PrecacheDecal},
491 {"PrecacheGeneric", PrecacheGeneric},
492 {"IsModelPrecached", IsModelPrecached},
493 {"IsDecalPrecached", IsDecalPrecached},
494 {"IsGenericPrecached", IsGenericPrecached},
495 {"PrecacheSound", PrecacheSound},
496 {"IsSoundPrecached", IsSoundPrecached},
497 {"CreateDialog", smn_CreateDialog},
498 {"PrintToChat", PrintToChat},
499 {"PrintCenterText", PrintCenterText},
500 {"PrintHintText", PrintHintText},
501 {"ShowVGUIPanel", ShowVGUIPanel},
502 {"IsPlayerAlive", smn_IsPlayerAlive},
503 {"GuessSDKVersion", GuessSDKVersion},