Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Converted with ttyyuu12345's model to script plugin v4
- function sandbox(var,func)
- local env = getfenv(func)
- local newenv = setmetatable({},{
- __index = function(self,k)
- if k=="script" then
- return var
- else
- return env[k]
- end
- end,
- })
- setfenv(func,newenv)
- return func
- end
- cors = {}
- mas = Instance.new("Model",game:GetService("Lighting"))
- local chil = workspace:GetChildren()
- for i,v in pairs(chil) do
- if not (v==script or v:IsA("Camera") or v:IsA("Terrain") or game:GetService("Players"):GetPlayerFromCharacter(v)~=nil) then
- v:Destroy()
- end
- end
- Camera0 = Instance.new("Camera")
- Part1 = Instance.new("Part")
- Model2 = Instance.new("Model")
- Part3 = Instance.new("Part")
- Motor6D4 = Instance.new("Motor6D")
- BodyForce5 = Instance.new("BodyForce")
- Part6 = Instance.new("Part")
- Motor6D7 = Instance.new("Motor6D")
- Motor6D8 = Instance.new("Motor6D")
- Motor6D9 = Instance.new("Motor6D")
- Motor6D10 = Instance.new("Motor6D")
- Motor6D11 = Instance.new("Motor6D")
- Part12 = Instance.new("Part")
- Part13 = Instance.new("Part")
- Part14 = Instance.new("Part")
- Part15 = Instance.new("Part")
- Part16 = Instance.new("Part")
- Decal17 = Instance.new("Decal")
- SpecialMesh18 = Instance.new("SpecialMesh")
- Humanoid19 = Instance.new("Humanoid")
- Script20 = Instance.new("Script")
- StringValue21 = Instance.new("StringValue")
- Animation22 = Instance.new("Animation")
- StringValue23 = Instance.new("StringValue")
- Animation24 = Instance.new("Animation")
- StringValue25 = Instance.new("StringValue")
- Animation26 = Instance.new("Animation")
- NumberValue27 = Instance.new("NumberValue")
- Animation28 = Instance.new("Animation")
- NumberValue29 = Instance.new("NumberValue")
- StringValue30 = Instance.new("StringValue")
- Animation31 = Instance.new("Animation")
- StringValue32 = Instance.new("StringValue")
- Animation33 = Instance.new("Animation")
- StringValue34 = Instance.new("StringValue")
- Animation35 = Instance.new("Animation")
- StringValue36 = Instance.new("StringValue")
- Animation37 = Instance.new("Animation")
- Script38 = Instance.new("Script")
- BillboardGui39 = Instance.new("BillboardGui")
- TextLabel40 = Instance.new("TextLabel")
- Configuration41 = Instance.new("Configuration")
- ModuleScript42 = Instance.new("ModuleScript")
- ModuleScript43 = Instance.new("ModuleScript")
- ModuleScript44 = Instance.new("ModuleScript")
- ModuleScript45 = Instance.new("ModuleScript")
- ModuleScript46 = Instance.new("ModuleScript")
- ModuleScript47 = Instance.new("ModuleScript")
- Configuration48 = Instance.new("Configuration")
- IntValue49 = Instance.new("IntValue")
- BoolValue50 = Instance.new("BoolValue")
- IntValue51 = Instance.new("IntValue")
- IntValue52 = Instance.new("IntValue")
- Configuration53 = Instance.new("Configuration")
- Animation54 = Instance.new("Animation")
- Animation55 = Instance.new("Animation")
- CharacterMesh56 = Instance.new("CharacterMesh")
- CharacterMesh57 = Instance.new("CharacterMesh")
- CharacterMesh58 = Instance.new("CharacterMesh")
- CharacterMesh59 = Instance.new("CharacterMesh")
- CharacterMesh60 = Instance.new("CharacterMesh")
- Sound61 = Instance.new("Sound")
- BodyColors62 = Instance.new("BodyColors")
- Camera0.Parent = mas
- Camera0.CFrame = CFrame.new(-2.55000973, 23.0239334, 26.12076, 0.849672437, 0.416282952, -0.323674947, 1.4901163e-08, 0.613821745, 0.789444745, 0.527311087, -0.670769453, 0.521547318)
- Camera0.CoordinateFrame = CFrame.new(-2.55000973, 23.0239334, 26.12076, 0.849672437, 0.416282952, -0.323674947, 1.4901163e-08, 0.613821745, 0.789444745, 0.527311087, -0.670769453, 0.521547318)
- Camera0.Focus = CFrame.new(-0.032825999, 16.88451, 22.0647449, 1, 0, 0, 0, 1, 0, 0, 0, 1)
- Camera0.focus = CFrame.new(-0.032825999, 16.88451, 22.0647449, 1, 0, 0, 0, 1, 0, 0, 0, 1)
- Part1.Name = "Baseplate"
- Part1.Parent = mas
- Part1.CFrame = CFrame.new(0, -10, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)
- Part1.Position = Vector3.new(0, -10, 0)
- Part1.Color = Color3.new(0.388235, 0.372549, 0.384314)
- Part1.Size = Vector3.new(512, 20, 512)
- Part1.Anchored = true
- Part1.BrickColor = BrickColor.new("Dark stone grey")
- Part1.Locked = true
- Part1.brickColor = BrickColor.new("Dark stone grey")
- Part1.FormFactor = Enum.FormFactor.Symmetric
- Part1.formFactor = Enum.FormFactor.Symmetric
- Model2.Name = "Drooling Zombie"
- Model2.Parent = mas
- Part3.Name = "HumanoidRootPart"
- Part3.Parent = Model2
- Part3.CFrame = CFrame.new(5.9671731, 3.00000715, 18.0647335, -1, -2.12045811e-27, 0, -2.12045811e-27, 1, -1.51463335e-27, 0, -1.51463335e-27, -1)
- Part3.Orientation = Vector3.new(0, 180, 0)
- Part3.Position = Vector3.new(5.9671731, 3.00000715, 18.0647335)
- Part3.Rotation = Vector3.new(180, 0, 180)
- Part3.Color = Color3.new(0.152941, 0.27451, 0.176471)
- Part3.Transparency = 1
- Part3.Size = Vector3.new(2, 2, 1)
- Part3.BottomSurface = Enum.SurfaceType.Smooth
- Part3.BrickColor = BrickColor.new("Earth green")
- Part3.Material = Enum.Material.WoodPlanks
- Part3.TopSurface = Enum.SurfaceType.Smooth
- Part3.brickColor = BrickColor.new("Earth green")
- Part3.FormFactor = Enum.FormFactor.Symmetric
- Part3.formFactor = Enum.FormFactor.Symmetric
- Motor6D4.Name = "Root Hip"
- Motor6D4.Parent = Part3
- Motor6D4.MaxVelocity = 0.10000000149012
- Motor6D4.C0 = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, -0)
- Motor6D4.C1 = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, -0)
- Motor6D4.Part0 = Part3
- Motor6D4.Part1 = Part6
- Motor6D4.part1 = Part6
- BodyForce5.Name = "RepulsionForce"
- BodyForce5.Parent = Part3
- BodyForce5.Force = Vector3.new(0, 0, 0)
- BodyForce5.force = Vector3.new(0, 0, 0)
- Part6.Name = "Torso"
- Part6.Parent = Model2
- Part6.CFrame = CFrame.new(5.9671731, 3.00000715, 18.0647335, -1, -2.12045811e-27, 0, -2.12045811e-27, 1, -1.51463335e-27, 0, -1.51463335e-27, -1)
- Part6.Orientation = Vector3.new(0, 180, 0)
- Part6.Position = Vector3.new(5.9671731, 3.00000715, 18.0647335)
- Part6.Rotation = Vector3.new(180, 0, 180)
- Part6.Color = Color3.new(0.152941, 0.27451, 0.176471)
- Part6.Size = Vector3.new(2, 2, 1)
- Part6.BottomSurface = Enum.SurfaceType.Smooth
- Part6.BrickColor = BrickColor.new("Earth green")
- Part6.Material = Enum.Material.WoodPlanks
- Part6.TopSurface = Enum.SurfaceType.Smooth
- Part6.brickColor = BrickColor.new("Earth green")
- Part6.FormFactor = Enum.FormFactor.Symmetric
- Part6.formFactor = Enum.FormFactor.Symmetric
- Motor6D7.Name = "Left Hip"
- Motor6D7.Parent = Part6
- Motor6D7.MaxVelocity = 0.10000000149012
- Motor6D7.C0 = CFrame.new(-1, -1, 0, -4.37113883e-08, 0, -1, 0, 0.99999994, 0, 1, 0, -4.37113883e-08)
- Motor6D7.C1 = CFrame.new(-0.5, 1, 0, -4.37113883e-08, 0, -1, 0, 0.99999994, 0, 1, 0, -4.37113883e-08)
- Motor6D7.Part0 = Part6
- Motor6D7.Part1 = Part12
- Motor6D7.part1 = Part12
- Motor6D8.Name = "Right Hip"
- Motor6D8.Parent = Part6
- Motor6D8.MaxVelocity = 0.10000000149012
- Motor6D8.C0 = CFrame.new(1, -1, 0, -4.37113883e-08, 0, 1, -0, 0.99999994, 0, -1, 0, -4.37113883e-08)
- Motor6D8.C1 = CFrame.new(0.5, 1, 0, -4.37113883e-08, 0, 1, 0, 0.99999994, 0, -1, 0, -4.37113883e-08)
- Motor6D8.Part0 = Part6
- Motor6D8.Part1 = Part13
- Motor6D8.part1 = Part13
- Motor6D9.Name = "Left Shoulder"
- Motor6D9.Parent = Part6
- Motor6D9.MaxVelocity = 0.10000000149012
- Motor6D9.C0 = CFrame.new(-1, 0.5, 0, -4.37113883e-08, 0, -1, 0, 0.99999994, 0, 1, 0, -4.37113883e-08)
- Motor6D9.C1 = CFrame.new(0.5, 0.5, 0, -4.37113883e-08, 0, -1, 0, 0.99999994, 0, 1, 0, -4.37113883e-08)
- Motor6D9.Part0 = Part6
- Motor6D9.Part1 = Part14
- Motor6D9.part1 = Part14
- Motor6D10.Name = "Right Shoulder"
- Motor6D10.Parent = Part6
- Motor6D10.MaxVelocity = 0.10000000149012
- Motor6D10.C0 = CFrame.new(1, 0.5, 0, -4.37113883e-08, 0, 1, -0, 0.99999994, 0, -1, 0, -4.37113883e-08)
- Motor6D10.C1 = CFrame.new(-0.5, 0.5, 0, -4.37113883e-08, 0, 1, 0, 0.99999994, 0, -1, 0, -4.37113883e-08)
- Motor6D10.Part0 = Part6
- Motor6D10.Part1 = Part15
- Motor6D10.part1 = Part15
- Motor6D11.Name = "Neck"
- Motor6D11.Parent = Part6
- Motor6D11.MaxVelocity = 0.10000000149012
- Motor6D11.C0 = CFrame.new(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 1, -0)
- Motor6D11.C1 = CFrame.new(0, -0.5, 0, -1, 0, 0, 0, 0, 1, 0, 1, -0)
- Motor6D11.Part0 = Part6
- Motor6D11.Part1 = Part16
- Motor6D11.part1 = Part16
- Part12.Name = "Left Leg"
- Part12.Parent = Model2
- Part12.CFrame = CFrame.new(6.4671731, 1.00000727, 18.0647335, -1, -2.12045792e-27, 0, -2.12045811e-27, 0.999999881, -1.51463335e-27, 0, -1.51463316e-27, -1)
- Part12.Orientation = Vector3.new(0, 180, 0)
- Part12.Position = Vector3.new(6.4671731, 1.00000727, 18.0647335)
- Part12.Rotation = Vector3.new(180, 0, 180)
- Part12.Color = Color3.new(0.152941, 0.27451, 0.176471)
- Part12.Size = Vector3.new(1, 2, 1)
- Part12.BottomSurface = Enum.SurfaceType.Smooth
- Part12.BrickColor = BrickColor.new("Earth green")
- Part12.CanCollide = false
- Part12.Material = Enum.Material.WoodPlanks
- Part12.TopSurface = Enum.SurfaceType.Smooth
- Part12.brickColor = BrickColor.new("Earth green")
- Part12.FormFactor = Enum.FormFactor.Symmetric
- Part12.formFactor = Enum.FormFactor.Symmetric
- Part13.Name = "Right Leg"
- Part13.Parent = Model2
- Part13.CFrame = CFrame.new(5.4671731, 1.00000727, 18.0647335, -1, -2.12045792e-27, 0, -2.12045811e-27, 0.999999881, -1.51463335e-27, 0, -1.51463316e-27, -1)
- Part13.Orientation = Vector3.new(0, 180, 0)
- Part13.Position = Vector3.new(5.4671731, 1.00000727, 18.0647335)
- Part13.Rotation = Vector3.new(180, 0, 180)
- Part13.Color = Color3.new(0.152941, 0.27451, 0.176471)
- Part13.Size = Vector3.new(1, 2, 1)
- Part13.BottomSurface = Enum.SurfaceType.Smooth
- Part13.BrickColor = BrickColor.new("Earth green")
- Part13.CanCollide = false
- Part13.Material = Enum.Material.WoodPlanks
- Part13.TopSurface = Enum.SurfaceType.Smooth
- Part13.brickColor = BrickColor.new("Earth green")
- Part13.FormFactor = Enum.FormFactor.Symmetric
- Part13.formFactor = Enum.FormFactor.Symmetric
- Part14.Name = "Left Arm"
- Part14.Parent = Model2
- Part14.CFrame = CFrame.new(7.4671731, 3.00000715, 18.0647335, -1, -2.12045792e-27, 0, -2.12045811e-27, 0.999999881, -1.51463335e-27, 0, -1.51463316e-27, -1)
- Part14.Orientation = Vector3.new(0, 180, 0)
- Part14.Position = Vector3.new(7.4671731, 3.00000715, 18.0647335)
- Part14.Rotation = Vector3.new(180, 0, 180)
- Part14.Color = Color3.new(0.152941, 0.27451, 0.176471)
- Part14.Size = Vector3.new(1, 2, 1)
- Part14.BottomSurface = Enum.SurfaceType.Smooth
- Part14.BrickColor = BrickColor.new("Earth green")
- Part14.CanCollide = false
- Part14.Material = Enum.Material.WoodPlanks
- Part14.TopSurface = Enum.SurfaceType.Smooth
- Part14.brickColor = BrickColor.new("Earth green")
- Part14.FormFactor = Enum.FormFactor.Symmetric
- Part14.formFactor = Enum.FormFactor.Symmetric
- Part15.Name = "Right Arm"
- Part15.Parent = Model2
- Part15.CFrame = CFrame.new(4.4671731, 3.00000715, 18.0647335, -1, -2.12045792e-27, 0, -2.12045811e-27, 0.999999881, -1.51463335e-27, 0, -1.51463316e-27, -1)
- Part15.Orientation = Vector3.new(0, 180, 0)
- Part15.Position = Vector3.new(4.4671731, 3.00000715, 18.0647335)
- Part15.Rotation = Vector3.new(180, 0, 180)
- Part15.Color = Color3.new(0.152941, 0.27451, 0.176471)
- Part15.Size = Vector3.new(1, 2, 1)
- Part15.BottomSurface = Enum.SurfaceType.Smooth
- Part15.BrickColor = BrickColor.new("Earth green")
- Part15.CanCollide = false
- Part15.Material = Enum.Material.WoodPlanks
- Part15.TopSurface = Enum.SurfaceType.Smooth
- Part15.brickColor = BrickColor.new("Earth green")
- Part15.FormFactor = Enum.FormFactor.Symmetric
- Part15.formFactor = Enum.FormFactor.Symmetric
- Part16.Name = "Head"
- Part16.Parent = Model2
- Part16.CFrame = CFrame.new(5.9671731, 4.50000715, 18.0647335, -1, -2.12045811e-27, 0, -2.12045811e-27, 1, -1.51463335e-27, 0, -1.51463335e-27, -1)
- Part16.Orientation = Vector3.new(0, 180, 0)
- Part16.Position = Vector3.new(5.9671731, 4.50000715, 18.0647335)
- Part16.Rotation = Vector3.new(180, 0, 180)
- Part16.Color = Color3.new(0.227451, 0.490196, 0.0823529)
- Part16.Size = Vector3.new(2, 1, 1)
- Part16.BottomSurface = Enum.SurfaceType.Smooth
- Part16.BrickColor = BrickColor.new("Camo")
- Part16.Material = Enum.Material.WoodPlanks
- Part16.TopSurface = Enum.SurfaceType.Smooth
- Part16.brickColor = BrickColor.new("Camo")
- Part16.FormFactor = Enum.FormFactor.Symmetric
- Part16.formFactor = Enum.FormFactor.Symmetric
- Decal17.Name = "Face"
- Decal17.Parent = Part16
- Decal17.Texture = "http://www.roblox.com/asset/?id=7074882"
- SpecialMesh18.Parent = Part16
- SpecialMesh18.Scale = Vector3.new(1.25, 1.25, 1.25)
- Humanoid19.Parent = Model2
- Humanoid19.LeftLeg = Part12
- Humanoid19.RightLeg = Part13
- Humanoid19.Torso = Part3
- Humanoid19.WalkSpeed = 10
- Script20.Name = "Animate"
- Script20.Parent = Model2
- table.insert(cors,sandbox(Script20,function()
- function waitForChild(parent, childName)
- local child = parent:findFirstChild(childName)
- if child then return child end
- while true do
- child = parent.ChildAdded:wait()
- if child.Name==childName then return child end
- end
- end
- local Figure = script.Parent
- local Torso = waitForChild(Figure, "Torso")
- local RightShoulder = waitForChild(Torso, "Right Shoulder")
- local LeftShoulder = waitForChild(Torso, "Left Shoulder")
- local RightHip = waitForChild(Torso, "Right Hip")
- local LeftHip = waitForChild(Torso, "Left Hip")
- local Neck = waitForChild(Torso, "Neck")
- local Humanoid = waitForChild(Figure, "Humanoid")
- local pose = "Standing"
- local currentAnim = ""
- local currentAnimTrack = nil
- local currentAnimKeyframeHandler = nil
- local currentAnimSpeed = 1.0
- local animTable = {}
- local animNames = {
- idle = {
- { id = "http://www.roblox.com/asset/?id=125750544", weight = 9 },
- { id = "http://www.roblox.com/asset/?id=125750618", weight = 1 }
- },
- walk = {
- { id = "http://www.roblox.com/asset/?id=125749145", weight = 10 }
- },
- run = {
- { id = "run.xml", weight = 10 }
- },
- jump = {
- { id = "http://www.roblox.com/asset/?id=125750702", weight = 10 }
- },
- fall = {
- { id = "http://www.roblox.com/asset/?id=125750759", weight = 10 }
- },
- climb = {
- { id = "http://www.roblox.com/asset/?id=125750800", weight = 10 }
- },
- toolnone = {
- { id = "http://www.roblox.com/asset/?id=125750867", weight = 10 }
- },
- toolslash = {
- { id = "http://www.roblox.com/asset/?id=129967390", weight = 10 }
- -- { id = "slash.xml", weight = 10 }
- },
- toollunge = {
- { id = "http://www.roblox.com/asset/?id=129967478", weight = 10 }
- },
- wave = {
- { id = "http://www.roblox.com/asset/?id=128777973", weight = 10 }
- },
- point = {
- { id = "http://www.roblox.com/asset/?id=128853357", weight = 10 }
- },
- dance = {
- { id = "http://www.roblox.com/asset/?id=130018893", weight = 10 },
- { id = "http://www.roblox.com/asset/?id=132546839", weight = 10 },
- { id = "http://www.roblox.com/asset/?id=132546884", weight = 10 }
- },
- dance2 = {
- { id = "http://www.roblox.com/asset/?id=160934142", weight = 10 },
- { id = "http://www.roblox.com/asset/?id=160934298", weight = 10 },
- { id = "http://www.roblox.com/asset/?id=160934376", weight = 10 }
- },
- dance3 = {
- { id = "http://www.roblox.com/asset/?id=160934458", weight = 10 },
- { id = "http://www.roblox.com/asset/?id=160934530", weight = 10 },
- { id = "http://www.roblox.com/asset/?id=160934593", weight = 10 }
- },
- laugh = {
- { id = "http://www.roblox.com/asset/?id=129423131", weight = 10 }
- },
- cheer = {
- { id = "http://www.roblox.com/asset/?id=129423030", weight = 10 }
- },
- }
- -- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote
- local emoteNames = { wave = false, point = false, dance = true, dance2 = true, dance3 = true, laugh = false, cheer = false}
- math.randomseed(tick())
- function configureAnimationSet(name, fileList)
- if (animTable[name] ~= nil) then
- for _, connection in pairs(animTable[name].connections) do
- connection:disconnect()
- end
- end
- animTable[name] = {}
- animTable[name].count = 0
- animTable[name].totalWeight = 0
- animTable[name].connections = {}
- -- check for config values
- local config = script:FindFirstChild(name)
- if (config ~= nil) then
- -- print("Loading anims " .. name)
- table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end))
- table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end))
- local idx = 1
- for _, childPart in pairs(config:GetChildren()) do
- if (childPart:IsA("Animation")) then
- table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end))
- animTable[name][idx] = {}
- animTable[name][idx].anim = childPart
- local weightObject = childPart:FindFirstChild("Weight")
- if (weightObject == nil) then
- animTable[name][idx].weight = 1
- else
- animTable[name][idx].weight = weightObject.Value
- end
- animTable[name].count = animTable[name].count + 1
- animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
- -- print(name .. " [" .. idx .. "] " .. animTable[name][idx].anim.AnimationId .. " (" .. animTable[name][idx].weight .. ")")
- idx = idx + 1
- end
- end
- end
- -- fallback to defaults
- if (animTable[name].count <= 0) then
- for idx, anim in pairs(fileList) do
- animTable[name][idx] = {}
- animTable[name][idx].anim = Instance.new("Animation")
- animTable[name][idx].anim.Name = name
- animTable[name][idx].anim.AnimationId = anim.id
- animTable[name][idx].weight = anim.weight
- animTable[name].count = animTable[name].count + 1
- animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
- -- print(name .. " [" .. idx .. "] " .. anim.id .. " (" .. anim.weight .. ")")
- end
- end
- end
- -- Setup animation objects
- function scriptChildModified(child)
- local fileList = animNames[child.Name]
- if (fileList ~= nil) then
- configureAnimationSet(child.Name, fileList)
- end
- end
- script.ChildAdded:connect(scriptChildModified)
- script.ChildRemoved:connect(scriptChildModified)
- for name, fileList in pairs(animNames) do
- configureAnimationSet(name, fileList)
- end
- -- ANIMATION
- -- declarations
- local toolAnim = "None"
- local toolAnimTime = 0
- local jumpAnimTime = 0
- local jumpAnimDuration = 0.3
- local toolTransitionTime = 0.1
- local fallTransitionTime = 0.3
- local jumpMaxLimbVelocity = 0.75
- -- functions
- function stopAllAnimations()
- local oldAnim = currentAnim
- -- return to idle if finishing an emote
- if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then
- oldAnim = "idle"
- end
- currentAnim = ""
- if (currentAnimKeyframeHandler ~= nil) then
- currentAnimKeyframeHandler:disconnect()
- end
- if (currentAnimTrack ~= nil) then
- currentAnimTrack:Stop()
- currentAnimTrack:Destroy()
- currentAnimTrack = nil
- end
- return oldAnim
- end
- function setAnimationSpeed(speed)
- if speed ~= currentAnimSpeed then
- currentAnimSpeed = speed
- currentAnimTrack:AdjustSpeed(currentAnimSpeed)
- end
- end
- function keyFrameReachedFunc(frameName)
- if (frameName == "End") then
- -- print("Keyframe : ".. frameName)
- local repeatAnim = stopAllAnimations()
- local animSpeed = currentAnimSpeed
- playAnimation(repeatAnim, 0.0, Humanoid)
- setAnimationSpeed(animSpeed)
- end
- end
- -- Preload animations
- function playAnimation(animName, transitionTime, humanoid)
- local idleFromEmote = (animName == "idle" and emoteNames[currentAnim] ~= nil)
- if (animName ~= currentAnim and not idleFromEmote) then
- if (currentAnimTrack ~= nil) then
- currentAnimTrack:Stop(transitionTime)
- currentAnimTrack:Destroy()
- end
- currentAnimSpeed = 1.0
- local roll = math.random(1, animTable[animName].totalWeight)
- local origRoll = roll
- local idx = 1
- while (roll > animTable[animName][idx].weight) do
- roll = roll - animTable[animName][idx].weight
- idx = idx + 1
- end
- -- print(animName .. " " .. idx .. " [" .. origRoll .. "]")
- local anim = animTable[animName][idx].anim
- -- load it to the humanoid; get AnimationTrack
- currentAnimTrack = humanoid:LoadAnimation(anim)
- -- play the animation
- currentAnimTrack:Play(transitionTime)
- currentAnim = animName
- -- set up keyframe name triggers
- if (currentAnimKeyframeHandler ~= nil) then
- currentAnimKeyframeHandler:disconnect()
- end
- currentAnimKeyframeHandler = currentAnimTrack.KeyframeReached:connect(keyFrameReachedFunc)
- end
- end
- -------------------------------------------------------------------------------------------
- -------------------------------------------------------------------------------------------
- local toolAnimName = ""
- local toolAnimTrack = nil
- local currentToolAnimKeyframeHandler = nil
- function toolKeyFrameReachedFunc(frameName)
- if (frameName == "End") then
- -- print("Keyframe : ".. frameName)
- local repeatAnim = stopToolAnimations()
- playToolAnimation(repeatAnim, 0.0, Humanoid)
- end
- end
- function playToolAnimation(animName, transitionTime, humanoid)
- if (animName ~= toolAnimName) then
- if (toolAnimTrack ~= nil) then
- toolAnimTrack:Stop()
- toolAnimTrack:Destroy()
- transitionTime = 0
- end
- local roll = math.random(1, animTable[animName].totalWeight)
- local origRoll = roll
- local idx = 1
- while (roll > animTable[animName][idx].weight) do
- roll = roll - animTable[animName][idx].weight
- idx = idx + 1
- end
- -- print(animName .. " * " .. idx .. " [" .. origRoll .. "]")
- local anim = animTable[animName][idx].anim
- -- load it to the humanoid; get AnimationTrack
- toolAnimTrack = humanoid:LoadAnimation(anim)
- -- play the animation
- toolAnimTrack:Play(transitionTime)
- toolAnimName = animName
- currentToolAnimKeyframeHandler = toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc)
- end
- end
- function stopToolAnimations()
- local oldAnim = toolAnimName
- if (currentToolAnimKeyframeHandler ~= nil) then
- currentToolAnimKeyframeHandler:disconnect()
- end
- toolAnimName = ""
- if (toolAnimTrack ~= nil) then
- toolAnimTrack:Stop()
- toolAnimTrack:Destroy()
- toolAnimTrack = nil
- end
- return oldAnim
- end
- -------------------------------------------------------------------------------------------
- -------------------------------------------------------------------------------------------
- function onRunning(speed)
- if speed>0.01 then
- playAnimation("walk", 0.1, Humanoid)
- pose = "Running"
- else
- playAnimation("idle", 0.1, Humanoid)
- pose = "Standing"
- end
- end
- function onDied()
- pose = "Dead"
- end
- function onJumping()
- playAnimation("jump", 0.1, Humanoid)
- jumpAnimTime = jumpAnimDuration
- pose = "Jumping"
- end
- function onClimbing(speed)
- playAnimation("climb", 0.1, Humanoid)
- setAnimationSpeed(speed / 12.0)
- pose = "Climbing"
- end
- function onGettingUp()
- pose = "GettingUp"
- end
- function onFreeFall()
- if (jumpAnimTime <= 0) then
- playAnimation("fall", fallTransitionTime, Humanoid)
- end
- pose = "FreeFall"
- end
- function onFallingDown()
- pose = "FallingDown"
- end
- function onSeated()
- pose = "Seated"
- end
- function onPlatformStanding()
- pose = "PlatformStanding"
- end
- function onSwimming(speed)
- if speed>0 then
- pose = "Running"
- else
- pose = "Standing"
- end
- end
- function getTool()
- for _, kid in ipairs(Figure:GetChildren()) do
- if kid.className == "Tool" then return kid end
- end
- return nil
- end
- function getToolAnim(tool)
- for _, c in ipairs(tool:GetChildren()) do
- if c.Name == "toolanim" and c.className == "StringValue" then
- return c
- end
- end
- return nil
- end
- function animateTool()
- if (toolAnim == "None") then
- playToolAnimation("toolnone", toolTransitionTime, Humanoid)
- return
- end
- if (toolAnim == "Slash") then
- playToolAnimation("toolslash", 0, Humanoid)
- return
- end
- if (toolAnim == "Lunge") then
- playToolAnimation("toollunge", 0, Humanoid)
- return
- end
- end
- function moveSit()
- RightShoulder.MaxVelocity = 0.15
- LeftShoulder.MaxVelocity = 0.15
- RightShoulder:SetDesiredAngle(3.14 /2)
- LeftShoulder:SetDesiredAngle(-3.14 /2)
- RightHip:SetDesiredAngle(3.14 /2)
- LeftHip:SetDesiredAngle(-3.14 /2)
- end
- local lastTick = 0
- function move(time)
- local amplitude = 1
- local frequency = 1
- local deltaTime = time - lastTick
- lastTick = time
- local climbFudge = 0
- local setAngles = false
- if (jumpAnimTime > 0) then
- jumpAnimTime = jumpAnimTime - deltaTime
- end
- if (pose == "FreeFall" and jumpAnimTime <= 0) then
- playAnimation("fall", fallTransitionTime, Humanoid)
- elseif (pose == "Seated") then
- stopAllAnimations()
- moveSit()
- return
- elseif (pose == "Running") then
- playAnimation("walk", 0.1, Humanoid)
- elseif (pose == "Dead" or pose == "GettingUp" or pose == "FallingDown" or pose == "Seated" or pose == "PlatformStanding") then
- -- print("Wha " .. pose)
- amplitude = 0.1
- frequency = 1
- setAngles = true
- end
- if (setAngles) then
- desiredAngle = amplitude * math.sin(time * frequency)
- RightShoulder:SetDesiredAngle(desiredAngle + climbFudge)
- LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge)
- RightHip:SetDesiredAngle(-desiredAngle)
- LeftHip:SetDesiredAngle(-desiredAngle)
- end
- -- Tool Animation handling
- local tool = getTool()
- if tool then
- animStringValueObject = getToolAnim(tool)
- if animStringValueObject then
- toolAnim = animStringValueObject.Value
- -- message recieved, delete StringValue
- animStringValueObject.Parent = nil
- toolAnimTime = time + .3
- end
- if time > toolAnimTime then
- toolAnimTime = 0
- toolAnim = "None"
- end
- animateTool()
- else
- stopToolAnimations()
- toolAnim = "None"
- toolAnimTime = 0
- end
- end
- -- connect events
- Humanoid.Died:connect(onDied)
- Humanoid.Running:connect(onRunning)
- Humanoid.Jumping:connect(onJumping)
- Humanoid.Climbing:connect(onClimbing)
- Humanoid.GettingUp:connect(onGettingUp)
- Humanoid.FreeFalling:connect(onFreeFall)
- Humanoid.FallingDown:connect(onFallingDown)
- Humanoid.Seated:connect(onSeated)
- Humanoid.PlatformStanding:connect(onPlatformStanding)
- Humanoid.Swimming:connect(onSwimming)
- -- main program
- local runService = game:service("RunService");
- -- initialize to idle
- playAnimation("idle", 0.1, Humanoid)
- pose = "Standing"
- while Figure.Parent~=nil do
- local _, time = wait(0.1)
- move(time)
- end
- end))
- StringValue21.Name = "climb"
- StringValue21.Parent = Script20
- Animation22.Name = "ClimbAnim"
- Animation22.Parent = StringValue21
- Animation22.AnimationId = "http://www.roblox.com/asset/?id=125750800"
- StringValue23.Name = "fall"
- StringValue23.Parent = Script20
- Animation24.Name = "FallAnim"
- Animation24.Parent = StringValue23
- Animation24.AnimationId = "http://www.roblox.com/asset/?id=125750759"
- StringValue25.Name = "idle"
- StringValue25.Parent = Script20
- Animation26.Name = "Animation1"
- Animation26.Parent = StringValue25
- Animation26.AnimationId = "http://www.roblox.com/asset/?id=125750544"
- NumberValue27.Name = "Weight"
- NumberValue27.Parent = Animation26
- NumberValue27.Value = 9
- Animation28.Name = "Animation2"
- Animation28.Parent = StringValue25
- Animation28.AnimationId = "http://www.roblox.com/asset/?id=125750618"
- NumberValue29.Name = "Weight"
- NumberValue29.Parent = Animation28
- NumberValue29.Value = 1
- StringValue30.Name = "jump"
- StringValue30.Parent = Script20
- Animation31.Name = "JumpAnim"
- Animation31.Parent = StringValue30
- Animation31.AnimationId = "http://www.roblox.com/asset/?id=125750702"
- StringValue32.Name = "run"
- StringValue32.Parent = Script20
- Animation33.Name = "RunAnim"
- Animation33.Parent = StringValue32
- Animation33.AnimationId = "http://www.roblox.com/asset/?id=125749145"
- StringValue34.Name = "toolnone"
- StringValue34.Parent = Script20
- Animation35.Name = "ToolNoneAnim"
- Animation35.Parent = StringValue34
- Animation35.AnimationId = "http://www.roblox.com/asset/?id=125750867"
- StringValue36.Name = "walk"
- StringValue36.Parent = Script20
- Animation37.Name = "WalkAnim"
- Animation37.Parent = StringValue36
- Animation37.AnimationId = "http://www.roblox.com/asset/?id=125749145"
- Script38.Parent = Model2
- table.insert(cors,sandbox(Script38,function()
- local zombie = script.Parent
- for _, script in pairs(zombie.ModuleScripts:GetChildren()) do
- if not game.ServerStorage:FindFirstChild(script.Name) then
- script:Clone().Parent = game.ServerStorage
- end
- end
- local AI = require(game.ServerStorage.ROBLOX_ZombieAI).new(zombie)
- local DestroyService = require(game.ServerStorage.ROBLOX_DestroyService)
- local function clearParts(parent)
- for _, part in pairs(parent:GetChildren()) do
- clearParts(part)
- end
- local delay
- if parent:IsA("Part") then
- delay = math.random(5,10)
- else
- delay = 11
- end
- DestroyService:AddItem(parent, delay)
- end
- zombie.Humanoid.Died:connect(function()
- AI.Stop()
- math.randomseed(tick())
- clearParts(zombie)
- script.Disabled = true
- end)
- local lastMoan = os.time()
- math.randomseed(os.time())
- while true do
- local animationTrack = zombie.Humanoid:LoadAnimation(zombie.Animations.Arms)
- animationTrack:Play()
- -- local now = os.time()
- -- if now - lastMoan > 5 then
- -- if math.random() > .3 then
- -- zombie.Moan:Play()
- ---- print("playing moan")
- -- lastMoan = now
- -- end
- -- end
- wait(2)
- end
- end))
- BillboardGui39.Parent = Model2
- BillboardGui39.Size = UDim2.new(0, 100, 0, 30)
- BillboardGui39.StudsOffset = Vector3.new(0, 5, 0)
- TextLabel40.Parent = BillboardGui39
- TextLabel40.Visible = false
- TextLabel40.Size = UDim2.new(1, 0, 1, 0)
- TextLabel40.BackgroundColor = BrickColor.new("Institutional white")
- TextLabel40.BackgroundColor3 = Color3.new(1, 1, 1)
- TextLabel40.Font = Enum.Font.SourceSansBold
- TextLabel40.FontSize = Enum.FontSize.Size24
- TextLabel40.Text = "Idle"
- TextLabel40.TextSize = 24
- Configuration41.Name = "ModuleScripts"
- Configuration41.Parent = Model2
- ModuleScript42.Name = "ROBLOX_AIUtilities"
- ModuleScript42.Parent = Configuration41
- table.insert(cors,sandbox(ModuleScript42,function()
- local utility = {}
- function utility:WideRayCast(start, target, offset, ignoreList)
- local parts = {}
- local ray = Ray.new(start, target - start)
- local part, point = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
- if part then table.insert(parts, part) end
- local offsetVector = offset * (target - start):Cross(Vector3.FromNormalId(Enum.NormalId.Top)).unit
- local ray = Ray.new(start + offsetVector, target - start + offsetVector)
- local part, point = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
- if part then table.insert(parts, part) end
- local ray = Ray.new(start - offsetVector, target - start - offsetVector)
- local part, point = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
- if part then table.insert(parts, part) end
- return parts
- end
- function utility:FindNearestPathPoint(path, point, start, target, ignoreList)
- local occludePoint = path:CheckOcclusionAsync(point)
- if occludePoint > 0 then
- utility:WideRayCast(start)
- end
- end
- local maxForce = 15
- function utility:GetRepulsionVector(unitPosition, otherUnitsPositions)
- local repulsionVector = Vector3.new(0,0,0)
- local count = 0
- for _, other in pairs(otherUnitsPositions) do
- local fromOther = unitPosition - other
- --fromOther = fromOther.unit * ((-maxForce / 5) * math.pow(fromOther.magnitude,2) + maxForce)
- fromOther = fromOther.unit * 1000 / math.pow((fromOther.magnitude + 1), 2)
- repulsionVector = repulsionVector + fromOther
- end
- return repulsionVector * maxForce
- end
- function utility:GetIdleState(StateMachine)
- local IdleState = StateMachine.NewState()
- IdleState.Name = "Idle"
- IdleState.Action = function() end
- IdleState.Init = function() end
- return IdleState
- end
- function utility:GetClosestVisibleTarget(npcModel, characters, ignoreList, fieldOfView)
- local closestTarget = nil
- local closestDistance = math.huge
- for _, character in pairs(characters) do
- local toTarget = character.HumanoidRootPart.Position - npcModel.HumanoidRootPart.Position
- local toTargetWedge = toTarget * Vector3.new(1,0,1)
- local angle = math.acos(toTargetWedge:Dot(npcModel.HumanoidRootPart.CFrame.lookVector)/toTargetWedge.magnitude)
- if math.deg(angle) < fieldOfView then
- local targetRay = Ray.new(npcModel.HumanoidRootPart.Position, toTarget)
- local part, position = game.Workspace:FindPartOnRayWithIgnoreList(targetRay, ignoreList)
- if part and part.Parent == character then
- if toTarget.magnitude < closestDistance then
- closestTarget = character
- closestDistance = toTarget.magnitude
- end
- end
- end
- end
- return closestTarget
- end
- local function isSpaceEmpty(position)
- local region = Region3.new(position - Vector3.new(2,2,2), position + Vector3.new(2,2,2))
- return game.Workspace:IsRegion3Empty(region)
- end
- function utility:FindCloseEmptySpace(model)
- local targetPos = Vector3.new(0,0,0)
- local count = 0
- math.randomseed(os.time())
- repeat
- local xoff = math.random(5,10)
- if math.random() > .5 then
- xoff = xoff * -1
- end
- local zoff = math.random(5, 10)
- if math.random() > .5 then
- zoff = zoff * -1
- end
- targetPos = Vector3.new(model.HumanoidRootPart.Position.X + xoff,model.HumanoidRootPart.Position.Y,model.HumanoidRootPart.Position.Z + zoff)
- if isSpaceEmpty(targetPos) then
- return targetPos
- else
- targetPos = targetPos + Vector3.new(0,4,0)
- end
- if isSpaceEmpty(targetPos) then
- return targetPos
- end
- count = count + 1
- until count > 10
- return nil
- end
- return utility
- end))
- ModuleScript43.Name = "ROBLOX_DestroyService"
- ModuleScript43.Parent = Configuration41
- table.insert(cors,sandbox(ModuleScript43,function()
- local destroyService = {}
- local destroyQueue = {}
- function destroyService:AddItem(theobject, delay)
- local now = os.time()
- local destroyObject = {object = theobject, destroyTime = delay + now}
- for i, storedObject in pairs(destroyQueue) do
- if destroyQueue[i].destroyTime > destroyObject.destroyTime then
- table.insert(destroyQueue, i, destroyObject)
- return true
- end
- end
- table.insert(destroyQueue, destroyObject)
- return true
- end
- local updateThread = coroutine.create(function()
- while true do
- local now = os.time()
- for _, storedObject in pairs(destroyQueue) do
- if now >= storedObject.destroyTime then
- table.remove(destroyQueue, 1)
- if storedObject.object then
- storedObject.object:Destroy()
- end
- elseif now >= storedObject.destroyTime - 1 then
- if storedObject.object and storedObject.object:IsA("Part") then
- local trans = storedObject.object.Transparency + 1/30
- storedObject.object.Transparency = trans
- end
- else
- break
- end
- end
- wait()
- end
- end)
- coroutine.resume(updateThread)
- return destroyService
- end))
- ModuleScript44.Name = "ROBLOX_HumanoidList"
- ModuleScript44.Parent = Configuration41
- table.insert(cors,sandbox(ModuleScript44,function()
- local humanoidList = {}
- local storage = {}
- function humanoidList:GetCurrent()
- return storage
- end
- local function findHumanoids(object, list)
- if object then
- if object:IsA("Humanoid") then
- table.insert(list, object)
- end
- for _, child in pairs(object:GetChildren()) do
- local childList = findHumanoids(child, list)
- end
- end
- end
- local updateThread = coroutine.create(function()
- while true do
- storage = {}
- findHumanoids(game.Workspace, storage)
- wait(3)
- end
- end)
- coroutine.resume(updateThread)
- return humanoidList
- end))
- ModuleScript45.Name = "ROBLOX_StateMachine"
- ModuleScript45.Parent = Configuration41
- table.insert(cors,sandbox(ModuleScript45,function()
- local machine = {}
- machine.new = function()
- local StateMachine = {}
- StateMachine.WaitTime = .2
- StateMachine.CurrentState = nil
- StateMachine.SwitchState = function(newState)
- if StateMachine.CurrentState then
- StateMachine.CurrentState.Stop()
- end
- StateMachine.CurrentState = newState
- if newState then
- newState.Start()
- end
- end
- StateMachine.NewState = function()
- local state = {}
- state.Name = ""
- state.Conditions = {}
- state.isRunning = false
- state.Action = function() end
- state.Run = function()
- state.isRunning = true
- while state.isRunning do
- --check conditions
- --print("checking conditions")
- for _, condition in pairs(state.Conditions) do
- --print("Checking " .. condition.Name)
- if condition.Evaluate() then
- --print(condition.Name .. " is true. Switching states")
- StateMachine.SwitchState(condition.TransitionState)
- return
- end
- end
- --if no conditions satisfied, perform action
- state.Action()
- wait(StateMachine.WaitTime)
- end
- end
- state.Init = function()
- end
- state.Start = function()
- --print("Starting " .. state.Name)
- state.Init()
- local thread = coroutine.create(state.Run)
- coroutine.resume(thread)
- end
- state.Stop = function()
- --print("Stopping " .. state.Name)
- state.isRunning = false
- end
- return state
- end
- StateMachine.NewCondition = function()
- local condition = {}
- condition.Name = ""
- condition.Evaluate = function() print("replace me") return false end
- condition.TransitionState = {}
- return condition
- end
- return StateMachine
- end
- return machine
- end))
- ModuleScript46.Name = "ROBLOX_ZombieAI"
- ModuleScript46.Parent = Configuration41
- table.insert(cors,sandbox(ModuleScript46,function()
- --local PathLib = require(game.ServerStorage.PathfindingLibrary).new()
- local HumanoidList = require(game.ServerStorage.ROBLOX_HumanoidList)
- local AIUtilities = require(game.ServerStorage.ROBLOX_AIUtilities)
- local ZombieAI = {}
- function updateDisplay(display, state)
- local thread = coroutine.create(function()
- while true do
- wait()
- if state then
- display.Text = state.Name
- end
- end
- end)
- coroutine.resume(thread)
- end
- ZombieAI.new = function(model)
- local zombie = {}
- -- CONFIGURATION VARIABLES
- -- local AttackRange, FieldOfView, AggroRange, ChanceOfBoredom, BoredomDuration,
- -- Damage, DamageCooldown
- local configTable = model.Configurations
- local configs = {}
- local function loadConfig(configName, defaultValue)
- if configTable:FindFirstChild(configName) then
- configs[configName] = configTable:FindFirstChild(configName).Value
- else
- configs[configName] = defaultValue
- end
- end
- loadConfig("AttackRange", 3)
- loadConfig("FieldOfView", 180)
- loadConfig("AggroRange", 200)
- loadConfig("ChanceOfBoredom", .5)
- loadConfig("BoredomDuration", 10)
- loadConfig("Damage", 10)
- loadConfig("DamageCooldown", 1)
- local StateMachine = require(game.ServerStorage.ROBLOX_StateMachine).new()
- local PathLib = require(game.ServerStorage.ROBLOX_PathfindingLibrary).new()
- local ZombieTarget = nil
- local ZombieTargetLastLocation = nil
- local lastBored = os.time()
- -- STATE DEFINITIONS
- -- IdleState: NPC stays still. Refreshes bored timer when started to
- -- allow for random state change
- local IdleState = StateMachine.NewState()
- IdleState.Name = "Idle"
- IdleState.Action = function()
- end
- IdleState.Init = function()
- lastBored = os.time()
- end
- -- SearchState: NPC wanders randomly increasing chance of spotting
- -- enemy. Refreshed bored timer when started to allow for random state
- -- change
- local SearchState = StateMachine.NewState()
- SearchState.Name = "Search"
- local lastmoved = os.time()
- local searchTarget = nil
- SearchState.Action = function()
- -- move to random spot nearby
- if model then
- local now = os.time()
- if now - lastmoved > 2 then
- lastmoved = now
- local xoff = math.random(5, 10)
- if math.random() > .5 then
- xoff = xoff * -1
- end
- local zoff = math.random(5, 10)
- if math.random() > .5 then
- zoff = zoff * -1
- end
- local testtarg = AIUtilities:FindCloseEmptySpace(model)
- --if testtarg then print(testtarg) else print("could not find") end
- searchTarget = Vector3.new(model.HumanoidRootPart.Position.X + xoff,model.HumanoidRootPart.Position.Y,model.HumanoidRootPart.Position.Z + zoff)
- --local target = Vector3.new(model.HumanoidRootPart.Position.X + xoff,model.HumanoidRootPart.Position.Y,model.HumanoidRootPart.Position.Z + zoff)
- --model.Humanoid:MoveTo(target)
- searchTarget = testtarg
- end
- if searchTarget then
- PathLib:MoveToTarget(model, searchTarget)
- end
- end
- end
- SearchState.Init = function()
- lastBored = os.time()
- end
- -- PursueState: Enemy has been spotted, need to give chase.
- local PursueState = StateMachine.NewState()
- PursueState.Name = "Pursue"
- PursueState.Action = function()
- -- Double check we still have target
- if ZombieTarget then
- -- Get distance to target
- local distance = (model.HumanoidRootPart.Position - ZombieTarget.HumanoidRootPart.Position).magnitude
- -- If we're far from target use pathfinding to move. Otherwise just MoveTo
- if distance > configs["AttackRange"] + 5 then
- PathLib:MoveToTarget(model, ZombieTarget.HumanoidRootPart.Position)
- else
- model.Humanoid:MoveTo(ZombieTarget.HumanoidRootPart.Position)
- -- if ZombieTarget.HumanoidRootPart.Position.Y > model.HumanoidRootPart.Position.Y + 2 then
- -- model.Humanoid.Jump = true
- -- end
- end
- end
- end
- PursueState.Init = function()
- end
- -- AttackState: Keep moving towards target and play attack animation.
- local AttackState = StateMachine.NewState()
- AttackState.Name = "Attack"
- local lastAttack = os.time()
- local attackTrack = model.Humanoid:LoadAnimation(model.Animations.Attack)
- AttackState.Action = function()
- model.Humanoid:MoveTo(ZombieTarget.HumanoidRootPart.Position)
- local now = os.time()
- if now - lastAttack > 3 then
- lastAttack = now
- attackTrack:Play()
- end
- end
- -- HuntState: Can't see target but NPC will move to target's last known location.
- -- Will eventually get bored and switch state.
- local HuntState = StateMachine.NewState()
- HuntState.Name = "Hunt"
- HuntState.Action = function()
- if ZombieTargetLastLocation then
- PathLib:MoveToTarget(model, ZombieTargetLastLocation)
- end
- end
- HuntState.Init = function()
- lastBored = os.time() + configs["BoredomDuration"] / 2
- end
- -- CONDITION DEFINITIONS
- -- CanSeeTarget: Determines if a target is visible. Returns true if target is visible and
- -- sets current target. A target is valid if it is nearby, visible, has a Torso and WalkSpeed
- -- greater than 0 (this is to ignore inanimate objects that happen to use humanoids)
- local CanSeeTarget = StateMachine.NewCondition()
- CanSeeTarget.Name = "CanSeeTarget"
- CanSeeTarget.Evaluate = function()
- if model then
- -- Get list of all nearby Zombies and non-Zombie humanoids
- -- Zombie list is used to ignore zombies during later raycast
- local humanoids = HumanoidList:GetCurrent()
- local zombies = {}
- local characters = {}
- for _, object in pairs(humanoids) do
- if object and object.Parent and object.Parent:FindFirstChild("HumanoidRootPart") and object.Health > 0 and object.WalkSpeed > 0 then
- local torso = object.Parent:FindFirstChild("HumanoidRootPart")
- if torso then
- local distance = (model.HumanoidRootPart.Position - torso.Position).magnitude
- if distance <= configs["AggroRange"] then
- if object.Parent.Name == "Drooling Zombie" then
- table.insert(zombies, object.Parent)
- else
- table.insert(characters, object.Parent)
- end
- end
- end
- end
- end
- local target = AIUtilities:GetClosestVisibleTarget(model, characters, zombies, configs["FieldOfView"])
- if target then
- ZombieTarget = target
- return true
- end
- -- -- Go through each valid target to see if within field of view and if there is
- -- -- clear line of sight. Field of view treated as wedge in front of character.
- -- for _, character in pairs(characters) do
- -- local toTarget = (character.HumanoidRootPart.Position - model.HumanoidRootPart.Position)
- -- toTarget = Vector3.new(toTarget.X, 0, toTarget.Z)
- -- local angle = math.acos(toTarget:Dot(model.HumanoidRootPart.CFrame.lookVector)/toTarget.magnitude)
- -- if math.deg(angle) < configs["FieldOfView"]/2 then
- -- ZombieTarget = character
- -- -- raycast to see if target is actually visible
- -- local toTarget = Ray.new(model.HumanoidRootPart.Position, (ZombieTarget.HumanoidRootPart.Position - model.HumanoidRootPart.Position))
- -- local part, position = game.Workspace:FindPartOnRayWithIgnoreList(toTarget, zombies)
- -- if part and part.Parent == ZombieTarget then
- -- return true
- -- end
- -- ZombieTarget = nil
- -- end
- -- end
- end
- return false
- end
- CanSeeTarget.TransitionState = PursueState
- -- TargetDead: Check if target is dead.
- local TargetDead = StateMachine.NewCondition()
- TargetDead.Name = "TargetDead"
- TargetDead.Evaluate = function()
- if ZombieTarget and ZombieTarget.Humanoid then
- return ZombieTarget.Humanoid.Health <= 0
- end
- return true
- end
- TargetDead.TransitionState = IdleState
- -- GotDamaged: Check if NPC has taken damage
- local lastHealth = model.Humanoid.Health
- local GotDamaged = StateMachine.NewCondition()
- GotDamaged.Name = "GotDamaged"
- GotDamaged.Evaluate = function()
- if model then
- if lastHealth > model.Humanoid.Health then
- return true
- end
- end
- return false
- end
- GotDamaged.TransitionState = SearchState
- -- GotBored: Used to provide random state change.
- local GotBored = StateMachine.NewCondition()
- GotBored.Name = "GotBored"
- GotBored.Evaluate = function()
- local now = os.time()
- if now - lastBored > configs["BoredomDuration"] then
- local roll = math.random()
- if roll < configs["ChanceOfBoredom"] then
- lastBored = now
- if GotBored.TransitionState == SearchState then
- GotBored.TransitionState = IdleState
- else
- GotBored.TransitionState = SearchState
- end
- return true
- end
- end
- return false
- end
- GotBored.TransitionState = IdleState
- -- LostTarget: Checks clear line of sight
- local LostTarget = StateMachine.NewCondition()
- LostTarget.Name = "LostTarget"
- LostTarget.Evaluate = function()
- if true then return false end
- if ZombieTarget then
- if (ZombieTarget.HumanoidRootPart.Position - model.HumanoidRootPart.Position).magnitude > 10 then
- local toTarget = Ray.new(model.HumanoidRootPart.Position, (ZombieTarget.HumanoidRootPart.Position - model.HumanoidRootPart.Position))
- local part, position = game.Workspace:FindPartOnRay(toTarget, model)
- if not part or part.Parent ~= ZombieTarget then
- --print("Lost target!")
- ZombieTargetLastLocation = ZombieTarget.HumanoidRootPart.Position
- ZombieTarget = nil
- return true
- end
- end
- end
- return false
- end
- LostTarget.TransitionState = HuntState
- local WithinRange = StateMachine.NewCondition()
- WithinRange.Name = "WithinRange"
- WithinRange.Evaluate = function()
- if ZombieTarget then
- local distance = (model.HumanoidRootPart.Position - ZombieTarget.HumanoidRootPart.Position).magnitude
- if distance < configs["AttackRange"] then
- --print("Within attack range!")
- return true
- end
- end
- return false
- end
- WithinRange.TransitionState = AttackState
- local OutsideRange = StateMachine.NewCondition()
- OutsideRange.Name = "OutsideRange"
- OutsideRange.Evaluate = function()
- if ZombieTarget then
- local distance = (model.HumanoidRootPart.Position - ZombieTarget.HumanoidRootPart.Position).magnitude
- if distance > configs["AttackRange"] then
- --print("Outside attack range!")
- return true
- end
- end
- return false
- end
- OutsideRange.TransitionState = PursueState
- table.insert(IdleState.Conditions, CanSeeTarget)
- table.insert(IdleState.Conditions, GotDamaged)
- table.insert(IdleState.Conditions, GotBored)
- table.insert(SearchState.Conditions, GotBored)
- table.insert(SearchState.Conditions, CanSeeTarget)
- table.insert(PursueState.Conditions, LostTarget)
- table.insert(PursueState.Conditions, WithinRange)
- table.insert(PursueState.Conditions, TargetDead)
- table.insert(AttackState.Conditions, OutsideRange)
- table.insert(AttackState.Conditions, TargetDead)
- table.insert(HuntState.Conditions, GotBored)
- table.insert(HuntState.Conditions, CanSeeTarget)
- -- Setup arms damage
- local canHit = true
- local lastHit = os.time()
- local function handleHit(other)
- if canHit then
- if other and other.Parent and other.Parent.Name ~= "Drooling Zombie" and other.Parent:FindFirstChild("Humanoid") then
- local enemy = other.Parent
- if enemy.Humanoid.WalkSpeed > 0 then
- enemy.Humanoid.Health = enemy.Humanoid.Health - configs["Damage"]
- canHit = false
- end
- end
- else
- local now = os.time()
- if now - lastHit > configs["DamageCooldown"] then
- lastHit = now
- canHit = true
- end
- end
- end
- local leftHitConnect, rightHitConnect
- leftHitConnect = model:FindFirstChild("Left Arm").Touched:connect(handleHit)
- rightHitConnect = model:FindFirstChild("Right Arm").Touched:connect(handleHit)
- --ZombieAI.Animate(model)
- --updateDisplay()
- --updateDisplay(model.BillboardGui.TextLabel, StateMachine.CurrentState)
- local thread = coroutine.create(function()
- while true do
- wait()
- -- calculate repulsion force
- local humanoids = HumanoidList:GetCurrent()
- local localZombies = {}
- for _, humanoid in pairs(humanoids) do
- if humanoid and humanoid ~= model.Humanoid and humanoid.Parent and humanoid.Parent:FindFirstChild("HumanoidRootPart") then
- local torso = humanoid.Parent:FindFirstChild("HumanoidRootPart")
- local distance = (model.HumanoidRootPart.Position - torso.Position).magnitude
- if distance <= 2.5 then
- table.insert(localZombies, torso.Position)
- end
- end
- end
- local repulsionDirection = AIUtilities:GetRepulsionVector(model.HumanoidRootPart.Position, localZombies)
- if repulsionDirection.magnitude > 0 then
- --print("replusion direction: " .. tostring(repulsionDirection))
- end
- model.HumanoidRootPart.RepulsionForce.force = repulsionDirection
- if StateMachine.CurrentState and model.Configurations.Debug.Value then
- model.BillboardGui.TextLabel.Visible = true
- model.BillboardGui.TextLabel.Text = StateMachine.CurrentState.Name
- end
- if not model.Configurations.Debug.Value then
- model.BillboardGui.TextLabel.Visible = false
- end
- end
- end)
- coroutine.resume(thread)
- StateMachine.SwitchState(IdleState)
- zombie.Stop = function()
- StateMachine.SwitchState(nil)
- end
- return zombie
- end
- return ZombieAI
- end))
- ModuleScript47.Name = "ROBLOX_PathfindingLibrary"
- ModuleScript47.Parent = Configuration41
- table.insert(cors,sandbox(ModuleScript47,function()
- local PathfindingUtility = {}
- local TargetOffsetMax = 10--5
- local JumpThreshold = 1.5 --2.5
- local NextPointThreshold = 4
- local PathfindingService = game:GetService("PathfindingService")
- PathfindingService.EmptyCutoff = .3
- function PathfindingUtility.new()
- local this = {}
- local currentTargetPos = nil
- local lastTargetPos = Vector3.new(math.huge, math.huge, math.huge)
- local path = nil
- local currentPointIndex = 1
- function this:MoveToTarget(character, target)
- local targetOffset = (lastTargetPos - target).magnitude
- --
- -- local targetOffsetVector = (lastTargetPos - target)
- -- if targetOffsetVector.magnitude < math.huge then
- -- targetOffsetVector = (lastTargetPos - target) * Vector3.new(1,0,1)
- -- end
- if targetOffset > TargetOffsetMax then
- --if targetOffsetVector.magnitude > TargetOffsetMax then
- --print("moveto")
- local startPoint = character.HumanoidRootPart.Position
- local humanoidState = character.Humanoid:GetState()
- if humanoidState == Enum.HumanoidStateType.Jumping or humanoidState == Enum.HumanoidStateType.Freefall then
- --print("this")
- local ray = Ray.new(character.HumanoidRootPart.Position, Vector3.new(0, -100, 0))
- local hitPart, hitPoint = game.Workspace:FindPartOnRay(ray, character)
- if hitPart then
- startPoint = hitPoint
- end
- end
- --print("making new path")
- local newTarget = target
- local ray = Ray.new(target + Vector3.new(0,-3,0), Vector3.new(0, -100, 0))
- local hitPart, hitPoint = game.Workspace:FindPartOnRay(ray, character)
- if hitPoint then
- if (hitPoint - target).magnitude > 4 then
- newTarget = newTarget * Vector3.new(1,0,1) + Vector3.new(0,3,0)
- end
- end
- --local newTarget = Vector3.new(1,0,1) * target + Vector3.new(0, 2, 0)
- path = PathfindingService:ComputeSmoothPathAsync(startPoint, newTarget, 500)
- if path.Status ~= Enum.PathStatus.Success then
- --print(tostring(path.Status))
- end
- --path = PathfindingService:ComputeRawPathAsync(startPoint, target, 500)
- -- game.Workspace.Points:ClearAllChildren()
- -- local ps = path:GetPointCoordinates()
- -- for _, point in pairs(ps) do
- -- local part = Instance.new("Part", game.Workspace.Points)
- -- part.CanCollide = false
- -- part.Anchored = true
- -- part.FormFactor = Enum.FormFactor.Custom
- -- part.Size = Vector3.new(1,1,1)
- -- part.Position = point
- -- end
- currentPointIndex = 1
- lastTargetPos = target
- end
- if path then
- local points = path:GetPointCoordinates()
- if currentPointIndex < #points then
- local currentPoint = points[currentPointIndex]
- local distance = (character.HumanoidRootPart.Position - currentPoint).magnitude
- if distance < NextPointThreshold then
- currentPointIndex = currentPointIndex + 1
- end
- character.Humanoid:MoveTo(points[currentPointIndex])
- if points[currentPointIndex].Y - character.HumanoidRootPart.Position.Y > JumpThreshold then
- character.Humanoid.Jump = true
- end
- else
- character.Humanoid:MoveTo(target)
- end
- end
- end
- return this
- end
- return PathfindingUtility
- end))
- Configuration48.Name = "Configurations"
- Configuration48.Parent = Model2
- IntValue49.Name = "Damage"
- IntValue49.Parent = Configuration48
- IntValue49.Value = 30
- BoolValue50.Name = "Debug"
- BoolValue50.Parent = Configuration48
- IntValue51.Name = "FieldOfView"
- IntValue51.Parent = Configuration48
- IntValue51.Value = 180
- IntValue52.Name = "AggroRange"
- IntValue52.Parent = Configuration48
- IntValue52.Value = 200
- Configuration53.Name = "Animations"
- Configuration53.Parent = Model2
- Animation54.Name = "Attack"
- Animation54.Parent = Configuration53
- Animation54.AnimationId = "http://www.roblox.com/asset/?id=180416148"
- Animation55.Name = "Arms"
- Animation55.Parent = Configuration53
- Animation55.AnimationId = "http://www.roblox.com/asset/?id=183294396"
- CharacterMesh56.Name = "Zombie Left Arm"
- CharacterMesh56.Parent = Model2
- CharacterMesh56.BodyPart = Enum.BodyPart.LeftArm
- CharacterMesh56.MeshId = 37683097
- CharacterMesh56.OverlayTextureId = 37686282
- CharacterMesh57.Name = "Zombie Left Leg"
- CharacterMesh57.Parent = Model2
- CharacterMesh57.BodyPart = Enum.BodyPart.LeftLeg
- CharacterMesh57.MeshId = 37683150
- CharacterMesh57.OverlayTextureId = 37687646
- CharacterMesh58.Name = "Zombie Right Arm"
- CharacterMesh58.Parent = Model2
- CharacterMesh58.BodyPart = Enum.BodyPart.RightArm
- CharacterMesh58.MeshId = 37683174
- CharacterMesh58.OverlayTextureId = 37686282
- CharacterMesh59.Name = "Zombie Right Leg"
- CharacterMesh59.Parent = Model2
- CharacterMesh59.BodyPart = Enum.BodyPart.RightLeg
- CharacterMesh59.MeshId = 37683227
- CharacterMesh59.OverlayTextureId = 37687646
- CharacterMesh60.Name = "Zombie torso"
- CharacterMesh60.Parent = Model2
- CharacterMesh60.BodyPart = Enum.BodyPart.Torso
- CharacterMesh60.MeshId = 37683263
- CharacterMesh60.OverlayTextureId = 37686282
- Sound61.Name = "Moan"
- Sound61.Parent = Model2
- Sound61.Pitch = 0.15000000596046
- Sound61.PlaybackSpeed = 0.15000000596046
- Sound61.Volume = 0.050000000745058
- BodyColors62.Parent = Model2
- BodyColors62.HeadColor = BrickColor.new("Camo")
- BodyColors62.HeadColor3 = Color3.new(0.227451, 0.490196, 0.0823529)
- BodyColors62.LeftArmColor = BrickColor.new("Earth green")
- BodyColors62.LeftArmColor3 = Color3.new(0.152941, 0.27451, 0.176471)
- BodyColors62.LeftLegColor = BrickColor.new("Earth green")
- BodyColors62.LeftLegColor3 = Color3.new(0.152941, 0.27451, 0.176471)
- BodyColors62.RightArmColor = BrickColor.new("Earth green")
- BodyColors62.RightArmColor3 = Color3.new(0.152941, 0.27451, 0.176471)
- BodyColors62.RightLegColor = BrickColor.new("Earth green")
- BodyColors62.RightLegColor3 = Color3.new(0.152941, 0.27451, 0.176471)
- BodyColors62.TorsoColor = BrickColor.new("Earth green")
- BodyColors62.TorsoColor3 = Color3.new(0.152941, 0.27451, 0.176471)
- for i,v in pairs(mas:GetChildren()) do
- v.Parent = script
- pcall(function() v:MakeJoints() end)
- end
- mas:Destroy()
- for i,v in pairs(cors) do
- spawn(function()
- pcall(v)
- end)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement