Hello! This is kinda a lot and I really don’t expect anyone to solve my issue here but I am using Tags and basically I have 2 Milkshake glasses but with different :GetFullName() (workspace paths), but I don’t want to have to double my code when I could just send the item path to the module.
If this doesn’t make sense lol here’s my question, how would I use the correct ItemPath in the moudle script
Client:
for _, MilkshakeGlass in game:GetService("CollectionService"):GetTagged("MilkshakeGlass") do
local ClickDetector = MilkshakeGlass.MilkshakeGlassClickDetector
spawn(function()
while wait() do
MilkshakeGlass.Capacity.Overhead.Main.Image.Rotation = MilkshakeGlass.Capacity.Overhead.Main.Image.Rotation + 5
end
end)
ClickDetector.MouseClick:Connect(function()
if LocalPlayer:GetRankInGroup(GameDataModule.GroupID) >= RankDataModule.JuniorBarista then
GetItemEvent:InvokeServer("MilkshakeGlass")
CorrectItemPath:FireServer(MilkshakeGlass:GetFullName())
end
end)
end
Server Script:
local CorrectItemPath = game.ReplicatedStorage.Events.RemoteEvents.CorrectItemPath
local ActualItemPath
CorrectItemPath.OnServerEvent:Connect(function(ItemPath)
ActualItemPath = ItemPath
end)
local function ClickEvent(Player, ItemType)
if Player:GetRankInGroup(GameDataModule.GroupID) >= RankDataModule.JuniorBarista then
if ItemType == "MilkshakeGlass" then
GetItemModule.MilkshakeGlass(Player)
end
else
Player:Kick(KickMessageModule.GetItemHandler)
end
end
GetItemEvent.OnServerInvoke = ClickEvent
Module Script:
local CorrectItemPath = game.ReplicatedStorage.Events.RemoteEvents.CorrectItemPath
local ActualItemPath
CorrectItemPath.OnServerEvent:Connect(function(ItemPath)
ActualItemPath = ItemPath
end)
function GetItem.MilkshakeGlass(Player)
local ItemPath = ActualItemPath
local ProgressBar = ItemPath.Capacity.Overhead.Main.Bar.Progress
local RemainingText = ItemPath.Capacity.Overhead.Main.Remaining
local Remaining = ItemPath:GetAttribute("Remaining")
local Active = ItemPath:GetAttribute("Active")
if Active == true then
if Remaining == 1 then
local CopiedItem = MilkshakeGlass:Clone()
ItemPath:SetAttribute("Remaining", Remaining - 1)
ItemPath:SetAttribute("Active", false)
ItemPath:SetAttribute("CanBeRestocked", true)
ItemPath.Hitbox.GetItem:Play()
TweenService:Create(ProgressBar, TweenInformation, {Size = UDim2.new(0, 0, 1, 0)}):Play()
RemainingText.Text = ItemPath:GetAttribute("Remaining")
CopiedItem.Parent = Player.Backpack
wait(NextPossibleGetItemTime)
ItemPath.Capacity.Overhead.Main.Image.Visible = true
ItemPath.Capacity.Overhead.Main.Message.Visible = true
ItemPath.Capacity.Overhead.Main.Bar.Visible = false
ItemPath.Capacity.Overhead.Main.Remaining.Visible = false
ItemPath.Capacity.Overhead.Main.Header.Text = "Milkshake Glasses"
elseif Remaining >= 2 then
local CopiedItem = MilkshakeGlass:Clone()
ItemPath:SetAttribute("Remaining", Remaining - 1)
ItemPath:SetAttribute("Active", false)
ItemPath.Hitbox.GetItem:Play()
TweenService:Create(ProgressBar, TweenInformation, {Size = ProgressBar.Size - UDim2.fromScale(0.05, 0)}):Play()
RemainingText.Text = ItemPath:GetAttribute("Remaining")
CopiedItem.Parent = Player.Backpack
wait(NextPossibleGetItemTime)
ItemPath:SetAttribute("Active", true)
end
end
end
I decided to do this because I realized that when I would click on either of the Milkshake glasses only one of them would update the value and do other stuff so I want it to work on the correct one so I tried using a RemoteEvent and it isn’t working.
CorrectItemPath.OnServerEvent:Connect(function(Item) -- Item is a string with the name of the milkshake that got clicked
if Item == "Milkshake1" then
-- Update the value for the first milkshake
elseif Item == "Milkshake2" then
-- Update the value for the second milkshake
end
end)
See, the issue im having is in the module script, I can clone as many Milkshake glasses as I want but each Milkshake glass has a BillboardGui that displays how many are left before it has to be restocked
Well in that case you could use loadstring() since GetFullName() returns a string. First, you must enable it. ServerScriptStorage has a property called LoadStringEnabled which you must enable in order for loadstring() to work. Once you have it enabled, here’s how you use loadstring().
There’s quite a bit going on here. Can you elaborate on what you’re looking to do? Are you just trying to find an item in the workspace by its full name?
CollectionService:GetTagged already returns a table of tagged instances, is there a reason you need to use :GetFullName to find the instance instead of just using the table of instances?
I would advise against using loadstring whenever possible, there are essentially no reasons to use loadstring for non-malicious purposes, it disables Luau optimizations and is overall not secure, especially if you don’t know what you’re doing. There are a few posts on this topic but this one sums it up pretty well:
It wouldn’t work syntactically either, you’re basically just putting the following into a function, so it’s going to error when you call it:
Oh, I didn’t know it didn’t work with functions. Thanks for letting me know. Also, I agree with you guys, loadstring() should try to be avoided. I was just giving it as an option for him to consider.
Yeah sorry there is a lot but basically I have 2 Milkshake Glasses and their tagged with MilkshakeGlass and each of the Glasses have a BillBoardGUI on them displaying how many glasses are left and i’m trying to get the correct workspace path
Couldn’t you just iterate through the table CollectionService:GetTagged returns then?
Eg.
local milkshakeGlasses = collectionService:GetTagged('MilkshakeGlass')
for i, milkshakeGlass in ipairs(milkshakeGlasses) do
-- update milkshake glass billboard gui
end
If you need to look in the workspace though, you can split the string up using . as a separator:
local path = milkshakeGlass:GetFullName()
-- so if path is workspace.someModel.MilkshakeGlass, you can split it up using "." as separator
local splitPath = path:split('.')
-- so now splitPath would be a table: {"Workspace", "someModel", "MilkshakeGlass"}
local last = game
for i, childName in ipairs(splitPath) do
last = last:WaitForChild(childName) -- so it would do game:WaitForChild('Workspace') (you can probably create an exception when i == 1 to use getservice instead of waitforchild but just for example purposes) -> workspace:WaitForChild('SomeModel') and so on to the end of the table
end
-- now, last should be equal to the milkshake glass
print(last) -- should be MilkshakeGlass
Before I found out about this issue in the past this user to be local ItemPath = game.workspace.TheRestOfThePath but that doesn’t work because each Milkshake Glass displays a Billboard GUI
loadstring() can’t be exploited unless there is a back door in your game. This is because it can only be used on the server, hence the property being located in ServerScriptService.
Oops I meant to reply but guess I forgot. My guess is that this is happening because you have more than one glass with the same name in the workspace. Couldn’t you just pass the actual object in the workspace to the server instead of its path? Then you know for sure that you’re passing the correct object instead of going by its name, which is a nonunique identifier.