Advertisement
MLGQuickSkopur

HitboxCaster

Oct 12th, 2020 (edited)
850
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.83 KB | None | 0 0
  1. -- Made by St_vnC
  2. -- St_vn#3931
  3. -- Latest update : 12/11/2020
  4.  
  5. --[[
  6. API :
  7.   ** IMPORTANT : Requiring the module returns the constructor function **
  8.  
  9.   Constructor function : Parameter(Part), creates a new hitbox with the attachments in the specified part
  10.  
  11.   Hitbox:Cast(Filter) : Raycasts continuously for the hitbox with a specified filter until Hitbox:Stop() is called, the parameters are Part, Model, Humanoid, The attachment's parent
  12.  
  13.   Hitbox:Stop() : Stop casting rays for this hitbox
  14.  
  15.   Hitbox:Remove() : Removes the hitbox and allows it to be garbage collected
  16. ]]
  17.  
  18. local createSignal = require(game.ReplicatedStorage.Modules.Util.ScriptSignalService) -- You could alternatively use BindableEvents but I'd rather not use instances. Signal Service : https://pastebin.com/P4C3X7KV
  19. local Heartbeat = game:GetService("RunService").Heartbeat -- recommended to handle connection(s)/tasks procedurally
  20.  
  21. local hitbox = {}
  22. hitbox.__index = hitbox
  23.  
  24. local hitboxes = {}
  25. local active = {}
  26.  
  27. local zero = Vector3.new()
  28. local whitelist = "DmgPoint"
  29. local rayParams = RaycastParams.new()
  30. rayParams.FilterType = Enum.RaycastFilterType.Blacklist
  31.  
  32. local function Callback()
  33.     for myPart, info in pairs(active) do
  34.         if info.Position - myPart.Position == zero then continue end
  35.        
  36.         for _, attachment in ipairs(info.Attachments) do
  37.             rayParams.FilterDescendantsInstances = info.Filter
  38.            
  39.             local results = workspace:Raycast(attachment.WorldPosition, (myPart.Position - info.Position).Unit, rayParams)
  40.  
  41.             if results then
  42.                 local part = results.Instance
  43.                 local model = part:FindFirstAncestorWhichIsA("Model")
  44.                 local human = model and model:FindFirstChildWhichIsA("Humanoid")
  45.                
  46.                 table.insert(info.Filter, model)
  47.                
  48.                 if human then
  49.                     info.Signal:Fire(part, model, human, myPart)
  50.                 end
  51.             end
  52.         end
  53.        
  54.         info.Position = myPart.Position
  55.     end
  56. end
  57.  
  58. function hitbox:Cast(Filter)
  59.     self.Position = self.Part.Position
  60.     self.Filter = Filter
  61.    
  62.     active[self.Part] = self
  63. end
  64.  
  65. function hitbox:Stop()
  66.     local Filter = self.Filter
  67.     self.Position = nil
  68.  
  69.     for _ = 1, #Filter or 1 do
  70.         table.remove(Filter)
  71.     end
  72.  
  73.     activeCount -= 1
  74.     active[self.Part] = nil
  75. end
  76.  
  77. function hitbox:Remove()
  78.     local attachments = self.Attachments
  79.    
  80.     self:Stop()
  81.     self.Signal:Destroy()
  82.     hitboxes[self.Part] = nil
  83.     self.Part = nil
  84.    
  85.     for _ = 1, #attachments do
  86.         table.remove(attachments)
  87.     end
  88. end
  89.  
  90. return function(part)
  91.     if hitboxes[part] then
  92.         return hitboxes[part]
  93.     else
  94.         local attachments = {}
  95.        
  96.         for _, attachment in ipairs(part:GetChildren()) do
  97.             if not attachment:IsA("Attachment") then continue end
  98.             attachments[#attachments + 1] = attachment
  99.         end
  100.        
  101.         hitboxes[part] = setmetatable({
  102.             Part = part,
  103.             Attachments = attachments,
  104.             Signal = createSignal()
  105.         }, hitbox)
  106.        
  107.         return hitboxes[part]
  108.     end
  109. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement