Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local Players = game:GetService("Players")
- local RunService = game:GetService("RunService")
- local ReplicatedStorage = game:GetService("ReplicatedStorage")
- local ServerScriptService = game:GetService("ServerScriptService")
- local Container = require(ReplicatedStorage.Classes.Containers.Container)
- local ContainerReceiver = require(ReplicatedStorage.Classes.ContainerReceiver)
- local ContainerHolder = require(ReplicatedStorage.Classes.ContainerHolders.ContainerHolder)
- local ReplicatedContainerHolder = require(ReplicatedStorage.Classes.ContainerHolders.ReplicatedContainerHolder)
- local AllPlayerFilterer = require(ReplicatedStorage.Classes.PlayerFilterers.AllPlayerFilterer)
- local DamageManager = require(ReplicatedStorage.Modules.DamageManager)
- local Signal = require(ReplicatedStorage.Libs.Signal)
- local ProjectileManager = {}
- local IS_CLIENT = RunService:IsClient()
- -- TODO: add curve function
- ProjectileManager.ProjectileHit = Signal.new()
- ProjectileManager.ProjectileDestroyed = Signal.new()
- ProjectileManager.LastCFrames = {}
- ProjectileManager.MoveFunctions = {}
- ProjectileManager.DefaultProperties = {
- MoveType = "Linear",
- Lifetime = 0.7,
- HitRadius = 5,
- Damage = 5,
- Owner = nil,
- Object = nil,
- StartTime = nil,
- StartCFrame = nil,
- TargetCFrame = nil,
- }
- function ProjectileManager.MoveFunctions.Linear(startCFrame, targetCFrame, time)
- return startCFrame:Lerp(targetCFrame, time)
- end
- function ProjectileManager.MoveFunctions.Quadratic(startCFrame, targetCFrame, time)
- return startCFrame:Lerp(targetCFrame, 1 - math.pow(1 - time, 2))
- end
- function ProjectileManager.CreateProjectile(container)
- if not getmetatable(container) then
- container = Container.new(container)
- end
- for k, v in ProjectileManager.DefaultProperties do
- if container:GetValue(k) == nil then
- container:SetValue(k, v)
- end
- end
- if not container:GetValue("StartTime") then
- container:SetValue("StartTime", workspace:GetServerTimeNow())
- end
- if not container:GetValue("RaycastParams") then
- local params = RaycastParams.new()
- params.FilterDescendantsInstances = {
- container:GetValue("Object"),
- container:GetValue("Shooter")
- }
- container:SetValue("RaycastParams", params)
- end
- end
- function ProjectileManager.AddProjectile(container)
- ProjectileManager.ProjectileContainerHolder:AddContainer(container.Object, container)
- end
- function ProjectileManager.DestroyProjectile(container)
- ProjectileManager.ProjectileDestroyed:Fire(container)
- ProjectileManager.ProjectileContainerHolder:RemoveContainer(container.Object)
- end
- if RunService:IsClient() then
- local CONTAINER_CONSTRUCTOR = function(key, data)
- return Container.new(data)
- end
- ProjectileManager.ProjectileContainerHolder = ContainerHolder.new()
- ProjectileManager.ProjectileContainerReceiver = ContainerReceiver.new("Projectiles", ProjectileManager.ProjectileContainerHolder, CONTAINER_CONSTRUCTOR)
- else
- ProjectileManager.ProjectileContainerHolder = ReplicatedContainerHolder.new("Projectiles", ContainerHolder.new(), function(player)
- return AllPlayerFilterer.new()
- end)
- end
- RunService.Stepped:Connect(function()
- for _, container in ProjectileManager.ProjectileContainerHolder:GetAllContainers() do
- local timePassed = workspace:GetServerTimeNow() - container:GetValue("StartTime")
- local timePercentage = timePassed / container:GetValue("Lifetime")
- if timePercentage > 1 then
- ProjectileManager.DestroyProjectile(container)
- continue
- end
- local currentCFrame = ProjectileManager.MoveFunctions[container:GetValue("MoveType")](
- container:GetValue("StartCFrame"),
- container:GetValue("TargetCFrame"),
- timePercentage
- )
- local lastCFrame = ProjectileManager.LastCFrames[container] or currentCFrame
- local lastPosition = lastCFrame.Position
- local currentPosition = currentCFrame.Position
- local direction = currentPosition - lastPosition
- local result = workspace:Spherecast(
- lastPosition,
- container:GetValue("HitRadius"),
- direction,
- container:GetValue("RaycastParams")
- )
- if result then
- ProjectileManager.DestroyProjectile(container)
- ProjectileManager.ProjectileHit:Fire(container, result)
- continue
- end
- if IS_CLIENT then
- container:GetValue("Object").CFrame = currentCFrame
- end
- end
- end)
- ProjectileManager.ProjectileHit:Connect(function(container, result)
- DamageManager.ApplyDamage(
- result.Instance,
- container:GetValue("Damage"),
- container:GetValue("Shooter")
- )
- end)
- return ProjectileManager
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement