Advertisement
Guest User

Untitled

a guest
Feb 16th, 2020
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.67 KB | None | 0 0
  1. local Players = game:GetService('Players')
  2.  
  3. local module = {}
  4. local existingNPC = {}
  5.  
  6. function module.new(npc)
  7.     if not existingNPC[npc.Name] then
  8.         return module:create(npc)
  9.     end
  10.     return existingNPC[npc.Name]
  11. end
  12.  
  13. function module:create(npc)
  14.     local newNPC = {}
  15.     setmetatable(newNPC, self)
  16.    
  17.     self.NPC = npc
  18.     self.Name = self.NPC.Name
  19.     self.Root = self.NPC.PrimaryPart
  20.     self.Humanoid = self.NPC:WaitForChild('Humanoid')
  21.     self.Health = self.Humanoid.Health
  22.     self.MaxHealth = self.Humanoid.MaxHealth
  23.     self.TargetChanged = nil
  24.    
  25.     -- Stats
  26.     self.Visibility = 100
  27.     self.WalkingSpeed = 9
  28.     self.RunningSpeed = 15
  29.     self.ScareFactor = 0.25 -- Determines the health at which it stops attacking in order to heal.
  30.    
  31.     -- Info
  32.     self.Target = nil
  33.     self.TargetPoints = {}
  34.     self.Distance = 0
  35.     self.Path = nil
  36.    
  37.     -- Internal
  38.     self.WalkSpeed = self.Humanoid.WalkSpeed
  39.     self.States = {Walking = self.WalkingSpeed, Running = self.RunningSpeed}
  40.     self.State = self.States.Walking
  41.     self.UnusedStateTypes = {
  42.         Enum.HumanoidStateType.Flying,
  43.         Enum.HumanoidStateType.Seated,
  44.         Enum.HumanoidStateType.StrafingNoPhysics,
  45.         Enum.HumanoidStateType.Climbing,
  46.         Enum.HumanoidStateType.Swimming
  47.     }
  48.    
  49.     function self.CheckDistance(player)
  50.         local character = player.Character or player.CharacterAdded:Wait()
  51.         return math.abs((self.Root.Position - character.PrimaryPart.Position).Magnitude)
  52.     end
  53.    
  54.     function self.MandateType(object)
  55.         if typeof(object) ~= Vector3 then
  56.             return object.Position
  57.         end
  58.         return object
  59.     end
  60.    
  61.     function self.GetNearestPlayer()
  62.         local closestDistance = self.Visibility
  63.         local closestPlayer = nil
  64.         for _, player in pairs(Players:GetPlayers()) do
  65.             local dist = self.CheckDistance(player)
  66.             self.TargetPoints[player.Name] = dist
  67.             if dist < closestDistance then
  68.                 closestDistance = dist
  69.                 closestPlayer = player
  70.             end
  71.         end
  72.         return closestPlayer, closestDistance
  73.     end
  74.    
  75.     function self.RayCast(thing)
  76.         thing = self.MandateType(thing)
  77.         local ray = Ray.new(self.Root.Position, (thing - self.Root.Position).Unit * (self.Visibility + 10))
  78.         local part, pos = workspace:FindPartOnRay(ray, self.NPC)
  79.         local distance = math.abs((self.Root.Position - pos).Magnitude)
  80.         return part, pos, distance
  81.     end
  82.    
  83.     function self.AvoidEnemyPosition()
  84.         local targetPos = self.Target.Character.PrimaryPart.Position
  85.         local rand = Random.new():NextNumber(-90, 90)
  86.         local unit = (targetPos - self.Root.Position).Unit
  87.         local angle = math.atan2(-unit.Z, -unit.X) + math.rad(rand)
  88.         local cframe = CFrame.new(self.Root.Position) * CFrame.Angles(0, angle, 0) * CFrame.new(0, 0, -1)
  89.         return (cframe.Position - self.Root.Position).Unit
  90.     end
  91.    
  92.     function self.Logic()
  93.         -- still doing
  94.     end
  95.    
  96.     function self.Init()
  97.         self.Target, self.Distance = self.GetNearestPlayer()
  98.         if not self.TargetChanged then
  99.             repeat wait() until self.TargetChanged
  100.         end
  101.         self.TargetChanged:Fire(self.Target)
  102.     end
  103.    
  104.     function self.Setup()
  105.         coroutine.resume(coroutine.create(function()
  106.             for _, stateType in pairs(self.UnusedStateTypes) do
  107.                 self.Humanoid:SetStateEnabled(stateType, false)
  108.             end
  109.         end))
  110.            
  111.         if not script:FindFirstChild(self.Name .. 'Event') then
  112.             self.TargetChanged = Instance.new('BindableEvent')
  113.             self.TargetChanged.Name = self.Name .. 'Event'
  114.             self.TargetChanged.Parent = script
  115.         end
  116.        
  117.         -- Update state/walkspeed
  118.         script[self.Name .. 'Event'].Event:Connect(function(target)
  119.             self.State = (not self.Target and self.States.Walking) or self.States.Running
  120.             self.WalkSpeed = self.State
  121.         end)
  122.     end
  123.  
  124.     existingNPC[self.Name] = self
  125.     self.__tostring = self.Name
  126.     self.__index = self
  127.     self.Setup()
  128.     return self
  129. end
  130.  
  131. return module
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement