--[[local function VisualizeRay(ray,RayLength)
	local RayCast = Instance.new("Part")
	RayCast.Material = Enum.Material.Neon
	RayCast.Color = Color3.new(0,1,0)
	RayCast.Size = Vector3.new(0.2,0.2,(RayLength or 5))
	RayCast.CFrame = CFrame.new(ray.Origin, ray.Origin+ray.Direction) * CFrame.new(0, 0, -(RayLength or 5) / 2)
	RayCast.Anchored = true
	RayCast.CanCollide = false
	RayCast.Parent = workspace
	Debris:AddItem(RayCast,0.5)
end]]

function IsTeamMate(Player1, Player2)
	return (Player1 and Player2 and not Player1.Neutral and not Player2.Neutral and Player1.TeamColor == Player2.TeamColor)
end

function TagHumanoid(humanoid, player)
	local Creator_Tag = Instance.new("ObjectValue")
	Creator_Tag.Name = "creator"
	Creator_Tag.Value = player
	Debris:AddItem(Creator_Tag, 2)
	Creator_Tag.Parent = humanoid
end

function UntagHumanoid(humanoid)
	for i, v in pairs(GetChildren(humanoid)) do
		if IsA(v,"ObjectValue") and v.Name == "creator" then
			Destroy(v)
		end
	end
end

local Player, Character, Humanoid

local Seed = Random.new(tick())

local Hit_WhiteList = {}
function Touched(hit)
	
	if not hit or not hit.Parent then return end
	
	Hit_WhiteList[1] = hit --Replace the Whitelisted entry (Also helps reduce lag)
	
	--Do a Server-sided check to make sure the sword is in reasonable distance to the part hit (To prevent exploits)
	
	local DistanceRay = NewRay( Handle.Position , (hit.Position - Handle.Position).Unit * math.max(Handle.Size.X,Handle.Size.Y,Handle.Size.Z) * 2 )
	
	local part = workspace:FindPartOnRayWithWhitelist(DistanceRay, Hit_WhiteList , true)	
	
	--warn((part and "Part in range") or "Part not in range")
	--assert(part, "Part not in range: Potential exploit")
	if part ~= hit then return end -- Potential exploiter may be abusing the touched events
	
	local FF, Hum = FindFirstChildOfClass(hit.Parent, "ForceField"), FindFirstChildOfClass(hit.Parent, "Humanoid")
	
	if FF or not Hum or Hum == Humanoid or Hum.Health <= 0 then return end --Don't hit yourself or anyone with a ForceField now..
	
	if IsTeamMate(Player, Players:GetPlayerFromCharacter(Hum.Parent)) then return end
	
	if Properties.Special then
		Properties.Special = false
		
		pcall(function()
			--Handle["Sparkle_Large_Blue"].Enabled = false
			Handle["Sparkle_Large_Blue"].Rate = Handle["Sparkle_Large_Blue"].Rate * 8
		end)
		
		local Constellation_Link = Clone(WaitForChild(script, "Constellation_Link"))
		
		local Val = Instance.new("ObjectValue")
		Val.Name = "HandleRef"
		Val.Value = Handle
		Val.Parent = Constellation_Link
		
		Val = Instance.new("ObjectValue")
		Val.Name = "Creator"
		Val.Value = Player
		Val.Parent = Constellation_Link
		
		Val = Instance.new("ObjectValue")
		Val.Name = "InitialTarget"
		Val.Value = Hum
		Val.Parent = Constellation_Link
		
		Constellation_Link.Parent = ServerScriptService
		
		Constellation_Link.Disabled = false
		
		Constellation_Link.AncestryChanged:Connect(function(obj, parent)
			
			if parent then return end
			
			if obj ~= Constellation_Link then return end
			
			print("Reloading...")
			pcall(function()
				Handle["Sparkle_Large_Blue"].Enabled = false
				Handle["Sparkle_Large_Blue"].Rate = Handle["Sparkle_Large_Blue"].Rate / 8
			end)
			delay(Properties.Special_Reload, function()
				pcall(function()
					Handle["Sparkle_Large_Blue"].Enabled = true
				end)
				Properties.Special = true
			end)
			
		end)
	end
	
	UntagHumanoid(Hum)
	TagHumanoid(Hum, Player)
	
	local Damage = Seed:NextNumber(Properties["DamageValues"][Properties.DamageMode].Min, Properties["DamageValues"][Properties.DamageMode].Max)
	
	Hum:TakeDamage(Damage)
	
	if Hum.Health <= 0 then
		--Finisher activated!
		local Finisher = Clone(WaitForChild(script, "Finisher"))
		Finisher.Parent = Hum.Parent
		Finisher.Disabled = false
	end
	
end

local LastAttack = tick()
function Activated()
	
	if not Tool.Enabled then return end
	
	Tool.Enabled = false
	
	local CurrentTime = tick()
	
	if (CurrentTime - LastAttack) <= 0.2 then
		
		for _,v in pairs(GetChildren(Handle)) do
			if v and IsA(v, "ParticleEmitter") then
				coroutine.wrap(function()
					local x = 0
					repeat
						local delta = RunService.Heartbeat:Wait()
						x = x + delta
						v:Emit((v.Enabled and math.ceil(v.Rate * .25)) or 0)
					until x >= .5
				end)()
				
			end
		end
		
		Sounds.Lunge:Play()
		
		Tool.Grip = DefaultGrip.Value * CFrame.Angles(math.rad(90),0,0)
		
		local LungeAnim = Instance.new("StringValue")
		LungeAnim.Name = "toolanim"
		LungeAnim.Value = "Lunge"
		LungeAnim.Parent = Tool
		
		--Lunge
		Properties.DamageMode = "Lunge" --Should allow the sword to deal more damage while lunging
		--print("Lunge")
		wait(.5)
		Properties.DamageMode = "Normal"
		Tool.Grip = DefaultGrip.Value
		wait(.5)
	else
		--Slash
		Sounds.Slash.TimePosition = Sounds.Slash.TimeLength/2
		Sounds.Slash:Play()
		local SwingAnim = Instance.new("StringValue")
		SwingAnim.Name = "toolanim"
		SwingAnim.Value = "Slash"
		SwingAnim.Parent = Tool
		--print("Swing")
	end
	
	LastAttack = CurrentTime
	
	Tool.Enabled = true
	
end


local Events = {} 

function Equipped()
	
	Character = Tool.Parent
	
	if not Character then return end
	
	Humanoid = FindFirstChildOfClass(Character, "Humanoid")
	
	if not Humanoid or Humanoid.Health <= 0 then return end
	
	Sounds.Equip:Play()
	
	Player = Players:GetPlayerFromCharacter(Character)
	
	if Player then
		Events[#Events+1] = Player.CharacterRemoving:Connect(Unequipped) --To keep some things from breaking
	end
	
	Events[#Events+1] = Handle.Touched:Connect(Touched)
	
	Events[#Events+1] = Tool.Activated:Connect(Activated)
	
	Events[#Events+1] = Humanoid.Died:Connect(Unequipped)
	
	Humanoid.WalkSpeed = Properties.SpeedCap
	Events[#Events+1] = Humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
		if not Humanoid then return end
		Humanoid.WalkSpeed = Properties.SpeedCap
	end)
	
	
	
end


function Unequipped()
	
	for i=1,#Events,1 do
		if Events[i] then
			Events[i]:Disconnect()
		end
	end
	Events = {}
	
	if Humanoid then
		Humanoid.WalkSpeed = 16
	end
end

Tool.Equipped:Connect(Equipped)
Tool.Unequipped:Connect(Unequipped)