-- NoXious 2D
-- By JetBoom

FLAGAUTORETURN = false


_ServerCommand("gm_sv_teamplay 1\ngm_sv_setrules\n")

Projectiles = {}
Walls = {}
players = {}
for i=1, _MaxPlayers() do
	players[i] = {}
	players[i].health = 100
	players[i].x = 50
	players[i].y = 50
	players[i].dir = 0
	players[i].lastattack = 0
	players[i].data = ""
end

teams = {}
teams[TEAM_BLUE] = {name="Team Tubgirl", GFX="lm/lm2", color={r=0, g=100, b=255}, flagstart={x=10, y=50}, flag={x=10, y=50}, flagcarrier=0}
teams[TEAM_RED] = {name="Team Goatse", GFX="lm/lm", color={r=255, g=50, b=0}, flagstart={x=95, y=50}, flag={x=95, y=50}, flagcarrier=0}

for i in teams do
	_TeamSetName(i, teams[i].name)
end

-- ================================= --

function GiveDefaultItems(userid)
end

lasttick = 0
function gamerulesThink()
	if _CurTime() >= lasttick+0.2 then
		DoProjectiles()
		lasttick = _CurTime()
	end
end

function CreateResFile()
	_file.Write("maps/".._GetCurrentMap()..".res", [["resources"
{
"materials/lm/lm.vtf" "file"
"materials/lm/lm.vmt" "file"
"materials/lm/lm2.vtf" "file"
"materials/lm/lm2.vmt" "file"
"materials/noxctf/yinyang.vmt" "file"
"materials/noxctf/yinyang.vtf" "file"
"sound/speach/obeyyourthirst2.wav" "file"
"sound/speach/obeyyourthirst.wav" "file"
"sound/speach/obeyyourthirst3.wav" "file"
"sound/stfu.wav" "file"
"sound/banned.wav" "file"
"sound/lm/lm.wav" "file"
}	
]])
end

START = false
function gamerulesStartMap ()
	if START then return end
	START = true
	PlayerFreezeAll(false)
	CreateResFile()
end

UP = 0
RIGHT = 1
DOWN = 2
LEFT = 3

function PlayerNear(userid, dist, x, y)
	return math.abs(players[userid].x - x) <= dist and math.abs(players[userid].y - y) <= dist
end

-- Keeps the mouse on the screen.
function Cap(number)
	if number < 0.0 then number = 0.0 elseif number > 100.0 then number = 100.0 end
	return number
end

function eventKeyPressed(userid, in_key)
	if _PlayerInfo(userid, "alive") then
		if in_key == IN_ATTACK then
			if _CurTime() > players[userid].lastattack+1.0 then
				FireWeapon(userid)
				players[userid].lastattack = _CurTime()
				return
			end
		end
		if in_key == IN_FORWARD then
			local desty = Cap(players[userid].y - 2.0)
			if OpenSpace(players[userid].x, desty) then
				players[userid].y = desty
			end
			players[userid].dir = UP
		elseif in_key == IN_BACK then
			local desty = Cap(players[userid].y + 2.0)
			if OpenSpace(players[userid].x, desty) then
				players[userid].y = desty
			end
			players[userid].dir = DOWN
		elseif in_key == IN_MOVELEFT then
			local destx = Cap(players[userid].x - 2.0)
			if OpenSpace(destx, players[userid].y) then
				players[userid].x = destx
			end
			players[userid].dir = LEFT
		elseif in_key == IN_MOVERIGHT then
			local destx = Cap(players[userid].x + 2.0)
			if OpenSpace(destx, players[userid].y) then
				players[userid].x = destx
			end
			players[userid].dir = RIGHT
		end
		UpdatePlayer(userid)
		for i in teams do
			if teams[i].flagcarrier == userid then
				if PlayerNear(userid, 2, teams[_PlayerInfo(userid,"team")].flagstart.x, teams[_PlayerInfo(userid,"team")].flagstart.y) then
					if teams[_PlayerInfo(userid,"team")].flagcarrier <= 0 then
						teams[i].flagcarrier = 0
						teams[i].flag.x = teams[i].flagstart.x
						teams[i].flag.y = teams[i].flagstart.y
						_PrintMessageAll(4, _PlayerInfo(userid,"name").." captured the "..teams[i].name.." flag!!")
						_PlaySound("weapons/physcannon/energy_disintegrate4.wav")
						DrawFlag(i)
						_TeamAddScore(_PlayerInfo(userid, "team"), 1)
						_PlayerAddScore(userid, 10)
					end
				else
					teams[i].flag.x = players[userid].x
					teams[i].flag.y = players[userid].y
					DrawFlag(i)
				end
			elseif teams[i].flagcarrier <= 0 then
				if PlayerNear(userid, 2, teams[i].flag.x, teams[i].flag.y) then
					if _PlayerInfo(userid, "team") ~= i then
						_PrintMessageAll(4, _PlayerInfo(userid, "name").." took the "..teams[i].name.." flag.")
						_PlaySound("npc/roller/mine/rmine_tossed1.wav")
						teams[i].flagcarrier = userid
						DrawFlag(i)
					else
						if teams[i].flag.x ~= teams[i].flagstart.x or teams[i].flag.y ~= teams[i].flagstart.y then
							teams[i].flagcarrier = 0
							teams[i].flag.x = teams[i].flagstart.x
							teams[i].flag.y = teams[i].flagstart.y
							_PrintMessageAll(4, _PlayerInfo(userid, "name").." returned the "..teams[i].name.." flag.")
							_PlaySound("weapons/physcannon/energy_bounce1.wav")
							teams[i].flagcarrier = 0
							DrawFlag(i)
						end
					end
				end
			end
		end
	end
end

function DrawFlag(i)
	_GModRect_Start("noxctf/yinyang")
	 _GModRect_SetPos((teams[i].flag.x-0.018)/100, (teams[i].flag.y-0.018)/100, 0.036, 0.036)
	 _GModRect_SetColor(teams[i].color.r, teams[i].color.g, teams[i].color.b, 255 )
	 _GModRect_SetTime(9999, 0, 0)
	_GModRect_Send(0, 750+i)
end

function DoProjectiles()
	for i in Projectiles do
		if Projectiles[i].x > 100.0 or Projectiles[i].x < 0.0 or Projectiles[i].y > 100.0 or Projectiles[i].y < 0.0 then
			ProjectileExplode(i)
		else
			if Projectiles[i].dir == UP then
				Projectiles[i].y = Projectiles[i].y - 4
			elseif Projectiles[i].dir == RIGHT then
				Projectiles[i].x = Projectiles[i].x + 4
			elseif Projectiles[i].dir == DOWN then
				Projectiles[i].y = Projectiles[i].y + 4
			else
				Projectiles[i].x = Projectiles[i].x - 4
			end
			--_GModRect_Start("sprites/autoaim_1b")
			local color = teams[_PlayerInfo(Projectiles[i].owner, "team")].color
			_GModRect_Start("gmod/white")
			 _GModRect_SetPos((Projectiles[i].x-0.009)/100, (Projectiles[i].y-0.009)/100, 0.018, 0.018)
			 _GModRect_SetColor(color.r, color.g, color.b, 255 )
			 _GModRect_SetTime(9999, 0, 0)
			_GModRect_Send(0, 100+i)
			for x=1, _MaxPlayers() do
				if PlayerNear(x, 2.0, Projectiles[i].x, Projectiles[i].y) and IsPlayerOnline(x) then
					if _PlayerInfo(x, "team") ~= _PlayerInfo(Projectiles[i].owner,"team") and _PlayerInfo(x, "alive") then
						ProjectileExplode(i)
						return
					end
				end
			end
			for x in Walls do
				if Projectiles[i].x >= Walls[x].Start.x and Projectiles[i].y >= Walls[x].Start.y and Projectiles[i].x <= Walls[x].End.x and Projectiles[i].y <= Walls[x].End.y then
					ProjectileExplode(i)
				end
			end
		end
	end
end

function eventPlayerActive(name, userid, steamid)
	_GModRect_Start("gmod/white")
	 _GModRect_SetPos(0.0, 0.0, 1.0, 1.0)
	 _GModRect_SetColor(0, 0, 0, 240)
	 _GModRect_SetTime(9999, 0.5, 0.5)
	_GModRect_Send(userid, 0)
	for i=1, _MaxPlayers() do
		if IsPlayerOnline(i) then
			UpdatePlayer(userid)
		end
	end
	for i in Walls do
		_GModRect_Start("gmod/white")
		 _GModRect_SetPos(Walls[i].Start.x/100, Walls[i].Start.y/100, (Walls[i].End.x-Walls[i].Start.x)/100, (Walls[i].End.y-Walls[i].Start.y)/100)
		 _GModRect_SetColor(255, 255, 255, 240)
		 _GModRect_SetTime(9999, 0.5, 0.5)
		_GModRect_Send(userid, 2000+i)
	end
	for i in teams do
		DrawFlag(i)
	end
end

function AddWall(nStartx, nStarty, nEndx, nEndy)
	local i = table.getn(Walls)+1
	Walls[i] = {Start={x=nStartx, y=nStarty}, End={x=nEndx, y=nEndy}}
	_GModRect_Start("gmod/white")
	 _GModRect_SetPos(Walls[i].Start.x/100, Walls[i].Start.y/100, (Walls[i].End.x-Walls[i].Start.x)/100, (Walls[i].End.y-Walls[i].Start.y)/100)
	 _GModRect_SetColor(255, 255, 255, 240)
	 _GModRect_SetTime(9999, 0.5, 0.5)
	_GModRect_Send(0, 2000+i)
end

function OpenSpace(x, y)
	for i in Walls do
		if x >= Walls[i].Start.x and y >= Walls[i].Start.y and x <= Walls[i].End.x and y <= Walls[i].End.y then
			return false
		end
	end
	return true
end

function eventPlayerKilled(killed, attacker, weapon)
	_PlayerAddDeath(killed, 1)
	if IsPlayer(attacker) then
		_PlayerAddScore(attacker, 1)
	end
	_GModRect_Hide(0, killed, 0.5)
	_GModText_Hide(0, killed, 0.5)
	_PlaySound("ambient/machines/thumper_hit.wav")
	_PlayerLockInPlace(killed, false)
	for i in teams do
		if teams[i].flagcarrier == killed then
			teams[i].flagcarrier = 0
			if FLAGAUTORETURN then
				teams[i].flag.x = teams[i].flagstart.x
				teams[i].flag.y = teams[i].flagstart.y
			end
			_PrintMessageAll(4, _PlayerInfo(killed,"name").." dropped the "..teams[i].name.." flag.")
			break
		end
	end
end

function eventPlayerSpawn(userid)
	_EntSetPos(userid, vector3(math.random(0,2000), math.random(0, 2000), math.random(0,2000)))
	local i = _PlayerInfo(userid,"team")
	players[userid].x = teams[i].flagstart.x+math.random(-4, 4)
	players[userid].y = teams[i].flagstart.y+math.random(-4, 4)
	UpdatePlayer(userid)
	_PlayerLockInPlace(userid, true)
end

function ProjectileExplode(i)
	for x=1, _MaxPlayers() do
		if PlayerNear(x, 3, Projectiles[i].x, Projectiles[i].y) and IsPlayerOnline(x) then
			if _PlayerInfo(x, "team") ~= _PlayerInfo(Projectiles[i].owner,"team") then
				_PlaySound("physics/flesh/flesh_impact_bullet"..math.random(1,5)..".wav")
				_TraceAttack(x, Projectiles[i].owner, Projectiles[i].owner, math.random(40,60))
			end
		end
	end
	_GModRect_Hide(0, 100+i, 0.5)
	Projectiles[i] = nil
end

function FireWeapon(userid)
	_PlaySound("weapons/mortar/mortar_fire1.wav")
	local i = table.getn(Projectiles)+1
	Projectiles[i] = {}
	Projectiles[i].dir = players[userid].dir
	if Projectiles[i].dir == UP then
		Projectiles[i].x = players[userid].x
		Projectiles[i].y = players[userid].y-0.5
	elseif Projectiles[i].dir == RIGHT then
		Projectiles[i].x = players[userid].x+0.5
		Projectiles[i].y = players[userid].y
	elseif Projectiles[i].dir == DOWN then
		Projectiles[i].x = players[userid].x
		Projectiles[i].y = players[userid].y+0.5
	else
		Projectiles[i].x = players[userid].x-0.5
		Projectiles[i].y = players[userid].y
	end
	Projectiles[i].owner = userid
end

function onShowTeam(userid)
	if _PlayerInfo(userid, "team") == TEAM_RED then
	_PlayerChangeTeam(userid, TEAM_BLUE)
	else _PlayerChangeTeam(userid, TEAM_RED) end
	_PlayerKill(userid)
end

function PickDefaultSpawnTeam(userid)
	if _TeamNumPlayers(TEAM_BLUE) > _TeamNumPlayers(TEAM_RED) then
		_PlayerChangeTeam(userid, TEAM_RED)
	else
		_PlayerChangeTeam(userid, TEAM_BLUE)
	end
	return true
end

function UpdatePlayer(userid)
	_GModRect_Start(teams[_PlayerInfo(userid,"team")].GFX)
	 _GModRect_SetPos(players[userid].x/100-0.0125, players[userid].y/100-0.0125, 0.025, 0.025)
	 _GModRect_SetColor(255, 255, 255, 225)
	 _GModRect_SetTime(9999, 0, 0)
	_GModRect_Send(0, userid)
	_GModText_Start("BudgetLabel")
	 _GModText_SetPos(players[userid].x/100-0.015, players[userid].y/100-0.03)
	 _GModText_SetColor( teams[_PlayerInfo(userid,"team")].color.r, teams[_PlayerInfo(userid,"team")].color.g, teams[_PlayerInfo(userid,"team")].color.b, 255 )
	 _GModText_SetTime( 9999, 0, 0 )
	 _GModText_AllowOffscreen( true )
	 _GModText_SetText( "["..userid.."] ".._PlayerInfo(userid, "name"))
	_GModText_Send(0, userid)
end

function eventPlayerDisconnect(name, userid, address, steamid, reason)
	if IsPlayerOnline(userid) then
		NDB.SaveInfo()
		players[userid].health = 100
		players[userid].x = 0.5
		players[userid].y = 0.5
		players[userid].data = ""
		_GModRect_Hide(0, userid, 0.5)
		_GModText_Hide(0, userid, 0.5)
		_PlaySound("ambient/machines/thumper_hit.wav")
	end
end

gamerulesStartMap()

function SampleField()
	Walls = nil
	Walls = {}

	AddWall(45, 20, 55, 80)

	AddWall(20, 40, 25, 60)

	AddWall(80, 40, 85, 60)

	--[[
	AddWall(0, 35, 30, 40)
	AddWall(0, 65, 30, 70)
	AddWall(25, 40, 30, 45)

	AddWall(60, 35, 100, 40)
	AddWall(60, 65, 100, 70)
	AddWall(75, 60, 80, 45)]]
end

SampleField()

for i=1, _MaxPlayers() do
	if IsPlayerOnline(i) then
		eventPlayerActive(_PlayerInfo(i, "name"), i, _PlayerInfo(i, "networkid"))
		onShowTeam(i)
	end
end
