Code Issues - Cloning Tools onto Delivery Area Boxes positions

Hello! I’m facing an issue trying to position my tools within the delivery areas. Currently, the cloned tools are not being correctly positioned within the delivery areas. My objective is to have these cloned tools fixed in place (without moving) within the positions of the delivery areas. How can I achieve this?

The delivery areas are identified as “deliverareabox_1”, etc. The system is modular, and it’s crucial that two tools are not cloned in the same position. There should always be only one tool in each delivery area, and it should be the closest one to the player.

I appreciate any guidance or suggestions to solve this issue.

I’ve attached the organizational structure of my project for better understanding

image

server-side script:

-- Get the RemoteFunction for delivering orders from the client
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local deliverOrderFunction = ReplicatedStorage.remoteFunctions:WaitForChild("deliverOrderFunction")

-- Folder for delivery boxes
local deliveryBoxesFolder = game.Workspace.Game_Elements.Deliverables.CheffDeliver_Area.deliverAreasBoxes

-- Function to find the nearest deliver area box
local function findNearestDeliverAreaBox(playerPosition)
	local nearestBox = nil
	local shortestDistance = math.huge

	for _, box in ipairs(deliveryBoxesFolder:GetChildren()) do
		local boxPosition = box.Position
		local distance = (playerPosition - boxPosition).magnitude

		if distance < shortestDistance then
			nearestBox = box
			shortestDistance = distance
		end
	end

	return nearestBox
end

-- Define the action when the function is invoked on the server
deliverOrderFunction.OnServerInvoke = function(player, orderData)
	-- Get the player's position
	local playerPosition = player.Character and player.Character.HumanoidRootPart.Position
	if not playerPosition then
		return false, "Player position not available"
	end

	-- Get the player's tools
	local playerTools = player.Backpack:GetChildren()

	-- Flag to check if both items are found
	local item1Found = false
	local item2Found = false

	-- Iterate through the player's tools
	for _, tool in ipairs(playerTools) do
		-- Check if the tool's name matches orderData.item1
		if tool.Name == orderData.item1 then
			item1Found = true
		end

		-- Check if the tool's name matches orderData.item2 if it exists
		if orderData.item2 and tool.Name == orderData.item2 then
			item2Found = true
		end

		-- If both items are found, break the loop
		if item1Found and (not orderData.item2 or item2Found) then
			break
		end
	end

	-- Check if both items are found
	if item1Found and (not orderData.item2 or item2Found) then
		-- Print a message indicating that both items are found
		print("Both items found for player: " .. player.Name)

		-- Find the nearest deliver area box
		local nearestBox = findNearestDeliverAreaBox(playerPosition)
		if nearestBox then
			-- Clone the tools at the position of the nearest deliver area box
			for _, tool in ipairs(playerTools) do
				local toolClone = tool:Clone()
				-- Set the cloned tool's position to the position of the deliver area box
				toolClone.Handle.Position = nearestBox.Position
				-- Set the cloned tool's name to match the item name
				toolClone.Name = tool.Name
				toolClone.Parent = nearestBox
			end

			-- Destroy the tools from the player's inventory
			for _, tool in ipairs(playerTools) do
				tool:Destroy()
			end

			print("Tools cloned and removed from player's inventory")

			-- Get the player's PlayerData folder
			local playerData = player:WaitForChild("PlayerData")

			-- Get the CB IntValue inside PlayerData
			local CBValue = playerData:WaitForChild("CB", 2) -- Timeout after 2 seconds if not found

			-- Check if CB IntValue exists
			if CBValue then
				-- Increase the CB value by the order total price
				CBValue.Value = CBValue.Value + orderData.totalprice

				-- Print a message indicating the increase in CB
				print("CB increased for player " .. player.Name .. " by " .. orderData.totalprice)
			else
				print("CB value not found in PlayerData")
			end
		else
			print("No deliver area box found near the player")
		end
	else
		-- Print a message indicating that one or both items are missing
		print("One or both items are missing for player: " .. player.Name)
	end

	-- Print order details
	print("Order received by: " .. player.Name)   

	return true, "Order complete by the server side"
end

I think this could potentially solve your problem, try and tell me.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local deliverOrderFunction = ReplicatedStorage.remoteFunctions:WaitForChild("deliverOrderFunction")

local deliveryAreasFolder = game.Workspace.Game_Elements.Deliverables.CheffDeliver_Area.deliverAreasBoxes

local function findNearestDeliveryArea(playerPosition)
    local nearestBox = nil
    local shortestDistance = math.huge

    for _, box in ipairs(deliveryAreasFolder:GetChildren()) do
        local boxPosition = box.Position
        local distance = (playerPosition - boxPosition).Magnitude

        if distance < shortestDistance then
            nearestBox = box
            shortestDistance = distance
        end
    end

    return nearestBox
end

deliverOrderFunction.OnServerInvoke = function(player, orderData)
    local playerPosition = player.Character and player.Character.HumanoidRootPart.Position
    if not playerPosition then
        return false, "Player position not available"
    end

    local playerTools = player.Backpack:GetChildren()

    local item1Found = false
    local item2Found = false

    for _, tool in ipairs(playerTools) do
        if tool.Name == orderData.item1 then
            item1Found = true
        end

        if orderData.item2 and tool.Name == orderData.item2 then
            item2Found = true
        end

        if item1Found and (not orderData.item2 or item2Found) then
            break
        end
    end

    if item1Found and (not orderData.item2 or item2Found) then
        print("Both items found for player: " .. player.Name)

        local nearestBox = findNearestDeliveryArea(playerPosition)
        if nearestBox then
            local clonedTools = {}

            for _, tool in ipairs(playerTools) do
                local toolClone = tool:Clone()
                toolClone.Parent = nearestBox
                table.insert(clonedTools, toolClone)
            end

            for _, toolClone in ipairs(clonedTools) do
                toolClone.Handle.Position = nearestBox.Position
            end

            for _, tool in ipairs(playerTools) do
                tool:Destroy()
            end

            print("Tools cloned and removed from player's inventory")
        else
            print("No delivery area found near the player")
        end
    else
        print("One or both items are missing for player: " .. player.Name)
    end

    print("Order received by: " .. player.Name)

    return true, "Order complete by the server side"
end

	-- Print order details
	print("Order received by: " .. player.Name)   

	return true, "Order complete by the server side"
end

1 Like

image

It works but the issue is that both tools are being cloned in the same position. The tools aren’t staying fixed in position and they fall off. Do you happen to know how I could make it so that only one tool is cloned per delivery area? That way, if there are two tools, one would be cloned in a delivery area that doesn’t have other tools inside, and the other in another delivery area.

1 Like

Oh! I managed to do it anyway, thank you very much for your comments, you gave me the idea and improved my code! Thank you very much, you are marked as a solution :smiley:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local deliverOrderFunction = ReplicatedStorage.remoteFunctions:WaitForChild("deliverOrderFunction")

local deliveryAreasFolder = game.Workspace.Game_Elements.Deliverables.CheffDeliver_Area.deliverAreasBoxes

local function findNearestDeliveryArea(playerPosition)
	local nearestBox = nil
	local shortestDistance = math.huge

	for _, box in ipairs(deliveryAreasFolder:GetChildren()) do
		local boxPosition = box.Position
		local distance = (playerPosition - boxPosition).Magnitude

		if distance < shortestDistance then
			nearestBox = box
			shortestDistance = distance
		end
	end

	return nearestBox
end

local function resetDeliveryAreaTransparency(tool, deliveryBox)
	tool.Equipped:Connect(function()
		deliveryBox.Transparency = 0
	end)
end

deliverOrderFunction.OnServerInvoke = function(player, orderData)
	local playerPosition = player.Character and player.Character.HumanoidRootPart.Position
	if not playerPosition then
		return false, "Player position not available"
	end

	local playerTools = player.Backpack:GetChildren()

	local item1Found = false
	local item2Found = false

	for _, tool in ipairs(playerTools) do
		if tool.Name == orderData.item1 then
			item1Found = true
		end

		if orderData.item2 and tool.Name == orderData.item2 then
			item2Found = true
		end

		if item1Found and (not orderData.item2 or item2Found) then
			break
		end
	end

	if item1Found then
		print("Item 1 found for player: " .. player.Name)

		local nearestBox1 = findNearestDeliveryArea(playerPosition)
		if nearestBox1 then
			local tool1 = nil
			for _, tool in ipairs(playerTools) do
				if tool.Name == orderData.item1 then
					tool1 = tool
					break
				end
			end

			if tool1 then
				local tool1Clone = tool1:Clone()
				tool1Clone.Parent = nearestBox1
				tool1Clone.Handle.Position = nearestBox1.Position
				nearestBox1.Transparency = 1
				tool1:Destroy()

				print("Tool 1 cloned and removed from player's inventory")
				resetDeliveryAreaTransparency(tool1Clone, nearestBox1)
			end
		else
			print("No delivery area found near the player for item 1")
		end
	end

	if orderData.item2 and item2Found then
		print("Item 2 found for player: " .. player.Name)

		local nearestBox2 = nil
		for _, box in ipairs(deliveryAreasFolder:GetChildren()) do
			if box ~= nearestBox1 then
				nearestBox2 = box
				break
			end
		end

		if nearestBox2 then
			local tool2 = nil
			for _, tool in ipairs(playerTools) do
				if tool.Name == orderData.item2 then
					tool2 = tool
					break
				end
			end

			if tool2 then
				local tool2Clone = tool2:Clone()
				tool2Clone.Parent = nearestBox2
				tool2Clone.Handle.Position = nearestBox2.Position
				nearestBox2.Transparency = 1
				tool2:Destroy()

				print("Tool 2 cloned and removed from player's inventory")
				resetDeliveryAreaTransparency(tool2Clone, nearestBox2)
			end
		else
			print("No delivery area found near the player for item 2")
		end
	end

	print("Order received by: " .. player.Name)

	return true, "Order complete by the server side"
end
1 Like

ahah pleased to have been able to help you

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.