I don’t really understand – why not use a shop GUI with an open/close
button, and handle the verification of the purchase on the server? Using chat commands seems to overcomplicate this purpose and doesn’t seem very productive for a consumer, not to mention it would be easier to accomplish the former. Is there a reason for this choice in design?
It just looks cool to me. That is the entire reason.
But seriously I just do not want to make a shop since there is not downtime at all inside the game, and I just want there to be a notification since it looks cool, instead of a giant box on your screen.
That seems to have fixed it.
Also about that.
I scripted that inside of the little notification ‘if else’ statement. Did not seem to work at all (Also as of this edit I’m going to go eat)
if Reponse == "Yes" then
if plr.leaderstats.Cash.Value >= 300 then
plr.leaderstats.Cash.Value = plr.leaderstats.Cash.Value - 300
local c = SS.Weapons["AK-47"]:Clone()
c.Parent = plr.Backpack
end
else
print("Player canceled the purchase");
end;
It would be better to have an ID system of sorts and utilize a RemoteFunction
to determine whether the player purchased the weapon or not.
For example,
local Weapons = {
["AK-47"] = 47, -- Weapon name, price of weapon
}
local function RetrieveWeaponData(Arg)
for WeaponName, Price in pairs(Weapons) do
if WeaponName:lower():find(Arg) == 1 then
return WeaponName, Price
end
end
return nil, nil
end
...
local Arg = Msg:lower():match("%!buy (%w+)")
if Arg then
local WeaponName, _ = GetWeaponData(Arg)
if WeaponName then
local NewNotif = script.Notification:Clone()
NewNotif.WantedWeapon.Value = Weapon
NewNotif.TextLabel.Text = "Are you sure you want to buy [" .. Weapon .. "] ?"
NewNotif.Parent = Player.PlayerGui
end
end
...
PurchaseWeapon.OnServerInvoke = function(Player, WeaponName)
local WeaponName, Price = GetWeaponData(WeaponName)
-- Verify purchase on server, and give the specified weapon
end
That seems like a smart idea although it looks extremely confusing and
Notifications don’t work like that
That notification system seems fine to me. Simply clone the notification parent it to the player’s PlayerGui folder somewhere (so that it’s correctly rendered onto the screen) and then modify the shown GuiObjects accordingly (alter text, images etc.).
Sorry, went to bed.
The reason why its not working is because you need to give the item on the Server not the client. To do this you would have to use RemoteEvent and/or RemoteFunctions.
So right click on replicatedStorage → insert a new object (aka a remoteEvent) → name that remote whatever you want → define that remote in your notification script → have it FireServer() when player buys an item → server listens for the event → server gives item
Do I need to make a separate event for every single item?
No, what you want to do is pass arguments to differentiate between task you want to do.
E.g on the client you might have something like:
local Remote = game:GetService("ReplicatedStorage").MyRemote
Remote:FireServer("AK-47", 1235) -- we can send arguments!!
On the server script you would do:
local Remote = game:GetService("ReplicatedStorage").MyRemote
Remote.OnServerEvent:Connect(function(Player, WeaponName, RandomNumbers)
print(Player, WeaponName, RandomNumbers)
end)
I’m on mobile so there may be typos and bad formatting.
So the only arguments you really want to be passing to the server is the name of the item the player purchased. The server will then use that name to search a folder to get said item. You then can deduct whatever cash and give the item.
So your telling me I just fire the server with the item the player wants to buy, and then have a server script handle the fired event?
Yes. All the client is going to do is fire the remote and provide the name of the item. The server will handle the rest (such as finding the item, giving it, and deducting points).
Like this?
local Remote = game:GetService("ReplicatedStorage").Purchase
local Folder = game:GetService("ServerStorage").Weapons
Remote.OnServerEvent:Connect(function(Player, Weapon)
print(Player, Weapon)
local c = Folder:FindFirstChild(Weapon):Clone()
c.Parent = Player.BackPack
end)
Also here is what my Notification Script looks like now:
if Reponse == "Yes" then
if plr.leaderstats.Cash.Value >= 300 then
plr.leaderstats.Cash.Value = plr.leaderstats.Cash.Value - 300
RS.Purchase:FireServer("AK-47")
end
else
print("Player canceled the purchase");
end;
if plr.leaderstats.Cash.Value >= 300 then
plr.leaderstats.Cash.Value = plr.leaderstats.Cash.Value - 300
Move this part to the server for security and replication reasons. Security cause an exploiter can just fire the remote directly and get a free tool and what i mean by replication is that when you update a value on the client. The server won’t see it. So even if you’re deducting 300 cash from the player on the client. In reality the player will still have his 300 cash.
Ok I’ll just make it an argument while firing the server, would that be alright? like:
RS.Purchase:FireServer("AK-47", 300)
I don’t think you should make it an argument as exploiters can still fire the remote and just set the value to 0. Basically giving them a free weapon.
A simple alternative would be to store an IntValue called “Cost” inside the actual weapon. Then just get the cost on the server.
E.g
Remote.OnServerEvent:Connect(function(Player, Weapon)
print(Player, Weapon)
local GetWeapon = Folder:FindFirstChild(Weapon)
local Cost = GetWeapon:FindFirstChild("Cost").Value
-- do your check where you see if the player has enough
-- if they do then deduct the points and give the weapon
GetWeapon:Clone().Parent = Player.BackPack
end)
I made a little IntValue inside of my Tool
local Remote = game:GetService("ReplicatedStorage").Purchase
local Folder = game:GetService("ServerStorage").Weapons
Remote.OnServerEvent:Connect(function(Player, Weapon)
print(Player, Weapon)
local Price = Folder:FindFirstChild(Weapon).Cost.Value
if Player.leaderstats.Cash.Value >= Price then
Player.leaderstats.Cash.Value = Player.leaderstats.Cash.Value - Price
local c = Folder:FindFirstChild(Weapon):Clone()
c.Parent = Player.BackPack
end
end)
That’s what it looks like now
Skimmed over it and so far so good. Test it out in studio.
It worked! I did BackPack instead of Backpack, but I fixed it and it worked!