#pragma semicolon 1

#define DEBUG

#define PLUGIN_AUTHOR "jenz"
#define PLUGIN_VERSION "1.01"

#include <sourcemod>
#include <sdkhooks>
#include <sdktools>
#include <smlib>
#include <zr/infect.zr>
#include <cstrike>


//global
float g_IAdminspin;
float g_iBotairjump;
int g_iDelay;
bool g_bRoundStart;

public Plugin myinfo = 
{
	name = "autism bot",
	author = PLUGIN_AUTHOR,
	description = "spawns the bot on a team",
	version = PLUGIN_VERSION,
	url = "www.unloze.com"
};

public void OnMapStart()
{
	g_IAdminspin = 0.0;
	g_iBotairjump = 1.0;
	g_iDelay = 0;
}

public void OnPluginStart()
{
	RegAdminCmd("sm_botspin", Cmd_botSpin, ADMFLAG_GENERIC);
	RegAdminCmd("sm_botjump", Cmd_botJump, ADMFLAG_GENERIC);
	
	//hook
	HookEvent("player_death", PlayerDeath);
	HookEvent("round_start", Event_roundStart, EventHookMode_Post);
}

public void OnClientPostAdminCheck(int client)
{
	if (IsFakeClient(client))
	{
		SDKHook(client, SDKHook_OnTakeDamagePost, OnTakeDamagePost);
		ChangeClientTeam(client, CS_TEAM_CT);
	}
}
public void Event_roundStart(Handle event, const char[] name, bool dontBroadcast)
{
	g_bRoundStart = true;
	for (int i = 1; i < MaxClients; i++)
	{
		if (IsClientConnected(i) && IsClientInGame(i) && IsClientSourceTV(i) && IsPlayerAlive(i))
		{
			ForcePlayerSuicide(i);
			CreateTimer(0.5, safeSpec, i);
			break;
		}	
	}
}

public Action PlayerDeath(Handle event, const char[] name, bool dontBroadcast)
{
	int client = GetClientOfUserId(GetEventInt(event, "userid"));
	if (IsClientSourceTV(client) && !g_bRoundStart)
	{
		CreateTimer(0.5, safeSpec, client);
		CreateTimer(9.0, respawn_func, client);
	}
}
public Action safeSpec(Handle timer, int client)
{  
	ChangeClientTeam(client, CS_TEAM_SPECTATOR);
}

public Action respawn_func(Handle timer, int client)
{
	if (!g_bRoundStart)
	{
		ChangeClientTeam(client, CS_TEAM_CT);
		ServerCommand("sm_fakecommand %N say /zspawn", client);
		//ZR_InfectClient(client);
	}
}

public Action Cmd_botSpin(int client, int args)
{
	char inputArgs[250];
	float input;
	GetCmdArgString(inputArgs, sizeof(inputArgs));
	
	input = StringToFloat(inputArgs);
	PrintToChat(client, "spin value: %f", input);
	if (input == 0.0)
	{
		PrintToChat(client, "input failed");
		return Plugin_Handled;
	}
	else if (input >= 360.0 || input <= -360.0)
	{
		PrintToChat(client, "Input Range: -360 to 360");
		return Plugin_Handled;
	}
	g_IAdminspin = input;
	
	return Plugin_Handled;
}

public Action Cmd_botJump(int client, int args)
{
	char inputArgs[250];
	float input;
	GetCmdArgString(inputArgs, sizeof(inputArgs));
	
	input = StringToFloat(inputArgs);
	PrintToChat(client, "jump value: %f", input);
	if (input == 0.0)
	{
		PrintToChat(client, "input failed");
		return Plugin_Handled;
	}
	else if (input >= 10.0 || input <= -10.0)
	{
		PrintToChat(client, "Input Range: -10 to 10");
		return Plugin_Handled;
	}
	g_iBotairjump = input;
	
	return Plugin_Handled;
}

public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float move[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
{
	if (IsFakeClient(client))
	{	
		if (g_IAdminspin == 0.0)
		{
			angles[1] += 30.0;
			if (angles[1] >= 360.0)
			{
				angles[1] = 0.0;
			}
			TeleportEntity(client, NULL_VECTOR, angles, NULL_VECTOR);
			++g_iDelay;
			if (g_iDelay >= 10)
			{
				buttons |= IN_ATTACK;
				g_iDelay = 0;
				buttons |= IN_DUCK;
				Client_Push(client);
			}
			return Plugin_Changed;
		}
		else
		{
			angles[1] += g_IAdminspin;
			if (angles[1] >= 360.0)
			{
				angles[1] = 0.0;
			}
			TeleportEntity(client, NULL_VECTOR, angles, NULL_VECTOR);
			++g_iDelay;
			if (g_iDelay >= 10)
			{
				buttons |= IN_ATTACK;
				buttons |= IN_DUCK;
				g_iDelay = 0;
				Client_Push(client);
			}
			return Plugin_Changed;
		}
	}
	return Plugin_Continue;
}

public void Client_Push (int client)
{
	float newVel[3];
	int GroundEnt = GetEntPropEnt(client, Prop_Send, "m_hGroundEntity"); 
	if (GroundEnt == -1)
	{
		//PrintToChatAll("Bot %N is not on ground", client);
	}
	else
	{
		int i_nr = GetRandomInt(1, 4);
		if (i_nr == 1)
		{
			newVel[1] += GetRandomInt(50, 350);
		}
		else if (i_nr == 2)
		{
			newVel[0] += GetRandomInt(50, 350);
		}
		else if (i_nr == 3)
		{
			newVel[0] -= GetRandomInt(50, 350);
		}
		else if (i_nr == 4)
		{
			newVel[1] -= GetRandomInt(50, 350);
		}
		newVel[2] += GetRandomInt(50, 350) * g_iBotairjump;
		//newVel[1] += GetRandomFloat(0.10, 270.10);
		Entity_SetAbsVelocity(client, newVel);
		//PrintToChatAll("Bot %N is on ground", client);
	}
}

public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
{
	if (!motherInfect)
	return;
	for (int i = 1; i <= MaxClients; i++)
	{
		if (IsClientConnected(i) && IsClientInGame(i) && IsClientSourceTV(i))
		{
			g_bRoundStart = false;
			CreateTimer(1.0, respawn_func, i);	
		}
	}
}

//----------------------------------------------------------------------------------------------------
// Purpose: damageHook
//----------------------------------------------------------------------------------------------------

public Action OnTakeDamagePost(victim, &attacker, &inflictor, &Float:damage, &damagetype)
{
	// Don't pass alive players
    if (IsPlayerAlive(victim))
    {
    	return Plugin_Handled;
    }
    if (attacker == 0)
    {
        // World
         ServerCommand("sm_fakecommand #%i say \"fuck u world!\"", GetClientUserId(victim), attacker);
    }
    else if (victim == attacker)
    {
        // Suicide
         ServerCommand("sm_fakecommand #%i say \"fuck ur admin abuse!\"", GetClientUserId(victim), attacker);
    }
    else if (1 <= attacker <= MaxClients)
    {
   		ServerCommand("sm_fakecommand #%i say \"%N fuck u m8!\"", GetClientUserId(victim), attacker);
    }
    return Plugin_Handled;
}