Added amb1186 - TF2 Extension.
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401987
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
#if defined _tf2_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _tf2_included
|
||||
|
||||
enum TFClassType
|
||||
{
|
||||
TFClass_Unknown = 0,
|
||||
TFClass_Scout,
|
||||
TFClass_Sniper,
|
||||
TFClass_Soldier,
|
||||
TFClass_DemoMan,
|
||||
TFClass_Medic,
|
||||
TFClass_Heavy,
|
||||
TFClass_Pyro,
|
||||
TFClass_Spy,
|
||||
TFClass_Engineer
|
||||
}
|
||||
|
||||
enum TFTeam
|
||||
{
|
||||
TFTeam_Unassigned = 0,
|
||||
TFTeam_Spectator = 1,
|
||||
TFTeam_Red = 2,
|
||||
TFTeam_Blue = 3
|
||||
}
|
||||
|
||||
/**
|
||||
* Set's a Clients invulnrability status (ubercharge effect)
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param enabled Enable/Disable invulnrability.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native TF2_SetPlayerInvuln(client, bool:enabled);
|
||||
|
||||
|
||||
/**
|
||||
* Sets a client on fire for 10 seconds.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native TF2_IgnitePlayer(client, target);
|
||||
|
||||
/**
|
||||
* Respawns a client
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native TF2_RespawnPlayer(client);
|
||||
|
||||
/**
|
||||
* Disguises a client to the given model and team. Only has an effect on spies.
|
||||
*
|
||||
* Note: This only starts the disguise process and a delay occurs before the spy is fully disguised
|
||||
*
|
||||
* @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
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native TF2_DisguisePlayer(client, TFTeam:team, TFClassType:class);
|
||||
|
||||
/**
|
||||
* Removes the current disguise from a client. Only has an effect on spies.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native TF2_RemovePlayerDisguise(client);
|
||||
|
||||
/**
|
||||
* Retrieves the entity index of the CPlayerResource entity
|
||||
*
|
||||
* @return The current resource entity index.
|
||||
*/
|
||||
native TF2_GetResourceEntity();
|
||||
|
||||
/**
|
||||
* Finds the TFClassType for a given class name.
|
||||
*
|
||||
* @param classname A classname string such as "sniper" or "demoman"
|
||||
* @return A TFClassType constant.
|
||||
*/
|
||||
native TFClassType:TF2_GetClass(const String:classname[]);
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension:__ext_tf2 =
|
||||
{
|
||||
name = "TF2 Tools",
|
||||
file = "game.tf2.ext",
|
||||
autoload = 1,
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,301 @@
|
||||
#if defined _tf2_stocks_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _tf2_stocks_included
|
||||
|
||||
#include <tf2>
|
||||
#include <sdktools>
|
||||
|
||||
enum TFResourceType
|
||||
{
|
||||
TFResource_Ping,
|
||||
TFResource_Score,
|
||||
TFResource_Deaths,
|
||||
TFResource_TotalScore,
|
||||
TFResource_Captures,
|
||||
TFResource_Defenses,
|
||||
TFResource_Dominations,
|
||||
TFResource_Revenge,
|
||||
TFResource_BuildingsDestroyed,
|
||||
TFResource_Headshots,
|
||||
TFResource_Backstabs,
|
||||
TFResource_HealPoints,
|
||||
TFResource_Invulns,
|
||||
TFResource_Teleports,
|
||||
TFResource_ResupplyPoints,
|
||||
TFResource_KillAssists,
|
||||
TFResource_MaxHealth,
|
||||
TFResource_PlayerClass
|
||||
};
|
||||
|
||||
static const String:TFResourceNames[TFResourceType][] =
|
||||
{
|
||||
"m_iPing",
|
||||
"m_iScore",
|
||||
"m_iDeaths",
|
||||
"m_iTotalScore",
|
||||
"m_iCaptures",
|
||||
"m_iDefenses",
|
||||
"m_iDominations",
|
||||
"m_iRevenge",
|
||||
"m_iBuildingsDestroyed",
|
||||
"m_iHeadshots",
|
||||
"m_iBackstabs",
|
||||
"m_iHealPoints",
|
||||
"m_iInvulns",
|
||||
"m_iTeleports",
|
||||
"m_iResupplyPoints",
|
||||
"m_iKillAssists",
|
||||
"m_iMaxHealth",
|
||||
"m_iPlayerClass"
|
||||
};
|
||||
|
||||
/**
|
||||
* Get's a Clients current class.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param class TFClassType to change to.
|
||||
* @noreturn
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
stock TFClassType:TF2_GetPlayerClass(client)
|
||||
{
|
||||
return TFClassType:GetEntProp(client, Prop_Send, "m_iClass");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set's a Clients class.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param class TFClassType class symbol.
|
||||
* @param weapons If true, changes the players weapon set to that of the new class.
|
||||
* @noreturn
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
stock TF2_SetPlayerClass(client, TFClassType:class, bool:weapons=true)
|
||||
{
|
||||
SetEntProp(client, Prop_Send, "m_iClass", _:class);
|
||||
SetEntProp(client, Prop_Send, "m_iDesiredPlayerClass", _:class);
|
||||
TF2_SetPlayerResourceData(client, TFResource_PlayerClass, class);
|
||||
|
||||
if (weapons)
|
||||
{
|
||||
TF2_RemoveAllWeapons(client);
|
||||
TF2_EquipPlayerClassWeapons(client, class)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves client data from the resource entity
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param type ResourceType constant
|
||||
* @return Value or -1 on failure.
|
||||
* @error Invalid client index, client not in game or failed to find resource entity.
|
||||
*/
|
||||
stock TF2_GetPlayerResourceData(client, TFResourceType:type)
|
||||
{
|
||||
if (!IsClientConnected(client))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static offset;
|
||||
static set = false;
|
||||
|
||||
if (!set)
|
||||
{
|
||||
offset = FindSendPropInfo("CTFPlayerResource", TFResourceNames[type]);
|
||||
set = true;
|
||||
}
|
||||
|
||||
if (offset < 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
new entity = TF2_GetResourceEntity();
|
||||
|
||||
if (entity == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return GetEntData(entity, offset + (client*4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets client data in the resource entity
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param type ResourceType constant
|
||||
* @param value Value to set.
|
||||
* @return Value or -1 on failure.
|
||||
* @error Invalid client index, client not in game or failed to find resource entity.
|
||||
*/
|
||||
stock bool:TF2_SetPlayerResourceData(client, TFResourceType:type, any:value)
|
||||
{
|
||||
if (!IsClientConnected(client))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static offset;
|
||||
static set = false;
|
||||
|
||||
if (!set)
|
||||
{
|
||||
offset = FindSendPropInfo("CTFPlayerResource", TFResourceNames[type]);
|
||||
set = true;
|
||||
}
|
||||
|
||||
if (offset < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
new entity = TF2_GetResourceEntity();
|
||||
|
||||
if (entity == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SetEntData(entity, offset + (client*4), value)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all weapons from a client's weapon slot
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param slot Slot index (0-5)
|
||||
* @noreturn
|
||||
* @error Invalid client, invalid slot or lack of mod support
|
||||
*/
|
||||
stock TF2_RemoveWeaponSlot(client, slot)
|
||||
{
|
||||
new weaponIndex;
|
||||
while ((weaponIndex = GetPlayerWeaponSlot(client, slot)) != -1)
|
||||
{
|
||||
RemovePlayerItem(client, weaponIndex);
|
||||
RemoveEdict(weaponIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all weapons from a client
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TF2_RemoveAllWeapons(client)
|
||||
{
|
||||
for (new i = 0; i <= 5; i++)
|
||||
{
|
||||
TF2_RemoveWeaponSlot(client, i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives a named weapon to a client
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param weapon Weapon name
|
||||
* @return False if weapon could not be created, true on success
|
||||
* @error Invalid client index or lack of mod support
|
||||
*/
|
||||
stock bool:TF2_GivePlayerWeapon(client, const String:weapon[])
|
||||
{
|
||||
new weaponIndex = GivePlayerItem(client, weapon);
|
||||
if (weaponIndex == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
EquipPlayerWeapon(client, weaponIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equips a client with a class's weapons. This does not remove existing weapons.
|
||||
*
|
||||
* Note: Some class specific items such tf_weapon_pda_engineer_build are only given
|
||||
* if the client is the correct class.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param class TFClasssType class symbol.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TF2_EquipPlayerClassWeapons(client, TFClassType:class)
|
||||
{
|
||||
switch(class)
|
||||
{
|
||||
case TFClass_Scout:
|
||||
{
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_scattergun");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_pistol_scout");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_bat");
|
||||
}
|
||||
case TFClass_Sniper:
|
||||
{
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_sniperrifle");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_smg");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_club");
|
||||
}
|
||||
case TFClass_Soldier:
|
||||
{
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_rocketlauncher");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_shotgun_soldier");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_shovel");
|
||||
}
|
||||
case TFClass_DemoMan:
|
||||
{
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_pipebomblauncher");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_grenadelauncher");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_bottle");
|
||||
}
|
||||
case TFClass_Medic:
|
||||
{
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_syringegun_medic");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_medigun");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_bonesaw");
|
||||
}
|
||||
case TFClass_Heavy:
|
||||
{
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_minigun");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_shotgun_hwg");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_fists");
|
||||
}
|
||||
case TFClass_Pyro:
|
||||
{
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_flamethrower");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_shotgun_pyro");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_fireaxe");
|
||||
}
|
||||
case TFClass_Spy:
|
||||
{
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_revolver");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_knife");
|
||||
|
||||
if (TF2_GetPlayerClass(client) != TFClass_Spy)
|
||||
return;
|
||||
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_pda_spy");
|
||||
}
|
||||
case TFClass_Engineer:
|
||||
{
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_shotgun_primary");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_pistol");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_wrench");
|
||||
|
||||
if (TF2_GetPlayerClass(client) != TFClass_Engineer)
|
||||
return;
|
||||
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_pda_engineer_build");
|
||||
TF2_GivePlayerWeapon(client, "tf_weapon_pda_engineer_destroy");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <tf2>
|
||||
#include <tf2_stocks>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "TF2 Test",
|
||||
author = "pRED*",
|
||||
description = "Test of Tf2 functions",
|
||||
version = "1.0",
|
||||
url = "www.sourcemod.net"
|
||||
}
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
RegConsoleCmd("sm_burnme", Command_Burn);
|
||||
RegConsoleCmd("sm_invuln", Command_Invuln);
|
||||
RegConsoleCmd("sm_respawn", Command_Respawn);
|
||||
RegConsoleCmd("sm_disguise", Command_Disguise);
|
||||
RegConsoleCmd("sm_remdisguise", Command_RemDisguise);
|
||||
RegConsoleCmd("sm_class", Command_Class);
|
||||
RegConsoleCmd("sm_remove", Command_Remove);
|
||||
RegConsoleCmd("sm_changeclass", Command_ChangeClass);
|
||||
}
|
||||
|
||||
public Action:Command_Class(client, args)
|
||||
{
|
||||
TF2_RemoveAllWeapons(client);
|
||||
|
||||
decl String:text[10];
|
||||
GetCmdArg(1, text, sizeof(text));
|
||||
|
||||
new one = StringToInt(text);
|
||||
|
||||
TF2_EquipPlayerClassWeapons(client, TFClassType:one);
|
||||
|
||||
PrintToChat(client, "Test: sniper's classnum is %i (should be %i)", TF2_GetClass("sniper"), TFClass_Sniper);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Remove(client, args)
|
||||
{
|
||||
decl String:text[10];
|
||||
GetCmdArg(1, text, sizeof(text));
|
||||
|
||||
new one = StringToInt(text);
|
||||
|
||||
TF2_RemoveWeaponSlot(client, one);
|
||||
|
||||
PrintToChat(client, "Test: heavy's classnum is %i (should be %i)", TF2_GetClass("heavy"), TFClass_Heavy);
|
||||
|
||||
new doms = TF2_GetPlayerResourceData(client, TFResource_Dominations);
|
||||
PrintToChat(client, "Dominations read test: %i", doms);
|
||||
|
||||
TF2_SetPlayerResourceData(client, TFResource_Dominations, doms + 10);
|
||||
doms = TF2_GetPlayerResourceData(client, TFResource_Dominations);
|
||||
PrintToChat(client, "Dominations write test: %i", doms);
|
||||
|
||||
/* Note: This didn't appear to change my dominations value when I pressed tab. */
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_ChangeClass(client, args)
|
||||
{
|
||||
decl String:text[10];
|
||||
GetCmdArg(1, text, sizeof(text));
|
||||
|
||||
new one = StringToInt(text);
|
||||
|
||||
PrintToChat(client, "Current class is :%i", TF2_GetPlayerClass(client));
|
||||
|
||||
TF2_SetPlayerClass(client, TFClassType:one);
|
||||
|
||||
PrintToChat(client, "New class is :%i", TF2_GetPlayerClass(client));
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Action:Command_Burn(client, args)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
TF2_IgnitePlayer(client, client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Invuln(client, args)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (args < 1)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[10];
|
||||
GetCmdArg(1, text, sizeof(text));
|
||||
|
||||
new bool:one = !!StringToInt(text);
|
||||
|
||||
TF2_SetPlayerInvuln(client, one)
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Disguise(client, args)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (args < 2)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[10];
|
||||
decl String:text2[10];
|
||||
GetCmdArg(1, text, sizeof(text));
|
||||
GetCmdArg(2, text2, sizeof(text2));
|
||||
|
||||
new one = StringToInt(text);
|
||||
new two = StringToInt(text2);
|
||||
|
||||
TF2_DisguisePlayer(client, TFTeam:one, TFClassType:two);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_RemDisguise(client, args)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
TF2_RemovePlayerDisguise(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
|
||||
public Action:Command_Respawn(client, args)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
|
||||
TF2_RespawnPlayer(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
Reference in New Issue
Block a user