Advertisement
N0ePlox

spooky npc

Nov 25th, 2018
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 62.40 KB | None | 0 0
  1.  
  2. --Converted with ttyyuu12345's model to script plugin v4
  3. function sandbox(var,func)
  4. local env = getfenv(func)
  5. local newenv = setmetatable({},{
  6. __index = function(self,k)
  7. if k=="script" then
  8. return var
  9. else
  10. return env[k]
  11. end
  12. end,
  13. })
  14. setfenv(func,newenv)
  15. return func
  16. end
  17. cors = {}
  18. mas = Instance.new("Model",game:GetService("Lighting"))
  19. Model0 = Instance.new("Model")
  20. Part1 = Instance.new("Part")
  21. Motor6D2 = Instance.new("Motor6D")
  22. Part3 = Instance.new("Part")
  23. Motor6D4 = Instance.new("Motor6D")
  24. Motor6D5 = Instance.new("Motor6D")
  25. Motor6D6 = Instance.new("Motor6D")
  26. Motor6D7 = Instance.new("Motor6D")
  27. BodyForce8 = Instance.new("BodyForce")
  28. Motor6D9 = Instance.new("Motor6D")
  29. Part10 = Instance.new("Part")
  30. Part11 = Instance.new("Part")
  31. Part12 = Instance.new("Part")
  32. Part13 = Instance.new("Part")
  33. Part14 = Instance.new("Part")
  34. SpecialMesh15 = Instance.new("SpecialMesh")
  35. Humanoid16 = Instance.new("Humanoid")
  36. Script17 = Instance.new("Script")
  37. StringValue18 = Instance.new("StringValue")
  38. Animation19 = Instance.new("Animation")
  39. StringValue20 = Instance.new("StringValue")
  40. Animation21 = Instance.new("Animation")
  41. StringValue22 = Instance.new("StringValue")
  42. Animation23 = Instance.new("Animation")
  43. NumberValue24 = Instance.new("NumberValue")
  44. Animation25 = Instance.new("Animation")
  45. NumberValue26 = Instance.new("NumberValue")
  46. StringValue27 = Instance.new("StringValue")
  47. Animation28 = Instance.new("Animation")
  48. StringValue29 = Instance.new("StringValue")
  49. Animation30 = Instance.new("Animation")
  50. StringValue31 = Instance.new("StringValue")
  51. Animation32 = Instance.new("Animation")
  52. StringValue33 = Instance.new("StringValue")
  53. Animation34 = Instance.new("Animation")
  54. Script35 = Instance.new("Script")
  55. BillboardGui36 = Instance.new("BillboardGui")
  56. TextLabel37 = Instance.new("TextLabel")
  57. Configuration38 = Instance.new("Configuration")
  58. ModuleScript39 = Instance.new("ModuleScript")
  59. ModuleScript40 = Instance.new("ModuleScript")
  60. ModuleScript41 = Instance.new("ModuleScript")
  61. ModuleScript42 = Instance.new("ModuleScript")
  62. ModuleScript43 = Instance.new("ModuleScript")
  63. ModuleScript44 = Instance.new("ModuleScript")
  64. Configuration45 = Instance.new("Configuration")
  65. IntValue46 = Instance.new("IntValue")
  66. BoolValue47 = Instance.new("BoolValue")
  67. IntValue48 = Instance.new("IntValue")
  68. IntValue49 = Instance.new("IntValue")
  69. Configuration50 = Instance.new("Configuration")
  70. Animation51 = Instance.new("Animation")
  71. Animation52 = Instance.new("Animation")
  72. CharacterMesh53 = Instance.new("CharacterMesh")
  73. CharacterMesh54 = Instance.new("CharacterMesh")
  74. CharacterMesh55 = Instance.new("CharacterMesh")
  75. CharacterMesh56 = Instance.new("CharacterMesh")
  76. CharacterMesh57 = Instance.new("CharacterMesh")
  77. Sound58 = Instance.new("Sound")
  78. BodyColors59 = Instance.new("BodyColors")
  79. Script60 = Instance.new("Script")
  80. MeshPart61 = Instance.new("MeshPart")
  81. Model0.Name = "Drooling Zombie"
  82. Model0.Parent = mas
  83. Part1.Name = "HumanoidRootPart"
  84. Part1.Parent = Model0
  85. Part1.CFrame = CFrame.new(-28.6997967, 3.010041, 13.4000378, 4.49431016e-21, -6.795317e-22, -1, 4.72532479e-22, 1, -6.795317e-22, 1, -4.72532479e-22, 4.49431016e-21)
  86. Part1.Orientation = Vector3.new(0, -90, 0)
  87. Part1.Position = Vector3.new(-28.6997967, 3.010041, 13.4000378)
  88. Part1.Rotation = Vector3.new(0, -90, 0)
  89. Part1.Color = Color3.new(0.152941, 0.27451, 0.176471)
  90. Part1.Transparency = 1
  91. Part1.Size = Vector3.new(2, 2, 1)
  92. Part1.BottomSurface = Enum.SurfaceType.Smooth
  93. Part1.BrickColor = BrickColor.new("Earth green")
  94. Part1.Material = Enum.Material.WoodPlanks
  95. Part1.TopSurface = Enum.SurfaceType.Smooth
  96. Part1.brickColor = BrickColor.new("Earth green")
  97. Part1.FormFactor = Enum.FormFactor.Symmetric
  98. Part1.formFactor = Enum.FormFactor.Symmetric
  99. Motor6D2.Name = "Root Hip"
  100. Motor6D2.Parent = Part1
  101. Motor6D2.MaxVelocity = 0.10000000149012
  102. Motor6D2.C0 = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, -0)
  103. Motor6D2.C1 = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, -0)
  104. Motor6D2.Part0 = Part1
  105. Motor6D2.Part1 = Part3
  106. Motor6D2.part1 = Part3
  107. Part3.Name = "Torso"
  108. Part3.Parent = Model0
  109. Part3.CFrame = CFrame.new(-28.6997967, 3.010041, 13.4000378, 4.49431016e-21, -6.795317e-22, -1, 4.72532479e-22, 1, -6.795317e-22, 1, -4.72532479e-22, 4.49431016e-21)
  110. Part3.Orientation = Vector3.new(0, -90, 0)
  111. Part3.Position = Vector3.new(-28.6997967, 3.010041, 13.4000378)
  112. Part3.Rotation = Vector3.new(0, -90, 0)
  113. Part3.Color = Color3.new(0.156863, 0.498039, 0.278431)
  114. Part3.Transparency = 1
  115. Part3.Size = Vector3.new(2, 2, 1)
  116. Part3.BottomSurface = Enum.SurfaceType.Smooth
  117. Part3.BrickColor = BrickColor.new("Dark green")
  118. Part3.Material = Enum.Material.WoodPlanks
  119. Part3.TopSurface = Enum.SurfaceType.Smooth
  120. Part3.brickColor = BrickColor.new("Dark green")
  121. Part3.FormFactor = Enum.FormFactor.Symmetric
  122. Part3.formFactor = Enum.FormFactor.Symmetric
  123. Motor6D4.Name = "Left Hip"
  124. Motor6D4.Parent = Part3
  125. Motor6D4.MaxVelocity = 0.10000000149012
  126. Motor6D4.C0 = CFrame.new(-1, -1, 0, -4.37113883e-08, 0, -1, 0, 0.99999994, 0, 1, 0, -4.37113883e-08)
  127. Motor6D4.C1 = CFrame.new(-0.5, 1, 0, -4.37113883e-08, 0, -1, 0, 0.99999994, 0, 1, 0, -4.37113883e-08)
  128. Motor6D4.Part0 = Part3
  129. Motor6D4.Part1 = Part10
  130. Motor6D4.part1 = Part10
  131. Motor6D5.Name = "Left Shoulder"
  132. Motor6D5.Parent = Part3
  133. Motor6D5.MaxVelocity = 0.10000000149012
  134. Motor6D5.C0 = CFrame.new(-1, 0.5, 0, -4.37113883e-08, 0, -1, 0, 0.99999994, 0, 1, 0, -4.37113883e-08)
  135. Motor6D5.C1 = CFrame.new(0.5, 0.5, 0, -4.37113883e-08, 0, -1, 0, 0.99999994, 0, 1, 0, -4.37113883e-08)
  136. Motor6D5.Part0 = Part3
  137. Motor6D5.Part1 = Part12
  138. Motor6D5.part1 = Part12
  139. Motor6D6.Name = "Right Shoulder"
  140. Motor6D6.Parent = Part3
  141. Motor6D6.MaxVelocity = 0.10000000149012
  142. Motor6D6.C0 = CFrame.new(1, 0.5, 0, -4.37113883e-08, 0, 1, -0, 0.99999994, 0, -1, 0, -4.37113883e-08)
  143. Motor6D6.C1 = CFrame.new(-0.5, 0.5, 0, -4.37113883e-08, 0, 1, 0, 0.99999994, 0, -1, 0, -4.37113883e-08)
  144. Motor6D6.Part0 = Part3
  145. Motor6D6.Part1 = Part13
  146. Motor6D6.part1 = Part13
  147. Motor6D7.Name = "Neck"
  148. Motor6D7.Parent = Part3
  149. Motor6D7.MaxVelocity = 0.10000000149012
  150. Motor6D7.C0 = CFrame.new(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 1, -0)
  151. Motor6D7.C1 = CFrame.new(0, -0.5, 0, -1, 0, 0, 0, 0, 1, 0, 1, -0)
  152. Motor6D7.Part0 = Part3
  153. Motor6D7.Part1 = Part14
  154. Motor6D7.part1 = Part14
  155. BodyForce8.Name = "RepulsionForce"
  156. BodyForce8.Parent = Part3
  157. BodyForce8.Force = Vector3.new(0, 0, 0)
  158. BodyForce8.force = Vector3.new(0, 0, 0)
  159. Motor6D9.Name = "Right Hip"
  160. Motor6D9.Parent = Part3
  161. Motor6D9.MaxVelocity = 0.10000000149012
  162. Motor6D9.C0 = CFrame.new(1, -1, 0, -4.37113883e-08, 0, 1, -0, 0.99999994, 0, -1, 0, -4.37113883e-08)
  163. Motor6D9.C1 = CFrame.new(0.5, 1, 0, -4.37113883e-08, 0, 1, 0, 0.99999994, 0, -1, 0, -4.37113883e-08)
  164. Motor6D9.Part0 = Part3
  165. Motor6D9.Part1 = Part11
  166. Motor6D9.part1 = Part11
  167. Part10.Name = "Left Leg"
  168. Part10.Parent = Model0
  169. Part10.CFrame = CFrame.new(-28.6997967, 1.01004112, 12.9000378, 4.49431016e-21, -6.795316e-22, -1, 4.72532479e-22, 0.999999881, -6.795317e-22, 1, -4.72532428e-22, 4.49431016e-21)
  170. Part10.Orientation = Vector3.new(0, -90, 0)
  171. Part10.Position = Vector3.new(-28.6997967, 1.01004112, 12.9000378)
  172. Part10.Rotation = Vector3.new(0, -90, 0)
  173. Part10.Color = Color3.new(0.0509804, 0.411765, 0.67451)
  174. Part10.Transparency = 1
  175. Part10.Size = Vector3.new(1, 2, 1)
  176. Part10.BottomSurface = Enum.SurfaceType.Smooth
  177. Part10.BrickColor = BrickColor.new("Bright blue")
  178. Part10.CanCollide = false
  179. Part10.Material = Enum.Material.WoodPlanks
  180. Part10.TopSurface = Enum.SurfaceType.Smooth
  181. Part10.brickColor = BrickColor.new("Bright blue")
  182. Part10.FormFactor = Enum.FormFactor.Symmetric
  183. Part10.formFactor = Enum.FormFactor.Symmetric
  184. Part11.Name = "Right Leg"
  185. Part11.Parent = Model0
  186. Part11.CFrame = CFrame.new(-28.6997967, 1.01004112, 13.9000378, 4.49431016e-21, -6.795316e-22, -1, 4.72532479e-22, 0.999999881, -6.795317e-22, 1, -4.72532428e-22, 4.49431016e-21)
  187. Part11.Orientation = Vector3.new(0, -90, 0)
  188. Part11.Position = Vector3.new(-28.6997967, 1.01004112, 13.9000378)
  189. Part11.Rotation = Vector3.new(0, -90, 0)
  190. Part11.Color = Color3.new(0.0509804, 0.411765, 0.67451)
  191. Part11.Transparency = 1
  192. Part11.Size = Vector3.new(1, 2, 1)
  193. Part11.BottomSurface = Enum.SurfaceType.Smooth
  194. Part11.BrickColor = BrickColor.new("Bright blue")
  195. Part11.CanCollide = false
  196. Part11.Material = Enum.Material.WoodPlanks
  197. Part11.TopSurface = Enum.SurfaceType.Smooth
  198. Part11.brickColor = BrickColor.new("Bright blue")
  199. Part11.FormFactor = Enum.FormFactor.Symmetric
  200. Part11.formFactor = Enum.FormFactor.Symmetric
  201. Part12.Name = "Left Arm"
  202. Part12.Parent = Model0
  203. Part12.CFrame = CFrame.new(-28.6997967, 3.010041, 11.9000378, 4.49431016e-21, -6.795316e-22, -1, 4.72532479e-22, 0.999999881, -6.795317e-22, 1, -4.72532428e-22, 4.49431016e-21)
  204. Part12.Orientation = Vector3.new(0, -90, 0)
  205. Part12.Position = Vector3.new(-28.6997967, 3.010041, 11.9000378)
  206. Part12.Rotation = Vector3.new(0, -90, 0)
  207. Part12.Color = Color3.new(0.992157, 0.917647, 0.552941)
  208. Part12.Transparency = 1
  209. Part12.Size = Vector3.new(1, 2, 1)
  210. Part12.BottomSurface = Enum.SurfaceType.Smooth
  211. Part12.BrickColor = BrickColor.new("Cool yellow")
  212. Part12.CanCollide = false
  213. Part12.Material = Enum.Material.WoodPlanks
  214. Part12.TopSurface = Enum.SurfaceType.Smooth
  215. Part12.brickColor = BrickColor.new("Cool yellow")
  216. Part12.FormFactor = Enum.FormFactor.Symmetric
  217. Part12.formFactor = Enum.FormFactor.Symmetric
  218. Part13.Name = "Right Arm"
  219. Part13.Parent = Model0
  220. Part13.CFrame = CFrame.new(-28.6997967, 3.010041, 14.9000378, 4.49431016e-21, -6.795316e-22, -1, 4.72532479e-22, 0.999999881, -6.795317e-22, 1, -4.72532428e-22, 4.49431016e-21)
  221. Part13.Orientation = Vector3.new(0, -90, 0)
  222. Part13.Position = Vector3.new(-28.6997967, 3.010041, 14.9000378)
  223. Part13.Rotation = Vector3.new(0, -90, 0)
  224. Part13.Color = Color3.new(0.992157, 0.917647, 0.552941)
  225. Part13.Transparency = 1
  226. Part13.Size = Vector3.new(1, 2, 1)
  227. Part13.BottomSurface = Enum.SurfaceType.Smooth
  228. Part13.BrickColor = BrickColor.new("Cool yellow")
  229. Part13.CanCollide = false
  230. Part13.Material = Enum.Material.WoodPlanks
  231. Part13.TopSurface = Enum.SurfaceType.Smooth
  232. Part13.brickColor = BrickColor.new("Cool yellow")
  233. Part13.FormFactor = Enum.FormFactor.Symmetric
  234. Part13.formFactor = Enum.FormFactor.Symmetric
  235. Part14.Name = "Head"
  236. Part14.Parent = Model0
  237. Part14.CFrame = CFrame.new(-28.6997967, 4.51004124, 13.4000378, 4.49431016e-21, -6.795317e-22, -1, 4.72532479e-22, 1, -6.795317e-22, 1, -4.72532479e-22, 4.49431016e-21)
  238. Part14.Orientation = Vector3.new(0, -90, 0)
  239. Part14.Position = Vector3.new(-28.6997967, 4.51004124, 13.4000378)
  240. Part14.Rotation = Vector3.new(0, -90, 0)
  241. Part14.Color = Color3.new(0.992157, 0.917647, 0.552941)
  242. Part14.Transparency = 1
  243. Part14.Size = Vector3.new(2, 1, 1)
  244. Part14.BottomSurface = Enum.SurfaceType.Smooth
  245. Part14.BrickColor = BrickColor.new("Cool yellow")
  246. Part14.Material = Enum.Material.WoodPlanks
  247. Part14.TopSurface = Enum.SurfaceType.Smooth
  248. Part14.brickColor = BrickColor.new("Cool yellow")
  249. Part14.FormFactor = Enum.FormFactor.Symmetric
  250. Part14.formFactor = Enum.FormFactor.Symmetric
  251. SpecialMesh15.Parent = Part14
  252. SpecialMesh15.Scale = Vector3.new(1.25, 1.25, 1.25)
  253. Humanoid16.Parent = Model0
  254. Humanoid16.Health = inf
  255. Humanoid16.Jump = true
  256. Humanoid16.LeftLeg = Part10
  257. Humanoid16.MaxHealth = inf
  258. Humanoid16.RightLeg = Part11
  259. Humanoid16.Torso = Part1
  260. Humanoid16.WalkSpeed = 26
  261. Humanoid16.maxHealth = inf
  262. Script17.Name = "Animate"
  263. Script17.Parent = Model0
  264. table.insert(cors,sandbox(Script17,function()
  265. function waitForChild(parent, childName)
  266. local child = parent:findFirstChild(childName)
  267. if child then return child end
  268. while true do
  269. child = parent.ChildAdded:wait()
  270. if child.Name==childName then return child end
  271. end
  272. end
  273.  
  274. local Figure = script.Parent
  275. local Torso = waitForChild(Figure, "Torso")
  276. local RightShoulder = waitForChild(Torso, "Right Shoulder")
  277. local LeftShoulder = waitForChild(Torso, "Left Shoulder")
  278. local RightHip = waitForChild(Torso, "Right Hip")
  279. local LeftHip = waitForChild(Torso, "Left Hip")
  280. local Neck = waitForChild(Torso, "Neck")
  281. local Humanoid = waitForChild(Figure, "Humanoid")
  282. local pose = "Standing"
  283.  
  284. local currentAnim = ""
  285. local currentAnimTrack = nil
  286. local currentAnimKeyframeHandler = nil
  287. local currentAnimSpeed = 1.0
  288. local animTable = {}
  289. local animNames = {
  290. idle = {
  291. { id = "http://www.roblox.com/asset/?id=125750544", weight = 9 },
  292. { id = "http://www.roblox.com/asset/?id=125750618", weight = 1 }
  293. },
  294. walk = {
  295. { id = "http://www.roblox.com/asset/?id=125749145", weight = 10 }
  296. },
  297. run = {
  298. { id = "run.xml", weight = 10 }
  299. },
  300. jump = {
  301. { id = "http://www.roblox.com/asset/?id=125750702", weight = 10 }
  302. },
  303. fall = {
  304. { id = "http://www.roblox.com/asset/?id=125750759", weight = 10 }
  305. },
  306. climb = {
  307. { id = "http://www.roblox.com/asset/?id=125750800", weight = 10 }
  308. },
  309. toolnone = {
  310. { id = "http://www.roblox.com/asset/?id=125750867", weight = 10 }
  311. },
  312. toolslash = {
  313. { id = "http://www.roblox.com/asset/?id=129967390", weight = 10 }
  314. -- { id = "slash.xml", weight = 10 }
  315. },
  316. toollunge = {
  317. { id = "http://www.roblox.com/asset/?id=129967478", weight = 10 }
  318. },
  319. wave = {
  320. { id = "http://www.roblox.com/asset/?id=128777973", weight = 10 }
  321. },
  322. point = {
  323. { id = "http://www.roblox.com/asset/?id=128853357", weight = 10 }
  324. },
  325. dance = {
  326. { id = "http://www.roblox.com/asset/?id=130018893", weight = 10 },
  327. { id = "http://www.roblox.com/asset/?id=132546839", weight = 10 },
  328. { id = "http://www.roblox.com/asset/?id=132546884", weight = 10 }
  329. },
  330. dance2 = {
  331. { id = "http://www.roblox.com/asset/?id=160934142", weight = 10 },
  332. { id = "http://www.roblox.com/asset/?id=160934298", weight = 10 },
  333. { id = "http://www.roblox.com/asset/?id=160934376", weight = 10 }
  334. },
  335. dance3 = {
  336. { id = "http://www.roblox.com/asset/?id=160934458", weight = 10 },
  337. { id = "http://www.roblox.com/asset/?id=160934530", weight = 10 },
  338. { id = "http://www.roblox.com/asset/?id=160934593", weight = 10 }
  339. },
  340. laugh = {
  341. { id = "http://www.roblox.com/asset/?id=129423131", weight = 10 }
  342. },
  343. cheer = {
  344. { id = "http://www.roblox.com/asset/?id=129423030", weight = 10 }
  345. },
  346. }
  347.  
  348. -- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote
  349. local emoteNames = { wave = false, point = false, dance = true, dance2 = true, dance3 = true, laugh = false, cheer = false}
  350.  
  351. math.randomseed(tick())
  352.  
  353. function configureAnimationSet(name, fileList)
  354. if (animTable[name] ~= nil) then
  355. for _, connection in pairs(animTable[name].connections) do
  356. connection:disconnect()
  357. end
  358. end
  359. animTable[name] = {}
  360. animTable[name].count = 0
  361. animTable[name].totalWeight = 0
  362. animTable[name].connections = {}
  363.  
  364. -- check for config values
  365. local config = script:FindFirstChild(name)
  366. if (config ~= nil) then
  367. -- print("Loading anims " .. name)
  368. table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end))
  369. table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end))
  370. local idx = 1
  371. for _, childPart in pairs(config:GetChildren()) do
  372. if (childPart:IsA("Animation")) then
  373. table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end))
  374. animTable[name][idx] = {}
  375. animTable[name][idx].anim = childPart
  376. local weightObject = childPart:FindFirstChild("Weight")
  377. if (weightObject == nil) then
  378. animTable[name][idx].weight = 1
  379. else
  380. animTable[name][idx].weight = weightObject.Value
  381. end
  382. animTable[name].count = animTable[name].count + 1
  383. animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
  384. -- print(name .. " [" .. idx .. "] " .. animTable[name][idx].anim.AnimationId .. " (" .. animTable[name][idx].weight .. ")")
  385. idx = idx + 1
  386. end
  387. end
  388. end
  389.  
  390. -- fallback to defaults
  391. if (animTable[name].count <= 0) then
  392. for idx, anim in pairs(fileList) do
  393. animTable[name][idx] = {}
  394. animTable[name][idx].anim = Instance.new("Animation")
  395. animTable[name][idx].anim.Name = name
  396. animTable[name][idx].anim.AnimationId = anim.id
  397. animTable[name][idx].weight = anim.weight
  398. animTable[name].count = animTable[name].count + 1
  399. animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
  400. -- print(name .. " [" .. idx .. "] " .. anim.id .. " (" .. anim.weight .. ")")
  401. end
  402. end
  403. end
  404.  
  405. -- Setup animation objects
  406. function scriptChildModified(child)
  407. local fileList = animNames[child.Name]
  408. if (fileList ~= nil) then
  409. configureAnimationSet(child.Name, fileList)
  410. end
  411. end
  412.  
  413. script.ChildAdded:connect(scriptChildModified)
  414. script.ChildRemoved:connect(scriptChildModified)
  415.  
  416.  
  417. for name, fileList in pairs(animNames) do
  418. configureAnimationSet(name, fileList)
  419. end
  420.  
  421. -- ANIMATION
  422.  
  423. -- declarations
  424. local toolAnim = "None"
  425. local toolAnimTime = 0
  426.  
  427. local jumpAnimTime = 0
  428. local jumpAnimDuration = 0.3
  429.  
  430. local toolTransitionTime = 0.1
  431. local fallTransitionTime = 0.3
  432. local jumpMaxLimbVelocity = 0.75
  433.  
  434. -- functions
  435.  
  436. function stopAllAnimations()
  437. local oldAnim = currentAnim
  438.  
  439. -- return to idle if finishing an emote
  440. if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then
  441. oldAnim = "idle"
  442. end
  443.  
  444. currentAnim = ""
  445. if (currentAnimKeyframeHandler ~= nil) then
  446. currentAnimKeyframeHandler:disconnect()
  447. end
  448.  
  449. if (currentAnimTrack ~= nil) then
  450. currentAnimTrack:Stop()
  451. currentAnimTrack:Destroy()
  452. currentAnimTrack = nil
  453. end
  454. return oldAnim
  455. end
  456.  
  457. function setAnimationSpeed(speed)
  458. if speed ~= currentAnimSpeed then
  459. currentAnimSpeed = speed
  460. currentAnimTrack:AdjustSpeed(currentAnimSpeed)
  461. end
  462. end
  463.  
  464. function keyFrameReachedFunc(frameName)
  465. if (frameName == "End") then
  466. -- print("Keyframe : ".. frameName)
  467. local repeatAnim = stopAllAnimations()
  468. local animSpeed = currentAnimSpeed
  469. playAnimation(repeatAnim, 0.0, Humanoid)
  470. setAnimationSpeed(animSpeed)
  471. end
  472. end
  473.  
  474. -- Preload animations
  475. function playAnimation(animName, transitionTime, humanoid)
  476. local idleFromEmote = (animName == "idle" and emoteNames[currentAnim] ~= nil)
  477. if (animName ~= currentAnim and not idleFromEmote) then
  478.  
  479. if (currentAnimTrack ~= nil) then
  480. currentAnimTrack:Stop(transitionTime)
  481. currentAnimTrack:Destroy()
  482. end
  483.  
  484. currentAnimSpeed = 1.0
  485. local roll = math.random(1, animTable[animName].totalWeight)
  486. local origRoll = roll
  487. local idx = 1
  488. while (roll > animTable[animName][idx].weight) do
  489. roll = roll - animTable[animName][idx].weight
  490. idx = idx + 1
  491. end
  492. -- print(animName .. " " .. idx .. " [" .. origRoll .. "]")
  493. local anim = animTable[animName][idx].anim
  494.  
  495. -- load it to the humanoid; get AnimationTrack
  496. currentAnimTrack = humanoid:LoadAnimation(anim)
  497.  
  498. -- play the animation
  499. currentAnimTrack:Play(transitionTime)
  500. currentAnim = animName
  501.  
  502. -- set up keyframe name triggers
  503. if (currentAnimKeyframeHandler ~= nil) then
  504. currentAnimKeyframeHandler:disconnect()
  505. end
  506. currentAnimKeyframeHandler = currentAnimTrack.KeyframeReached:connect(keyFrameReachedFunc)
  507. end
  508. end
  509.  
  510. -------------------------------------------------------------------------------------------
  511. -------------------------------------------------------------------------------------------
  512.  
  513. local toolAnimName = ""
  514. local toolAnimTrack = nil
  515. local currentToolAnimKeyframeHandler = nil
  516.  
  517. function toolKeyFrameReachedFunc(frameName)
  518. if (frameName == "End") then
  519. -- print("Keyframe : ".. frameName)
  520. local repeatAnim = stopToolAnimations()
  521. playToolAnimation(repeatAnim, 0.0, Humanoid)
  522. end
  523. end
  524.  
  525.  
  526. function playToolAnimation(animName, transitionTime, humanoid)
  527. if (animName ~= toolAnimName) then
  528.  
  529. if (toolAnimTrack ~= nil) then
  530. toolAnimTrack:Stop()
  531. toolAnimTrack:Destroy()
  532. transitionTime = 0
  533. end
  534.  
  535. local roll = math.random(1, animTable[animName].totalWeight)
  536. local origRoll = roll
  537. local idx = 1
  538. while (roll > animTable[animName][idx].weight) do
  539. roll = roll - animTable[animName][idx].weight
  540. idx = idx + 1
  541. end
  542. -- print(animName .. " * " .. idx .. " [" .. origRoll .. "]")
  543. local anim = animTable[animName][idx].anim
  544.  
  545. -- load it to the humanoid; get AnimationTrack
  546. toolAnimTrack = humanoid:LoadAnimation(anim)
  547.  
  548. -- play the animation
  549. toolAnimTrack:Play(transitionTime)
  550. toolAnimName = animName
  551.  
  552. currentToolAnimKeyframeHandler = toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc)
  553. end
  554. end
  555.  
  556. function stopToolAnimations()
  557. local oldAnim = toolAnimName
  558.  
  559. if (currentToolAnimKeyframeHandler ~= nil) then
  560. currentToolAnimKeyframeHandler:disconnect()
  561. end
  562.  
  563. toolAnimName = ""
  564. if (toolAnimTrack ~= nil) then
  565. toolAnimTrack:Stop()
  566. toolAnimTrack:Destroy()
  567. toolAnimTrack = nil
  568. end
  569.  
  570.  
  571. return oldAnim
  572. end
  573.  
  574. -------------------------------------------------------------------------------------------
  575. -------------------------------------------------------------------------------------------
  576.  
  577.  
  578. function onRunning(speed)
  579. if speed>0.01 then
  580. playAnimation("walk", 0.1, Humanoid)
  581. pose = "Running"
  582. else
  583. playAnimation("idle", 0.1, Humanoid)
  584. pose = "Standing"
  585. end
  586. end
  587.  
  588. function onDied()
  589. pose = "Dead"
  590. end
  591.  
  592. function onJumping()
  593. playAnimation("jump", 0.1, Humanoid)
  594. jumpAnimTime = jumpAnimDuration
  595. pose = "Jumping"
  596. end
  597.  
  598. function onClimbing(speed)
  599. playAnimation("climb", 0.1, Humanoid)
  600. setAnimationSpeed(speed / 12.0)
  601. pose = "Climbing"
  602. end
  603.  
  604. function onGettingUp()
  605. pose = "GettingUp"
  606. end
  607.  
  608. function onFreeFall()
  609. if (jumpAnimTime <= 0) then
  610. playAnimation("fall", fallTransitionTime, Humanoid)
  611. end
  612. pose = "FreeFall"
  613. end
  614.  
  615. function onFallingDown()
  616. pose = "FallingDown"
  617. end
  618.  
  619. function onSeated()
  620. pose = "Seated"
  621. end
  622.  
  623. function onPlatformStanding()
  624. pose = "PlatformStanding"
  625. end
  626.  
  627. function onSwimming(speed)
  628. if speed>0 then
  629. pose = "Running"
  630. else
  631. pose = "Standing"
  632. end
  633. end
  634.  
  635. function getTool()
  636. for _, kid in ipairs(Figure:GetChildren()) do
  637. if kid.className == "Tool" then return kid end
  638. end
  639. return nil
  640. end
  641.  
  642. function getToolAnim(tool)
  643. for _, c in ipairs(tool:GetChildren()) do
  644. if c.Name == "toolanim" and c.className == "StringValue" then
  645. return c
  646. end
  647. end
  648. return nil
  649. end
  650.  
  651. function animateTool()
  652.  
  653. if (toolAnim == "None") then
  654. playToolAnimation("toolnone", toolTransitionTime, Humanoid)
  655. return
  656. end
  657.  
  658. if (toolAnim == "Slash") then
  659. playToolAnimation("toolslash", 0, Humanoid)
  660. return
  661. end
  662.  
  663. if (toolAnim == "Lunge") then
  664. playToolAnimation("toollunge", 0, Humanoid)
  665. return
  666. end
  667. end
  668.  
  669. function moveSit()
  670. RightShoulder.MaxVelocity = 0.15
  671. LeftShoulder.MaxVelocity = 0.15
  672. RightShoulder:SetDesiredAngle(3.14 /2)
  673. LeftShoulder:SetDesiredAngle(-3.14 /2)
  674. RightHip:SetDesiredAngle(3.14 /2)
  675. LeftHip:SetDesiredAngle(-3.14 /2)
  676. end
  677.  
  678. local lastTick = 0
  679.  
  680. function move(time)
  681. local amplitude = 1
  682. local frequency = 1
  683. local deltaTime = time - lastTick
  684. lastTick = time
  685.  
  686. local climbFudge = 0
  687. local setAngles = false
  688.  
  689. if (jumpAnimTime > 0) then
  690. jumpAnimTime = jumpAnimTime - deltaTime
  691. end
  692.  
  693. if (pose == "FreeFall" and jumpAnimTime <= 0) then
  694. playAnimation("fall", fallTransitionTime, Humanoid)
  695. elseif (pose == "Seated") then
  696. stopAllAnimations()
  697. moveSit()
  698. return
  699. elseif (pose == "Running") then
  700. playAnimation("walk", 0.1, Humanoid)
  701. elseif (pose == "Dead" or pose == "GettingUp" or pose == "FallingDown" or pose == "Seated" or pose == "PlatformStanding") then
  702. -- print("Wha " .. pose)
  703. amplitude = 0.1
  704. frequency = 1
  705. setAngles = true
  706. end
  707.  
  708. if (setAngles) then
  709. desiredAngle = amplitude * math.sin(time * frequency)
  710.  
  711. RightShoulder:SetDesiredAngle(desiredAngle + climbFudge)
  712. LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge)
  713. RightHip:SetDesiredAngle(-desiredAngle)
  714. LeftHip:SetDesiredAngle(-desiredAngle)
  715. end
  716.  
  717. -- Tool Animation handling
  718. local tool = getTool()
  719. if tool then
  720.  
  721. animStringValueObject = getToolAnim(tool)
  722.  
  723. if animStringValueObject then
  724. toolAnim = animStringValueObject.Value
  725. -- message recieved, delete StringValue
  726. animStringValueObject.Parent = nil
  727. toolAnimTime = time + .3
  728. end
  729.  
  730. if time > toolAnimTime then
  731. toolAnimTime = 0
  732. toolAnim = "None"
  733. end
  734.  
  735. animateTool()
  736. else
  737. stopToolAnimations()
  738. toolAnim = "None"
  739. toolAnimTime = 0
  740. end
  741. end
  742.  
  743. -- connect events
  744. Humanoid.Died:connect(onDied)
  745. Humanoid.Running:connect(onRunning)
  746. Humanoid.Jumping:connect(onJumping)
  747. Humanoid.Climbing:connect(onClimbing)
  748. Humanoid.GettingUp:connect(onGettingUp)
  749. Humanoid.FreeFalling:connect(onFreeFall)
  750. Humanoid.FallingDown:connect(onFallingDown)
  751. Humanoid.Seated:connect(onSeated)
  752. Humanoid.PlatformStanding:connect(onPlatformStanding)
  753. Humanoid.Swimming:connect(onSwimming)
  754.  
  755. -- main program
  756.  
  757. local runService = game:service("RunService");
  758.  
  759. -- initialize to idle
  760. playAnimation("idle", 0.1, Humanoid)
  761. pose = "Standing"
  762.  
  763. while Figure.Parent~=nil do
  764. local _, time = wait(0.1)
  765. move(time)
  766. end
  767.  
  768.  
  769.  
  770. end))
  771. StringValue18.Name = "climb"
  772. StringValue18.Parent = Script17
  773. Animation19.Name = "ClimbAnim"
  774. Animation19.Parent = StringValue18
  775. Animation19.AnimationId = "http://www.roblox.com/asset/?id=125750800"
  776. StringValue20.Name = "fall"
  777. StringValue20.Parent = Script17
  778. Animation21.Name = "FallAnim"
  779. Animation21.Parent = StringValue20
  780. Animation21.AnimationId = "http://www.roblox.com/asset/?id=125750759"
  781. StringValue22.Name = "idle"
  782. StringValue22.Parent = Script17
  783. Animation23.Name = "Animation1"
  784. Animation23.Parent = StringValue22
  785. Animation23.AnimationId = "http://www.roblox.com/asset/?id=125750544"
  786. NumberValue24.Name = "Weight"
  787. NumberValue24.Parent = Animation23
  788. NumberValue24.Value = 9
  789. Animation25.Name = "Animation2"
  790. Animation25.Parent = StringValue22
  791. Animation25.AnimationId = "http://www.roblox.com/asset/?id=125750618"
  792. NumberValue26.Name = "Weight"
  793. NumberValue26.Parent = Animation25
  794. NumberValue26.Value = 1
  795. StringValue27.Name = "jump"
  796. StringValue27.Parent = Script17
  797. Animation28.Name = "JumpAnim"
  798. Animation28.Parent = StringValue27
  799. Animation28.AnimationId = "http://www.roblox.com/asset/?id=125750702"
  800. StringValue29.Name = "run"
  801. StringValue29.Parent = Script17
  802. Animation30.Name = "RunAnim"
  803. Animation30.Parent = StringValue29
  804. Animation30.AnimationId = "http://www.roblox.com/asset/?id=125749145"
  805. StringValue31.Name = "toolnone"
  806. StringValue31.Parent = Script17
  807. Animation32.Name = "ToolNoneAnim"
  808. Animation32.Parent = StringValue31
  809. Animation32.AnimationId = "http://www.roblox.com/asset/?id=125750867"
  810. StringValue33.Name = "walk"
  811. StringValue33.Parent = Script17
  812. Animation34.Name = "WalkAnim"
  813. Animation34.Parent = StringValue33
  814. Animation34.AnimationId = "http://www.roblox.com/asset/?id=125749145"
  815. Script35.Parent = Model0
  816. table.insert(cors,sandbox(Script35,function()
  817. local zombie = script.Parent
  818.  
  819. for _, script in pairs(zombie.ModuleScripts:GetChildren()) do
  820. if not game.ServerStorage:FindFirstChild(script.Name) then
  821. script:Clone().Parent = game.ServerStorage
  822. end
  823. end
  824.  
  825. local AI = require(game.ServerStorage.ROBLOX_ZombieAI).new(zombie)
  826. local DestroyService = require(game.ServerStorage.ROBLOX_DestroyService)
  827.  
  828.  
  829. local function clearParts(parent)
  830. for _, part in pairs(parent:GetChildren()) do
  831. clearParts(part)
  832. end
  833. local delay
  834. if parent:IsA("Part") then
  835. delay = math.random(5,10)
  836. else
  837. delay = 11
  838. end
  839. DestroyService:AddItem(parent, delay)
  840. end
  841.  
  842. zombie.Humanoid.Died:connect(function()
  843. AI.Stop()
  844. math.randomseed(tick())
  845. clearParts(zombie)
  846. script.Disabled = true
  847. end)
  848.  
  849. local lastMoan = os.time()
  850. math.randomseed(os.time())
  851. while true do
  852. local animationTrack = zombie.Humanoid:LoadAnimation(zombie.Animations.Arms)
  853. animationTrack:Play()
  854. -- local now = os.time()
  855. -- if now - lastMoan > 5 then
  856. -- if math.random() > .3 then
  857. -- zombie.Moan:Play()
  858. ---- print("playing moan")
  859. -- lastMoan = now
  860. -- end
  861. -- end
  862. wait(2)
  863. end
  864.  
  865.  
  866. end))
  867. BillboardGui36.Parent = Model0
  868. BillboardGui36.Size = UDim2.new(0, 100, 0, 30)
  869. BillboardGui36.StudsOffset = Vector3.new(0, 5, 0)
  870. TextLabel37.Parent = BillboardGui36
  871. TextLabel37.Visible = false
  872. TextLabel37.Size = UDim2.new(1, 0, 1, 0)
  873. TextLabel37.BackgroundColor = BrickColor.new("Institutional white")
  874. TextLabel37.BackgroundColor3 = Color3.new(1, 1, 1)
  875. TextLabel37.Font = Enum.Font.SourceSansBold
  876. TextLabel37.FontSize = Enum.FontSize.Size24
  877. TextLabel37.Text = "Idle"
  878. TextLabel37.TextSize = 24
  879. Configuration38.Name = "ModuleScripts"
  880. Configuration38.Parent = Model0
  881. ModuleScript39.Name = "ROBLOX_AIUtilities"
  882. ModuleScript39.Parent = Configuration38
  883. table.insert(cors,sandbox(ModuleScript39,function()
  884. local utility = {}
  885.  
  886. function utility:WideRayCast(start, target, offset, ignoreList)
  887. local parts = {}
  888.  
  889. local ray = Ray.new(start, target - start)
  890. local part, point = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
  891. if part then table.insert(parts, part) end
  892.  
  893. local offsetVector = offset * (target - start):Cross(Vector3.FromNormalId(Enum.NormalId.Top)).unit
  894. local ray = Ray.new(start + offsetVector, target - start + offsetVector)
  895. local part, point = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
  896. if part then table.insert(parts, part) end
  897.  
  898. local ray = Ray.new(start - offsetVector, target - start - offsetVector)
  899. local part, point = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
  900. if part then table.insert(parts, part) end
  901.  
  902. return parts
  903. end
  904.  
  905. function utility:FindNearestPathPoint(path, point, start, target, ignoreList)
  906. local occludePoint = path:CheckOcclusionAsync(point)
  907. if occludePoint > 0 then
  908. utility:WideRayCast(start)
  909. end
  910. end
  911.  
  912. local maxForce = 75
  913.  
  914. function utility:GetRepulsionVector(unitPosition, otherUnitsPositions)
  915. local repulsionVector = Vector3.new(0,0,0)
  916. local count = 0
  917. for _, other in pairs(otherUnitsPositions) do
  918. local fromOther = unitPosition - other
  919. --fromOther = fromOther.unit * ((-maxForce / 5) * math.pow(fromOther.magnitude,2) + maxForce)
  920. fromOther = fromOther.unit * 1000 / math.pow((fromOther.magnitude + 1), 2)
  921. repulsionVector = repulsionVector + fromOther
  922. end
  923. return repulsionVector * maxForce
  924. end
  925.  
  926. function utility:GetIdleState(StateMachine)
  927. local IdleState = StateMachine.NewState()
  928. IdleState.Name = "Idle"
  929. IdleState.Action = function() end
  930. IdleState.Init = function() end
  931. return IdleState
  932. end
  933.  
  934. function utility:GetClosestVisibleTarget(npcModel, characters, ignoreList, fieldOfView)
  935. local closestTarget = nil
  936. local closestDistance = math.huge
  937. for _, character in pairs(characters) do
  938. local toTarget = character.Torso.Position - npcModel.Torso.Position
  939. local toTargetWedge = toTarget * Vector3.new(1,0,1)
  940. local angle = math.acos(toTargetWedge:Dot(npcModel.Torso.CFrame.lookVector)/toTargetWedge.magnitude)
  941. if math.deg(angle) < fieldOfView then
  942. local targetRay = Ray.new(npcModel.Torso.Position, toTarget)
  943. local part, position = game.Workspace:FindPartOnRayWithIgnoreList(targetRay, ignoreList)
  944. if part and part.Parent == character then
  945. if toTarget.magnitude < closestDistance then
  946. closestTarget = character
  947. closestDistance = toTarget.magnitude
  948. end
  949. end
  950. end
  951. end
  952. return closestTarget
  953. end
  954.  
  955. local function isSpaceEmpty(position)
  956. local region = Region3.new(position - Vector3.new(2,2,2), position + Vector3.new(2,2,2))
  957. return game.Workspace:IsRegion3Empty(region)
  958. end
  959.  
  960. function utility:FindCloseEmptySpace(model)
  961. local targetPos = Vector3.new(0,0,0)
  962. local count = 0
  963. math.randomseed(os.time())
  964. repeat
  965. local xoff = math.random(5,10)
  966. if math.random() > .5 then
  967. xoff = xoff * -1
  968. end
  969. local zoff = math.random(5, 10)
  970. if math.random() > .5 then
  971. zoff = zoff * -1
  972. end
  973.  
  974. targetPos = Vector3.new(model.Torso.Position.X + xoff,model.Torso.Position.Y,model.Torso.Position.Z + zoff)
  975. if isSpaceEmpty(targetPos) then
  976. return targetPos
  977. else
  978. targetPos = targetPos + Vector3.new(0,4,0)
  979. end
  980.  
  981. if isSpaceEmpty(targetPos) then
  982. return targetPos
  983. end
  984. count = count + 1
  985. until count > 10
  986. return nil
  987. end
  988.  
  989. return utility
  990. end))
  991. ModuleScript40.Name = "ROBLOX_DestroyService"
  992. ModuleScript40.Parent = Configuration38
  993. table.insert(cors,sandbox(ModuleScript40,function()
  994. local destroyService = {}
  995.  
  996. local destroyQueue = {}
  997.  
  998. function destroyService:AddItem(theobject, delay)
  999. local now = os.time()
  1000. local destroyObject = {object = theobject, destroyTime = delay + now}
  1001. for i, storedObject in pairs(destroyQueue) do
  1002. if destroyQueue[i].destroyTime > destroyObject.destroyTime then
  1003. table.insert(destroyQueue, i, destroyObject)
  1004. return true
  1005. end
  1006. end
  1007. table.insert(destroyQueue, destroyObject)
  1008. return true
  1009. end
  1010.  
  1011. local updateThread = coroutine.create(function()
  1012. while true do
  1013. local now = os.time()
  1014. for _, storedObject in pairs(destroyQueue) do
  1015. if now >= storedObject.destroyTime then
  1016. table.remove(destroyQueue, 1)
  1017. if storedObject.object then
  1018. storedObject.object:Destroy()
  1019. end
  1020. elseif now >= storedObject.destroyTime - 1 then
  1021.  
  1022. if storedObject.object and storedObject.object:IsA("Part") then
  1023. local trans = storedObject.object.Transparency + 1/30
  1024. storedObject.object.Transparency = trans
  1025. end
  1026. else
  1027. break
  1028. end
  1029. end
  1030. wait()
  1031. end
  1032. end)
  1033.  
  1034. coroutine.resume(updateThread)
  1035.  
  1036. return destroyService
  1037. end))
  1038. ModuleScript41.Name = "ROBLOX_HumanoidList"
  1039. ModuleScript41.Parent = Configuration38
  1040. table.insert(cors,sandbox(ModuleScript41,function()
  1041. local humanoidList = {}
  1042. local storage = {}
  1043.  
  1044. function humanoidList:GetCurrent()
  1045. return storage
  1046. end
  1047.  
  1048. local function findHumanoids(object, list)
  1049. if object then
  1050. if object:IsA("Humanoid") then
  1051. table.insert(list, object)
  1052. end
  1053.  
  1054. for _, child in pairs(object:GetChildren()) do
  1055. local childList = findHumanoids(child, list)
  1056. end
  1057. end
  1058. end
  1059.  
  1060. local updateThread = coroutine.create(function()
  1061. while true do
  1062. storage = {}
  1063. findHumanoids(game.Workspace, storage)
  1064. wait(3)
  1065. end
  1066. end)
  1067.  
  1068. coroutine.resume(updateThread)
  1069.  
  1070. return humanoidList
  1071. end))
  1072. ModuleScript42.Name = "ROBLOX_StateMachine"
  1073. ModuleScript42.Parent = Configuration38
  1074. table.insert(cors,sandbox(ModuleScript42,function()
  1075. local machine = {}
  1076.  
  1077. machine.new = function()
  1078. local StateMachine = {}
  1079.  
  1080. StateMachine.WaitTime = .2
  1081. StateMachine.CurrentState = nil
  1082. StateMachine.SwitchState = function(newState)
  1083. if StateMachine.CurrentState then
  1084. StateMachine.CurrentState.Stop()
  1085. end
  1086. StateMachine.CurrentState = newState
  1087. if newState then
  1088. newState.Start()
  1089. end
  1090. end
  1091.  
  1092. StateMachine.NewState = function()
  1093. local state = {}
  1094. state.Name = ""
  1095. state.Conditions = {}
  1096. state.isRunning = false
  1097. state.Action = function() end
  1098. state.Run = function()
  1099. state.isRunning = true
  1100. while state.isRunning do
  1101. --check conditions
  1102. --print("checking conditions")
  1103. for _, condition in pairs(state.Conditions) do
  1104. --print("Checking " .. condition.Name)
  1105. if condition.Evaluate() then
  1106. --print(condition.Name .. " is true. Switching states")
  1107. StateMachine.SwitchState(condition.TransitionState)
  1108. return
  1109. end
  1110. end
  1111.  
  1112. --if no conditions satisfied, perform action
  1113. state.Action()
  1114. wait(StateMachine.WaitTime)
  1115. end
  1116. end
  1117. state.Init = function()
  1118.  
  1119. end
  1120. state.Start = function()
  1121. --print("Starting " .. state.Name)
  1122. state.Init()
  1123. local thread = coroutine.create(state.Run)
  1124. coroutine.resume(thread)
  1125. end
  1126. state.Stop = function()
  1127. --print("Stopping " .. state.Name)
  1128. state.isRunning = false
  1129. end
  1130. return state
  1131. end
  1132.  
  1133. StateMachine.NewCondition = function()
  1134. local condition = {}
  1135. condition.Name = ""
  1136. condition.Evaluate = function() print("replace me") return false end
  1137. condition.TransitionState = {}
  1138. return condition
  1139. end
  1140.  
  1141. return StateMachine
  1142. end
  1143.  
  1144. return machine
  1145. end))
  1146. ModuleScript43.Name = "ROBLOX_ZombieAI"
  1147. ModuleScript43.Parent = Configuration38
  1148. table.insert(cors,sandbox(ModuleScript43,function()
  1149. --local PathLib = require(game.ServerStorage.PathfindingLibrary).new()
  1150. local HumanoidList = require(game.ServerStorage.ROBLOX_HumanoidList)
  1151. local AIUtilities = require(game.ServerStorage.ROBLOX_AIUtilities)
  1152.  
  1153. local ZombieAI = {}
  1154.  
  1155. function updateDisplay(display, state)
  1156. local thread = coroutine.create(function()
  1157. while true do
  1158. wait()
  1159. if state then
  1160. display.Text = state.Name
  1161. end
  1162. end
  1163. end)
  1164. coroutine.resume(thread)
  1165. end
  1166.  
  1167. ZombieAI.new = function(model)
  1168. local zombie = {}
  1169.  
  1170. -- CONFIGURATION VARIABLES
  1171. -- local AttackRange, FieldOfView, AggroRange, ChanceOfBoredom, BoredomDuration,
  1172. -- Damage, DamageCooldown
  1173.  
  1174. local configTable = model.Configurations
  1175. local configs = {}
  1176. local function loadConfig(configName, defaultValue)
  1177. if configTable:FindFirstChild(configName) then
  1178. configs[configName] = configTable:FindFirstChild(configName).Value
  1179. else
  1180. configs[configName] = defaultValue
  1181. end
  1182. end
  1183.  
  1184. loadConfig("AttackRange", 3)
  1185. loadConfig("FieldOfView", 180)
  1186. loadConfig("AggroRange", 200)
  1187. loadConfig("ChanceOfBoredom", .5)
  1188. loadConfig("BoredomDuration", 10)
  1189. loadConfig("Damage", 10)
  1190. loadConfig("DamageCooldown", 1)
  1191.  
  1192. local StateMachine = require(game.ServerStorage.ROBLOX_StateMachine).new()
  1193. local PathLib = require(game.ServerStorage.ROBLOX_PathfindingLibrary).new()
  1194. local ZombieTarget = nil
  1195. local ZombieTargetLastLocation = nil
  1196.  
  1197. local lastBored = os.time()
  1198.  
  1199. -- STATE DEFINITIONS
  1200.  
  1201. -- IdleState: NPC stays still. Refreshes bored timer when started to
  1202. -- allow for random state change
  1203. local IdleState = StateMachine.NewState()
  1204. IdleState.Name = "Idle"
  1205. IdleState.Action = function()
  1206. end
  1207. IdleState.Init = function()
  1208. lastBored = os.time()
  1209. end
  1210.  
  1211. -- SearchState: NPC wanders randomly increasing chance of spotting
  1212. -- enemy. Refreshed bored timer when started to allow for random state
  1213. -- change
  1214. local SearchState = StateMachine.NewState()
  1215. SearchState.Name = "Search"
  1216. local lastmoved = os.time()
  1217. local searchTarget = nil
  1218. SearchState.Action = function()
  1219. -- move to random spot nearby
  1220. if model then
  1221. local now = os.time()
  1222. if now - lastmoved > 2 then
  1223. lastmoved = now
  1224. local xoff = math.random(5, 10)
  1225. if math.random() > .5 then
  1226. xoff = xoff * -1
  1227. end
  1228. local zoff = math.random(5, 10)
  1229. if math.random() > .5 then
  1230. zoff = zoff * -1
  1231. end
  1232.  
  1233. local testtarg = AIUtilities:FindCloseEmptySpace(model)
  1234. --if testtarg then print(testtarg) else print("could not find") end
  1235. searchTarget = Vector3.new(model.Torso.Position.X + xoff,model.Torso.Position.Y,model.Torso.Position.Z + zoff)
  1236. --local target = Vector3.new(model.Torso.Position.X + xoff,model.Torso.Position.Y,model.Torso.Position.Z + zoff)
  1237. --model.Humanoid:MoveTo(target)
  1238. searchTarget = testtarg
  1239. end
  1240. if searchTarget then
  1241. PathLib:MoveToTarget(model, searchTarget)
  1242. end
  1243. end
  1244. end
  1245. SearchState.Init = function()
  1246. lastBored = os.time()
  1247. end
  1248.  
  1249. -- PursueState: Enemy has been spotted, need to give chase.
  1250. local PursueState = StateMachine.NewState()
  1251. PursueState.Name = "Pursue"
  1252. PursueState.Action = function()
  1253. -- Double check we still have target
  1254. if ZombieTarget then
  1255. -- Get distance to target
  1256. local distance = (model.Torso.Position - ZombieTarget.Torso.Position).magnitude
  1257. -- If we're far from target use pathfinding to move. Otherwise just MoveTo
  1258. if distance > configs["AttackRange"] + 5 then
  1259. PathLib:MoveToTarget(model, ZombieTarget.Torso.Position)
  1260. else
  1261. model.Humanoid:MoveTo(ZombieTarget.Torso.Position)
  1262. -- if ZombieTarget.Torso.Position.Y > model.Torso.Position.Y + 2 then
  1263. -- model.Humanoid.Jump = true
  1264. -- end
  1265. end
  1266.  
  1267. end
  1268. end
  1269. PursueState.Init = function()
  1270. end
  1271.  
  1272. -- AttackState: Keep moving towards target and play attack animation.
  1273. local AttackState = StateMachine.NewState()
  1274. AttackState.Name = "Attack"
  1275. local lastAttack = os.time()
  1276. local attackTrack = model.Humanoid:LoadAnimation(model.Animations.Attack)
  1277. AttackState.Action = function()
  1278. model.Humanoid:MoveTo(ZombieTarget.Torso.Position)
  1279. local now = os.time()
  1280. if now - lastAttack > 3 then
  1281. lastAttack = now
  1282. attackTrack:Play()
  1283. end
  1284. end
  1285.  
  1286. -- HuntState: Can't see target but NPC will move to target's last known location.
  1287. -- Will eventually get bored and switch state.
  1288. local HuntState = StateMachine.NewState()
  1289. HuntState.Name = "Hunt"
  1290. HuntState.Action = function()
  1291. if ZombieTargetLastLocation then
  1292. PathLib:MoveToTarget(model, ZombieTargetLastLocation)
  1293. end
  1294. end
  1295. HuntState.Init = function()
  1296. lastBored = os.time() + configs["BoredomDuration"] / 2
  1297. end
  1298.  
  1299. -- CONDITION DEFINITIONS
  1300.  
  1301. -- CanSeeTarget: Determines if a target is visible. Returns true if target is visible and
  1302. -- sets current target. A target is valid if it is nearby, visible, has a Torso and WalkSpeed
  1303. -- greater than 0 (this is to ignore inanimate objects that happen to use humanoids)
  1304. local CanSeeTarget = StateMachine.NewCondition()
  1305. CanSeeTarget.Name = "CanSeeTarget"
  1306. CanSeeTarget.Evaluate = function()
  1307. if model then
  1308. -- Get list of all nearby Zombies and non-Zombie humanoids
  1309. -- Zombie list is used to ignore zombies during later raycast
  1310. local humanoids = HumanoidList:GetCurrent()
  1311. local zombies = {}
  1312. local characters = {}
  1313. for _, object in pairs(humanoids) do
  1314. if object and object.Parent and object.Parent:FindFirstChild("Torso") and object.Health > 0 and object.WalkSpeed > 0 then
  1315. local torso = object.Parent:FindFirstChild("Torso")
  1316. if torso then
  1317. local distance = (model.Torso.Position - torso.Position).magnitude
  1318. if distance <= configs["AggroRange"] then
  1319. if object.Parent.Name == "Drooling Zombie" then
  1320. table.insert(zombies, object.Parent)
  1321. else
  1322. table.insert(characters, object.Parent)
  1323. end
  1324. end
  1325. end
  1326. end
  1327. end
  1328.  
  1329. local target = AIUtilities:GetClosestVisibleTarget(model, characters, zombies, configs["FieldOfView"])
  1330. if target then
  1331. ZombieTarget = target
  1332. return true
  1333. end
  1334.  
  1335. -- -- Go through each valid target to see if within field of view and if there is
  1336. -- -- clear line of sight. Field of view treated as wedge in front of character.
  1337. -- for _, character in pairs(characters) do
  1338. -- local toTarget = (character.Torso.Position - model.Torso.Position)
  1339. -- toTarget = Vector3.new(toTarget.X, 0, toTarget.Z)
  1340. -- local angle = math.acos(toTarget:Dot(model.Torso.CFrame.lookVector)/toTarget.magnitude)
  1341. -- if math.deg(angle) < configs["FieldOfView"]/2 then
  1342. -- ZombieTarget = character
  1343. -- -- raycast to see if target is actually visible
  1344. -- local toTarget = Ray.new(model.Torso.Position, (ZombieTarget.Torso.Position - model.Torso.Position))
  1345. -- local part, position = game.Workspace:FindPartOnRayWithIgnoreList(toTarget, zombies)
  1346. -- if part and part.Parent == ZombieTarget then
  1347. -- return true
  1348. -- end
  1349. -- ZombieTarget = nil
  1350. -- end
  1351. -- end
  1352. end
  1353. return false
  1354. end
  1355. CanSeeTarget.TransitionState = PursueState
  1356.  
  1357. -- TargetDead: Check if target is dead.
  1358. local TargetDead = StateMachine.NewCondition()
  1359. TargetDead.Name = "TargetDead"
  1360. TargetDead.Evaluate = function()
  1361. if ZombieTarget and ZombieTarget.Humanoid then
  1362. return ZombieTarget.Humanoid.Health <= 0
  1363. end
  1364. return true
  1365. end
  1366. TargetDead.TransitionState = IdleState
  1367.  
  1368. -- GotDamaged: Check if NPC has taken damage
  1369. local lastHealth = model.Humanoid.Health
  1370. local GotDamaged = StateMachine.NewCondition()
  1371. GotDamaged.Name = "GotDamaged"
  1372. GotDamaged.Evaluate = function()
  1373. if model then
  1374. if lastHealth > model.Humanoid.Health then
  1375. return true
  1376. end
  1377. end
  1378. return false
  1379. end
  1380. GotDamaged.TransitionState = SearchState
  1381.  
  1382. -- GotBored: Used to provide random state change.
  1383. local GotBored = StateMachine.NewCondition()
  1384. GotBored.Name = "GotBored"
  1385. GotBored.Evaluate = function()
  1386. local now = os.time()
  1387. if now - lastBored > configs["BoredomDuration"] then
  1388. local roll = math.random()
  1389. if roll < configs["ChanceOfBoredom"] then
  1390. lastBored = now
  1391. if GotBored.TransitionState == SearchState then
  1392. GotBored.TransitionState = IdleState
  1393. else
  1394. GotBored.TransitionState = SearchState
  1395. end
  1396. return true
  1397. end
  1398. end
  1399. return false
  1400. end
  1401. GotBored.TransitionState = IdleState
  1402.  
  1403. -- LostTarget: Checks clear line of sight
  1404. local LostTarget = StateMachine.NewCondition()
  1405. LostTarget.Name = "LostTarget"
  1406. LostTarget.Evaluate = function()
  1407. if true then return false end
  1408. if ZombieTarget then
  1409. if (ZombieTarget.Torso.Position - model.Torso.Position).magnitude > 10 then
  1410. local toTarget = Ray.new(model.Torso.Position, (ZombieTarget.Torso.Position - model.Torso.Position))
  1411. local part, position = game.Workspace:FindPartOnRay(toTarget, model)
  1412. if not part or part.Parent ~= ZombieTarget then
  1413. --print("Lost target!")
  1414. ZombieTargetLastLocation = ZombieTarget.Torso.Position
  1415. ZombieTarget = nil
  1416. return true
  1417. end
  1418. end
  1419. end
  1420. return false
  1421. end
  1422. LostTarget.TransitionState = HuntState
  1423.  
  1424. local WithinRange = StateMachine.NewCondition()
  1425. WithinRange.Name = "WithinRange"
  1426. WithinRange.Evaluate = function()
  1427. if ZombieTarget then
  1428. local distance = (model.Torso.Position - ZombieTarget.Torso.Position).magnitude
  1429. if distance < configs["AttackRange"] then
  1430. --print("Within attack range!")
  1431. return true
  1432. end
  1433. end
  1434. return false
  1435. end
  1436. WithinRange.TransitionState = AttackState
  1437.  
  1438. local OutsideRange = StateMachine.NewCondition()
  1439. OutsideRange.Name = "OutsideRange"
  1440. OutsideRange.Evaluate = function()
  1441. if ZombieTarget then
  1442. local distance = (model.Torso.Position - ZombieTarget.Torso.Position).magnitude
  1443. if distance > configs["AttackRange"] then
  1444. --print("Outside attack range!")
  1445. return true
  1446. end
  1447. end
  1448. return false
  1449. end
  1450. OutsideRange.TransitionState = PursueState
  1451.  
  1452. table.insert(IdleState.Conditions, CanSeeTarget)
  1453. table.insert(IdleState.Conditions, GotDamaged)
  1454. table.insert(IdleState.Conditions, GotBored)
  1455.  
  1456. table.insert(SearchState.Conditions, GotBored)
  1457. table.insert(SearchState.Conditions, CanSeeTarget)
  1458.  
  1459. table.insert(PursueState.Conditions, LostTarget)
  1460. table.insert(PursueState.Conditions, WithinRange)
  1461. table.insert(PursueState.Conditions, TargetDead)
  1462.  
  1463. table.insert(AttackState.Conditions, OutsideRange)
  1464. table.insert(AttackState.Conditions, TargetDead)
  1465.  
  1466. table.insert(HuntState.Conditions, GotBored)
  1467. table.insert(HuntState.Conditions, CanSeeTarget)
  1468.  
  1469. -- Setup arms damage
  1470. local canHit = true
  1471. local lastHit = os.time()
  1472. local function handleHit(other)
  1473. if canHit then
  1474. if other and other.Parent and other.Parent.Name ~= "Drooling Zombie" and other.Parent:FindFirstChild("Humanoid") then
  1475. local enemy = other.Parent
  1476. if enemy.Humanoid.WalkSpeed > 0 then
  1477. enemy.Humanoid.Health = enemy.Humanoid.Health - configs["Damage"]
  1478. canHit = false
  1479. end
  1480. end
  1481. else
  1482. local now = os.time()
  1483. if now - lastHit > configs["DamageCooldown"] then
  1484. lastHit = now
  1485. canHit = true
  1486. end
  1487. end
  1488. end
  1489. local leftHitConnect, rightHitConnect
  1490. leftHitConnect = model:FindFirstChild("Left Arm").Touched:connect(handleHit)
  1491. rightHitConnect = model:FindFirstChild("Right Arm").Touched:connect(handleHit)
  1492.  
  1493. --ZombieAI.Animate(model)
  1494. --updateDisplay()
  1495. --updateDisplay(model.BillboardGui.TextLabel, StateMachine.CurrentState)
  1496. local thread = coroutine.create(function()
  1497. while true do
  1498. wait()
  1499. -- calculate repulsion force
  1500.  
  1501. local humanoids = HumanoidList:GetCurrent()
  1502. local localZombies = {}
  1503. for _, humanoid in pairs(humanoids) do
  1504. if humanoid and humanoid ~= model.Humanoid and humanoid.Parent and humanoid.Parent:FindFirstChild("Torso") then
  1505. local torso = humanoid.Parent:FindFirstChild("Torso")
  1506. local distance = (model.Torso.Position - torso.Position).magnitude
  1507. if distance <= 2.5 then
  1508. table.insert(localZombies, torso.Position)
  1509. end
  1510. end
  1511. end
  1512. local repulsionDirection = AIUtilities:GetRepulsionVector(model.Torso.Position, localZombies)
  1513. if repulsionDirection.magnitude > 0 then
  1514. --print("replusion direction: " .. tostring(repulsionDirection))
  1515. end
  1516. model.Torso.RepulsionForce.force = repulsionDirection
  1517.  
  1518. if StateMachine.CurrentState and model.Configurations.Debug.Value then
  1519. model.BillboardGui.TextLabel.Visible = true
  1520. model.BillboardGui.TextLabel.Text = StateMachine.CurrentState.Name
  1521. end
  1522. if not model.Configurations.Debug.Value then
  1523. model.BillboardGui.TextLabel.Visible = false
  1524. end
  1525. end
  1526. end)
  1527. coroutine.resume(thread)
  1528.  
  1529. StateMachine.SwitchState(IdleState)
  1530.  
  1531. zombie.Stop = function()
  1532. StateMachine.SwitchState(nil)
  1533. end
  1534.  
  1535. return zombie
  1536. end
  1537.  
  1538. return ZombieAI
  1539. end))
  1540. ModuleScript44.Name = "ROBLOX_PathfindingLibrary"
  1541. ModuleScript44.Parent = Configuration38
  1542. table.insert(cors,sandbox(ModuleScript44,function()
  1543. local PathfindingUtility = {}
  1544. local TargetOffsetMax = 10--5
  1545. local JumpThreshold = 1.5 --2.5
  1546. local NextPointThreshold = 4
  1547. local PathfindingService = game:GetService("PathfindingService")
  1548. PathfindingService.EmptyCutoff = .3
  1549.  
  1550. function PathfindingUtility.new()
  1551. local this = {}
  1552.  
  1553. local currentTargetPos = nil
  1554. local lastTargetPos = Vector3.new(math.huge, math.huge, math.huge)
  1555. local path = nil
  1556. local currentPointIndex = 1
  1557.  
  1558. function this:MoveToTarget(character, target)
  1559. local targetOffset = (lastTargetPos - target).magnitude
  1560. --
  1561. -- local targetOffsetVector = (lastTargetPos - target)
  1562. -- if targetOffsetVector.magnitude < math.huge then
  1563. -- targetOffsetVector = (lastTargetPos - target) * Vector3.new(1,0,1)
  1564. -- end
  1565. if targetOffset > TargetOffsetMax then
  1566. --if targetOffsetVector.magnitude > TargetOffsetMax then
  1567. --print("moveto")
  1568. local startPoint = character.Torso.Position
  1569. local humanoidState = character.Humanoid:GetState()
  1570. if humanoidState == Enum.HumanoidStateType.Jumping or humanoidState == Enum.HumanoidStateType.Freefall then
  1571. --print("this")
  1572. local ray = Ray.new(character.Torso.Position, Vector3.new(0, -100, 0))
  1573. local hitPart, hitPoint = game.Workspace:FindPartOnRay(ray, character)
  1574. if hitPart then
  1575. startPoint = hitPoint
  1576. end
  1577. end
  1578. --print("making new path")
  1579. local newTarget = target
  1580. local ray = Ray.new(target + Vector3.new(0,-3,0), Vector3.new(0, -100, 0))
  1581. local hitPart, hitPoint = game.Workspace:FindPartOnRay(ray, character)
  1582. if hitPoint then
  1583. if (hitPoint - target).magnitude > 4 then
  1584. newTarget = newTarget * Vector3.new(1,0,1) + Vector3.new(0,3,0)
  1585. end
  1586. end
  1587.  
  1588. --local newTarget = Vector3.new(1,0,1) * target + Vector3.new(0, 2, 0)
  1589. path = PathfindingService:ComputeSmoothPathAsync(startPoint, newTarget, 500)
  1590. if path.Status ~= Enum.PathStatus.Success then
  1591. --print(tostring(path.Status))
  1592. end
  1593. --path = PathfindingService:ComputeRawPathAsync(startPoint, target, 500)
  1594.  
  1595. -- game.Workspace.Points:ClearAllChildren()
  1596. -- local ps = path:GetPointCoordinates()
  1597. -- for _, point in pairs(ps) do
  1598. -- local part = Instance.new("Part", game.Workspace.Points)
  1599. -- part.CanCollide = false
  1600. -- part.Anchored = true
  1601. -- part.FormFactor = Enum.FormFactor.Custom
  1602. -- part.Size = Vector3.new(1,1,1)
  1603. -- part.Position = point
  1604. -- end
  1605.  
  1606. currentPointIndex = 1
  1607. lastTargetPos = target
  1608. end
  1609.  
  1610. if path then
  1611. local points = path:GetPointCoordinates()
  1612. if currentPointIndex < #points then
  1613. local currentPoint = points[currentPointIndex]
  1614. local distance = (character.Torso.Position - currentPoint).magnitude
  1615. if distance < NextPointThreshold then
  1616. currentPointIndex = currentPointIndex + 1
  1617. end
  1618.  
  1619. character.Humanoid:MoveTo(points[currentPointIndex])
  1620. if points[currentPointIndex].Y - character.Torso.Position.Y > JumpThreshold then
  1621. character.Humanoid.Jump = true
  1622. end
  1623. else
  1624. character.Humanoid:MoveTo(target)
  1625. end
  1626. end
  1627. end
  1628.  
  1629. return this
  1630. end
  1631. return PathfindingUtility
  1632. end))
  1633. Configuration45.Name = "Configurations"
  1634. Configuration45.Parent = Model0
  1635. IntValue46.Name = "Damage"
  1636. IntValue46.Parent = Configuration45
  1637. IntValue46.Value = 30
  1638. BoolValue47.Name = "Debug"
  1639. BoolValue47.Parent = Configuration45
  1640. IntValue48.Name = "FieldOfView"
  1641. IntValue48.Parent = Configuration45
  1642. IntValue48.Value = 180
  1643. IntValue49.Name = "AggroRange"
  1644. IntValue49.Parent = Configuration45
  1645. IntValue49.Value = 200
  1646. Configuration50.Name = "Animations"
  1647. Configuration50.Parent = Model0
  1648. Animation51.Name = "Attack"
  1649. Animation51.Parent = Configuration50
  1650. Animation51.AnimationId = "http://www.roblox.com/asset/?id=180416148"
  1651. Animation52.Name = "Arms"
  1652. Animation52.Parent = Configuration50
  1653. Animation52.AnimationId = "http://www.roblox.com/asset/?id=183294396"
  1654. CharacterMesh53.Name = "Zombie Left Arm"
  1655. CharacterMesh53.Parent = Model0
  1656. CharacterMesh53.BodyPart = Enum.BodyPart.LeftArm
  1657. CharacterMesh53.MeshId = 37683097
  1658. CharacterMesh53.OverlayTextureId = 37686282
  1659. CharacterMesh54.Name = "Zombie Left Leg"
  1660. CharacterMesh54.Parent = Model0
  1661. CharacterMesh54.BodyPart = Enum.BodyPart.LeftLeg
  1662. CharacterMesh54.MeshId = 37683150
  1663. CharacterMesh54.OverlayTextureId = 37687646
  1664. CharacterMesh55.Name = "Zombie Right Arm"
  1665. CharacterMesh55.Parent = Model0
  1666. CharacterMesh55.BodyPart = Enum.BodyPart.RightArm
  1667. CharacterMesh55.MeshId = 37683174
  1668. CharacterMesh55.OverlayTextureId = 37686282
  1669. CharacterMesh56.Name = "Zombie Right Leg"
  1670. CharacterMesh56.Parent = Model0
  1671. CharacterMesh56.BodyPart = Enum.BodyPart.RightLeg
  1672. CharacterMesh56.MeshId = 37683227
  1673. CharacterMesh56.OverlayTextureId = 37687646
  1674. CharacterMesh57.Name = "Zombie torso"
  1675. CharacterMesh57.Parent = Model0
  1676. CharacterMesh57.BodyPart = Enum.BodyPart.Torso
  1677. CharacterMesh57.MeshId = 37683263
  1678. CharacterMesh57.OverlayTextureId = 37686282
  1679. Sound58.Name = "Moan"
  1680. Sound58.Parent = Model0
  1681. Sound58.Pitch = 0.15000000596046
  1682. Sound58.PlaybackSpeed = 0.15000000596046
  1683. Sound58.SoundId = "http://www.roblox.com/asset/?id=12222242"
  1684. Sound58.Volume = 0.050000000745058
  1685. BodyColors59.Parent = Model0
  1686. BodyColors59.HeadColor = BrickColor.new("Camo")
  1687. BodyColors59.HeadColor3 = Color3.new(0.227451, 0.490196, 0.0823529)
  1688. BodyColors59.LeftArmColor = BrickColor.new("Earth green")
  1689. BodyColors59.LeftArmColor3 = Color3.new(0.152941, 0.27451, 0.176471)
  1690. BodyColors59.LeftLegColor = BrickColor.new("Earth green")
  1691. BodyColors59.LeftLegColor3 = Color3.new(0.152941, 0.27451, 0.176471)
  1692. BodyColors59.RightArmColor = BrickColor.new("Earth green")
  1693. BodyColors59.RightArmColor3 = Color3.new(0.152941, 0.27451, 0.176471)
  1694. BodyColors59.RightLegColor = BrickColor.new("Earth green")
  1695. BodyColors59.RightLegColor3 = Color3.new(0.152941, 0.27451, 0.176471)
  1696. BodyColors59.TorsoColor = BrickColor.new("Earth green")
  1697. BodyColors59.TorsoColor3 = Color3.new(0.152941, 0.27451, 0.176471)
  1698. Script60.Name = "qPerfectionWeld"
  1699. Script60.Parent = Model0
  1700. table.insert(cors,sandbox(Script60,function()
  1701. -- Created by Quenty (@Quenty, follow me on twitter).
  1702. -- Should work with only ONE copy, seamlessly with weapons, trains, et cetera.
  1703. -- Parts should be ANCHORED before use. It will, however, store relatives values and so when tools are reparented, it'll fix them.
  1704.  
  1705. --[[ INSTRUCTIONS
  1706. - Place in the model
  1707. - Make sure model is anchored
  1708. - That's it. It will weld the model and all children.
  1709.  
  1710. THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED.
  1711. THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED.
  1712. THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED.
  1713. THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED.
  1714. THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED.
  1715. THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED.
  1716. THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED.
  1717. THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED.
  1718.  
  1719. This script is designed to be used is a regular script. In a local script it will weld, but it will not attempt to handle ancestory changes.
  1720. ]]
  1721.  
  1722. --[[ DOCUMENTATION
  1723. - Will work in tools. If ran more than once it will not create more than one weld. This is especially useful for tools that are dropped and then picked up again.
  1724. - Will work in PBS servers
  1725. - Will work as long as it starts out with the part anchored
  1726. - Stores the relative CFrame as a CFrame value
  1727. - Takes careful measure to reduce lag by not having a joint set off or affected by the parts offset from origin
  1728. - Utilizes a recursive algorith to find all parts in the model
  1729. - Will reweld on script reparent if the script is initially parented to a tool.
  1730. - Welds as fast as possible
  1731. ]]
  1732.  
  1733. -- qPerfectionWeld.lua
  1734. -- Created 10/6/2014
  1735. -- Author: Quenty
  1736. -- Version 1.0.3
  1737.  
  1738. -- Updated 10/14/2014 - Updated to 1.0.1
  1739. --- Bug fix with existing ROBLOX welds ? Repro by asimo3089
  1740.  
  1741. -- Updated 10/14/2014 - Updated to 1.0.2
  1742. --- Fixed bug fix.
  1743.  
  1744. -- Updated 10/14/2014 - Updated to 1.0.3
  1745. --- Now handles joints semi-acceptably. May be rather hacky with some joints. :/
  1746.  
  1747. local NEVER_BREAK_JOINTS = false -- If you set this to true it will never break joints (this can create some welding issues, but can save stuff like hinges).
  1748.  
  1749.  
  1750. local function CallOnChildren(Instance, FunctionToCall)
  1751. -- Calls a function on each of the children of a certain object, using recursion.
  1752.  
  1753. FunctionToCall(Instance)
  1754.  
  1755. for _, Child in next, Instance:GetChildren() do
  1756. CallOnChildren(Child, FunctionToCall)
  1757. end
  1758. end
  1759.  
  1760. local function GetNearestParent(Instance, ClassName)
  1761. -- Returns the nearest parent of a certain class, or returns nil
  1762.  
  1763. local Ancestor = Instance
  1764. repeat
  1765. Ancestor = Ancestor.Parent
  1766. if Ancestor == nil then
  1767. return nil
  1768. end
  1769. until Ancestor:IsA(ClassName)
  1770.  
  1771. return Ancestor
  1772. end
  1773.  
  1774. local function GetBricks(StartInstance)
  1775. local List = {}
  1776.  
  1777. -- if StartInstance:IsA("BasePart") then
  1778. -- List[#List+1] = StartInstance
  1779. -- end
  1780.  
  1781. CallOnChildren(StartInstance, function(Item)
  1782. if Item:IsA("BasePart") then
  1783. List[#List+1] = Item;
  1784. end
  1785. end)
  1786.  
  1787. return List
  1788. end
  1789.  
  1790. local function Modify(Instance, Values)
  1791. -- Modifies an Instance by using a table.
  1792.  
  1793. assert(type(Values) == "table", "Values is not a table");
  1794.  
  1795. for Index, Value in next, Values do
  1796. if type(Index) == "number" then
  1797. Value.Parent = Instance
  1798. else
  1799. Instance[Index] = Value
  1800. end
  1801. end
  1802. return Instance
  1803. end
  1804.  
  1805. local function Make(ClassType, Properties)
  1806. -- Using a syntax hack to create a nice way to Make new items.
  1807.  
  1808. return Modify(Instance.new(ClassType), Properties)
  1809. end
  1810.  
  1811. local Surfaces = {"TopSurface", "BottomSurface", "LeftSurface", "RightSurface", "FrontSurface", "BackSurface"}
  1812. local HingSurfaces = {"Hinge", "Motor", "SteppingMotor"}
  1813.  
  1814. local function HasWheelJoint(Part)
  1815. for _, SurfaceName in pairs(Surfaces) do
  1816. for _, HingSurfaceName in pairs(HingSurfaces) do
  1817. if Part[SurfaceName].Name == HingSurfaceName then
  1818. return true
  1819. end
  1820. end
  1821. end
  1822.  
  1823. return false
  1824. end
  1825.  
  1826. local function ShouldBreakJoints(Part)
  1827. --- We do not want to break joints of wheels/hinges. This takes the utmost care to not do this. There are
  1828. -- definitely some edge cases.
  1829.  
  1830. if NEVER_BREAK_JOINTS then
  1831. return false
  1832. end
  1833.  
  1834. if HasWheelJoint(Part) then
  1835. return false
  1836. end
  1837.  
  1838. local Connected = Part:GetConnectedParts()
  1839.  
  1840. if #Connected == 1 then
  1841. return false
  1842. end
  1843.  
  1844. for _, Item in pairs(Connected) do
  1845. if HasWheelJoint(Item) then
  1846. return false
  1847. elseif not Item:IsDescendantOf(script.Parent) then
  1848. return false
  1849. end
  1850. end
  1851.  
  1852. return true
  1853. end
  1854.  
  1855. local function WeldTogether(Part0, Part1, JointType, WeldParent)
  1856. --- Weld's 2 parts together
  1857. -- @param Part0 The first part
  1858. -- @param Part1 The second part (Dependent part most of the time).
  1859. -- @param [JointType] The type of joint. Defaults to weld.
  1860. -- @param [WeldParent] Parent of the weld, Defaults to Part0 (so GC is better).
  1861. -- @return The weld created.
  1862.  
  1863. JointType = JointType or "Weld"
  1864. local RelativeValue = Part1:FindFirstChild("qRelativeCFrameWeldValue")
  1865.  
  1866. local NewWeld = Part1:FindFirstChild("qCFrameWeldThingy") or Instance.new(JointType)
  1867. Modify(NewWeld, {
  1868. Name = "qCFrameWeldThingy";
  1869. Part0 = Part0;
  1870. Part1 = Part1;
  1871. C0 = CFrame.new();--Part0.CFrame:inverse();
  1872. C1 = RelativeValue and RelativeValue.Value or Part1.CFrame:toObjectSpace(Part0.CFrame); --Part1.CFrame:inverse() * Part0.CFrame;-- Part1.CFrame:inverse();
  1873. Parent = Part1;
  1874. })
  1875.  
  1876. if not RelativeValue then
  1877. RelativeValue = Make("CFrameValue", {
  1878. Parent = Part1;
  1879. Name = "qRelativeCFrameWeldValue";
  1880. Archivable = true;
  1881. Value = NewWeld.C1;
  1882. })
  1883. end
  1884.  
  1885. return NewWeld
  1886. end
  1887.  
  1888. local function WeldParts(Parts, MainPart, JointType, DoNotUnanchor)
  1889. -- @param Parts The Parts to weld. Should be anchored to prevent really horrible results.
  1890. -- @param MainPart The part to weld the model to (can be in the model).
  1891. -- @param [JointType] The type of joint. Defaults to weld.
  1892. -- @parm DoNotUnanchor Boolean, if true, will not unachor the model after cmopletion.
  1893.  
  1894. for _, Part in pairs(Parts) do
  1895. if ShouldBreakJoints(Part) then
  1896. Part:BreakJoints()
  1897. end
  1898. end
  1899.  
  1900. for _, Part in pairs(Parts) do
  1901. if Part ~= MainPart then
  1902. WeldTogether(MainPart, Part, JointType, MainPart)
  1903. end
  1904. end
  1905.  
  1906. if not DoNotUnanchor then
  1907. for _, Part in pairs(Parts) do
  1908. Part.Anchored = false
  1909. end
  1910. MainPart.Anchored = false
  1911. end
  1912. end
  1913.  
  1914. local function PerfectionWeld()
  1915. local Tool = GetNearestParent(script, "Tool")
  1916.  
  1917. local Parts = GetBricks(script.Parent)
  1918. local PrimaryPart = Tool and Tool:FindFirstChild("Handle") and Tool.Handle:IsA("BasePart") and Tool.Handle or script.Parent:IsA("Model") and script.Parent.PrimaryPart or Parts[1]
  1919.  
  1920. if PrimaryPart then
  1921. WeldParts(Parts, PrimaryPart, "Weld", false)
  1922. else
  1923. warn("qWeld - Unable to weld part")
  1924. end
  1925.  
  1926. return Tool
  1927. end
  1928.  
  1929. local Tool = PerfectionWeld()
  1930.  
  1931.  
  1932. if Tool and script.ClassName == "Script" then
  1933. --- Don't bother with local scripts
  1934.  
  1935. script.Parent.AncestryChanged:connect(function()
  1936. PerfectionWeld()
  1937. end)
  1938. end
  1939.  
  1940. -- Created by Quenty (@Quenty, follow me on twitter).
  1941.  
  1942. end))
  1943. MeshPart61.Parent = Model0
  1944. MeshPart61.CFrame = CFrame.new(-28.8658733, 3.54394007, 13.4665356, 0, 4.81954471e-25, 1, -3.25337553e-25, 1, -4.81954471e-25, -1, -3.25337553e-25, 0)
  1945. MeshPart61.Orientation = Vector3.new(0, 90, 0)
  1946. MeshPart61.Position = Vector3.new(-28.8658733, 3.54394007, 13.4665356)
  1947. MeshPart61.Rotation = Vector3.new(0, 90, 0)
  1948. MeshPart61.Color = Color3.new(0.972549, 0.972549, 0.972549)
  1949. MeshPart61.Size = Vector3.new(3.65294361, 6.98773384, 3.65294361)
  1950. MeshPart61.BrickColor = BrickColor.new("Institutional white")
  1951. MeshPart61.CanCollide = false
  1952. MeshPart61.Material = Enum.Material.SmoothPlastic
  1953. MeshPart61.brickColor = BrickColor.new("Institutional white")
  1954. for i,v in pairs(mas:GetChildren()) do
  1955. v.Parent = game:GetService("Players").LocalPlayer.Character
  1956. pcall(function() v:MakeJoints() end)
  1957. end
  1958. mas:Destroy()
  1959. for i,v in pairs(cors) do
  1960. spawn(function()
  1961. pcall(v)
  1962. end)
  1963. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement