diff --git a/extensions/sdktools/Makefile b/extensions/sdktools/Makefile
index 3023bc40..eb92d33c 100644
--- a/extensions/sdktools/Makefile
+++ b/extensions/sdktools/Makefile
@@ -14,9 +14,9 @@ PROJECT = sdktools
#Uncomment for SourceMM-enabled extensions
LINK_HL2 = $(HL2LIB)/tier1_i486.a $(HL2LIB)/mathlib_i486.a vstdlib_i486.so tier0_i486.so
-OBJECTS = sdk/smsdk_ext.cpp extension.cpp gamerules.cpp vdecoder.cpp vcallbuilder.cpp \
- vcaller.cpp vnatives.cpp vsound.cpp tenatives.cpp trnatives.cpp tempents.cpp vstringtable.cpp \
- vhelpers.cpp voice.cpp
+OBJECTS = sdk/smsdk_ext.cpp extension.cpp vdecoder.cpp vcallbuilder.cpp vcaller.cpp \
+ vnatives.cpp vsound.cpp tenatives.cpp trnatives.cpp tempents.cpp vstringtable.cpp \
+ vhelpers.cpp vglobals.cpp voice.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
diff --git a/extensions/sdktools/extension.cpp b/extensions/sdktools/extension.cpp
index ea11b22c..eae9bd95 100644
--- a/extensions/sdktools/extension.cpp
+++ b/extensions/sdktools/extension.cpp
@@ -34,8 +34,8 @@
#include "vcallbuilder.h"
#include "vnatives.h"
#include "vhelpers.h"
+#include "vglobals.h"
#include "tempents.h"
-#include "gamerules.h"
/**
* @file extension.cpp
@@ -52,10 +52,10 @@ IBinTools *g_pBinTools = NULL;
IGameConfig *g_pGameConf = NULL;
IGameHelpers *g_pGameHelpers = NULL;
IServerGameClients *serverClients = NULL;
+IVoiceServer *voiceserver = NULL;
IPlayerInfoManager *playerinfomngr = NULL;
HandleType_t g_CallHandle = 0;
HandleType_t g_TraceHandle = 0;
-IVoiceServer *voiceserver = NULL;
SMEXT_LINK(&g_SdkTools);
@@ -143,7 +143,7 @@ void SDKTools::SDK_OnAllLoaded()
SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
g_TEManager.Initialize();
- InitializeGameRules();
+ InitializeValveGlobals();
}
bool SDKTools::QueryRunning(char *error, size_t maxlength)
diff --git a/extensions/sdktools/gamerules.h b/extensions/sdktools/gamerules.h
deleted file mode 100644
index e39801b2..00000000
--- a/extensions/sdktools/gamerules.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * vim: set ts=4 :
- * ================================================================
- * SourceMod SDKTools Extension
- * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
- * ================================================================
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License,
- * version 3.0, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- * As a special exception, AlliedModders LLC gives you permission to
- * link the code of this program (as well as its derivative works) to
- * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any
- * Game MODs that run on software by the Valve Corporation. You must
- * obey the GNU General Public License in all respects for all other
- * code used. Additionally, AlliedModders LLC grants this exception
- * to all derivative works. AlliedModders LLC defines further
- * exceptions, found in LICENSE.txt (as of this writing, version
- * JULY-31-2007), or .
- *
- * Version: $Id$
- */
-
-#ifndef _INCLUDE_SDKTOOLS_GAMERULES_H_
-#define _INCLUDE_SDKTOOLS_GAMERULES_H_
-
-extern void **g_pGameRules;
-
-void InitializeGameRules();
-
-#endif // _INCLUDE_SDKTOOLS_GAMERULES_H_
diff --git a/extensions/sdktools/msvc8/sdktools.vcproj b/extensions/sdktools/msvc8/sdktools.vcproj
index ba77f491..b218dd4f 100644
--- a/extensions/sdktools/msvc8/sdktools.vcproj
+++ b/extensions/sdktools/msvc8/sdktools.vcproj
@@ -187,10 +187,6 @@
RelativePath="..\extension.cpp"
>
-
-
@@ -215,6 +211,10 @@
RelativePath="..\vdecoder.cpp"
>
+
+
@@ -249,10 +249,6 @@
RelativePath="..\extension.h"
>
-
-
@@ -265,6 +261,10 @@
RelativePath="..\vdecoder.h"
>
+
+
diff --git a/extensions/sdktools/vcallbuilder.cpp b/extensions/sdktools/vcallbuilder.cpp
index 15ea6444..7288ba4e 100644
--- a/extensions/sdktools/vcallbuilder.cpp
+++ b/extensions/sdktools/vcallbuilder.cpp
@@ -156,10 +156,11 @@ ValveCall *CreateValveCall(void *addr,
thisinfo->flags = PASSFLAG_BYVAL;
thisinfo->decflags = 0;
break;
- case ValveCall_GameRules:
+ default:
thisinfo->vtype = Valve_POD;
thisinfo->flags = PASSFLAG_ASPOINTER;
thisinfo->decflags = 0;
+ break;
}
thisinfo->encflags = 0;
thisinfo->offset = 0;
@@ -340,7 +341,7 @@ ValveCall *CreateValveVCall(unsigned int vtableIdx,
vc->thisinfo->flags = PASSFLAG_BYVAL;
vc->thisinfo->decflags = 0;
break;
- case ValveCall_GameRules:
+ default:
vc->thisinfo->vtype = Valve_POD;
vc->thisinfo->flags = PASSFLAG_ASPOINTER;
vc->thisinfo->decflags = 0;
diff --git a/extensions/sdktools/vcaller.cpp b/extensions/sdktools/vcaller.cpp
index 5d0453dc..df7c38f6 100644
--- a/extensions/sdktools/vcaller.cpp
+++ b/extensions/sdktools/vcaller.cpp
@@ -32,7 +32,7 @@
#include "extension.h"
#include "vcallbuilder.h"
-#include "gamerules.h"
+#include "vglobals.h"
enum SDKLibrary
{
@@ -296,6 +296,17 @@ static cell_t SDKCall(IPluginContext *pContext, const cell_t *params)
*(void **)ptr = gamerules;
}
break;
+ case ValveCall_EntityList:
+ {
+ if (g_EntList == NULL)
+ {
+ vc->stk_put(ptr);
+ return pContext->ThrowNativeError("EntityList unsupported or not available; file a bug report");
+ }
+
+ *(void **)ptr = g_EntList;
+ }
+ break;
}
}
diff --git a/extensions/sdktools/vdecoder.h b/extensions/sdktools/vdecoder.h
index 4934f22b..34116d05 100644
--- a/extensions/sdktools/vdecoder.h
+++ b/extensions/sdktools/vdecoder.h
@@ -80,6 +80,7 @@ enum ValveCallType
ValveCall_Entity, /**< Thiscall (CBaseEntity implicit first parameter) */
ValveCall_Player, /**< Thiscall (CBasePlayer implicit first parameter) */
ValveCall_GameRules, /**< Thiscall (CGameRules implicit first paramater) */
+ ValveCall_EntityList, /**< Thiscall (CGlobalEntityList implicit first paramater) */
};
/**
diff --git a/extensions/sdktools/gamerules.cpp b/extensions/sdktools/vglobals.cpp
similarity index 51%
rename from extensions/sdktools/gamerules.cpp
rename to extensions/sdktools/vglobals.cpp
index 848754ec..35dcb58d 100644
--- a/extensions/sdktools/gamerules.cpp
+++ b/extensions/sdktools/vglobals.cpp
@@ -1,46 +1,38 @@
-/**
- * vim: set ts=4 :
- * ================================================================
- * SourceMod SDKTools Extension
- * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
- * ================================================================
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License,
- * version 3.0, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- * As a special exception, AlliedModders LLC gives you permission to
- * link the code of this program (as well as its derivative works) to
- * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any
- * Game MODs that run on software by the Valve Corporation. You must
- * obey the GNU General Public License in all respects for all other
- * code used. Additionally, AlliedModders LLC grants this exception
- * to all derivative works. AlliedModders LLC defines further
- * exceptions, found in LICENSE.txt (as of this writing, version
- * JULY-31-2007), or .
- *
- * Version: $Id$
+/**
+ * vim: set ts=4 :
+ * ===============================================================
+ * SourceMod SDK Tools Extension
+ * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
+ * ===============================================================
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Version: $Id$
*/
#include "extension.h"
void **g_pGameRules = NULL;
-
-void InitializeGameRules()
-{
- char *addr = NULL;
+void *g_EntList = NULL;
#ifdef PLATFORM_WINDOWS
- int offset = 0;
+void InitializeValveGlobals()
+{
+ char *addr = NULL;
+ int offset;
+ /* g_pGameRules */
if (!g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) || !addr)
{
return;
@@ -49,14 +41,36 @@ void InitializeGameRules()
{
return;
}
-
g_pGameRules = *reinterpret_cast(addr + offset);
+
+ /* gEntList and/or g_pEntityList */
+ if (!g_pGameConf->GetMemSig("LevelShutdown", (void **)&addr) || !addr)
+ {
+ return;
+ }
+ if (!g_pGameConf->GetOffset("gEntList", &offset) || !offset)
+ {
+ return;
+ }
+ g_EntList = *reinterpret_cast(addr + offset);
+}
#elif defined PLATFORM_LINUX
+void InitializeValveGlobals()
+{
+ char *addr = NULL;
+
+ /* g_pGameRules */
if (!g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) || !addr)
{
return;
}
-
g_pGameRules = reinterpret_cast(addr);
-#endif
+
+ /* gEntList and/or g_pEntityList */
+ if (!g_pGameConf->GetMemSig("gEntList", (void **)&addr) || !addr)
+ {
+ return;
+ }
+ g_EntList = reinterpret_cast(addr);
}
+#endif
diff --git a/extensions/sdktools/vglobals.h b/extensions/sdktools/vglobals.h
new file mode 100644
index 00000000..0b26c59a
--- /dev/null
+++ b/extensions/sdktools/vglobals.h
@@ -0,0 +1,32 @@
+/**
+ * vim: set ts=4 :
+ * ===============================================================
+ * SourceMod SDK Tools Extension
+ * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
+ * ===============================================================
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Version: $Id$
+ */
+
+#ifndef _INCLUDE_SDKTOOLS_VGLOBALS_H_
+#define _INCLUDE_SDKTOOLS_VGLOBALS_H_
+
+extern void **g_pGameRules;
+extern void *g_EntList;
+
+void InitializeValveGlobals();
+
+#endif // _INCLUDE_SDKTOOLS_VGLOBALS_H_
diff --git a/extensions/sdktools/vnatives.cpp b/extensions/sdktools/vnatives.cpp
index 13e3e277..ad9e8ed7 100644
--- a/extensions/sdktools/vnatives.cpp
+++ b/extensions/sdktools/vnatives.cpp
@@ -36,6 +36,7 @@
#include "vcallbuilder.h"
#include "vnatives.h"
#include "vhelpers.h"
+#include "vglobals.h"
#include "CellRecipientFilter.h"
List g_RegCalls;
@@ -212,7 +213,7 @@ static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params
return engine->IndexOfEdict(pEdict);
}
-static cell_t IgnitePlayer(IPluginContext *pContext, const cell_t *params)
+static cell_t IgniteEntity(IPluginContext *pContext, const cell_t *params)
{
static ValveCall *pCall = NULL;
if (!pCall)
@@ -241,7 +242,7 @@ static cell_t IgnitePlayer(IPluginContext *pContext, const cell_t *params)
return 1;
}
-static cell_t ExtinguishPlayer(IPluginContext *pContext, const cell_t *params)
+static cell_t ExtinguishEntity(IPluginContext *pContext, const cell_t *params)
{
static ValveCall *pCall = NULL;
if (!pCall)
@@ -261,7 +262,7 @@ static cell_t ExtinguishPlayer(IPluginContext *pContext, const cell_t *params)
return 1;
}
-static cell_t TeleportPlayer(IPluginContext *pContext, const cell_t *params)
+static cell_t TeleportEntity(IPluginContext *pContext, const cell_t *params)
{
static ValveCall *pCall = NULL;
if (!pCall)
@@ -564,6 +565,44 @@ static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params)
return 1;
}
+static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params)
+{
+ static ValveCall *pCall = NULL;
+ if (!pCall)
+ {
+ ValvePassInfo pass[3];
+ InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL|VDECODE_FLAG_ALLOWWORLD);
+ InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
+ InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
+ if (!CreateBaseCall("FindEntityByClassname", ValveCall_EntityList, &pass[2], pass, 2, &pCall))
+ {
+ return pContext->ThrowNativeError("\"FindEntityByClassname\" not supported by this mod");
+ } else if (!pCall) {
+ return pContext->ThrowNativeError("\"FindEntityByClassname\" wrapper failed to initialized");
+ }
+ }
+
+ CBaseEntity *pEntity;
+ START_CALL();
+ *(void **)vptr = g_EntList;
+ DECODE_VALVE_PARAM(1, vparams, 0);
+ DECODE_VALVE_PARAM(2, vparams, 1);
+ FINISH_CALL_SIMPLE(&pEntity);
+
+ if (pEntity == NULL)
+ {
+ return -1;
+ }
+
+ edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
+ if (!pEdict)
+ {
+ return -1;
+ }
+
+ return engine->IndexOfEdict(pEdict);
+}
+
static cell_t IsPlayerAlive(IPluginContext *pContext, const cell_t *params)
{
IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
@@ -600,21 +639,22 @@ static cell_t IsPlayerAlive(IPluginContext *pContext, const cell_t *params)
sp_nativeinfo_t g_Natives[] =
{
- {"ExtinguishPlayer", ExtinguishPlayer},
- {"ExtinguishEntity", ExtinguishPlayer},
+ {"ExtinguishPlayer", ExtinguishEntity},
+ {"ExtinguishEntity", ExtinguishEntity},
{"ForcePlayerSuicide", ForcePlayerSuicide},
{"GivePlayerItem", GiveNamedItem},
{"GetPlayerWeaponSlot", GetPlayerWeaponSlot},
- {"IgnitePlayer", IgnitePlayer},
- {"IgniteEntity", IgnitePlayer},
+ {"IgnitePlayer", IgniteEntity},
+ {"IgniteEntity", IgniteEntity},
{"RemovePlayerItem", RemovePlayerItem},
- {"TeleportPlayer", TeleportPlayer},
- {"TeleportEntity", TeleportPlayer},
+ {"TeleportPlayer", TeleportEntity},
+ {"TeleportEntity", TeleportEntity},
{"SetClientViewEntity", SetClientViewEntity},
{"SetLightStyle", SetLightStyle},
{"SlapPlayer", SlapPlayer},
{"GetClientEyePosition", GetClientEyePosition},
{"GetClientEyeAngles", GetClientEyeAngles},
+ {"FindEntityByClassname", FindEntityByClassname},
{"IsPlayerAlive", IsPlayerAlive},
{NULL, NULL},
};
diff --git a/gamedata/sdktools.games.txt b/gamedata/sdktools.games.txt
index 81cc68f9..d9e1910d 100644
--- a/gamedata/sdktools.games.txt
+++ b/gamedata/sdktools.games.txt
@@ -124,6 +124,53 @@
}
}
}
+
+ /* CGlobalEntityList */
+ "#default"
+ {
+ "#supported"
+ {
+ "game" "cstrike"
+ "game" "dod"
+ "game" "garrysmod"
+ "game" "hl2mp"
+ "game" "ship"
+ "game" "!Insurgency"
+ "game" "!Pirates, Vikings and Knights II"
+ "game" "!SourceForts v1.9.2"
+ }
+
+ "Offsets"
+ {
+ /* Offset into LevelShutdown */
+ "gEntList"
+ {
+ "windows" "11"
+ }
+ }
+
+ "Signatures"
+ {
+ "LevelShutdown"
+ {
+ "library" "server"
+ "windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
+ }
+ "gEntList"
+ {
+ "library" "server"
+ "linux" "@gEntList"
+ }
+
+ /* Functions in CGlobalEntityList */
+ "FindEntityByClassname"
+ {
+ "library" "server"
+ "windows" "\x53\x55\x56\x8B\xF1\x8B\x4C\x24\x2A\x85\xC9\x57\x74\x2A\x8B\x01\xFF\x50\x2A\x8B\x08\x81\xE1\x2A\x2A\x2A\x2A\x83\xC1\x2A\xC1\xE1\x2A\x8B\x3C\x31\xEB\x2A\x8B\xBE\x2A\x2A\x2A\x2A\x85\xFF\x74\x2A\x8B\x5C\x24\x2A\x8B\x2D\x2A\x2A\x2A\x2A\x8D\x9B\x00\x00\x00\x00\x8B\x37\x85\xF6\x75\x2A\x68\x2A\x2A\x2A\x2A\xFF\x2A\x83\xC4\x2A\xEB\x2A\x39"
+ "linux" "@_ZN17CGlobalEntityList21FindEntityByClassnameEP11CBaseEntityPKc"
+ }
+ }
+ }
/* Counter-Strike: Source */
"cstrike"
diff --git a/plugins/include/sdktools.inc b/plugins/include/sdktools.inc
index 272e5194..8664b91b 100644
--- a/plugins/include/sdktools.inc
+++ b/plugins/include/sdktools.inc
@@ -36,6 +36,7 @@ enum SDKCallType
SDKCall_Entity, /**< CBaseEntity call */
SDKCall_Player, /**< CBasePlayer call */
SDKCall_GameRules, /**< CGameRules call */
+ SDKCall_EntityList, /**< CGlobalEntityList call */
};
enum SDKLibrary
diff --git a/plugins/include/sdktools_functions.inc b/plugins/include/sdktools_functions.inc
index 6f2b8c55..f5687287 100644
--- a/plugins/include/sdktools_functions.inc
+++ b/plugins/include/sdktools_functions.inc
@@ -104,6 +104,17 @@ native ForcePlayerSuicide(client);
*/
native SlapPlayer(client, health=5, bool:sound=true);
+/**
+ * Searches for an entity by classname.
+ *
+ * @param startEnt The entity index to begin searching from.
+ * Use -1 to start from the first entity.
+ * @param classname Classname of the entity to find.
+ * @return Entity index >= 0 if found, -1 otherwise.
+ * @error Lack of mod support.
+ */
+native FindEntityByClassname(startEnt, const String:classname[]);
+
/**
* Returns the client's eye angles.
*