PLASMATURRETMODEL = "models/Combine_turrets/Floor_turret.mdl"
PLASMATURRETPRICE = 350
PLASMATURRETSCANRANGE = 1500
PLASMATURRETMAX = 3
PLASMATURRETMAXHEALTH = 400
_EntPrecacheModel(PLASMATURRETMODEL)
PlasmaTurrets = {}
for i in teams do
	teams[i].PlasmaTurrets = 0
end

function CreatePlasmaTurret(userid)
	PlayerLookTrace(userid, 300)
	local prop = _EntCreate("prop_physics")
	if prop > 0 then
		_EntSetModel(prop, PLASMATURRETMODEL)
		_EntSetPos(prop, vecAdd(_TraceEndPos(), vector3(0,0,45)))
		_EntSetKeyValue(prop, "rendermode", "1")
		_EntSpawn(prop)
		_EntSetName(prop, "unfrozenprop")
		_EntSetMaterial(prop, "gmod/wireframe")
		local n = _PlayerInfo(userid, "team")
		PhysProps[prop] = {}
		PhysProps[prop].Owner = userid
		PhysProps[prop].Team = n
		teams[n].props = teams[n].props+1
		_EntFire(prop, "color", teams[n].color.r.." "..teams[n].color.g.." "..teams[n].color.b, 0)
		PlasmaTurrets[prop] = {}
		PlasmaTurrets[prop].Target = 0
		PlasmaTurrets[prop].LastShot = 0
		PlasmaTurrets[prop].Team = _PlayerInfo(userid, "team")
		PlasmaTurrets[prop].Health = PLASMATURRETMAXHEALTH
		PlasmaTurrets[prop].Owner = userid
		teams[_PlayerInfo(userid, "team")].PlasmaTurrets = teams[_PlayerInfo(userid, "team")].PlasmaTurrets+1
	end
end

function ProcessPlasmaTurretDamaged(ent, attacker, damage)
	if PlasmaTurrets[ent] then
		if PlasmaTurrets[ent].Team ~= _PlayerInfo(attacker, "team") then
			if PlasmaTurrets[ent].Health>0 then
				PlasmaTurrets[ent].Health = PlasmaTurrets[ent].Health-damage
				_GModText_Start( "Default" )
				 _GModText_SetPos( 0.0, 0.0 )
			 	 _GModText_SetColor( 230, 0, 0, 255 )
				 _GModText_SetTime( 0.75, 0.2, 0.2 )
				 _GModText_SetAdditive(true)
				 _GModText_SetEntity(ent)
				 _GModText_SetEntityOffset(vector3(math.random(-25,25),math.random(-25,25),math.random(40,50)))
				 _GModText_SetText( "- "..math.floor(damage))
				_GModText_Send(attacker, attacker+ent+math.random(10000,22000))
				if PlasmaTurrets[ent].Health<0 then
					PlasmaTurrets[ent].Health = 0
					PlasmaTurretDestroyed(ent)
				end
			end
		end
	end
end

function PlasmaTurretDestroyed(prop)
	local enti = _EntCreate("env_explosion")
	if enti > 0 then
		_EntSetKeyValue(enti, "iMagnitude", "75")
		_EntSetPos(enti, GetPTShootPos(prop))
		_EntSpawn(enti)
		_EntFire(enti, "explode", "", 0)
		_EntFire(enti, "kill", "", 0.05)
	end
	local ent = _EntCreate("env_smoketrail")
	if ent > 0 then
		_EntSetPos(ent, GetPTShootPos(prop))
		_EntSpawn(ent)
		_EntFire(ent, "kill", "", 2.0)
	end
	_EntFire(prop, "alpha", "125", 0)
end

function TurretTargetVisible(turret, target)
	if turret <= 0 or target <= 0 then return false end
	_TraceLine(GetPTShootPos(turret), vecNormalize(vecSub(vecAdd(_EntGetPos(target), vector3(0,0,32)), GetPTShootPos(turret))), PLASMATURRETSCANRANGE+250, turret)
	if _TraceHitNonWorld() then
		return _TraceGetEnt() == target or Vehicles[_TraceGetEnt()] ~= nil
	end
	return false
end

_EntPrecacheModel("models/Weapons/w_bugbait.mdl")
function PlasmaTurretTick()
	for i in PlasmaTurrets do
		if _EntGetModel(i) ~= PLASMATURRETMODEL then PlasmaTurrets[i] = nil return end
		if PlasmaTurrets[i].Target > 0 then
			if not _PlayerInfo(PlasmaTurrets[i].Target, "alive") or not IsPlayerOnline(PlasmaTurrets[i].Target) or not IsInRadius(PlasmaTurrets[i].Target, i, PLASMATURRETSCANRANGE) or PlasmaTurrets[i].Health <= 0 or not TurretTargetVisible(i, PlasmaTurrets[i].Target) then
				PlasmaTurrets[i].Target = 0
			elseif _CurTime() > PlasmaTurrets[i].LastShot+3.0 then
				PlasmaTurrets[i].LastShot = _CurTime()
				_EntEmitSound(i, "nox/plasmaturret_fire.wav")
				local ent = _EntCreate("prop_physics")
				if ent > 0 then
					_EntSetPos(ent, GetPTShootPos(i))
					_EntSetModel(ent, "models/Weapons/w_bugbait.mdl")
					local addedvel = vecMul(_EntGetVelocity(PlasmaTurrets[i].Target), 3)
					local vel = vecMul(vecNormalize(vecSub(vecAdd(_EntGetPos(PlasmaTurrets[i].Target), vector3(0,0,20)), GetPTShootPos(i))), vector3(4000,4000,4000))
					vel = vecAdd(addedvel, vel)
					_EntSetAng(ent, vecNormalize(vel))
					_EntSpawn(ent)
					_phys.EnableGravity(ent, false)
					_phys.ApplyForceCenter(ent, vel)
					_EntFire(ent, "kill", "", 10.1)
					local trail = _EntCreate("env_smoketrail")
					if trail > 0 then
						_EntSetPos(trail, _EntGetPos(ent))
						_EntSetKeyValue(trail, "spawnrate", "25")
						_EntSetKeyValue(trail, "lifetime", "1.0")
						_EntSetKeyValue(trail, "startcolor", "0 0 255")
						_EntSetKeyValue(trail, "endcolor", "0 0 255")
						_EntSetKeyValue(trail, "minspeed", "0")
						_EntSetKeyValue(trail, "maxspeed", "0")
						_EntSetKeyValue(trail, "startsize", "6")
						_EntSetKeyValue(trail, "endsize", "9")
						_EntSetKeyValue(trail, "spawnradius", "2")
						_EntSetKeyValue(trail, "firesprite", "sprites/redglow3.spr")
						_EntSetKeyValue(trail, "smokesprite", "sprites/redglow3.spr")
						_EntSpawn(trail)
						_EntSetParent(trail, ent)
						_EntFire(trail, "kill", "", 10.0)
					end
					local glow = _EntCreate("env_sprite")
					if glow > 0 then
						_EntSetKeyValue(glow, "model", "sprites/physcannon_bluecore2b.spr")
						_EntSetKeyValue(glow, "rendermode", "5")
						_EntSetKeyValue(glow, "scale", "1.0")
						_EntSetKeyValue(glow, "spawnflags", "1")
						_EntSetPos(glow, _EntGetPos(ent))
						_EntSpawn(glow)
						_EntFire(glow, "showsprite", "", 0)
						_EntSetParent(glow, ent)
						_EntFire(glow, "kill", "", 10.0)
					end
					PlasmaTimers[ent] = AddTimer(0.05, 200, PlasmaCheckExplode, ent, PlasmaTurrets[i].Team, PlasmaTurrets[i].Owner)
				end
			end
		elseif PlasmaTurrets[i].Health > 0 then
			local ents = _EntitiesFindInSphere(_EntGetPos(i), PLASMATURRETSCANRANGE)
			for x=1, table.getn(ents) do
				if IsPlayer(ents[x]) then
					if _PlayerInfo(ents[x], "alive") and IsPlayerOnline(ents[x]) then
						if _PlayerInfo(ents[x], "team") ~= PlasmaTurrets[i].Team and _PlayerInfo(ents[x], "team") >= TEAM_BLUE then
							if TurretTargetVisible(i, ents[x]) then
								if ents[x] <= _MaxPlayers() then
									if not players[ents[x]].Invisible then
										PlasmaTurrets[i].Target = ents[x]
										_EntEmitSound(i, "npc/turret_floor/active.wav")
									end
								else
									PlasmaTurrets[i].Target = ents[x]
									_EntEmitSound(i, "npc/turret_floor/active.wav")
								end
							end
						end
					end
				end
			end
		end
	end
end
AddTimer(0.25, 0, PlasmaTurretTick)

PlasmaTimers = {}
function PlasmaCheckExplode(prop, team, owner)
	if not _EntExists(prop) then HaltTimer(PlasmaTimers[prop]) return end
	_TraceLine(_EntGetPos(prop), _EntGetForwardVector(prop), 90, prop)
	if _TraceHitNonWorld() then
		if string.lower(_EntGetModel(_TraceGetEnt())) ~= string.lower(PLASMATURRETMODEL) then
			PlasmaExplode(prop, team, owner)
		end
	elseif _TraceHit() then
		PlasmaExplode(prop, team, owner)
	end
end

function PlasmaExplode(prop, team, owner)
	local ents = _EntitiesFindInSphere(_EntGetPos(prop), 150)
	for i=1, table.getn(ents) do
		if _PlayerInfo(owner, "team") ~= team or not IsPlayerOnline(owner) then owner = ents[i] end
		if _phys.HasPhysics(ents[i]) then
			if IsPlayer(ents[i]) then
				if _PlayerInfo(ents[i], "team") ~= team then
					_TraceAttack(ents[i], prop, owner, (150-math.abs(vecLength(vecSub(_EntGetPos(prop),_EntGetPos(ents[i])))))*0.4)
				end
			elseif Vehicles[ents[i]] ~= nil then
				if Vehicles[ents[i]].Team ~= team then
					_TraceAttack(ents[i], prop, owner, (150-math.abs(vecLength(vecSub(_EntGetPos(prop),_EntGetPos(ents[i])))))*0.9)
				end
			else
				_TraceAttack(ents[i], prop, owner, (150-math.abs(vecLength(vecSub(_EntGetPos(prop),_EntGetPos(ents[i])))))*0.5)
			end
		end
	end

	local ent = _EntCreate("env_sprite")
	if ent > 0 then
		_EntSetKeyValue(ent, "model", "sprites/redglow3.spr")
		_EntSetKeyValue(ent, "rendermode", "5")
		_EntSetKeyValue(ent, "scale", "0.5")
		_EntSetKeyValue(ent, "spawnflags", "5")
		_EntSetPos(ent, _EntGetPos(prop))
		_EntSpawn(ent)
		_EntFire(ent, "showsprite", "", 0)
		for i=1, 10 do
			_EntFire(ent, "setscale", tostring(i*0.4), i*0.05)
		end
		_EntFire(ent, "hidesprite", "", 1.25)
		_EntFire(ent, "kill", "", 1.26)
		_EntEmitSound(ent, "nox/plasma_explode.wav")
	end
	_util.ScreenShake(_EntGetPos(prop), math.random(25,55), 180.0, 1.5, 220)
	_EntRemove(prop)
	HaltTimer(PlasmaTimers[prop])
	PlasmaTimers[prop] = nil
end

function GetPTShootPos(ent)
	return vecAdd(_EntGetPos(ent), vecMul(_EntGetUpVector(ent), vector3(55,55,55)))
end
