
// timers
public Action:SpurtTimer(Handle:Timer, any:client)
{
	if(IsClientInGame(client) && IsClientConnected(client) && IsPlayerAlive(client))
	{
		//if(IsPlayer(client) == false) PrintToServer("[SM][DC] SpurtTimer:FALSE");
		BloodSpurt(client);
		
		new bloodloss = GetConVarInt(cvBloodLoss);
		decl health;
		health = GetClientHealth(client);
		health -= bloodloss;

		if (health > 0)
			SetEntityHealth(client, health);
		else
			ForcePlayerSuicide(client);
	}

	return Plugin_Continue;
}

public Action:CheckPosTimer(Handle:Timer)
{
	new Float:tolerance = GetConVarFloat(cvAimTolerance);
	decl Float:distance;
	decl Float:ClientOrigin[3];
	decl Float:HeadOrigin[3];

	for (new client = 1; client <= MaxClients; client++)
	{
		if (g_HeadEnt[client] > 0)
		{
			//if(IsPlayer(client) == false) PrintToServer("[SM][DC] CheckPosTimer:FALSE");
			GetClientAbsOrigin(client,ClientOrigin);
			ClientOrigin[0] += 5.0;
			ClientOrigin[2] += 60.0;
			GetEntPropVector(g_HeadEnt[client], Prop_Send, "m_vecOrigin", HeadOrigin);
			distance = GetVectorDistance(ClientOrigin, HeadOrigin);
			
			if(distance < tolerance)
				ReattachHead(client);
		}
	}
	
	return Plugin_Continue;
}

// decapination functions
public GiveHead(any:victim, String:headmodel[])
{
	//if(IsPlayer(victim) == false) PrintToServer("[SM][DC] GiveHead:FALSE");
	g_HeadEnt[victim] = CreateEntityByName("prop_physics_override");
	SetEntityModel(g_HeadEnt[victim],headmodel);
	SetEntityMoveType(g_HeadEnt[victim], MOVETYPE_VPHYSICS);
	SetEntProp(g_HeadEnt[victim], Prop_Data, "m_CollisionGroup", 11); //TODO: CHECKME
	SetEntProp(g_HeadEnt[victim], Prop_Data, "m_usSolidFlags", 16);
	DispatchSpawn(g_HeadEnt[victim]);

	if(IsValidEntity(g_HeadEnt[victim]))
	{
		new Roll;
		
		new Float:spurtinterval = GetConVarFloat(cvSpurtInterval);

		new Float:Client_Origin[3];
		new Float:Client_Angles[3];
		new Float:vecVelocity[3];

		GetClientAbsOrigin(victim,Client_Origin);
		GetClientAbsAngles(victim,Client_Angles);

		//Client_Origin[0] += 30;
		Client_Origin[2] += 50;

		vecVelocity[0] = GetRandomFloat(-130.0,130.0);
		vecVelocity[1] = GetRandomFloat(-130.0,130.0);
		vecVelocity[2] = GetRandomFloat(100.0,250.0);
		
		TeleportEntity(g_HeadEnt[victim], Client_Origin, Client_Angles, vecVelocity);
		
		SetView(victim,g_HeadEnt[victim]);

		BloodSpurt(victim);

		g_SpurtTimer[victim] = CreateTimer((spurtinterval), SpurtTimer, victim, TIMER_REPEAT);
		
		Roll = GetRandomInt(1, 4);
		if(Roll == 1) EmitSoundToAll(g_ChippySquishy1Sound, g_HeadEnt[victim]);
		if(Roll == 2) EmitSoundToAll(g_ChippySquishy1Sound, g_HeadEnt[victim]);
		if(Roll == 3) EmitSoundToAll(g_ChippySquishy1Sound, g_HeadEnt[victim]);
		if(Roll == 4) EmitSoundToAll(g_ChippySquishy1Sound, g_HeadEnt[victim]);
	}
}

public ReattachHead(any:client)
{
	//if(IsPlayer(client) == false) PrintToServer("[SM][DC] ReattachHead:FALSE");
	if(IsClientInGame(client) && IsClientConnected(client))
	{
		new String:oldmodel[256];
		new String:bodymodel[256];

		GetClientModel(client, oldmodel, 256);

		if (StrEqual(oldmodel, "models/player/ct_gign1_dc.mdl", false))
		{
			bodymodel = "models/player/ct_gign.mdl";
		}
		else if (StrEqual(oldmodel, "models/player/ct_gsg91_dc.mdl", false))
		{
			bodymodel = "models/player/ct_gsg9.mdl";
		}
		else if (StrEqual(oldmodel, "models/player/ct_sas1_dc.mdl", false))
		{
			bodymodel = "models/player/ct_sas.mdl";
		}
		else if (StrEqual(oldmodel, "models/player/ct_urban1_dc.mdl", false))
		{
			bodymodel = "models/player/ct_urban.mdl";
		}
		else if (StrEqual(oldmodel, "models/player/t_arctic1_dc.mdl", false))
		{
			bodymodel = "models/player/t_arctic.mdl";
		}
		else if (StrEqual(oldmodel, "models/player/t_guerilla1_dc.mdl", false))
		{
			bodymodel = "models/player/t_guerilla.mdl";
		}
		else if (StrEqual(oldmodel, "models/player/t_leet1_dc.mdl", false))
		{
			bodymodel = "models/player/t_leet.mdl";
		}
		else if (StrEqual(oldmodel, "models/player/t_phoenix1_dc.mdl", false))
		{
			bodymodel = "models/player/t_phoenix.mdl";
		}

		if (IsModelPrecached(bodymodel))
		{
			SetEntityModel(client, bodymodel);
		}
		
		// check if another player is holding it
		for (new i=1; i<=MAX_PLAYERS; i++)
		{
			if (g_HeldEnt[i]==g_HeadEnt[client])
			{
				Command_UnGrab(i, 0);
			}
		}

		if (g_SpurtTimer[client] != INVALID_HANDLE)
		{
			KillTimer(g_SpurtTimer[client]);
			g_SpurtTimer[client] = INVALID_HANDLE;
		}

		if((g_HeadEnt[client]) && (IsValidEntity(g_HeadEnt[client])))
		{
			RemoveEdict(g_HeadEnt[client]);
		}
		
		g_HeadEnt[client] = -1;
		g_HeadLastHolder[client] = -1;

		ResetView(client);
	}
}

public ResetView(any:client)
{
	//if(IsPlayer(client) == false) PrintToServer("[SM][DC] ResetView:FALSE");
	if(IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client) && (GetClientTeam(client) > 1))
	{
		SetClientViewEntity(client,client);
		SetEntPropEnt(client, Prop_Send, "m_hObserverTarget", 0);
		SetEntProp(client, Prop_Send, "m_iObserverMode", 0);
		SetEntProp(client, Prop_Send, "m_bDrawViewmodel", 1);
	}
}

public SetView(any:client, any:entity)
{
	//if(IsPlayer(client) == false) PrintToServer("[SM][DC] SetView:FALSE");
	if(IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client) && (GetClientTeam(client) > 1))
	{
		SetClientViewEntity(client,entity);
		SetEntPropEnt(client, Prop_Send, "m_hObserverTarget", 0);
		SetEntProp(client, Prop_Send, "m_iObserverMode", 1);
		SetEntProp(client, Prop_Send, "m_bDrawViewmodel", 0);
	}
}
