--Made by Stickmasterluke




sp=script.Parent


speed=2
topspeed=50




function waitfor(parent,name)
	while parent:FindFirstChild(name)==nil do
		wait()
	end
	return parent:FindFirstChild(name)
end

local canim=waitfor(sp,"coastingpose")
local lanim=waitfor(sp,"leftturn")
local ranim=waitfor(sp,"rightturn")
local handle=waitfor(sp,"Handle")
local wind=waitfor(handle,"Wind")
local mesh=waitfor(handle,"Mesh")

inertia=1-(speed/topspeed)
debris=game:GetService("Debris")
equipped=false
flying=false
controls={forward=0,backward=0,left=0,right=0}
momentum=Vector3.new(0,0,0)
lastmomentum=Vector3.new(0,0,0)
totalmomentum=0
tilt=0
lasttilt=0
currentanim="coast"
lastanim=wind
mesh.Scale=Vector3.new(3,3,3)
handle.Size=Vector3.new(2,1.5,3)
sp.Grip=CFrame.new(0,0,0)


function RemoveFlyStuff()
	wind:Stop()
	local plr=game.Players.LocalPlayer
	if plr then
		local chr=plr.Character
		if chr then
			for i,v in ipairs(chr:getChildren()) do
				if v.Name=="Humanoid" then
					v.PlatformStand=false
				end
				if v and v.Name=="EffectCloud" then
					v:remove()
				end
			end
			local torso=chr:FindFirstChild("Torso")
			if torso~=nil then
				for i,v in ipairs(torso:GetChildren()) do
					if v and (v.Name=="FlightGyro" or v.Name=="FlightVelocity") then
						v:remove()
					end
				end
			end
		end
	end
	handle.Transparency=0
	handle.Smoke.Enabled=true
	if lastanim~=nil then
		lastanim:Stop()
	end
end

function fly()		--(de)activate fly mode
	if not equipped then
		flying=false
	else
		flying=not flying
	end
	RemoveFlyStuff()
	if flying then
		local torso=sp.Parent:FindFirstChild("Torso")
		local humanoid=sp.Parent:FindFirstChild("Humanoid")
		if torso and humanoid and humanoid.Health>0 then
			handle.Transparency=1
			handle.Smoke.Enabled=false
			humanoid.PlatformStand=true
			momentum=torso.Velocity+(torso.CFrame.lookVector*10)+Vector3.new(0,3,0)

			local gyro=Instance.new("BodyGyro")
			gyro.Name="FlightGyro"
			gyro.P=10^6
			gyro.maxTorque=Vector3.new(gyro.P,gyro.P,gyro.P)
			gyro.cframe=torso.CFrame
			gyro.Parent=torso

			velocity=Instance.new("BodyVelocity")
			velocity.Name="FlightVelocity"
			velocity.velocity=Vector3.new(0,0,0)
			velocity.P=10^4
			velocity.maxForce=Vector3.new(1,1,1)*(10^6)
			velocity.Parent=torso
			
			local cloud=handle:clone()
			cloud.Transparency=0
			cloud.CanCollide=false
			waitfor(cloud,"Smoke").Enabled=true
			cloud.Name="EffectCloud"
			local w=Instance.new("Weld")
			w.Part0=torso
			w.Part1=cloud
			w.C0=CFrame.new(1,-4,0)*CFrame.Angles(0,math.pi/2,0)
			w.Parent=cloud
			cloud.Parent=sp.Parent

			if lastanim~=nil then
				lastanim:Stop()
			end
			lastanim=humanoid:LoadAnimation(canim)
			lastanimused=0
			if lastanim then
				lastanim:Play(.5)
			end
			wind:Play()
			while flying and torso and humanoid and humanoid.Health>0 and equipped do
				local movement=game.Workspace.CurrentCamera.CoordinateFrame:vectorToWorldSpace(Vector3.new(controls.left+controls.right,math.abs(controls.forward)*.2,controls.forward+controls.backward))*speed

				momentum=(momentum*inertia)+movement
				totalmomentum=math.min(momentum.magnitude,topspeed)
				local momentumpercent=(totalmomentum/topspeed)
				if cloud~=nil then
					local m=cloud:FindFirstChild("Mesh")
					m.Scale=Vector3.new(4,4,4+(momentumpercent*4))
				end
				wind.Pitch=(momentumpercent*2)+1
				wind.Volume=momentumpercent+.1

				local tilt=((momentum*Vector3.new(1,0,1)).unit:Cross(((lastmomentum*Vector3.new(1,0,1)).unit))).y
				if tostring(tilt)=="-1.#IND" or tostring(tilt)=="1.#IND" or tilt==math.huge or tilt==-math.huge or tostring(0/0) == tostring(tilt) then
					tilt=0
				end
				local abstilt=math.abs(tilt)
				if abstilt>.06 or abstilt<.0001 then
					if math.abs(lasttilt)>.0001 then
						tilt=lasttilt*.96
					else
						tilt=0
					end
				else
					tilt=(lasttilt*.9)+(tilt*.1)			--weighted average
				end
				lasttilt=tilt
				if tilt>.01 then
					if lastanimused~=1 then
						lastanim:Stop(.5)
						lastanim=humanoid:LoadAnimation(ranim)
						lastanim:Play(.5)
						lastanimused=1
					end
				elseif tilt<(-.01) then
					if lastanimused~=-1 then
						lastanim:Stop(.5)
						lastanim=humanoid:LoadAnimation(lanim)
						lastanim:Play(.5)
						lastanimused=-1
					end
				elseif lastanimused~=0 then
					lastanim:Stop(.5)
					lastanim=humanoid:LoadAnimation(canim)
					lastanim:Play(.5)
					lastanimused=0
				end
				if totalmomentum<.5 then
					momentum=Vector3.new(0,0,0)
					totalmomentum=0
					gyro.cframe=CFrame.new(Vector3.new(0,0,0),game.Workspace.CurrentCamera.CoordinateFrame.lookVector*Vector3.new(1,0,1))*CFrame.Angles(0,-math.pi/2,0)
				else
					gyro.cframe=CFrame.new(Vector3.new(0,0,0),momentum)*CFrame.Angles(0,-math.pi/2,0)*CFrame.Angles(tilt*(-20),0,0)
				end
				velocity.velocity=momentum
				lastmomentum=momentum
				wait(rate)
			end
		end
		RemoveFlyStuff()
		flying=false
	end
end

function onEquipped(mouse)
	equipped=true
	if mouse~=nil then
		mouse.Icon="rbxasset://textures\\GunCursor.png"
		mouse.Button1Down:connect(function()
			fly()
			local torso=sp.Parent:FindFirstChild("Torso")
			if torso~=nil then
				torso.Velocity=momentum
			end
		end)
		mouse.KeyDown:connect(function(key2)
			local key=string.byte(key2)
			if key==32 then					--Space bar
				--[[fly()
				local torso=sp.Parent:FindFirstChild("Torso")
				if torso~=nil then
					torso.Velocity=momentum
				end]]
			elseif key==string.byte("w") or key==17 then
				controls.forward=-1
			elseif key==string.byte("a") or key==20 then
				controls.left=-1
			elseif key==string.byte("s") or key==18 then
				controls.backward=1
			elseif key==string.byte("d") or key==19 then
				controls.right=1
			end
		end)
		mouse.KeyUp:connect(function(key2)
			local key=string.byte(key2)
			if key==string.byte("w") or key==17 then
				controls.forward=0
			elseif key==string.byte("a") or key==20 then
				controls.left=0
			elseif key==string.byte("s") or key==18 then
				controls.backward=0
			elseif key==string.byte("d") or key==19 then
				controls.right=0
			end
		end)
	end

end

function onUnequipped()
	equipped=false
end

sp.Equipped:connect(onEquipped)
sp.Unequipped:connect(onUnequipped)