plugins/include/tf2_stocks.inc
author Kyle Sanderson <kyle.leet@gmail.com>
Mon Aug 12 00:54:21 2013 +0100 (2013-08-12)
changeset 3997 59bcfc51eb79
parent 3967 ceafb87d38a7
child 4036 646b27d3d64a
permissions -rw-r--r--
Add support for nested datatables. (bug 5446, r=asherkin)
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod (C)2004-2008 AlliedModders LLC.  All rights reserved.
     5  * =============================================================================
     6  *
     7  * This file is part of the SourceMod/SourcePawn SDK.
     8  *
     9  * This program is free software; you can redistribute it and/or modify it under
    10  * the terms of the GNU General Public License, version 3.0, as published by the
    11  * Free Software Foundation.
    12  * 
    13  * This program is distributed in the hope that it will be useful, but WITHOUT
    14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    15  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    16  * details.
    17  *
    18  * You should have received a copy of the GNU General Public License along with
    19  * this program.  If not, see <http://www.gnu.org/licenses/>.
    20  *
    21  * As a special exception, AlliedModders LLC gives you permission to link the
    22  * code of this program (as well as its derivative works) to "Half-Life 2," the
    23  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    24  * by the Valve Corporation.  You must obey the GNU General Public License in
    25  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    26  * this exception to all derivative works.  AlliedModders LLC defines further
    27  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    28  * or <http://www.sourcemod.net/license.php>.
    29  *
    30  * Version: $Id$
    31  */
    32 
    33 #if defined _tf2_stocks_included
    34  #endinput
    35 #endif
    36 #define _tf2_stocks_included
    37 
    38 #include <tf2>
    39 #include <sdktools>
    40 
    41 #define TF_CONDFLAG_NONE            0
    42 #define TF_CONDFLAG_SLOWED          (1 << 0)
    43 #define TF_CONDFLAG_ZOOMED          (1 << 1)
    44 #define TF_CONDFLAG_DISGUISING      (1 << 2)
    45 #define TF_CONDFLAG_DISGUISED       (1 << 3)
    46 #define TF_CONDFLAG_CLOAKED         (1 << 4)
    47 #define TF_CONDFLAG_UBERCHARGED     (1 << 5)
    48 #define TF_CONDFLAG_TELEPORTGLOW    (1 << 6)
    49 #define TF_CONDFLAG_TAUNTING        (1 << 7)
    50 #define TF_CONDFLAG_UBERCHARGEFADE  (1 << 8)
    51 #define TF_CONDFLAG_CLOAKFLICKER    (1 << 9)
    52 #define TF_CONDFLAG_TELEPORTING     (1 << 10)
    53 #define TF_CONDFLAG_KRITZKRIEGED    (1 << 11)
    54 #define TF_CONDFLAG_DEADRINGERED    (1 << 13)
    55 #define TF_CONDFLAG_BONKED          (1 << 14)
    56 #define TF_CONDFLAG_DAZED           (1 << 15)
    57 #define TF_CONDFLAG_BUFFED          (1 << 16)
    58 #define TF_CONDFLAG_CHARGING        (1 << 17)
    59 #define TF_CONDFLAG_DEMOBUFF        (1 << 18)
    60 #define TF_CONDFLAG_CRITCOLA        (1 << 19)
    61 #define TF_CONDFLAG_INHEALRADIUS    (1 << 20)
    62 #define TF_CONDFLAG_HEALING         (1 << 21)
    63 #define TF_CONDFLAG_ONFIRE          (1 << 22)
    64 #define TF_CONDFLAG_OVERHEALED      (1 << 23)
    65 #define TF_CONDFLAG_JARATED         (1 << 24)
    66 #define TF_CONDFLAG_BLEEDING        (1 << 25)
    67 #define TF_CONDFLAG_DEFENSEBUFFED   (1 << 26)
    68 #define TF_CONDFLAG_MILKED          (1 << 27)
    69 #define TF_CONDFLAG_MEGAHEAL        (1 << 28)
    70 #define TF_CONDFLAG_REGENBUFFED     (1 << 29)
    71 #define TF_CONDFLAG_MARKEDFORDEATH  (1 << 30)
    72 
    73 #define TF_DEATHFLAG_KILLERDOMINATION   (1 << 0)
    74 #define TF_DEATHFLAG_ASSISTERDOMINATION (1 << 1)
    75 #define TF_DEATHFLAG_KILLERREVENGE      (1 << 2)
    76 #define TF_DEATHFLAG_ASSISTERREVENGE    (1 << 3)
    77 #define TF_DEATHFLAG_FIRSTBLOOD         (1 << 4)
    78 #define TF_DEATHFLAG_DEADRINGER         (1 << 5)
    79 #define TF_DEATHFLAG_INTERRUPTED        (1 << 6)
    80 #define TF_DEATHFLAG_GIBBED             (1 << 7)
    81 #define TF_DEATHFLAG_PURGATORY          (1 << 8)
    82 
    83 // Custom kill identifiers for the customkill property on the player_death event
    84 enum {
    85 	TF_CUSTOM_HEADSHOT = 1,
    86 	TF_CUSTOM_BACKSTAB,
    87 	TF_CUSTOM_BURNING,
    88 	TF_CUSTOM_WRENCH_FIX,
    89 	TF_CUSTOM_MINIGUN,
    90 	TF_CUSTOM_SUICIDE,
    91 	TF_CUSTOM_TAUNT_HADOUKEN,
    92 	TF_CUSTOM_BURNING_FLARE,
    93 	TF_CUSTOM_TAUNT_HIGH_NOON,
    94 	TF_CUSTOM_TAUNT_GRAND_SLAM,
    95 	TF_CUSTOM_PENETRATE_MY_TEAM,
    96 	TF_CUSTOM_PENETRATE_ALL_PLAYERS,
    97 	TF_CUSTOM_TAUNT_FENCING,
    98 	TF_CUSTOM_PENETRATE_HEADSHOT,
    99 	TF_CUSTOM_TAUNT_ARROW_STAB,
   100 	TF_CUSTOM_TELEFRAG,
   101 	TF_CUSTOM_BURNING_ARROW,
   102 	TF_CUSTOM_FLYINGBURN,
   103 	TF_CUSTOM_PUMPKIN_BOMB,
   104 	TF_CUSTOM_DECAPITATION,
   105 	TF_CUSTOM_TAUNT_GRENADE,
   106 	TF_CUSTOM_BASEBALL,
   107 	TF_CUSTOM_CHARGE_IMPACT,
   108 	TF_CUSTOM_TAUNT_BARBARIAN_SWING,
   109 	TF_CUSTOM_AIR_STICKY_BURST,
   110 	TF_CUSTOM_DEFENSIVE_STICKY,
   111 	TF_CUSTOM_PICKAXE,
   112 	TF_CUSTOM_ROCKET_DIRECTHIT,
   113 	TF_CUSTOM_TAUNT_UBERSLICE,
   114 	TF_CUSTOM_PLAYER_SENTRY,
   115 	TF_CUSTOM_STANDARD_STICKY,
   116 	TF_CUSTOM_SHOTGUN_REVENGE_CRIT,
   117 	TF_CUSTOM_TAUNT_ENGINEER_SMASH,
   118 	TF_CUSTOM_BLEEDING,
   119 	TF_CUSTOM_GOLD_WRENCH,
   120 	TF_CUSTOM_CARRIED_BUILDING,
   121 	TF_CUSTOM_COMBO_PUNCH,
   122 	TF_CUSTOM_TAUNT_ENGINEER_ARM,
   123 	TF_CUSTOM_FISH_KILL,
   124 	TF_CUSTOM_TRIGGER_HURT,
   125 	TF_CUSTOM_DECAPITATION_BOSS,
   126 	TF_CUSTOM_STICKBOMB_EXPLOSION,
   127 	TF_CUSTOM_AEGIS_ROUND,
   128 	TF_CUSTOM_FLARE_EXPLOSION,
   129 	TF_CUSTOM_BOOTS_STOMP,
   130 	TF_CUSTOM_PLASMA,
   131 	TF_CUSTOM_PLASMA_CHARGED,
   132 	TF_CUSTOM_PLASMA_GIB,
   133 	TF_CUSTOM_PRACTICE_STICKY,
   134 	TF_CUSTOM_EYEBALL_ROCKET,
   135 	TF_CUSTOM_HEADSHOT_DECAPITATION,
   136 	TF_CUSTOM_TAUNT_ARMAGEDDON,
   137 	TF_CUSTOM_FLARE_PELLET,
   138 	TF_CUSTOM_CLEAVER,
   139 	TF_CUSTOM_CLEAVER_CRIT,
   140 	TF_CUSTOM_SAPPER_RECORDER_DEATH,
   141 	TF_CUSTOM_MERASMUS_PLAYER_BOMB,
   142 	TF_CUSTOM_MERASMUS_GRENADE,
   143 	TF_CUSTOM_MERASMUS_ZAP,
   144 	TF_CUSTOM_MERASMUS_DECAPITATION,
   145 	TF_CUSTOM_CANNONBALL_PUSH,
   146 };
   147 
   148 // Weapon codes as used in some events, such as player_death
   149 // (not to be confused with Item Definition Indexes)
   150 enum {
   151 	TF_WEAPON_NONE = 0,
   152 	TF_WEAPON_BAT,
   153 	TF_WEAPON_BAT_WOOD,
   154 	TF_WEAPON_BOTTLE,
   155 	TF_WEAPON_FIREAXE,
   156 	TF_WEAPON_CLUB,
   157 	TF_WEAPON_CROWBAR,
   158 	TF_WEAPON_KNIFE,
   159 	TF_WEAPON_FISTS,
   160 	TF_WEAPON_SHOVEL,
   161 	TF_WEAPON_WRENCH,
   162 	TF_WEAPON_BONESAW,
   163 	TF_WEAPON_SHOTGUN_PRIMARY,
   164 	TF_WEAPON_SHOTGUN_SOLDIER,
   165 	TF_WEAPON_SHOTGUN_HWG,
   166 	TF_WEAPON_SHOTGUN_PYRO,
   167 	TF_WEAPON_SCATTERGUN,
   168 	TF_WEAPON_SNIPERRIFLE,
   169 	TF_WEAPON_MINIGUN,
   170 	TF_WEAPON_SMG,
   171 	TF_WEAPON_SYRINGEGUN_MEDIC,
   172 	TF_WEAPON_TRANQ,
   173 	TF_WEAPON_ROCKETLAUNCHER,
   174 	TF_WEAPON_GRENADELAUNCHER,
   175 	TF_WEAPON_PIPEBOMBLAUNCHER,
   176 	TF_WEAPON_FLAMETHROWER,
   177 	TF_WEAPON_GRENADE_NORMAL,
   178 	TF_WEAPON_GRENADE_CONCUSSION,
   179 	TF_WEAPON_GRENADE_NAIL,
   180 	TF_WEAPON_GRENADE_MIRV,
   181 	TF_WEAPON_GRENADE_MIRV_DEMOMAN,
   182 	TF_WEAPON_GRENADE_NAPALM,
   183 	TF_WEAPON_GRENADE_GAS,
   184 	TF_WEAPON_GRENADE_EMP,
   185 	TF_WEAPON_GRENADE_CALTROP,
   186 	TF_WEAPON_GRENADE_PIPEBOMB,
   187 	TF_WEAPON_GRENADE_SMOKE_BOMB,
   188 	TF_WEAPON_GRENADE_HEAL,
   189 	TF_WEAPON_GRENADE_STUNBALL,
   190 	TF_WEAPON_GRENADE_JAR,
   191 	TF_WEAPON_GRENADE_JAR_MILK,
   192 	TF_WEAPON_PISTOL,
   193 	TF_WEAPON_PISTOL_SCOUT,
   194 	TF_WEAPON_REVOLVER,
   195 	TF_WEAPON_NAILGUN,
   196 	TF_WEAPON_PDA,
   197 	TF_WEAPON_PDA_ENGINEER_BUILD,
   198 	TF_WEAPON_PDA_ENGINEER_DESTROY,
   199 	TF_WEAPON_PDA_SPY,
   200 	TF_WEAPON_BUILDER,
   201 	TF_WEAPON_MEDIGUN,
   202 	TF_WEAPON_GRENADE_MIRVBOMB,
   203 	TF_WEAPON_FLAMETHROWER_ROCKET,
   204 	TF_WEAPON_GRENADE_DEMOMAN,
   205 	TF_WEAPON_SENTRY_BULLET,
   206 	TF_WEAPON_SENTRY_ROCKET,
   207 	TF_WEAPON_DISPENSER,
   208 	TF_WEAPON_INVIS,
   209 	TF_WEAPON_FLAREGUN,
   210 	TF_WEAPON_LUNCHBOX,
   211 	TF_WEAPON_JAR,
   212 	TF_WEAPON_COMPOUND_BOW,
   213 	TF_WEAPON_BUFF_ITEM,
   214 	TF_WEAPON_PUMPKIN_BOMB,
   215 	TF_WEAPON_SWORD,
   216 	TF_WEAPON_DIRECTHIT,
   217 	TF_WEAPON_LIFELINE,
   218 	TF_WEAPON_LASER_POINTER,
   219 	TF_WEAPON_DISPENSER_GUN,
   220 	TF_WEAPON_SENTRY_REVENGE,
   221 	TF_WEAPON_JAR_MILK,
   222 	TF_WEAPON_HANDGUN_SCOUT_PRIMARY,
   223 	TF_WEAPON_BAT_FISH,
   224 	TF_WEAPON_CROSSBOW,
   225 	TF_WEAPON_STICKBOMB,
   226 	TF_WEAPON_HANDGUN_SCOUT_SEC,
   227 	TF_WEAPON_SODA_POPPER,
   228 	TF_WEAPON_SNIPERRIFLE_DECAP,
   229 	TF_WEAPON_RAYGUN,
   230 	TF_WEAPON_PARTICLE_CANNON,
   231 	TF_WEAPON_MECHANICAL_ARM,
   232 	TF_WEAPON_DRG_POMSON,
   233 	TF_WEAPON_BAT_GIFTWRAP,
   234 	TF_WEAPON_GRENADE_ORNAMENT,
   235 	TF_WEAPON_RAYGUN_REVENGE,
   236 	TF_WEAPON_PEP_BRAWLER_BLASTER,
   237 	TF_WEAPON_CLEAVER,
   238 	TF_WEAPON_GRENADE_CLEAVER,
   239 	TF_WEAPON_STICKY_BALL_LAUNCHER,
   240 	TF_WEAPON_GRENADE_STICKY_BALL,
   241 	TF_WEAPON_SHOTGUN_BUILDING_RESCUE,
   242 	TF_WEAPON_CANNON,
   243 };
   244 
   245 // TF2 Weapon Loadout Slots
   246 enum
   247 {
   248 	TFWeaponSlot_Primary,
   249 	TFWeaponSlot_Secondary,
   250 	TFWeaponSlot_Melee,
   251 	TFWeaponSlot_Grenade,
   252 	TFWeaponSlot_Building,
   253 	TFWeaponSlot_PDA,
   254 	TFWeaponSlot_Item1,
   255 	TFWeaponSlot_Item2	
   256 };
   257 
   258 // Identifiers for the eventtype property on the teamplay_flag_event event
   259 enum {
   260 	TF_FLAGEVENT_PICKEDUP = 1,
   261 	TF_FLAGEVENT_CAPTURED,
   262 	TF_FLAGEVENT_DEFENDED,
   263 	TF_FLAGEVENT_DROPPED,
   264 	TF_FLAGEVENT_RETURNED
   265 };
   266 
   267 enum TFResourceType
   268 {
   269 	TFResource_Ping,
   270 	TFResource_Score,
   271 	TFResource_Deaths,
   272 	TFResource_TotalScore, 
   273 	TFResource_Captures,
   274 	TFResource_Defenses,
   275 	TFResource_Dominations,
   276 	TFResource_Revenge,
   277 	TFResource_BuildingsDestroyed, 
   278 	TFResource_Headshots,
   279 	TFResource_Backstabs,
   280 	TFResource_HealPoints,
   281 	TFResource_Invulns,
   282 	TFResource_Teleports,
   283 	TFResource_ResupplyPoints,
   284 	TFResource_KillAssists,
   285 	TFResource_MaxHealth,
   286 	TFResource_PlayerClass
   287 };
   288 
   289 static const String:TFResourceNames[TFResourceType][] =
   290 {
   291 	"m_iPing",
   292 	"m_iScore",
   293 	"m_iDeaths",
   294 	"m_iTotalScore",
   295 	"m_iCaptures",
   296 	"m_iDefenses",
   297 	"m_iDominations",
   298 	"m_iRevenge",
   299 	"m_iBuildingsDestroyed",
   300 	"m_iHeadshots",
   301 	"m_iBackstabs",
   302 	"m_iHealPoints",
   303 	"m_iInvulns",
   304 	"m_iTeleports",
   305 	"m_iResupplyPoints",
   306 	"m_iKillAssists",
   307 	"m_iMaxHealth",
   308 	"m_iPlayerClass"
   309 };
   310 
   311 /**
   312  * Get's a Clients current class.
   313  *
   314  * @param client		Player's index.
   315  * @return				Current TFClassType of player.
   316  * @error				Invalid client index.
   317  */
   318 stock TFClassType:TF2_GetPlayerClass(client)
   319 {
   320 	return TFClassType:GetEntProp(client, Prop_Send, "m_iClass");
   321 }
   322 
   323 /**
   324  * Set's a Clients class.
   325  *
   326  * Note: If setting player class in a player spawn hook weapons should be set to false.
   327  *
   328  * @param client		Player's index.
   329  * @param class			TFClassType class symbol.
   330  * @param weapons		This paramater is ignored.
   331  * @param persistent	If true changes the players desired class so the change stays after death.
   332  * @noreturn
   333  * @error				Invalid client index.
   334  */
   335 stock TF2_SetPlayerClass(client, TFClassType:class, bool:weapons=true, bool:persistent=true)
   336 {
   337 	SetEntProp(client, Prop_Send, "m_iClass", _:class);
   338 	
   339 	if (persistent)
   340 	{
   341 		SetEntProp(client, Prop_Send, "m_iDesiredPlayerClass", _:class);
   342 	}
   343 }
   344 
   345 /**
   346  * Retrieves client data from the resource entity
   347  *
   348  * @param client		Player's index.
   349  * @param type			ResourceType constant
   350  * @return				Value or -1 on failure.
   351  * @error				Invalid client index, client not in game or failed to find resource entity.
   352  */
   353 #pragma deprecated Use GetPlayerResourceEntity and GetEntProp instead
   354 stock TF2_GetPlayerResourceData(client, TFResourceType:type)
   355 {
   356 	if (!IsClientConnected(client))
   357 	{
   358 		return -1;	
   359 	}
   360 	
   361 	new offset = FindSendPropInfo("CTFPlayerResource", TFResourceNames[type]);
   362 		
   363 	if (offset < 1)
   364 	{
   365 		return -1;	
   366 	}
   367 				
   368 	new entity = TF2_GetResourceEntity();
   369 	
   370 	if (entity == -1)
   371 	{
   372 		return -1;
   373 	}
   374 	
   375 	return GetEntData(entity, offset + (client*4));
   376 }
   377 
   378 /**
   379  * Sets client data in the resource entity
   380  *
   381  * Note: The game overwrites these values every frame, so changing them will have very little effect.
   382  *
   383  * @param client		Player's index.
   384  * @param type			ResourceType constant
   385  * @param value			Value to set.
   386  * @return				Value or -1 on failure.
   387  * @error				Invalid client index, client not in game or failed to find resource entity.
   388  */
   389 #pragma deprecated Use GetPlayerResourceEntity and SetEntProp instead
   390 stock bool:TF2_SetPlayerResourceData(client, TFResourceType:type, any:value)
   391 {
   392 	if (!IsClientConnected(client))
   393 	{
   394 		return false;	
   395 	}
   396 	
   397 	new offset = FindSendPropInfo("CTFPlayerResource", TFResourceNames[type]);
   398 						
   399 	if (offset < 1)
   400 	{
   401 		return false;	
   402 	}
   403 				
   404 	new entity = TF2_GetResourceEntity();
   405 	
   406 	if (entity == -1)
   407 	{
   408 		return false;	
   409 	}
   410 	
   411 	SetEntData(entity, offset + (client*4), value);
   412 	
   413 	return true;	
   414 }
   415 
   416 /**
   417  * Removes all weapons from a client's weapon slot
   418  *
   419  * @param client		Player's index.
   420  * @param slot			Slot index (0-5)
   421  * @noreturn
   422  * @error				Invalid client, invalid slot or lack of mod support
   423  */
   424 stock TF2_RemoveWeaponSlot(client, slot)
   425 {
   426 	new weaponIndex;
   427 	while ((weaponIndex = GetPlayerWeaponSlot(client, slot)) != -1)
   428 	{
   429 		RemovePlayerItem(client, weaponIndex);
   430 		RemoveEdict(weaponIndex);
   431 	}
   432 }
   433 
   434 /**
   435  * Removes all weapons from a client
   436  *
   437  * @param client		Player's index.
   438  * @noreturn
   439  */
   440 stock TF2_RemoveAllWeapons(client)
   441 {
   442 	for (new i = 0; i <= 5; i++)
   443 	{
   444 		TF2_RemoveWeaponSlot(client, i);
   445 	}
   446 }
   447 
   448 /**
   449  * Gets a player's condition bits
   450  *
   451  * @param client		Player's index.
   452  * @return				Player's condition bits
   453  */
   454 #pragma deprecated Use TF2_IsPlayerInCondition instead.
   455 stock TF2_GetPlayerConditionFlags(client)
   456 {
   457 	return GetEntProp(client, Prop_Send, "m_nPlayerCond")|GetEntProp(client, Prop_Send, "_condition_bits");
   458 }
   459 
   460 /**
   461  * Check whether or not a condition is set on a player
   462  *
   463  * @param client		Player's index.
   464  * @param cond			TFCond constant
   465  * @return				True if set, false otherwise
   466  */
   467 stock bool:TF2_IsPlayerInCondition(client, TFCond:cond)
   468 {
   469 	// Conditions are stored across two netprops now, one for each 32-bit segment.
   470 	if (_:cond < 32)
   471 	{
   472 		new bit = 1 << _:cond;
   473 		if ((GetEntProp(client, Prop_Send, "m_nPlayerCond") & bit) == bit)
   474 		{
   475 			return true;
   476 		}
   477 		
   478 		if ((GetEntProp(client, Prop_Send, "_condition_bits") & bit) == bit)
   479 		{
   480 			return true;
   481 		}
   482 	}
   483 	else if (_:cond < 64)
   484 	{
   485 		new bit = (1 << (_:cond - 32));
   486 		if ((GetEntProp(client, Prop_Send, "m_nPlayerCondEx") & bit) == bit)
   487 		{
   488 			return true;
   489 		}
   490 	}
   491 	else
   492 	{
   493 		new bit = (1 << (_:cond - 64));
   494 		if ((GetEntProp(client, Prop_Send, "m_nPlayerCondEx2") & bit) == bit)
   495 		{
   496 			return true;
   497 		}
   498 	}
   499 	
   500 	return false;
   501 }
   502 
   503 /**
   504  * Gets an entity's object type.
   505  *
   506  * @param entity		Entity index.
   507  * @return				Current TFObjectType of entity.
   508  * @error				Invalid entity index.
   509  */
   510 stock TFObjectType:TF2_GetObjectType(entity)
   511 {
   512 	new offset = GetEntSendPropOffs(entity, "m_iObjectType");
   513 	
   514 	if (offset <= 0)
   515 	{
   516 		ThrowError("Entity index %d is not an object", entity);
   517 	}
   518 	
   519 	return TFObjectType:GetEntData(entity, offset);
   520 }
   521 
   522 /**
   523  * Gets an entity's object mode.
   524  *
   525  * @param entity		Entity index.
   526  * @return				Current TFObjectMode of entity.
   527  * @error				Invalid entity index.
   528  */
   529 stock TFObjectMode:TF2_GetObjectMode(entity)
   530 {
   531 	new offset = GetEntSendPropOffs(entity, "m_iObjectMode");
   532 	
   533 	if (offset <= 0)
   534 	{
   535 		ThrowError("Entity index %d is not an object", entity);
   536 	}
   537 	
   538 	return TFObjectMode:GetEntData(entity, offset);
   539 }