public Action DrawFullZoneTimer(Handle timer)
{
	int colorarray[][] =  {  { 124, 252, 0, 255 }, { 255, 0, 0, 255 } };
	
	if (!g_bLasers || g_iEditor == -1)
		return Plugin_Continue;
	
	for (int i = 0; i <= 1; i++)
	{
		if (g_iSnapToClient == i)
		{
			float vec[3];
			GetClientAbsOrigin(g_iEditor, vec);
			DrawFullZone(vec, g_fStartOrigins[i], colorarray[i], 0.1);
			continue;
		}
		DrawFullZone(g_fEndOrigins[i], g_fStartOrigins[i], colorarray[i], 0.2);
	}
	return Plugin_Continue;
}

public Action DrawZoneTimer(Handle timer)
{
	if (!g_bLasers || !g_bActive)
		return Plugin_Continue;
	
	int colorarray[][] =  {  { 124, 252, 0, 255 }, { 255, 0, 0, 255 } };
	
	if (g_iEditor != -1)
		return Plugin_Continue;
		
	float pos[3], eye[3];
	
	int[] clients = new int[MaxClients];
	int nClients = 0;

	for (int i = 0; i <= 1; i++)
	{
		for (int j = 1; j <= MaxClients; j++)
		{
			if (isValidClient(j))
			{
				//https://github.com/InfluxTimer/sm-timer/blob/master/addons/sourcemod/scripting/influx_zones_beams.sp
				GetClientEyePosition(j, eye);
				
				GetMiddleOfABox(g_fEndOrigins[i], g_fStartOrigins[i], pos);
				
				if (GetVectorDistance(eye, pos, true) < MAX_DIST_SQ)
				{
					clients[nClients++] = j;
				}
				else
				{
					TR_TraceRayFilter(eye, pos, CONTENTS_SOLID, RayType_EndPoint, TraceFilter_WorldOnly);
					
					if (!TR_DidHit())
					{
						clients[nClients++] = j;
					}
				}
			}
		}
		DrawZone(clients, nClients, g_fEndOrigins[i], g_fStartOrigins[i], colorarray[i], 1.0);
	}
	return Plugin_Continue;
}

public bool TraceFilter_WorldOnly( int ent, int mask )
{
    return ( ent == 0 );
}

public Action HudLoop(Handle timer)
{
	if (g_iMapID != -1 && g_bActive)
	{
		for (int i = 1; i <= MaxClients; i++)
		{
			if (isValidClient(i))
			{
				UpdateHUD(i);
			}
		}
		return Plugin_Continue;
	}
	return Plugin_Continue;
}

public void UpdateHUD(int client)
{
	int target = client;
	if (IsClientObserver(client))
	{
		int mode = GetEntProp(client, Prop_Send, "m_iObserverMode");
		if (mode == 4 || mode == 5)
		{
			target = GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
			if (!isValidClient(target))
				return;
		}
		else
			return;
	}
	
	if (g_iActivity[target] == -1)
	{
		return;
	}
	
	char HintTextBuffer[256];
	
	if (client != target)
		Format(HintTextBuffer, sizeof(HintTextBuffer), "Player: %N\n \n", target);
	
	if (g_iActivity[target] == 1)
		Format(HintTextBuffer, sizeof(HintTextBuffer), "%sIn Start Zone\n \n", HintTextBuffer);
	
	if (g_iActivity[target] == 0)
	{
		char cTime[16];
		float fTime;
		fTime = GetEngineTime() - g_fStartTime[target];
		TimerFormat(fTime, cTime, sizeof(cTime), true, false);
		Format(HintTextBuffer, sizeof(HintTextBuffer), "%sTime: %s\n \n", HintTextBuffer, cTime);
	}
	
	Format(HintTextBuffer, sizeof(HintTextBuffer), "%sSpeed: %i u/s", HintTextBuffer, Get2VecVelocity(target));
	
	PrintHintText(client, HintTextBuffer);
}

public Action SideHudLoop(Handle timer)
{
	if (g_iMapID != -1 && g_bActive)
	{
		for (int i = 1; i <= MaxClients; i++)
		{
			if (isValidClient(i))
			{
				UpdateSideHUD(i);
			}
		}
		return Plugin_Continue;
	}
	return Plugin_Continue;
}

public void UpdateSideHUD(int client)
{
	int target = client;
	if (IsClientObserver(client))
	{
		int mode = GetEntProp(client, Prop_Send, "m_iObserverMode");
		if (mode == 4 || mode == 5)
		{
			target = GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
			if (!isValidClient(target))
				return;
		}
		else
			return;
	}
	
	if (g_iActivity[target] == -1)
	{
		return;
	}
	
	char KeyHintBuffer[254];
	char cTimeLeft[16];
	GetTimerTimeLeft(cTimeLeft, sizeof(cTimeLeft));
	
	Format(KeyHintBuffer, sizeof(KeyHintBuffer), "Timeleft: %s\n \n", cTimeLeft);
	
	if (g_fMapTime[target] <= 0.0)
		Format(KeyHintBuffer, sizeof(KeyHintBuffer), "%sPR: None\n", KeyHintBuffer);
	
	else
	{
		char cTime[16], cTimeToWR[16];
		float fTimeToWR;
		fTimeToWR = g_fMapTime[target] - g_fWrTime;
		if (fTimeToWR == 0)
			Format(cTimeToWR, sizeof(cTimeToWR), "WR");
		else
			TimerFormat(fTimeToWR, cTimeToWR, sizeof(cTimeToWR), true, true);
		
		TimerFormat(g_fMapTime[target], cTime, sizeof(cTime), true, false);
		Format(KeyHintBuffer, sizeof(KeyHintBuffer), "%sPR: %s (%s)\n", KeyHintBuffer, cTime, cTimeToWR);
	}
	
	if (g_fWrTime <= 0.0)
		Format(KeyHintBuffer, sizeof(KeyHintBuffer), "%sWR: None\n \n", KeyHintBuffer);
	
	else
	{
		char cWR[16];
		TimerFormat(g_fWrTime, cWR, sizeof(cWR), true, false);
		Format(KeyHintBuffer, sizeof(KeyHintBuffer), "%sWR: %s (%s)\n \n", KeyHintBuffer, cWR, g_sWrHolder);
	}
	
	Format(KeyHintBuffer, sizeof(KeyHintBuffer), "%sSpectators: %i", KeyHintBuffer, GetSpecCount(target));
	
	PrintKeyHintText(client, KeyHintBuffer);
}

/*public Action Timer_CreateTrigger(Handle timer, int zonetype)
{
	CreateTrigger(zonetype);
}*/