|
|
|
|
| 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
|
|
|
|
|
| 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",
|
| startPos = droneModel.Position,
|
| targetPos = targetZone.Position + Vector3.new(0, 10, 0),
|
| carriedItem = nil
|
| }
|
|
|
| table.insert(activeDrones, droneData)
|
| return droneData
|
| end
|
|
|
|
|
| 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"
|
|
|
| if drone.carriedItem then
|
| drone.carriedItem.Anchored = false
|
| drone.carriedItem = nil
|
| end
|
|
|
|
|
| local temp = drone.startPos
|
| drone.startPos = drone.targetPos
|
| drone.targetPos = temp
|
| drone.state = "Traveling"
|
| end
|
| end
|
| end
|
| end)
|
|
|
|
|
| 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)
|
|
|
|
|
| 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
|
|
|