--------------------------------------------------------------------------------------
--------------------[ TOOL SELECTION AND DESELECTION ]--------------------------------
--------------------------------------------------------------------------------------


function OnEquipped(M_Icon)
	wait(math.random(10, 40) / 100)
	if Humanoid.Health ~= 0 and (not Selected) and Gun.Parent == Character then
		Selected = true
		
		BreakReload = false
		
		--------------------[ FAILSAFE RESETING ]-------------------------------------
		
		for _, GM in pairs(Ignore_Model:GetChildren()) do
			if GM.Name == "Gun_Ignore_"..Player.Name then
				GM:Destroy()
			end
		end
		
		for _,c in pairs(Connections) do
			c:disconnect()
		end
		
		Connections = {}
		
		--------------------[ CREATING IGNORE MODELS ]--------------------------------
		
		Gun_Ignore = Instance.new("Model")
		Gun_Ignore.Name = "Gun_Ignore_"..Player.Name
		Gun_Ignore.Parent = Ignore_Model
		
		--------------------[ MODIFYING THE PLAYER ]----------------------------------
		
		M_Icon.Icon = "rbxasset://textures\\Blank.png"
		
		Gui_Clone = Main_Gui:Clone()
		Gui_Clone.Parent = Player.PlayerGui
		
		SetUpGui()
		
		Shoulders.Right.Part1 = nil
		Shoulders.Left.Part1 = nil
		
		PrevNeckCF.C0 = Neck.C0
		PrevNeckCF.C1 = Neck.C1
		
		BG = Instance.new("BodyGyro", HRP)
		BG.maxTorque = VEC3(HUGE, HUGE, HUGE)
		BG.Name = "BG"
		BG.P = 1e5
		BG.cframe = CF(Torso.CFrame.p, Torso.CFrame.p + Torso.CFrame.lookVector)

		local PlayerFolder = Instance.new("Model")
		PlayerFolder.Name = "PlayerFolder"
		PlayerFolder.Parent = Gun_Ignore
		
		local AnimBase = Instance.new("Part")
		AnimBase.Transparency = 1
		AnimBase.Name = "AnimBase"
		AnimBase.CanCollide = false
		AnimBase.FormFactor = Enum.FormFactor.Custom
		AnimBase.Size = VEC3(0.2, 0.2, 0.2)
		AnimBase.BottomSurface = Enum.SurfaceType.Smooth
		AnimBase.TopSurface = Enum.SurfaceType.Smooth
		AnimBase.Parent = PlayerFolder
		
		AnimWeld = Instance.new("Weld")
		AnimWeld.Part0 = AnimBase
		AnimWeld.Part1 = Head
		AnimWeld.C0 = CF(0, 1, 0)
		AnimWeld.Parent = AnimBase
		
		local ArmBase = Instance.new("Part")
		ArmBase.Transparency = 1
		ArmBase.Name = "ArmBase"
		ArmBase.CanCollide = false
		ArmBase.FormFactor = Enum.FormFactor.Custom
		ArmBase.Size = VEC3(0.2, 0.2, 0.2)
		ArmBase.BottomSurface = Enum.SurfaceType.Smooth
		ArmBase.TopSurface = Enum.SurfaceType.Smooth
		ArmBase.Parent = PlayerFolder
		
		ABWeld = Instance.new("Weld")
		ABWeld.Part0 = ArmBase
		ABWeld.Part1 = AnimBase
		ABWeld.Parent = ArmBase
		
		local LArmBase = Instance.new("Part")
		LArmBase.Transparency = 1
		LArmBase.Name = "LArmBase"
		LArmBase.CanCollide = false
		LArmBase.FormFactor = Enum.FormFactor.Custom
		LArmBase.Size = VEC3(0.2, 0.2, 0.2)
		LArmBase.BottomSurface = Enum.SurfaceType.Smooth
		LArmBase.TopSurface = Enum.SurfaceType.Smooth
		LArmBase.Parent = PlayerFolder
		
		local RArmBase = Instance.new("Part")
		RArmBase.Transparency = 1
		RArmBase.Name = "RArmBase"
		RArmBase.CanCollide = false
		RArmBase.FormFactor = Enum.FormFactor.Custom
		RArmBase.Size = VEC3(0.2, 0.2, 0.2)
		RArmBase.BottomSurface = Enum.SurfaceType.Smooth
		RArmBase.TopSurface = Enum.SurfaceType.Smooth
		RArmBase.Parent = PlayerFolder
		
		LWeld = Instance.new("Weld")
		LWeld.Name = "LWeld"
		LWeld.Part0 = ArmBase
		LWeld.Part1 = LArmBase
		LWeld.C0 = ArmC0[1]
		LWeld.C1 = S.ArmC1_UnAimed.Left
		LWeld.Parent = ArmBase
		
		RWeld = Instance.new("Weld")
		RWeld.Name = "RWeld"
		RWeld.Part0 = ArmBase
		RWeld.Part1 = RArmBase
		RWeld.C0 = ArmC0[2]
		RWeld.C1 = S.ArmC1_UnAimed.Right
		RWeld.Parent = ArmBase
		
		LWeld2 = Instance.new("Weld")
		LWeld2.Name = "LWeld"
		LWeld2.Part0 = LArmBase
		LWeld2.Part1 = LArm
		LWeld2.Parent = LArmBase
		
		RWeld2 = Instance.new("Weld")
		RWeld2.Name = "RWeld"
		RWeld2.Part0 = RArmBase
		RWeld2.Part1 = RArm
		RWeld2.Parent = RArmBase
		
		if S.PlayerArms then
			FakeLArm = LArm:Clone()
			FakeLArm.Parent = PlayerFolder
			FakeLArm.Transparency = S.FakeArmTransparency
			FakeLArm:BreakJoints()
			
			LArm.Transparency = 1
			
			local FakeLWeld = Instance.new("Weld")
			FakeLWeld.Part0 = FakeLArm
			FakeLWeld.Part1 = LArm
			FakeLWeld.Parent = FakeLArm
			
			FakeRArm = RArm:Clone()
			FakeRArm.Parent = PlayerFolder
			FakeRArm.Transparency = S.FakeArmTransparency
			FakeRArm:BreakJoints()
			
			RArm.Transparency = 1
			
			local FakeRWeld = Instance.new("Weld")
			FakeRWeld.Part0 = FakeRArm
			FakeRWeld.Part1 = RArm
			FakeRWeld.Parent = FakeRArm
			
			Instance.new("Humanoid", PlayerFolder)
			
			for _,Obj in pairs(Character:GetChildren()) do
				if Obj:IsA("CharacterMesh") or Obj:IsA("Shirt") then
					Obj:Clone().Parent = PlayerFolder
				end
			end
		else
			local ArmTable = CreateArms()
			ArmTable[1].Model.Parent = PlayerFolder
			ArmTable[2].Model.Parent = PlayerFolder
			
			FakeLArm = ArmTable[1].ArmPart
			
			LArm.Transparency = 1
			
			local FakeLWeld = Instance.new("Weld")
			FakeLWeld.Part0 = FakeLArm
			FakeLWeld.Part1 = LArm
			FakeLWeld.Parent = FakeLArm
			
			FakeRArm = ArmTable[2].ArmPart
			
			RArm.Transparency = 1
			
			local FakeRWeld = Instance.new("Weld")
			FakeRWeld.Part0 = FakeRArm
			FakeRWeld.Part1 = RArm
			FakeRWeld.Parent = FakeRArm
		end
		
		--------------------[ MODIFYING THE GUN ]-------------------------------------
		
		for _, Tab in pairs(Parts) do
			local Weld = Instance.new("Weld")
			Weld.Name = "MainWeld"
			Weld.Part0 = Handle
			Weld.Part1 = Tab.Obj
			Weld.C0 = Tab.Obj.WeldCF.Value
			Weld.Parent = Handle
			Tab.Weld = Weld
		end
		
		Grip = RArm:WaitForChild("RightGrip")
		
		local HandleCF = ArmBase.CFrame * ArmC0[2] * S.ArmC1_Aimed.Right:inverse() * CF(0, -1, 0, 1, 0, 0, 0, 0, 1, 0, -1, 0)
		local HandleOffset = AimPart.CFrame:toObjectSpace(Handle.CFrame)
		Aimed_GripCF = (Head.CFrame * HandleOffset):toObjectSpace(HandleCF)
		
		--------------------[ CONNECTIONS ]-------------------------------------------
		
		INSERT(Connections, Humanoid.Died:connect(function()
			OnUnequipped(true)
		end))
		
		INSERT(Connections, M2.Button1Down:connect(function()
			MB1_Down = true
			if S.GunType.Auto and (not S.GunType.Semi) and (not S.GunType.Burst) then
				if (not CanFire) then return end
				CanFire = false
				if (not Running) and (not Knifing) and (not ThrowingGrenade) then
					CurrentSpread = (
						Aimed and S.Spread.Aimed or
						((Idleing and (not Walking)) and S.Spread.Hipfire or S.Spread.Walking)
					)
					while MB1_Down and (not Reloading) do
						if Knifing and (not ThrowingGrenade) then break end
						if Running then break end
						if Ammo.Value > 0 then
							Ammo.Value = Ammo.Value - 1
							if Humanoid.Health ~= 0 then
								if Aimed and Run_Key_Pressed and S.UnSteadyOnFire then
									Run_Key_Pressed = false
									CurrentSteadyTime = 0
								end
								Fire_Gun()
							end
						end
						if Ammo.Value == 0 and S.AutoReload then
							wait(0.2)
							Reload()
						end
						wait(60 / S.FireRate)
					end
				end
				CanFire = true
			elseif (not S.GunType.Auto) and S.GunType.Burst then
				if (not CanFire) then return end
				CanFire = false
				if (not Running) and (not Knifing) and (not ThrowingGrenade) then
					CurrentSpread = (
						Aimed and S.Spread.Aimed or
						((Idleing and (not Walking)) and S.Spread.Hipfire or S.Spread.Walking)
					)
					for i = 1, S.BurstAmount do
						if Ammo.Value > 0 then
							Ammo.Value = Ammo.Value - 1
							if Humanoid.Health ~= 0 then
								if Aimed and Run_Key_Pressed and S.UnSteadyOnFire then
									Run_Key_Pressed = false
									CurrentSteadyTime = 0
								end
								Fire_Gun()
							end
						end
						if Ammo.Value == 0 and S.AutoReload then
							wait(0.2)
							Reload()
							break
						end
						wait(S.BurstTime / S.BurstAmount)
					end
				end
				wait(S.BurstWait)
				CanFire = true
			elseif (not S.GunType.Auto) and S.GunType.Semi then
				if (not CanFire) then return end
				CanFire = false
				if (not Running) and (not Knifing) and (not ThrowingGrenade) then
					CurrentSpread = (
						Aimed and S.Spread.Aimed or
						((Idleing and (not Walking)) and S.Spread.Hipfire or S.Spread.Walking)
					)
					if Ammo.Value > 0 then
						Ammo.Value = Ammo.Value - 1
						if Humanoid.Health ~= 0 then
							if Aimed and Run_Key_Pressed and S.UnSteadyOnFire then
								Run_Key_Pressed = false
								CurrentSteadyTime = 0
							end
							Fire_Gun()
						end
					end
					if Ammo.Value == 0 and S.AutoReload then
						wait(0.2)
						Reload()
					end
					wait(60 / S.FireRate)
				end
				CanFire = true
			elseif (not S.GunType.Auto) and (not S.GunType.Semi) and (not S.GunType.Burst) and S.GunType.Shot then
				if (not CanFire) then return end
				CanFire = false
				if (not Running) and (not Knifing) and (not ThrowingGrenade) then
					CurrentSpread = (
						Aimed and S.Spread.Aimed or
						((Idleing and (not Walking)) and S.Spread.Hipfire or S.Spread.Walking)
					)
					if Ammo.Value > 0 then
						Ammo.Value = Ammo.Value - 1
						if Humanoid.Health ~= 0 then
							if Aimed and Run_Key_Pressed and S.UnSteadyOnFire then
								Run_Key_Pressed = false
								CurrentSteadyTime = 0
							end
							Fire_Gun()
						end
					end
					if Ammo.Value == 0 and S.AutoReload then
						wait(0.2)
						Reload()
					end
					wait(60 / S.FireRate)
				end
				CanFire = true
			elseif (not S.GunType.Auto) and (not S.GunType.Semi) and S.GunType.Burst and (not S.GunType.Shot) then
				if (not CanFire) then return end
				CanFire = false
				if (not Running) and (not Knifing) and (not ThrowingGrenade) then
					CurrentSpread = (
						Aimed and S.Spread.Aimed or
						((Idleing and (not Walking)) and S.Spread.Hipfire or S.Spread.Walking)
					)
					for i = 1, S.BurstAmount do
						if Ammo.Value > 0 then
							Ammo.Value = Ammo.Value - 1
							if Humanoid.Health ~= 0 then
								if Aimed and Run_Key_Pressed and S.UnSteadyOnFire then
									Run_Key_Pressed = false
									CurrentSteadyTime = 0
								end
								Fire_Gun()
							end
						end
						if Ammo.Value == 0 and S.AutoReload then
							wait(0.2)
							Reload()
							break
						end
						wait(S.BurstTime / S.BurstAmount)
					end
				end
				wait(S.BurstWait)
				CanFire = true
			elseif (not S.GunType.Auto) and (not S.GunType.Burst) and (not S.GunType.Shot) and S.GunType.Explosive then
				if (not CanFire) then return end
				CanFire = false
				if (not Running) and (not Knifing) and (not ThrowingGrenade) then
					CurrentSpread = (
						Aimed and S.Spread.Aimed or
						((Idleing and (not Walking)) and S.Spread.Hipfire or S.Spread.Walking)
					)
					if Ammo.Value > 0 then
						Ammo.Value = Ammo.Value - 1
						if Humanoid.Health ~= 0 then
							if Aimed and Run_Key_Pressed and S.UnSteadyOnFire then
								Run_Key_Pressed = false
								CurrentSteadyTime = 0
							end
							Fire_Gun()
						end
					end
					if Ammo.Value == 0 and S.AutoReload then
						wait(0.2)
						Reload()
					end
					wait(60 / S.FireRate)
				end
				CanFire = true
			end
		end))
		
		INSERT(Connections, M2.Button1Up:connect(function()
			MB1_Down = false
			CurrentSpread = (
				Aimed and S.Spread.Aimed or
				((Idleing and (not Walking)) and S.Spread.Hipfire or S.Spread.Walking)
			)
		end))
		
		INSERT(Connections, M2.Button2Down:connect(function()
			if S.HoldMouseOrKeyToADS then
				if (not AimingIn) and (not Aimed) then
					AimingIn = true
					AimGun()
					AimingIn = false
				end
			else
				if Aimed then
					UnAimGun()
				else
					AimGun()
				end
			end
		end))
		
		INSERT(Connections, M2.Button2Up:connect(function()
			if S.HoldMouseOrKeyToADS then
				if (not AimingOut) and Aimed then
					AimingOut = true
					UnAimGun()
					AimingOut = false
				end
			end
		end))
		
		INSERT(Connections, M2.KeyDown:connect(KeyDown))
		
		INSERT(Connections, M2.KeyUp:connect(KeyUp))
		
		INSERT(Connections, RS:connect(function()
			local CrossHair = Gui_Clone:WaitForChild("CrossHair")
			local HitMarker = Gui_Clone:WaitForChild("HitMarker")
			local HUD = Gui_Clone:WaitForChild("HUD")
			
			CrossHair.Position = UDim2.new(0, M2.X, 0, M2.Y)
			HitMarker.Position = UDim2.new(0, M2.X - 13, 0, M2.Y - 13)
			
			local Clip_Ammo_L = HUD:WaitForChild("Ammo"):WaitForChild("Clip")
			local Stored_Ammo_L = HUD:WaitForChild("Ammo"):WaitForChild("Stored")
			Clip_Ammo_L.Text = Ammo.Value
			Clip_Ammo_L.TextColor3 = (Ammo.Value <= (ClipSize.Value / 4) and Color3.new(1, 1, 0) or Color3.new(1, 1, 1))
			Stored_Ammo_L.Text = StoredAmmo.Value
			Stored_Ammo_L.TextColor3 = (StoredAmmo.Value <= (ClipSize.Value * 0.5) and Color3.new(1, 0.5, 0.5) or Color3.new(1, 1, 1))
			
			local Lethal_Grenade_Num_L = HUD:WaitForChild("Grenades"):WaitForChild("Lethals"):WaitForChild("Num")
			Lethal_Grenade_Num_L.Text = LethalGrenades.Value
			Lethal_Grenade_Num_L.TextColor3 = (LethalGrenades.Value < 2 and Color3.new(1, 0.5, 0.5) or Color3.new(1, 1, 1))
			
			local Tactical_Grenade_Num_L = HUD:WaitForChild("Grenades"):WaitForChild("Tacticals"):WaitForChild("Num")
			Tactical_Grenade_Num_L.Text = TacticalGrenades.Value
			Tactical_Grenade_Num_L.TextColor3 = (TacticalGrenades.Value < 2 and Color3.new(1, 0.5, 0.5) or Color3.new(1, 1, 1))
			
			local Mode = HUD:WaitForChild("Mode"):WaitForChild("Main")
			if S.GunType.Auto
			and (not S.GunType.Semi)
			and (not S.GunType.Burst)
			and (not S.GunType.Explosive) then
			
				Mode.Text = "Auto"
				
			elseif (not S.GunType.Auto)
			and S.GunType.Burst
			and (not S.GunType.Explosive) then
			
				Mode.Text = "Burst"
				
			elseif (not S.GunType.Auto)
			and S.GunType.Semi
			and (not S.GunType.Explosive) then
			
				Mode.Text = "Semi"
				
			elseif (not S.GunType.Auto)
			and (not S.GunType.Semi)
			and (not S.GunType.Burst)
			and S.GunType.Shot
			and (not S.GunType.Explosive) then
			
				Mode.Text = "Shotgun"
				
			elseif (not S.GunType.Auto)
			and (not S.GunType.Semi)
			and S.GunType.Burst
			and (not S.GunType.Shot)
			and (not S.GunType.Explosive) then
				
				Mode.Text = "Burst"
				
			elseif S.GunType.Explosive then
				
				Mode.Text = "Explosive"
				
			end
			
			if tick() - LastBeat > (Humanoid.Health / 75) then
				LastBeat = tick()
				HUD.Health.Tray.Beat:TweenPosition(
					UDim2.new(0, -21, 0, 0),
					Enum.EasingDirection.Out,
					Enum.EasingStyle.Linear,
					0.7 - ((100 - Humanoid.Health) / 400),
					false,
					function()
						HUD.Health.Tray.Beat.Position = UDim2.new(1, 0, 0, 0)
					end
				)
			end
			
			HUD.Health.Num.Text = CEIL(Humanoid.Health).."%"
			HUD.Health.Num.TextColor3 = (
				(Humanoid.Health > 200 / 3) and Color3.new(1, 1, 1) or
				(Humanoid.Health <= 200 / 3 and Humanoid.Health > 100 / 3) and Color3.new(1, 1, 0) or
				(Humanoid.Health <= 100 / 3) and Color3.new(1, 0, 0)
			)
		end))
		
		INSERT(Connections, RS:connect(function()
			local MDir = M2.UnitRay.Direction.unit
			
			local HRPCF = HRP.CFrame * CF(0, 1.5, 0) * CF(Humanoid.CameraOffset)
			Neck.C0 = Torso.CFrame:toObjectSpace(HRPCF)
			
			if MDir.y == MDir.y then
				HeadRot = -math.asin(MDir.y)
				Neck.C1 = CFANG(HeadRot,0,0)
				
				local RotTarget = VEC3(MDir.x,0,MDir.z)
				local Rotation = CF(Torso.Position,Torso.Position + RotTarget)
				BG.cframe = Rotation
				
				local MouseX = FLOOR((M2.X - M2.ViewSizeX / 2) + 0.5)
				local MouseY = FLOOR((M2.Y - M2.ViewSizeY / 2) + 0.5)
				local AppliedMaxTorque = nil
				if (Camera.CoordinateFrame.p - Head.Position).magnitude < 0.6 then
					if (MouseX >= 50 or MouseX <= -50)
					or (MouseY >= 50 or MouseY <= -50) then
						AppliedMaxTorque = VEC3()
					else
						AppliedMaxTorque = VEC3(HUGE,HUGE,HUGE)
					end
				else
					AppliedMaxTorque = VEC3(HUGE,HUGE,HUGE)
				end
				if (not S.RotateWhileSitting) and Humanoid.Sit then
					AppliedMaxTorque = VEC3()
				end
				BG.maxTorque = AppliedMaxTorque
			end
		end))
		
		INSERT(Connections, RS:connect(function()
			local Forward = (Keys["w"] or Keys[string.char(17)])
			local Backward = (Keys["s"] or Keys[string.char(18)])
			local Right = (Keys["d"] or Keys[string.char(19)])
			local Left = (Keys["a"] or Keys[string.char(20)])
			
			local WalkingForward = (Forward and (not Backward))
			local WalkingBackward = ((not Forward) and Backward)
			local WalkingRight = (Right and (not Left))
			local WalkingLeft = ((not Right) and Left)
			
			ArmTilt = (
				((WalkingForward or WalkingBackward) and WalkingRight) and 5 or
				((WalkingForward or WalkingBackward) and WalkingLeft) and -5 or
				((not (WalkingForward and WalkingBackward)) and WalkingRight) and 10 or
				((not (WalkingForward and WalkingBackward)) and WalkingLeft) and -10 or 0
			)
		end))
		
		INSERT(Connections, RS:connect(function()
			if (not Idleing) and Walking then
				if Running then
					Humanoid.WalkSpeed = S.SprintSpeed
				else
					local SpeedRatio = (S.AimedWalkSpeed / S.BaseWalkSpeed)
					if Stance == 0 then
						Humanoid.WalkSpeed = (Aimed and S.AimedWalkSpeed or S.BaseWalkSpeed)
					elseif Stance == 1 then
						Humanoid.WalkSpeed = (Aimed and S.CrouchWalkSpeed * SpeedRatio or S.CrouchWalkSpeed)
					elseif Stance == 2 then
						Humanoid.WalkSpeed = (Aimed and S.ProneWalkSpeed * SpeedRatio or S.ProneWalkSpeed)
					end
				end
			else
				Humanoid.WalkSpeed = 16
			end
			
			StanceSway = 1 - (0.25 * Stance)
		end))
		
		--------------------[ ANIMATE GUN ]-------------------------------------------
		
		Animate()
	end
end


function OnUnequipped(DeleteTool)
	if Selected then
		Selected = false
		
		BreakReload = true
		
		--------------------[ MODIFYING THE PLAYER ]----------------------------------
		
		Camera.FieldOfView = 70
		
		game:GetService("UserInputService").MouseIconEnabled = true
		
		Gui_Clone:Destroy()
		BG:Destroy()
		
		RArm.Transparency = 0
		LArm.Transparency = 0
		
		Shoulders.Right.Part1 = RArm
		Shoulders.Left.Part1 = LArm
		
		Neck.C0 = PrevNeckCF.C0
		Neck.C1 = PrevNeckCF.C1
		
		Humanoid.WalkSpeed = 16
		
		--------------------[ RESETING THE TOOL ]-------------------------------------
		
		Gun_Ignore:Destroy()
		
		Aimed = false
		
		for _, Tab in pairs(Parts) do
			Tab.Weld:Destroy()
			Tab.Weld = nil
		end
		
		for _,c in pairs(Connections) do
			c:disconnect()
		end
		
		Connections = {}
		
		if DeleteTool then
			Camera:ClearAllChildren()
			Gun:Destroy()
		end
		
		if S.StandOnDeselect and Stance ~= 0 then Stand(true) end
	end
end

Gun.Equipped:connect(OnEquipped)
Gun.Unequipped:connect(function() OnUnequipped(false) end)
