167 lines
4.7 KiB
Lua
167 lines
4.7 KiB
Lua
local RunService = game:GetService("RunService")
|
|
local UserInputService = game:GetService("UserInputService")
|
|
|
|
local Tower = require(script.Parent.Tower)
|
|
local Waves = require(script.Parent.Waves)
|
|
|
|
local towerTypes = {
|
|
{
|
|
name = "Basic",
|
|
model = workspace.BasicTowerModel,
|
|
range = 20,
|
|
damage = 10,
|
|
fireRate = 1,
|
|
},
|
|
{
|
|
name = "Slow",
|
|
model = workspace.SlowTowerModel,
|
|
range = 15,
|
|
damage = 5,
|
|
fireRate = 0.5,
|
|
effect = {name = "slow", params = {duration = 2, value = 0.5}}
|
|
},
|
|
{
|
|
name = "Fire",
|
|
model = workspace.FireTowerModel,
|
|
range = 18,
|
|
damage = 8,
|
|
fireRate = 1,
|
|
effect = {name = "burn", params = {duration = 3, tick = 1, value = 2}}
|
|
},
|
|
{
|
|
name = "Freeze",
|
|
model = workspace.FreezeTowerModel,
|
|
range = 12,
|
|
damage = 0,
|
|
fireRate = 0.5,
|
|
effect = {name = "freeze", params = {duration = 1}}
|
|
}
|
|
}
|
|
|
|
local waypoints = { -- Fill with your waypoint Parts
|
|
workspace.Waypoint1,
|
|
workspace.Waypoint2,
|
|
workspace.Waypoint3,
|
|
-- etc.
|
|
}
|
|
|
|
local selectedTowerType = towerTypes[1]
|
|
local enemies = {} -- Table to hold TrackEnemy objects
|
|
local towers = {}
|
|
local placingTower = false
|
|
local rangeIndicator = nil
|
|
|
|
function selectTowerType(index)
|
|
selectedTowerType = towerTypes[index]
|
|
end
|
|
|
|
local function spawnWave(waveData)
|
|
coroutine.wrap(function()
|
|
for _, group in ipairs(waveData) do
|
|
for i = 1, group.count do
|
|
local enemyModel = group.model:Clone()
|
|
enemyModel.Parent = workspace
|
|
local enemy = TrackEnemy:new(enemyModel, group.name, group.health, group.speed)
|
|
table.insert(enemies, enemy)
|
|
end
|
|
|
|
if group.delay and group.delay > 0 then
|
|
wait(group.delay)
|
|
end
|
|
end
|
|
end)()
|
|
end
|
|
|
|
spawnWave(Waves[1])
|
|
|
|
local function isOnTrack(position)
|
|
for _, waypoint in ipairs(waypoints) do
|
|
if (waypoint.Position - position).Magnitude < 5 then -- 5 studs
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function showRangeIndicator(position, range)
|
|
if not rangeIndicator then
|
|
rangeIndicator = Instance.new("Part")
|
|
rangeIndicator.Name = "RangeIndicator"
|
|
rangeIndicator.Shape = Enum.PartType.Cylinder
|
|
rangeIndicator.Anchored = true
|
|
rangeIndicator.CanCollide = false
|
|
rangeIndicator.Transparency = 0.6
|
|
rangeIndicator.Color = Color3.fromRGB(100, 200, 255)
|
|
rangeIndicator.Material = Enum.Material.Neon
|
|
rangeIndicator.Size = Vector3.new(range * 2, 0.2, range * 2)
|
|
rangeIndicator.Parent = workspace
|
|
-- Rotate so cylinder is flat
|
|
rangeIndicator.Orientation = Vector3.new(0, 0, 90)
|
|
end
|
|
rangeIndicator.Size = Vector3.new(range * 2, 0.2, range * 2)
|
|
rangeIndicator.Position = Vector3.new(position.X, position.Y + 0.1, position.Z)
|
|
rangeIndicator.Visible = true
|
|
end
|
|
|
|
local function hideRangeIndicator()
|
|
if rangeIndicator then
|
|
rangeIndicator:Destroy()
|
|
rangeIndicator = nil
|
|
end
|
|
end
|
|
|
|
RunService.RenderStepped:Connect(function ()
|
|
if placingTower then
|
|
local mouse = game.Players.LocalPlayer:GetMouse()
|
|
local position = mouse.Hit.p
|
|
showRangeIndicator(position, selectedTowerType.range)
|
|
else
|
|
hideRangeIndicator()
|
|
end
|
|
end)
|
|
|
|
UserInputService.InputBegan:Connect(function(input, gameProcessed)
|
|
if gameProcessed then return end
|
|
if input.KeyCode == Enum.KeyCode.T then
|
|
placingTower = not placingTower
|
|
print("Tower Placing Mode:", placingTower and "ON" or "OFF")
|
|
if not placingTower then
|
|
hideRangeIndicator()
|
|
end
|
|
end
|
|
end)
|
|
|
|
UserInputService.InputBegan:Connect(function (input, gameProcessed)
|
|
if gameProcessed then return end
|
|
if input.UserInputType == Enum.UserInputType.MouseButton1 and placingTower then
|
|
local mouse = game.Players.LocalPlayer():GetMouse()
|
|
local position = mouse.Hit.p
|
|
if not isOnTrack(position) then
|
|
local tower = Tower:new(
|
|
selectedTowerType.model,
|
|
position,
|
|
selectedTowerType.range,
|
|
selectedTowerType.damage,
|
|
selectedTowerType.fireRate,
|
|
selectedTowerType.effect
|
|
)
|
|
table.insert(towers, tower)
|
|
hideRangeIndicator()
|
|
end
|
|
end
|
|
end)
|
|
|
|
RunService.Heartbeat:Connect(function(dt)
|
|
for _, tower in ipairs(towers) do
|
|
tower:attack(enemies, dt)
|
|
end
|
|
end)
|
|
|
|
RunService.Heartbeat:Connect(function(dt)
|
|
for i, enemy in ipairs(enemies) do
|
|
if enemy.alive then
|
|
enemy:moveToWaypoints(waypoints, dt)
|
|
end
|
|
end
|
|
end)
|