Untitled
unknown
lua
2 years ago
6.3 kB
16
Indexable
-- Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
--ReplicatedItems
local Modules = ReplicatedStorage:WaitForChild("Modules")
local Events = ReplicatedStorage:WaitForChild("Events")
local EnemyModels = ReplicatedStorage:WaitForChild("EnemyModels")
--ModuleScripts
local Waves = require(Modules:WaitForChild("Waves"))
local EnemyDataBase = require(Modules:WaitForChild("EnemyDataBase"))
local EnemyInfoDataBase = require(Modules:WaitForChild("EnemyInfoDataBase"))
--Events
local EnemySyncer = Events:WaitForChild("EnemySyncer")
--Workspace Varibales
local Nodes = workspace.Nodes
local SpawnCFrame = Nodes[0].CFrame
--FunctionsDefine
--MathFunctions
local function Lerp(a, b, t)
return a + (b - a) * t
end
local function QuadraticBezier(t, p0, p1, p2)
local l1 = Lerp(p0, p1, t)
local l2 = Lerp(p1, p2, t)
local quad = Lerp(l1, l2, t)
return quad
end
--Enemy Functions
local function AddEnemyToDataBase(EnemyName)
local Table = {}
for ItemName, Item in pairs(EnemyInfoDataBase[EnemyName]) do
Table[ItemName] = Item
if ItemName == "CFrame" then
Table["CFrame"] = SpawnCFrame
elseif ItemName == "XOffset" then
Table["XOffset"] = Random.new():NextNumber(-1, 1)
end
end
table.insert(EnemyDataBase, Table)
end
local function InitiateDataBaseTurningSequence(EnemyData)
EnemyData.Turning = true
task.wait(((Nodes[EnemyData.Node].Position - Nodes[EnemyData.Node].Mid.Position).Magnitude / EnemyData.Speed) - EnemyData.TurningHelper)
EnemyData.CFrame = Nodes[EnemyData["Node"]].Mid.CFrame
task.wait((Nodes[EnemyData.Node].Mid.Position - Nodes[EnemyData.Node].End.Position).Magnitude / EnemyData.Speed)
EnemyData.Turning = false
EnemyData.CFrame = Nodes[EnemyData["Node"]].End.CFrame
EnemyData.Node += 1
end
local function InitiateGraphicalTurningSequenceLoop(DeltaTime, EnemyID, EnemyData, Time, Distance, Position, LookPosition, Node0, Node1, Node2, EndCFrame)
EnemyData.CornerStatus += DeltaTime
Time = EnemyData.CornerStatus / Distance
if Time > 1 then
workspace.Enemies:WaitForChild(EnemyID).PrimaryPart.CFrame = EndCFrame
EnemyData.CornerStatus = 0
RunService:UnbindFromRenderStep("CornerTurn"..EnemyID)
else
Position = QuadraticBezier(Time, Node0, Node1, Node2)
LookPosition = QuadraticBezier(Time + 0.001, Node0, Node1, Node2)
if workspace.Enemies:FindFirstChild(EnemyID) then
workspace.Enemies:WaitForChild(EnemyID).PrimaryPart.CFrame = CFrame.lookAt(Position, LookPosition)
end
end
end
local function InitiateGraphicalTurningSequence(EnemyID, EnemyData)
workspace.Enemies[EnemyID].PrimaryPart.CFrame = EnemyData.CFrame
local Distance = ((Nodes[EnemyData["Node"]].Position - Nodes[EnemyData["Node"]].Mid.Position).Magnitude / EnemyData["Speed"]) - EnemyData.TurnerHelper + (Nodes[EnemyData["Node"]].Mid.Position - Nodes[EnemyData["Node"]].End.Position).Magnitude / EnemyData["Speed"]
local Time = 0
local Position = 0
local LookPosition = 0
local Node = EnemyData["Node"]
local Node0 = Nodes[Node].Position + (workspace.Enemies[EnemyID].PrimaryPart.CFrame:ToWorldSpace(CFrame.new(EnemyData.XOffset, EnemyData.YOffset, 0)).Position - workspace.Enemies[EnemyID].PrimaryPart.Position)
local Node1 = Nodes[Node].Mid.Position + (workspace.Enemies[EnemyID].PrimaryPart.CFrame:ToWorldSpace(CFrame.new(EnemyData.XOffset, EnemyData.YOffset, EnemyData.XOffset)).Position - workspace.Enemies[EnemyID].PrimaryPart.Position)
local Node2 = Nodes[Node].End.Position + (workspace.Enemies[EnemyID].PrimaryPart.CFrame:ToWorldSpace(CFrame.new(0, EnemyData.YOffset, EnemyData.XOffset)).Position - workspace.Enemies[EnemyID].PrimaryPart.Position)
local EndCFrame = Nodes[Node].End.CFrame + (workspace.Enemies[EnemyID].PrimaryPart.CFrame:ToWorldSpace(CFrame.new(0, EnemyData.YOffset, EnemyData.XOffset)).Position - workspace.Enemies[EnemyID].PrimaryPart.Position)
RunService:BindToRenderStep("CornerTurn"..EnemyID, 0, function(DeltaTime)
InitiateGraphicalTurningSequenceLoop(DeltaTime, EnemyID, EnemyData, Time, Distance, Position, LookPosition, Node0, Node1, Node2, EndCFrame)
end)
end
local function LoopThroughEnemies(OverallDeltaTime)
for EnemyID, EnemyData in pairs(EnemyDataBase) do
if EnemyData["Turning"] == false then
EnemyData.CFrame = Nodes
EnemyData.CFrame = Nodes[EnemyData["Node"]].CFrame:ToWorldSpace(CFrame.new(0, 0,(EnemyData.CFrame.Position - Nodes[EnemyData["Node"]].Position).Magnitude - (EnemyData.Speed * OverallDeltaTime)))
if Nodes[EnemyData["Node"]].CFrame:ToWorldSpace():ToObjectSpace(EnemyData.CFrame).Position.Z <= 0 then
EnemyData.TurningHelper = (Nodes[EnemyData["Node"]].CFrame:ToWorldSpace():ToObjectSpace(EnemyData.CFrame).Position.Z * -1) / EnemyData.Speed
EnemyData.CFrame = Nodes[EnemyData["Node"]].CFrame
coroutine.wrap(InitiateDataBaseTurningSequence)(EnemyData)
coroutine.wrap(InitiateGraphicalTurningSequence)(EnemyID, EnemyData)
end
workspace.Enemies[EnemyID].PrimaryPart.CFrame = EnemyData.CFrame + (workspace.Enemies[EnemyID].PrimaryPart.CFrame:ToWorldSpace(CFrame.new(EnemyData.XOffset, EnemyData.YOffset, 0)).Position - workspace.Enemies[EnemyID].PrimaryPart.Position)
end
end
end
local function DoNeedenThings(Enemy, EnemyName)
local AnimationController = Instance.new("AnimationController", Enemy)
local Animator = Instance.new("Animator", AnimationController)
local Animation = Enemy:WaitForChild("Walk")
local Track = Animator:LoadAnimation(Animation)
Track:Play()
end
--WaveLoop
local function WaveSequence()
for WaveCount, WaveData in pairs(Waves) do
for EnemyName, EnemyData in pairs(WaveData.Enemies) do
task.wait(EnemyData.StartDelay)
for Count=1, EnemyData.Amount do
AddEnemyToDataBase(EnemyName)
local Enemy = EnemyModels[EnemyName]:Clone()
Enemy.Parent = workspace.Enemies
Enemy.Name = #EnemyDataBase
DoNeedenThings(Enemy)
if EnemyData.Interval ~= 0 then
task.wait(EnemyData.Interval)
end
end
end
end
end
--EnemyMover
RunService:BindToRenderStep("ClientLoop", 0, LoopThroughEnemies)
--WaveLoop
EnemySyncer.OnClientEvent:Connect(function()
coroutine.wrap(WaveSequence)()
end)Editor is loading...