VehicleTypes["Helicopter"] = {              -- The global reference to this type.
Name = "Attack Helicopter",                        -- The display name on vehicle menu.
Model = "models/combine_helicopter.mdl",    -- Model. If none, the vehicle will not create.
Description = "Helicopter with homing missiles and a bomber position.", -- Shown on the vehicle menu.
Stock = 1,                                  -- How many each team can have at one time.
EntityType = "prop_physics",                -- _EntCreate( ) type. Default is "prop_physics", if not specified.
MaxHealth = 150,                            -- Max HP before destroyed.
DamageMultiply = 0.4,                      -- Damage taken is multiplyed by this amount.
PassengerSlots = 1,                         -- Amount of passengers able to ride in this vehicle.
DriverCamDistance = 256,                    -- Camera distance from vehicle for the driver.
PassengerCamDistance = 0,                 -- Camera distance from vehicle for passengers.
CreationOffset = vector3(0,0,150),          -- Offset from vehicle pads.
ExitOffset = vector3(0,50,35),              -- Offset from vehicle that people exit at.

HUD = function(vehicle)
	local SendTo = {}
	if Vehicles[vehicle].Driver > 0 then
		SendTo[table.getn(SendTo)+1] = Vehicles[vehicle].Driver
	end
	for i=1, table.getn(Vehicles[vehicle].Passenger) do
		if Vehicles[vehicle].Passenger[i] > 0 then
			SendTo[table.getn(SendTo)+1] = Vehicles[vehicle].Passenger[i]
		end
	end

	local ms = "P:* BM:_"
	if Vehicles[vehicle].Passenger[1] > 0 then
		ms = string.gsub(ms, "BM:_", "BM:*")
	end
	for i=1, table.getn(SendTo) do
		_GModRect_Start("gmod/white")
		 _GModRect_SetPos(0.42, 0.85, 0.18, 0.1)
		 _GModRect_SetColor( 0, 0, 0, 100 )
		 _GModRect_SetTime( 9999, 0, 0 )
		_GModRect_Send( SendTo[i], 10000 )
		_GModText_Start( "Default" )
		 _GModText_SetPos( -1, 0.88 )
		 _GModText_SetColor( 255, 0, 0, 255 )
		 _GModText_SetTime( 9999, 0.1, 0.1 )
		 _GModText_SetText( "HP: "..math.ceil(Vehicles[vehicle].Health).."/"..VehicleTypes[Vehicles[vehicle].Type].MaxHealth )
		_GModText_Send( SendTo[i], 10001 )
		_GModText_Start( "Default" )
		 _GModText_SetPos( -1, 0.92 )
		 _GModText_SetColor( 255, 255, 255, 255 )
		 _GModText_SetTime( 9999, 0, 0 )
		 _GModText_SetText( ms )
		_GModText_Send( SendTo[i], 10002 )
	end
end,

HideHUD = function(userid)
	_GModRect_Hide(userid, 10000, 0.2)
	_GModText_Hide(userid, 10001, 0.2)
	_GModText_Hide(userid, 10002, 0.2)
end,

onAttack = function(vehicle)
	if _CurTime() > CHOPPERLASTATTACK[vehicle]+3.5 then
		if HelicopterSprites(vehicle) then
			CHOPPERLASTATTACK[vehicle] = _CurTime()
		end
	end
end,

onRemoved = function(vehicle)
	if CHOPPERSOUNDLOOP[vehicle] then HaltTimer(CHOPPERSOUNDLOOP[vehicle]) end
	CHOPPERLASTATTACK[vehicle] = nil
	CHOPPERLASTBOMB[vehicle] = nil
	CHOPPERSOUNDLOOP[vehicle] = nil
	CHOPPERDUPLICATE[vehicle] = nil
end,

onDestroyed = function(vehicle)
	if CHOPPERSOUNDLOOP[vehicle] then HaltTimer(CHOPPERSOUNDLOOP[vehicle]) end
	CHOPPERLASTATTACK[vehicle] = nil
	CHOPPERLASTBOMB[vehicle] = nil
	CHOPPERSOUNDLOOP[vehicle] = nil
	CHOPPERDUPLICATE[vehicle] = nil
	_EntEmitSoundEx(vehicle, "ambient/explosions/explode_6.wav", 1.1, 1.0)
	_EntEmitSoundEx(vehicle, "ambient/explosions/explode_5.wav", 1.1, 0.8)
	for i=1, 10 do
		local ent = _EntCreate("env_explosion")
		if ent > 0 then
			_EntSetKeyValue(ent, "spawnflags", "17")
			_EntSetPos(ent, _EntGetPos(vehicle))
			_EntSpawn(ent)
			_EntSetParent(ent, vehicle)
			_EntFire(ent, "explode", "", i*0.25)
			_EntFire(ent, "kill", "", (i*0.25)+0.1)
		end
	end
	_phys.EnableGravity(vehicle, true)
	local ent2 = _EntCreate("env_ar2explosion")
	if ent2 > 0 then
		_EntSetPos(ent2, _EntGetPos(vehicle))
		_EntSpawn(ent2)
		_EntSetParent(ent2, vehicle)
		_EntFire(ent2, "explode", "", 2.45)
		_EntFire(ent2, "kill", "", 2.55)
		local pos = _EntGetPos(vehicle)
		AddTimer(2.4, 1, LuaExplosionEntity, vehicle, 250, 400, 255)
	end
	AddTimer(2.45, 1, _EntEmitSoundEx, vehicle, "npc/combine_gunship/gunship_explode2.wav", 1.5, 1.0)
	_EntFire(vehicle, "break", "", 2.5)
	_EntFire(vehicle, "kill", "", 2.6)
	_phys.ApplyTorqueCenter(vehicle, vector3(-15000, -15000, -500000))
end,

onDamaged = function(vehicle, attacker, damage)
	if Vehicles[vehicle].Health < VehicleTypes[Vehicles[vehicle].Type].MaxHealth*0.5 and damage > 20 then
		local finalpos = vecAdd(_EntGetPos(vehicle), vector3(math.random(-50, 50), math.random(-50, 50), math.random(15, 50)))
		local ent = _EntCreate("env_fire_trail")
		if ent > 0 then
			_EntSetPos(ent, finalpos)
			_EntSpawn(ent)
			_EntSetParent(ent, vehicle)
			_EntFire(ent, "kill", "", math.random(3, 5))
		end
		local ent2 = _EntCreate("env_explosion")
		if ent2 > 0 then
			_EntSetKeyValue(ent2, "spawnflags", "17")
			_EntSetPos(ent2, finalpos)
			_EntSpawn(ent2)
			_EntFire(ent2, "explode", "", 0)
			_EntFire(ent2, "kill", "", 0.1)
		end
	end
end,

onPassengerAttack = function(vehicle, passenger)
	if _CurTime() > CHOPPERLASTBOMB[vehicle]+3.0 then
	local userid = Vehicles[vehicle].Passenger[passenger]
	if not userid then return end
	if userid <= 0 then return end
	local sunburst = _EntCreate("physics_prop")
	local trail = _EntCreate( "env_fire_trail" )
	_EntPrecacheModel( "models/props/cs_italy/orange.mdl" )			
	if sunburst > 0 then
		_EntSetPos(sunburst, _EntGetPos(vehicle))
		_EntSetModel(sunburst, "models/props/cs_italy/orange.mdl")
		_phys.SetMass(sunburst, 10)
		_EntSetPos(trail, _EntGetPos(sunburst))
		_EntSpawn(sunburst)
		_EntFire(sunburst, "sethealth", "99999", 0)
		_EntSetOwner(sunburst, vehicle)
		_EntitySetPhysicsAttacker(sunburst, userid)
		_EntSpawn(trail)
		local fireforce = vecMul(_PlayerGetShootAng(userid), vector3(50000, 50000, 50000))
        _phys.ApplyForceCenter(sunburst, fireforce)
		_EntSetName(sunburst, "sunburst")
		_EntSetParent(trail, sunburst)
		_EntFire(trail, "kill", "", 2.25)
		local glow = _EntCreate("env_sprite")
		if glow > 0 then
			_EntSetKeyValue(glow, "model", "sprites/animglow01.spr")
			_EntSetKeyValue(glow, "rendermode", "5")
			_EntSetKeyValue(glow, "scale", "2.5")
			_EntSetKeyValue(glow, "spawnflags", "1")
			_EntSetPos(glow, _EntGetPos(sunburst))
			_EntSpawn(glow)
			_EntFire(glow, "showsprite", "", 0)
			_EntSetParent(glow, sunburst)
			AddTimer(2, 1, SunBurstExplode, sunburst, glow, userid)
			CHOPPERLASTBOMB[vehicle] = _CurTime()
		end
	end
	end
end,

onCreated = function(vehicle)
	CHOPPERLASTATTACK[vehicle] = _CurTime()
	CHOPPERLASTBOMB[vehicle] = _CurTime()
	_phys.EnableGravity(vehicle, false)
end,

onDriverEnter = function(vehicle)
	_phys.EnableGravity(vehicle, false)
	local ent = _EntCreate("prop_dynamic_override")
	if ent > 0 then
		_EntSetPos(ent, _EntGetPos(vehicle))
		_EntSetAngAngle(ent, _EntGetAngAngle(vehicle))
		_EntSetModel(ent, VehicleTypes["Helicopter"].Model)
		_EntSetKeyValue(ent, "DefaultAnim", "idle")
		_EntSpawn(ent)
		_EntSetParent(ent, vehicle)
		_EntFire(ent, "color", TeamColor(Vehicles[vehicle].Team), 0)
		_EntFire(vehicle, "alpha", "0", 0)
		CHOPPERDUPLICATE[vehicle] = ent
		_EntEmitSound(vehicle, "nox/helirotor.wav")
		CHOPPERSOUNDLOOP[vehicle] = AddTimer(5.86, 0, _EntEmitSound, vehicle, "nox/helirotor.wav")
	end
end,

onPassengerEnter = function(vehicle, userid)
	local ent = _EntCreate("prop_dynamic_override")
	if ent > 0 then
		_EntSetPos(ent, vecAdd(_EntGetPos(vehicle), vector3(0,0,-64)))
		_EntSetModel(ent, "models/weapons/w_missile_closed.mdl")
		_EntSetKeyValue(ent, "rendermode", "5")
		_EntSpawn(ent)
		_EntSetParent(ent, vehicle)
		_EntFire(ent, "alpha", "0", 0)
		_PlayerSpectatorTarget(userid, ent)
	end
end,

onDriverExit = function(vehicle)
	_phys.EnableGravity(vehicle, true)
	if CHOPPERDUPLICATE[vehicle] ~= nil then
		_EntFire(vehicle, "alpha", "255", 0)
		_EntRemove(CHOPPERDUPLICATE[vehicle])
		CHOPPERDUPLICATE[vehicle] = nil
		HaltTimer(CHOPPERSOUNDLOOP[vehicle])
	end
end,

onThink = function(vehicle)
	local owner = Vehicles[vehicle].Owner
	local driver = Vehicles[vehicle].Driver
	if driver > 0 then
		_EntitySetPhysicsAttacker(vehicle, driver)
		_EntitySetPhysicsAttacker(vehicle, driver)
		if _EntGetWaterLevel(driver) ~= nil then
			if _EntGetWaterLevel(driver) > 1 then
				if Vehicles[vehicle].Health > 0 then
					VehicleDestroyed(owner, vehicle)
				end
			end
		end
		local Ang = _EntGetAngAngle(vehicle)
		local vVec = vector3(0,0,0)
		if Ang.z > 0 and Ang.z < 180 then
			vVec = vecMul(_EntGetForwardVector(vehicle),vector3(-425*TICKRATE,-425*TICKRATE,-425*TICKRATE))
			_phys.ApplyTorqueCenter(vehicle, vVec)
		elseif Ang.z > 180 and Ang.z <= 360 then
			vVec = vecMul(_EntGetForwardVector(vehicle),vector3(425*TICKRATE,425*TICKRATE,425*TICKRATE))
			_phys.ApplyTorqueCenter(vehicle, vVec)
		end
		if Ang.x > -80 and Ang.x < 0 then
			vVec = vecMul(_EntGetRightVector(vehicle),vector3(-425*TICKRATE,-425*TICKRATE,-425*TICKRATE))
			_phys.ApplyTorqueCenter(vehicle, vVec)
		elseif Ang.x > 0 and Ang.x < 80 then
			vVec = vecMul(_EntGetRightVector(vehicle),vector3(425*TICKRATE,425*TICKRATE,425*TICKRATE))
			_phys.ApplyTorqueCenter(vehicle, vVec)
		end
	elseif owner > 0 then
		_EntitySetPhysicsAttacker(vehicle, Vehicles[vehicle].Owner)
	end
end,

onForward = function(vehicle)
	_phys.ApplyForceCenter(vehicle, vecMul(_EntGetAng(vehicle), vector3(5000*TICKRATE,5000*TICKRATE,0)))
end,

onBackward = function(vehicle)
	_phys.ApplyForceCenter(vehicle, vecMul(_EntGetAng(vehicle), vector3(-5000*TICKRATE,-5000*TICKRATE,0)))
end,

onLeft = function(vehicle)
	_phys.ApplyTorqueCenter(vehicle, vector3(0, 0, 5000*TICKRATE))
end,

onRight = function(vehicle)
	_phys.ApplyTorqueCenter(vehicle, vector3(0, 0, -5000*TICKRATE))
end,

onJump = function(vehicle)
	_phys.ApplyForceCenter(vehicle, vecMul(_EntGetUpVector(vehicle), vector3(0,0,4000*TICKRATE)))
end,

onDuck = function(vehicle)
	_phys.ApplyForceCenter(vehicle, vecMul(_EntGetUpVector(vehicle), vector3(0,0,-4000*TICKRATE)))
end
}

_EntPrecacheModel("models/Combine_Helicopter/helicopter_bomb01.mdl")
CHOPPERLASTATTACK = {}
CHOPPERLASTBOMB = {}
CHOPPERSOUNDLOOP = {}
CHOPPERDUPLICATE = {}
CHOPPERBULLETDAMAGE = 10

function ChopperAttack(vehicle)
	if Vehicles[vehicle] == nil or _EntGetType(vehicle) == "n/a" then return end
	_TraceLine(_EntGetPos(vehicle), _PlayerGetShootAng(Vehicles[vehicle].Driver) or _EntGetForwardVector(vehicle), 2000, vehicle)
	if _TraceHitNonWorld() then
		if IsPlayer(_TraceGetEnt()) then
			_EntEmitSound(_TraceGetEnt(), "physics/flesh/flesh_impact_bullet"..math.random(1,5)..".wav")
			_MakeDecal(math.random(20,24))
		else
			local ent = _EntCreate("info_target")
			if ent > 0 then
				_EntSetPos(ent, _TraceEndPos())
				_EntSpawn(ent)
				_EntEmitSound(ent, "physics/concrete/concrete_impact_bullet"..math.random(1,4)..".wav")
				_EntFire(ent, "kill", "", 0.1)
			end
			_MakeDecal(math.random(0,4))
		end
		_TraceAttack(_TraceGetEnt(), Vehicles[vehicle].Driver or Vehicles[vehicle].Owner, Vehicles[vehicle].Driver or Vehicles[vehicle].Owner, CHOPPERBULLETDAMAGE)
	elseif _TraceHit() then
		local ent = _EntCreate("info_target")
		if ent > 0 then
			_EntSetPos(ent, _TraceEndPos())
			_EntSpawn(ent)
			_EntEmitSound(ent, "physics/concrete/concrete_impact_bullet"..math.random(1,4)..".wav")
			_EntFire(ent, "kill", "", 0.1)
		end
		_MakeDecal(math.random(0,4))
	end
	_EffectInit()
	 _EffectSetEnt(Vehicles[vehicle].Driver or 255)
	 _EffectSetOrigin(_EntGetPos(vehicle))
	 _EffectSetStart(_TraceEndPos())
	 _EffectSetScale(40)
	 _EffectSetMagnitude(0.5)
	_EffectDispatch("FadingLineTeamSolid")
end

function HelicopterSprites(vehicle)
	local userid = Vehicles[vehicle].Driver or 0
	if userid <= 0 then return false end
	if not _PlayerInfo(userid, "alive") or not _PlayerInfo(userid, "connected") then return false end
	if _PlayerGetShootAng(userid) == nil then return false end
	_TraceLine(_EntGetPos(vehicle), _PlayerGetShootAng(userid), 3000, vehicle)
	for o=1, 2 do
	local x = table.getn(Sprites)+1
	Sprites[x] = {}
	Sprites[x].Target = -1
	Sprites[x].Owner = userid
	Sprites[x].Sprites = 0
	local ents = _EntitiesFindInSphere(_TraceEndPos(), 364)
	for i=1, table.getn(ents) do
		if ents[i] <= _MaxPlayers() then
			if _PlayerInfo(ents[i], "team") ~= _PlayerInfo(userid, "team") then
				Sprites[x].Target = ents[i]
				break
			end
		elseif Vehicles[ents[i]] ~= nil then
			if Vehicles[ents[i]].Team ~= Vehicles[vehicle].Team then
				Sprites[x].Target = ents[i]
				break
			end
		end
	end
	if Sprites[x].Target <= 0 then
		Sprites[x] = nil
		return false
	else
		if o > 1 then
			_EntEmitSound(vehicle, "weapons/stinger_fire1.wav")
		end
	end
	local fireball = _EntCreate("rpg_missile")
	if fireball > 0 then
		local right = _EntGetRightVector(vehicle)
		local left = vecMul(right, vector3(-1,-1,-1))
		right = vecMul(right, vector3(50,50,50))
		left = vecMul(left, vector3(50,50,50))
		if o > 1 then
			_EntSetPos(fireball, vecAdd(vecAdd(_EntGetPos(vehicle), vector3(0,0,-50)), right))
		else
			_EntSetPos(fireball, vecAdd(vecAdd(_EntGetPos(vehicle), vector3(0,0,-50)), left))
		end
		_EntSpawn(fireball)
		_EntSetOwner(fireball, vehicle)
		_EntSetAng(fireball, _EntGetAng(vehicle))
		_EntSetName(fireball, "firesprite:"..x)
		_EntSetVelocity(fireball, vecMul(_EntGetAng(fireball), vector3(1200,1200,1200)))
		Sprites[x].Sprites = fireball
		Sprites[x].Timer = AddTimer(0.075, 0, SpriteTimer, x)
	end
	end
	return true
end
