--[[Engine]]



	local fFD = _Tune.FinalDrive*_Tune.FDMult
	local fFDr = fFD*30/math.pi
	local cGrav = workspace.Gravity*_Tune.InclineComp/32.2
	local wDRatio = wDia*math.pi/60
	local cfWRot = CFrame.Angles(math.pi/2,-math.pi/2,0)
	local cfYRot = CFrame.Angles(0,math.pi,0)
	local rtTwo = (2^.5)/2

	--Horsepower Curve
	local fgc_h=_Tune.Horsepower/100
	local fgc_n=_Tune.PeakRPM/1000
	local fgc_a=_Tune.PeakSharpness
	local fgc_c=_Tune.CurveMult
	
	function FGC(x)
		x=x/1000
		return (((-(x-fgc_n)^2)*math.min(fgc_h/(fgc_n^2),fgc_c^(fgc_n/fgc_h)))+fgc_h)*(x-((x^fgc_a)/((fgc_a*fgc_n)^(fgc_a-1))))
	end
	local PeakFGC = FGC(_Tune.PeakRPM)
	
	--Plot Current Horsepower
	function GetCurve(x,gear)
		local hp=math.max((FGC(x)*_Tune.Horsepower)/PeakFGC,0)
		return hp,hp*(_Tune.EqPoint/x)*_Tune.Ratios[gear+2]*fFD*hpScaling
	end
	
	--Output Cache
	local CacheTorque = true
	local HPCache = {}
	local HPInc = 100
	
	if CacheTorque then
		for gear,ratio in pairs(_Tune.Ratios) do
			local hpPlot = {}
			for rpm = math.floor(_Tune.IdleRPM/HPInc),math.ceil((_Tune.Redline+100)/HPInc) do
				local tqPlot = {}
				tqPlot.Horsepower,tqPlot.Torque = GetCurve(rpm*HPInc,gear-2)
				hp1,tq1 = GetCurve((rpm+1)*HPInc,gear-2)
				tqPlot.HpSlope = (hp1 - tqPlot.Horsepower)/(HPInc/1000)
				tqPlot.TqSlope = (tq1 - tqPlot.Torque)/(HPInc/1000)
				hpPlot[rpm] = tqPlot
			end
			table.insert(HPCache,hpPlot)
		end
	end
	
	--Powertrain
	
	--Update RPM
	function RPM()
		--Neutral Gear
		if _CGear==0 then _ClutchOn = false end
	
		--Car Is Off
		local revMin = _Tune.IdleRPM
		if not _IsOn then 
			revMin = 0 
			_CGear = 0
			_ClutchOn = false
			_GThrot = _Tune.IdleThrottle/100
		end
		
		--Determine RPM
		local maxSpin=0
		for i,v in pairs(Drive) do
			if v.RotVelocity.Magnitude>maxSpin then maxSpin = v.RotVelocity.Magnitude end
		end
		if _ClutchOn then
			local aRPM = math.max(math.min(maxSpin*_Tune.Ratios[_CGear+2]*fFDr,_Tune.Redline+100),revMin)
			local clutchP = math.min(math.abs(aRPM-_RPM)/_Tune.ClutchTol,.9)
			_RPM = _RPM*clutchP  +  aRPM*(1-clutchP)
		else
			if _GThrot-(_Tune.IdleThrottle/100)>0 then
				if _RPM>_Tune.Redline then
					_RPM = _RPM-_Tune.RevBounce*2
				else
					_RPM = math.min(_RPM+_Tune.RevAccel*_GThrot,_Tune.Redline+100)
				end
			else
				_RPM = math.max(_RPM-_Tune.RevDecay,revMin)
			end
		end
		
		--Rev Limiter
		_spLimit = (_Tune.Redline+100)/(fFDr*_Tune.Ratios[_CGear+2])
		if _RPM>_Tune.Redline then 
			if _CGear<#_Tune.Ratios-2 then
				_RPM = _RPM-_Tune.RevBounce
			else
				_RPM = _RPM-_Tune.RevBounce*.5
			end
		end
	end
	
	--Apply Power
	function Engine()
		--Get Torque
		local maxSpin=0
		for i,v in pairs(Drive) do
			if v.RotVelocity.Magnitude>maxSpin then maxSpin = v.RotVelocity.Magnitude end
		end
		if _ClutchOn then
			if CacheTorque then
				local cTq = HPCache[_CGear+2][math.floor(math.min(_Tune.Redline,math.max(_Tune.IdleRPM,_RPM))/HPInc)]
				_HP = cTq.Horsepower+(cTq.HpSlope*(_RPM-math.floor(_RPM/HPInc))/1000)
				_OutTorque = cTq.Torque+(cTq.TqSlope*(_RPM-math.floor(_RPM/HPInc))/1000)
			else
				_HP,_OutTorque = GetCurve(_RPM,_CGear)
				
			end
			local iComp =(car.DriveSeat.CFrame.lookVector.y)*cGrav
			if _CGear==-1 then iComp=-iComp end
			_OutTorque = _OutTorque*math.max(1,(1+iComp))
		else
			_HP,_OutTorque = 0,0
		end
		
		--Automatic Transmission
		if _TMode == "Auto" and _IsOn then
			_ClutchOn = true
			if _CGear == 0 then _CGear = 1 end
			if _CGear >= 1 then