Advertisement
AlewAlow

Projectile manager

May 2nd, 2024 (edited)
598
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.50 KB | None | 0 0
  1. local Players = game:GetService("Players")
  2. local RunService = game:GetService("RunService")
  3. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  4. local ServerScriptService = game:GetService("ServerScriptService")
  5.  
  6. local Container = require(ReplicatedStorage.Classes.Containers.Container)
  7. local ContainerReceiver = require(ReplicatedStorage.Classes.ContainerReceiver)
  8. local ContainerHolder = require(ReplicatedStorage.Classes.ContainerHolders.ContainerHolder)
  9. local ReplicatedContainerHolder = require(ReplicatedStorage.Classes.ContainerHolders.ReplicatedContainerHolder)
  10. local AllPlayerFilterer = require(ReplicatedStorage.Classes.PlayerFilterers.AllPlayerFilterer)
  11.  
  12. local DamageManager = require(ReplicatedStorage.Modules.DamageManager)
  13.  
  14. local Signal = require(ReplicatedStorage.Libs.Signal)
  15.  
  16. local ProjectileManager = {}
  17.  
  18. local IS_CLIENT = RunService:IsClient()
  19.  
  20. -- TODO: add curve function
  21. ProjectileManager.ProjectileHit = Signal.new()
  22. ProjectileManager.ProjectileDestroyed = Signal.new()
  23.  
  24. ProjectileManager.LastCFrames = {}
  25. ProjectileManager.MoveFunctions = {}
  26. ProjectileManager.DefaultProperties = {
  27.     MoveType = "Linear",
  28.     Lifetime = 0.7,
  29.     HitRadius = 5,
  30.     Damage = 5,
  31.    
  32.     Owner = nil,
  33.     Object = nil,
  34.    
  35.     StartTime = nil,
  36.     StartCFrame = nil,
  37.     TargetCFrame = nil,
  38. }
  39.  
  40. function ProjectileManager.MoveFunctions.Linear(startCFrame, targetCFrame, time)
  41.     return startCFrame:Lerp(targetCFrame, time)
  42. end
  43.  
  44. function ProjectileManager.MoveFunctions.Quadratic(startCFrame, targetCFrame, time)
  45.     return startCFrame:Lerp(targetCFrame, 1 - math.pow(1 - time, 2))
  46. end
  47.  
  48. function ProjectileManager.CreateProjectile(container)
  49.     if not getmetatable(container) then
  50.         container = Container.new(container)
  51.     end
  52.    
  53.     for k, v in ProjectileManager.DefaultProperties do
  54.         if container:GetValue(k) == nil then
  55.             container:SetValue(k, v)
  56.         end
  57.     end
  58.    
  59.     if not container:GetValue("StartTime") then
  60.         container:SetValue("StartTime", workspace:GetServerTimeNow())
  61.     end
  62.    
  63.     if not container:GetValue("RaycastParams") then
  64.         local params = RaycastParams.new()
  65.        
  66.         params.FilterDescendantsInstances = {
  67.             container:GetValue("Object"),
  68.             container:GetValue("Shooter")
  69.         }
  70.        
  71.         container:SetValue("RaycastParams", params)
  72.     end
  73. end
  74.  
  75. function ProjectileManager.AddProjectile(container)
  76.     ProjectileManager.ProjectileContainerHolder:AddContainer(container.Object, container)
  77. end
  78.  
  79. function ProjectileManager.DestroyProjectile(container)
  80.     ProjectileManager.ProjectileDestroyed:Fire(container)
  81.     ProjectileManager.ProjectileContainerHolder:RemoveContainer(container.Object)
  82. end
  83.  
  84. if RunService:IsClient() then
  85.     local CONTAINER_CONSTRUCTOR = function(key, data)
  86.         return Container.new(data)
  87.     end
  88.    
  89.     ProjectileManager.ProjectileContainerHolder = ContainerHolder.new()
  90.     ProjectileManager.ProjectileContainerReceiver = ContainerReceiver.new("Projectiles", ProjectileManager.ProjectileContainerHolder, CONTAINER_CONSTRUCTOR)
  91. else
  92.     ProjectileManager.ProjectileContainerHolder = ReplicatedContainerHolder.new("Projectiles", ContainerHolder.new(), function(player)
  93.         return AllPlayerFilterer.new()
  94.     end)
  95. end
  96.  
  97. RunService.Stepped:Connect(function()
  98.     for _, container in ProjectileManager.ProjectileContainerHolder:GetAllContainers() do
  99.         local timePassed = workspace:GetServerTimeNow() - container:GetValue("StartTime")
  100.         local timePercentage = timePassed / container:GetValue("Lifetime")
  101.         if timePercentage > 1 then
  102.             ProjectileManager.DestroyProjectile(container)
  103.             continue
  104.         end
  105.        
  106.         local currentCFrame = ProjectileManager.MoveFunctions[container:GetValue("MoveType")](
  107.             container:GetValue("StartCFrame"),
  108.             container:GetValue("TargetCFrame"),
  109.             timePercentage
  110.         )
  111.        
  112.         local lastCFrame = ProjectileManager.LastCFrames[container] or currentCFrame
  113.         local lastPosition = lastCFrame.Position
  114.         local currentPosition = currentCFrame.Position
  115.         local direction = currentPosition - lastPosition
  116.        
  117.         local result = workspace:Spherecast(
  118.             lastPosition,
  119.             container:GetValue("HitRadius"),
  120.             direction,
  121.             container:GetValue("RaycastParams")
  122.         )
  123.        
  124.         if result then
  125.             ProjectileManager.DestroyProjectile(container)
  126.             ProjectileManager.ProjectileHit:Fire(container, result)
  127.             continue
  128.         end
  129.        
  130.         if IS_CLIENT then
  131.             container:GetValue("Object").CFrame = currentCFrame
  132.         end
  133.     end
  134. end)
  135.  
  136. ProjectileManager.ProjectileHit:Connect(function(container, result)
  137.     DamageManager.ApplyDamage(
  138.         result.Instance,
  139.         container:GetValue("Damage"),
  140.         container:GetValue("Shooter")
  141.     )
  142. end)
  143.  
  144.  
  145. return ProjectileManager
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement