local O if debrisFolder:FindFirstChild("\077\111\099\104\105")then O=debrisFolder.Mochi else O=Instance.new("\070\111\108\100\101\114")O.Name="\077\111\099\104\105"O.Parent=debrisFolder end local V=partCacheMod.new(RS.FX.Mochi.MochiBall,300,O)local function G(O,G)local Q=math.random(1,2)local a={RS.Sounds.Mochi.MochiFistHit1;RS.Sounds.Mochi.MochiFistHit2}for O,V in pairs(a)do local Q=V:Clone()Q.Parent=G Q:Play()game.Debris:AddItem(Q,2)end for G=1,Q,1 do local Q=(Random.new()):NextNumber(1,3)local a=V:GetPart()a.Size=Vector3.new(Q,Q,Q)a.CFrame=CFrame.new(O)local f=CFrame.new(O)*CFrame.new((Random.new()):NextNumber(-30,30),15,(Random.new()):NextNumber(-30,30))local r=Ray.new(f.Position,Vector3.new(0,50,0))local y,h,u=workspace:FindPartOnRayWithIgnoreList(r,{a,debrisFolder})local n local d if y then d=O.Y-y.Position.Y n=Ray.new(Vector3.new(f.Position.X,d-1,f.Position.Z),Vector3.new(0,-1000,0))else d=50 n=Ray.new(f.Position,Vector3.new(0,-1000,0))end local l,p,D=workspace:FindPartOnRayWithIgnoreList(n,{a,debrisFolder})if l then local O=CFrame.new(p,p+D)*CFrame.Angles(-math.pi/2,0,0)local G=a.Position local Q=O.Position local f=CFrame.new((G+Q)/2)*(CFrame.new(0,(Random.new()):NextNumber(d*.25,d),0)).Position local r=(G-Q).Magnitude local y=40 local h=(Random.new()):NextNumber(2,4)a.Parent=debrisFolder local u=bezierTween.Create(a,{Waypoints=Waypoints.new(G,f,Q),EasingStyle=Enum.EasingStyle.Linear,EasingDirection=Enum.EasingDirection.In,Time=r/y})u:Play();(TS:Create(a,TweenInfo.new(r/y,Enum.EasingStyle.Quad,Enum.EasingDirection.InOut),{Color=Color3.fromRGB(255,246,208)})):Play()u.Completed:Connect(function()a.CFrame=CFrame.new(p,p+D)*CFrame.Angles(-math.pi/2,0,0);(TS:Create(a,TweenInfo.new(.18,Enum.EasingStyle.Quad,Enum.EasingDirection.InOut),{Size=Vector3.new(h*2,.5,h*2)})):Play()task.delay(5,function()(TS:Create(a,TweenInfo.new(.6,Enum.EasingStyle.Quad,Enum.EasingDirection.InOut),{Size=Vector3.new(0,0,0)})):Play()task.delay(.7,function()V:ReturnPart(a)end)end)end)else V:ReturnPart(a)end end end return function(O,Q)local a=Q.HumanoidRootPart local f=(Random.new()):NextNumber(1,2)local r=V:GetPart()r.Size=Vector3.new(f,f,f)local y=Ray.new(O+Vector3.new(0,1,0),Vector3.new(0,-50,0))local h,u,n=workspace:FindPartOnRayWithIgnoreList(y,{r;debrisFolder;Q})local d=math.rad(math.random(360))if h then local O=(CFrame.new(u,u+n)*CFrame.Angles(-math.pi/2,0,0))*CFrame.Angles(0,d,0)local Q=a.Position local f=O.Position local y=CFrame.new((Q+f)/2)*(CFrame.new(0,(Random.new()):NextNumber(25,45),0)).Position local h=(Q-f).Magnitude local l=100 local p=(Random.new()):NextNumber(8,14)r.Parent=debrisFolder local D=bezierTween.Create(r,{Waypoints=Waypoints.new(Q,y,f);EasingStyle=Enum.EasingStyle.Linear;EasingDirection=Enum.EasingDirection.In,Time=h/l})D:Play();(TS:Create(r,TweenInfo.new(h/l,Enum.EasingStyle.Quad,Enum.EasingDirection.InOut),{Color=Color3.fromRGB(255,246,208)})):Play()D.Completed:Connect(function()r.CFrame=(CFrame.new(u,u+n)*CFrame.Angles(-math.pi/2,0,0))*CFrame.Angles(0,d,0)local O=RS.FX.Mochi.C.MochiCFloor:Clone()O.Size=Vector3.new(0,1,0)O.CFrame=r.CFrame V:ReturnPart(r)O.Parent=debrisFolder;(TS:Create(O,TweenInfo.new(.18,Enum.EasingStyle.Quad,Enum.EasingDirection.InOut),{Size=Vector3.new(p*2,1.5,p*2)})):Play()local Q={RS.FX.Mochi.C.Spike1;RS.FX.Mochi.C.Spike2;RS.FX.Mochi.C.Spike3}local a=Q[math.random(1,#Q)]:Clone()a.CFrame=O.CFrame task.delay(.7,function()a.Size=Vector3.new(O.Size.X*.45,.01,O.Size.Z*.5)a.Parent=debrisFolder local V=(Random.new()):NextNumber(20,35);(TS:Create(a,TweenInfo.new(.17,Enum.EasingStyle.Back,Enum.EasingDirection.Out),{Size=Vector3.new(a.Size.X,V,a.Size.Z);CFrame=((CFrame.new(u,u+n)*CFrame.Angles(-math.pi/2,0,0))*CFrame.new(0,V/2-2,0))*CFrame.Angles(0,d,0)})):Play()G(a.Position,a)for O,V in pairs(O.ExpFX:GetChildren())do V:Emit(V:GetAttribute("\069\109\105\116\067\111\117\110\116"))end task.delay(1,function()(TS:Create(a,TweenInfo.new(5,Enum.EasingStyle.Back,Enum.EasingDirection.Out),{Size=a.Size*.98,CFrame=(CFrame.new(u,u+n)*CFrame.Angles(-math.pi/2,0,0))*CFrame.new(0,(a.Size.Y*.98)/2-3,0)})):Play()task.delay(3,function()(TS:Create(a,TweenInfo.new(.45,Enum.EasingStyle.Quad,Enum.EasingDirection.InOut),{Size=Vector3.new(p*2,.3,p*2),CFrame=CFrame.new(u,u+n)*CFrame.Angles(-math.pi/2,0,0)})):Play()task.delay(.45,function()(TS:Create(a,TweenInfo.new(.5,Enum.EasingStyle.Quad,Enum.EasingDirection.InOut),{Size=Vector3.new()})):Play()game.Debris:AddItem(a,.6)end)end)end)end)task.delay(6,function()(TS:Create(O,TweenInfo.new(.6,Enum.EasingStyle.Quad,Enum.EasingDirection.InOut),{Size=Vector3.new(0,0,0)})):Play()game.Debris:AddItem(O,.7)end)end)end end

local cacheFolder
if debrisFolder:FindFirstChild("Mochi") then
	cacheFolder = debrisFolder.Mochi
else
	cacheFolder = Instance.new("Folder")
	cacheFolder.Name = "Mochi"
	cacheFolder.Parent = debrisFolder
end

local partCache = partCacheMod.new(RS.FX.Mochi.MochiBall, 300, cacheFolder)

local function mochiExplosion(OriginPosition, OriginInstance)
	local amount = math.random(1, 2)

	local hitSFX = {
		RS.Sounds.Mochi.MochiFistHit1,
		RS.Sounds.Mochi.MochiFistHit2,
	}

	for sounds, sfx in pairs(hitSFX) do
		local clonedSFX = sfx:Clone()
		clonedSFX.Parent = OriginInstance
		clonedSFX:Play()
		game.Debris:AddItem(clonedSFX, 2)
	end

	for i = 1, amount do
		local mochiSize = Random.new():NextNumber(1, 3)
		local mochiPart = partCache:GetPart() --RS.FX.MochiDrip:Clone()
		mochiPart.Size = Vector3.new(mochiSize, mochiSize, mochiSize)
		mochiPart.CFrame = CFrame.new(OriginPosition)

		local rayCheck = CFrame.new(OriginPosition) * CFrame.new(Random.new():NextNumber(-30, 30), 15, Random.new():NextNumber(-30, 30))

		local roofCheckRay = Ray.new(rayCheck.Position, Vector3.new(0, 50, 0))
		local Rhit, Rvec2Pos, RsurfaceNormal = workspace:FindPartOnRayWithIgnoreList(roofCheckRay, {mochiPart, debrisFolder})

		local ray
		local maxHeight

		if Rhit then
			maxHeight = (OriginPosition.Y - Rhit.Position.Y)
			ray = Ray.new(Vector3.new(rayCheck.Position.X, maxHeight - 1, rayCheck.Position.Z), Vector3.new(0, -1000, 0))
		else
			maxHeight = 50
			ray = Ray.new(rayCheck.Position, Vector3.new(0, -1000, 0))
		end


		local hit, vec2Pos, surfaceNormal = workspace:FindPartOnRayWithIgnoreList(ray, {mochiPart, debrisFolder})

		if hit then
			local endCF = CFrame.new(vec2Pos, vec2Pos + surfaceNormal) * CFrame.Angles(-math.pi/2, 0, 0)		
			local p0 = mochiPart.Position
			local p2 = endCF.Position
			local p1 = CFrame.new((p0 + p2) / 2) * CFrame.new(0, Random.new():NextNumber(maxHeight * 0.25, maxHeight), 0).Position

			local distance = (p0 - p2).Magnitude
			local speed = 40

			local poolSize = Random.new():NextNumber(2, 4)

			mochiPart.Parent = debrisFolder

			local Tween = bezierTween.Create(mochiPart, {
				Waypoints = Waypoints.new(p0, p1, p2),
				EasingStyle = Enum.EasingStyle.Linear,
				EasingDirection = Enum.EasingDirection.In,
				Time = distance/speed
			})

			Tween:Play()
			TS:Create(mochiPart, TweenInfo.new(distance/speed, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {Color = Color3.fromRGB(255, 246, 208)}):Play()

			Tween.Completed:Connect(function()
				mochiPart.CFrame = CFrame.new(vec2Pos, vec2Pos + surfaceNormal) * CFrame.Angles(-math.pi/2, 0, 0)	
				TS:Create(mochiPart, TweenInfo.new(.18, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {Size = Vector3.new(poolSize * 2, 0.5, poolSize * 2)}):Play()
				task.delay(5, function()
					TS:Create(mochiPart, TweenInfo.new(.6, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {Size = Vector3.new(0,0,0)}):Play()
					--game.Debris:AddItem(mochiPart, .7)
					task.delay(.7, function()
						partCache:ReturnPart(mochiPart)
					end)
				end)
			end)
		else
			partCache:ReturnPart(mochiPart)
		end
	end
end

return function(HitboxPos, Character)
	local HRP = Character.HumanoidRootPart
	local mochiSize = Random.new():NextNumber(1, 2)
	local mochiPart = partCache:GetPart()
	mochiPart.Size = Vector3.new(mochiSize, mochiSize, mochiSize)

	local ray = Ray.new(HitboxPos + Vector3.new(0, 1, 0), Vector3.new(0, -50, 0))
	local hit, vec2Pos, surfaceNormal = workspace:FindPartOnRayWithIgnoreList(ray, {mochiPart, debrisFolder, Character})
	local angle	= math.rad(math.random(360))
	
	if hit then
		local endCF = CFrame.new(vec2Pos, vec2Pos + surfaceNormal) * CFrame.Angles(-math.pi/2, 0, 0) * CFrame.Angles(0, angle, 0)
		local p0 = HRP.Position
		local p2 = endCF.Position
		local p1 = CFrame.new((p0 + p2) / 2) * CFrame.new(0, Random.new():NextNumber(25, 45), 0).Position

		local distance = (p0 - p2).Magnitude
		local speed = 100
		
		local poolSize = Random.new():NextNumber(8, 14)

		mochiPart.Parent = debrisFolder

		local Tween = bezierTween.Create(mochiPart, {
			Waypoints = Waypoints.new(p0, p1, p2),
			EasingStyle = Enum.EasingStyle.Linear,
			EasingDirection = Enum.EasingDirection.In,
			Time = distance/speed
		})

		Tween:Play()
		TS:Create(mochiPart, TweenInfo.new(distance/speed, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {Color = Color3.fromRGB(255, 246, 208)}):Play()

		Tween.Completed:Connect(function()
			mochiPart.CFrame = CFrame.new(vec2Pos, vec2Pos + surfaceNormal) * CFrame.Angles(-math.pi/2, 0, 0) * CFrame.Angles(0, angle, 0)
			--mochiPart.Transparency = 1
			
			local mochiFloor = RS.FX.Mochi.C.MochiCFloor:Clone()
			mochiFloor.Size = Vector3.new(0, 1, 0)
			mochiFloor.CFrame = mochiPart.CFrame

			partCache:ReturnPart(mochiPart)

			mochiFloor.Parent = debrisFolder

			TS:Create(mochiFloor, TweenInfo.new(.18, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {Size = Vector3.new(poolSize * 2, 1.5, poolSize * 2)}):Play()

			local spikes = {
				RS.FX.Mochi.C.Spike1,
				RS.FX.Mochi.C.Spike2,
				RS.FX.Mochi.C.Spike3,
			}

			local mochiSpike = spikes[math.random(1, #spikes)]:Clone()
			mochiSpike.CFrame = mochiFloor.CFrame


			task.delay(0.7, function()
				mochiSpike.Size = Vector3.new(mochiFloor.Size.X * 0.45, 0.01, mochiFloor.Size.Z * 0.5)
				mochiSpike.Parent = debrisFolder
				local spikeHeight = Random.new():NextNumber(20, 35)
				--print(spikeHeight)
				TS:Create(mochiSpike, TweenInfo.new(0.17, Enum.EasingStyle.Back, Enum.EasingDirection.Out), {Size = Vector3.new(mochiSpike.Size.X, spikeHeight, mochiSpike.Size.Z), CFrame = CFrame.new(vec2Pos, vec2Pos + surfaceNormal) * CFrame.Angles(-math.pi/2, 0, 0) * CFrame.new(0, spikeHeight/2 - 2, 0)  * CFrame.Angles(0, angle, 0)}):Play()

				mochiExplosion(mochiSpike.Position, mochiSpike)
				for i, v in pairs(mochiFloor.ExpFX:GetChildren()) do
					v:Emit(v:GetAttribute("EmitCount"))
				end

				task.delay(1, function()
					--warn(mochiSpike.Size)
					TS:Create(mochiSpike, TweenInfo.new(5, Enum.EasingStyle.Back, Enum.EasingDirection.Out), {Size = mochiSpike.Size * 0.98, CFrame = CFrame.new(vec2Pos, vec2Pos + surfaceNormal) * CFrame.Angles(-math.pi/2, 0, 0) * CFrame.new(0, (mochiSpike.Size.Y * 0.98)/2 - 3, 0)}):Play()
					task.delay(3, function()
						TS:Create(mochiSpike, TweenInfo.new(0.45, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {Size = Vector3.new(poolSize * 2, 0.3, poolSize * 2), CFrame = CFrame.new(vec2Pos, vec2Pos + surfaceNormal) * CFrame.Angles(-math.pi/2, 0, 0)}):Play()
						task.delay(0.45, function()
							TS:Create(mochiSpike, TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {Size = Vector3.new()}):Play()
							game.Debris:AddItem(mochiSpike, 0.6)
						end)
					end)
				end)
			end)

			task.delay(6, function()
				TS:Create(mochiFloor, TweenInfo.new(.6, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {Size = Vector3.new(0,0,0)}):Play()
				game.Debris:AddItem(mochiFloor, .7)
			end)
		end)
	end
end
