Veteran Member
|
09-30-2021
, 02:51
[TF2] Halloween Boss Killfeed
|
#1
|
When I use this Skeleton King plugin the kill feed shows the attacker as SKELETON when I use fists or stomp. It shows my player name of PC Gamer in the kill feed when I use spell. It shows ERRORNAME when dominating. The plugin works fine other than that.
Questions:
1. How can I ensure the attacker appears as SKELETON for all kills made while player is the Skeleton King?
2. How can I ensure the attacker appears as the player's name for all kills made while the player is the Skeleton King?
Plugin is attached, changeteam.txt goes in gamedata folder. Fair warning... The Skeleton King is going to be waaaaaay too powerful for your server unless you are running Uber Upgrades or X10.
Code:
PHP Code:
#include <sdkhooks>
#include <tf2_stocks>
#include <tf2attributes>
//#pragma newdecls required;
#define MODEL_SKELETON "models/bots/skeleton_sniper_boss/skeleton_sniper_boss.mdl"
#define PLUGIN_VERSION "1.6"
#define SPAWN "vo/halloween_mann_brothers/sf13_blutarch_enemies13.mp3"
#define SPAWN2 "ui/halloween_boss_summoned_fx.wav"
#define DEATH "vo/halloween_boss/knight_dying.mp3"
#define DEATHBOSS "ui/halloween_boss_defeated_fx.wav"
#define TEAM_CLASSNAME "tf_team"
#define FIREBALL 0 // Done
#define BATS 1 // Done
#define PUMPKIN 2 // Done
#define TELE 3 // Done
#define LIGHTNING 4 // Done
#define BOSS 5 // Done
#define METEOR 6 // Done
#define ZOMBIEH 7 // Done
#define ZOMBIE 8
#define PUMPKIN2 9
bool g_bSpecial[MAXPLAYERS + 1];
bool g_bSkeleton[MAXPLAYERS + 1];
TFTeam g_iOldTeam[MAXPLAYERS + 1];
Handle g_hCvarStompDamage;
new lastTeam[MAXPLAYERS + 1];
new Handle:g_hSDKTeamAddPlayer;
new Handle:g_hSDKTeamRemovePlayer;
new bool:g_wait[MAXPLAYERS + 1];
Handle g_hWearableEquip;
public Plugin myinfo =
{
name = "[TF2] Be The Skeleton King!",
author = "Pelipoika, modified by PC Gamer",
description = "Spooky scary skeleton",
version = PLUGIN_VERSION,
url = ""
}
public void OnPluginStart()
{
Handle hGameData = LoadGameConfigFile("changeteam");
StartPrepSDKCall(SDKCall_Entity);
PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, "CTeam::AddPlayer");
PrepSDKCall_AddParameter(SDKType_CBasePlayer, SDKPass_Pointer);
g_hSDKTeamAddPlayer = EndPrepSDKCall();
if(g_hSDKTeamAddPlayer == INVALID_HANDLE)
SetFailState("Could not find CTeam::AddPlayer!");
StartPrepSDKCall(SDKCall_Entity);
PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, "CTeam::RemovePlayer");
PrepSDKCall_AddParameter(SDKType_CBasePlayer, SDKPass_Pointer);
g_hSDKTeamRemovePlayer = EndPrepSDKCall();
if(g_hSDKTeamRemovePlayer == INVALID_HANDLE)
SetFailState("Could not find CTeam::RemovePlayer!");
delete hGameData;
AddTempEntHook("TFBlood", TempHook);
RegAdminCmd("sm_beskeletonking", Command_Skeleton, ADMFLAG_SLAY);
HookEvent("post_inventory_application", Event_SkeletonDeath);
HookEvent("player_death", Event_SkeletonDeath, EventHookMode_Pre);
HookEvent("round_end", Event_SkeletonDeath);
CreateConVar("tf2_beskeleton_version", PLUGIN_VERSION, "Be the Skeleton King version", FCVAR_NOTIFY|FCVAR_DONTRECORD|FCVAR_SPONLY);
g_hCvarStompDamage = CreateConVar("tf2_beskeleton_stompdamage", "120", "Movement speed penalty when carrying a bomb", FCVAR_NOTIFY|FCVAR_DONTRECORD, true, 0.0, true, 1.0);
for (int client = 1; client <= MaxClients; client++)
{
if(client > 0 && client <= MaxClients && IsClientInGame(client))
{
g_bSkeleton[client] = false;
g_bSpecial[client] = false;
g_iOldTeam[client] = TF2_GetClientTeam(client);
SDKHook(client, SDKHook_OnTakeDamageAlive, TakeDamage);
}
}
AddNormalSoundHook(SkeletonSH);
GameData hTF2 = new GameData("sm-tf2.games"); // sourcemod's tf2 gamedata
if (!hTF2)
SetFailState("This plugin is designed for a TF2 dedicated server only.");
StartPrepSDKCall(SDKCall_Player);
PrepSDKCall_SetVirtual(hTF2.GetOffset("RemoveWearable") - 1); // EquipWearable offset is always behind RemoveWearable, subtract its value by 1
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer);
g_hWearableEquip = EndPrepSDKCall();
if (!g_hWearableEquip)
SetFailState("Failed to create call: CBasePlayer::EquipWearable");
delete hTF2;
}
public Action TempHook(const char[] te_name, const Players[], int numClients, float delay)
{
int client = TE_ReadNum("entindex");
if (client > 0 && client <= MaxClients && IsClientInGame(client) && g_bSkeleton[client])
{
float m_vecOrigin[3];
m_vecOrigin[0] = TE_ReadFloat("m_vecOrigin[0]");
m_vecOrigin[1] = TE_ReadFloat("m_vecOrigin[1]");
m_vecOrigin[2] = TE_ReadFloat("m_vecOrigin[2]");
if(GetEntProp(client, Prop_Send, "m_iTeamNum") == 0)
{
CreateParticle("spell_skeleton_goop_green", m_vecOrigin);
}
else
{
switch(TF2_GetClientTeam(client))
{
case TFTeam_Red: CreateParticle("spell_pumpkin_mirv_goop_red", m_vecOrigin);
case TFTeam_Blue: CreateParticle("spell_pumpkin_mirv_goop_blue", m_vecOrigin);
}
}
return Plugin_Stop;
}
return Plugin_Continue;
}
public void OnMapStart()
{
PrecacheModel(MODEL_SKELETON);
PrecacheSound("misc/halloween/skeleton_break.wav");
PrecacheSound(SPAWN);
PrecacheSound(SPAWN2);
PrecacheSound(DEATH);
PrecacheSound(DEATHBOSS);
}
public void OnClientPutInServer(int client)
{
g_bSkeleton[client] = false;
g_bSpecial[client] = false;
g_iOldTeam[client] = TFTeam_Spectator;
SDKHook(client, SDKHook_OnTakeDamageAlive, TakeDamage);
}
public Action Command_Skeleton(int client, int args)
{
if (client > 0 && client <= MaxClients && IsClientInGame(client))
{
char arg1[32], arg2[6];
GetCmdArg(1, arg1, sizeof(arg1));
GetCmdArg(2, arg2, sizeof(arg2));
if(args < 1)
{
MakeSkeleton(client);
EmitSoundToAll(SPAWN);
EmitSoundToAll(SPAWN2);
}
else
{
char target_name[MAX_TARGET_LENGTH];
int target_list[MAXPLAYERS];
int target_count;
bool tn_is_ml;
if ((target_count = ProcessTargetString(
arg1,
client,
target_list,
MAXPLAYERS,
0,
target_name,
sizeof(target_name),
tn_is_ml)) <= 0)
{
ReplyToTargetError(client, target_count);
return Plugin_Handled;
}
for (int i = 0; i < target_count; i++)
{
int player = target_list[i];
if(player > 0 && player <= MaxClients && IsClientInGame(player) && IsPlayerAlive(player))
{
if(StringToInt(arg2) == 1)
MakeSkeleton(player, true);
else
MakeSkeleton(player);
}
EmitSoundToAll(SPAWN);
EmitSoundToAll(SPAWN2);
}
}
}
return Plugin_Handled;
}
public Action GetMaxHealth(int client, int &MaxHealth)
{
if (client > 0 && client <= MaxClients && IsClientInGame(client))
{
MaxHealth = 1000;
return Plugin_Changed;
}
return Plugin_Continue;
}
public Action SetModel(int client, const char[] model)
{
SetVariantString(model);
AcceptEntityInput(client, "SetCustomModel");
SetEntProp(client, Prop_Send, "m_bUseClassAnimations", 1);
}
stock void MakeSkeleton(int client, bool spectator = false)
{
if(spectator)
{
g_iOldTeam[client] = TF2_GetClientTeam(client);
SetEntProp(client, Prop_Send, "m_bForcedSkin", 1);
SetEntProp(client, Prop_Send, "m_nForcedSkin", 2);
SetEntProp(client, Prop_Send, "m_iTeamNum", 0);
}
TF2_SetPlayerClass(client, TFClass_Sniper, _, false);
ServerCommand("tf_models_remove #%d", GetClientUserId(client));
lastTeam[client] = GetClientTeam(client);
ChangeClientTeamEx(client, 0);
SetVariantString("1.5");
AcceptEntityInput(client, "SetModelScale");
SetModel(client, MODEL_SKELETON);
TF2_RemoveAllWearables(client);
TF2_RemoveAllWeapons(client);
CreateHat(client, 342, 10, 6); //Prince Tavish Crown
TF2_RemoveWeaponSlot(client, 2);
CreateWeapon(client, "tf_weapon_fists", 5, 6, 99, 2, 0);
int iEntity = GetPlayerWeaponSlot(client, 2);
SetEntityRenderMode(iEntity, RENDER_TRANSCOLOR);
SetEntityRenderColor(iEntity, 255, 255, 255, 0);
SetEntProp(iEntity, Prop_Send, "m_fEffects", 16);
char anim[16];
Format(anim, 32, "spawn0%i", GetRandomInt(1, 7));
PlayAnimation(client, anim);
g_bSpecial[client] = true;
SetNextAttack(iEntity, 2.0);
SDKHook(client, SDKHook_GetMaxHealth, GetMaxHealth);
SetEntProp(client, Prop_Send, "m_iHealth", 40000);
CreateTimer(0.0, Timer_SetModel, client);
g_bSkeleton[client] = true;
TF2Attrib_RemoveAll(client);
TF2Attrib_SetByName(client, "health from packs decreased", 0.001);
TF2Attrib_SetByName(client, "cancel falling damage", 1.0);
TF2Attrib_SetByName(client, "dmg taken from blast reduced", 0.3);
TF2Attrib_SetByName(client, "dmg taken from fire reduced", 0.3);
TF2Attrib_SetByName(client, "dmg taken from bullets reduced", 0.3);
TF2Attrib_SetByName(client, "dmg taken from crit reduced", 0.3);
TF2Attrib_SetByName(client, "dmg from ranged reduced", 0.3);
TF2Attrib_SetByName(client, "SET BONUS: dmg from sentry reduced", 0.3);
TF2Attrib_SetByName(client, "damage force reduction", 0.3);
TF2Attrib_SetByName(client, "cannot be backstabbed", 1.0);
TF2Attrib_SetByName(client, "airblast vulnerability multiplier", 0.0);
TF2Attrib_SetByName(client, "airblast vertical vulnerability multiplier", 0.0);
TF2Attrib_SetByName(client, "cannot pick up intelligence", 1.0);
new Weapon3 = GetPlayerWeaponSlot(client, 2);
TF2Attrib_RemoveAll(Weapon3);
TF2Attrib_SetByName(Weapon3, "melee attack rate bonus", 0.4);
TF2Attrib_SetByName(Weapon3, "melee bounds multiplier", 5.0);
TF2Attrib_SetByName(Weapon3, "melee range multiplier", 5.0);
TF2Attrib_SetByName(Weapon3, "damage bonus", 12.0);
TF2Attrib_SetByName(Weapon3, "armor piercing", 100.0);
TF2Attrib_SetByName(Weapon3, "dmg pierces resists absorbs", 1.0);
TF2Attrib_SetByName(Weapon3, "dmg bonus vs buildings", 5.0);
PrintToChat(client, "You are the Skeleton King!");
PrintToChat(client, "Skeleton King Commands: Use Right-Click to Stomp players,");
PrintToChat(client, "Use Mouse3 button (press down on mousewheel) to cast a Lightning spell");
PrintToChat(client, "You can attack BOTH Teams.");
PrintCenterText(client, "Skeleton King Commands: Use Right-Click to Stomp players, Use Mouse3 button (press down on mousewheel) to cast a Lightning spell, You can attack BOTH Teams.");
}
stock void PlayAnimation(int client, char[] anim)
{
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, view_as<float>({0.0, 0.0, 0.0}));
SetEntityRenderMode(client, RENDER_TRANSCOLOR);
SetEntityRenderColor(client, 255, 255, 255, 0);
SetEntProp(client, Prop_Send, "m_bUseClassAnimations", 0);
SetEntityMoveType(client, MOVETYPE_NONE);
float vecOrigin[3], vecAngles[3];
GetClientAbsOrigin(client, vecOrigin);
GetClientAbsAngles(client, vecAngles);
vecAngles[0] = 0.0;
int animationentity = CreateEntityByName("prop_dynamic_override");
if(IsValidEntity(animationentity))
{
DispatchKeyValueVector(animationentity, "origin", vecOrigin);
DispatchKeyValueVector(animationentity, "angles", vecAngles);
DispatchKeyValue(animationentity, "model", MODEL_SKELETON);
DispatchKeyValue(animationentity, "defaultanim", anim);
DispatchSpawn(animationentity);
SetEntPropEnt(animationentity, Prop_Send, "m_hOwnerEntity", client);
if(GetEntProp(client, Prop_Send, "m_iTeamNum") == 0)
SetEntProp(animationentity, Prop_Send, "m_nSkin", GetEntProp(client, Prop_Send, "m_nForcedSkin"));
else
SetEntProp(animationentity, Prop_Send, "m_nSkin", GetClientTeam(client) - 2);
SetEntPropFloat(animationentity, Prop_Send, "m_flModelScale", 1.5);
SetVariantString("OnAnimationDone !self:KillHierarchy::0.0:1");
AcceptEntityInput(animationentity, "AddOutput");
HookSingleEntityOutput(animationentity, "OnAnimationDone", OnAnimationDone, true);
}
}
public void OnAnimationDone(const char[] output, int caller, int activator, float delay)
{
if(IsValidEntity(caller))
{
int client = GetEntPropEnt(caller, Prop_Send, "m_hOwnerEntity");
if(client > 0 && client <= MaxClients && IsClientInGame(client) && IsPlayerAlive(client))
{
SetEntityMoveType(client, MOVETYPE_WALK);
SetEntProp(client, Prop_Send, "m_bUseClassAnimations", 1);
SetEntityRenderMode(client, RENDER_TRANSCOLOR);
SetEntityRenderColor(client, 255, 255, 255, 255);
g_bSpecial[client] = false;
}
}
}
public Action OnPlayerRunCmd(int client, int &iButtons, int &iImpulse, float fVel[3], float fAng[3], int &iWeapon)
{
if (IsPlayerAlive(client))
{
if(iButtons & IN_ATTACK2 && !g_bSpecial[client] && g_bSkeleton[client] && GetEntPropEnt(client, Prop_Send, "m_hGroundEntity") != -1)
{
SetNextAttack(GetPlayerWeaponSlot(client, TFWeaponSlot_Melee), 2.0);
PlayAnimation(client, "MELEE_swing3");
g_bSpecial[client] = true;
float vecAngles[3], vecOrigin[3];
GetClientAbsAngles(client, vecAngles);
GetClientAbsOrigin(client, vecOrigin);
vecAngles[0] = 0.0;
Handle pack;
CreateDataTimer(0.75, Timer_PerformStomp, pack, TIMER_FLAG_NO_MAPCHANGE);
WritePackCell(pack, client);
WritePackFloat(pack, vecOrigin[0]);
WritePackFloat(pack, vecOrigin[1]);
WritePackFloat(pack, vecOrigin[2]);
WritePackFloat(pack, vecAngles[0]);
WritePackFloat(pack, vecAngles[1]);
WritePackFloat(pack, vecAngles[2]);
}
else if(iButtons & IN_ATTACK3 && g_bSkeleton[client] == true && g_wait[client] == false)
{
ShootProjectile(client, LIGHTNING);
g_wait[client] = true;
CreateTimer(5.0, Waiting, client);
}
}
return Plugin_Continue;
}
public Action Timer_PerformStomp(Handle timer, Handle pack)
{
ResetPack(pack);
int client = ReadPackCell(pack);
float vecAngles[3], vecOrigin[3];
vecOrigin[0] = ReadPackFloat(pack);
vecOrigin[1] = ReadPackFloat(pack);
vecOrigin[2] = ReadPackFloat(pack);
vecAngles[0] = ReadPackFloat(pack);
vecAngles[1] = ReadPackFloat(pack);
vecAngles[2] = ReadPackFloat(pack);
float vForward[3], vLeft[3];
GetAngleVectors(vecAngles, vForward, NULL_VECTOR, NULL_VECTOR);
GetAngleVectors(vecAngles, NULL_VECTOR, vLeft, NULL_VECTOR);
vecOrigin[0] += (vForward[0] * 55);
vecOrigin[1] += (vForward[1] * 55);
vecOrigin[2] += (vForward[2] * 55);
vecOrigin[0] += (vLeft[0] * -35);
vecOrigin[1] += (vLeft[1] * -35);
vecOrigin[2] += (vLeft[2] * -35);
CreateParticle("bomibomicon_ring", vecOrigin); //The effect actually comes out of his leg VALVE
float pos2[3], Vec[3], AngBuff[3];
for(int i = 1; i <= MaxClients; i++)
{
if(IsClientInGame(i) && IsPlayerAlive(i) && i != client && GetClientTeam(i) != GetClientTeam(client))
{
GetClientAbsOrigin(i, pos2);
if(GetVectorDistance(vecOrigin, pos2) <= 200.0)
{
MakeVectorFromPoints(vecOrigin, pos2, Vec);
GetVectorAngles(Vec, AngBuff);
AngBuff[0] -= 30.0;
GetAngleVectors(AngBuff, Vec, NULL_VECTOR, NULL_VECTOR);
NormalizeVector(Vec, Vec);
ScaleVector(Vec, 500.0);
Vec[2] += 250.0;
SDKHooks_TakeDamage(i, client, client, GetConVarFloat(g_hCvarStompDamage));
TeleportEntity(i, NULL_VECTOR, NULL_VECTOR, Vec);
}
}
}
}
public Action TakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype)
{
if(victim > 0 && victim <= MaxClients && IsClientInGame(victim)
&& attacker > 0 && attacker <= MaxClients && IsClientInGame(attacker)
&& attacker != victim)
{
if(g_bSkeleton[attacker])
{
//damage = GetRandomFloat(95.0, 120.0);
damage = damage * 20
return Plugin_Changed;
}
}
return Plugin_Continue;
}
public Action Event_SkeletonDeath(Handle hEvent, char[] name, bool dontBroadcast)
{
int client = GetClientOfUserId(GetEventInt(hEvent, "userid"));
int attacker = GetEventInt(hEvent, "inflictor_entindex");
if(g_bSkeleton[client])
{
EmitSoundToAll("misc/halloween/skeleton_break.wav", client);
EmitSoundToAll(DEATH);
EmitSoundToAll(DEATHBOSS);
TF2Attrib_RemoveAll(client);
ForcePlayerSuicide(client);
g_bSkeleton[client] = false;
g_bSpecial[client] = false;
SDKUnhook(client, SDKHook_GetMaxHealth, GetMaxHealth);
SetEntityMoveType(client, MOVETYPE_WALK);
SetEntProp(client, Prop_Send, "m_bUseClassAnimations", 1);
SetEntProp(client, Prop_Send, "m_bForcedSkin", 0);
if(GetEntProp(client, Prop_Send, "m_iTeamNum") == 0)
{
SetEntProp(client, Prop_Send, "m_iTeamNum", g_iOldTeam[client]);
g_iOldTeam[client] = TFTeam_Spectator;
}
SetEntityRenderMode(client, RENDER_TRANSCOLOR);
SetEntityRenderColor(client, 255, 255, 255, 255);
SetVariantString("");
AcceptEntityInput(client, "SetCustomModel");
SetVariantString("1.0");
AcceptEntityInput(client, "SetModelScale");
RemoveModel(client);
ChangeClientTeamEx(client, lastTeam[client]);
ForcePlayerSuicide(client);
float vecOrigin[3];
GetClientAbsOrigin(client, vecOrigin);
//Drop a Rare spellbook
int spell = CreateEntityByName("tf_spell_pickup");
if(IsValidEntity(spell))
{
DispatchKeyValueVector(spell, "origin", vecOrigin);
DispatchKeyValueVector(spell, "basevelocity", view_as<float>({0.0, 0.0, 0.0}));
DispatchKeyValueVector(spell, "velocity", view_as<float>({0.0, 0.0, 0.0}));
DispatchKeyValue(spell, "powerup_model", "models/props_halloween/hwn_spellbook_upright_major.mdl");
DispatchKeyValue(spell, "OnPlayerTouch", "!self,Kill,,0,-1");
DispatchSpawn(spell);
SetVariantString("OnUser1 !self:kill::60:1");
AcceptEntityInput(spell, "AddOutput");
AcceptEntityInput(spell, "FireUser1");
SetEntPropEnt(spell, Prop_Send, "m_hOwnerEntity", client);
SetEntProp(spell, Prop_Data, "m_nTier", 1);
}
}
if(attacker > 0 && attacker <= MaxClients && IsClientInGame(attacker) && g_bSkeleton[attacker])
{
SetEventInt(hEvent, "attacker", 0);
SetEventString(hEvent, "weapon", "spellbook_skeleton");
SetEventInt(hEvent, "customkill", 66);
SetEventString(hEvent, "weapon_logclassname", "spellbook_skeleton");
}
return Plugin_Continue;
}
public Action SkeletonSH(clients[64], int &numClients, char sample[PLATFORM_MAX_PATH], int &entity, int &channel, float &volume, int &level, int &pitch, int &flags, char soundEntry[PLATFORM_MAX_PATH], int &seed)
{
if (entity > 0 && entity <= MaxClients && IsClientInGame(entity))
{
if (!g_bSkeleton[entity]) return Plugin_Continue;
if (StrContains(sample, "vo/sniper", false) != -1)
{
Format(sample, sizeof(sample), "misc/halloween/skeletons/skelly_giant_0%i.wav", GetRandomInt(1, 3));
PrecacheSound(sample);
EmitSoundToAll(sample, entity, channel, level, flags, volume);
return Plugin_Changed;
}
}
return Plugin_Continue;
}
stock void TF2_RemoveAllWearables(int client)
{
int wearable = -1;
while ((wearable = FindEntityByClassname(wearable, "tf_wearable*")) != -1)
{
if (IsValidEntity(wearable))
{
int player = GetEntPropEnt(wearable, Prop_Send, "m_hOwnerEntity");
if (client == player)
{
TF2_RemoveWearable(client, wearable);
}
}
}
while ((wearable = FindEntityByClassname(wearable, "vgui_screen")) != -1)
{
if (IsValidEntity(wearable))
{
int player = GetEntPropEnt(wearable, Prop_Data, "m_hOwnerEntity");
if (client == player)
{
AcceptEntityInput(wearable, "Kill");
}
}
}
while ((wearable = FindEntityByClassname(wearable, "tf_powerup_bottle")) != -1)
{
if (IsValidEntity(wearable))
{
int player = GetEntPropEnt(wearable, Prop_Send, "m_hOwnerEntity");
if (client == player)
{
TF2_RemoveWearable(client, wearable);
}
}
}
while ((wearable = FindEntityByClassname(wearable, "tf_weapon_spellbook")) != -1)
{
if (IsValidEntity(wearable))
{
int player = GetEntPropEnt(wearable, Prop_Send, "m_hOwnerEntity");
if (client == player)
{
TF2_RemoveWearable(client, wearable);
}
}
}
}
stock void SetNextAttack(int weapon, float duration = 0.0)
{
if (!IsValidEntity(weapon)) return;
float next = GetGameTime() + duration;
SetEntPropFloat(weapon, Prop_Send, "m_flNextPrimaryAttack", next);
SetEntPropFloat(weapon, Prop_Send, "m_flNextSecondaryAttack", next);
}
stock void CreateParticle(char[] particle, float pos[3])
{
int tblidx = FindStringTable("ParticleEffectNames");
char tmp[256];
int count = GetStringTableNumStrings(tblidx);
int stridx = INVALID_STRING_INDEX;
for(int i = 0; i < count; i++)
{
ReadStringTable(tblidx, i, tmp, sizeof(tmp));
if(StrEqual(tmp, particle, false))
{
stridx = i;
break;
}
}
for(int i = 1; i <= MaxClients; i++)
{
if(!IsValidEntity(i)) continue;
if(!IsClientInGame(i)) continue;
TE_Start("TFParticleEffect");
TE_WriteFloat("m_vecOrigin[0]", pos[0]);
TE_WriteFloat("m_vecOrigin[1]", pos[1]);
TE_WriteFloat("m_vecOrigin[2]", pos[2]);
TE_WriteNum("m_iParticleSystemIndex", stridx);
TE_WriteNum("entindex", -1);
TE_WriteNum("m_iAttachType", 5); //Dont associate with any entity
TE_SendToClient(i, 0.0);
}
}
public int Native_SetSkeleton(Handle plugin, int args)
{
MakeSkeleton(GetNativeCell(1));
}
public int Native_IsSkeleton(Handle plugin, int args)
{
return g_bSkeleton[GetNativeCell(1)];
}
public Action:RemoveModel(client)
{
if (IsValidClient(client))
{
SetEntPropFloat(client, Prop_Send, "m_flModelScale", 1.0);
SetVariantString("");
AcceptEntityInput(client, "SetCustomModel");
}
}
stock bool:IsValidClient(client)
{
if (client <= 0) return false;
if (client > MaxClients) return false;
return IsClientInGame(client);
}
public Action:Timer_SetModel(Handle:timer, any:client)
{
if (IsValidClient(client))
SetModel(client, MODEL_SKELETON);
}
void ChangeClientTeamEx(iClient, int iNewTeamNum)
{
int iTeamNum = GetEntProp(iClient, Prop_Send, "m_iTeamNum");
// Safely swap team
int iTeam = MaxClients+1;
while ((iTeam = FindEntityByClassname(iTeam, TEAM_CLASSNAME)) != -1)
{
int iAssociatedTeam = GetEntProp(iTeam, Prop_Send, "m_iTeamNum");
if (iAssociatedTeam == iTeamNum)
SDK_Team_RemovePlayer(iTeam, iClient);
else if (iAssociatedTeam == iNewTeamNum)
SDK_Team_AddPlayer(iTeam, iClient);
}
SetEntProp(iClient, Prop_Send, "m_iTeamNum", iNewTeamNum);
}
void SDK_Team_AddPlayer(int iTeam, int iClient)
{
if (g_hSDKTeamAddPlayer != INVALID_HANDLE)
{
SDKCall(g_hSDKTeamAddPlayer, iTeam, iClient);
}
}
void SDK_Team_RemovePlayer(int iTeam, int iClient)
{
if (g_hSDKTeamRemovePlayer != INVALID_HANDLE)
{
SDKCall(g_hSDKTeamRemovePlayer, iTeam, iClient);
}
}
ShootProjectile(client, spell)
{
new Float:vAngles[3]; // original
new Float:vPosition[3]; // original
GetClientEyeAngles(client, vAngles);
GetClientEyePosition(client, vPosition);
new String:strEntname[45] = "";
switch(spell)
{
case FIREBALL: strEntname = "tf_projectile_spellfireball";
case LIGHTNING: strEntname = "tf_projectile_lightningorb";
case PUMPKIN: strEntname = "tf_projectile_spellmirv";
case PUMPKIN2: strEntname = "tf_projectile_spellpumpkin";
case BATS: strEntname = "tf_projectile_spellbats";
case METEOR: strEntname = "tf_projectile_spellmeteorshower";
case TELE: strEntname = "tf_projectile_spelltransposeteleport";
case BOSS: strEntname = "tf_projectile_spellspawnboss";
case ZOMBIEH: strEntname = "tf_projectile_spellspawnhorde";
case ZOMBIE: strEntname = "tf_projectile_spellspawnzombie";
}
new iTeam = GetClientTeam(client);
new iSpell = CreateEntityByName(strEntname);
if(!IsValidEntity(iSpell))
return -1;
decl Float:vVelocity[3];
decl Float:vBuffer[3];
GetAngleVectors(vAngles, vBuffer, NULL_VECTOR, NULL_VECTOR);
vVelocity[0] = vBuffer[0]*1100.0; //Speed of a tf2 rocket.
vVelocity[1] = vBuffer[1]*1100.0;
vVelocity[2] = vBuffer[2]*1100.0;
SetEntPropEnt(iSpell, Prop_Send, "m_hOwnerEntity", client);
SetEntProp(iSpell, Prop_Send, "m_bCritical", (GetRandomInt(0, 100) <= 5)? 1 : 0, 1);
SetEntProp(iSpell, Prop_Send, "m_iTeamNum", iTeam, 1);
SetEntProp(iSpell, Prop_Send, "m_nSkin", (iTeam-2));
TeleportEntity(iSpell, vPosition, vAngles, NULL_VECTOR);
SetVariantInt(iTeam);
AcceptEntityInput(iSpell, "TeamNum", -1, -1, 0);
SetVariantInt(iTeam);
AcceptEntityInput(iSpell, "SetTeam", -1, -1, 0);
DispatchSpawn(iSpell);
TeleportEntity(iSpell, NULL_VECTOR, NULL_VECTOR, vVelocity);
return iSpell;
}
public Action:Waiting(Handle:timer, any:client)
{
g_wait[client] = false;
}
bool CreateHat(int client, int itemindex, int level, int quality)
{
int hat = CreateEntityByName("tf_wearable");
if (!IsValidEntity(hat))
{
return false;
}
char entclass[64];
GetEntityNetClass(hat, entclass, sizeof(entclass));
SetEntData(hat, FindSendPropInfo(entclass, "m_iItemDefinitionIndex"), itemindex);
SetEntData(hat, FindSendPropInfo(entclass, "m_bInitialized"), 1);
SetEntData(hat, FindSendPropInfo(entclass, "m_iEntityLevel"), level);
SetEntData(hat, FindSendPropInfo(entclass, "m_iEntityQuality"), quality);
SetEntProp(hat, Prop_Send, "m_bValidatedAttachedEntity", 1);
if (level)
{
SetEntData(hat, FindSendPropInfo(entclass, "m_iEntityLevel"), level);
}
else
{
SetEntData(hat, FindSendPropInfo(entclass, "m_iEntityLevel"), GetRandomInt(1,100));
}
SetEntData(hat, FindSendPropInfo(entclass, "m_iEntityQuality"), 5);
TF2Attrib_SetByDefIndex(hat, 134, 37.0);
DispatchSpawn(hat);
SDKCall(g_hWearableEquip, client, hat);
return true;
}
bool CreateWeapon(int client, char[] classname, int itemindex, int quality, int level, int slot, int paint)
{
TF2_RemoveWeaponSlot(client, slot);
int weapon = CreateEntityByName(classname);
if (!IsValidEntity(weapon))
{
return false;
}
quality = 7;
char entclass[64];
GetEntityNetClass(weapon, entclass, sizeof(entclass));
SetEntProp(weapon, Prop_Send, "m_iItemDefinitionIndex", itemindex);
SetEntProp(weapon, Prop_Send, "m_bInitialized", 1);
SetEntData(weapon, FindSendPropInfo(entclass, "m_iEntityQuality"), quality);
SetEntProp(weapon, Prop_Send, "m_bValidatedAttachedEntity", 1);
if (level)
{
SetEntData(weapon, FindSendPropInfo(entclass, "m_iEntityLevel"), level);
}
else
{
SetEntData(weapon, FindSendPropInfo(entclass, "m_iEntityLevel"), 20);
}
TF2Attrib_SetByDefIndex(weapon, 834, view_as<float>(paint));
DispatchSpawn(weapon);
EquipPlayerWeapon(client, weapon);
return true;
}
|
|