local L=.1 local W=5 local f=.8 local w=4 local g=10 local y=20 local O=Instance.new("\070\111\108\100\101\114")O.Name="\082\097\105\110"O.Parent=game.Workspace.CurrentCamera local T=Instance.new("\080\097\114\116")T.Transparency=1 T.Size=Vector3.new(.2,.2,.2)T.Anchored=true T.CanCollide=false T.TopSurface="\083\109\111\111\116\104"T.BottomSurface="\083\109\111\111\116\104"local function Y()local w,O=math.random(-g,g),math.random(-g,g)local Y=math.random(0,y)local l=Instance.new("\065\116\116\097\099\104\109\101\110\116")l.Position=Vector3.new(w-L/2,Y,O)l.Parent=T local i=Instance.new("\065\116\116\097\099\104\109\101\110\116")i.Position=Vector3.new(w+L/2,Y,O)i.Parent=T local p=Instance.new("\084\114\097\105\108")p.Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,f,0),NumberSequenceKeypoint.new(1,1)})p.Attachment0=l p.Attachment1=i p.Lifetime=W/RainFallSpeed p.Parent=T end for L=1,w,1 do Y()end local l=game.Workspace.CurrentCamera local i=(game:GetService("\082\117\110\083\101\114\118\105\099\101")).RenderStepped local p=RainRadius/2 local j=T.Clone local q,k=CFrame.new,CFrame.Angles local t=math.random local d=i.Connect local x={}local Z={}local U=0 local b local function I(L,W,f,w,g,y,Y)local l,p=q(L,W,f)*Y,q(w,g,y)*Y local k=l.lerp local function t(L)return k(l,p,L)end local x=j(T)x.CFrame=l x.Parent=O local Z=(W-g)/RainFallSpeed local U=tick()local b b=d(i,function()local L=(tick()-U)/Z if L>1 then x:Destroy()b:disconnect()else x.CFrame=t(L)end end)end local function R(L,W)local f,w=L+t(-p,p),W+t(-p,p)local g,y=StartY,DefaultEndY for L=1,#Z,1 do local W=Z[L]if f>W[1]and(w>W[2]and(f<W[3]and w<W[4]))then y=W[5]break end end local O=(g-y)/RainFallSpeed local T,Y=(O*WindSpeedX)/2,(O*WindSpeedZ)/2 I(f-T,g,w-Y,f+T,y,w+Y,k(0,t(),0))end local function N()if b then b:Disconnect()end end local function s()N()b=d(i,function(L)local W=l.CFrame.p local f,w=W.X,W.Z for L=1,RainGroupsPerSecond*L,1 do R(f,w)end end)end function x.AddOverrideRegion(O,L,W,f,w,y)U=U+1 local T=U table.insert(Z,{L-g,W-g;f+g;w+g;y,T})return T end function x.RemoveOverrideRegion(W,L)for L,W in pairs(Z)do if W[6]==L then table.remove(Z,L)end end end function x.StartRain(L)s()end function x.StopRain(L)N()end function x.SetWindSpeed(f,L,W)WindSpeedX=L WindSpeedZ=W end function x.GetWindSpeed(L)return WindSpeedX,WindSpeedZ end function x.SetRainGroupsPerSecond(W,L)RainGroupsPerSecond=L end function x.GetRainGroupsPerSecond(L)return RainGroupsPerSecond end return x

local RainThickness = 0.1 --Thickness of the rain drops in studs
local RainLength = 5 --Length of the rain drop in studs
local RainTransparency = 0.8 --Transparency of the rain
local TrailPerPart = 4 --Amount of trails adorned to one part
local TrailPartRadius = 10 --Max radius from the part a trail can be adorned
local TrailYOffset = 20 --Max Y offset a trail can have





local RainParent = Instance.new("Folder")
RainParent.Name = "Rain"
RainParent.Parent = game.Workspace.CurrentCamera

local RainPart = Instance.new("Part")
RainPart.Transparency = 1
RainPart.Size = Vector3.new(0.2,0.2,0.2)
RainPart.Anchored = true
RainPart.CanCollide = false
RainPart.TopSurface = "Smooth"
RainPart.BottomSurface = "Smooth"

local function AdornRandomTrailToPart()
	local RandomCenterX,RandomCenterZ = math.random(-TrailPartRadius,TrailPartRadius),math.random(-TrailPartRadius,TrailPartRadius)
	local YOffset = math.random(0,TrailYOffset)
	local Attahcment1 = Instance.new("Attachment")
	Attahcment1.Position = Vector3.new(RandomCenterX - RainThickness/2,YOffset,RandomCenterZ)
	Attahcment1.Parent = RainPart
	
	local Attahcment2 = Instance.new("Attachment")
	Attahcment2.Position = Vector3.new(RandomCenterX + RainThickness/2,YOffset,RandomCenterZ)
	Attahcment2.Parent = RainPart
	
	local Trail = Instance.new("Trail")
	Trail.Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0,RainTransparency,0),NumberSequenceKeypoint.new(1,1)})
	Trail.Attachment0 = Attahcment1
	Trail.Attachment1 = Attahcment2
	Trail.Lifetime = RainLength/RainFallSpeed
	Trail.Parent = RainPart
end

for _ = 1, TrailPerPart do
	AdornRandomTrailToPart()
end



local Camera = game.Workspace.CurrentCamera
local RenderStepped = game:GetService("RunService").RenderStepped

local RainRadiusDiv2 = RainRadius/2
local RainPartClone = RainPart.Clone
local CFramenew,CFrameAngles = CFrame.new,CFrame.Angles
local random = math.random
local RenderSteppedConnect = RenderStepped.Connect

local RainAPI = {}
local OverridenRegions = {}
local CurrentOverrideId = 0
local CurrentCreateEvent

local function CreateRainDrop(StartX,StartY,StartZ,EndX,EndY,EndZ,Rotation)
	local StartCF,EndCF = CFramenew(StartX,StartY,StartZ) * Rotation,CFramenew(EndX,EndY,EndZ) * Rotation
	local LerpFunction = StartCF.lerp
	
	local function GetCFrame(Alpha)
		return LerpFunction(StartCF,EndCF,Alpha)
	end
	
	local NewDrop = RainPartClone(RainPart)
	NewDrop.CFrame = StartCF
	NewDrop.Parent = RainParent
	
	local FallTime = (StartY - EndY)/RainFallSpeed
	local StartTime = tick()
	local RenderSteppedEvent
	RenderSteppedEvent = RenderSteppedConnect(RenderStepped,function()
		local Alpha = (tick() - StartTime)/FallTime
		if Alpha > 1 then
			NewDrop:Destroy()
			RenderSteppedEvent:disconnect()
		else
			NewDrop.CFrame = GetCFrame(Alpha)
		end
	end)
end

local function SpawnRainDrop(CenterX,CenterZ)
	local X,Z = CenterX + random(-RainRadiusDiv2,RainRadiusDiv2),CenterZ + random(-RainRadiusDiv2,RainRadiusDiv2)
	local StartY,EndY = StartY,DefaultEndY
	
	for i = 1, #OverridenRegions do
		local RegionData = OverridenRegions[i]
		if X > RegionData[1] and Z > RegionData[2] and X < RegionData[3] and Z < RegionData[4] then
			EndY = RegionData[5]
			break
		end
	end
	
	local FallTime = (StartY - EndY)/RainFallSpeed
	local WindOffsetX,WindOffsetZ = (FallTime * WindSpeedX)/2,(FallTime * WindSpeedZ)/2
	CreateRainDrop(X - WindOffsetX,StartY,Z - WindOffsetZ,X + WindOffsetX,EndY,Z + WindOffsetZ,CFrameAngles(0,random(),0))
end


local function StopRain()
	if CurrentCreateEvent then CurrentCreateEvent:Disconnect() end
end

local function StartRain()
	StopRain()
	CurrentCreateEvent = RenderSteppedConnect(RenderStepped,function(Delta)
		local CameraPosition = Camera.CFrame.p
		local X,Z = CameraPosition.X,CameraPosition.Z
		for _ = 1, RainGroupsPerSecond * Delta do
			SpawnRainDrop(X,Z)
		end
	end)
end





function RainAPI:AddOverrideRegion(X1,Z1,X2,Z2,OverrideY)
	CurrentOverrideId = CurrentOverrideId + 1
	local Id = CurrentOverrideId
	
	table.insert(OverridenRegions,{X1 - TrailPartRadius,Z1 - TrailPartRadius,X2 + TrailPartRadius,Z2 + TrailPartRadius,OverrideY,Id})
	return Id
end

function RainAPI:RemoveOverrideRegion(Id)
	for i,RegionData in pairs(OverridenRegions) do
		if RegionData[6] == i  then
			table.remove(OverridenRegions,i)
		end
	end
end

function RainAPI:StartRain()
	StartRain()
end

function RainAPI:StopRain()
	StopRain()
end

function RainAPI:SetWindSpeed(X,Z)
	WindSpeedX = X
	WindSpeedZ = Z
end

function RainAPI:GetWindSpeed()
	return WindSpeedX,WindSpeedZ
end

function RainAPI:SetRainGroupsPerSecond(NewRainGroupsPerSecond)
	RainGroupsPerSecond = NewRainGroupsPerSecond
end

function RainAPI:GetRainGroupsPerSecond()
	return RainGroupsPerSecond
end

return RainAPI
