File size: 3,858 Bytes
0712d5f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
-- 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