From 64f9aedebc1b684ccf34a44fcddd6df4b0bb7322 Mon Sep 17 00:00:00 2001
From: Nicholas Hastings <nshastings@gmail.com>
Date: Wed, 6 May 2015 21:12:13 -0400
Subject: [PATCH 1/5] Add basic support for Black Mesa.

(Basically a copy of SDK 2013's support, but against BMS SDK).
---
 AMBuildScript                              | 35 +++++++++++-----------
 core/HalfLife2.cpp                         | 14 +++++----
 core/MenuStyle_Base.cpp                    |  3 +-
 core/logic_bridge.cpp                      |  5 ++++
 core/smn_entities.cpp                      | 12 +++++---
 core/smn_halflife.cpp                      |  1 +
 extensions/sdkhooks/extension.cpp          |  9 ++++--
 extensions/sdkhooks/extension.h            |  3 +-
 extensions/sdkhooks/takedamageinfohack.cpp |  3 +-
 extensions/sdktools/tempents.cpp           | 11 +++----
 extensions/sdktools/vcaller.cpp            |  1 +
 extensions/sdktools/vglobals.cpp           |  9 +++---
 extensions/sdktools/vhelpers.cpp           | 24 ++++++++-------
 extensions/sdktools/vnatives.cpp           |  4 ++-
 extensions/sdktools/vsound.cpp             | 24 ++++++++++-----
 extensions/sdktools/vsound.h               |  5 ++--
 loader/loader.cpp                          |  6 ++++
 plugins/include/halflife.inc               |  1 +
 tools/checkout-deps.sh                     |  2 +-
 19 files changed, 108 insertions(+), 64 deletions(-)

diff --git a/AMBuildScript b/AMBuildScript
index fd5ea381..a02779f9 100644
--- a/AMBuildScript
+++ b/AMBuildScript
@@ -23,20 +23,21 @@ PossibleSDKs = {
   'hl2dm':  SDK('HL2SDKHL2DM', '2.hl2dm', '7', 'HL2DM', WinLinuxMac, 'hl2dm'),
   'dods': SDK('HL2SDKDODS', '2.dods', '8', 'DODS', WinLinuxMac, 'dods'),
   'sdk2013': SDK('HL2SDK2013', '2.sdk2013', '9', 'SDK2013', WinLinuxMac, 'sdk2013'),
-  'tf2':  SDK('HL2SDKTF2', '2.tf2', '10', 'TF2', WinLinuxMac, 'tf2'),
-  'l4d':  SDK('HL2SDKL4D', '2.l4d', '11', 'LEFT4DEAD', WinLinuxMac, 'l4d'),
-  'nucleardawn': SDK('HL2SDKND', '2.nd', '12', 'NUCLEARDAWN', WinLinuxMac, 'nucleardawn'),
-  'l4d2': SDK('HL2SDKL4D2', '2.l4d2', '14', 'LEFT4DEAD2', WinLinuxMac, 'l4d2'),
+  'tf2':  SDK('HL2SDKTF2', '2.tf2', '11', 'TF2', WinLinuxMac, 'tf2'),
+  'l4d':  SDK('HL2SDKL4D', '2.l4d', '12', 'LEFT4DEAD', WinLinuxMac, 'l4d'),
+  'nucleardawn': SDK('HL2SDKND', '2.nd', '13', 'NUCLEARDAWN', WinLinuxMac, 'nucleardawn'),
+  'l4d2': SDK('HL2SDKL4D2', '2.l4d2', '15', 'LEFT4DEAD2', WinLinuxMac, 'l4d2'),
   'darkm':  SDK('HL2SDK-DARKM', '2.darkm', '2', 'DARKMESSIAH', WinOnly, 'darkm'),
-  'swarm':  SDK('HL2SDK-SWARM', '2.swarm', '15', 'ALIENSWARM', WinOnly, 'swarm'),
+  'swarm':  SDK('HL2SDK-SWARM', '2.swarm', '16', 'ALIENSWARM', WinOnly, 'swarm'),
   'bgt':  SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'),
   'eye':  SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'),
-  'csgo': SDK('HL2SDKCSGO', '2.csgo', '19', 'CSGO', WinLinuxMac, 'csgo'),
-  'dota': SDK('HL2SDKDOTA', '2.dota', '20', 'DOTA', WinLinuxMac, 'dota'),
-  'portal2':  SDK('HL2SDKPORTAL2', '2.portal2', '16', 'PORTAL2', [], 'portal2'),
-  'blade':  SDK('HL2SDKBLADE', '2.blade', '17', 'BLADE', WinLinux, 'blade'),
-  'insurgency':  SDK('HL2SDKINSURGENCY', '2.insurgency', '18', 'INSURGENCY', WinLinuxMac, 'insurgency'),
-  'contagion':  SDK('HL2SDKCONTAGION', '2.contagion', '13', 'CONTAGION', WinOnly, 'contagion'),
+  'csgo': SDK('HL2SDKCSGO', '2.csgo', '20', 'CSGO', WinLinuxMac, 'csgo'),
+  'dota': SDK('HL2SDKDOTA', '2.dota', '21', 'DOTA', WinLinuxMac, 'dota'),
+  'portal2':  SDK('HL2SDKPORTAL2', '2.portal2', '17', 'PORTAL2', [], 'portal2'),
+  'blade':  SDK('HL2SDKBLADE', '2.blade', '18', 'BLADE', WinLinux, 'blade'),
+  'insurgency':  SDK('HL2SDKINSURGENCY', '2.insurgency', '19', 'INSURGENCY', WinLinuxMac, 'insurgency'),
+  'contagion':  SDK('HL2SDKCONTAGION', '2.contagion', '14', 'CONTAGION', WinOnly, 'contagion'),
+  'bms':  SDK('HL2SDKBMS', '2.bms', '10', 'BMS', WinLinux, 'bms'),
 }
 
 def ResolveEnvPath(env, folder):
@@ -377,7 +378,7 @@ class SMConfig(object):
 
     compiler.defines += ['SOURCE_ENGINE=' + sdk.code]
 
-    if sdk.name == 'sdk2013' and compiler.like('gcc'):
+    if sdk.name in ['sdk2013', 'bms'] and compiler.like('gcc'):
       # The 2013 SDK already has these in public/tier0/basetypes.h
       compiler.defines.remove('stricmp=strcasecmp')
       compiler.defines.remove('_stricmp=strcasecmp')
@@ -394,7 +395,7 @@ class SMConfig(object):
     if sdk.name in ['blade', 'insurgency', 'csgo', 'dota']:
       compiler.defines += ['NETWORK_VARS_ENABLED']
 
-    if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'tf2', 'l4d', 'nucleardawn', 'l4d2', 'dota']:
+    if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'bms', 'tf2', 'l4d', 'nucleardawn', 'l4d2', 'dota']:
       if builder.target_platform in ['linux', 'mac']:
         compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE']
 
@@ -407,18 +408,18 @@ class SMConfig(object):
     if builder.target_platform == 'linux':
       if sdk.name == 'episode1':
         lib_folder = os.path.join(sdk.path, 'linux_sdk')
-      elif sdk.name == 'sdk2013':
+      elif sdk.name in ['sdk2013', 'bms']:
         lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32')
       else:
         lib_folder = os.path.join(sdk.path, 'lib', 'linux')
     elif builder.target_platform == 'mac':
-      if sdk.name == 'sdk2013':
+      if sdk.name in ['sdk2013', 'bms']:
         lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32')
       else:
         lib_folder = os.path.join(sdk.path, 'lib', 'mac')
 
     if builder.target_platform in ['linux', 'mac']:
-      if sdk.name == 'sdk2013':
+      if sdk.name in ['sdk2013', 'bms']:
         compiler.postlink += [
           compiler.Dep(os.path.join(lib_folder, 'tier1.a')),
           compiler.Dep(os.path.join(lib_folder, 'mathlib.a'))
@@ -437,7 +438,7 @@ class SMConfig(object):
     dynamic_libs = []
     if builder.target_platform == 'linux':
       compiler.linkflags[0:0] = ['-lm']
-      if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'nucleardawn', 'l4d2']:
+      if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'bms', 'nucleardawn', 'l4d2']:
         dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so']
       elif sdk.name in ['l4d', 'blade', 'insurgency', 'csgo', 'dota']:
         dynamic_libs = ['libtier0.so', 'libvstdlib.so']
diff --git a/core/HalfLife2.cpp b/core/HalfLife2.cpp
index d52bc6fa..aff756f1 100644
--- a/core/HalfLife2.cpp
+++ b/core/HalfLife2.cpp
@@ -59,7 +59,8 @@ typedef ICommandLine *(*FakeGetCommandLine)();
 #define VSTDLIB_NAME		"libvstdlib.dylib"
 #elif defined __linux__
 #if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
-	|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_LEFT4DEAD2 || SOURCE_ENGINE == SE_NUCLEARDAWN
+	|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_LEFT4DEAD2 || SOURCE_ENGINE == SE_NUCLEARDAWN \
+	|| SOURCE_ENGINE == SE_BMS
 #define TIER0_NAME			"libtier0_srv.so"
 #define VSTDLIB_NAME		"libvstdlib_srv.so"
 #elif SOURCE_ENGINE >= SE_LEFT4DEAD
@@ -153,11 +154,12 @@ void CHalfLife2::OnSourceModAllInitialized_Post()
 
 void CHalfLife2::InitLogicalEntData()
 {
-#if SOURCE_ENGINE == SE_TF2      \
-	|| SOURCE_ENGINE == SE_DODS  \
-	|| SOURCE_ENGINE == SE_HL2DM \
-	|| SOURCE_ENGINE == SE_CSS   \
-	|| SOURCE_ENGINE == SE_SDK2013
+#if SOURCE_ENGINE == SE_TF2        \
+	|| SOURCE_ENGINE == SE_DODS    \
+	|| SOURCE_ENGINE == SE_HL2DM   \
+	|| SOURCE_ENGINE == SE_CSS     \
+	|| SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS
 
 	if (g_SMAPI->GetServerFactory(false)("VSERVERTOOLS003", nullptr))
 	{
diff --git a/core/MenuStyle_Base.cpp b/core/MenuStyle_Base.cpp
index cda17be8..415029c1 100644
--- a/core/MenuStyle_Base.cpp
+++ b/core/MenuStyle_Base.cpp
@@ -338,7 +338,8 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
 #endif
 							0, 
 							PITCH_NORM, 
-#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS \
+	|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 							0,
 #endif
 							&pos);
diff --git a/core/logic_bridge.cpp b/core/logic_bridge.cpp
index 8fc82e53..bec62764 100644
--- a/core/logic_bridge.cpp
+++ b/core/logic_bridge.cpp
@@ -373,6 +373,8 @@ static const char *get_source_engine_name()
 	return "dods";
 #elif SOURCE_ENGINE == SE_SDK2013
 	return "sdk2013";
+#elif SOURCE_ENGINE == SE_BMS
+	return "bms";
 #elif SOURCE_ENGINE == SE_TF2
 	return "tf2";
 #elif SOURCE_ENGINE == SE_LEFT4DEAD
@@ -404,6 +406,7 @@ static bool symbols_are_hidden()
 	|| (SOURCE_ENGINE == SE_HL2DM)       \
 	|| (SOURCE_ENGINE == SE_DODS)        \
 	|| (SOURCE_ENGINE == SE_SDK2013)     \
+	|| (SOURCE_ENGINE == SE_BMS)         \
 	|| (SOURCE_ENGINE == SE_TF2)         \
 	|| (SOURCE_ENGINE == SE_LEFT4DEAD)   \
 	|| (SOURCE_ENGINE == SE_NUCLEARDAWN) \
@@ -540,6 +543,8 @@ void do_global_plugin_loads()
 #define GAMEFIX "2.dods"
 #elif SOURCE_ENGINE == SE_SDK2013
 #define GAMEFIX "2.sdk2013"
+#elif SOURCE_ENGINE == SE_BMS
+#define GAMEFIX "2.bms"
 #elif SOURCE_ENGINE == SE_TF2
 #define GAMEFIX "2.tf2"
 #elif SOURCE_ENGINE == SE_DARKMESSIAH
diff --git a/core/smn_entities.cpp b/core/smn_entities.cpp
index d7d99b4b..37a9848c 100644
--- a/core/smn_entities.cpp
+++ b/core/smn_entities.cpp
@@ -1254,7 +1254,8 @@ static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
 			is_unsigned = ((pProp->GetFlags() & SPROP_UNSIGNED) == SPROP_UNSIGNED);
 
 			// This isn't in CS:S yet, but will be, doesn't hurt to add now, and will save us a build later
-#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
 			if (pProp->GetFlags() & SPROP_VARINT)
 			{
 				bit_count = sizeof(int) * 8;
@@ -1352,7 +1353,8 @@ static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
 			FIND_PROP_SEND(DPT_Int, "integer");
 
 			// This isn't in CS:S yet, but will be, doesn't hurt to add now, and will save us a build later
-#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
 			if (pProp->GetFlags() & SPROP_VARINT)
 			{
 				bit_count = sizeof(int) * 8;
@@ -2156,7 +2158,8 @@ static int32_t SDKEntFlagToSMEntFlag(int flag)
 #if SOURCE_ENGINE == SE_ALIENSWARM
 		case FL_FREEZING:
 			return ENTFLAG_FREEZING;
-#elif SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
+#elif SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
 		case FL_EP2V_UNKNOWN:
 			return ENTFLAG_EP2V_UNKNOWN1;
 #endif
@@ -2234,7 +2237,8 @@ static int32_t SMEntFlagToSDKEntFlag(int32_t flag)
 #if SOURCE_ENGINE == SE_ALIENSWARM
 		case ENTFLAG_FREEZING:
 			return FL_FREEZING;
-#elif SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
+#elif SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
 		case ENTFLAG_EP2V_UNKNOWN1:
 			return FL_EP2V_UNKNOWN;
 #endif
diff --git a/core/smn_halflife.cpp b/core/smn_halflife.cpp
index d8e02507..b9de4e6a 100644
--- a/core/smn_halflife.cpp
+++ b/core/smn_halflife.cpp
@@ -498,6 +498,7 @@ static cell_t GuessSDKVersion(IPluginContext *pContext, const cell_t *params)
 	case SOURCE_ENGINE_HL2DM:
 	case SOURCE_ENGINE_DODS:
 	case SOURCE_ENGINE_TF2:
+	case SOURCE_ENGINE_BMS:
 	case SOURCE_ENGINE_SDK2013:
 		return 35;
 	case SOURCE_ENGINE_LEFT4DEAD:
diff --git a/extensions/sdkhooks/extension.cpp b/extensions/sdkhooks/extension.cpp
index 82d977b1..d0a0261d 100644
--- a/extensions/sdkhooks/extension.cpp
+++ b/extensions/sdkhooks/extension.cpp
@@ -184,7 +184,8 @@ SH_DECL_MANUALHOOK0_void(Spawn, 0, 0, 0);
 SH_DECL_MANUALHOOK1_void(StartTouch, 0, 0, 0, CBaseEntity *);
 SH_DECL_MANUALHOOK0_void(Think, 0, 0, 0);
 SH_DECL_MANUALHOOK1_void(Touch, 0, 0, 0, CBaseEntity *);
-#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
+#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_SDK2013
 SH_DECL_MANUALHOOK4_void(TraceAttack, 0, 0, 0, CTakeDamageInfoHack &, const Vector &, CGameTrace *, CDmgAccumulator *);
 #else
 SH_DECL_MANUALHOOK3_void(TraceAttack, 0, 0, 0, CTakeDamageInfoHack &, const Vector &, CGameTrace *);
@@ -1391,7 +1392,8 @@ void SDKHooks::Hook_TouchPost(CBaseEntity *pOther)
 	RETURN_META(MRES_IGNORED);
 }
 
-#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
+#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_SDK2013
 void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator)
 #else
 void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr)
@@ -1471,7 +1473,8 @@ void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir,
 	RETURN_META(MRES_IGNORED);
 }
 
-#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
+#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_SDK2013
 void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator)
 #else
 void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr)
diff --git a/extensions/sdkhooks/extension.h b/extensions/sdkhooks/extension.h
index 7beb86ab..62745ae9 100644
--- a/extensions/sdkhooks/extension.h
+++ b/extensions/sdkhooks/extension.h
@@ -313,7 +313,8 @@ public:
 	void Hook_ThinkPost();
 	void Hook_Touch(CBaseEntity *pOther);
 	void Hook_TouchPost(CBaseEntity *pOther);
-#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
+#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_SDK2013
 	void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
 	void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
 #else
diff --git a/extensions/sdkhooks/takedamageinfohack.cpp b/extensions/sdkhooks/takedamageinfohack.cpp
index 5e5a6300..ef71b46f 100644
--- a/extensions/sdkhooks/takedamageinfohack.cpp
+++ b/extensions/sdkhooks/takedamageinfohack.cpp
@@ -68,7 +68,8 @@ CTakeDamageInfoHack::CTakeDamageInfoHack( CBaseEntity *pInflictor, CBaseEntity *
 	m_iDamageCustom = 0;
 #endif
 
-#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 	m_iDamagedOtherPlayers = 0;
 	m_iPlayerPenetrationCount = 0;
 	m_flDamageBonus = 0.0f;
diff --git a/extensions/sdktools/tempents.cpp b/extensions/sdktools/tempents.cpp
index 2a41b7b0..25eabb11 100644
--- a/extensions/sdktools/tempents.cpp
+++ b/extensions/sdktools/tempents.cpp
@@ -285,11 +285,12 @@ void TempEntityManager::Initialize()
 	int offset;
 	m_Loaded = false;
 
-#if SOURCE_ENGINE == SE_TF2      \
-	|| SOURCE_ENGINE == SE_DODS  \
-	|| SOURCE_ENGINE == SE_HL2DM \
-	|| SOURCE_ENGINE == SE_CSS   \
-	|| SOURCE_ENGINE == SE_SDK2013
+#if SOURCE_ENGINE == SE_TF2        \
+	|| SOURCE_ENGINE == SE_DODS    \
+	|| SOURCE_ENGINE == SE_HL2DM   \
+	|| SOURCE_ENGINE == SE_CSS     \
+	|| SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS
 
 	if (g_SMAPI->GetServerFactory(false)("VSERVERTOOLS003", nullptr))
 	{
diff --git a/extensions/sdktools/vcaller.cpp b/extensions/sdktools/vcaller.cpp
index ebcfe186..45d8e4bd 100644
--- a/extensions/sdktools/vcaller.cpp
+++ b/extensions/sdktools/vcaller.cpp
@@ -133,6 +133,7 @@ static cell_t PrepSDKCall_SetSignature(IPluginContext *pContext, const cell_t *p
 	|| SOURCE_ENGINE == SE_HL2DM       \
 	|| SOURCE_ENGINE == SE_DODS        \
 	|| SOURCE_ENGINE == SE_SDK2013     \
+	|| SOURCE_ENGINE == SE_BMS         \
 	|| SOURCE_ENGINE == SE_TF2         \
 	|| SOURCE_ENGINE == SE_LEFT4DEAD   \
 	|| SOURCE_ENGINE == SE_LEFT4DEAD2  \
diff --git a/extensions/sdktools/vglobals.cpp b/extensions/sdktools/vglobals.cpp
index 76b5609d..ded75ef4 100644
--- a/extensions/sdktools/vglobals.cpp
+++ b/extensions/sdktools/vglobals.cpp
@@ -211,11 +211,12 @@ bool UTIL_VerifySignature(const void *addr, const char *sig, size_t len)
 
 void GetIServer()
 {
-#if SOURCE_ENGINE == SE_TF2      \
-	|| SOURCE_ENGINE == SE_DODS  \
-	|| SOURCE_ENGINE == SE_HL2DM \
-	|| SOURCE_ENGINE == SE_CSS   \
+#if SOURCE_ENGINE == SE_TF2        \
+	|| SOURCE_ENGINE == SE_DODS    \
+	|| SOURCE_ENGINE == SE_HL2DM   \
+	|| SOURCE_ENGINE == SE_CSS     \
 	|| SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS     \
 	|| SOURCE_ENGINE == SE_INSURGENCY
 
 #if SOURCE_ENGINE != SE_INSURGENCY
diff --git a/extensions/sdktools/vhelpers.cpp b/extensions/sdktools/vhelpers.cpp
index 9207dcba..a34c5ccb 100644
--- a/extensions/sdktools/vhelpers.cpp
+++ b/extensions/sdktools/vhelpers.cpp
@@ -458,11 +458,12 @@ void UTIL_DrawSendTable(FILE *fp, SendTable *pTable, int level = 1)
 		pProp = pTable->GetProp(i);
 		if (pProp->GetDataTable())
 		{
-			fprintf(fp, "%*sTable: %s (offset %d) (type %s)\n", 
+			fprintf(fp, "%*sTable: %s (offset %d) (type %s) (unk %d 0x%p)\n", 
 				level, "", 
 				pProp->GetName(), 
 				pProp->GetOffset(), 
-				pProp->GetDataTable()->GetName());
+				pProp->GetDataTable()->GetName(),
+				pProp->m_Unknown1, pProp->m_Unknown1);
 			
 			UTIL_DrawSendTable(fp, pProp->GetDataTable(), level + 1);
 		}
@@ -473,24 +474,26 @@ void UTIL_DrawSendTable(FILE *fp, SendTable *pTable, int level = 1)
 			if (type != NULL)
 			{
 				fprintf(fp,
-					"%*sMember: %s (offset %d) (type %s) (bits %d) (%s)\n", 
+					"%*sMember: %s (offset %d) (type %s) (bits %d) (%s) (unk %d 0x%p)\n", 
 					level, "", 
 					pProp->GetName(),
 					pProp->GetOffset(),
 					type,
 					pProp->m_nBits,
-					UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType()));
+					UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType()),
+					pProp->m_Unknown1, pProp->m_Unknown1);
 			}
 			else
 			{
 				fprintf(fp,
-					"%*sMember: %s (offset %d) (type %d) (bits %d) (%s)\n", 
+					"%*sMember: %s (offset %d) (type %d) (bits %d) (%s) (unk %d 0x%p)\n", 
 					level, "", 
 					pProp->GetName(),
 					pProp->GetOffset(),
 					pProp->GetType(),
 					pProp->m_nBits,
-					UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType()));
+					UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType()),
+					pProp->m_Unknown1, pProp->m_Unknown1);
 			}
 		}
 	}
@@ -597,11 +600,12 @@ CEntityFactoryDictionary *GetEntityFactoryDictionary()
 {
 	static CEntityFactoryDictionary *dict = NULL;
 
-#if SOURCE_ENGINE == SE_TF2 \
-	|| SOURCE_ENGINE == SE_CSS \
-	|| SOURCE_ENGINE == SE_DODS \
-	|| SOURCE_ENGINE == SE_HL2DM \
+#if SOURCE_ENGINE == SE_TF2        \
+	|| SOURCE_ENGINE == SE_CSS     \
+	|| SOURCE_ENGINE == SE_DODS    \
+	|| SOURCE_ENGINE == SE_HL2DM   \
 	|| SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS     \
 	|| SOURCE_ENGINE == SE_NUCLEARDAWN
 	dict = (CEntityFactoryDictionary *) servertools->GetEntityFactoryDictionary();
 #else
diff --git a/extensions/sdktools/vnatives.cpp b/extensions/sdktools/vnatives.cpp
index ff1ebe60..fab25181 100644
--- a/extensions/sdktools/vnatives.cpp
+++ b/extensions/sdktools/vnatives.cpp
@@ -598,7 +598,8 @@ static cell_t SlapPlayer(IPluginContext *pContext, const cell_t *params)
 			CellRecipientFilter rf;
 			rf.SetToReliable(true);
 			rf.Initialize(player_list, total_players);
-#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 			engsound->EmitSound(rf, params[1], CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, 0, &pos);
 #elif SOURCE_ENGINE < SE_PORTAL2
 			engsound->EmitSound(rf, params[1], CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos);
@@ -797,6 +798,7 @@ static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *para
 	|| SOURCE_ENGINE == SE_DODS  \
 	|| SOURCE_ENGINE == SE_HL2DM \
 	|| SOURCE_ENGINE == SE_CSS   \
+	|| SOURCE_ENGINE == SE_BMS   \
 	|| SOURCE_ENGINE == SE_SDK2013
 
 	static bool bHasServerTools3 = !!g_SMAPI->GetServerFactory(false)("VSERVERTOOLS003", nullptr);
diff --git a/extensions/sdktools/vsound.cpp b/extensions/sdktools/vsound.cpp
index cbf2da5c..cfd4ec6a 100644
--- a/extensions/sdktools/vsound.cpp
+++ b/extensions/sdktools/vsound.cpp
@@ -41,7 +41,8 @@ SH_DECL_HOOK8_void(IVEngineServer, EmitAmbientSound, SH_NOATTRIB, 0, int, const
 #if SOURCE_ENGINE >= SE_PORTAL2
 SH_DECL_HOOK17(IEngineSound, EmitSound, SH_NOATTRIB, 0, int, IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
 SH_DECL_HOOK17(IEngineSound, EmitSound, SH_NOATTRIB, 1, int, IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
-#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 SH_DECL_HOOK15_void(IEngineSound, EmitSound, SH_NOATTRIB, 0, IRecipientFilter &, int, int, const char *, float, float, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
 SH_DECL_HOOK15_void(IEngineSound, EmitSound, SH_NOATTRIB, 1, IRecipientFilter &, int, int, const char *, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
 #else
@@ -339,7 +340,8 @@ int SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChanne
 							 float flVolume, soundlevel_t iSoundlevel, int nSeed, int iFlags, int iPitch, const Vector *pOrigin, 
 							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
 							 float soundtime, int speakerentity)
-#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, 
 							 float flVolume, soundlevel_t iSoundlevel, int iFlags, int iPitch, int iSpecialDSP, const Vector *pOrigin, 
 							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
@@ -443,7 +445,8 @@ void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChann
 					(crf, iEntIndex, iChannel, soundEntry, nSoundEntryHash, buffer, flVolume, iSoundlevel, nSeed, iFlags, iPitch, pOrigin,
 					pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
 					);
-#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 				RETURN_META_NEWPARAMS(
 					MRES_IGNORED,
 					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, 
@@ -474,7 +477,8 @@ int SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChann
 							 float flVolume, float flAttenuation, int nSeed, int iFlags, int iPitch, const Vector *pOrigin, 
 							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
 							 float soundtime, int speakerentity)
-#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, 
 							 float flVolume, float flAttenuation, int iFlags, int iPitch, int iSpecialDSP, const Vector *pOrigin, 
 							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
@@ -579,7 +583,8 @@ void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChan
 					(crf, iEntIndex, iChannel, soundEntry, nSoundEntryHash, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)),
 					nSeed, iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
 					);
-#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 RETURN_META_NEWPARAMS(
 					MRES_IGNORED,
 					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char *, float, float, 
@@ -916,7 +921,8 @@ static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
 					soundtime,
 					speakerentity);
 			}
-#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 			if (g_InSoundHook)
 			{
 				SH_CALL(enginesoundPatch, 
@@ -1044,7 +1050,8 @@ static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
 				soundtime,
 				speakerentity);
 		}
-#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 		if (g_InSoundHook)
 		{
 			SH_CALL(enginesoundPatch, 
@@ -1358,7 +1365,8 @@ static cell_t EmitSentence(IPluginContext *pContext, const cell_t *params)
 #endif
 		flags, 
 		pitch, 
-#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 		0, 
 #endif
 		pOrigin,
diff --git a/extensions/sdktools/vsound.h b/extensions/sdktools/vsound.h
index 855d74cf..531e1fa5 100644
--- a/extensions/sdktools/vsound.h
+++ b/extensions/sdktools/vsound.h
@@ -67,7 +67,8 @@ public:
 		const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
 		float soundtime, int speakerentity);
 #else
-#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \
+	|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
 	
 	void OnEmitSound(IRecipientFilter& filter, int iEntIndex, int iChannel, const char *pSample, float flVolume, 
 		soundlevel_t iSoundlevel, int iFlags, int iPitch, int iSpecialDSP, const Vector *pOrigin, 
@@ -86,7 +87,7 @@ public:
 		float flAttenuation, int iFlags, int iPitch, const Vector *pOrigin, 
 		const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
 		float soundtime, int speakerentity);
-#endif // SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
+#endif // SOURCE_ENGINE == SE_CSS, SE_HL2DM, SE_DODS, SE_SDK2013, SE_BMS, SE_TF2
 #endif // SOURCE_ENGINE >= SE_PORTAL2
 private:
 	size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter);
diff --git a/loader/loader.cpp b/loader/loader.cpp
index eb2c8fad..66531929 100644
--- a/loader/loader.cpp
+++ b/loader/loader.cpp
@@ -87,6 +87,7 @@
 #define FILENAME_1_6_BLADE			"sourcemod.2.blade" PLATFORM_EXT
 #define FILENAME_1_6_INSURGENCY		"sourcemod.2.insurgency" PLATFORM_EXT
 #define FILENAME_1_6_CONTAGION		"sourcemod.2.contagion" PLATFORM_EXT
+#define FILENAME_1_6_BMS			"sourcemod.2.bms" PLATFORM_EXT
 
 HINSTANCE g_hCore = NULL;
 bool load_attempted = false;
@@ -311,6 +312,11 @@ DLL_EXPORT METAMOD_PLUGIN *CreateInterface_MMS(const MetamodVersionInfo *mvi, co
 			filename = FILENAME_1_6_SDK2013;
 			break;
 		}
+	case SOURCE_ENGINE_BMS:
+		{
+			filename = FILENAME_1_6_BMS;
+			break;
+		}
 	case SOURCE_ENGINE_TF2:
 		{
 			filename = FILENAME_1_6_TF2;
diff --git a/plugins/include/halflife.inc b/plugins/include/halflife.inc
index 4514bb08..5454eb7f 100644
--- a/plugins/include/halflife.inc
+++ b/plugins/include/halflife.inc
@@ -88,6 +88,7 @@ enum EngineVersion
 	Engine_Blade,				/**< Blade Symphony */
 	Engine_Insurgency,			/**< Insurgency (2013 Retail version)*/
 	Engine_Contagion,			/**< Contagion */
+	Engine_BlackMesa,			/**< Black Mesa Multiplayer */
 };
 
 #define INVALID_ENT_REFERENCE 0xFFFFFFFF
diff --git a/tools/checkout-deps.sh b/tools/checkout-deps.sh
index 40461e0c..c0c9e5bb 100755
--- a/tools/checkout-deps.sh
+++ b/tools/checkout-deps.sh
@@ -79,7 +79,7 @@ sdks=( csgo hl2dm nucleardawn l4d2 dods l4d css tf2 insurgency sdk2013 dota )
 
 if [ $ismac -eq 0 ]; then
   # Add these SDKs for Windows or Linux
-  sdks+=( orangebox blade episode1 )
+  sdks+=( orangebox blade episode1 bms )
 
   # Add more SDKs for Windows only
   if [ $iswin -eq 1 ]; then

From 9164730b07b7f497d4b93644a1e8a5edcabfadb0 Mon Sep 17 00:00:00 2001
From: Nicholas Hastings <nshastings@gmail.com>
Date: Wed, 6 May 2015 22:01:29 -0400
Subject: [PATCH 2/5] Add gamedata for Black Mesa.

---
 gamedata/core.games/common.games.txt     |   1 +
 gamedata/core.games/engine.bms.txt       |  60 +++++++
 gamedata/core.games/master.games.txt     |   5 +
 gamedata/sdkhooks.games/game.bms.txt     | 129 +++++++++++++++
 gamedata/sdkhooks.games/master.games.txt |   5 +
 gamedata/sdktools.games/game.bms.txt     | 200 +++++++++++++++++++++++
 gamedata/sdktools.games/master.games.txt |   4 +
 tools/buildbot/PackageScript             |   2 +
 8 files changed, 406 insertions(+)
 create mode 100644 gamedata/core.games/engine.bms.txt
 create mode 100644 gamedata/sdkhooks.games/game.bms.txt
 create mode 100644 gamedata/sdktools.games/game.bms.txt

diff --git a/gamedata/core.games/common.games.txt b/gamedata/core.games/common.games.txt
index 4d7b31f3..ea1219f3 100644
--- a/gamedata/core.games/common.games.txt
+++ b/gamedata/core.games/common.games.txt
@@ -236,6 +236,7 @@
 			"game"					"berimbau"
 			"game"					"cstrike"
 			"game"					"synergy"
+			"game"					"bms"
 		}
 		
 		"Keys"
diff --git a/gamedata/core.games/engine.bms.txt b/gamedata/core.games/engine.bms.txt
new file mode 100644
index 00000000..a7e0c701
--- /dev/null
+++ b/gamedata/core.games/engine.bms.txt
@@ -0,0 +1,60 @@
+/**
+ * Do not edit this file.  Any changes will be overwritten by the gamedata
+ * updater or by upgrading your SourceMod install.
+ *
+ * To override data in this file, create a subdirectory named "custom" and
+ * place your own gamedata file(s) inside of it.  Such files will be parsed
+ * after SM's own.
+ *
+ * For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(SourceMod)
+ */
+
+"Games"
+{
+	/* CGlobalEntityList */
+	"#default"
+	{
+		"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"
+				"linux"		"\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xC7\x2A\x2A\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
+			}
+			"gEntList"
+			{
+				"library"	"server"
+				"linux"		"@gEntList"
+				"mac"		"@gEntList"
+			}
+		}
+	}
+	
+	"#default"
+	{
+		"Keys"
+		{
+			"UseInvalidUniverseInSteam2IDs"		"1"
+		}
+		
+		"Offsets"
+		{
+			"EntInfo"
+			{
+				"windows"	"4"	
+				"linux"		"4"
+				"mac"		"4"
+			}
+		}
+	}
+}
diff --git a/gamedata/core.games/master.games.txt b/gamedata/core.games/master.games.txt
index c6b29853..0bb61480 100644
--- a/gamedata/core.games/master.games.txt
+++ b/gamedata/core.games/master.games.txt
@@ -50,6 +50,11 @@
 		"engine"	"sdk2013"
 	}
 	
+	"engine.bms.txt"
+	{
+		"engine"	"bms"
+	}
+	
 	"engine.css.txt"
 	{
 		"engine"	"css"
diff --git a/gamedata/sdkhooks.games/game.bms.txt b/gamedata/sdkhooks.games/game.bms.txt
new file mode 100644
index 00000000..13cc7346
--- /dev/null
+++ b/gamedata/sdkhooks.games/game.bms.txt
@@ -0,0 +1,129 @@
+"Games"
+{			
+	"#default"
+	{
+		"Offsets"
+		{
+			"Blocked"
+			{
+				"windows"	"108"
+				"linux"		"109"
+				"mac"		"109"
+			}
+			"EndTouch"
+			{
+				"windows"	"106"
+				"linux"		"107"
+				"mac"		"107"
+			}
+			"FireBullets"
+			{
+				"windows"	"119"
+				"linux"		"120"
+				"mac"		"120"
+			}
+			"OnTakeDamage"
+			{
+				"windows"	"66"
+				"linux"		"67"
+				"mac"		"67"
+			}
+			"OnTakeDamage_Alive"
+			{
+				"windows"	"287"
+				"linux"		"288"
+				"mac"		"288"
+			}
+			"PreThink"
+			{
+				"windows"	"349"
+				"linux"		"350"
+				"mac"		"350"
+			}
+			"PostThink"
+			{
+				"windows"	"350"
+				"linux"		"351"
+				"mac"		"351"
+			}
+			"SetTransmit"
+			{
+				"windows"	"20"
+				"linux"		"21"
+				"mac"		"21"
+			}
+			"ShouldCollide"
+			{
+				"windows"	"16"
+				"linux"		"17"
+				"mac"		"17"
+			}
+			"Spawn"
+			{
+				"windows"	"22"
+				"linux"		"23"
+				"mac"		"23"
+			}
+			"StartTouch"
+			{
+				"windows"	"104"
+				"linux"		"105"
+				"mac"		"105"
+			}
+			"Think"
+			{
+				"windows"	"48"
+				"linux"		"49"
+				"mac"		"49"
+			}
+			"Touch"
+			{
+				"windows"	"105"
+				"linux"		"106"
+				"mac"		"106"
+			}
+			"TraceAttack"
+			{
+				"windows"	"64"
+				"linux"		"65"
+				"mac"		"65"
+			}
+			"VPhysicsUpdate"
+			{
+				"windows"	"155"
+				"linux"		"156"
+				"mac"		"156"
+			}
+			"Weapon_CanSwitchTo"
+			{
+				"windows"	"281"
+				"linux"		"282"
+				"mac"		"282"
+			}
+			"Weapon_CanUse"
+			{
+				"windows"	"275"
+				"linux"		"276
+				"mac"		"276"
+			}
+			"Weapon_Drop"
+			{
+				"windows"	"278"
+				"linux"		"279"
+				"mac"		"279"
+			}
+			"Weapon_Equip"
+			{
+				"windows"	"276"
+				"linux"		"277"
+				"mac"		"277"
+			}
+			"Weapon_Switch"
+			{
+				"windows"	"279"
+				"linux"		"280"
+				"mac"		"280"
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/gamedata/sdkhooks.games/master.games.txt b/gamedata/sdkhooks.games/master.games.txt
index aefdfa85..0d45ef4a 100644
--- a/gamedata/sdkhooks.games/master.games.txt
+++ b/gamedata/sdkhooks.games/master.games.txt
@@ -179,4 +179,9 @@
 	{
 		"game"		"hl2ctf"
 	}
+	
+	"game.bms.txt"
+	{
+		"game"		"bms"
+	}
 }
diff --git a/gamedata/sdktools.games/game.bms.txt b/gamedata/sdktools.games/game.bms.txt
new file mode 100644
index 00000000..c29bf8ed
--- /dev/null
+++ b/gamedata/sdktools.games/game.bms.txt
@@ -0,0 +1,200 @@
+/**
+ * Do not edit this file.  Any changes will be overwritten by the gamedata
+ * updater or by upgrading your SourceMod install.
+ *
+ * To override data in this file, create a subdirectory named "custom" and
+ * place your own gamedata file(s) inside of it.  Such files will be parsed
+ * after SM's own.
+ *
+ * For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(SourceMod)
+ */
+
+"Games"
+{
+	/* General Temp Entities */
+	"#default"
+	{
+		"Offsets"
+		{
+			"GetTEName"
+			{
+				"windows"	"4"
+				"linux"		"4"
+				"mac"		"4"
+			}
+			"GetTENext"
+			{
+				"windows"	"8"
+				"linux"		"8"
+				"mac"		"8"
+			}
+			"TE_GetServerClass"
+			{
+				"windows"	"0"
+				"linux"		"0"
+				"mac"		"0"
+			}
+		}
+	}
+	
+	/* CBaseEntityOutput::FireOutput */
+	"#default"
+	{
+		"Signatures"
+		{
+			"FireOutput"
+			{
+				"library"	"server"
+				"windows"	"\x55\x8B\xEC\x81\xEC\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\x53\x8B\x5D\x20\x8B\xC1\x8B\x4D\x1C\x56\x57\x8B"
+				"linux"		"@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
+				"mac"		"@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
+			}
+		}
+	}
+	
+	/* SetUserInfo data */
+	"#default"
+	{
+		"Offsets"
+		{
+			/**
+			 * CBaseClient::SetUserCVar(char  const*,char  const*);
+			 * Linux offset straight from VTable dump.
+			 * Windows offset is crazy. Found the windows SetName function using string "(%d)%-0.*s"
+			 * Cross referenced back to the vtable and counted manually (SetUserCvar is 1 higher, offsets start from 1)
+			 */
+			"SetUserCvar"
+			{
+				"windows"	"18"
+				"linux"		"58"
+				"mac"		"58"
+			}
+			/**
+			 * CBaseClient::SetName(char  const*);
+			 * Linux offset straight from VTable dump.
+			 * Has string "(%d)%-0.*s"
+			 */
+			"SetClientName"
+			{
+				"windows"	"17"
+				"linux"		"57"
+				"mac"		"57"
+			}
+			/**
+			 * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
+			 * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.
+			 * Linux: 	mov     byte ptr [esi+98h], 0
+			 * Win:	mov     byte ptr [esi+0A4h], 0
+			 */
+			"InfoChanged"
+			{
+				"windows"	"140"
+				"linux"		"140"
+				"mac"		"140"
+			}
+		}
+	}
+	
+	"#default"
+	{
+		"Offsets"
+		{
+			"GiveNamedItem"
+			{
+				"windows"	"418"
+				"linux"		"419"
+				"mac"		"419"
+			}
+			"RemovePlayerItem"
+			{
+				"windows"	"285"
+				"linux"		"286"
+				"mac"		"286"
+			}
+			"Weapon_GetSlot"
+			{
+				"windows"	"283"
+				"linux"		"284"
+				"mac"		"284"
+			}
+			"Ignite"
+			{
+				"windows"	"222"
+				"linux"		"223"
+				"mac"		"223"
+			}
+			"Extinguish"
+			{
+				"windows"	"226"
+				"linux"		"227"
+				"mac"		"227"
+			}
+			"Teleport"
+			{
+				"windows"	"115"
+				"linux"		"116"
+				"mac"		"116"
+			}
+			"CommitSuicide"
+			{
+				"windows"	"458"
+				"linux"		"458"
+				"mac"		"458"
+			}
+			"GetVelocity"
+			{
+				"windows"	"148"
+				"linux"		"149"
+				"mac"		"149"
+			}
+			"EyeAngles"
+			{
+				"windows"	"138"
+				"linux"		"139"
+				"mac"		"139"
+			}
+			"SetEntityModel"
+			{
+				"windows"	"24"
+				"linux"		"25"
+				"mac"		"25"
+			}
+			"AcceptInput"
+			{
+				"windows"	"37"
+				"linux"		"38"
+				"mac"		"38"
+			}
+			"WeaponEquip"
+			{
+				"windows"	"276"
+				"linux"		"277"
+				"mac"		"277"
+			}
+			"Activate"
+			{
+				"windows"	"34"
+				"linux"		"35"
+				"mac"		"35"
+			}
+			"PlayerRunCmd"
+			{
+				"windows"	"437"
+				"linux"		"438"
+				"mac"		"438"
+			}
+			"GiveAmmo"
+			{
+				"windows"	"267"
+				"linux"		"268"
+				"mac"		"268"
+			}
+		}
+		
+		"Keys"
+		{
+			"GameRulesProxy"	"CTFGameRulesProxy"
+			"GameRulesDataTable" "tf_gamerules_data"
+		}
+	}
+}
diff --git a/gamedata/sdktools.games/master.games.txt b/gamedata/sdktools.games/master.games.txt
index b0926386..2f2e550a 100644
--- a/gamedata/sdktools.games/master.games.txt
+++ b/gamedata/sdktools.games/master.games.txt
@@ -243,4 +243,8 @@
 	{
 		"game"		"nmrih"
 	}
+	"game.bms.txt"
+	{
+		"game"		"bms"
+	}
 }
diff --git a/tools/buildbot/PackageScript b/tools/buildbot/PackageScript
index 94219560..ca16d605 100644
--- a/tools/buildbot/PackageScript
+++ b/tools/buildbot/PackageScript
@@ -150,6 +150,7 @@ CopyFiles('gamedata/sdkhooks.games', 'addons/sourcemod/gamedata/sdkhooks.games',
     'game.ag2.txt',
     'game.alienswarm.txt',
     'game.aoc.txt',
+	'game.bms.txt',
     'game.cspromod.txt',
     'game.cstrike.txt',
     'game.dinodday.txt',
@@ -195,6 +196,7 @@ CopyFiles('gamedata/sdktools.games', 'addons/sourcemod/gamedata/sdktools.games',
     'game.alienswarm.txt',
     'game.aoc.txt',
     'game.bg2.txt',
+	'game.bms.txt',
     'game.cspromod.txt',
     'game.cstrike.txt',
     'game.dinodday.txt',

From dac3d1c988668bbdc669b2a2844f140eeb320794 Mon Sep 17 00:00:00 2001
From: Nicholas Hastings <nshastings@gmail.com>
Date: Wed, 6 May 2015 22:01:39 -0400
Subject: [PATCH 3/5] Remove leftover debug code.

---
 extensions/sdktools/vhelpers.cpp | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/extensions/sdktools/vhelpers.cpp b/extensions/sdktools/vhelpers.cpp
index a34c5ccb..d9e4b292 100644
--- a/extensions/sdktools/vhelpers.cpp
+++ b/extensions/sdktools/vhelpers.cpp
@@ -458,12 +458,11 @@ void UTIL_DrawSendTable(FILE *fp, SendTable *pTable, int level = 1)
 		pProp = pTable->GetProp(i);
 		if (pProp->GetDataTable())
 		{
-			fprintf(fp, "%*sTable: %s (offset %d) (type %s) (unk %d 0x%p)\n", 
+			fprintf(fp, "%*sTable: %s (offset %d) (type %s)\n", 
 				level, "", 
 				pProp->GetName(), 
 				pProp->GetOffset(), 
-				pProp->GetDataTable()->GetName(),
-				pProp->m_Unknown1, pProp->m_Unknown1);
+				pProp->GetDataTable()->GetName());
 			
 			UTIL_DrawSendTable(fp, pProp->GetDataTable(), level + 1);
 		}
@@ -474,26 +473,24 @@ void UTIL_DrawSendTable(FILE *fp, SendTable *pTable, int level = 1)
 			if (type != NULL)
 			{
 				fprintf(fp,
-					"%*sMember: %s (offset %d) (type %s) (bits %d) (%s) (unk %d 0x%p)\n", 
+					"%*sMember: %s (offset %d) (type %s) (bits %d) (%s)\n", 
 					level, "", 
 					pProp->GetName(),
 					pProp->GetOffset(),
 					type,
 					pProp->m_nBits,
-					UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType()),
-					pProp->m_Unknown1, pProp->m_Unknown1);
+					UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType()));
 			}
 			else
 			{
 				fprintf(fp,
-					"%*sMember: %s (offset %d) (type %d) (bits %d) (%s) (unk %d 0x%p)\n", 
+					"%*sMember: %s (offset %d) (type %d) (bits %d) (%s)\n", 
 					level, "", 
 					pProp->GetName(),
 					pProp->GetOffset(),
 					pProp->GetType(),
 					pProp->m_nBits,
-					UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType()),
-					pProp->m_Unknown1, pProp->m_Unknown1);
+					UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType()));
 			}
 		}
 	}

From 909598920ba28722f3612266b42416fc798a605c Mon Sep 17 00:00:00 2001
From: Nicholas Hastings <nshastings@gmail.com>
Date: Wed, 6 May 2015 22:01:57 -0400
Subject: [PATCH 4/5] Disable nextmap on Black Mesa for now. (Doesn't ship with
 mapcycle.txt).

---
 plugins/nextmap.sp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/plugins/nextmap.sp b/plugins/nextmap.sp
index 4408a16e..accd8339 100644
--- a/plugins/nextmap.sp
+++ b/plugins/nextmap.sp
@@ -64,6 +64,7 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
 			|| StrEqual(game, "garrysmod", false)
 			|| StrEqual(game, "swarm", false)
 			|| StrEqual(game, "dota", false)
+			|| StrEqual(game, "bms", false)
 			|| GetEngineVersion() == Engine_Insurgency)
 	{
 		strcopy(error, err_max, "Nextmap is incompatible with this game");

From 397c45457a11f3ca0b7aaa296fcf783b0ad6f419 Mon Sep 17 00:00:00 2001
From: Nicholas Hastings <nshastings@gmail.com>
Date: Wed, 6 May 2015 22:18:43 -0400
Subject: [PATCH 5/5] Fix spacing in PackageScript.

---
 tools/buildbot/PackageScript | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/buildbot/PackageScript b/tools/buildbot/PackageScript
index ca16d605..30e55361 100644
--- a/tools/buildbot/PackageScript
+++ b/tools/buildbot/PackageScript
@@ -150,7 +150,7 @@ CopyFiles('gamedata/sdkhooks.games', 'addons/sourcemod/gamedata/sdkhooks.games',
     'game.ag2.txt',
     'game.alienswarm.txt',
     'game.aoc.txt',
-	'game.bms.txt',
+    'game.bms.txt',
     'game.cspromod.txt',
     'game.cstrike.txt',
     'game.dinodday.txt',
@@ -196,7 +196,7 @@ CopyFiles('gamedata/sdktools.games', 'addons/sourcemod/gamedata/sdktools.games',
     'game.alienswarm.txt',
     'game.aoc.txt',
     'game.bg2.txt',
-	'game.bms.txt',
+    'game.bms.txt',
     'game.cspromod.txt',
     'game.cstrike.txt',
     'game.dinodday.txt',