#pragma semicolon 1
#include <sourcemod>
#define PLUGIN_VERSION "1.1.1"
public Plugin:myinfo =
{
name = "L4D2 Monster Bots",
author = "Machine & Pan Xiaohai modified",
description = "Automated Special Infected Creator",
version = PLUGIN_VERSION,
url = "www.AlliedMods.net"
};
//////////////////////////////////////////////////////////
//Monster Types
//
//0 = Random (Smoker,Boomer,Hunter,Spitter,Jockey,Charger)
//1 = Smoker
//2 = Boomer
//3 = Hunter
//4 = Spitter
//5 = Jockey
//6 = Charger
//7 = Witch
//8 = Tank
//////////////////////////////////////////////////////////
new nummonsters;
new Handle:monstermaxbots;
new Handle:monsterbotson;
new Handle:monsterinterval;
new Handle:monsternodirector;
new Handle:monsterwitchrange;
new Handle:monstermaxbots_tank;
new timertick;
new numoutrange;
new numsurvivors;
new bool:tank;
public OnPluginStart()
{
CreateConVar("monsterbots_version", PLUGIN_VERSION, "L4D2 Monster Bots Version", FCVAR_PLUGIN|FCVAR_DONTRECORD);
monstermaxbots = CreateConVar("monsterbots_maxbots", "14", "The maximum amount of monster bots", FCVAR_PLUGIN, true, 0.0);
monstermaxbots_tank = CreateConVar("monstermaxbots_tank", "4", "The maximum amount of monster bots", FCVAR_PLUGIN, true, 0.0);
monsterbotson = CreateConVar("monsterbots_on","1", "Is monster bots on?", FCVAR_PLUGIN, true, 0.0);
monsterinterval = CreateConVar("monsterbots_interval","50", "How many seconds till another monster spawns", FCVAR_PLUGIN, true, 0.0);
monsternodirector = CreateConVar("monsterbots_nodirector","0", "Shutdown the director?", FCVAR_PLUGIN, true, 0.0);
HookEvent("round_start", Event_RoundStart);
HookEvent("round_end", Event_RoundEnd);
HookEvent("tank_spawn", Event_Tank_Spawn);
HookConVarChange(monsterbotson, MonsterBots_Switch);
CreateTimer(1.0,TimerUpdate, _, TIMER_REPEAT);
//AutoExecConfig(true, "l4d2_monsterbots_config2");
}
public Action:Event_Tank_Spawn(Handle:event, const String:name[], bool:dontBroadcast)
{
new client = GetClientOfUserId(GetEventInt(event, "userid"));
CreateTimer(3.0, SpawnWitch, client);
}
public Action:SpawnWitch(Handle:timer, any:client)
{
new bot = CreateFakeClient("Monster");
if (bot > 0)
{
SpawnCommand(bot, "z_spawn", "witch");
}
return Plugin_Continue;
}
public Action:Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
new flags = GetConVarFlags(FindConVar("z_max_player_zombies"));
SetConVarBounds(FindConVar("z_max_player_zombies"), ConVarBound_Upper, false);
SetConVarFlags(FindConVar("z_max_player_zombies"), flags & ~FCVAR_NOTIFY);
}
public Action:Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
for (new i=1; i<=MaxClients; i++)
{
if (IsClientInGame(i))
{
if (GetClientTeam(i) == 3)
{
if (IsFakeClient(i))
{
KickClient(i);
}
}
}
}
}
public Action:TimerUpdate(Handle:timer)
{
if (!IsServerProcessing()) return;
if (GetConVarBool(monsterbotson))
{
if (GetConVarBool(monsternodirector))
{
new anyclient = GetAnyClient();
if (anyclient > 0)
{
DirectorCommand(anyclient, "director_stop");
}
SetConVarInt(FindConVar("director_no_bosses"), 1);
SetConVarInt(FindConVar("director_no_specials"), 1);
SetConVarInt(FindConVar("director_no_mobs"), 1);
SetConVarInt(FindConVar("z_common_limit"), 0);
}
SetConVarInt(FindConVar("z_max_player_zombies"), 32);
timertick += 1;
if (timertick >= GetConVarInt(monsterinterval))
{
CountMonsters();
new max=0;
if(tank)max=GetConVarInt(monstermaxbots_tank);
else max=GetConVarInt(monstermaxbots);
//PrintToChatAll("max %d", max);
if (nummonsters < max)
{
new bot = CreateFakeClient("Monster");
if (bot > 0)
{
new random = GetRandomInt(1,6);
switch(random)
{
case 1:
SpawnCommand(bot, "z_spawn", "smoker auto");
case 2:
SpawnCommand(bot, "z_spawn", "boomer auto");
case 3:
SpawnCommand(bot, "z_spawn", "hunter auto");
case 4:
SpawnCommand(bot, "z_spawn", "spitter auto");
case 5:
SpawnCommand(bot, "z_spawn", "jockey auto");
case 6:
SpawnCommand(bot, "z_spawn", "charger auto");
}
//Kickbot(0.1, bot);
}
}
timertick = 0;
}
}
}
public MonsterBots_Switch(Handle:hVariable, const String:strOldValue[], const String:strNewValue[])
{
if (GetConVarInt(monsterbotson) == 0)
{
if (GetConVarBool(monsternodirector))
{
SetConVarInt(FindConVar("director_no_bosses"), 0);
SetConVarInt(FindConVar("director_no_specials"), 0);
SetConVarInt(FindConVar("director_no_mobs"), 0);
SetConVarInt(FindConVar("z_common_limit"), 30);
new anyclient = GetAnyClient();
if (anyclient > 0)
{
DirectorCommand(anyclient, "director_start");
}
}
}
}
public Action:Kickbot(Handle:timer, any:client)
{
if (IsClientInGame(client))
{
if (IsFakeClient(client))
{
KickClient(client);
}
}
}
CountMonsters()
{
nummonsters = 0;
tank=false;
for (new i=1; i<=MaxClients; i++)
{
if (IsClientInGame(i))
{
if (GetClientTeam(i) == 3)
{
if (IsFakeClient(i))
{
nummonsters++;
new class = GetEntProp(i, Prop_Send, "m_zombieClass");
if (class == 8) tank=true;
}
}
}
}
}
CountSurvivors()
{
numsurvivors = 0;
for (new i=1; i<=MaxClients; i++)
{
if (IsClientInGame(i))
{
if (GetClientTeam(i) == 2)
{
if (IsPlayerAlive(i))
{
numsurvivors++;
}
}
}
}
}
stock GetAnyClient()
{
for (new i=1; i<=MaxClients; i++)
{
if (IsClientInGame(i) && (!IsFakeClient(i)))
{
return i;
}
}
return 0;
}
stock SpawnCommand(client, String:command[], String:arguments[] = "")
{
if (client)
{
ChangeClientTeam(client,3);
new flags = GetCommandFlags(command);
SetCommandFlags(command, flags & ~FCVAR_CHEAT);
FakeClientCommand(client, "%s %s", command, arguments);
SetCommandFlags(command, flags);
CreateTimer(0.1,Kickbot,client);
}
}
stock DirectorCommand(client, String:command[])
{
if (client)
{
new flags = GetCommandFlags(command);
SetCommandFlags(command, flags & ~FCVAR_CHEAT);
FakeClientCommand(client, "%s", command);
SetCommandFlags(command, flags);
}
}
求生之路 妖怪特感-源码
评论
(0)