Guest User

Untitled

a guest
Sep 10th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 31.55 KB | None | 0 0
  1. #pragma semicolon 1
  2.  
  3. #include <sourcemod>
  4. #include <sdktools>
  5. #include <sdkhooks>
  6. #include <tf2_stocks>
  7. #include <morecolors>
  8. #include <tf2items>
  9. #include <freak_fortress_2>
  10. #include <freak_fortress_2_subplugin>
  11.  
  12. #define CBS_MAX_ARROWS 9
  13.  
  14. #define SOUND_SLOW_MO_START "replay/enterperformancemode.wav"  //Used when Ninja Spy enters slow mo
  15. #define SOUND_SLOW_MO_END "replay/exitperformancemode.wav"  //Used when Ninja Spy exits slow mo
  16. #define SOUND_DEMOPAN_RAGE "ui/notification_alert.wav"  //Used when Demopan rages
  17.  
  18. #define PLUGIN_VERSION "1.10.7"
  19.  
  20. public Plugin:myinfo=
  21. {
  22.     name="Freak Fortress 2: Abilities of 1st set",
  23.     author="RainBolt Dash",
  24.     description="FF2: Abilities used by Seeldier, Seeman, Demopan, CBS, and Ninja Spy",
  25.     version=PLUGIN_VERSION,
  26. };
  27.  
  28. #define FLAG_ONSLOWMO           (1<<0)
  29. #define FLAG_SLOWMOREADYCHANGE  (1<<1)
  30.  
  31. new FF2Flags[MAXPLAYERS+1];
  32. new CloneOwnerIndex[MAXPLAYERS+1]=-1;
  33.  
  34. new Handle:SlowMoTimer;
  35. new oldTarget;
  36.  
  37. new Handle:OnHaleRage=INVALID_HANDLE;
  38.  
  39. new Handle:cvarTimeScale;
  40. new Handle:cvarCheats;
  41. new Handle:cvarKAC;
  42. new BossTeam=_:TFTeam_Blue;
  43.  
  44. public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
  45. {
  46.     OnHaleRage=CreateGlobalForward("VSH_OnDoRage", ET_Hook, Param_FloatByRef);
  47.     return APLRes_Success;
  48. }
  49.  
  50.  
  51. public OnPluginStart2()
  52. {
  53.     new version[3];
  54.     FF2_GetFF2Version(version);
  55.     if(version[0]==1 && (version[1]<10 || (version[1]==10 && version[2]<3)))
  56.     {
  57.         SetFailState("This subplugin depends on at least FF2 v1.10.3");
  58.     }
  59.  
  60.     HookEvent("teamplay_round_start", OnRoundStart);
  61.     HookEvent("teamplay_round_win", OnRoundEnd);
  62.     HookEvent("player_death", OnPlayerDeath);
  63.  
  64.     cvarTimeScale=FindConVar("host_timescale");
  65.     cvarCheats=FindConVar("sv_cheats");
  66.     cvarKAC=FindConVar("kac_enable");
  67.  
  68.     LoadTranslations("ff2_1st_set.phrases");
  69. }
  70.  
  71. public OnMapStart()
  72. {
  73.     PrecacheSound(SOUND_SLOW_MO_START, true);
  74.     PrecacheSound(SOUND_SLOW_MO_END, true);
  75.     PrecacheSound(SOUND_DEMOPAN_RAGE, true);
  76. }
  77.  
  78. public Action:OnRoundStart(Handle:event, const String:name[], bool:dontBroadcast)
  79. {
  80.     CreateTimer(0.3, Timer_GetBossTeam, _, TIMER_FLAG_NO_MAPCHANGE);
  81.     for(new client=1; client<=MaxClients; client++)
  82.     {
  83.         FF2Flags[client]=0;
  84.         CloneOwnerIndex[client]=-1;
  85.     }
  86.     return Plugin_Continue;
  87. }
  88.  
  89. /*public Action:FF2_OnSpecialSelected(boss, &special, String:specialName[])  //Re-enable in v2 or whenever the late-loading forward bug is fixed
  90. {
  91.     if(FF2_HasAbility(boss, this_plugin_name, "special_dropprop"))
  92.     {
  93.         decl String:model[PLATFORM_MAX_PATH];
  94.         FF2_GetAbilityArgumentString(boss, this_plugin_name, "special_dropprop", 1, model, sizeof(model));
  95.         PrecacheModel(model);
  96.     }
  97.     return Plugin_Continue;
  98. }*/
  99.  
  100. public Action:OnRoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
  101. {
  102.     for(new client=1; client<=MaxClients; client++)
  103.     {
  104.         if(FF2Flags[client] & FLAG_ONSLOWMO)
  105.         {
  106.             if(SlowMoTimer)
  107.             {
  108.                 KillTimer(SlowMoTimer);
  109.             }
  110.             Timer_StopSlowMo(INVALID_HANDLE, -1);
  111.             return Plugin_Continue;
  112.         }
  113.  
  114.         if(IsClientInGame(client) && CloneOwnerIndex[client]!=-1)  //FIXME: IsClientInGame() shouldn't be needed
  115.         {
  116.             CloneOwnerIndex[client]=-1;
  117.             FF2_SetFF2flags(client, FF2_GetFF2flags(client) & ~FF2FLAG_CLASSTIMERDISABLED);
  118.         }
  119.     }
  120.     return Plugin_Continue;
  121. }
  122.  
  123. public OnClientDisconnect(client)
  124. {
  125.     FF2Flags[client]=0;
  126.     if(CloneOwnerIndex[client]!=-1)
  127.     {
  128.         CloneOwnerIndex[client]=-1;
  129.         FF2_SetFF2flags(client, FF2_GetFF2flags(client) & ~FF2FLAG_CLASSTIMERDISABLED);
  130.     }
  131. }
  132.  
  133. public Action:Timer_GetBossTeam(Handle:timer)
  134. {
  135.     if(cvarKAC && GetConVarBool(cvarKAC))
  136.     {
  137.         SetConVarBool(cvarKAC, false);
  138.     }
  139.     BossTeam=FF2_GetBossTeam();
  140.     return Plugin_Continue;
  141. }
  142.  
  143. public Action:FF2_OnAbility2(boss, const String:plugin_name[], const String:ability_name[], status)
  144. {
  145.     new slot=FF2_GetAbilityArgument(boss, this_plugin_name, ability_name, 0);
  146.     if(!slot)  //Rage
  147.     {
  148.         if(!boss)
  149.         {
  150.             new Action:action=Plugin_Continue;
  151.             Call_StartForward(OnHaleRage);
  152.             new Float:distance=FF2_GetRageDist(boss, this_plugin_name, ability_name);
  153.             new Float:newDistance=distance;
  154.             Call_PushFloatRef(newDistance);
  155.             Call_Finish(action);
  156.             if(action!=Plugin_Continue && action!=Plugin_Changed)
  157.             {
  158.                 return Plugin_Continue;
  159.             }
  160.             else if(action==Plugin_Changed)
  161.             {
  162.                 distance=newDistance;
  163.             }
  164.         }
  165.     }
  166.  
  167.     if(!strcmp(ability_name, "special_democharge"))
  168.     {
  169.         if(status>0)
  170.         {
  171.             new client=GetClientOfUserId(FF2_GetBossUserId(boss));
  172.             new Float:charge=FF2_GetBossCharge(boss, 0);
  173.             SetEntPropFloat(client, Prop_Send, "m_flChargeMeter", 100.0);
  174.             TF2_AddCondition(client, TFCond_Charging, 0.25);
  175.             if(charge>10.0 && charge<90.0)
  176.             {
  177.                 FF2_SetBossCharge(boss, 0, charge-0.4);
  178.             }
  179.         }
  180.     }
  181.     else if(!strcmp(ability_name, "rage_cloneattack"))
  182.     {
  183.         Rage_Clone(ability_name, boss);
  184.     }
  185.     else if(!strcmp(ability_name, "rage_tradespam"))
  186.     {
  187.         CreateTimer(0.0, Timer_Demopan_Rage, 1, TIMER_FLAG_NO_MAPCHANGE);
  188.     }
  189.     else if(!strcmp(ability_name, "rage_cbs_bowrage"))
  190.     {
  191.         Rage_Bow(boss);
  192.     }
  193.     else if(!strcmp(ability_name, "rage_explosive_dance"))
  194.     {
  195.         SetEntityMoveType(GetClientOfUserId(FF2_GetBossUserId(boss)), MOVETYPE_NONE);
  196.         new Handle:data;
  197.         CreateDataTimer(0.15, Timer_Prepare_Explosion_Rage, data);
  198.         WritePackString(data, ability_name);
  199.         WritePackCell(data, boss);
  200.         ResetPack(data);
  201.     }
  202.     else if(!strcmp(ability_name, "rage_matrix_attack"))
  203.     {
  204.         Rage_Slowmo(boss, ability_name);
  205.     }
  206.     return Plugin_Continue;
  207. }
  208.  
  209. Rage_Clone(const String:ability_name[], boss)
  210. {
  211.     new Handle:bossKV[8];
  212.     decl String:bossName[32];
  213.     new bool:changeModel=bool:FF2_GetAbilityArgument(boss, this_plugin_name, ability_name, 1);
  214.     new weaponMode=FF2_GetAbilityArgument(boss, this_plugin_name, ability_name, 2);
  215.     decl String:model[PLATFORM_MAX_PATH];
  216.     FF2_GetAbilityArgumentString(boss, this_plugin_name, ability_name, 3, model, sizeof(model));
  217.     new class=FF2_GetAbilityArgument(boss, this_plugin_name, ability_name, 4);
  218.     new Float:ratio=FF2_GetAbilityArgumentFloat(boss, this_plugin_name, ability_name, 5, 0.0);
  219.     new String:classname[64]="tf_weapon_bottle";
  220.     FF2_GetAbilityArgumentString(boss, this_plugin_name, ability_name, 6, classname, sizeof(classname));
  221.     new index=FF2_GetAbilityArgument(boss, this_plugin_name, ability_name, 7, 191);
  222.     new String:attributes[64]="68 ; -1";
  223.     FF2_GetAbilityArgumentString(boss, this_plugin_name, ability_name, 8, attributes, sizeof(attributes));
  224.     new ammo=FF2_GetAbilityArgument(boss, this_plugin_name, ability_name, 9, -1);
  225.     new clip=FF2_GetAbilityArgument(boss, this_plugin_name, ability_name, 10, -1);
  226.     new health=FF2_GetAbilityArgument(boss, this_plugin_name, ability_name, 11, 0);
  227.  
  228.     new Float:position[3], Float:velocity[3];
  229.     GetEntPropVector(GetClientOfUserId(FF2_GetBossUserId(boss)), Prop_Data, "m_vecOrigin", position);
  230.  
  231.     FF2_GetBossSpecial(boss, bossName, sizeof(bossName));
  232.  
  233.     new maxKV;
  234.     for(maxKV=0; maxKV<8; maxKV++)
  235.     {
  236.         if(!(bossKV[maxKV]=FF2_GetSpecialKV(maxKV)))
  237.         {
  238.             break;
  239.         }
  240.     }
  241.  
  242.     new alive, dead;
  243.     new Handle:players=CreateArray();
  244.     for(new target=1; target<=MaxClients; target++)
  245.     {
  246.         if(IsClientInGame(target))
  247.         {
  248.             new TFTeam:team=TFTeam:GetClientTeam(target);
  249.             if(team>TFTeam_Spectator && team!=TFTeam_Blue)
  250.             {
  251.                 if(IsPlayerAlive(target))
  252.                 {
  253.                     alive++;
  254.                 }
  255.                 else if(FF2_GetBossIndex(target)==-1)  //Don't let dead bosses become clones
  256.                 {
  257.                     PushArrayCell(players, target);
  258.                     dead++;
  259.                 }
  260.             }
  261.         }
  262.     }
  263.  
  264.     new totalMinions=(ratio ? RoundToCeil(alive*ratio) : MaxClients);  //If ratio is 0, use MaxClients instead
  265.     new config=GetRandomInt(0, maxKV-1);
  266.     new clone, temp;
  267.     for(new i=1; i<=dead && i<=totalMinions; i++)
  268.     {
  269.         temp=GetRandomInt(0, GetArraySize(players)-1);
  270.         clone=GetArrayCell(players, temp);
  271.         RemoveFromArray(players, temp);
  272.  
  273.         FF2_SetFF2flags(clone, FF2_GetFF2flags(clone)|FF2FLAG_ALLOWSPAWNINBOSSTEAM|FF2FLAG_CLASSTIMERDISABLED);
  274.         ChangeClientTeam(clone, BossTeam);
  275.         TF2_RespawnPlayer(clone);
  276.         CloneOwnerIndex[clone]=boss;
  277.         TF2_SetPlayerClass(clone, (class ? (TFClassType:class) : (TFClassType:KvGetNum(bossKV[config], "class", 0))), _, false);
  278.  
  279.         if(changeModel)
  280.         {
  281.             if(model[0]=='\0')
  282.             {
  283.                 KvGetString(bossKV[config], "model", model, sizeof(model));
  284.             }
  285.             SetVariantString(model);
  286.             AcceptEntityInput(clone, "SetCustomModel");
  287.             SetEntProp(clone, Prop_Send, "m_bUseClassAnimations", 1);
  288.         }
  289.  
  290.         switch(weaponMode)
  291.         {
  292.             case 0:
  293.             {
  294.                 TF2_RemoveAllWeapons(clone);
  295.             }
  296.             case 1:
  297.             {
  298.                 new weapon;
  299.                 TF2_RemoveAllWeapons(clone);
  300.                 if(classname[0]=='\0')
  301.                 {
  302.                     classname="tf_weapon_bottle";
  303.                 }
  304.  
  305.                 if(attributes[0]=='\0')
  306.                 {
  307.                     attributes="68 ; -1";
  308.                 }
  309.  
  310.                 weapon=SpawnWeapon(clone, classname, index, 101, 0, attributes);
  311.                 if(StrEqual(classname, "tf_weapon_builder") && index!=735)  //PDA, normal sapper
  312.                 {
  313.                     SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 1, _, 0);
  314.                     SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 1, _, 1);
  315.                     SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 1, _, 2);
  316.                     SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 0, _, 3);
  317.                 }
  318.                 else if(StrEqual(classname, "tf_weapon_sapper") || index==735)  //Sappers, normal sapper
  319.                 {
  320.                     SetEntProp(weapon, Prop_Send, "m_iObjectType", 3);
  321.                     SetEntProp(weapon, Prop_Data, "m_iSubType", 3);
  322.                     SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 0, _, 0);
  323.                     SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 0, _, 1);
  324.                     SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 0, _, 2);
  325.                     SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 1, _, 3);
  326.                 }
  327.  
  328.                 if(IsValidEntity(weapon))
  329.                 {
  330.                     SetEntPropEnt(clone, Prop_Send, "m_hActiveWeapon", weapon);
  331.                     SetEntProp(weapon, Prop_Send, "m_iWorldModelIndex", -1);
  332.                 }
  333.  
  334.                 FF2_SetAmmo(clone, weapon, ammo, clip);
  335.             }
  336.         }
  337.  
  338.         if(health)
  339.         {
  340.             SetEntProp(clone, Prop_Data, "m_iMaxHealth", health);
  341.             SetEntProp(clone, Prop_Data, "m_iHealth", health);
  342.             SetEntProp(clone, Prop_Send, "m_iHealth", health);
  343.         }
  344.  
  345.         velocity[0]=GetRandomFloat(300.0, 500.0)*(GetRandomInt(0, 1) ? 1:-1);
  346.         velocity[1]=GetRandomFloat(300.0, 500.0)*(GetRandomInt(0, 1) ? 1:-1);
  347.         velocity[2]=GetRandomFloat(300.0, 500.0);
  348.         TeleportEntity(clone, position, NULL_VECTOR, velocity);
  349.  
  350.         PrintHintText(clone, "%t", "seeldier_rage_message", bossName);
  351.  
  352.         SetEntProp(clone, Prop_Data, "m_takedamage", 0);
  353.         SDKHook(clone, SDKHook_OnTakeDamage, SaveMinion);
  354.         CreateTimer(4.0, Timer_Enable_Damage, GetClientUserId(clone), TIMER_FLAG_NO_MAPCHANGE);
  355.  
  356.         new Handle:data;
  357.         CreateDataTimer(0.1, Timer_EquipModel, data, TIMER_FLAG_NO_MAPCHANGE);
  358.         WritePackCell(data, GetClientUserId(clone));
  359.         WritePackString(data, model);
  360.     }
  361.     CloseHandle(players);
  362.  
  363.     new entity, owner;
  364.     while((entity=FindEntityByClassname(entity, "tf_wearable"))!=-1)
  365.     {
  366.         if((owner=GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity"))<=MaxClients && owner>0 && GetClientTeam(owner)==BossTeam)
  367.         {
  368.             TF2_RemoveWearable(owner, entity);
  369.         }
  370.     }
  371.  
  372.     while((entity=FindEntityByClassname(entity, "tf_wearable_demoshield"))!=-1)
  373.     {
  374.         if((owner=GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity"))<=MaxClients && owner>0 && GetClientTeam(owner)==BossTeam)
  375.         {
  376.             TF2_RemoveWearable(owner, entity);
  377.         }
  378.     }
  379.  
  380.     while((entity=FindEntityByClassname(entity, "tf_powerup_bottle"))!=-1)
  381.     {
  382.         if((owner=GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity"))<=MaxClients && owner>0 && GetClientTeam(owner)==BossTeam)
  383.         {
  384.             TF2_RemoveWearable(owner, entity);
  385.         }
  386.     }
  387. }
  388.  
  389. public Action:Timer_EquipModel(Handle:timer, any:pack)
  390. {
  391.     ResetPack(pack);
  392.     new client=GetClientOfUserId(ReadPackCell(pack));
  393.     if(client && IsClientInGame(client) && IsPlayerAlive(client))
  394.     {
  395.         decl String:model[PLATFORM_MAX_PATH];
  396.         ReadPackString(pack, model, PLATFORM_MAX_PATH);
  397.         SetVariantString(model);
  398.         AcceptEntityInput(client, "SetCustomModel");
  399.         SetEntProp(client, Prop_Send, "m_bUseClassAnimations", 1);
  400.     }
  401. }
  402.  
  403. public Action:Timer_Enable_Damage(Handle:timer, any:userid)
  404. {
  405.     new client=GetClientOfUserId(userid);
  406.     if(client)
  407.     {
  408.         SetEntProp(client, Prop_Data, "m_takedamage", 2);
  409.         FF2_SetFF2flags(client, FF2_GetFF2flags(client) & ~FF2FLAG_ALLOWSPAWNINBOSSTEAM);
  410.         SDKUnhook(client, SDKHook_OnTakeDamage, SaveMinion);
  411.     }
  412.     return Plugin_Continue;
  413. }
  414.  
  415. public Action:SaveMinion(client, &attacker, &inflictor, &Float:damage, &damagetype, &weapon, Float:damageForce[3], Float:damagePosition[3])
  416. {
  417.     if(attacker>MaxClients)
  418.     {
  419.         decl String:edict[64];
  420.         if(GetEntityClassname(attacker, edict, sizeof(edict)) && !strcmp(edict, "trigger_hurt", false))
  421.         {
  422.             new target, Float:position[3];
  423.             new bool:otherTeamIsAlive;
  424.             for(new clone=1; clone<=MaxClients; clone++)
  425.             {
  426.                 if(IsValidEntity(clone) && IsClientInGame(clone) && IsPlayerAlive(clone) && GetClientTeam(clone)!=BossTeam)
  427.                 {
  428.                     otherTeamIsAlive=true;
  429.                     break;
  430.                 }
  431.             }
  432.  
  433.             new tries;
  434.             do
  435.             {
  436.                 tries++;
  437.                 target=GetRandomInt(1, MaxClients);
  438.                 if(tries==100)
  439.                 {
  440.                     return Plugin_Continue;
  441.                 }
  442.             }
  443.             while(otherTeamIsAlive && (!IsValidEntity(target) || GetClientTeam(target)==BossTeam || !IsPlayerAlive(target)));
  444.  
  445.             GetEntPropVector(target, Prop_Data, "m_vecOrigin", position);
  446.             TeleportEntity(client, position, NULL_VECTOR, NULL_VECTOR);
  447.             TF2_StunPlayer(client, 2.0, 0.0, TF_STUNFLAGS_GHOSTSCARE|TF_STUNFLAG_NOSOUNDOREFFECT, client);
  448.             return Plugin_Handled;
  449.         }
  450.     }
  451.     return Plugin_Continue;
  452. }
  453.  
  454. public Action:Timer_Demopan_Rage(Handle:timer, any:count)  //TODO: Make this rage configurable
  455. {
  456.     if(count==13)  //Rage has finished-reset it in 6 seconds (trade_0 is 100% transparent apparently)
  457.     {
  458.         CreateTimer(6.0, Timer_Demopan_Rage, 0, TIMER_FLAG_NO_MAPCHANGE);
  459.     }
  460.     else
  461.     {
  462.         decl String:overlay[PLATFORM_MAX_PATH];
  463.         Format(overlay, sizeof(overlay), "r_screenoverlay \"freak_fortress_2/demopan/trade_%i\"", count);
  464.  
  465.         SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & ~FCVAR_CHEAT);  //Allow normal players to use r_screenoverlay
  466.         for(new client=1; client<=MaxClients; client++)
  467.         {
  468.             if(IsClientInGame(client) && IsPlayerAlive(client) && GetClientTeam(client)!=BossTeam)
  469.             {
  470.                 ClientCommand(client, overlay);
  471.             }
  472.         }
  473.         SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT);  //Reset the cheat permissions
  474.  
  475.         if(count)
  476.         {
  477.             EmitSoundToAll(SOUND_DEMOPAN_RAGE, _, _, _, _, _, _, _, _, _, false);
  478.             CreateTimer(count==1 ? 1.0 : 0.5/float(count), Timer_Demopan_Rage, count+1, TIMER_FLAG_NO_MAPCHANGE);  //Give a longer delay between the first and second overlay for "smoothness"
  479.         }
  480.         else  //Stop the rage
  481.         {
  482.             return Plugin_Stop;
  483.         }
  484.     }
  485.     return Plugin_Continue;
  486. }
  487.  
  488. Rage_Bow(boss)
  489. {
  490.     new client=GetClientOfUserId(FF2_GetBossUserId(boss));
  491.     TF2_RemoveWeaponSlot(client, TFWeaponSlot_Primary);
  492.     new weapon=SpawnWeapon(client, "tf_weapon_compound_bow", 1005, 100, 5, "6 ; 0.5 ; 37 ; 0.0 ; 280 ; 19");
  493.     SetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", weapon);
  494.     new TFTeam:team=(FF2_GetBossTeam()==_:TFTeam_Blue ? TFTeam_Red:TFTeam_Blue);
  495.  
  496.     new otherTeamAlivePlayers;
  497.     for(new target=1; target<=MaxClients; target++)
  498.     {
  499.         if(IsClientInGame(target) && TFTeam:GetClientTeam(target)==team && IsPlayerAlive(target))
  500.         {
  501.             otherTeamAlivePlayers++;
  502.         }
  503.     }
  504.  
  505.     FF2_SetAmmo(client, weapon, ((otherTeamAlivePlayers>=CBS_MAX_ARROWS) ? CBS_MAX_ARROWS : otherTeamAlivePlayers)-1, 1);  //Put one arrow in the clip
  506. }
  507.  
  508. public Action:Timer_Prepare_Explosion_Rage(Handle:timer, Handle:data)
  509. {
  510.     new boss=ReadPackCell(data);
  511.     new client=GetClientOfUserId(FF2_GetBossUserId(boss));
  512.  
  513.     decl String:ability_name[64];
  514.     ReadPackString(data, ability_name, sizeof(ability_name));
  515.  
  516.     CreateTimer(0.13, Timer_Rage_Explosive_Dance, boss, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
  517.  
  518.     new Float:position[3];
  519.     GetEntPropVector(client, Prop_Data, "m_vecOrigin", position);
  520.  
  521.     new String:sound[PLATFORM_MAX_PATH];
  522.     FF2_GetAbilityArgumentString(boss, this_plugin_name, ability_name, 1, sound, PLATFORM_MAX_PATH);
  523.     if(strlen(sound))
  524.     {
  525.         EmitSoundToAll(sound, client, _, _, _, _, _, client, position);
  526.         EmitSoundToAll(sound, client, _, _, _, _, _, client, position);
  527.         for(new target=1; target<=MaxClients; target++)
  528.         {
  529.             if(IsClientInGame(target) && target!=client)
  530.             {
  531.                 EmitSoundToClient(target, sound, client, _, _, _, _, _, client, position);
  532.                 EmitSoundToClient(target, sound, client, _, _, _, _, _, client, position);
  533.             }
  534.         }
  535.     }
  536.     return Plugin_Continue;
  537. }
  538.  
  539. public Action:Timer_Rage_Explosive_Dance(Handle:timer, any:boss)
  540. {
  541.     static count;
  542.     new client=GetClientOfUserId(FF2_GetBossUserId(boss));
  543.     count++;
  544.     if(count<=35 && IsPlayerAlive(client))
  545.     {
  546.         SetEntityMoveType(boss, MOVETYPE_NONE);
  547.         new Float:bossPosition[3], Float:explosionPosition[3];
  548.         GetEntPropVector(client, Prop_Send, "m_vecOrigin", bossPosition);
  549.         explosionPosition[2]=bossPosition[2];
  550.         for(new i; i<5; i++)
  551.         {
  552.             new explosion=CreateEntityByName("env_explosion");
  553.             DispatchKeyValueFloat(explosion, "DamageForce", 180.0);
  554.  
  555.             SetEntProp(explosion, Prop_Data, "m_iMagnitude", 280, 4);
  556.             SetEntProp(explosion, Prop_Data, "m_iRadiusOverride", 200, 4);
  557.             SetEntPropEnt(explosion, Prop_Data, "m_hOwnerEntity", client);
  558.  
  559.             DispatchSpawn(explosion);
  560.  
  561.             explosionPosition[0]=bossPosition[0]+GetRandomInt(-350, 350);
  562.             explosionPosition[1]=bossPosition[1]+GetRandomInt(-350, 350);
  563.             if(!(GetEntityFlags(boss) & FL_ONGROUND))
  564.             {
  565.                 explosionPosition[2]=bossPosition[2]+GetRandomInt(-150, 150);
  566.             }
  567.             else
  568.             {
  569.                 explosionPosition[2]=bossPosition[2]+GetRandomInt(0,100);
  570.             }
  571.             TeleportEntity(explosion, explosionPosition, NULL_VECTOR, NULL_VECTOR);
  572.             AcceptEntityInput(explosion, "Explode");
  573.             AcceptEntityInput(explosion, "kill");
  574.  
  575.             /*proj=CreateEntityByName("tf_projectile_rocket");
  576.             SetVariantInt(BossTeam);
  577.             AcceptEntityInput(proj, "TeamNum", -1, -1, 0);
  578.             SetVariantInt(BossTeam);
  579.             AcceptEntityInput(proj, "SetTeam", -1, -1, 0);
  580.             SetEntPropEnt(proj, Prop_Send, "m_hOwnerEntity",boss);
  581.             decl Float:position[3];
  582.             new Float:rot[3]={0.0,90.0,0.0};
  583.             new Float:see[3]={0.0,0.0,-1000.0};
  584.             GetEntPropVector(boss, Prop_Send, "m_vecOrigin", position);
  585.             position[0]+=GetRandomInt(-250,250);
  586.             position[1]+=GetRandomInt(-250,250);
  587.             position[2]+=40;
  588.             TeleportEntity(proj, position, rot,see);
  589.             SetEntDataFloat(proj, FindSendPropOffs("CTFProjectile_Rocket", "m_iDeflected") + 4, 300.0, true);
  590.             DispatchSpawn(proj);
  591.             CreateTimer(0.1,Timer_Rage_Explosive_Dance_Boom,EntIndextoEntRef(proj));*/
  592.         }
  593.     }
  594.     else
  595.     {
  596.         SetEntityMoveType(client, MOVETYPE_WALK);
  597.         count=0;
  598.         return Plugin_Stop;
  599.     }
  600.     return Plugin_Continue;
  601. }
  602.  
  603. Rage_Slowmo(boss, const String:ability_name[])
  604. {
  605.     FF2_SetFF2flags(boss, FF2_GetFF2flags(boss)|FF2FLAG_CHANGECVAR);
  606.     SetConVarFloat(cvarTimeScale, FF2_GetAbilityArgumentFloat(boss, this_plugin_name, ability_name, 2, 0.1));
  607.     new Float:duration=FF2_GetAbilityArgumentFloat(boss, this_plugin_name, ability_name, 1, 1.0)+1.0;
  608.     SlowMoTimer=CreateTimer(duration, Timer_StopSlowMo, boss, TIMER_FLAG_NO_MAPCHANGE);
  609.     FF2Flags[boss]=FF2Flags[boss]|FLAG_SLOWMOREADYCHANGE|FLAG_ONSLOWMO;
  610.     UpdateClientCheatValue(1);
  611.  
  612.     new client=GetClientOfUserId(FF2_GetBossUserId(boss));
  613.     if(client)
  614.     {
  615.         CreateTimer(duration, Timer_RemoveEntity, EntIndexToEntRef(AttachParticle(client, BossTeam==_:TFTeam_Blue ? "scout_dodge_blue" : "scout_dodge_red", 75.0)), TIMER_FLAG_NO_MAPCHANGE);
  616.     }
  617.  
  618.     EmitSoundToAll(SOUND_SLOW_MO_START, _, _, _, _, _, _, _, _, _, false);
  619.     EmitSoundToAll(SOUND_SLOW_MO_START, _, _, _, _, _, _, _, _, _, false);
  620. }
  621.  
  622. public Action:Timer_StopSlowMo(Handle:timer, any:boss)
  623. {
  624.     SlowMoTimer=INVALID_HANDLE;
  625.     oldTarget=0;
  626.     SetConVarFloat(cvarTimeScale, 1.0);
  627.     UpdateClientCheatValue(0);
  628.     if(boss!=-1)
  629.     {
  630.         FF2_SetFF2flags(boss, FF2_GetFF2flags(boss) & ~FF2FLAG_CHANGECVAR);
  631.         FF2Flags[boss]&=~FLAG_ONSLOWMO;
  632.     }
  633.     EmitSoundToAll(SOUND_SLOW_MO_END, _, _, _, _, _, _, _, _, _, false);
  634.     EmitSoundToAll(SOUND_SLOW_MO_END, _, _, _, _, _, _, _, _, _, false);
  635.     return Plugin_Continue;
  636. }
  637.  
  638. public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:velocity[3], Float:angles[3], &weapon)
  639. {
  640.     new boss=FF2_GetBossIndex(client);
  641.     if(boss==-1 || !(FF2Flags[boss] & FLAG_ONSLOWMO))
  642.     {
  643.         return Plugin_Continue;
  644.     }
  645.  
  646.     if(buttons & IN_ATTACK)
  647.     {
  648.         FF2Flags[boss]&=~FLAG_SLOWMOREADYCHANGE;
  649.         CreateTimer(FF2_GetAbilityArgumentFloat(boss, this_plugin_name, "rage_matrix_attack", 3, 0.2), Timer_SlowMoChange, boss, TIMER_FLAG_NO_MAPCHANGE);
  650.  
  651.         new Float:bossPosition[3], Float:endPosition[3], Float:eyeAngles[3];
  652.         GetEntPropVector(client, Prop_Send, "m_vecOrigin", bossPosition);
  653.         bossPosition[2]+=65;
  654.         GetClientEyeAngles(client, eyeAngles);
  655.  
  656.         new Handle:trace=TR_TraceRayFilterEx(bossPosition, eyeAngles, MASK_SOLID, RayType_Infinite, TraceRayDontHitSelf);
  657.         TR_GetEndPosition(endPosition, trace);
  658.         endPosition[2]+=100;
  659.         SubtractVectors(endPosition, bossPosition, velocity);
  660.         NormalizeVector(velocity, velocity);
  661.         ScaleVector(velocity, 2012.0);
  662.         TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, velocity);
  663.         new target=TR_GetEntityIndex(trace);
  664.         if(target && target<=MaxClients)
  665.         {
  666.             new Handle:data;
  667.             CreateDataTimer(0.15, Timer_Rage_SlowMo_Attack, data);
  668.             WritePackCell(data, GetClientUserId(client));
  669.             WritePackCell(data, GetClientUserId(target));
  670.             ResetPack(data);
  671.         }
  672.         CloseHandle(trace);
  673.     }
  674.     return Plugin_Continue;
  675. }
  676.  
  677. public Action:Timer_Rage_SlowMo_Attack(Handle:timer, Handle:data)
  678. {
  679.     new client=GetClientOfUserId(ReadPackCell(data));
  680.     new target=GetClientOfUserId(ReadPackCell(data));
  681.     if(client && target && IsClientInGame(client) && IsClientInGame(target))
  682.     {
  683.         new Float:clientPosition[3], Float:targetPosition[3];
  684.         GetEntPropVector(client, Prop_Send, "m_vecOrigin", clientPosition);
  685.         GetEntPropVector(target, Prop_Send, "m_vecOrigin", targetPosition);
  686.         if(GetVectorDistance(clientPosition, targetPosition)<=1500 && target!=oldTarget)
  687.         {
  688.             SetEntProp(client, Prop_Send, "m_bDucked", 1);
  689.             SetEntityFlags(client, GetEntityFlags(client)|FL_DUCKING);
  690.             SDKHooks_TakeDamage(target, client, client, 900.0);
  691.             TeleportEntity(client, targetPosition, NULL_VECTOR, NULL_VECTOR);
  692.             oldTarget=target;
  693.         }
  694.     }
  695. }
  696.  
  697. public bool:TraceRayDontHitSelf(entity, mask)
  698. {
  699.     if(!entity || entity>MaxClients)
  700.     {
  701.         return true;
  702.     }
  703.  
  704.     if(FF2_GetBossIndex(entity)==-1)
  705.     {
  706.         return true;
  707.     }
  708.     return false;
  709. }
  710.  
  711.  
  712. public Action:Timer_SlowMoChange(Handle:timer, any:boss)
  713. {
  714.     FF2Flags[boss]|=FLAG_SLOWMOREADYCHANGE;
  715.     return Plugin_Continue;
  716. }
  717.  
  718.  
  719. //Unused single rocket shoot charge
  720. /*Charge_RocketSpawn(const String:ability_name[],index,slot,action)
  721. {
  722.     if(FF2_GetBossCharge(index,0)<10)
  723.         return;
  724.     new boss=GetClientOfUserId(FF2_GetBossUserId(index));
  725.     new Float:see=FF2_GetAbilityArgumentFloat(index,this_plugin_name,ability_name,1,5.0);
  726.     new Float:charge=FF2_GetBossCharge(index,slot);
  727.     switch(action)
  728.     {
  729.         case 2:
  730.         {
  731.             SetHudTextParams(-1.0, 0.93, 0.15, 255, 255, 255, 255);
  732.             if(charge+1<see)
  733.                 FF2_SetBossCharge(index,slot,charge+1);
  734.             else
  735.                 FF2_SetBossCharge(index,slot,see);
  736.             ShowSyncHudText(boss, chargeHUD, "%t","charge_status",RoundFloat(charge*100/see));
  737.         }
  738.         case 3:
  739.         {
  740.             FF2_SetBossCharge(index,0,charge-10);
  741.             decl Float:position[3];
  742.             decl Float:rot[3];
  743.             decl Float:velocity[3];
  744.             GetEntPropVector(boss, Prop_Send, "m_vecOrigin", position);
  745.             GetClientEyeAngles(boss,rot);
  746.             position[2]+=63;
  747.  
  748.             new proj=CreateEntityByName("tf_projectile_rocket");
  749.             SetVariantInt(BossTeam);
  750.             AcceptEntityInput(proj, "TeamNum", -1, -1, 0);
  751.             SetVariantInt(BossTeam);
  752.             AcceptEntityInput(proj, "SetTeam", -1, -1, 0);
  753.             SetEntPropEnt(proj, Prop_Send, "m_hOwnerEntity",boss);
  754.             new Float:speed=FF2_GetAbilityArgumentFloat(index,this_plugin_name,ability_name,3,1000.0);
  755.             velocity[0]=Cosine(DegToRad(rot[0]))*Cosine(DegToRad(rot[1]))*speed;
  756.             velocity[1]=Cosine(DegToRad(rot[0]))*Sine(DegToRad(rot[1]))*speed;
  757.             velocity[2]=Sine(DegToRad(rot[0]))*speed;
  758.             velocity[2]*=-1;
  759.             TeleportEntity(proj, position, rot,velocity);
  760.             SetEntDataFloat(proj, FindSendPropOffs("CTFProjectile_Rocket", "m_iDeflected") + 4, FF2_GetAbilityArgumentFloat(index,this_plugin_name,ability_name,5,150.0), true);
  761.             DispatchSpawn(proj);
  762.             new String:s[PLATFORM_MAX_PATH];
  763.             FF2_GetAbilityArgumentString(index,this_plugin_name,ability_name,4,s,PLATFORM_MAX_PATH);
  764.             if(strlen(s)>5)
  765.                 SetEntityModel(proj,s);
  766.             FF2_SetBossCharge(index,slot,-5*FF2_GetAbilityArgumentFloat(index,this_plugin_name,ability_name,2,5.0));
  767.             if(FF2_RandomSound("sound_ability",s,PLATFORM_MAX_PATH,index,slot))
  768.             {
  769.                 EmitSoundToAll(s, boss, _, SNDLEVEL_TRAFFIC, SND_NOFLAGS, SNDVOL_NORMAL, 100, boss, position, NULL_VECTOR, true, 0.0);
  770.                 EmitSoundToAll(s, boss, _, SNDLEVEL_TRAFFIC, SND_NOFLAGS, SNDVOL_NORMAL, 100, boss, position, NULL_VECTOR, true, 0.0);
  771.  
  772.                 for(new i=1; i<=MaxClients; i++)
  773.                     if(IsClientInGame(i) && i!=boss)
  774.                     {
  775.                         EmitSoundToClient(i,s, boss, _, SNDLEVEL_TRAFFIC, SND_NOFLAGS, SNDVOL_NORMAL, 100, boss, position, NULL_VECTOR, true, 0.0);
  776.                         EmitSoundToClient(i,s, boss, _, SNDLEVEL_TRAFFIC, SND_NOFLAGS, SNDVOL_NORMAL, 100, boss, position, NULL_VECTOR, true, 0.0);
  777.                     }
  778.             }
  779.         }
  780.     }
  781. }
  782. */
  783.  
  784. public Action:OnPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
  785. {
  786.     new attacker=GetClientOfUserId(GetEventInt(event, "attacker"));
  787.     new client=GetClientOfUserId(GetEventInt(event, "userid"));
  788.     new boss=FF2_GetBossIndex(attacker);
  789.  
  790.     if(boss!=-1)
  791.     {
  792.         if(FF2_HasAbility(boss, this_plugin_name, "special_dropprop"))
  793.         {
  794.             decl String:model[PLATFORM_MAX_PATH];
  795.             FF2_GetAbilityArgumentString(boss, this_plugin_name, "special_dropprop", 1, model, sizeof(model));
  796.             if(model[0]!='\0')  //Because you never know when someone is careless and doesn't specify a model...
  797.             {
  798.                 if(!IsModelPrecached(model))  //Make sure the boss author precached the model (similar to above)
  799.                 {
  800.                     new String:bossName[64];
  801.                     FF2_GetBossSpecial(boss, bossName, sizeof(bossName));
  802.                     if(!FileExists(model, true))
  803.                     {
  804.                         LogError("[FF2 Bosses] Model '%s' doesn't exist!  Please check %s's config", model, bossName);
  805.                         return Plugin_Continue;
  806.                     }
  807.  
  808.                     LogError("[FF2 Bosses] Model '%s' isn't precached!  Please check %s's \"mod_precache\"", model, bossName);
  809.                     PrecacheModel(model);
  810.                 }
  811.  
  812.                 if(FF2_GetAbilityArgument(boss, this_plugin_name, "special_dropprop", 3, 0))
  813.                 {
  814.                     CreateTimer(0.01, Timer_RemoveRagdoll, GetEventInt(event, "userid"), TIMER_FLAG_NO_MAPCHANGE);
  815.                 }
  816.  
  817.                 new prop=CreateEntityByName("prop_physics_override");
  818.                 if(IsValidEntity(prop))
  819.                 {
  820.                     SetEntityModel(prop, model);
  821.                     SetEntityMoveType(prop, MOVETYPE_VPHYSICS);
  822.                     SetEntProp(prop, Prop_Send, "m_CollisionGroup", 1);
  823.                     SetEntProp(prop, Prop_Send, "m_usSolidFlags", 16);
  824.                     DispatchSpawn(prop);
  825.  
  826.                     new Float:position[3];
  827.                     GetEntPropVector(client, Prop_Send, "m_vecOrigin", position);
  828.                     position[2]+=20;
  829.                     TeleportEntity(prop, position, NULL_VECTOR, NULL_VECTOR);
  830.                     new Float:duration=FF2_GetAbilityArgumentFloat(boss, this_plugin_name, "special_dropprop", 2, 0.0);
  831.                     if(duration>0.5)
  832.                     {
  833.                         CreateTimer(duration, Timer_RemoveEntity, EntIndexToEntRef(prop), TIMER_FLAG_NO_MAPCHANGE);
  834.                     }
  835.                 }
  836.             }
  837.         }
  838.  
  839.         if(FF2_HasAbility(boss, this_plugin_name, "special_cbs_multimelee"))
  840.         {
  841.             if(GetEntPropEnt(attacker, Prop_Send, "m_hActiveWeapon")==GetPlayerWeaponSlot(attacker, TFWeaponSlot_Melee))
  842.             {
  843.                 TF2_RemoveWeaponSlot(attacker, TFWeaponSlot_Melee);
  844.                 new weapon;
  845.                 switch(GetRandomInt(0, 2))
  846.                 {
  847.                     case 0:
  848.                     {
  849.                         weapon=SpawnWeapon(attacker, "tf_weapon_club", 171, 101, 5, "68 ; 2 ; 2 ; 3.1");
  850.                     }
  851.                     case 1:
  852.                     {
  853.                         weapon=SpawnWeapon(attacker, "tf_weapon_club", 193, 101, 5, "68 ; 2 ; 2 ; 3.1");
  854.                     }
  855.                     case 2:
  856.                     {
  857.                         weapon=SpawnWeapon(attacker, "tf_weapon_club", 232, 101, 5, "68 ; 2 ; 2 ; 3.1");
  858.                     }
  859.                 }
  860.                 SetEntPropEnt(attacker, Prop_Data, "m_hActiveWeapon", weapon);
  861.             }
  862.         }
  863.     }
  864.  
  865.     boss=FF2_GetBossIndex(client);
  866.     if(boss!=-1 && FF2_HasAbility(boss, this_plugin_name, "rage_cloneattack") && FF2_GetAbilityArgument(boss, this_plugin_name, "rage_cloneattack", 12, 1) && !(GetEventInt(event, "death_flags") & TF_DEATHFLAG_DEADRINGER))
  867.     {
  868.         for(new target=1; target<=MaxClients; target++)
  869.         {
  870.             if(CloneOwnerIndex[target]==boss)
  871.             {
  872.                 CloneOwnerIndex[target]=-1;
  873.                 FF2_SetFF2flags(target, FF2_GetFF2flags(target) & ~FF2FLAG_CLASSTIMERDISABLED);
  874.                 if(IsClientInGame(target) && GetClientTeam(target)==BossTeam)
  875.                 {
  876.                     ChangeClientTeam(target, (BossTeam==_:TFTeam_Blue) ? (_:TFTeam_Red) : (_:TFTeam_Blue));
  877.                 }
  878.             }
  879.         }
  880.     }
  881.  
  882.     if(CloneOwnerIndex[client]!=-1 && !(GetEventInt(event, "death_flags") & TF_DEATHFLAG_DEADRINGER))  //Switch clones back to the other team after they die
  883.     {
  884.         CloneOwnerIndex[client]=-1;
  885.         FF2_SetFF2flags(client, FF2_GetFF2flags(client) & ~FF2FLAG_CLASSTIMERDISABLED);
  886.         ChangeClientTeam(client, (BossTeam==_:TFTeam_Blue) ? (_:TFTeam_Red) : (_:TFTeam_Blue));
  887.     }
  888.     return Plugin_Continue;
  889. }
  890.  
  891. public Action:Timer_RemoveRagdoll(Handle:timer, any:userid)
  892. {
  893.     new client=GetClientOfUserId(userid);
  894.     new ragdoll;
  895.     if(client>0 && (ragdoll=GetEntPropEnt(client, Prop_Send, "m_hRagdoll"))>MaxClients)
  896.     {
  897.         AcceptEntityInput(ragdoll, "Kill");
  898.     }
  899. }
  900.  
  901. stock SpawnWeapon(client, String:name[], index, level, quality, String:attribute[])
  902. {
  903.     new Handle:weapon=TF2Items_CreateItem(OVERRIDE_ALL|FORCE_GENERATION);
  904.     TF2Items_SetClassname(weapon, name);
  905.     TF2Items_SetItemIndex(weapon, index);
  906.     TF2Items_SetLevel(weapon, level);
  907.     TF2Items_SetQuality(weapon, quality);
  908.     new String:attributes[32][32];
  909.     new count = ExplodeString(attribute, ";", attributes, 32, 32);
  910.     if(count%2!=0)
  911.     {
  912.         count--;
  913.     }
  914.  
  915.     if(count>0)
  916.     {
  917.         TF2Items_SetNumAttributes(weapon, count/2);
  918.         new i2=0;
  919.         for(new i=0; i<count; i+=2)
  920.         {
  921.             new attrib=StringToInt(attributes[i]);
  922.             if(attrib==0)
  923.             {
  924.                 LogError("Bad weapon attribute passed: %s ; %s", attributes[i], attributes[i+1]);
  925.                 return -1;
  926.             }
  927.             TF2Items_SetAttribute(weapon, i2, attrib, StringToFloat(attributes[i+1]));
  928.             i2++;
  929.         }
  930.     }
  931.     else
  932.     {
  933.         TF2Items_SetNumAttributes(weapon, 0);
  934.     }
  935.  
  936.     if(weapon==INVALID_HANDLE)
  937.     {
  938.         return -1;
  939.     }
  940.     new entity=TF2Items_GiveNamedItem(client, weapon);
  941.     CloseHandle(weapon);
  942.     EquipPlayerWeapon(client, entity);
  943.     return entity;
  944. }
  945.  
  946. public Action:Timer_RemoveEntity(Handle:timer, any:entid)
  947. {
  948.     new entity=EntRefToEntIndex(entid);
  949.     if(IsValidEntity(entity) && entity>MaxClients)
  950.     {
  951.         AcceptEntityInput(entity, "Kill");
  952.     }
  953. }
  954.  
  955. stock AttachParticle(entity, String:particleType[], Float:offset=0.0, bool:attach=true)
  956. {
  957.     new particle=CreateEntityByName("info_particle_system");
  958.  
  959.     decl String:targetName[128];
  960.     new Float:position[3];
  961.     GetEntPropVector(entity, Prop_Send, "m_vecOrigin", position);
  962.     position[2]+=offset;
  963.     TeleportEntity(particle, position, NULL_VECTOR, NULL_VECTOR);
  964.  
  965.     Format(targetName, sizeof(targetName), "target%i", entity);
  966.     DispatchKeyValue(entity, "targetname", targetName);
  967.  
  968.     DispatchKeyValue(particle, "targetname", "tf2particle");
  969.     DispatchKeyValue(particle, "parentname", targetName);
  970.     DispatchKeyValue(particle, "effect_name", particleType);
  971.     DispatchSpawn(particle);
  972.     SetVariantString(targetName);
  973.     if(attach)
  974.     {
  975.         AcceptEntityInput(particle, "SetParent", particle, particle, 0);
  976.         SetEntPropEnt(particle, Prop_Send, "m_hOwnerEntity", entity);
  977.     }
  978.     ActivateEntity(particle);
  979.     AcceptEntityInput(particle, "start");
  980.     return particle;
  981. }
  982.  
  983. stock UpdateClientCheatValue(value)
  984. {
  985.     for(new client=1; client<=MaxClients; client++)
  986.     {
  987.         if(IsClientInGame(client) && !IsFakeClient(client))
  988.         {
  989.             SendConVarValue(client, cvarCheats, value ? "1" : "0");
  990.         }
  991.     }
  992. }
Add Comment
Please, Sign In to add comment