VoidScript

Snow

Sep 1st, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.62 KB | None | 0 0
  1. -- @author Quenty
  2. -- Stick this guy in the StarterGui...
  3.  
  4. local Players = game:GetService("Players")
  5. --Players.LocalPlayer.CameraMode = "Classic"
  6. --Players.LocalPlayer.CameraMode = "LockFirstPerson"
  7.  
  8.  
  9. -- You can use this to make it fall a lot...
  10. local Configuration = {
  11. SnowModelName = "ThatSnowRenderModel";
  12. SnowColor = Vector3.new(1, 1, 1);
  13. SmallestFlakeSize = 8;-- Divided by 100
  14. LargestFlakeSize = 15;
  15. MaxMoveX = 5; -- Divided by 100
  16. MinMoveX = -5;
  17. MaxMoveY = 1;
  18. MinMoveY = -12;
  19. MaxMoveZ = 5;
  20. MinMoveZ = -5;
  21. CyclesPerLifeMax = 4;
  22. CyclesPerLifeMin = 2;
  23. CycleLife = 20;
  24. MaxTransparency = 0.3;
  25. RangeX = 8;
  26. RangeY = 4;
  27. RangeZ = 8;
  28.  
  29. -- QUICK EDITING STUFF HERE
  30. SnowAmountFactor = 3; -- Snowflakes made every frame. Double this, double lag, more snowflakes!
  31. }
  32.  
  33. local function GetSnowModel()
  34. local Model = workspace:FindFirstChild(Configuration.SnowModelName)
  35. if not Model then
  36. Model = Instance.new("Camera", workspace)
  37. Model.Name = Configuration.SnowModelName
  38. Model.Archivable = false;
  39. end
  40. return Model
  41. end
  42.  
  43. local function GetSnowflakeMovement()
  44. return Vector3.new(
  45. math.random(Configuration.MinMoveX, Configuration.MaxMoveX)/100,
  46. math.random(Configuration.MinMoveY, Configuration.MaxMoveY)/100,
  47. math.random(Configuration.MinMoveZ, Configuration.MaxMoveZ)/100
  48. )
  49. end
  50.  
  51. local function GetRandomSnowflakePosition(LastValidPlace) --, CoordinateFrame)
  52. --[[return CFrame.new(LastValidPlace + Vector3.new(
  53. math.random(-Configuration.RangeX, Configuration.RangeX),
  54. math.random(-3, Configuration.RangeY),
  55. math.random(-Configuration.RangeZ, Configuration.RangeZ)
  56. ) + Players.LocalPlayer.Character.Torso.CFrame.lookVector * 2)--]]
  57. return CFrame.new() + LastValidPlace:pointToWorldSpace(Vector3.new(
  58. math.random(-Configuration.RangeX, Configuration.RangeX),
  59. math.random(-3, Configuration.RangeY),
  60. math.random(-Configuration.RangeZ*2, 0)))
  61. end
  62.  
  63. local SnowflakeQueue = {}
  64.  
  65. local function UpdateQueue()
  66. local HalfLife = Configuration.CycleLife;
  67. local MaxTransparency = Configuration.MaxTransparency
  68. --for Index, SnowFlake in pairs(SnowflakeQueue) do
  69. local Index = 1
  70. while Index <= #SnowflakeQueue do
  71. local SnowFlake = SnowflakeQueue[Index]
  72.  
  73. local CycleTick = SnowFlake.CycleTick
  74. local Flake = SnowFlake.Flake
  75. if SnowFlake.Mode == 2 then
  76. SnowFlake.CyclesLeft = SnowFlake.CyclesLeft - 1
  77. if SnowFlake.CyclesLeft <= 0 then
  78. SnowFlake.Flake:Destroy()
  79. table.remove(SnowflakeQueue, Index)
  80. else
  81. SnowFlake.CycleTick = Configuration.CycleLife
  82. SnowFlake.Mode = 0
  83. Index = Index + 1
  84. end
  85. elseif SnowFlake.Mode == 0 then
  86. Flake.Transparency = (CycleTick/HalfLife)* MaxTransparency + (MaxTransparency)
  87. Flake.CFrame = Flake.CFrame + SnowFlake.MoveRate
  88. SnowFlake.CycleTick = CycleTick - 1
  89. if SnowFlake.CycleTick <= 0 then
  90. SnowFlake.Mode = 1
  91. end
  92. Index = Index + 1
  93. elseif SnowFlake.Mode == 1 then
  94. Flake.Transparency = (CycleTick/HalfLife)*MaxTransparency + (MaxTransparency)
  95. Flake.CFrame = Flake.CFrame + SnowFlake.MoveRate
  96. SnowFlake.CycleTick = CycleTick + 1
  97. if SnowFlake.CycleTick >= HalfLife then
  98. SnowFlake.Mode = 2
  99. end
  100. Index = Index + 1
  101. end
  102. end
  103. end
  104.  
  105. local function MakeSnowFlake(Parent, InitialCFrame)
  106. local FlakeSize = math.random(Configuration.SmallestFlakeSize, Configuration.LargestFlakeSize)/100
  107.  
  108. local Flake = Instance.new("Part", Parent)
  109. Flake.Anchored = true;
  110. Flake.CanCollide = false;
  111. Flake.FormFactor = "Custom";
  112. Flake.Size = Vector3.new(1, 1, 1)
  113. Flake.Name = "SnowFlake";
  114. Flake.BottomSurface = "Smooth";
  115. Flake.CFrame = InitialCFrame
  116. Flake.Transparency = 1;
  117.  
  118. local Mesh = Instance.new("SpecialMesh", Flake)
  119. Mesh.MeshType = "FileMesh"
  120. Mesh.MeshId = "http://www.roblox.com/asset/?id=1185246"
  121. Mesh.TextureId = "http://www.roblox.com/asset/?id=1361097"
  122. Mesh.VertexColor = Configuration.SnowColor;
  123. Mesh.Scale = Vector3.new(FlakeSize, FlakeSize, FlakeSize)
  124.  
  125. local SnowFlake = {}
  126. SnowFlake.Flake = Flake;
  127. SnowFlake.CycleTick = Configuration.CycleLife
  128. SnowFlake.CyclesLeft = math.random(Configuration.CyclesPerLifeMin, Configuration.CyclesPerLifeMax)
  129. SnowFlake.MoveRate = GetSnowflakeMovement()
  130. SnowFlake.Mode = 0
  131. table.insert(SnowflakeQueue, SnowFlake)
  132. end
  133.  
  134. local function CheckPlayer(Player)
  135. --- Makes sure a player has all necessary components.
  136. -- @return Boolean If the player has all the right components
  137.  
  138. return Player and Player:IsA("Player") and Player:IsDescendantOf(Players)
  139. end
  140.  
  141.  
  142. local function CheckCharacter(Player)
  143. -- Makes sure a character has all the right "parts"
  144.  
  145. if CheckPlayer(Player) then
  146. local Character = Player.Character;
  147.  
  148. if Character then
  149.  
  150. return Character.Parent
  151. and Character:FindFirstChild("Humanoid")
  152. and Character:FindFirstChild("HumanoidRootPart")
  153. and Character:FindFirstChild("Torso")
  154. and Character:FindFirstChild("Head")
  155. and Character.Humanoid:IsA("Humanoid")
  156. and Character.Head:IsA("BasePart")
  157. and Character.Torso:IsA("BasePart")
  158. and true
  159. end
  160. else
  161. warn("[CheckCharacter] - Character Check failed!")
  162. end
  163.  
  164. return nil
  165. end
  166.  
  167.  
  168.  
  169.  
  170. local FindPartOnRayWithIgnoreList = workspace.FindPartOnRayWithIgnoreList
  171.  
  172. local function AdvanceRaycast(RayTrace, IgnoreList, TransparencyThreshold, IgnoreCanCollideFalse, TerrainCellsAreCubes, MaximumCastCount, CustomCondition)
  173. -- @param TransparencyThreshold The transparency a part can be for it to be counted. For example, if TransparencyThreshold is 0.25, and a part is 0.24 transparency then it will be counted as solid, otherwise if it
  174. -- is 0.26 then it will be counted as transparent.
  175. -- If you don't want to hit transparent parts, then you can set it to -math.huge.
  176. -- TransparencyThreshold should not be above 1, probably.
  177. -- @param [CustomCondition] A function that can be defined to create a custom condition (such as making sure a character is hit)
  178. -- CustomCondition(HitObject, Position)
  179. -- @return boolean If true, then it will automatically abort the cycle and return.
  180.  
  181. assert(type(MaximumCastCount) == "number", "MaximumCastCount is not a number")
  182. assert(type(TransparencyThreshold) == "number", "TransparencyThreshold must be a number")
  183.  
  184. --print(TransparencyThreshold)
  185.  
  186. local ContinueCasting = true;
  187. local CastCount = 0
  188.  
  189. local function CastAttempt(NewRayTrace)
  190. -- print("Cast attempt " .. CastCount)
  191.  
  192. if CastCount >= MaximumCastCount then
  193. return
  194. else
  195. CastCount = CastCount + 1
  196. end
  197.  
  198. local Object, Position = FindPartOnRayWithIgnoreList(workspace, NewRayTrace, IgnoreList, TerrainCellsAreCubes)
  199.  
  200. if Object and Position then
  201. if CustomCondition and CustomCondition(Object, Position) then
  202. -- print("Custom override")
  203. return Object, Position
  204. elseif IgnoreCanCollideFalse and Object.CanCollide == false then
  205. IgnoreList[#IgnoreList+1] = Object
  206.  
  207. --print("Hit something cancollide false", Object:GetFullName())
  208. return CastAttempt(NewRayTrace)
  209. elseif TransparencyThreshold and Object.Transparency >= TransparencyThreshold then
  210. IgnoreList[#IgnoreList+1] = Object
  211.  
  212. --print("Hit something transparent false", Object:GetFullName())
  213. return CastAttempt(NewRayTrace)
  214. else
  215. return Object, Position
  216. end
  217. else
  218. --print("Just didn't hit anything")
  219. return
  220. end
  221. end
  222.  
  223. local DirectionUnit = RayTrace.Direction.unit
  224. local Magnitude = RayTrace.Direction.magnitude
  225. local CastedMagnitude = 0
  226.  
  227. --game:GetService("Debris"):AddItem(
  228. -- lib.DrawRay(RayTrace, BrickColor.new("Bright orange"))
  229. --, 2)
  230.  
  231. while CastedMagnitude < Magnitude do
  232. local ToCastMagnitude = Magnitude - CastedMagnitude
  233.  
  234. if ToCastMagnitude > 999.5 then
  235. ToCastMagnitude = 999
  236. end
  237.  
  238. local WaysAlongPath = RayTrace.Origin + (DirectionUnit * CastedMagnitude)
  239. local NewRayTrace = Ray.new(WaysAlongPath, DirectionUnit * ToCastMagnitude)
  240. local Object, Position = CastAttempt(NewRayTrace)
  241.  
  242. -- game:GetService("Debris"):AddItem(
  243. -- lib.DrawRay(NewRayTrace, BrickColor.new("Bright green"))
  244. --, 2)
  245.  
  246. if Object then
  247. return Object, Position
  248. end
  249.  
  250. CastedMagnitude = CastedMagnitude + ToCastMagnitude
  251.  
  252. if CastCount >= MaximumCastCount then
  253. print("[AdvanceRaycast] - Reached maximum cast count @ " .. CastCount .. "; MaximumCastCount = " .. MaximumCastCount)
  254. return nil
  255. end
  256. end
  257. end
  258.  
  259. local SnowModel = GetSnowModel()
  260. SnowModel:ClearAllChildren()
  261.  
  262. local LocalPlayer = Players.LocalPlayer
  263. --[[
  264. local function SetupCharacter(Character)
  265. local IgnoreList = {}
  266. local LastValidPlace = nil --Players.LocalPlayer.Character.Torso.Position
  267. while not CheckCharacter(LocalPlayer) and Character == LocalPlayer.Character do
  268. wait()
  269. end
  270.  
  271. while CheckCharacter(LocalPlayer) and Character == LocalPlayer.Character do
  272. --if Character:FindFirstChild("Torso") then
  273.  
  274. local NewRay = Ray.new(Torso.Position + Vector3.new(0, 3, 0), Vector3.new(0, 100, 0))
  275. local Hit, Position = AdvanceRaycast(NewRay, IgnoreList, 0.001, true, true, 5)
  276. if not Hit then
  277. LastValidPlace = Torso.Position
  278. --else
  279. --print("Inside")
  280. end
  281. if LastValidPlace then
  282. MakeSnowFlake(SnowModel, GetRandomSnowflakePosition(LastValidPlace))
  283. end
  284. --end
  285. UpdateQueue()
  286. wait()
  287. end
  288. end
  289.  
  290. if LocalPlayer.Character then
  291. SetupCharacter(LocalPlayer.Character)
  292. end
  293.  
  294. LocalPlayer.CharacterAdded:connect(SetupCharacter)--]]
  295.  
  296. local LastValidPlace
  297. local IgnoreList = {SnowModel, LocalPlayer.Character}
  298. local LastClean = tick()
  299.  
  300. local function CleanIgnoreList()
  301. if LastClean + 5 <= tick() then
  302. IgnoreList = {SnowModel, LocalPlayer.Character}
  303. LastClean = tick()
  304. end
  305. end
  306.  
  307. local function DrawRay(Ray, Color, Parent)
  308. --- Draw's a ray out (for debugging)
  309. -- Credit to Cirrus for initial code.
  310.  
  311. Parent = Parent or workspace
  312.  
  313. local NewPart = Instance.new("Part", Parent)
  314.  
  315. NewPart.FormFactor = "Custom"
  316. NewPart.Size = Vector3.new(0.2, Ray.Direction.magnitude, 0.2)
  317.  
  318. local Center = Ray.Origin + Ray.Direction/2
  319. -- lib.DrawPoint(Ray.Origin).Name = "origin"
  320. -- lib.DrawPoint(Center).Name = "Center"
  321. -- lib.DrawPoint(Ray.Origin + Ray.Direction).Name = "Destination"
  322.  
  323. NewPart.CFrame = CFrame.new(Center, Ray.Origin + Ray.Direction) * CFrame.Angles(math.pi/2, 0, 0) --* GetCFramePitch(math.pi/2)
  324. NewPart.Anchored = true
  325. NewPart.CanCollide = false
  326. NewPart.Transparency = 0.5
  327. NewPart.BrickColor = Color or BrickColor.new("Bright red")
  328. NewPart.Name = "DrawnRay"
  329.  
  330. Instance.new("SpecialMesh", NewPart)
  331.  
  332. return NewPart
  333. end
  334.  
  335.  
  336. while true do
  337. local Camera = workspace.CurrentCamera
  338. if Camera then
  339. -- Check to make sure we're next extending through a roof or something...
  340. local ExtensionRay = Ray.new(Camera.CoordinateFrame.p,
  341. Camera.CoordinateFrame:vectorToWorldSpace(Vector3.new(0, 0, -Configuration.RangeZ))
  342. )
  343. local Hit, Position = AdvanceRaycast(ExtensionRay, IgnoreList, 0.001, true, true, 5)
  344. if not Hit then
  345. -- Extend by mid range.
  346. local NewRay = Ray.new((Camera.CoordinateFrame * CFrame.new(0, 0, -Configuration.RangeZ)).p, Vector3.new(0, 100, 0))
  347. local Hit, Position = AdvanceRaycast(NewRay, IgnoreList, 0.001, true, true, 5)
  348. if not Hit then
  349. LastValidPlace = Camera.CoordinateFrame
  350. end
  351. end
  352.  
  353. if LastValidPlace then
  354. for Index = 1, Configuration.SnowAmountFactor do
  355. MakeSnowFlake(SnowModel, GetRandomSnowflakePosition(LastValidPlace, Camera.CoordinateFrame))
  356. end
  357. end
  358. end
  359. UpdateQueue()
  360. CleanIgnoreList()
  361. wait(0.03)
  362. end
Add Comment
Please, Sign In to add comment