TimberWoods / src /ServerScriptService /DroneAutomationManager.server.lua
algorembrant's picture
Upload 88 files
0712d5f verified
-- src/ServerScriptService/DroneAutomationManager.server.lua
local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local AutomationConfig = require(ReplicatedStorage:WaitForChild("Shared"):WaitForChild("AutomationConfig"))
local activeDrones = {}
local function getPartVolume(part)
return part.Size.X * part.Size.Y * part.Size.Z
end
local function spawnDrone(droneType, startZone, targetZone)
local config = AutomationConfig.Drones[droneType]
if not config then return end
-- In real game, clone from ReplicatedStorage
local droneModel = Instance.new("Part")
droneModel.Name = "DeliveryDrone"
droneModel.Size = Vector3.new(4, 1, 4)
droneModel.BrickColor = BrickColor.new("Dark stone grey")
droneModel.Anchored = true
droneModel.CFrame = startZone.CFrame + Vector3.new(0, 5, 0)
droneModel:SetAttribute("TargetZone", targetZone.Name)
droneModel.Parent = workspace
local droneData = {
model = droneModel,
config = config,
state = "Idle", -- Idle, Loading, Traveling, Unloading
startPos = droneModel.Position,
targetPos = targetZone.Position + Vector3.new(0, 10, 0),
carriedItem = nil
}
table.insert(activeDrones, droneData)
return droneData
end
-- Simplified Drone AI Loop
RunService.Heartbeat:Connect(function(dt)
for i, drone in ipairs(activeDrones) do
local model = drone.model
if not model or not model.Parent then
table.remove(activeDrones, i)
continue
end
if drone.state == "Traveling" then
local direction = (drone.targetPos - model.Position).Unit
local distance = (drone.targetPos - model.Position).Magnitude
local moveStep = math.min(drone.config.Speed * dt, distance)
model.Position = model.Position + (direction * moveStep)
if drone.carriedItem and drone.carriedItem.Parent then
drone.carriedItem.Position = model.Position - Vector3.new(0, 3, 0)
end
if distance < 1 then
drone.state = "Unloading"
-- Drop item
if drone.carriedItem then
drone.carriedItem.Anchored = false
drone.carriedItem = nil
end
-- Return Home
local temp = drone.startPos
drone.startPos = drone.targetPos
drone.targetPos = temp
drone.state = "Traveling"
end
end
end
end)
-- Drone Pickup Pad Logic
local function bindDronePad(pad)
local debounce = {}
pad.Touched:Connect(function(hit)
if CollectionService:HasTag(hit, "TreeSegment") and not debounce[hit] then
debounce[hit] = true
local volume = getPartVolume(hit)
-- Find an available idle drone assigned to this pad
for _, drone in ipairs(activeDrones) do
if drone.state == "Idle" and volume <= drone.config.MaxCarryWeight then
drone.state = "Traveling"
drone.carriedItem = hit
hit.Anchored = true
break
end
end
task.delay(1, function()
debounce[hit] = nil
end)
end
end)
end
CollectionService:GetInstanceAddedSignal("DronePad"):Connect(bindDronePad)
for _, pad in pairs(CollectionService:GetTagged("DronePad")) do
bindDronePad(pad)
end