diff --git a/Makefile b/Makefile
index 2bf6a87..d3262ab 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,24 @@
 # Script made by [SG-10]Cpt.Moore
+# Note that this script will convert line endings in source files to LF.
 
 SOURCEDIR=src
 SMINCLUDES=env/include
 BUILDDIR=build
-SPCOMP=env/linux/bin/spcomp-1.4.0-3218
+SPCOMP_LINUX=env/linux/bin/spcomp-1.4.1
+SPCOMP_DARWIN=env/darwin/bin/spcomp-1.4.1
+DOS2UNIX_LINUX=dos2unix -p
+DOS2UNIX_DARWIN=env/darwin/bin/dos2unix -p
 VERSIONDUMP=./updateversion.sh
 
+OS = $(shell uname -s)
+ifeq "$(OS)" "Darwin"
+	SPCOMP = $(SPCOMP_DARWIN)
+	DOS2UNIX = $(DOS2UNIX_DARWIN)
+else
+	SPCOMP = $(SPCOMP_LINUX)
+	DOS2UNIX = $(DOS2UNIX_LINUX)
+endif
+
 vpath %.sp $(SOURCEDIR)
 vpath %.inc $(SOURCEDIR)/zr
 vpath %.smx $(BUILDDIR)
@@ -19,8 +32,9 @@ prepare: prepare_newlines prepare_builddir
 
 prepare_newlines:
 	@echo "Removing windows newlines"
-	@find $(SOURCEDIR)/zr -name \*.inc -exec dos2unix -p '{}' \;
-	@find $(SOURCEDIR)  -name \*.sp -exec dos2unix -p '{}' \;
+	@find $(SOURCEDIR)  -name \*.inc -exec $(DOS2UNIX) '{}' \;
+	@find $(SOURCEDIR)  -name \*.sp  -exec $(DOS2UNIX) '{}' \;
+	@find $(SMINCLUDES) -name \*.inc -exec $(DOS2UNIX) '{}' \;
 
 prepare_builddir:
 	@echo "Creating build directory"
@@ -28,9 +42,8 @@ prepare_builddir:
 
 %.smx: %.sp
 	$(VERSIONDUMP)
-	$(SPCOMP) -i$(SOURCEDIR) -i$(SOURCEDIR)/include -i$(SMINCLUDES) -o$(BUILDDIR)/$@ $<
+	$(SPCOMP) -i$(SOURCEDIR) -i$(SMINCLUDES) -o$(BUILDDIR)/$@ $<
 
 clean:
 	@echo "Removing build directory"
 	@rm -fr $(BUILDDIR)
-
diff --git a/compile.bat b/compile.bat
index fc407ee..769c6ee 100644
--- a/compile.bat
+++ b/compile.bat
@@ -3,7 +3,7 @@
 set SOURCEDIR=src
 set SMINCLUDES=env\include
 set BUILDDIR=build
-set SPCOMP=env\win32\bin\spcomp-1.4.0-3218.exe
+set SPCOMP=env\win32\bin\spcomp-1.4.1.exe
 set VERSIONDUMP=updateversion.bat
 
 :: Dump version and revision information first.
diff --git a/env/darwin/bin/dos2unix b/env/darwin/bin/dos2unix
new file mode 100755
index 0000000..9b15a7c
Binary files /dev/null and b/env/darwin/bin/dos2unix differ
diff --git a/env/darwin/bin/dos2unix.txt b/env/darwin/bin/dos2unix.txt
new file mode 100644
index 0000000..53432bf
--- /dev/null
+++ b/env/darwin/bin/dos2unix.txt
@@ -0,0 +1 @@
+dos2unix source: http://www.thefreecountry.com/tofrodos/
diff --git a/env/darwin/bin/spcomp-1.4.1 b/env/darwin/bin/spcomp-1.4.1
new file mode 100755
index 0000000..1a977ce
Binary files /dev/null and b/env/darwin/bin/spcomp-1.4.1 differ
diff --git a/env/include/adt_array.inc b/env/include/adt_array.inc
index 038ca29..e8b81f6 100644
--- a/env/include/adt_array.inc
+++ b/env/include/adt_array.inc
@@ -88,7 +88,7 @@ native ClearArray(Handle:array);
  * @return				New handle to the cloned array object
  * @error				Invalid Handle
  */
- native Handle:CloneArray(Handle:array);
+native Handle:CloneArray(Handle:array);
 
 /**
  * Resizes an array.  If the size is smaller than the current size,
diff --git a/env/include/adt_trie.inc b/env/include/adt_trie.inc
index 516c794..4de66fa 100644
--- a/env/include/adt_trie.inc
+++ b/env/include/adt_trie.inc
@@ -79,8 +79,7 @@ native bool:SetTrieArray(Handle:trie, const String:key[], const any:array[], num
  *
  * @param trie		Trie Handle.
  * @param key		Key string.
- * @param array		Array to store.
- * @param num_items	Number of items in the array.
+ * @param value		String to store.
  * @param replace	If false, operation will fail if the key is already set.
  * @return			True on success, false on failure.
  * @error			Invalid Handle.
diff --git a/env/include/basecomm.inc b/env/include/basecomm.inc
new file mode 100644
index 0000000..8cfd319
--- /dev/null
+++ b/env/include/basecomm.inc
@@ -0,0 +1,93 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod (C)2004-2011 AlliedModders LLC.  All rights reserved.
+ * =============================================================================
+ *
+ * This file is part of the SourceMod/SourcePawn SDK.
+ *
+ * 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$
+ */
+ 
+#if defined _basecomm_included
+ #endinput
+#endif
+#define _basecomm_included
+
+/**
+ * Returns whether or not a client is gagged
+ *
+ * @param client		Client index.
+ * @return				True if client is gagged, false otherwise.
+ */
+native bool:BaseComm_IsClientGagged(client);
+
+/**
+ * Returns whether or not a client is muted
+ *
+ * @param client		Client index.
+ * @return				True if client is muted, false otherwise.
+ */
+native bool:BaseComm_IsClientMuted(client);
+
+/**
+ * Sets a client's gag state
+ *
+ * @param client		Client index.
+ * @param gagState		True to gag client, false to ungag.
+ * @return				True if this caused a change in gag state, false otherwise.
+ */
+native bool:BaseComm_SetClientGag(client, bool:gagState);
+
+/**
+ * Sets a client's mute state
+ *
+ * @param client		Client index.
+ * @param muteState		True to mute client, false to unmute.
+ * @return				True if this caused a change in mute state, false otherwise.
+ */
+native bool:BaseComm_SetClientMute(client, bool:muteState);
+
+/* DO NOT EDIT BELOW THIS LINE */
+
+public SharedPlugin:__pl_basecomm = 
+{
+	name = "basecomm",
+	file = "basecomm.smx",
+#if defined REQUIRE_PLUGIN
+	required = 1,
+#else
+	required = 0,
+#endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public __pl_basecomm_SetNTVOptional()
+{
+	MarkNativeAsOptional("BaseComm_IsClientGagged");
+	MarkNativeAsOptional("BaseComm_IsClientMuted");
+	MarkNativeAsOptional("BaseComm_SetClientGag");
+	MarkNativeAsOptional("BaseComm_SetClientMute");
+}
+#endif
diff --git a/env/include/clientprefs.inc b/env/include/clientprefs.inc
index 5466399..2a78a11 100644
--- a/env/include/clientprefs.inc
+++ b/env/include/clientprefs.inc
@@ -1,7 +1,7 @@
 /**
  * vim: set ts=4 :
  * =============================================================================
- * SourceMod (C)2004-2008 AlliedModders LLC.  All rights reserved.
+ * SourceMod (C)2004-2011 AlliedModders LLC.  All rights reserved.
  * =============================================================================
  *
  * This file is part of the SourceMod/SourcePawn SDK.
@@ -131,6 +131,17 @@ native SetClientCookie(client, Handle:cookie, const String:value[]);
  */
 native GetClientCookie(client, Handle:cookie, String:buffer[], maxlen);
 
+/**
+ * Sets the value of a Client preference cookie based on an authID string.
+ *
+ * @param authID		String Auth/STEAM ID of player to set.
+ * @param cookie		Client preference cookie handle.
+ * @param value			String value to set.
+ * @noreturn
+ * @error			Invalid cookie handle.
+ */
+native SetAuthIdCookie(const String:authID[], Handle:cookie, const String:value[]);
+
 /**
  * Checks if a clients cookies have been loaded from the database.
  *
@@ -241,7 +252,7 @@ native GetClientCookieTime(client, Handle:cookie);
 /**
  * Do not edit below this line!
  */
-public Extension:__ext_clientprefs = 
+public Extension:__ext_cprefs = 
 {
 	name = "Client Preferences",
 	file = "clientprefs.ext",
@@ -252,3 +263,21 @@ public Extension:__ext_clientprefs =
 	required = 0,
 #endif
 };
+
+#if !defined REQUIRE_EXTENSIONS
+public __ext_cprefs_SetNTVOptional()
+{
+	MarkNativeAsOptional("RegClientCookie");
+	MarkNativeAsOptional("FindClientCookie");
+	MarkNativeAsOptional("SetClientCookie");
+	MarkNativeAsOptional("GetClientCookie");
+	MarkNativeAsOptional("AreClientCookiesCached");
+	MarkNativeAsOptional("SetCookiePrefabMenu");
+	MarkNativeAsOptional("SetCookieMenuItem");
+	MarkNativeAsOptional("ShowCookieMenu");
+	MarkNativeAsOptional("GetCookieIterator");
+	MarkNativeAsOptional("ReadCookieIterator");
+	MarkNativeAsOptional("GetCookieAccess");
+	MarkNativeAsOptional("GetClientCookieTime");
+}
+#endif
diff --git a/env/include/clients.inc b/env/include/clients.inc
index 4facbc1..be1d5f0 100644
--- a/env/include/clients.inc
+++ b/env/include/clients.inc
@@ -53,7 +53,7 @@ enum NetFlow
  * not be used in OnPluginStart().
  */
 
-#define MAXPLAYERS		64	/**< Maximum number of players SourceMod supports */
+#define MAXPLAYERS		65	/**< Maximum number of players SourceMod supports */
 #define MAX_NAME_LENGTH 32	/**< Maximum buffer required to store a client name */
 
 public const MaxClients;	/**< Maximum number of players the server supports (dynamic) */
@@ -314,6 +314,22 @@ native bool:IsClientAuthorized(client);
  */
 native bool:IsFakeClient(client);
 
+/**
+ * Returns if a certain player is the SourceTV bot.
+ *
+ * @param client		Player index.
+ * @return				True if player is the SourceTV bot, false otherwise.
+ */
+native bool:IsClientSourceTV(client);
+
+/**
+ * Returns if a certain player is the Replay bot.
+ *
+ * @param client		Player index.
+ * @return				True if player is the Replay bot, false otherwise.
+ */
+native bool:IsClientReplay(client);
+
 /**
  * Returns if a certain player is an observer/spectator.
  *
diff --git a/env/include/commandfilters.inc b/env/include/commandfilters.inc
index 1143627..6ea447c 100644
--- a/env/include/commandfilters.inc
+++ b/env/include/commandfilters.inc
@@ -132,3 +132,34 @@ stock ReplyToTargetError(client, reason)
 		}
 	}
 }
+
+/**
+ * Adds clients to a multi-target filter.
+ *
+ * @param pattern       Pattern name.
+ * @param clients       Array to fill with unique, valid client indexes.
+ * @return              True if pattern was recognized, false otherwise.
+ */
+functag public bool:MultiTargetFilter(const String:pattern[], Handle:clients);
+
+/**
+ * Adds a multi-target filter function for ProcessTargetString().
+ *
+ * @param pattern       Pattern to match (case sensitive).
+ * @param filter        Filter function.
+ * @param phrase        Descriptive phrase to display on successful match.
+ * @param phraseIsML    True if phrase is multi-lingual, false otherwise.
+ * @noreturn
+ */
+native AddMultiTargetFilter(const String:pattern[], MultiTargetFilter:filter,
+                            const String:phrase[], bool:phraseIsML);
+
+/**
+ * Removes a multi-target filter function from ProcessTargetString().
+ *
+ * @param pattern       Pattern to match (case sensitive).
+ * @param filter        Filter function.
+ * @noreturn
+ */
+native RemoveMultiTargetFilter(const String:pattern[], MultiTargetFilter:filter);
+
diff --git a/env/include/console.inc b/env/include/console.inc
index 177d23b..140a059 100644
--- a/env/include/console.inc
+++ b/env/include/console.inc
@@ -121,6 +121,23 @@ enum ConVarQueryResult
  */
 native ServerCommand(const String:format[], any:...);
 
+/**
+ * Executes a server command as if it were on the server console (or RCON) 
+ * and stores the printed text into buffer.
+ *
+ * Warning: This calls ServerExecute internally and may have issues if
+ * certain commands are in the buffer, only use when you really need
+ * the response.
+ * Also, on L4D2 this will not print the command output to the server console.
+ *
+ * @param buffer		String to store command result into.
+ * @param maxlen		Length of buffer.
+ * @param format		Formatting rules.
+ * @param ...			Variable number of format parameters.
+ * @noreturn
+ */
+native ServerCommandEx(String:buffer[], maxlen, const String:format[], any:...);
+
 /**
  * Inserts a server command at the beginning of the server command buffer.
  *
@@ -722,8 +739,8 @@ native bool:ReadCommandIterator(Handle:iter,
 
 /**
  * Returns whether a client has access to a given command string.  The string 
- * can also be any override string, as overrides can be independent of 
- * commands.  This important feature essentially allows you to create custom 
+ * can be any override string, as overrides can be independent of 
+ * commands.  This feature essentially allows you to create custom 
  * flags using the override system.
  *
  * @param client		Client index.
@@ -742,6 +759,28 @@ native bool:CheckCommandAccess(client,
 							   flags,
 							   bool:override_only=false);
 
+/**
+ * Returns whether an admin has access to a given command string.  The string 
+ * can be any override string, as overrides can be independent of 
+ * commands.  This feature essentially allows you to create custom flags
+ * using the override system.
+ *
+ * @param id			AdminId of the admin.
+ * @param command		Command name.  If the command is not found, the default 
+ *						flags are used.
+ * @param flags			Flag string to use as a default, if the command or override 
+ *						is not found.
+ * @param override_only	If true, SourceMod will not attempt to find a matching 
+ *						command, and it will only use the default flags specified.
+ *						Otherwise, SourceMod will ignore the default flags if 
+ *						there is a matching admin command.
+ * @return				True if the admin has access, false otherwise.
+ */
+native bool:CheckAccess(AdminId:id, 
+							   const String:command[],
+							   flags,
+							   bool:override_only=false);
+
 /**
  * Returns true if the supplied character is valid in a ConVar name.
  *
diff --git a/env/include/cstrike.inc b/env/include/cstrike.inc
index 954dc2f..2d82a14 100644
--- a/env/include/cstrike.inc
+++ b/env/include/cstrike.inc
@@ -45,6 +45,109 @@
 #define CS_SLOT_GRENADE		3	/**< Grenade slot (will only return one grenade). */
 #define CS_SLOT_C4			4	/**< C4 slot. */
 
+enum CSRoundEndReason
+{
+	CSRoundEnd_TargetBombed = 0,           // Target Successfully Bombed!
+	CSRoundEnd_VIPEscaped,                 // The VIP has escaped!
+	CSRoundEnd_VIPKilled,                  // VIP has been assassinated!
+	CSRoundEnd_TerroristsEscaped,          // The terrorists have escaped!
+	CSRoundEnd_CTStoppedEscape,            // The CTs have prevented most of the terrorists from escaping!
+	CSRoundEnd_TerroristsStopped,          // Escaping terrorists have all been neutralized!
+	CSRoundEnd_BombDefused,                // The bomb has been defused!
+	CSRoundEnd_CTWin,                      // Counter-Terrorists Win!
+	CSRoundEnd_TerroristWin,               // Terrorists Win!
+	CSRoundEnd_Draw,                       // Round Draw!
+	CSRoundEnd_HostagesRescued,            // All Hostages have been rescued!
+	CSRoundEnd_TargetSaved,                // Target has been saved!
+	CSRoundEnd_HostagesNotRescued,         // Hostages have not been rescued!
+	CSRoundEnd_TerroristsNotEscaped,       // Terrorists have not escaped!
+	CSRoundEnd_VIPNotEscaped,              // VIP has not escaped!
+	CSRoundEnd_GameStart                   // Game Commencing!
+};
+
+enum CSWeaponID
+{
+    CSWeapon_NONE,
+    CSWeapon_P228,
+    CSWeapon_GLOCK,
+    CSWeapon_SCOUT,
+    CSWeapon_HEGRENADE,
+    CSWeapon_XM1014,
+    CSWeapon_C4,
+    CSWeapon_MAC10,
+    CSWeapon_AUG,
+    CSWeapon_SMOKEGRENADE,
+    CSWeapon_ELITE,
+    CSWeapon_FIVESEVEN,
+    CSWeapon_UMP45,
+    CSWeapon_SG550,
+    CSWeapon_GALIL,
+    CSWeapon_FAMAS,
+    CSWeapon_USP,
+    CSWeapon_AWP,
+    CSWeapon_MP5NAVY,
+    CSWeapon_M249,
+    CSWeapon_M3,
+    CSWeapon_M4A1,
+    CSWeapon_TMP,
+    CSWeapon_G3SG1,
+    CSWeapon_FLASHBANG,
+    CSWeapon_DEAGLE,
+    CSWeapon_SG552,
+    CSWeapon_AK47,
+    CSWeapon_KNIFE,
+    CSWeapon_P90,
+    CSWeapon_SHIELD,
+    CSWeapon_KEVLAR,
+    CSWeapon_ASSAULTSUIT,
+    CSWeapon_NIGHTVISION
+};
+/**
+ * Called when a player attempts to purchase an item.
+ * Return Plugin_Continue to allow the purchase or return a
+ * higher action to deny.
+ *
+ * @param client	Client index
+ * @param weapon	User input for weapon name
+ */
+forward Action:CS_OnBuyCommand(client, const String:weapon[]);
+
+/**
+ * Called when CSWeaponDrop is called
+ * Return Plugin_Continue to allow the call or return a
+ * higher action to deny.
+ *
+ * @param client	Client index
+ * @param weapon	Weapon index
+ */
+forward Action:CS_OnCSWeaponDrop(client, weaponIndex);
+
+/**
+ * Called when game retrieves a weapon's price for a player.
+ * Return Plugin_Continue to use default value or return a higher
+ * action to use a newly-set price.
+ * 
+ * @note This can be called multiple times per weapon purchase
+ * 
+ * @param client	Client index
+ * @param weapon	Weapon classname
+ * @param price		Buffer param for the price of the weapon
+ *
+ * @note			Not all "weapons" call GetWeaponPrice. Example: c4, knife, vest, vest helmet, night vision.
+ */
+forward Action:CS_OnGetWeaponPrice(client, const String:weapon[], &price);
+
+/**
+ * Called when TerminateRound is called.
+ * Return Plugin_Continue to ignore, return Plugin_Changed to continue,
+ * using the given delay and reason, or return Plugin_Handled or a higher
+ * action to block TerminateRound from firing.
+ *
+ * @param delay		Time (in seconds) until new round starts
+ * @param reason	Reason for round end
+ */
+forward Action:CS_OnTerminateRound(&Float:delay, &CSRoundEndReason:reason);
+
 /**
  * Respawns a player.
  *
@@ -64,6 +167,76 @@ native CS_RespawnPlayer(client);
  */
 native CS_SwitchTeam(client, team);
 
+/**
+ * Forces a player to drop or toss their weapon
+ *
+ * @param client		Player's index.
+ * @param weaponIndex	Index of weapon to drop.
+ * @param toss			True to toss weapon (with velocity) or false to just drop weapon
+ * @param blockhook		Set to true to stop the corresponding CS_OnCSWeaponDrop
+ * 
+ * @noreturn
+ * @error				Invalid client index, client not in game, or invalid weapon index.
+ */
+native CS_DropWeapon(client, weaponIndex, bool:toss, bool:blockhook = false);
+
+/**
+ * Forces round to end with a reason
+ *
+ * @param delay			Time (in seconds) to delay before new round starts
+ * @param reason		Reason for the round ending
+ * @param blockhook		Set to true to stop the corresponding CS_OnTerminateRound
+ *						forward from being called.
+ * @noreturn
+ */
+native CS_TerminateRound(Float:delay, CSRoundEndReason:reason, bool:blockhook = false);
+ 
+/**
+ * Gets a weapon name from a weapon alias
+ *
+ * @param alias			Weapons alias to get weapon name for.
+ * @param weapon		Buffer to store weapons name
+ * @param size			Size of buffer to store the weapons name.
+ * @noreturn
+ *
+ * @note				Will set the buffer to the original alias if it is not an alias to a weapon.
+ */
+native CS_GetTranslatedWeaponAlias(const String:alias[], String:weapon[], size);
+ 
+/**
+ * Gets a weapon's price
+ *
+ * @param client		Client to check weapon price for.
+ * @param id			Weapon id for the weapon to check
+ * @param defaultprice	Set to true to get defaultprice.
+ * @return				Returns price of the weapon (even if modified)
+ *
+ * @error				Invalid client, failing to get weapon info, or failing to get price offset.
+ * @note				c4, knife and shield will always return 0. vest, vest helmet and night vision will always return default price.
+ */
+native CS_GetWeaponPrice(client, CSWeaponID:id, bool:defaultprice = false);
+ 
+/**
+ * Gets a clients clan tag
+ * @param client		Client index to get clan tag for.
+ * @param buffer		Buffer to store clients clan tag in.
+ * @param size			Size of the buffer.
+ * @return				Number of non-null bytes written.
+ *
+ * @error				Invalid client.
+ */
+native CS_GetClientClanTag(client, String:buffer[], size);
+
+/**
+ * Sets a clients clan tag
+ * @param client		Client index to set clan tag for.
+ * @param tag			Tag to set clients clan tag as.
+ * @noreturn
+ *
+ * @error				Invalid client.
+ */
+native CS_SetClientClanTag(client, const String:tag[]);
+ 
 /**
  * Do not edit below this line!
  */
@@ -84,5 +257,12 @@ public __ext_cstrike_SetNTVOptional()
 {
 	MarkNativeAsOptional("CS_RespawnPlayer");
 	MarkNativeAsOptional("CS_SwitchTeam");
+	MarkNativeAsOptional("CS_DropWeapon");
+	MarkNativeAsOptional("CS_TerminateRound");
+	MarkNativeAsOptional("CS_GetTranslatedWeaponAlias");
+	MarkNativeAsOptional("CS_GetWeaponPrice");
+	MarkNativeAsOptional("CS_GetClientClanTag");
+	MarkNativeAsOptional("CS_SetClientClanTag");
 }
 #endif
+
diff --git a/env/include/dbi.inc b/env/include/dbi.inc
index 5fb9ba8..175d1c6 100644
--- a/env/include/dbi.inc
+++ b/env/include/dbi.inc
@@ -261,20 +261,20 @@ native SQL_GetAffectedRows(Handle:hndl);
 /**
  * Returns the last query's insertion id.
  *
- * @param hndl			A database OR statement Handle.
+ * @param hndl			A database, query, OR statement Handle.
  * @return				Last query's insertion id.
- * @error				Invalid database or statement Handle.
+ * @error				Invalid database, query, or statement Handle.
  */
 native SQL_GetInsertId(Handle:hndl);
 
 /**
  * Returns the error reported by the last query.
  *
- * @param hndl			A database OR statement Handle.
+ * @param hndl			A database, query, OR statement Handle.
  * @param error			Error buffer.
  * @param maxlength		Maximum length of the buffer.
  * @return				True if there was an error, false otherwise.
- * @error				Invalid database or statement Handle.
+ * @error				Invalid database, query, or statement Handle.
  */
 native bool:SQL_GetError(Handle:hndl, String:error[], maxlength);
 
diff --git a/env/include/entity.inc b/env/include/entity.inc
index 8a7335c..6fb8d7c 100644
--- a/env/include/entity.inc
+++ b/env/include/entity.inc
@@ -1,7 +1,7 @@
 /**
  * vim: set ts=4 :
  * =============================================================================
- * SourceMod (C)2004-2008 AlliedModders LLC.  All rights reserved.
+ * SourceMod (C)2004-2011 AlliedModders LLC.  All rights reserved.
  * =============================================================================
  *
  * This file is part of the SourceMod/SourcePawn SDK.
@@ -246,7 +246,7 @@ native SetEntData(entity, offset, any:value, size=4, bool:changeState=false);
 native Float:GetEntDataFloat(entity, offset);
 
 /**
- * Peeks into an entity's object data and sets the integer value at 
+ * Peeks into an entity's object data and sets the float value at 
  * the given offset.
  *
  * @param entity		Edict index.
@@ -489,10 +489,11 @@ stock GetEntSendPropOffs(ent, const String:prop[], bool:actual=false)
  * @param size			Number of bytes to write (valid values are 1, 2, or 4).
  *						This value is auto-detected, and the size parameter is 
  *						only used as a fallback in case detection fails.
+ * @param element		Element # (starting from 0) if property is an array.
  * @return				Value at the given property offset.
  * @error				Invalid entity or property not found.
  */
-native GetEntProp(entity, PropType:type, const String:prop[], size=4);
+native GetEntProp(entity, PropType:type, const String:prop[], size=4, element=0);
 
 /**
  * Sets an integer value in an entity's property.
@@ -503,13 +504,15 @@ native GetEntProp(entity, PropType:type, const String:prop[], size=4);
  * @param entity		Entity/edict index.
  * @param type			Property type.
  * @param prop			Property name.
+ * @param value			Value to set.
  * @param size			Number of bytes to write (valid values are 1, 2, or 4).
  *						This value is auto-detected, and the size parameter is 
  *						only used as a fallback in case detection fails.
+ * @param element		Element # (starting from 0) if property is an array.
  * @error				Invalid entity or offset out of reasonable bounds.
  * @noreturn
  */
-native SetEntProp(entity, PropType:type, const String:prop[], any:value, size=4);
+native SetEntProp(entity, PropType:type, const String:prop[], any:value, size=4, element=0);
 
 /**
  * Retrieves a float value from an entity's property.
@@ -520,10 +523,11 @@ native SetEntProp(entity, PropType:type, const String:prop[], any:value, size=4)
  * @param entity		Entity/edict index.
  * @param type			Property type.
  * @param prop			Property name.
+ * @param element		Element # (starting from 0) if property is an array.
  * @return				Value at the given property offset.
  * @error				Invalid entity or offset out of reasonable bounds.
  */
-native Float:GetEntPropFloat(entity, PropType:type, const String:prop[]);
+native Float:GetEntPropFloat(entity, PropType:type, const String:prop[], element=0);
 
 /**
  * Sets a float value in an entity's property.
@@ -535,10 +539,11 @@ native Float:GetEntPropFloat(entity, PropType:type, const String:prop[]);
  * @param type			Property type.
  * @param prop			Property name.
  * @param value			Value to set.
+ * @param element		Element # (starting from 0) if property is an array.
  * @noreturn
  * @error				Invalid entity or offset out of reasonable bounds.
  */
-native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value);
+native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value, element=0);
 
 /**
  * Retrieves an entity index from an entity's property.
@@ -549,12 +554,13 @@ native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value);
  * @param entity		Entity/edict index.
  * @param type			Property type.
  * @param prop			Property name.
+ * @param element		Element # (starting from 0) if property is an array.
  * @return				Entity index at the given property.
  *						If there is no entity, or the entity is not valid, 
  *						then -1 is returned.
  * @error				Invalid entity or offset out of reasonable bounds.
  */
-native GetEntPropEnt(entity, PropType:type, const String:prop[]);
+native GetEntPropEnt(entity, PropType:type, const String:prop[], element=0);
 
 /**
  * Sets an entity index in an entity's property.
@@ -566,10 +572,11 @@ native GetEntPropEnt(entity, PropType:type, const String:prop[]);
  * @param type			Property type.
  * @param prop			Property name.
  * @param other			Entity index to set, or -1 to unset.
+ * @param element		Element # (starting from 0) if property is an array.
  * @noreturn
  * @error				Invalid entity or offset out of reasonable bounds.
  */
-native SetEntPropEnt(entity, PropType:type, const String:prop[], other);
+native SetEntPropEnt(entity, PropType:type, const String:prop[], other, element=0);
 
 /**
  * Retrieves a vector of floats from an entity, given a named network property.
@@ -581,11 +588,12 @@ native SetEntPropEnt(entity, PropType:type, const String:prop[], other);
  * @param type			Property type.
  * @param prop			Property name.
  * @param vec			Vector buffer to store data in.
+ * @param element		Element # (starting from 0) if property is an array.
  * @noreturn
  * @error				Invalid entity, property not found, or property not 
  *						actually a vector data type.
  */
-native GetEntPropVector(entity, PropType:type, const String:prop[], Float:vec[3]);
+native GetEntPropVector(entity, PropType:type, const String:prop[], Float:vec[3], element=0);
 
 /**
  * Sets a vector of floats in an entity, given a named network property.
@@ -597,11 +605,12 @@ native GetEntPropVector(entity, PropType:type, const String:prop[], Float:vec[3]
  * @param type			Property type.
  * @param prop			Property name.
  * @param vec			Vector to set.
+ * @param element		Element # (starting from 0) if property is an array.
  * @noreturn
  * @error				Invalid entity, property not found, or property not 
  *						actually a vector data type.
  */
-native SetEntPropVector(entity, PropType:type, const String:prop[], const Float:vec[3]);
+native SetEntPropVector(entity, PropType:type, const String:prop[], const Float:vec[3], element=0);
 
 /**
  * Gets a network property as a string.
@@ -611,10 +620,11 @@ native SetEntPropVector(entity, PropType:type, const String:prop[], const Float:
  * @param prop			Property to use.
  * @param buffer		Destination string buffer.
  * @param maxlen		Maximum length of output string buffer.		
+ * @param element		Element # (starting from 0) if property is an array.
  * @return				Number of non-null bytes written.
  * @error				Invalid entity, offset out of reasonable bounds, or property is not a valid string.
  */
-native GetEntPropString(entity, PropType:type, const String:prop[], String:buffer[], maxlen);
+native GetEntPropString(entity, PropType:type, const String:prop[], String:buffer[], maxlen, element=0);
 
 /**
  * Sets a network property as a string.
@@ -631,6 +641,17 @@ native GetEntPropString(entity, PropType:type, const String:prop[], String:buffe
  */
 native SetEntPropString(entity, PropType:type, const String:prop[], const String:buffer[]);
 
+/**
+ * Retrieves the count of values that an entity property's array can store.
+ * 
+ * @param entity		Entity/edict index.
+ * @param type			Property type.
+ * @param prop			Property name.
+ * @return				Size of array (in elements) or 1 if property is not an array.
+ * @error				Invalid entity or property not found.
+ */
+native GetEntPropArraySize(entity, PropType:type, const String:prop[]);
+
 /**
  * Copies an array of cells from an entity at a given offset.
  *
@@ -669,3 +690,18 @@ stock SetEntDataArray(entity, offset, const array[], arraySize, dataSize=4, bool
 		SetEntData(entity, offset + i*dataSize, array[i], dataSize, changeState);
 	}
 }
+
+/**
+ * Retrieves the classname of an entity.
+ * This is like GetEdictClassname(), except it works for ALL
+ * entities, not just edicts.
+ *
+ * @param edict			Index of the entity.
+ * @param clsname		Buffer to store the classname.
+ * @param maxlength		Maximum length of the buffer.
+ * @return				True on success, false if there is no classname set.
+ */
+stock bool:GetEntityClassname(entity, String:clsname[], maxlength)
+{
+	return !!GetEntPropString(entity, Prop_Data, "m_iClassname", clsname, maxlength);
+}
diff --git a/env/include/entity_prop_stocks.inc b/env/include/entity_prop_stocks.inc
index 855f6a6..91d7951 100644
--- a/env/include/entity_prop_stocks.inc
+++ b/env/include/entity_prop_stocks.inc
@@ -123,7 +123,8 @@ enum RenderFx
 #define IN_GRENADE1		(1 << 23)	// grenade 1
 #define IN_GRENADE2		(1 << 24)	// grenade 2
 
-// CBaseEntity::m_fFlags
+// Note: these are only for use with GetEntityFlags and SetEntityFlags
+//       and may not match the game's actual, internal m_fFlags values.
 // PLAYER SPECIFIC FLAGS FIRST BECAUSE WE USE ONLY A FEW BITS OF NETWORK PRECISION
 #define	FL_ONGROUND			(1 << 0)	// At rest / on the ground
 #define FL_DUCKING			(1 << 1)	// Player flag -- Player is fully crouched
@@ -159,36 +160,36 @@ enum RenderFx
 #define FL_DISSOLVING			(1 << 28)	// We're dissolving!
 #define FL_TRANSRAGDOLL			(1 << 29)	// In the process of turning into a client side ragdoll.
 #define FL_UNBLOCKABLE_BY_PLAYER	(1 << 30)	// pusher that can't be blocked by the player
-// END m_fFlags #defines
+#define FL_FREEZING				(1 << 31)	// We're becoming frozen!
+#define FL_EP2V_UNKNOWN1		(1 << 31)	// Unknown
+// END entity flag #defines
 
 /**
  * Get an entity's flags.
  *
+ * @note The game's actual flags are internally translated by SM
+ *       to match the entity flags defined above as the actual values
+ *       can differ per engine.
+ *
  * @param entity	Entity index.
- * @return			Entity's flags, see m_fFlag defines above
+ * @return			Entity's flags, see entity flag defines above.
  * @error			Invalid entity index, or lack of mod compliance.
  */
-stock GetEntityFlags(entity)
-{
-	static bool:gotconfig = false;
-	static String:datamap[32];
-	
-	if (!gotconfig)
-	{
-		new Handle:gc = LoadGameConfigFile("core.games");
-		new bool:exists = GameConfGetKeyValue(gc, "m_fFlags", datamap, sizeof(datamap));
-		CloseHandle(gc);
-		
-		if (!exists)
-		{
-			strcopy(datamap, sizeof(datamap), "m_fFlags");
-		}
-		
-		gotconfig = true;
-	}
-	
-	return GetEntProp(entity, Prop_Data, datamap);
-}
+native GetEntityFlags(entity);
+
+/**
+ * Sets an entity's flags.
+ *
+ * @note The entity flags as defined above are internally translated by SM
+ *       to match the current game's expected value for the flags as
+ *       the actual values can differ per engine.
+ *
+ * @param entity	Entity index.
+ * @param flags		Entity flags, see entity flag defines above.
+ * @noreturn
+ * @error			Invalid entity index, or lack of mod compliance.
+ */
+native SetEntityFlags(entity, flags);
 
 
 /**
diff --git a/env/include/halflife.inc b/env/include/halflife.inc
index c02cc55..18294d9 100644
--- a/env/include/halflife.inc
+++ b/env/include/halflife.inc
@@ -40,9 +40,12 @@
 #define SOURCE_SDK_DARKMESSIAH		15		/**< Modified version of original engine used by Dark Messiah (no SDK) */
 #define SOURCE_SDK_EPISODE1			20		/**< SDK+Engine released after Episode 1 */
 #define SOURCE_SDK_EPISODE2			30		/**< SDK+Engine released after Episode 2/Orange Box */
+#define SOURCE_SDK_BLOODYGOODTIME	32		/**< Modified version of ep2 engine used by Bloody Good Time (no SDK) */
+#define SOURCE_SDK_EYE				33		/**< Modified version of ep2 engine used by E.Y.E Divine Cybermancy (no SDK) */
 #define SOURCE_SDK_EPISODE2VALVE	35		/**< SDK+Engine released after Episode 2/Orange Box */
 #define SOURCE_SDK_LEFT4DEAD		40		/**< Engine released after Left 4 Dead (no SDK yet) */
-#define SOURCE_SDK_LEFT4DEAD2		50		/**< Engine released after Left 4 Dead 2 (no SDK yet) */
+#define SOURCE_SDK_LEFT4DEAD2		50		/**< Engine released after Left 4 Dead 2 (no SDK yet) */
+#define SOURCE_SDK_ALIENSWARM		60		/**< SDK+Engine released after Alien Swarm */
 
 #define MOTDPANEL_TYPE_TEXT		0	/**< Treat msg as plain text */
 #define MOTDPANEL_TYPE_INDEX	1	/**< Msg is auto determined by the engine */
diff --git a/env/include/keyvalues.inc b/env/include/keyvalues.inc
index 97f4991..a026b4f 100644
--- a/env/include/keyvalues.inc
+++ b/env/include/keyvalues.inc
@@ -389,7 +389,7 @@ native KvNodesInStack(Handle:kv);
  * NOTE: All KeyValues are processed from the current location not the root one.
  *
  * @param origin		Origin KeyValues Handle.
- * @param dest			Destination KeyValues Handlee.
+ * @param dest			Destination KeyValues Handle.
  * @noreturn
  * @error				Invalid Handle.
  */
diff --git a/env/include/lang.inc b/env/include/lang.inc
index 4f570a6..8d57f16 100644
--- a/env/include/lang.inc
+++ b/env/include/lang.inc
@@ -63,7 +63,7 @@ native SetGlobalTransTarget(client);
  *
  * @param client	Client index.
  * @return			Language number client is using.
- * @error			Invalid client index or client not in game.
+ * @error			Invalid client index or client not connected.
  */
 native GetClientLanguage(client);
 
@@ -94,3 +94,28 @@ native GetLanguageCount();
  */
 native GetLanguageInfo(language, String:code[]="", codeLen=0, String:name[]="", nameLen=0);
 
+/**
+ * Sets the language number of a client.
+ *
+ * @param client	Client index.
+ * @param language	Language number.
+ * @noreturn
+ * @error			Invalid client index or client not connected.
+ */
+native SetClientLanguage(client, language);
+
+/**
+ * Retrieves the language number from a language code.
+ *
+ * @param code		Language code (2-3 characters usually).
+ * @return			Language number. -1 if not found.
+ */
+native GetLanguageByCode(const String:code[]);
+
+/**
+ * Retrieves the language number from a language name.
+ *
+ * @param name		Language name (case insensitive).
+ * @return			Language number. -1 if not found.
+ */
+native GetLanguageByName(const String:name[]);
diff --git a/env/include/mapchooser.inc b/env/include/mapchooser.inc
index 7da8a29..0e9e73c 100644
--- a/env/include/mapchooser.inc
+++ b/env/include/mapchooser.inc
@@ -29,14 +29,39 @@ enum MapChange
  */
 native NominateResult:NominateMap(const String:map[], bool:force, owner);
 
+/**
+ * Attempt to remove a map from the mapchooser map list.
+ *
+ * @param map		Map to remove.
+ * @return			True if the nomination was found and removed, or false if the nomination was not found.
+ */
+native bool:RemoveNominationByMap(const String:map[]);
+
+/**
+ * Attempt to remove a map from the mapchooser map list.
+ *
+ * @param owner		Client index of the nominater.
+ * @return			True if the nomination was found and removed, or false if the nomination was not found.
+ */
+native bool:RemoveNominationByOwner(owner);
+
 /**
  * Gets the current list of excluded maps.
  *
- * @param array		An ADT array handle to add the map strings to. Needs to be 
+ * @param array		An ADT array handle to add the map strings to.
  * @noreturn
  */
 native GetExcludeMapList(Handle:array);
 
+/**
+ * Gets the current list of nominated maps.
+ *
+ * @param maparray		An ADT array handle to add the map strings to.
+ * @param ownerarray	An optional ADT array handle to add the nominator client indexes to.
+ * @noreturn
+ */
+native GetNominatedMapList(Handle:maparray, Handle:ownerarray = INVALID_HANDLE);
+
 /**
  * Checks if MapChooser will allow a vote
  *
@@ -75,6 +100,11 @@ native bool:EndOfMapVoteEnabled();
  */
 forward OnNominationRemoved(const String:map[], owner);
 
+/**
+ * Called when mapchooser starts a Map Vote.
+ */
+forward OnMapVoteStarted();
+
 
 public SharedPlugin:__pl_mapchooser = 
 {
@@ -90,7 +120,10 @@ public SharedPlugin:__pl_mapchooser =
 public __pl_mapchooser_SetNTVOptional()
 {
 	MarkNativeAsOptional("NominateMap");
+	MarkNativeAsOptional("RemoveNominationByMap");
+	MarkNativeAsOptional("RemoveNominationByOwner");
 	MarkNativeAsOptional("GetExcludeMapList");
+	MarkNativeAsOptional("GetNominatedMapList");
 	MarkNativeAsOptional("CanMapChooserStartVote");
 	MarkNativeAsOptional("InitiateMapChooserVote");
 	MarkNativeAsOptional("HasEndOfMapVoteFinished");
diff --git a/env/include/menus.inc b/env/include/menus.inc
index 8ff1d69..3d44aa8 100644
--- a/env/include/menus.inc
+++ b/env/include/menus.inc
@@ -88,6 +88,7 @@ enum MenuAction
 #define MENUFLAG_BUTTON_EXIT		(1<<0)	/**< Menu has an "exit" button (default if paginated) */
 #define MENUFLAG_BUTTON_EXITBACK	(1<<1)	/**< Menu has an "exit back" button */
 #define MENUFLAG_NO_SOUND			(1<<2)	/**< Menu will not have any select sounds */
+#define MENUFLAG_BUTTON_NOVOTE		(1<<3)	/**< Menu has a "No Vote" button at slot 1 */
 
 #define VOTEINFO_CLIENT_INDEX		0		/**< Client index */
 #define VOTEINFO_CLIENT_ITEM		1		/**< Item the client selected, or -1 for none */
diff --git a/env/include/sdktools.inc b/env/include/sdktools.inc
index 573a9d0..db96337 100644
--- a/env/include/sdktools.inc
+++ b/env/include/sdktools.inc
@@ -49,6 +49,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 enum SDKCallType
 {
@@ -57,6 +59,7 @@ enum SDKCallType
 	SDKCall_Player,		/**< CBasePlayer call */
 	SDKCall_GameRules,	/**< CGameRules call */
 	SDKCall_EntityList,	/**< CGlobalEntityList call */ 
+	SDKCall_Raw,		/**< |this| pointer with an arbitrary address */ 
 };
 
 enum SDKLibrary
diff --git a/env/include/sdktools_client.inc b/env/include/sdktools_client.inc
new file mode 100644
index 0000000..02dfcfd
--- /dev/null
+++ b/env/include/sdktools_client.inc
@@ -0,0 +1,52 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod (C)2004-2008 AlliedModders LLC.  All rights reserved.
+ * =============================================================================
+ *
+ * This file is part of the SourceMod/SourcePawn SDK.
+ *
+ * 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$
+ */
+
+#if defined _sdktools_client_included
+  #endinput
+#endif
+#define _sdktools_client_included
+
+/**
+ * Sets the client to an inactive state waiting for a new map
+ *
+ * @param client		The client index
+ * @noreturn
+ */
+native InactivateClient(client);
+
+/**
+ * Reconnect a client without dropping the netchannel
+ *
+ * @param client		The client index
+ * @noreturn
+ */
+native ReconnectClient(client);
diff --git a/env/include/sdktools_functions.inc b/env/include/sdktools_functions.inc
index 507af1d..c8e3705 100644
--- a/env/include/sdktools_functions.inc
+++ b/env/include/sdktools_functions.inc
@@ -148,7 +148,7 @@ native bool:GetClientEyeAngles(client, Float:ang[3]);
  *  invalid or there is already an edict using that index, it will error out.
  *
  * @param classname			Entity classname.
- * @param ForceEdictIndex	Edict index used by the created entity.
+ * @param ForceEdictIndex	Edict index used by the created entity (ignored on Orangebox and above).
  * @return					Entity index on success, or -1 on failure.
  * @error					Invalid edict index, or no mod support.
  */
diff --git a/env/include/sdktools_gamerules.inc b/env/include/sdktools_gamerules.inc
new file mode 100644
index 0000000..967963d
--- /dev/null
+++ b/env/include/sdktools_gamerules.inc
@@ -0,0 +1,194 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod (C)2004-2011 AlliedModders LLC.  All rights reserved.
+ * =============================================================================
+ *
+ * This file is part of the SourceMod/SourcePawn SDK.
+ *
+ * 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$
+ */
+
+#if defined _sdktools_gamerules_included
+  #endinput
+#endif
+#define _sdktools_gamerules_included
+
+enum RoundState {
+	// initialize the game, create teams
+	RoundState_Init,
+	
+	//Before players have joined the game. Periodically checks to see if enough players are ready
+	//to start a game. Also reverts to this when there are no active players
+	RoundState_Pregame,
+	
+	//The game is about to start, wait a bit and spawn everyone
+	RoundState_StartGame,
+	
+	//All players are respawned, frozen in place
+	RoundState_Preround,
+	
+	//Round is on, playing normally
+	RoundState_RoundRunning,
+	
+	//Someone has won the round
+	RoundState_TeamWin,
+	
+	//Noone has won, manually restart the game, reset scores
+	RoundState_Restart,
+	
+	//Noone has won, restart the game
+	RoundState_Stalemate,
+	
+	//Game is over, showing the scoreboard etc
+	RoundState_GameOver,
+	
+	//Game is over, doing bonus round stuff
+	RoundState_Bonus,
+};
+
+/**
+ * Retrieves an integer value from a property of the gamerules entity.
+ * 
+ * @param prop			Property name.
+ * @param size			Number of bytes to read (valid values are 1, 2, or 4).
+ *						This value is auto-detected, and the size parameter is 
+ *						only used as a fallback in case detection fails.
+ * @param element		Element # (starting from 0) if property is an array.
+ * @return				Value at the given property offset.
+ * @error				Not supported.
+ */
+native GameRules_GetProp(const String:prop[], size=4, element=0);
+
+/**
+ * Sets an integer value for a property of the gamerules entity.
+ *
+ * @param prop			Property name.
+ * @param value			Value to set.
+ * @param size			Number of bytes to write (valid values are 1, 2, or 4).
+ *						This value is auto-detected, and the size parameter is 
+ *						only used as a fallback in case detection fails.
+ * @param element		Element # (starting from 0) if property is an array.
+ * @error				Not supported.
+ * @noreturn
+ */
+native GameRules_SetProp(const String:prop[], any:value, size=4, element=0, bool:changeState=false);
+
+/**
+ * Retrieves a float value from a property of the gamerules entity.
+ * 
+ * @param prop			Property name.
+ * @param element		Element # (starting from 0) if property is an array.
+ * @return				Value at the given property offset.
+ * @error				Not supported.
+ */
+native Float:GameRules_GetPropFloat(const String:prop[], element=0);
+
+/**
+ * Sets a float value for a property of the gamerules entity.
+ * 
+ * @param prop			Property name.
+ * @param value			Value to set.
+ * @param element		Element # (starting from 0) if property is an array.
+ * @noreturn
+ * @error				Not supported.
+ */
+native GameRules_SetPropFloat(const String:prop[], Float:value, element=0, bool:changeState=false);
+
+/**
+ * Retrieves a entity index from a property of the gamerules entity.
+ * 
+ * @param prop			Property name.
+ * @param element		Element # (starting from 0) if property is an array.
+ * @return				Entity index at the given property.
+ *						If there is no entity, or the entity is not valid, 
+ *						then -1 is returned.
+ * @error				Not supported.
+ */
+native GameRules_GetPropEnt(const String:prop[], element=0);
+
+/**
+ * Sets an entity index for a property of the gamerules entity.
+ * 
+ * @param prop			Property name.
+ * @param other			Entity index to set, or -1 to unset.
+ * @param element		Element # (starting from 0) if property is an array.
+ * @noreturn
+ * @error				Not supported.
+ */
+native GameRules_SetPropEnt(const String:prop[], other, element=0, bool:changeState=false);
+
+/**
+ * Retrieves a vector of floats from the gamerules entity, given a named network property.
+ * 
+ * @param prop			Property name.
+ * @param vec			Vector buffer to store data in.
+ * @param element		Element # (starting from 0) if property is an array.
+ * @noreturn
+ * @error				Not supported.
+ */
+native GameRules_GetPropVector(const String:prop[], Float:vec[3], element=0);
+
+/**
+ * Sets a vector of floats in the gamerules entity, given a named network property.
+ *
+ * @param prop			Property name.
+ * @param vec			Vector to set.
+ * @param element		Element # (starting from 0) if property is an array.
+ * @noreturn
+ * @error				Not supported.
+ */
+native GameRules_SetPropVector(const String:prop[], const Float:vec[3], element=0, bool:changeState=false);
+
+/**
+ * Gets a gamerules property as a string.
+ * 
+ * @param prop			Property to use.
+ * @param buffer		Destination string buffer.
+ * @param maxlen		Maximum length of output string buffer.
+ * @return				Number of non-null bytes written.
+ * @error				Not supported.
+ */
+native GameRules_GetPropString(const String:prop[], String:buffer[], maxlen);
+
+/**
+ * Sets a gamerules property as a string.
+ *
+ * @param prop			Property to use.
+ * @param buffer		String to set.		
+ * @return				Number of non-null bytes written.
+ * @error				Not supported.
+ */
+native GameRules_SetPropString(const String:prop[], const String:buffer[], bool:changeState=false);
+
+/**
+ * Gets the current round state.
+ *
+ * @return				Round state.
+ * @error				Game doesn't support round state.
+ */
+stock RoundState:GameRules_GetRoundState()
+{
+	return RoundState:GameRules_GetProp("m_iRoundState");
+}
diff --git a/env/include/sdktools_sound.inc b/env/include/sdktools_sound.inc
index dc9e099..a978dbd 100644
--- a/env/include/sdktools_sound.inc
+++ b/env/include/sdktools_sound.inc
@@ -257,6 +257,15 @@ native EmitSentence(const clients[],
 				 bool:updatePos = true,
 				 Float:soundtime = 0.0,
 				 any:...);
+				 
+/**
+ *Calculates gain of sound on given distance with given sound level in decibel
+ *
+ * @param soundlevel	decibel of sound, like SNDLEVEL_NORMAL or integer value
+ * @param distance	distance of sound to calculate, not meter or feet, but Source Engine`s normal Coordinate unit
+ * @return			gain of sound. you can multiply this with original sound`s volume to calculate volume on given distance
+ */
+native Float:GetDistGainFromSoundLevel(soundlevel, Float:distance);
 
 /**
  * Called when an ambient sound is about to be emitted to one or more clients.
diff --git a/env/include/sourcemod.inc b/env/include/sourcemod.inc
index bf27516..8d165f7 100644
--- a/env/include/sourcemod.inc
+++ b/env/include/sourcemod.inc
@@ -386,6 +386,16 @@ native GameConfGetOffset(Handle:gc, const String:key[]);
  */
 native bool:GameConfGetKeyValue(Handle:gc, const String:key[], String:buffer[], maxlen);
 
+/*
+ * Finds an address calculation in a GameConfig file,
+ * performs LoadFromAddress on it as appropriate, then returns the final address.
+ *
+ * @param gameconf      GameConfig Handle, or INVALID_HANDLE to use sdktools.games.txt.
+ * @param name          Name of the property to find.
+ * @return              An address calculated on success, or 0 on failure.
+ */
+native Address:GameConfGetAddress(Handle:gameconf, const String:name[]);
+
 /**
  * Returns the operating system's "tick count," which is a number of 
  * milliseconds since the operating system loaded.  This can be used
@@ -630,6 +640,41 @@ native FeatureStatus:GetFeatureStatus(FeatureType:type, const String:name[]);
 native RequireFeature(FeatureType:type, const String:name[],
                       const String:fmt[]="", any:...);
 
+/**
+ * Represents how many bytes we can read from an address with one load
+ */
+enum NumberType
+{
+    NumberType_Int8,
+    NumberType_Int16,
+    NumberType_Int32
+};
+
+enum Address
+{
+    Address_Null = 0,              //a typical invalid result when an address lookup fails
+    Address_MinimumValid = 0x10000 //addresses below this value are considered invalid to use for Load/Store
+};
+
+/**
+ * Load up to 4 bytes from a memory address.
+ *
+ * @param addr          Address to a memory location.
+ * @param size          How many bytes should be read.
+ * @return              The value that is stored at that address.
+ */
+native LoadFromAddress(Address:addr, NumberType:size);
+
+/**
+ * Store up to 4 bytes to a memory address.
+ *
+ * @param addr          Address to a memory location.
+ * @param data          Value to store at the address.
+ * @param size          How many bytes should be written.
+ * @noreturn
+ */
+native StoreToAddress(Address:addr, data, NumberType:size); 
+
 #include 
 #include 
 #include 
diff --git a/env/include/string.inc b/env/include/string.inc
index 6369c8a..957ad68 100644
--- a/env/include/string.inc
+++ b/env/include/string.inc
@@ -379,7 +379,7 @@ native bool:IsCharLower(chr);
 
 /**
  * Strips a quote pair off a string if it exists.  That is, the following 
- * replace rule is applied once:  $"(.*)"^ -> $\1^
+ * replace rule is applied once:  ^"(.*)"$ -> ^\1$
  *
  * Note that the leading and trailing quotes will only be removed if both 
  * exist.  Otherwise, the string is left unmodified.  This function should 
@@ -490,35 +490,35 @@ stock StrCat(String:buffer[], maxlength, const String:source[])
  * @param buffers			An array of string buffers (2D array).
  * @param maxStrings		Number of string buffers (first dimension size).
  * @param maxStringLength	Maximum length of each string buffer.
+ * @param copyRemainder		False (default) discard excess pieces, true to ignore
+ *							delimiters after last piece.
  * @return					Number of strings retrieved.
  */
-stock ExplodeString(const String:text[], const String:split[], String:buffers[][], maxStrings, maxStringLength)
+stock ExplodeString(const String:text[], const String:split[], String:buffers[][], maxStrings,
+                    maxStringLength, bool:copyRemainder = false)
 {
 	new reloc_idx, idx, total;
-	
-	if (maxStrings < 1 || split[0] == '\0')
+
+	if (maxStrings < 1 || !split[0])
 	{
 		return 0;
 	}
-	
+
 	while ((idx = SplitString(text[reloc_idx], split, buffers[total], maxStringLength)) != -1)
 	{
 		reloc_idx += idx;
-		if (text[reloc_idx] == '\0')
-		{
-			break;
-		}
-		if (++total >= maxStrings)
+		if (++total == maxStrings)
 		{
+			if (copyRemainder)
+			{
+				strcopy(buffers[total-1], maxStringLength, text[reloc_idx-idx]);
+			}
 			return total;
 		}
 	}
-	
-	if (text[reloc_idx] != '\0' && total <= maxStrings - 1)
-	{
-		strcopy(buffers[total++], maxStringLength, text[reloc_idx]);
-	}
-	
+
+	strcopy(buffers[total++], maxStringLength, text[reloc_idx]);
+
 	return total;
 }
 
diff --git a/env/include/tf2.inc b/env/include/tf2.inc
index d8b0068..bba1efd 100644
--- a/env/include/tf2.inc
+++ b/env/include/tf2.inc
@@ -82,10 +82,12 @@ enum TFCond
 	TFCond_TeleportedGlow,
 	TFCond_Taunting,
 	TFCond_UberchargeFading,
-	TFCond_Unknown1,
+	TFCond_Unknown1, //9
+	TFCond_CloakFlicker = 9,
 	TFCond_Teleporting,
 	TFCond_Kritzkrieged,
-	TFCond_Unknown2,
+	TFCond_Unknown2, //12
+	TFCond_TmpDamageBonus = 12,
 	TFCond_DeadRingered,
 	TFCond_Bonked,
 	TFCond_Dazed,
@@ -93,17 +95,51 @@ enum TFCond
 	TFCond_Charging,
 	TFCond_DemoBuff,
 	TFCond_CritCola,
+	TFCond_InHealRadius,
 	TFCond_Healing,
 	TFCond_OnFire,
 	TFCond_Overhealed,
-	TFCond_Jarated
+	TFCond_Jarated,
+	TFCond_Bleeding,
+	TFCond_DefenseBuffed,
+	TFCond_Milked,
+	TFCond_MegaHeal,
+	TFCond_RegenBuffed,
+	TFCond_MarkedForDeath,
+	TFCond_NoHealingDamageBuff,
+	TFCond_SpeedBuffAlly,
+	TFCond_HalloweenCritCandy,
+	
+	TFCond_CritHype = 36,
+	TFCond_CritOnFirstBlood,
+	TFCond_CritOnWin,
+	TFCond_CritOnFlagCapture,
+	TFCond_CritOnKill,
+	TFCond_RestrictToMelee
 };
 
 enum TFHoliday
 {
-	TFHoliday_None = 1,
+	TFHoliday_Birthday = 1,
 	TFHoliday_Halloween,
-	TFHoliday_Birthday
+	TFHoliday_FullMoon,
+	TFHoliday_HalloweenOrFullMoon,
+};
+
+enum TFObjectType
+{
+	TFObject_CartDispenser = 0,
+	TFObject_Dispenser = 0,
+	TFObject_Teleporter = 1,
+	TFObject_Sentry = 2,
+	TFObject_Sapper = 3
+};
+
+enum TFObjectMode
+{
+	TFObjectMode_None = 0,
+	TFObjectMode_Entrance = 0,
+	TFObjectMode_Exit = 1
 };
 
 /**
@@ -172,10 +208,11 @@ native TF2_SetPlayerPowerPlay(client, bool:enabled);
  * @param client		Player's index.
  * @param team			Team to disguise the player as (only TFTeam_Red and TFTeam_Blue have an effect)
  * @param class			TFClassType class to disguise the player as
+ * @param target		Specific target player to disguise as (0 for any)
  * @noreturn
  * @error				Invalid client index, client not in game, or no mod support.
  */
-native TF2_DisguisePlayer(client, TFTeam:team, TFClassType:class);
+native TF2_DisguisePlayer(client, TFTeam:team, TFClassType:class, target=0);
 
 /**
  * Removes the current disguise from a client. Only has an effect on spies.
@@ -199,6 +236,16 @@ native TF2_RemovePlayerDisguise(client);
  */
 native TF2_StunPlayer(client, Float:duration, Float:slowdown=0.0, stunflags, attacker=0);
 
+/**
+ * Induces the bleed effect on a client
+ *
+ * @param client		Player's index.
+ * @param attacker		Attacker's index.
+ * @param float			Duration of bleeding (in seconds).
+ * @noreturn
+ */
+native TF2_MakeBleed(client, attacker, Float:duration);
+
 /**
  * Retrieves the entity index of the CPlayerResource entity
  *
@@ -232,15 +279,62 @@ native TFClassType:TF2_GetClass(const String:classname[]);
 forward Action:TF2_CalcIsAttackCritical(client, weapon, String:weaponname[], &bool:result);
 
 /**
- * Called when the game checks to see if the current day is one of its tracked holidays
- *
- * @note Change the value of holiday and return Plugin_Changed to override.
- *       Return Plugin_Continue for no change.
- *
- * @param holiday		Current Holiday
+ * @deprecated		No longer called. Use TF2_OnIsHolidayActive.
  */
+#pragma deprecated No longer called. Use TF2_OnIsHolidayActive.
 forward Action:TF2_OnGetHoliday(&TFHoliday:holiday);
 
+/**
+ * Called at various times when the game checks to see if the given holiday is active.
+ * Return Plugin_Continue to let the original calculation or return a higher
+ * action to override the decision with the value of 'result'
+ *
+ * @param holiday		Holiday being checked.
+ * @param result		Buffer param for the result of the decision.
+ * @return				Plugin_Continue for original calculation, higher value to use 'result'.
+ */
+forward Action:TF2_OnIsHolidayActive(TFHoliday:holiday, &bool:result);
+
+/**
+ * Returns whether or not a client (Player) is in a duel.
+ *
+ * @param client    Client Index.
+ * @return          Boolean of whether or not the client/player is dueling.
+ */
+native bool:TF2_IsPlayerInDuel(client);
+
+/**
+ * Called after a condition is added to a player
+ *
+ * @param client		Index of the client to which the conditon is being added.
+ * @param condition     Condition that is being added.
+ * @noreturn
+ */
+forward TF2_OnConditionAdded(client, TFCond:condition);
+
+/**
+ * Called after a condition is removed from a player
+ *
+ * @param client		Index of the client to which the condition is being removed.
+ * @param condition		Condition that is being removed.
+ * @noreturn
+ */
+forward TF2_OnConditionRemoved(client, TFCond:condition);
+
+/**
+ * Called when the server enters the Waiting for Players round state
+ *
+ * @noreturn
+ */
+forward TF2_OnWaitingForPlayersStart();
+
+/**
+ * Called when the server exits the Waiting for Players round state
+ *
+ * @noreturn
+ */
+forward TF2_OnWaitingForPlayersEnd();
+
 /**
  * Do not edit below this line!
  */
@@ -268,7 +362,9 @@ public __ext_tf2_SetNTVOptional()
 	MarkNativeAsOptional("TF2_DisguisePlayer");
 	MarkNativeAsOptional("TF2_RemovePlayerDisguise");
 	MarkNativeAsOptional("TF2_StunPlayer");
+	MarkNativeAsOptional("TF2_MakeBleed");
 	MarkNativeAsOptional("TF2_GetResourceEntity");
 	MarkNativeAsOptional("TF2_GetClass");
+	MarkNativeAsOptional("TF2_IsPlayerInDuel");
 }
 #endif
diff --git a/env/include/tf2_stocks.inc b/env/include/tf2_stocks.inc
index cfa13c8..dff35b6 100644
--- a/env/include/tf2_stocks.inc
+++ b/env/include/tf2_stocks.inc
@@ -48,6 +48,7 @@
 #define TF_CONDFLAG_TELEPORTGLOW    (1 << 6)
 #define TF_CONDFLAG_TAUNTING        (1 << 7)
 #define TF_CONDFLAG_UBERCHARGEFADE  (1 << 8)
+#define TF_CONDFLAG_CLOAKFLICKER    (1 << 9)
 #define TF_CONDFLAG_TELEPORTING     (1 << 10)
 #define TF_CONDFLAG_KRITZKRIEGED    (1 << 11)
 #define TF_CONDFLAG_DEADRINGERED    (1 << 13)
@@ -57,10 +58,17 @@
 #define TF_CONDFLAG_CHARGING        (1 << 17)
 #define TF_CONDFLAG_DEMOBUFF        (1 << 18)
 #define TF_CONDFLAG_CRITCOLA        (1 << 19)
-#define TF_CONDFLAG_HEALING         (1 << 20)
-#define TF_CONDFLAG_ONFIRE          (1 << 21)
-#define TF_CONDFLAG_OVERHEALED      (1 << 22)
-#define TF_CONDFLAG_JARATED         (1 << 23)
+#define TF_CONDFLAG_INHEALRADIUS    (1 << 20)
+#define TF_CONDFLAG_HEALING         (1 << 21)
+#define TF_CONDFLAG_ONFIRE          (1 << 22)
+#define TF_CONDFLAG_OVERHEALED      (1 << 23)
+#define TF_CONDFLAG_JARATED         (1 << 24)
+#define TF_CONDFLAG_BLEEDING        (1 << 25)
+#define TF_CONDFLAG_DEFENSEBUFFED   (1 << 26)
+#define TF_CONDFLAG_MILKED          (1 << 27)
+#define TF_CONDFLAG_MEGAHEAL        (1 << 28)
+#define TF_CONDFLAG_REGENBUFFED     (1 << 29)
+#define TF_CONDFLAG_MARKEDFORDEATH  (1 << 30)
 
 #define TF_DEATHFLAG_KILLERDOMINATION   (1 << 0)
 #define TF_DEATHFLAG_ASSISTERDOMINATION (1 << 1)
@@ -68,6 +76,171 @@
 #define TF_DEATHFLAG_ASSISTERREVENGE    (1 << 3)
 #define TF_DEATHFLAG_FIRSTBLOOD         (1 << 4)
 #define TF_DEATHFLAG_DEADRINGER         (1 << 5)
+#define TF_DEATHFLAG_INTERRUPTED        (1 << 6)
+#define TF_DEATHFLAG_GIBBED             (1 << 7)
+#define TF_DEATHFLAG_PURGATORY          (1 << 8)
+
+// Custom kill identifiers for the customkill property on the player_death event
+enum {
+	TF_CUSTOM_HEADSHOT = 1,
+	TF_CUSTOM_BACKSTAB,
+	TF_CUSTOM_BURNING,
+	TF_CUSTOM_WRENCH_FIX,
+	TF_CUSTOM_MINIGUN,
+	TF_CUSTOM_SUICIDE,
+	TF_CUSTOM_TAUNT_HADOUKEN,
+	TF_CUSTOM_BURNING_FLARE,
+	TF_CUSTOM_TAUNT_HIGH_NOON,
+	TF_CUSTOM_TAUNT_GRAND_SLAM,
+	TF_CUSTOM_PENETRATE_MY_TEAM,
+	TF_CUSTOM_PENETRATE_ALL_PLAYERS,
+	TF_CUSTOM_TAUNT_FENCING,
+	TF_CUSTOM_PENETRATE_HEADSHOT,
+	TF_CUSTOM_TAUNT_ARROW_STAB,
+	TF_CUSTOM_TELEFRAG,
+	TF_CUSTOM_BURNING_ARROW,
+	TF_CUSTOM_FLYINGBURN,
+	TF_CUSTOM_PUMPKIN_BOMB,
+	TF_CUSTOM_DECAPITATION,
+	TF_CUSTOM_TAUNT_GRENADE,
+	TF_CUSTOM_BASEBALL,
+	TF_CUSTOM_CHARGE_IMPACT,
+	TF_CUSTOM_TAUNT_BARBARIAN_SWING,
+	TF_CUSTOM_AIR_STICKY_BURST,
+	TF_CUSTOM_DEFENSIVE_STICKY,
+	TF_CUSTOM_PICKAXE,
+	TF_CUSTOM_ROCKET_DIRECTHIT,
+	TF_CUSTOM_TAUNT_UBERSLICE,
+	TF_CUSTOM_PLAYER_SENTRY,
+	TF_CUSTOM_STANDARD_STICKY,
+	TF_CUSTOM_SHOTGUN_REVENGE_CRIT,
+	TF_CUSTOM_TAUNT_ENGINEER_SMASH,
+	TF_CUSTOM_BLEEDING,
+	TF_CUSTOM_GOLD_WRENCH,
+	TF_CUSTOM_CARRIED_BUILDING,
+	TF_CUSTOM_COMBO_PUNCH,
+	TF_CUSTOM_TAUNT_ENGINEER_ARM,
+	TF_CUSTOM_FISH_KILL,
+	TF_CUSTOM_TRIGGER_HURT,
+	TF_CUSTOM_DECAPITATION_BOSS,
+	TF_CUSTOM_STICKBOMB_EXPLOSION,
+	TF_CUSTOM_AEGIS_ROUND,
+	TF_CUSTOM_FLARE_EXPLOSION,
+	TF_CUSTOM_BOOTS_STOMP,
+	TF_CUSTOM_PLASMA,
+	TF_CUSTOM_PLASMA_CHARGED,
+	TF_CUSTOM_PLASMA_GIB,
+	TF_CUSTOM_PRACTICE_STICKY,
+	TF_CUSTOM_EYEBALL_ROCKET,
+};
+
+// Weapon codes as used in some events, such as player_death
+// (not to be confused with Item Definition Indexes)
+enum {
+	TF_WEAPON_NONE = 0,
+	TF_WEAPON_BAT,
+	TF_WEAPON_BAT_WOOD,
+	TF_WEAPON_BOTTLE,
+	TF_WEAPON_FIREAXE,
+	TF_WEAPON_CLUB,
+	TF_WEAPON_CROWBAR,
+	TF_WEAPON_KNIFE,
+	TF_WEAPON_FISTS,
+	TF_WEAPON_SHOVEL,
+	TF_WEAPON_WRENCH,
+	TF_WEAPON_BONESAW,
+	TF_WEAPON_SHOTGUN_PRIMARY,
+	TF_WEAPON_SHOTGUN_SOLDIER,
+	TF_WEAPON_SHOTGUN_HWG,
+	TF_WEAPON_SHOTGUN_PYRO,
+	TF_WEAPON_SCATTERGUN,
+	TF_WEAPON_SNIPERRIFLE,
+	TF_WEAPON_MINIGUN,
+	TF_WEAPON_SMG,
+	TF_WEAPON_SYRINGEGUN_MEDIC,
+	TF_WEAPON_TRANQ,
+	TF_WEAPON_ROCKETLAUNCHER,
+	TF_WEAPON_GRENADELAUNCHER,
+	TF_WEAPON_PIPEBOMBLAUNCHER,
+	TF_WEAPON_FLAMETHROWER,
+	TF_WEAPON_GRENADE_NORMAL,
+	TF_WEAPON_GRENADE_CONCUSSION,
+	TF_WEAPON_GRENADE_NAIL,
+	TF_WEAPON_GRENADE_MIRV,
+	TF_WEAPON_GRENADE_MIRV_DEMOMAN,
+	TF_WEAPON_GRENADE_NAPALM,
+	TF_WEAPON_GRENADE_GAS,
+	TF_WEAPON_GRENADE_EMP,
+	TF_WEAPON_GRENADE_CALTROP,
+	TF_WEAPON_GRENADE_PIPEBOMB,
+	TF_WEAPON_GRENADE_SMOKE_BOMB,
+	TF_WEAPON_GRENADE_HEAL,
+	TF_WEAPON_GRENADE_STUNBALL,
+	TF_WEAPON_GRENADE_JAR,
+	TF_WEAPON_GRENADE_JAR_MILK,
+	TF_WEAPON_PISTOL,
+	TF_WEAPON_PISTOL_SCOUT,
+	TF_WEAPON_REVOLVER,
+	TF_WEAPON_NAILGUN,
+	TF_WEAPON_PDA,
+	TF_WEAPON_PDA_ENGINEER_BUILD,
+	TF_WEAPON_PDA_ENGINEER_DESTROY,
+	TF_WEAPON_PDA_SPY,
+	TF_WEAPON_BUILDER,
+	TF_WEAPON_MEDIGUN,
+	TF_WEAPON_GRENADE_MIRVBOMB,
+	TF_WEAPON_FLAMETHROWER_ROCKET,
+	TF_WEAPON_GRENADE_DEMOMAN,
+	TF_WEAPON_SENTRY_BULLET,
+	TF_WEAPON_SENTRY_ROCKET,
+	TF_WEAPON_DISPENSER,
+	TF_WEAPON_INVIS,
+	TF_WEAPON_FLAREGUN,
+	TF_WEAPON_LUNCHBOX,
+	TF_WEAPON_JAR,
+	TF_WEAPON_COMPOUND_BOW,
+	TF_WEAPON_BUFF_ITEM,
+	TF_WEAPON_PUMPKIN_BOMB,
+	TF_WEAPON_SWORD,
+	TF_WEAPON_DIRECTHIT,
+	TF_WEAPON_LIFELINE,
+	TF_WEAPON_LASER_POINTER,
+	TF_WEAPON_DISPENSER_GUN,
+	TF_WEAPON_SENTRY_REVENGE,
+	TF_WEAPON_JAR_MILK,
+	TF_WEAPON_HANDGUN_SCOUT_PRIMARY,
+	TF_WEAPON_BAT_FISH,
+	TF_WEAPON_CROSSBOW,
+	TF_WEAPON_STICKBOMB,
+	TF_WEAPON_HANDGUN_SCOUT_SEC,
+	TF_WEAPON_SODA_POPPER,
+	TF_WEAPON_SNIPERRIFLE_DECAP,
+	TF_WEAPON_RAYGUN,
+	TF_WEAPON_PARTICLE_CANNON,
+	TF_WEAPON_MECHANICAL_ARM,
+};
+
+// TF2 Weapon Slots for GetPlayerWeaponSlot
+enum
+{
+	TFWeaponSlot_Primary,
+	TFWeaponSlot_Secondary,
+	TFWeaponSlot_Melee,
+	TFWeaponSlot_Grenade,
+	TFWeaponSlot_Building,
+	TFWeaponSlot_PDA,
+	TFWeaponSlot_Item1,
+	TFWeaponSlot_Item2	
+};
+
+// Identifiers for the eventtype property on the teamplay_flag_event event
+enum {
+	TF_FLAGEVENT_PICKEDUP = 1,
+	TF_FLAGEVENT_CAPTURED,
+	TF_FLAGEVENT_DEFENDED,
+	TF_FLAGEVENT_DROPPED,
+	TF_FLAGEVENT_RETURNED
+};
 
 enum TFResourceType
 {
@@ -133,15 +306,15 @@ stock TFClassType:TF2_GetPlayerClass(client)
  * @param client		Player's index.
  * @param class			TFClassType class symbol.
  * @param weapons		This paramater is ignored.
- * @param persistant	If true changes the players desired class so the change stays after death.
+ * @param persistent	If true changes the players desired class so the change stays after death.
  * @noreturn
  * @error				Invalid client index.
  */
-stock TF2_SetPlayerClass(client, TFClassType:class, bool:weapons=true, bool:persistant=true)
+stock TF2_SetPlayerClass(client, TFClassType:class, bool:weapons=true, bool:persistent=true)
 {
 	SetEntProp(client, Prop_Send, "m_iClass", _:class);
 	
-	if (persistant)
+	if (persistent)
 	{
 		SetEntProp(client, Prop_Send, "m_iDesiredPlayerClass", _:class);
 	}
@@ -254,7 +427,80 @@ stock TF2_RemoveAllWeapons(client)
  * @param client		Player's index.
  * @return				Player's condition bits
  */
+#pragma deprecated Use TF2_IsPlayerInCondition instead.
 stock TF2_GetPlayerConditionFlags(client)
 {
-	return GetEntProp(client, Prop_Send, "m_nPlayerCond");
+	return GetEntProp(client, Prop_Send, "m_nPlayerCond")|GetEntProp(client, Prop_Send, "_condition_bits");
+}
+
+/**
+ * Check whether or not a condition is set on a player
+ *
+ * @param client		Player's index.
+ * @return				True if set, false otherwise
+ */
+stock bool:TF2_IsPlayerInCondition(client, TFCond:cond)
+{
+	// Conditions are stored across two netprops now, one for each 32-bit segment.
+	if (_:cond < 32)
+	{
+		new bit = 1 << _:cond;
+		if ((GetEntProp(client, Prop_Send, "m_nPlayerCond") & bit) == bit)
+		{
+			return true;
+		}
+		
+		if ((GetEntProp(client, Prop_Send, "_condition_bits") & bit) == bit)
+		{
+			return true;
+		}
+	}
+	else
+	{
+		new bit = (1 << (_:cond - 32));
+		if ((GetEntProp(client, Prop_Send, "m_nPlayerCondEx") & bit) == bit)
+		{
+			return true;
+		}
+	}
+	
+	return false;
+}
+
+/**
+ * Gets an entity's object type.
+ *
+ * @param entity		Entity index.
+ * @return				Current TFObjectType of entity.
+ * @error				Invalid entity index.
+ */
+stock TFObjectType:TF2_GetObjectType(entity)
+{
+	new offset = GetEntSendPropOffs(entity, "m_iObjectType");
+	
+	if (offset <= 0)
+	{
+		ThrowError("Entity index %d is not an object", entity);
+	}
+	
+	return TFObjectType:GetEntData(entity, offset);
+}
+
+/**
+ * Gets an entity's object mode.
+ *
+ * @param entity		Entity index.
+ * @return				Current TFObjectMode of entity.
+ * @error				Invalid entity index.
+ */
+stock TFObjectMode:TF2_GetObjectMode(entity)
+{
+	new offset = GetEntSendPropOffs(entity, "m_iObjectMode");
+	
+	if (offset <= 0)
+	{
+		ThrowError("Entity index %d is not an object", entity);
+	}
+	
+	return TFObjectMode:GetEntData(entity, offset);
 }
diff --git a/env/include/version.inc b/env/include/version.inc
index fe346f3..50accf5 100644
--- a/env/include/version.inc
+++ b/env/include/version.inc
@@ -36,7 +36,7 @@
 #define _version_included
 
 #define SOURCEMOD_V_MAJOR		1				/**< SourceMod Major version */
-#define SOURCEMOD_V_MINOR		3				/**< SourceMod Minor version */
-#define SOURCEMOD_V_RELEASE		4				/**< SourceMod Release version */
+#define SOURCEMOD_V_MINOR		4				/**< SourceMod Minor version */
+#define SOURCEMOD_V_RELEASE		1				/**< SourceMod Release version */
 
-#define SOURCEMOD_VERSION	"1.3.4"				/**< SourceMod version string (major.minor.release.build) */
+#define SOURCEMOD_VERSION	"1.4.1"	/**< SourceMod version string (major.minor.release.build) */
diff --git a/env/linux/bin/spcomp-1.4.1 b/env/linux/bin/spcomp-1.4.1
new file mode 100755
index 0000000..5d9dd96
Binary files /dev/null and b/env/linux/bin/spcomp-1.4.1 differ
diff --git a/env/win32/bin/spcomp-1.4.1.exe b/env/win32/bin/spcomp-1.4.1.exe
new file mode 100644
index 0000000..1f52d8f
Binary files /dev/null and b/env/win32/bin/spcomp-1.4.1.exe differ
diff --git a/src/include/zr/infect.zr.inc b/src/include/zr/infect.zr.inc
index e3b9ce3..f6de92b 100644
--- a/src/include/zr/infect.zr.inc
+++ b/src/include/zr/infect.zr.inc
@@ -1,123 +1,123 @@
-/*
- * ============================================================================
- *
- *  Zombie:Reloaded
- *
- *  File:          infect.zr.inc
- *  Type:          Include
- *  Description:   Infect-related natives/forwards.
- *
- *  Copyright (C) 2009-2010  Greyscale, Richard Helgeby
- *
- *  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 3 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, see .
- *
- * ============================================================================
- */
-
-/**
- * Returns true if the player is a zombie, false if not.
- *
- * @param client            The client index.
- *  
- * @return			        True if zombie, false if not.
- * @error                   Invalid client index, not connected or not alive.
- */
-native bool:ZR_IsClientZombie(client);
-
-/**
- * Returns true if the player is a human, false if not.
- *
- * @param client            The client index.
- *  
- * @return			        True if human, false if not.
- * @error                   Invalid client index, not connected or not alive.
- */
-native bool:ZR_IsClientHuman(client);
-
-/**
- * Infects a player.
- *
- * Note: If the player already is a zombie, the player will be re-infected.
- *
- * @param client            The client to infect.
- * @param attacker          (Optional) The attacker who did the infect.
- * @param motherInfect      (Optional) Infect as a mother zombie.
- * @param respawnOverride   (Optional) Set to true to override respawn cvar.
- * @param respawn           (Optional) Value to override with.
- *
- * @error                   Invalid client index, not connected or not alive.
- */
-native ZR_InfectClient(client, attacker = -1, bool:motherInfect = false, bool:respawnOverride = false, bool:respawn = false);
-
-/**
- * Turns a zombie back into a human.
- *
- * Note: If the player already is a human, this code will still run as the
- *       player was a zombie.
- *
- * @param client            The client to make human.
- * @param respawn           Teleport client back to spawn.
- * @param protect           Start spawn protection on client.
- *
- * @error                   Invalid client index, not connected or not alive.
- */
-native ZR_HumanClient(client, bool:respawn = false, bool:protect = false);
-
-/**
- * Called when a player is about to become a zombie.
- * Here you can modify any variable or block the infection entirely.
- * 
- * @param client            The client index.
- * @param attacker          The the infecter. (-1 if there is no infecter)
- * @param motherInfect      If the client is becoming a mother zombie.
- * @param respawnOverride   True if the respawn cvar is being overridden.
- * @param respawn           The value that respawn is being overridden with.
- * 
- * @return                  Plugin_Handled to block infection. Anything else
- *                          (like Plugin_Continue) to allow infection.
- */
-forward Action:ZR_OnClientInfect(&client, &attacker, &bool:motherInfect, &bool:respawnOverride, &bool:respawn);
-
-/**
- * Called after a player has become a zombie.
- * 
- * @param client            The client that was infected.
- * @param attacker          The the infecter. (-1 if there is no infecter)
- * @param motherInfect      If the client is a mother zombie.
- * @param respawnOverride   True if the respawn cvar was overridden.
- * @param respawn           The value that respawn was overridden with.
- */
-forward ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn);
-
-/**
- * Called when a player is about to become a human. (Through an admin command).
- * Here you can modify any variable or block the action entirely.
- * 
- * @param client            The client index.
- * @param respawn           True if the client was respawned, false if not.
- * @param protect           True if the client spawn protected, false if not.
- * 
- * @return                  Plugin_Handled to block infection. Anything else
- *                          (like Plugin_Continue) to allow acion.
- */
-forward Action:ZR_OnClientHuman(&client, &bool:respawn, &bool:protect);
-
-/**
- * Called after a player has become a human. (Through an admin command.)
- * 
- * @param client            The client index.
- * @param respawn           Whether the client was respawned.
- * @param protect           Whether the client has spawn protection.
- */
-forward ZR_OnClientHumanPost(client, bool:respawn, bool:protect);
+/*
+ * ============================================================================
+ *
+ *  Zombie:Reloaded
+ *
+ *  File:          infect.zr.inc
+ *  Type:          Include
+ *  Description:   Infect-related natives/forwards.
+ *
+ *  Copyright (C) 2009-2010  Greyscale, Richard Helgeby
+ *
+ *  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 3 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, see .
+ *
+ * ============================================================================
+ */
+
+/**
+ * Returns true if the player is a zombie, false if not.
+ *
+ * @param client            The client index.
+ *  
+ * @return			        True if zombie, false if not.
+ * @error                   Invalid client index, not connected or not alive.
+ */
+native bool:ZR_IsClientZombie(client);
+
+/**
+ * Returns true if the player is a human, false if not.
+ *
+ * @param client            The client index.
+ *  
+ * @return			        True if human, false if not.
+ * @error                   Invalid client index, not connected or not alive.
+ */
+native bool:ZR_IsClientHuman(client);
+
+/**
+ * Infects a player.
+ *
+ * Note: If the player already is a zombie, the player will be re-infected.
+ *
+ * @param client            The client to infect.
+ * @param attacker          (Optional) The attacker who did the infect.
+ * @param motherInfect      (Optional) Infect as a mother zombie.
+ * @param respawnOverride   (Optional) Set to true to override respawn cvar.
+ * @param respawn           (Optional) Value to override with.
+ *
+ * @error                   Invalid client index, not connected or not alive.
+ */
+native ZR_InfectClient(client, attacker = -1, bool:motherInfect = false, bool:respawnOverride = false, bool:respawn = false);
+
+/**
+ * Turns a zombie back into a human.
+ *
+ * Note: If the player already is a human, this code will still run as the
+ *       player was a zombie.
+ *
+ * @param client            The client to make human.
+ * @param respawn           Teleport client back to spawn.
+ * @param protect           Start spawn protection on client.
+ *
+ * @error                   Invalid client index, not connected or not alive.
+ */
+native ZR_HumanClient(client, bool:respawn = false, bool:protect = false);
+
+/**
+ * Called when a player is about to become a zombie.
+ * Here you can modify any variable or block the infection entirely.
+ * 
+ * @param client            The client index.
+ * @param attacker          The the infecter. (-1 if there is no infecter)
+ * @param motherInfect      If the client is becoming a mother zombie.
+ * @param respawnOverride   True if the respawn cvar is being overridden.
+ * @param respawn           The value that respawn is being overridden with.
+ * 
+ * @return                  Plugin_Handled to block infection. Anything else
+ *                          (like Plugin_Continue) to allow infection.
+ */
+forward Action:ZR_OnClientInfect(&client, &attacker, &bool:motherInfect, &bool:respawnOverride, &bool:respawn);
+
+/**
+ * Called after a player has become a zombie.
+ * 
+ * @param client            The client that was infected.
+ * @param attacker          The the infecter. (-1 if there is no infecter)
+ * @param motherInfect      If the client is a mother zombie.
+ * @param respawnOverride   True if the respawn cvar was overridden.
+ * @param respawn           The value that respawn was overridden with.
+ */
+forward ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn);
+
+/**
+ * Called when a player is about to become a human. (Through an admin command).
+ * Here you can modify any variable or block the action entirely.
+ * 
+ * @param client            The client index.
+ * @param respawn           True if the client was respawned, false if not.
+ * @param protect           True if the client spawn protected, false if not.
+ * 
+ * @return                  Plugin_Handled to block infection. Anything else
+ *                          (like Plugin_Continue) to allow acion.
+ */
+forward Action:ZR_OnClientHuman(&client, &bool:respawn, &bool:protect);
+
+/**
+ * Called after a player has become a human. (Through an admin command.)
+ * 
+ * @param client            The client index.
+ * @param respawn           Whether the client was respawned.
+ * @param protect           Whether the client has spawn protection.
+ */
+forward ZR_OnClientHumanPost(client, bool:respawn, bool:protect);
diff --git a/src/include/zr/respawn.zr.inc b/src/include/zr/respawn.zr.inc
index f27c1ee..841555d 100644
--- a/src/include/zr/respawn.zr.inc
+++ b/src/include/zr/respawn.zr.inc
@@ -1,95 +1,95 @@
-/*
- * ============================================================================
- *
- *  Zombie:Reloaded
- *
- *  File:          respawn.zr.inc
- *  Type:          Include
- *  Description:   Infect-related natives/forwards.
- *
- *  Copyright (C) 2009-2010  Greyscale, Richard Helgeby
- *
- *  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 3 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, see .
- *
- * ============================================================================
- */
-
-/**
- * Conditions for respawning players.
- */
-enum ZR_RespawnCondition
-{
-    ZR_Repsawn_Default = -1,    /** Let ZR decide according to its settings. */
-    ZR_Respawn_Human = 0,       /** Respawn as a human. */
-    ZR_Respawn_Zombie,          /** Respawn as a zombie. */
-    ZR_Respawn_ZombieIfSuicide  /** Respawn as a zombie if killed by world damage. */
-}
-
-/**
- * Spawns a player into the round.
- * 
- * @param client            The client index.
- * @param condition         Optional. Set respawn condition, defaults to current
- *                          ZR settings. See ZR_RespawnCondition for details.
- * @error                   Invalid client index, not connected or already alive.
- */
-native ZR_RespawnClient(client, ZR_RespawnCondition:condition = ZR_Repsawn_Default);
-
-/**
- * Called right before ZR is about to respawn a player.
- * Here you can modify any variable or stop the action entirely.
- * 
- * @param client            The client index.
- * @param condition         Respawn condition. See ZR_RespawnCondition for
- *                          details.
- *
- * @return      Plugin_Handled to block respawn.
- */
-forward Action:ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition);
-
-/**
- * Called after ZR respawned a player.
- * 
- * @param client            The client index.
- * @param condition         Current condition of the respawned player. See
- *                          ZR_RespawnCondition for details.
- */
-forward ZR_OnClientRespawned(client, ZR_RespawnCondition:condition);
-
-/**
- * Set if a player died by a suicide or world damage.
- 
- * Note: This will change the respawn condition.
- * Note: This value is reset to default by ZR when a zombie player dies.
- * 
- * @param client    The client index.
- * @param suicide   True to say the player suicided, false if killed by another
- *                  player.
- *
- * @error           Invalid client index or not connected.
- */
-native ZR_SetKilledByWorld(client, bool:suicide);
-
-/**
- * Get whether the player died by a suicide or world damage.
- *
- * Note: This value is only valid after death event, and before respawn.
- * 
- * @param client    The client index.
- * 
- * @return          True if the player died by suicide, false if killed by
- *                  another player.
- * @error           Invalid client index or not connected.
- */
-native bool:ZR_GetKilledByWorld(client);
+/*
+ * ============================================================================
+ *
+ *  Zombie:Reloaded
+ *
+ *  File:          respawn.zr.inc
+ *  Type:          Include
+ *  Description:   Infect-related natives/forwards.
+ *
+ *  Copyright (C) 2009-2010  Greyscale, Richard Helgeby
+ *
+ *  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 3 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, see .
+ *
+ * ============================================================================
+ */
+
+/**
+ * Conditions for respawning players.
+ */
+enum ZR_RespawnCondition
+{
+    ZR_Repsawn_Default = -1,    /** Let ZR decide according to its settings. */
+    ZR_Respawn_Human = 0,       /** Respawn as a human. */
+    ZR_Respawn_Zombie,          /** Respawn as a zombie. */
+    ZR_Respawn_ZombieIfSuicide  /** Respawn as a zombie if killed by world damage. */
+}
+
+/**
+ * Spawns a player into the round.
+ * 
+ * @param client            The client index.
+ * @param condition         Optional. Set respawn condition, defaults to current
+ *                          ZR settings. See ZR_RespawnCondition for details.
+ * @error                   Invalid client index, not connected or already alive.
+ */
+native ZR_RespawnClient(client, ZR_RespawnCondition:condition = ZR_Repsawn_Default);
+
+/**
+ * Called right before ZR is about to respawn a player.
+ * Here you can modify any variable or stop the action entirely.
+ * 
+ * @param client            The client index.
+ * @param condition         Respawn condition. See ZR_RespawnCondition for
+ *                          details.
+ *
+ * @return      Plugin_Handled to block respawn.
+ */
+forward Action:ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition);
+
+/**
+ * Called after ZR respawned a player.
+ * 
+ * @param client            The client index.
+ * @param condition         Current condition of the respawned player. See
+ *                          ZR_RespawnCondition for details.
+ */
+forward ZR_OnClientRespawned(client, ZR_RespawnCondition:condition);
+
+/**
+ * Set if a player died by a suicide or world damage.
+ 
+ * Note: This will change the respawn condition.
+ * Note: This value is reset to default by ZR when a zombie player dies.
+ * 
+ * @param client    The client index.
+ * @param suicide   True to say the player suicided, false if killed by another
+ *                  player.
+ *
+ * @error           Invalid client index or not connected.
+ */
+native ZR_SetKilledByWorld(client, bool:suicide);
+
+/**
+ * Get whether the player died by a suicide or world damage.
+ *
+ * Note: This value is only valid after death event, and before respawn.
+ * 
+ * @param client    The client index.
+ * 
+ * @return          True if the player died by suicide, false if killed by
+ *                  another player.
+ * @error           Invalid client index or not connected.
+ */
+native bool:ZR_GetKilledByWorld(client);
diff --git a/src/zombiereloaded.sp b/src/zombiereloaded.sp
index fdceceb..0c46161 100644
--- a/src/zombiereloaded.sp
+++ b/src/zombiereloaded.sp
@@ -123,7 +123,7 @@ public Plugin:myinfo =
     author = "Greyscale | Richard Helgeby",
     description = "Infection/survival style gameplay",
     version = VERSION,
-    url = "http://www.zombiereloaded.com"
+    url = "http://forums.alliedmods.net/forumdisplay.php?f=132"
 };
 
 /**
diff --git a/updateversion.sh b/updateversion.sh
index ac57ffb..bc62cbc 100755
--- a/updateversion.sh
+++ b/updateversion.sh
@@ -21,7 +21,7 @@ fi
 ZR_VERSION_FILE="src/zr/hgversion.h.inc"
 
 ZR_PRODUCT_NAME="Zombie:Reloaded"
-ZR_COPYRIGHT="Copyright (C) 2009  Greyscale, Richard Helgeby"
+ZR_COPYRIGHT="Copyright (C) 2009-2012  Greyscale, Richard Helgeby"
 ZR_BRANCH="zr-3.0-b2"
 ZR_REVISION=$(hg id -n):$(hg id -i)