--[[
				    game.ReplicatedStorage:WaitForChild("InflictTarget"):InvokeServer(Tool,
				                                                                    Tagger,
				                                                                    TargetHumanoid,
						                                                            TargetTorso,
						                                                           (HitPart.Name == "Head" and DamageData[3]) and DamageData[1] * DamageData[2] or DamageData[1],
						                                                           {Misc[1],Misc[2],Misc[3],Misc[4],Misc[5],Misc[6],Misc[7],Misc[8]},
						                                                           {Critical[1],Critical[2],Critical[3]},
						                                                            HitPart,
						                                                           {GoreData[1], GoreData[2], GoreData[3], GoreData[4], GoreData[5]})
			        Tool.GunScript_Local:FindFirstChild("MarkerEvent"):Fire(HitPart.Name == "Head" and DamageData[3])
--]]
			    end
		    else
		        MakeImpactFX(HitPart, HitPoint, Normal, HitEffectData, BulletHoleData)
		    end
	    end
    else
	    if ExplosiveData[3] then
			local Sound = Instance.new("Sound")
		    Sound.SoundId = "rbxassetid://"..ExplosiveData[4][math.random(1,#ExplosiveData[4])]
		    Sound.PlaybackSpeed = Random.new():NextNumber(ExplosiveData[5], ExplosiveData[6])
		    Sound.Volume = ExplosiveData[7]
		    Sound.Parent = CosmeticBulletObject
		    Sound:Play()	
		end
		
		local Explosion = Instance.new("Explosion")
		Explosion.BlastRadius = ExplosiveData[2]
		Explosion.BlastPressure = 0
	    Explosion.Position = HitPoint
		Explosion.Parent = workspace.CurrentCamera
		
		if ExplosiveData[8] then
			Explosion.Visible = false
	        local surfaceCF = CFrame.new(HitPoint, HitPoint + Normal)
	
		    local Attachment = Instance.new("Attachment")
		    Attachment.CFrame = surfaceCF
	        Attachment.Parent = workspace.Terrain
	
		    local function spawner4()
	            local C = ExplosiveData[9]:GetChildren()
	            for i=1,#C do
		            if C[i].className == "ParticleEmitter" then
			            local count = 1
			            local Particle = C[i]:Clone()
			            Particle.Parent = Attachment
		                if Particle:FindFirstChild("EmitCount") then
			                count = Particle.EmitCount.Value
		                end
			            delay(0.01,function()
			                Particle:Emit(count)
			                game.Debris:AddItem(Particle,Particle.Lifetime.Max)
		                end)
		            end
	            end
		    end
		
	        spawn(spawner4)
	        game.Debris:AddItem(Attachment,10)
	    end	
		
		Explosion.Hit:connect(function(HitPart)
			if HitPart and HitPart.Parent and HitPart.Name == "HumanoidRootPart" or HitPart.Name == "Head" then
				local TargetHumanoid = findFirstByClass(HitPart.Parent,"Humanoid")
				local TargetTorso = HitPart.Parent:FindFirstChild("HumanoidRootPart") or HitPart.Parent:FindFirstChild("Head")
				local Tagger = game.Players:GetPlayerFromCharacter(Tool.Parent)
				if TargetHumanoid then
					if TargetHumanoid.Health > 0 then	
 					    game.ReplicatedStorage:WaitForChild("InflictTarget"):InvokeServer(Tool,
					                                                                    Tagger,
					                                                                    TargetHumanoid,
							                                                            TargetTorso,
							                                                           (HitPart.Name == "Head" and DamageData[3]) and DamageData[1] * DamageData[2] or DamageData[1],
							                                                           {Misc[1],Misc[2],Misc[3],Misc[4],Misc[5],Misc[6],Misc[7],Misc[8]},
							                                                           {Critical[1],Critical[2],Critical[3]},
							                                                            HitPart,
							                                                           {GoreData[1], GoreData[2], GoreData[3], GoreData[4], GoreData[5]})
			            Tool.GunScript_Local:FindFirstChild("MarkerEvent"):Fire(HitPart.Name == "Head" and DamageData[3])
			        end
				end
		    end
	    end)
	end
end
function VisualizeBullet(Tool,Handle,Direction,FirePointObject,HitEffectData,BloodEffectData,BulletHoleData,ExplosiveData,BulletData,DamageData,BulletLightData,Misc,Critical,GoreData)
	if Handle then		
		Caster.Gravity = BulletData[9]
        Caster.ExtraForce = Vector3.new(BulletData[10].X, BulletData[10].Y, BulletData[10].Z)

	    --UPDATE V6: Proper bullet velocity!
	    --Requested by https://www.roblox.com/users/898618/profile/
	    --We need to make sure the bullet inherits the velocity of the gun as it fires, just like in real life.
	    local HumanoidRootPart = Tool.Parent:WaitForChild("HumanoidRootPart", 1)	--Add a timeout to this.
	    local MyMovementSpeed = HumanoidRootPart.Velocity							--To do: It may be better to get this value on the clientside since the server will see this value differently due to ping and such.
	    local ModifiedBulletSpeed = (Direction * BulletData[8]) + MyMovementSpeed	--We multiply our direction unit by the bullet speed. This creates a Vector3 version of the bullet's velocity at the given speed. We then add MyMovementSpeed to add our body's motion to the velocity.
			
		--Make a base cosmetic bullet object. This will be cloned every time we fire off a ray
        local CosmeticBullet = Instance.new("Part")
        CosmeticBullet.Name = "Bullet"
        CosmeticBullet.Material = BulletData[14]
        CosmeticBullet.Color = BulletData[12]
        CosmeticBullet.CanCollide = false
        CosmeticBullet.Anchored = true
        CosmeticBullet.Size = Vector3.new(BulletData[11].X, BulletData[11].Y, BulletData[11].Z)
        CosmeticBullet.Transparency = BulletData[13]
        CosmeticBullet.Shape = BulletData[15]

        if BulletData[16] then
	        local BulletMesh = Instance.new("SpecialMesh")
	        BulletMesh.Scale = Vector3.new(BulletData[19].X, BulletData[19].Y, BulletData[19].Z)
	        BulletMesh.MeshId = "rbxassetid://"..BulletData[17]
	        BulletMesh.TextureId = "rbxassetid://"..BulletData[18]
	        BulletMesh.MeshType = "FileMesh"
	        BulletMesh.Parent = CosmeticBullet
        end
           
	    --Prepare a new cosmetic bullet
	    local Bullet = CosmeticBullet:Clone()
	    Bullet.CFrame = CFrame.new(FirePointObject.WorldPosition, FirePointObject.WorldPosition + Direction)
	    Bullet.Parent = workspace.CurrentCamera

        if BulletLightData[1] then
	        local Light = Instance.new("PointLight")
	        Light.Brightness = BulletLightData[2]
	        Light.Color = BulletLightData[3]
	        Light.Enabled = true
	        Light.Range = BulletLightData[4]
	        Light.Shadows = BulletLightData[5]
	        Light.Parent = Bullet
        end
	
	    if BulletData[1] then
	        local A0 = Instance.new("Attachment", Bullet)
	        A0.Position = Vector3.new(BulletData[2].X, BulletData[2].Y, BulletData[2].Z)
	        A0.Name = "Attachment0"
	        local A1 = Instance.new("Attachment", Bullet)
	        A1.Position = Vector3.new(BulletData[3].X, BulletData[3].Y, BulletData[3].Z)
	        A1.Name = "Attachment1"
	
	        local C = BulletData[4]:GetChildren()
	        for i=1,#C do
		        if C[i].className == "Trail" then
		            local count = 1
		            local Tracer = C[i]:Clone()
		            Tracer.Attachment0 = A0
		            Tracer.Attachment1 = A1
		            Tracer.Parent = Bullet
		        end
	        end
	    end
	
	    if BulletData[5] then
	        local C = BulletData[6]:GetChildren()
	        for i=1,#C do
		        if C[i].className == "ParticleEmitter" then
		            local Particle = C[i]:Clone()
		            Particle.Parent = Bullet
                    Particle.Enabled = true
		        end
	        end
	    end	

	    Caster:FireWithBlacklist(FirePointObject.WorldPosition, Direction * BulletData[7], ModifiedBulletSpeed, {Handle, Tool.Parent, workspace.CurrentCamera}, Bullet)

        function OnRayHit_Sub(HitPart, HitPoint, Normal, Material, CosmeticBulletObject)
            OnRayHit_Sub2(HitPart,
	                HitPoint,
	                Normal,
	                Material,
	                CosmeticBulletObject,
	                Tool,
	                {ExplosiveData[1], ExplosiveData[2], ExplosiveData[3], ExplosiveData[4], ExplosiveData[5], ExplosiveData[6], ExplosiveData[7], ExplosiveData[8], ExplosiveData[9]},
	                {DamageData[1], DamageData[2], DamageData[3]},
	                {HitEffectData[1], HitEffectData[2], HitEffectData[3], HitEffectData[4], HitEffectData[5], HitEffectData[6], HitEffectData[7]},
	                {BulletHoleData[1], BulletHoleData[2], BulletHoleData[3], BulletHoleData[4], BulletHoleData[5], BulletHoleData[6]},
	                {BloodEffectData[1], BloodEffectData[2], BloodEffectData[3], BloodEffectData[4], BloodEffectData[5], BloodEffectData[6]},
	                {Misc[1],Misc[2],Misc[3],Misc[4],Misc[5],Misc[6],Misc[7],Misc[8]},
	                {Critical[1],Critical[2],Critical[3]},
	                {GoreData[1], GoreData[2], GoreData[3], GoreData[4], GoreData[5]})
        end
	end
end

function OnRayHit(HitPart, HitPoint, Normal, Material, CosmeticBulletObject)
	OnRayHit_Sub(HitPart, HitPoint, Normal, Material, CosmeticBulletObject)
end

function OnRayUpdated(CastOrigin, SegmentOrigin, SegmentDirection, Length, CosmeticBulletObject)
    local BulletLength = CosmeticBulletObject.Size.Z / 2 --This is used to move the bullet to the right spot based on a CFrame offset
	CosmeticBulletObject.CFrame = CFrame.new(SegmentOrigin, SegmentOrigin + SegmentDirection) * CFrame.new(0, 0, -(Length - BulletLength))
end

BE.Event:connect(VisualizeBullet)
Caster.LengthChanged:Connect(OnRayUpdated)
Caster.RayHit:Connect(OnRayHit)