csmit195

Roblox Rain Library

Jun 12th, 2019
747
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 26.03 KB | None | 0 0
  1. --SynapseX Decompiler
  2.  
  3. local MIN_SIZE = Vector3.new(0.05, 0.05, 0.05)
  4. local RAIN_DEFAULT_COLOR = Color3.new(1, 1, 1)
  5. local RAIN_DEFAULT_TRANSPARENCY = 0
  6. local RAIN_DEFAULT_SPEEDRATIO = 1
  7. local RAIN_DEFAULT_INTENSITYRATIO = 1
  8. local RAIN_DEFAULT_LIGHTEMISSION = 0.05
  9. local RAIN_DEFAULT_LIGHTINFLUENCE = 0.9
  10. local RAIN_DEFAULT_DIRECTION = Vector3.new(0, -1, 0)
  11. local RAIN_TRANSPARENCY_T1 = 0.25
  12. local RAIN_TRANSPARENCY_T2 = 0.75
  13. local RAIN_SCANHEIGHT = 1000
  14. local RAIN_EMITTER_DIM_DEFAULT = 40
  15. local RAIN_EMITTER_DIM_MAXFORWARD = 100
  16. local RAIN_EMITTER_UP_MODIFIER = 20
  17. local RAIN_SOUND_ASSET = "rbxassetid://1516791621"
  18. local RAIN_SOUND_BASEVOLUME = 0.2
  19. local RAIN_SOUND_FADEIN_TIME = 1
  20. local RAIN_SOUND_FADEOUT_TIME = 1
  21. local RAIN_STRAIGHT_ASSET = "rbxassetid://1822883048"
  22. local RAIN_STRAIGHT_ALPHA_LOW = 0.7
  23. local RAIN_STRAIGHT_SIZE = NumberSequence.new(10)
  24. local RAIN_STRAIGHT_LIFETIME = NumberRange.new(0.8)
  25. local RAIN_STRAIGHT_MAX_RATE = 600
  26. local RAIN_STRAIGHT_MAX_SPEED = 60
  27. local RAIN_TOPDOWN_ASSET = "rbxassetid://1822856633"
  28. local RAIN_TOPDOWN_ALPHA_LOW = 0.85
  29. local RAIN_TOPDOWN_SIZE = NumberSequence.new({
  30.     NumberSequenceKeypoint.new(0, 5.33, 2.75),
  31.     NumberSequenceKeypoint.new(1, 5.33, 2.75)
  32. })
  33. local RAIN_TOPDOWN_LIFETIME = NumberRange.new(0.8)
  34. local RAIN_TOPDOWN_ROTATION = NumberRange.new(0, 360)
  35. local RAIN_TOPDOWN_MAX_RATE = 600
  36. local RAIN_TOPDOWN_MAX_SPEED = 60
  37. local RAIN_SPLASH_ASSET = "rbxassetid://1822856633"
  38. local RAIN_SPLASH_ALPHA_LOW = 0.6
  39. local RAIN_SPLASH_SIZE = NumberSequence.new({
  40.     NumberSequenceKeypoint.new(0, 0),
  41.     NumberSequenceKeypoint.new(0.4, 3),
  42.     NumberSequenceKeypoint.new(1, 0)
  43. })
  44. local RAIN_SPLASH_LIFETIME = NumberRange.new(0.1, 0.15)
  45. local RAIN_SPLASH_ROTATION = NumberRange.new(0, 360)
  46. local RAIN_SPLASH_NUM = 20
  47. local RAIN_SPLASH_CORRECTION_Y = 0.5
  48. local RAIN_SPLASH_STRAIGHT_OFFSET_Y = 50
  49. local RAIN_NOSPLASH_STRAIGHT_OFFSET_Y_MIN = 20
  50. local RAIN_NOSPLASH_STRAIGHT_OFFSET_Y_MAX = 100
  51. local RAIN_OCCLUDED_MINSPEED = 70
  52. local RAIN_OCCLUDED_MAXSPEED = 100
  53. local RAIN_OCCLUDED_SPREAD = Vector2.new(10, 10)
  54. local RAIN_OCCLUDED_MAXINTENSITY = 2
  55. local RAIN_OCCLUDECHECK_OFFSET_Y = 500
  56. local RAIN_OCCLUDECHECK_OFFSET_XZ_MIN = -100
  57. local RAIN_OCCLUDECHECK_OFFSET_XZ_MAX = 100
  58. local RAIN_OCCLUDECHECK_SCAN_Y = 550
  59. local RAIN_UPDATE_PERIOD = 6
  60. local RAIN_VOLUME_SCAN_RADIUS = 35
  61. local RAIN_VOLUME_SCAN_GRID = {
  62.     Vector3.new(0.141421363, 0, 0.141421363),
  63.     Vector3.new(-0.141421363, 0, 0.141421363),
  64.     Vector3.new(-0.141421363, 0, -0.141421363),
  65.     Vector3.new(0.141421363, 0, -0.141421363),
  66.     Vector3.new(0.400000006, 0, 0),
  67.     Vector3.new(0.282842726, 0, 0.282842726),
  68.     Vector3.new(2.44929371E-17, 0, 0.400000006),
  69.     Vector3.new(-0.282842726, 0, 0.282842726),
  70.     Vector3.new(-0.400000006, 0, 4.89858741E-17),
  71.     Vector3.new(-0.282842726, 0, -0.282842726),
  72.     Vector3.new(-7.34788045E-17, 0, -0.400000006),
  73.     Vector3.new(0.282842726, 0, -0.282842726),
  74.     Vector3.new(0.600000024, 0, 0),
  75.     Vector3.new(0.485410213, 0, 0.352671146),
  76.     Vector3.new(0.185410202, 0, 0.570633948),
  77.     Vector3.new(-0.185410202, 0, 0.570633948),
  78.     Vector3.new(-0.485410213, 0, 0.352671146),
  79.     Vector3.new(-0.600000024, 0, 7.34788112E-17),
  80.     Vector3.new(-0.485410213, 0, -0.352671146),
  81.     Vector3.new(-0.185410202, 0, -0.570633948),
  82.     Vector3.new(0.185410202, 0, -0.570633948),
  83.     Vector3.new(0.485410213, 0, -0.352671146),
  84.     Vector3.new(0.772740662, 0, 0.207055241),
  85.     Vector3.new(0.565685451, 0, 0.565685451),
  86.     Vector3.new(0.207055241, 0, 0.772740662),
  87.     Vector3.new(-0.207055241, 0, 0.772740662),
  88.     Vector3.new(-0.565685451, 0, 0.565685451),
  89.     Vector3.new(-0.772740662, 0, 0.207055241),
  90.     Vector3.new(-0.772740662, 0, -0.207055241),
  91.     Vector3.new(-0.565685451, 0, -0.565685451),
  92.     Vector3.new(-0.207055241, 0, -0.772740662),
  93.     Vector3.new(0.207055241, 0, -0.772740662),
  94.     Vector3.new(0.565685451, 0, -0.565685451),
  95.     Vector3.new(0.772740662, 0, -0.207055241)
  96. }
  97. local CollisionMode = {
  98.     None = 0,
  99.     Whitelist = 1,
  100.     Blacklist = 2,
  101.     Function = 3
  102. }
  103. local Players = game:GetService("Players")
  104. local TweenService = game:GetService("TweenService")
  105. local RunService = game:GetService("RunService")
  106. local GlobalModifier = Instance.new("NumberValue")
  107. GlobalModifier.Value = 1
  108. local connections = {}
  109. local disabled = true
  110. local rainDirection = RAIN_DEFAULT_DIRECTION
  111. local currentCeiling
  112. local collisionMode = CollisionMode.None
  113. local collisionList, collisionFunc
  114. local straightLowAlpha = 1
  115. local topdownLowAlpha = 1
  116. local intensityOccludedRain = 0
  117. local numSplashes = 0
  118. local volumeTarget = 0
  119. local v3 = Vector3.new
  120. local NSK010 = NumberSequenceKeypoint.new(0, 1, 0)
  121. local NSK110 = NumberSequenceKeypoint.new(1, 1, 0)
  122. local volumeScanGrid = {}
  123. for _, v in pairs(RAIN_VOLUME_SCAN_GRID) do
  124.     table.insert(volumeScanGrid, v * RAIN_VOLUME_SCAN_RADIUS)
  125. end
  126. table.sort(volumeScanGrid, function(a, b)
  127.     return a.magnitude < b.magnitude
  128. end)
  129. local SoundGroup = Instance.new("SoundGroup")
  130. SoundGroup.Name = "__RainSoundGroup"
  131. SoundGroup.Volume = RAIN_SOUND_BASEVOLUME
  132. SoundGroup.Archivable = false
  133. local Sound = Instance.new("Sound")
  134. Sound.Name = "RainSound"
  135. Sound.Volume = volumeTarget
  136. Sound.SoundId = RAIN_SOUND_ASSET
  137. Sound.Looped = true
  138. Sound.SoundGroup = SoundGroup
  139. Sound.Parent = SoundGroup
  140. Sound.Archivable = false
  141. local Emitter
  142. Emitter = Instance.new("Part")
  143. Emitter.Transparency = 1
  144. Emitter.Anchored = true
  145. Emitter.CanCollide = false
  146. Emitter.Locked = false
  147. Emitter.Archivable = false
  148. Emitter.TopSurface = Enum.SurfaceType.Smooth
  149. Emitter.BottomSurface = Enum.SurfaceType.Smooth
  150. Emitter.Name = "__RainEmitter"
  151. Emitter.Size = MIN_SIZE
  152. Emitter.Archivable = false
  153. do
  154.     local straight = Instance.new("ParticleEmitter")
  155.     straight.Name = "RainStraight"
  156.     straight.LightEmission = RAIN_DEFAULT_LIGHTEMISSION
  157.     straight.LightInfluence = RAIN_DEFAULT_LIGHTINFLUENCE
  158.     straight.Size = RAIN_STRAIGHT_SIZE
  159.     straight.Texture = RAIN_STRAIGHT_ASSET
  160.     straight.LockedToPart = true
  161.     straight.Enabled = false
  162.     straight.Lifetime = RAIN_STRAIGHT_LIFETIME
  163.     straight.Rate = RAIN_STRAIGHT_MAX_RATE
  164.     straight.Speed = NumberRange.new(RAIN_STRAIGHT_MAX_SPEED)
  165.     straight.EmissionDirection = Enum.NormalId.Bottom
  166.     straight.Parent = Emitter
  167.     local topdown = Instance.new("ParticleEmitter")
  168.     topdown.Name = "RainTopDown"
  169.     topdown.LightEmission = RAIN_DEFAULT_LIGHTEMISSION
  170.     topdown.LightInfluence = RAIN_DEFAULT_LIGHTINFLUENCE
  171.     topdown.Size = RAIN_TOPDOWN_SIZE
  172.     topdown.Texture = RAIN_TOPDOWN_ASSET
  173.     topdown.LockedToPart = true
  174.     topdown.Enabled = false
  175.     topdown.Rotation = RAIN_TOPDOWN_ROTATION
  176.     topdown.Lifetime = RAIN_TOPDOWN_LIFETIME
  177.     topdown.Rate = RAIN_TOPDOWN_MAX_RATE
  178.     topdown.Speed = NumberRange.new(RAIN_TOPDOWN_MAX_SPEED)
  179.     topdown.EmissionDirection = Enum.NormalId.Bottom
  180.     topdown.Parent = Emitter
  181. end
  182. local splashAttachments, rainAttachments
  183. splashAttachments = {}
  184. rainAttachments = {}
  185. for i = 1, RAIN_SPLASH_NUM do
  186.     local splashAttachment = Instance.new("Attachment")
  187.     splashAttachment.Name = "__RainSplashAttachment"
  188.     local splash = Instance.new("ParticleEmitter")
  189.     splash.LightEmission = RAIN_DEFAULT_LIGHTEMISSION
  190.     splash.LightInfluence = RAIN_DEFAULT_LIGHTINFLUENCE
  191.     splash.Size = RAIN_SPLASH_SIZE
  192.     splash.Texture = RAIN_SPLASH_ASSET
  193.     splash.Rotation = RAIN_SPLASH_ROTATION
  194.     splash.Lifetime = RAIN_SPLASH_LIFETIME
  195.     splash.Transparency = NumberSequence.new({
  196.         NSK010,
  197.         NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T1, RAIN_SPLASH_ALPHA_LOW, 0),
  198.         NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T2, RAIN_SPLASH_ALPHA_LOW, 0),
  199.         NSK110
  200.     })
  201.     splash.Enabled = false
  202.     splash.Rate = 0
  203.     splash.Speed = NumberRange.new(0)
  204.     splash.Name = "RainSplash"
  205.     splash.Parent = splashAttachment
  206.     splashAttachment.Archivable = false
  207.     table.insert(splashAttachments, splashAttachment)
  208.     local rainAttachment = Instance.new("Attachment")
  209.     rainAttachment.Name = "__RainOccludedAttachment"
  210.     local straightOccluded = Emitter.RainStraight:Clone()
  211.     straightOccluded.Speed = NumberRange.new(RAIN_OCCLUDED_MINSPEED, RAIN_OCCLUDED_MAXSPEED)
  212.     straightOccluded.SpreadAngle = RAIN_OCCLUDED_SPREAD
  213.     straightOccluded.LockedToPart = false
  214.     straightOccluded.Enabled = false
  215.     straightOccluded.Parent = rainAttachment
  216.     local topdownOccluded = Emitter.RainTopDown:Clone()
  217.     topdownOccluded.Speed = NumberRange.new(RAIN_OCCLUDED_MINSPEED, RAIN_OCCLUDED_MAXSPEED)
  218.     topdownOccluded.SpreadAngle = RAIN_OCCLUDED_SPREAD
  219.     topdownOccluded.LockedToPart = false
  220.     topdownOccluded.Enabled = false
  221.     topdownOccluded.Parent = rainAttachment
  222.     rainAttachment.Archivable = false
  223.     table.insert(rainAttachments, rainAttachment)
  224. end
  225. local ignoreEmitterList = {Emitter}
  226. local raycastFunctions = {
  227.     [CollisionMode.None] = function(ray, ignoreCharacter)
  228.         return workspace:FindPartOnRayWithIgnoreList(ray, ignoreCharacter and {
  229.             Emitter,
  230.             Players.LocalPlayer and Players.LocalPlayer.Character
  231.         } or ignoreEmitterList)
  232.     end,
  233.     [CollisionMode.Blacklist] = function(ray)
  234.         return workspace:FindPartOnRayWithIgnoreList(ray, collisionList)
  235.     end,
  236.     [CollisionMode.Whitelist] = function(ray)
  237.         return workspace:FindPartOnRayWithWhitelist(ray, collisionList)
  238.     end,
  239.     [CollisionMode.Function] = function(ray)
  240.         local destination = ray.Origin + ray.Direction
  241.         while ray.Direction.magnitude > 0.001 do
  242.             local part, pos, norm, mat = workspace:FindPartOnRayWithIgnoreList(ray, ignoreEmitterList)
  243.             if not part or collisionFunc(part) then
  244.                 return part, pos, norm, mat
  245.             end
  246.             local start = pos + ray.Direction.Unit * 0.001
  247.             ray = Ray.new(start, destination - start)
  248.         end
  249.     end
  250. }
  251. local raycast = raycastFunctions[collisionMode]
  252. local function connectLoop()
  253.     local rand = Random.new()
  254.     local inside = true
  255.     local frame = RAIN_UPDATE_PERIOD
  256.     table.insert(connections, RunService.RenderStepped:connect(function()
  257.         local part, position = raycast(Ray.new(workspace.CurrentCamera.CFrame.p, -rainDirection * RAIN_SCANHEIGHT), true)
  258.         if (not currentCeiling or workspace.CurrentCamera.CFrame.p.y <= currentCeiling) and not part then
  259.             if volumeTarget < 1 and not disabled then
  260.                 volumeTarget = 1
  261.                 TweenService:Create(Sound, TweenInfo.new(0.5), {Volume = 1}):Play()
  262.             end
  263.             frame = RAIN_UPDATE_PERIOD
  264.             local t = math.abs(workspace.CurrentCamera.CFrame.lookVector:Dot(rainDirection))
  265.             local center = workspace.CurrentCamera.CFrame.p
  266.             local right = workspace.CurrentCamera.CFrame.lookVector:Cross(-rainDirection)
  267.             right = right.magnitude > 0.001 and right.unit or -rainDirection
  268.             local forward = rainDirection:Cross(right).unit
  269.             Emitter.Size = v3(RAIN_EMITTER_DIM_DEFAULT, RAIN_EMITTER_DIM_DEFAULT, RAIN_EMITTER_DIM_DEFAULT + (1 - t) * (RAIN_EMITTER_DIM_MAXFORWARD - RAIN_EMITTER_DIM_DEFAULT))
  270.             Emitter.CFrame = CFrame.new(center.x, center.y, center.z, right.x, -rainDirection.x, forward.x, right.y, -rainDirection.y, forward.y, right.z, -rainDirection.z, forward.z) + (1 - t) * workspace.CurrentCamera.CFrame.lookVector * Emitter.Size.Z / 3 - t * rainDirection * RAIN_EMITTER_UP_MODIFIER
  271.             Emitter.RainStraight.Enabled = true
  272.             Emitter.RainTopDown.Enabled = true
  273.             inside = false
  274.         else
  275.             Emitter.RainStraight.Enabled = false
  276.             Emitter.RainTopDown.Enabled = false
  277.             inside = true
  278.         end
  279.     end))
  280.     local signal = RunService:IsRunning() and RunService.Stepped or RunService.RenderStepped
  281.     table.insert(connections, signal:connect(function()
  282.         frame = frame + 1
  283.         if frame >= RAIN_UPDATE_PERIOD then
  284.             local t = math.abs(workspace.CurrentCamera.CFrame.lookVector:Dot(rainDirection))
  285.             local straightSequence = NumberSequence.new({
  286.                 NSK010,
  287.                 NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T1, (1 - t) * straightLowAlpha + t, 0),
  288.                 NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T2, (1 - t) * straightLowAlpha + t, 0),
  289.                 NSK110
  290.             })
  291.             local topdownSequence = NumberSequence.new({
  292.                 NSK010,
  293.                 NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T1, t * topdownLowAlpha + (1 - t), 0),
  294.                 NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T2, t * topdownLowAlpha + (1 - t), 0),
  295.                 NSK110
  296.             })
  297.             local mapped = workspace.Camera.CFrame:inverse() * (workspace.Camera.CFrame.p - rainDirection)
  298.             local straightRotation = NumberRange.new(math.deg(math.atan2(-mapped.x, mapped.y)))
  299.             if inside then
  300.                 for _, v in pairs(rainAttachments) do
  301.                     v.RainStraight.Transparency = straightSequence
  302.                     v.RainStraight.Rotation = straightRotation
  303.                     v.RainTopDown.Transparency = topdownSequence
  304.                 end
  305.                 if not disabled then
  306.                     local volume = 0
  307.                     if not currentCeiling or workspace.CurrentCamera.CFrame.p.y <= currentCeiling then
  308.                         local minDistance = RAIN_VOLUME_SCAN_RADIUS
  309.                         local rayDirection = -rainDirection * RAIN_SCANHEIGHT
  310.                         for i = 1, #volumeScanGrid do
  311.                             if not raycast(Ray.new(workspace.CurrentCamera.CFrame * volumeScanGrid[i], rayDirection), true) then
  312.                                 minDistance = volumeScanGrid[i].magnitude
  313.                                 break
  314.                             end
  315.                         end
  316.                         volume = 1 - minDistance / RAIN_VOLUME_SCAN_RADIUS
  317.                     end
  318.                     if math.abs(volume - volumeTarget) > 0.01 then
  319.                         volumeTarget = volume
  320.                         TweenService:Create(Sound, TweenInfo.new(1), {Volume = volumeTarget}):Play()
  321.                     end
  322.                 end
  323.             else
  324.                 Emitter.RainStraight.Transparency = straightSequence
  325.                 Emitter.RainStraight.Rotation = straightRotation
  326.                 Emitter.RainTopDown.Transparency = topdownSequence
  327.             end
  328.             frame = 0
  329.         end
  330.         local center = workspace.CurrentCamera.CFrame.p
  331.         local right = workspace.CurrentCamera.CFrame.lookVector:Cross(-rainDirection)
  332.         right = right.magnitude > 0.001 and right.unit or -rainDirection
  333.         local forward = rainDirection:Cross(right).unit
  334.         local transform = CFrame.new(center.x, center.y, center.z, right.x, -rainDirection.x, forward.x, right.y, -rainDirection.y, forward.y, right.z, -rainDirection.z, forward.z)
  335.         local rayDirection = rainDirection * RAIN_OCCLUDECHECK_SCAN_Y
  336.         for i = 1, numSplashes do
  337.             local splashAttachment = splashAttachments[i]
  338.             local rainAttachment = rainAttachments[i]
  339.             local x = rand:NextNumber(RAIN_OCCLUDECHECK_OFFSET_XZ_MIN, RAIN_OCCLUDECHECK_OFFSET_XZ_MAX)
  340.             local z = rand:NextNumber(RAIN_OCCLUDECHECK_OFFSET_XZ_MIN, RAIN_OCCLUDECHECK_OFFSET_XZ_MAX)
  341.             local part, position, normal = raycast(Ray.new(transform * v3(x, RAIN_OCCLUDECHECK_OFFSET_Y, z), rayDirection))
  342.             if part then
  343.                 splashAttachment.Position = position + normal * RAIN_SPLASH_CORRECTION_Y
  344.                 splashAttachment.RainSplash:Emit(1)
  345.                 if inside then
  346.                     local corrected = position - rainDirection * RAIN_SPLASH_STRAIGHT_OFFSET_Y
  347.                     if currentCeiling and corrected.Y > currentCeiling and 0 > rainDirection.Y then
  348.                         corrected = corrected + rainDirection * (currentCeiling - corrected.Y) / rainDirection.Y
  349.                     end
  350.                     rainAttachment.CFrame = transform - transform.p + corrected
  351.                     rainAttachment.RainStraight:Emit(intensityOccludedRain)
  352.                     rainAttachment.RainTopDown:Emit(intensityOccludedRain)
  353.                 end
  354.             elseif inside then
  355.                 local corrected = transform * v3(x, rand:NextNumber(RAIN_NOSPLASH_STRAIGHT_OFFSET_Y_MIN, RAIN_NOSPLASH_STRAIGHT_OFFSET_Y_MAX), z)
  356.                 if currentCeiling and corrected.Y > currentCeiling and 0 > rainDirection.Y then
  357.                     corrected = corrected + rainDirection * (currentCeiling - corrected.Y) / rainDirection.Y
  358.                 end
  359.                 rainAttachment.CFrame = transform - transform.p + corrected
  360.                 rainAttachment.RainStraight:Emit(intensityOccludedRain)
  361.                 rainAttachment.RainTopDown:Emit(intensityOccludedRain)
  362.             end
  363.         end
  364.     end))
  365. end
  366. local function disconnectLoop()
  367.     if #connections > 0 then
  368.         for _, v in pairs(connections) do
  369.             v:disconnect()
  370.         end
  371.         connections = {}
  372.     end
  373. end
  374. local function disableSound(tweenInfo)
  375.     volumeTarget = 0
  376.     local tween = TweenService:Create(Sound, tweenInfo, {Volume = 0})
  377.     tween.Completed:connect(function(state)
  378.         if state == Enum.PlaybackState.Completed then
  379.             Sound:Stop()
  380.         end
  381.         tween:Destroy()
  382.     end)
  383.     tween:Play()
  384. end
  385. local function disable()
  386.     disconnectLoop()
  387.     Emitter.RainStraight.Enabled = false
  388.     Emitter.RainTopDown.Enabled = false
  389.     Emitter.Size = MIN_SIZE
  390.     if not disabled then
  391.         disableSound(TweenInfo.new(RAIN_SOUND_FADEOUT_TIME))
  392.     end
  393. end
  394. local makeProperty = function(valueObjectClass, defaultValue, setter)
  395.     local valueObject = Instance.new(valueObjectClass)
  396.     if defaultValue then
  397.         valueObject.Value = defaultValue
  398.     end
  399.     valueObject.Changed:connect(setter)
  400.     setter(valueObject.Value)
  401.     return valueObject
  402. end
  403. local Color = makeProperty("Color3Value", RAIN_DEFAULT_COLOR, function(value)
  404.     local value = ColorSequence.new(value)
  405.     Emitter.RainStraight.Color = value
  406.     Emitter.RainTopDown.Color = value
  407.     for _, v in pairs(splashAttachments) do
  408.         v.RainSplash.Color = value
  409.     end
  410.     for _, v in pairs(rainAttachments) do
  411.         v.RainStraight.Color = value
  412.         v.RainTopDown.Color = value
  413.     end
  414. end)
  415. local function updateTransparency(value)
  416.     local opacity = (1 - value) * (1 - GlobalModifier.Value)
  417.     local transparency = 1 - opacity
  418.     straightLowAlpha = RAIN_STRAIGHT_ALPHA_LOW * opacity + transparency
  419.     topdownLowAlpha = RAIN_TOPDOWN_ALPHA_LOW * opacity + transparency
  420.     local splashSequence = NumberSequence.new({
  421.         NSK010,
  422.         NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T1, opacity * RAIN_SPLASH_ALPHA_LOW + transparency, 0),
  423.         NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T2, opacity * RAIN_SPLASH_ALPHA_LOW + transparency, 0),
  424.         NSK110
  425.     })
  426.     for _, v in pairs(splashAttachments) do
  427.         v.RainSplash.Transparency = splashSequence
  428.     end
  429. end
  430. local Transparency = makeProperty("NumberValue", RAIN_DEFAULT_TRANSPARENCY, updateTransparency)
  431. GlobalModifier.Changed:connect(updateTransparency)
  432. local SpeedRatio = makeProperty("NumberValue", RAIN_DEFAULT_SPEEDRATIO, function(value)
  433.     Emitter.RainStraight.Speed = NumberRange.new(value * RAIN_STRAIGHT_MAX_SPEED)
  434.     Emitter.RainTopDown.Speed = NumberRange.new(value * RAIN_TOPDOWN_MAX_SPEED)
  435. end)
  436. local IntensityRatio = makeProperty("NumberValue", RAIN_DEFAULT_INTENSITYRATIO, function(value)
  437.     Emitter.RainStraight.Rate = RAIN_STRAIGHT_MAX_RATE * value
  438.     Emitter.RainTopDown.Rate = RAIN_TOPDOWN_MAX_RATE * value
  439.     intensityOccludedRain = math.ceil(RAIN_OCCLUDED_MAXINTENSITY * value)
  440.     numSplashes = RAIN_SPLASH_NUM * value
  441. end)
  442. local LightEmission = makeProperty("NumberValue", RAIN_DEFAULT_LIGHTEMISSION, function(value)
  443.     Emitter.RainStraight.LightEmission = value
  444.     Emitter.RainTopDown.LightEmission = value
  445.     for _, v in pairs(rainAttachments) do
  446.         v.RainStraight.LightEmission = value
  447.         v.RainTopDown.LightEmission = value
  448.     end
  449.     for _, v in pairs(splashAttachments) do
  450.         v.RainSplash.LightEmission = value
  451.     end
  452. end)
  453. local LightInfluence = makeProperty("NumberValue", RAIN_DEFAULT_LIGHTINFLUENCE, function(value)
  454.     Emitter.RainStraight.LightInfluence = value
  455.     Emitter.RainTopDown.LightInfluence = value
  456.     for _, v in pairs(rainAttachments) do
  457.         v.RainStraight.LightInfluence = value
  458.         v.RainTopDown.LightInfluence = value
  459.     end
  460.     for _, v in pairs(splashAttachments) do
  461.         v.RainSplash.LightInfluence = value
  462.     end
  463. end)
  464. local RainDirection = makeProperty("Vector3Value", RAIN_DEFAULT_DIRECTION, function(value)
  465.     if value.magnitude > 0.001 then
  466.         rainDirection = value.unit
  467.     end
  468. end)
  469. local Rain = {}
  470. Rain.CollisionMode = CollisionMode
  471. function Rain:Enable(tweenInfo)
  472.     if tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
  473.         error("bad argument #1 to 'Enable' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
  474.     end
  475.     disconnectLoop()
  476.     Emitter.RainStraight.Enabled = true
  477.     Emitter.RainTopDown.Enabled = true
  478.     Emitter.Parent = workspace.CurrentCamera
  479.     for i = 1, RAIN_SPLASH_NUM do
  480.         splashAttachments[i].Parent = workspace.Terrain
  481.         rainAttachments[i].Parent = workspace.Terrain
  482.     end
  483.     if RunService:IsRunning() then
  484.         SoundGroup.Parent = game:GetService("SoundService")
  485.     end
  486.     connectLoop()
  487.     if tweenInfo then
  488.         TweenService:Create(GlobalModifier, tweenInfo, {Value = 0}):Play()
  489.     else
  490.         GlobalModifier.Value = 0
  491.     end
  492.     if not Sound.Playing then
  493.         Sound:Play()
  494.         Sound.TimePosition = math.random() * Sound.TimeLength
  495.     end
  496.     disabled = false
  497. end
  498. function Rain:Disable(tweenInfo)
  499.     if tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
  500.         error("bad argument #1 to 'Disable' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
  501.     end
  502.     if tweenInfo then
  503.         do
  504.             local tween = TweenService:Create(GlobalModifier, tweenInfo, {Value = 1})
  505.             tween.Completed:connect(function(state)
  506.                 if state == Enum.PlaybackState.Completed then
  507.                     disable()
  508.                 end
  509.                 tween:Destroy()
  510.             end)
  511.             tween:Play()
  512.             disableSound(tweenInfo)
  513.         end
  514.     else
  515.         GlobalModifier.Value = 1
  516.         disable()
  517.     end
  518.     disabled = true
  519. end
  520. function Rain:SetColor(value, tweenInfo)
  521.     if typeof(value) ~= "Color3" then
  522.         error("bad argument #1 to 'SetColor' (Color3 expected, got " .. typeof(value) .. ")", 2)
  523.     elseif tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
  524.         error("bad argument #2 to 'SetColor' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
  525.     end
  526.     if tweenInfo then
  527.         TweenService:Create(Color, tweenInfo, {Value = value}):Play()
  528.     else
  529.         Color.Value = value
  530.     end
  531. end
  532. local function makeRatioSetter(methodName, valueObject)
  533.     return function(_, value, tweenInfo)
  534.         if typeof(value) ~= "number" then
  535.             error("bad argument #1 to '" .. methodName .. "' (number expected, got " .. typeof(value) .. ")", 2)
  536.         elseif tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
  537.             error("bad argument #2 to '" .. methodName .. "' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
  538.         end
  539.         value = math.clamp(value, 0, 1)
  540.         if tweenInfo then
  541.             TweenService:Create(valueObject, tweenInfo, {Value = value}):Play()
  542.         else
  543.             valueObject.Value = value
  544.         end
  545.     end
  546. end
  547. Rain.SetTransparency = makeRatioSetter("SetTransparency", Transparency)
  548. Rain.SetSpeedRatio = makeRatioSetter("SetSpeedRatio", SpeedRatio)
  549. Rain.SetIntensityRatio = makeRatioSetter("SetIntensityRatio", IntensityRatio)
  550. Rain.SetLightEmission = makeRatioSetter("SetLightEmission", LightEmission)
  551. Rain.SetLightInfluence = makeRatioSetter("SetLightInfluence", LightInfluence)
  552. function Rain:SetVolume(volume, tweenInfo)
  553.     if typeof(volume) ~= "number" then
  554.         error("bad argument #1 to 'SetVolume' (number expected, got " .. typeof(volume) .. ")", 2)
  555.     elseif tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
  556.         error("bad argument #2 to 'SetVolume' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
  557.     end
  558.     if tweenInfo then
  559.         TweenService:Create(SoundGroup, tweenInfo, {Volume = volume}):Play()
  560.     else
  561.         SoundGroup.Volume = volume
  562.     end
  563. end
  564. function Rain:SetDirection(direction, tweenInfo)
  565.     if typeof(direction) ~= "Vector3" then
  566.         error("bad argument #1 to 'SetDirection' (Vector3 expected, got " .. typeof(direction) .. ")", 2)
  567.     elseif tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
  568.         error("bad argument #2 to 'SetDirection' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
  569.     end
  570.     if not (direction.unit.magnitude > 0) then
  571.         warn("Attempt to set rain direction to a zero-length vector, falling back on default direction = (" .. tostring(RAIN_DEFAULT_DIRECTION) .. ")")
  572.         direction = RAIN_DEFAULT_DIRECTION
  573.     end
  574.     if tweenInfo then
  575.         TweenService:Create(RainDirection, tweenInfo, {Value = direction}):Play()
  576.     else
  577.         RainDirection.Value = direction
  578.     end
  579. end
  580. function Rain:SetCeiling(ceiling)
  581.     if ceiling ~= nil and typeof(ceiling) ~= "number" then
  582.         error("bad argument #1 to 'SetCeiling' (number expected, got " .. typeof(ceiling) .. ")", 2)
  583.     end
  584.     currentCeiling = ceiling
  585. end
  586. function Rain:SetStraightTexture(asset)
  587.     if typeof(asset) ~= "string" then
  588.         error("bad argument #1 to 'SetStraightTexture' (string expected, got " .. typeof(asset) .. ")", 2)
  589.     end
  590.     Emitter.RainStraight.Texture = asset
  591.     for _, v in pairs(rainAttachments) do
  592.         v.RainStraight.Texture = asset
  593.     end
  594. end
  595. function Rain:SetTopDownTexture(asset)
  596.     if typeof(asset) ~= "string" then
  597.         error("bad argument #1 to 'SetStraightTexture' (string expected, got " .. typeof(asset) .. ")", 2)
  598.     end
  599.     Emitter.RainTopDown.Texture = asset
  600.     for _, v in pairs(rainAttachments) do
  601.         v.RainTopDown.Texture = asset
  602.     end
  603. end
  604. function Rain:SetSplashTexture(asset)
  605.     if typeof(asset) ~= "string" then
  606.         error("bad argument #1 to 'SetStraightTexture' (string expected, got " .. typeof(asset) .. ")", 2)
  607.     end
  608.     for _, v in pairs(splashAttachments) do
  609.         v.RainSplash.Texture = asset
  610.     end
  611. end
  612. function Rain:SetSoundId(asset)
  613.     if typeof(asset) ~= "string" then
  614.         error("bad argument #1 to 'SetSoundId' (string expected, got " .. typeof(asset) .. ")", 2)
  615.     end
  616.     Sound.SoundId = asset
  617. end
  618. function Rain:SetCollisionMode(mode, param)
  619.     if mode == CollisionMode.None then
  620.         collisionList = nil
  621.         collisionFunc = nil
  622.     elseif mode == CollisionMode.Blacklist then
  623.         if typeof(param) == "Instance" then
  624.             collisionList = {param, Emitter}
  625.         elseif typeof(param) == "table" then
  626.             for i = 1, #param do
  627.                 if typeof(param[i]) ~= "Instance" then
  628.                     error("bad argument #2 to 'SetCollisionMode' (blacklist contained a " .. typeof(param[i]) .. " on index " .. tostring(i) .. " which is not an Instance)", 2)
  629.                 end
  630.             end
  631.             collisionList = {Emitter}
  632.             for i = 1, #param do
  633.                 table.insert(collisionList, param[i])
  634.             end
  635.         else
  636.             error("bad argument #2 to 'SetCollisionMode (Instance or array of Instance expected, got " .. typeof(param) .. ")'", 2)
  637.         end
  638.         collisionFunc = nil
  639.     elseif mode == CollisionMode.Whitelist then
  640.         if typeof(param) == "Instance" then
  641.             collisionList = {param}
  642.         elseif typeof(param) == "table" then
  643.             for i = 1, #param do
  644.                 if typeof(param[i]) ~= "Instance" then
  645.                     error("bad argument #2 to 'SetCollisionMode' (whitelist contained a " .. typeof(param[i]) .. " on index " .. tostring(i) .. " which is not an Instance)", 2)
  646.                 end
  647.             end
  648.             collisionList = {}
  649.             for i = 1, #param do
  650.                 table.insert(collisionList, param[i])
  651.             end
  652.         else
  653.             error("bad argument #2 to 'SetCollisionMode (Instance or array of Instance expected, got " .. typeof(param) .. ")'", 2)
  654.         end
  655.         collisionFunc = nil
  656.     elseif mode == CollisionMode.Function then
  657.         if typeof(param) ~= "function" then
  658.             error("bad argument #2 to 'SetCollisionMode' (function expected, got " .. typeof(param) .. ")", 2)
  659.         end
  660.         collisionList = nil
  661.         collisionFunc = param
  662.     else
  663.         error("bad argument #1 to 'SetCollisionMode (Rain.CollisionMode expected, got " .. typeof(param) .. ")'", 2)
  664.     end
  665.     collisionMode = mode
  666.     raycast = raycastFunctions[mode]
  667. end
  668. return Rain
Advertisement
Add Comment
Please, Sign In to add comment