| |
|
| |
|
| | 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
|
| |
|