Hi, with the help of @Elttob I was able to re-work a version of a custom Backpack Gui I’m working on to allow items to move backwards if one were removed. I’m now looking to reverse this so that if a specific item [E.G. Named: “Wand”] is added into the Backpack then it is placed in [1] and is the first item in the order and all others, if there are any, are moved up to the next corresponding one.
Now, I’ve tried reversing what I’ve learned with the removing; but that doesn’t seem to work. I am relatively new to the use of Tables and was wondering if anyone could please help?
function ChildAdded(Child)
if Child:IsA("Tool") then
local isNew = true
for _, Value in pairs(inputKeys) do
local Tool = Value["Tool"]
if Tool then
if Tool == Child then
isNew = false
end
end
end
if isNew == true then
for i = 1, #inputOrder do wait()
local Tool = inputOrder[i]["Tool"]
if inputOrder[i]["Tool"] == Child then
inputOrder[i]["Tool"] = nil
end
if not Tool then
inputOrder[i]["Tool"] = Child
break
end
end
end
Configure()
end
end
ChildRemoved
function ChildRemoved(Child)
if Child:IsA("Tool") then
if Child.Parent ~= Player.Character and Child.Parent ~= Player["Backpack"] then
for i = 1, #inputOrder do wait()
if inputOrder[i]["Tool"] == Child then
inputOrder[i]["Tool"] = nil
break
end
end
for index=1, #inputOrder - 1 do
wait()
local thisItem = inputOrder[index]
local nextItem = inputOrder[index + 1]
if thisItem["Tool"] == nil and nextItem["Tool"] ~= nil then
thisItem["Tool"] = nextItem["Tool"]
nextItem["Tool"] = nil
end
end
end
Configure()
end
end
Now I’m not that familiar with tables, but what I would do is to rewrite the entire table. But that’s just me, I’m sure there is an easier way to do it.
When adding an item at index n, loop for i = #table, -1, n do, and move table[i] to table[i + 1]. Then you can put the item in at index n.
Edit: Sample code for clarification
local list = {1, 2, 3, 5, 6}
local function addItem(item, index)
-- move everything behind index back
for i = #list, -1, index do
list[i + 1] = list[i]
end
-- place item in
list[index] = item
end
addItem(7, 4)
for i = 1, #list do
print(list[i])
end
-- Output >> 1 2 3 7 5 6
cc @KossmoZ
Just saying, it would most likely be easier to use table.insert(table, index, value). The above is pretty much what the function does behind the scenes, but it’s easier to use.
Hi, I’m trying to wrap my head around these tables - As your list only lists 1 - 6 with no 4; table.insert would added a fourth variable but what if one were to already exist and just needs moving forward one space? :L
local tableSample = {index 1, index 2, index 3...}
table.insert shoves everything over, then replaces the specified index with the specified value.
local sample = {3, 9, 2}
--`3` is at index 1, `9` is at index 2, `2` is at index 2
table.insert(sample, 2, 10) --Table, index, value
--So, the above turns the table into {3, index 2, 9, 2}
--Then: {3, 10, 9, 2}
if I were to use Table.Insert would there not then be six variables?
Full script for reference:
local System = {}
local UserInputService = game:GetService("UserInputService")
local CoreGui = script.Parent
local Gui = CoreGui["ToolBar"]
local Player = game:GetService("Players").LocalPlayer
local StarterGui = game:GetService("StarterGui")
local success, result = pcall(StarterGui.SetCoreGuiEnabled, StarterGui, Enum.CoreGuiType.Backpack, false)
local inputKeys =
{["One"] = {Text = "1"};
["Two"] = {Text = "2"};
["Three"] = {Text = "3"};
["Four"] = {Text = "4"};
["Five"] = {Text = "5"}}
local inputOrder =
{inputKeys["One"]; inputKeys["Two"]; inputKeys["Three"]; inputKeys["Four"]; inputKeys["Five"]}
function System:Enable()
local PlayerTools = Player["Backpack"]:GetChildren()
for i = 1, #PlayerTools do wait()
if PlayerTools[i]:IsA("Tool") then
for i = 1, #inputOrder do wait()
local Value = inputOrder[i]
if not Value["Tool"] then
Value["Tool"] = PlayerTools[i]
break
end
end
end
end
Create()
UserInputService.InputBegan:Connect(onKeyPress)
Player.Character.ChildAdded:Connect(ChildAdded)
Player.Character.ChildRemoved:Connect(ChildRemoved)
Player["Backpack"].ChildAdded:Connect(ChildAdded)
Player["Backpack"].ChildRemoved:Connect(ChildRemoved)
end
function Create()
for i = 1, #inputOrder do wait()
local Value = inputOrder[i]
local Template = script["Template"]:Clone()
Template.Parent = Gui
Template["TextLabel"].Text = Value["Text"]
Template.Name = Value["Text"]
local Tool = Value["Tool"]
if Tool then
if Tool.TextureId == "" then
Template["ItemName"].Text = Tool.Name
else
Template["Item"].Image = Tool.TextureId
end
Template.Visible = true
end
Template["Item"].MouseButton1Down:Connect(function()
for i, Value in pairs(inputKeys) do
if Value["Text"] == Template.Name then
EquipTool(Value["Tool"])
end
end
end)
end
end
function onKeyPress(inputObject)
local Key = inputObject.KeyCode.Name
local Value = inputKeys[Key]
if Value and UserInputService:GetFocusedTextBox() == nil then
EquipTool(Value["Tool"])
end
end
function EquipTool(Tool)
if Tool then
if Tool.Parent ~= Player.Character then
Player.Character:WaitForChild("Humanoid"):EquipTool(Tool)
else
Player.Character:WaitForChild("Humanoid"):UnequipTools()
end
end
end
function ChildAdded(Child)
if Child:IsA("Tool") then
local isNew = true
for _, Value in pairs(inputKeys) do
local Tool = Value["Tool"]
if Tool then
if Tool == Child then
isNew = false
end
end
end
if isNew == true then
if Child.Name == "Tool" then
table.insert(inputOrder, 1, Child)
else
for i = 1, #inputOrder do wait()
local Tool = inputOrder[i]["Tool"]
if inputOrder[i]["Tool"] == Child then
inputOrder[i]["Tool"] = nil
end
if not Tool then
inputOrder[i]["Tool"] = Child
break
end
end
end
end
Configure()
end
end
function ChildRemoved(Child)
if Child:IsA("Tool") then
if Child.Parent ~= Player.Character and Child.Parent ~= Player["Backpack"] then
for i = 1, #inputOrder do wait()
if inputOrder[i]["Tool"] == Child then
inputOrder[i]["Tool"] = nil
break
end
end
for index=1, #inputOrder - 1 do
wait()
local thisItem = inputOrder[index]
local nextItem = inputOrder[index + 1]
if thisItem["Tool"] == nil and nextItem["Tool"] ~= nil then
thisItem["Tool"] = nextItem["Tool"]
nextItem["Tool"] = nil
end
end
end
Configure()
end
end
function Configure()
for _, Value in pairs (inputKeys) do
local Tool = Value["Tool"]
local Item = Gui:FindFirstChild(Value["Text"])
if Tool then
Item.Visible = true
if Tool.TextureId == "" then
Item["ItemName"].Text = Tool.Name
else
Item["Item"].Image = Tool.TextureId
end
if Tool.Parent == Player.Character then
Item.ImageTransparency = .5
else
Item.ImageTransparency = .75
end
else
Item.Visible = false
Item["Item"].Image = ""
Item["ItemName"].Text = ""
end
end
end
System:Enable()
return System
I want it to work where if a new Child is added into the Backpack i.e. collected; and it’s titled: “Wand” then that’s always placed in Slot1 to be the front of the queue.
If any other item is in Slot1 at the time of collection, i.e. “Potion” then when “Wand” becomes Slot1; Potions becomes Slot2 and carrying on for others if found.
Currently this is how I’m working on moving the indexes forward by one however I am currently experiencing some unintended bugs that are causing the other segments of the table to become occupied by multiple of the same tools.
for i = 1, #inputOrder - 1 do wait()
local currentIndex = inputOrder[i]
local nextIndex = inputOrder[i + 1]
if currentIndex["Tool"] ~= nil then
nextIndex["Tool"] = currentIndex["Tool"]
currentIndex["Tool"] = nil
end
end
inputOrder[1]["Tool"] = Child
for i = 1, #inputOrder - 1 do wait()
local currentIndex = inputOrder[i]
local nextIndex = inputOrder[i + 1]
if currentIndex["Tool"] ~= nil and currentIndex["Tool"] == not currentIndex["Tool"] then
nextIndex["Tool"] = currentIndex["Tool"]
currentIndex["Tool"] = nil
break
end
inputOrder[1]["Tool"] = Child
end