How do I make the sender and recipient of a trade always see what they are offering at the top?

totally fine if no one has solution but thought id ask anyways

So I’m in the process of making a trading system and I’m on the part where I’m displaying information about who is offering what, and basically this is the UI

I want the trade list on the top to always be the local players trade offers if that makes sense regardless if they are the sender or if they are the recipient but having a hard time wrapping my head around this

This is the server code

local TradeRequest = {}
TradeRequest.__index = TradeRequest

local Cache = require(game.ReplicatedStorage.Cache)

local timeLeftToRespond = 15

-- This function creates a new TradeRequest object
function TradeRequest.new(sender : Player, recipient : Player)
   local self = setmetatable({
      sender = sender,
      recipient = recipient,
      timeLeftToRespond = timeLeftToRespond,
      initialTimeLeftToRespond = timeLeftToRespond
   }, TradeRequest)

   Cache.UpdateTradeRequest(sender, {
      sender = sender.Name,
      recipient = recipient.Name,
      timeLeftToRespond = self.timeLeftToRespond,
      initialTimeLeftToRespond = self.timeLeftToRespond
   })

   task.spawn(function()
      self:startTimer()
   end)

   return self
end

-- This function is called every 0.1 seconds to decrement the timeLeftToRespond
function TradeRequest:startTimer()
   local decrementAmount = 1 / 10 -- Decrement timeLeftToRespond by this amount every 0.1 seconds
   while self.timeLeftToRespond and self.timeLeftToRespond > 0 and not self.isTradeInProgress do
      self.timeLeftToRespond -= decrementAmount
      Cache.UpdateTradeRequest(self.sender, {
         sender = self.sender.Name,
         recipient = self.recipient.Name,
         timeLeftToRespond = self.timeLeftToRespond,
         initialTimeLeftToRespond = self.initialTimeLeftToRespond
      })
      task.wait(.1)
   end
   if self.sender and not self.isTradeInProgress then
      self:Decline()
   end
end

-- This function is called when the recipient accepts the trade request
function TradeRequest:Accept()
   self.isTradeInProgress = true
   self.senderCapes = {}
   self.recipientCapes = {}
   Cache.UpdateTradeRequest(self.sender, {
      sender = self.sender.Name,
      recipient = self.recipient.Name,
      isTradeInProgress = true,
      recipientCapes = self.recipientCapes,
      senderCapes = self.senderCapes
   })
end

-- This function is called when the recipient declines the trade request
function TradeRequest:Decline()
   Cache.TradeRequests[tostring(self.sender.UserId)] = nil
   Cache.UpdateTradeRequest(self.sender, nil)
   for k in pairs(self) do
      self[k] = nil
   end
end

-- This method is called when either the sender or the recipient adds a cape to the trade
function TradeRequest:AddCape(player : Player, capeName : string)
   local function add(tbl)
      local myInventory = Cache.Inventories[tostring(player.UserId)]

      local hasThisCape = myInventory:DoesThisPlayerHaveThisCape(capeName)
      local capeQuantity = myInventory:GetCapeQuantity(capeName)

      if not hasThisCape then
         return
      end

      if tbl[capeName] and tbl[capeName].Quantity >= capeQuantity then
         print("You don't have enough of this cape to trade")
         return
      end

      if not tbl[capeName] then
         tbl[capeName] = {
            Quantity = 1
         }
      else
         self.senderCapes[capeName].Quantity += 1
      end

      Cache.UpdateTradeRequest(self.sender, {
         sender = self.sender.Name,
         recipient = self.recipient.Name,
         isTradeInProgress = true,
         recipientCapes = self.recipientCapes,
         senderCapes = self.senderCapes
      })

      print(Cache.TempCache.TradeRequests)
   end

   if player == self.sender then
      add(self.senderCapes)
   elseif player == self.recipient then
      add(self.recipientCapes)
   end
end

return TradeRequest

This is the client code (UI Stuff)

-- Trade Requests
local seenTradeRequests = {}

for _, data in pairs(tradeRequests) do
   local sender : string = data.sender
   local recipient : string = data.recipient
   local isTradeInProgress : boolean = data.isTradeInProgress
   
   -- If the player has a trade request
   if recipient == player.Name and not isTradeInProgress then
      seenTradeRequests[sender] = true

      local template : ImageButton
      local senderPlayer : Player = game.Players:FindFirstChild(sender)

      if existingTradeRequestsTemplates[sender] then
         template = existingTradeRequestsTemplates[sender]

         local BottomFrame : Frame = template.BottomFrame
         local TopFrame : Frame = BottomFrame.TopFrame

         local timeLeftToRespond : number = data.timeLeftToRespond
         local initialTimeLeftToRespond : number = data.initialTimeLeftToRespond

         local ratio = (timeLeftToRespond / initialTimeLeftToRespond)

         spr.target(TopFrame, .9, 2, {
            Size = UDim2.new(ratio, 0, TopFrame.Size.Y.Scale, 0)
         })
      else
         template = TradeRequests.PendingRequests.Templates.Template:Clone()
         template.Name = sender
         template.Parent = TradeRequests.PendingRequests
         template.Visible = true
         template.displayName.Text = senderPlayer.DisplayName
         template.username.Text = "@"..senderPlayer.Name

         task.spawn(function()
            if TradeRequests.Position.X.Scale <= .99 then return end
            TradeRequestTimer += 5
            spr.target(TradeRequests, .7, 2.5, {
               Position = UDim2.new(.99, 0, .5, 0)
            })
            task.wait(TradeRequestTimer)
            spr.target(TradeRequests, .7, 2.5, {
               Position = UDim2.new(1.5, 0, .5, 0)
            })
         end)

         template.Accept.MouseButton1Click:Connect(function()
            RemoteManager.acceptTradeRequest:FireServer(sender, true)
         end)

         template.Decline.MouseButton1Click:Connect(function()
            RemoteManager.acceptTradeRequest:FireServer(sender, false)
         end)

         if not existingThumbnails[senderPlayer.Name] then
            local thumbnail = game.Players:GetUserThumbnailAsync(senderPlayer.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size180x180)
            template.Image.Image = thumbnail
            existingThumbnails[senderPlayer.Name] = thumbnail
         else
            template.Image.Image = existingThumbnails[senderPlayer.Name]
         end
         existingTradeRequestsTemplates[sender] = template
      end
      -- If the player is in a trade
   elseif recipient == player.Name or sender == player.Name and isTradeInProgress then
      if ActiveTrade.Position.Y.Scale >= 1.5 then
         spr.target(ActiveTrade, .7, 2.5, {
            Position = UDim2.new(.5, 0, .5, 0)
         })
      end

      for capeName, capeData in pairs(playersCapes) do
         seenCapes[capeName.."_ActiveTrade"] = true
         local template : ImageButton

         if existingCapeTemplates[capeName.."_ActiveTrade"] then
            template = existingCapeTemplates[capeName.."_ActiveTrade"]
            template.Quantity.Text = "x"..capeData.Quantity
         else
            template = ActiveTrade.MyCapes.Templates.Template:Clone()
            template.Name = capeName.."_ActiveTrade"
            template.Parent = ActiveTrade.MyCapes
            template.Visible = true
            template.CapeName.Text = capeName
            template.Quantity.Text = "x"..capeData.Quantity
            existingCapeTemplates[capeName.."_ActiveTrade"] = template

            template.MouseButton1Click:Connect(function()
               RemoteManager.addCapeToTrade:FireServer(capeName)
            end)
         end
      end

      -- Trade offers

      for capeName, capeData in pairs(data.senderCapes) do
         seenCapes[capeName.."_Sender"] = true
         local template : ImageButton

         if existingCapeTemplates[capeName.."_Sender"] then
            template = existingCapeTemplates[capeName.."_Sender"]
            template.Quantity.Text = "x"..capeData.Quantity
         else
            template = ActiveTrade.TheirCapes.Templates.Template:Clone()
            template.Name = capeName.."_Sender"
            template.Parent = ActiveTrade.TheirCapes
            template.Visible = true
            template.CapeName.Text = capeName
            template.Quantity.Text = "x"..capeData.Quantity
            existingCapeTemplates[capeName.."_Sender"] = template
         end
      end

      for capeName, capeData in pairs(data.recipientCapes) do
         seenCapes[capeName.."_Recipient"] = true
         local template : ImageButton

         if existingCapeTemplates[capeName.."_Recipient"] then
            template = existingCapeTemplates[capeName.."_Recipient"]
            template.Quantity.Text = "x"..capeData.Quantity
         else
            template = ActiveTrade.MyCapes.Templates.Template:Clone()
            template.Name = capeName.."_Recipient"
            template.Parent = ActiveTrade.MyCapes
            template.Visible = true
            template.CapeName.Text = capeName
            template.Quantity.Text = "x"..capeData.Quantity
            existingCapeTemplates[capeName.."_Recipient"] = template
         end
      end
   end
end

You could create a folder inside the ServerStorage that will be the container for all current trades. Here’s a screenshot so you may understand it easily:

snip1

Now everytime a player adds an item, fire a remote event to the server to add a ValueObject to their respective folder. Now in that event, fire another remote event but this time to the client of those 2 players to update the list of items using tables.

Why would I do that when my clients already have access to every single active trade in the game?

All I need to do print(Cache.Get("TradeRequests"))

If that’s all you need to do, what’s your actual issue? Getting the information from the items to show up on the screen? That seems rather trivial no?

Well the problem is that i need to always have the top trade offer list to be the current player whether they are the sender or the recipient, what he offered is a completely different thing

1 Like

That’s the point of the folder-thing I sent earlier. The server would send the value from those folders to each of the 2 players. Then the client would detect if which folder is for them and for the other player.

1 Like

But I already know whos the sender and whos the recipient though, so I dont get what the point of that is if you could help me understand

image

Then use that data to pass on to the 2 players. Then the client would be the one to visualize that data.

Yeah thats what im doing im looping over them but I dont know how to make it so the top trade offer frame is populated with MY PLAYERS offers whether I am a sender or recipient

Can you send the client-sided code? The script that handles the UI for the trades.

um thats the one i put in the original post, it handles showing when someones sends you a request and when you are currently in a trade with someone who accepted your request

-- Trade Requests
local seenTradeRequests = {}

for _, data in pairs(tradeRequests) do
   local sender : string = data.sender
   local recipient : string = data.recipient
   local isTradeInProgress : boolean = data.isTradeInProgress
   
   -- If the player has a trade request
   if recipient == player.Name and not isTradeInProgress then
      seenTradeRequests[sender] = true

      local template : ImageButton
      local senderPlayer : Player = game.Players:FindFirstChild(sender)

      if existingTradeRequestsTemplates[sender] then
         template = existingTradeRequestsTemplates[sender]

         local BottomFrame : Frame = template.BottomFrame
         local TopFrame : Frame = BottomFrame.TopFrame

         local timeLeftToRespond : number = data.timeLeftToRespond
         local initialTimeLeftToRespond : number = data.initialTimeLeftToRespond

         local ratio = (timeLeftToRespond / initialTimeLeftToRespond)

         spr.target(TopFrame, .9, 2, {
            Size = UDim2.new(ratio, 0, TopFrame.Size.Y.Scale, 0)
         })
      else
         template = TradeRequests.PendingRequests.Templates.Template:Clone()
         template.Name = sender
         template.Parent = TradeRequests.PendingRequests
         template.Visible = true
         template.displayName.Text = senderPlayer.DisplayName
         template.username.Text = "@"..senderPlayer.Name

         task.spawn(function()
            if TradeRequests.Position.X.Scale <= .99 then return end
            TradeRequestTimer += 5
            spr.target(TradeRequests, .7, 2.5, {
               Position = UDim2.new(.99, 0, .5, 0)
            })
            task.wait(TradeRequestTimer)
            spr.target(TradeRequests, .7, 2.5, {
               Position = UDim2.new(1.5, 0, .5, 0)
            })
         end)

         template.Accept.MouseButton1Click:Connect(function()
            RemoteManager.acceptTradeRequest:FireServer(sender, true)
         end)

         template.Decline.MouseButton1Click:Connect(function()
            RemoteManager.acceptTradeRequest:FireServer(sender, false)
         end)

         if not existingThumbnails[senderPlayer.Name] then
            local thumbnail = game.Players:GetUserThumbnailAsync(senderPlayer.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size180x180)
            template.Image.Image = thumbnail
            existingThumbnails[senderPlayer.Name] = thumbnail
         else
            template.Image.Image = existingThumbnails[senderPlayer.Name]
         end
         existingTradeRequestsTemplates[sender] = template
      end
      -- If the player is in a trade
   elseif recipient == player.Name or sender == player.Name and isTradeInProgress then
      if ActiveTrade.Position.Y.Scale >= 1.5 then
         spr.target(ActiveTrade, .7, 2.5, {
            Position = UDim2.new(.5, 0, .5, 0)
         })
      end

      for capeName, capeData in pairs(playersCapes) do
         seenCapes[capeName.."_ActiveTrade"] = true
         local template : ImageButton

         if existingCapeTemplates[capeName.."_ActiveTrade"] then
            template = existingCapeTemplates[capeName.."_ActiveTrade"]
            template.Quantity.Text = "x"..capeData.Quantity
         else
            template = ActiveTrade.MyCapes.Templates.Template:Clone()
            template.Name = capeName.."_ActiveTrade"
            template.Parent = ActiveTrade.MyCapes
            template.Visible = true
            template.CapeName.Text = capeName
            template.Quantity.Text = "x"..capeData.Quantity
            existingCapeTemplates[capeName.."_ActiveTrade"] = template

            template.MouseButton1Click:Connect(function()
               RemoteManager.addCapeToTrade:FireServer(capeName)
            end)
         end
      end

      -- Trade offers

      for capeName, capeData in pairs(data.senderCapes) do
         seenCapes[capeName.."_Sender"] = true
         local template : ImageButton

         if existingCapeTemplates[capeName.."_Sender"] then
            template = existingCapeTemplates[capeName.."_Sender"]
            template.Quantity.Text = "x"..capeData.Quantity
         else
            template = ActiveTrade.TheirCapes.Templates.Template:Clone()
            template.Name = capeName.."_Sender"
            template.Parent = ActiveTrade.TheirCapes
            template.Visible = true
            template.CapeName.Text = capeName
            template.Quantity.Text = "x"..capeData.Quantity
            existingCapeTemplates[capeName.."_Sender"] = template
         end
      end

      for capeName, capeData in pairs(data.recipientCapes) do
         seenCapes[capeName.."_Recipient"] = true
         local template : ImageButton

         if existingCapeTemplates[capeName.."_Recipient"] then
            template = existingCapeTemplates[capeName.."_Recipient"]
            template.Quantity.Text = "x"..capeData.Quantity
         else
            template = ActiveTrade.MyCapes.Templates.Template:Clone()
            template.Name = capeName.."_Recipient"
            template.Parent = ActiveTrade.MyCapes
            template.Visible = true
            template.CapeName.Text = capeName
            template.Quantity.Text = "x"..capeData.Quantity
            existingCapeTemplates[capeName.."_Recipient"] = template
         end
      end
   end
end

What you could do is detect if the data is for the local player or the other player. If it is for the local player, then it would be visualized on the top frame. If it was for the other player, then it would be at the bottom frame.

1 Like

could you give me a code snippet please still kinda hard for me to think

1 Like

How will I do that if I don’t know the GUI element names. Let’s discuss about this on discord. my username: reeed_puulaaaa

1 Like

oh i dont use discord though so could you maybe me some pseudocode

1 Like

like this?

local localplayer = game.Players.LocalPlayer

local recipient = data.recipient
local sender = data.sender

local topframe = ActiveTrade.MyCapes
local bottomframe = ActiveTrade.TheirCapes

if recipient == localplayer.Name then
	for capeName, capeData in pairs(data.recipientCapes) do
		seenCapes[capeName.."_Recipient"] = true
		local template : ImageButton

		if existingCapeTemplates[capeName.."_Recipient"] then
			template = existingCapeTemplates[capeName.."_Recipient"]
			template.Quantity.Text = "x"..capeData.Quantity
		else
			template = topframe.Templates.Template:Clone()
			template.Name = capeName.."_Recipient"
			template.Parent = topframe
			template.Visible = true
			template.CapeName.Text = capeName
			template.Quantity.Text = "x"..capeData.Quantity
			existingCapeTemplates[capeName.."_Recipient"] = template
		end
	end
	for capeName, capeData in pairs(data.senderCapes) do
		seenCapes[capeName.."_Sender"] = true
		local template : ImageButton

		if existingCapeTemplates[capeName.."_Sender"] then
			template = existingCapeTemplates[capeName.."_Sender"]
			template.Quantity.Text = "x"..capeData.Quantity
		else
			template = bottomframe.Templates.Template:Clone()
			template.Name = capeName.."_Sender"
			template.Parent = bottomframe
			template.Visible = true
			template.CapeName.Text = capeName
			template.Quantity.Text = "x"..capeData.Quantity
			existingCapeTemplates[capeName.."_Sender"] = template
		end
	end
elseif sender == localplayer.Name then
	for capeName, capeData in pairs(data.senderCapes) do
		seenCapes[capeName.."_Sender"] = true
		local template : ImageButton

		if existingCapeTemplates[capeName.."_Sender"] then
			template = existingCapeTemplates[capeName.."_Sender"]
			template.Quantity.Text = "x"..capeData.Quantity
		else
			template = topframe.Templates.Template:Clone()
			template.Name = capeName.."_Sender"
			template.Parent = topframe
			template.Visible = true
			template.CapeName.Text = capeName
			template.Quantity.Text = "x"..capeData.Quantity
			existingCapeTemplates[capeName.."_Sender"] = template
		end
	end
	for capeName, capeData in pairs(data.recipientCapes) do
		seenCapes[capeName.."_Recipient"] = true
		local template : ImageButton

		if existingCapeTemplates[capeName.."_Recipient"] then
			template = existingCapeTemplates[capeName.."_Recipient"]
			template.Quantity.Text = "x"..capeData.Quantity
		else
			template = bottomframe.Templates.Template:Clone()
			template.Name = capeName.."_Recipient"
			template.Parent = bottomframe
			template.Visible = true
			template.CapeName.Text = capeName
			template.Quantity.Text = "x"..capeData.Quantity
			existingCapeTemplates[capeName.."_Recipient"] = template
		end
	end
end

i have absolutely no idea

1 Like

LETS GOOOOOOOOOOOO!!!

Alright so i did it a bit different and I checked inside of both loops and had just a blank variable for which UI and seems to be working!

for capeName, capeData in pairs(data.senderCapes) do
   seenCapes[capeName.."_Sender"] = true
   local template : ImageButton
   local parent : ScrollingFrame

   if player.Name == sender then
      parent = ActiveTrade.MyTradeList
   else
      parent = ActiveTrade.TheirTradeList
   end

   if existingCapeTemplates[capeName.."_Sender"] then
      template = existingCapeTemplates[capeName.."_Sender"]
      template.Quantity.Text = "x"..capeData.Quantity
   else
      template = ActiveTrade.Templates.Template:Clone()
      template.Name = capeName.."_Sender"
      template.Parent = parent
      template.Visible = true
      template.CapeName.Text = capeName
      template.Quantity.Text = "x"..capeData.Quantity
      existingCapeTemplates[capeName.."_Sender"] = template
   end
end

for capeName, capeData in pairs(data.recipientCapes) do
   seenCapes[capeName.."_Recipient"] = true
   local template : ImageButton
   local parent : ScrollingFrame

   if player.Name == sender then
      parent = ActiveTrade.MyTradeList
   else
      parent = ActiveTrade.TheirTradeList
   end

   if existingCapeTemplates[capeName.."_Recipient"] then
      template = existingCapeTemplates[capeName.."_Recipient"]
      template.Quantity.Text = "x"..capeData.Quantity
   else
      template = ActiveTrade.Templates.Template:Clone()
      template.Name = capeName.."_Recipient"
      template.Parent = parent
      template.Visible = true
      template.CapeName.Text = capeName
      template.Quantity.Text = "x"..capeData.Quantity
      existingCapeTemplates[capeName.."_Recipient"] = template
   end
end

1 Like

NICEE!! Goodluck on your project!

1 Like

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