CapsAdmin

Untitled

Jun 24th, 2011
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.86 KB | None | 0 0
  1. local PANEL = vgui.Register("items.Trading", {}, "DFrame")
  2.  
  3. function PANEL:Init()
  4.    
  5.     self.sheet = vgui.Create("DPropertySheet", self)
  6.    
  7.         self.trading = vgui.Create("DPanel", self)
  8.         local trading = self.trading
  9.        
  10.         trading.divider = vgui.Create("DHorizontalDivider", trading)
  11.        
  12.         trading.left = {}
  13.         trading.left.items = {}
  14.        
  15.         trading.right = {}
  16.         trading.right.items = {}
  17.            
  18.         trading:SetPaintBackground(false)
  19.        
  20. --      RunConsoleCommand("gm_clearfonts")
  21.        
  22.         surface.CreateFont("Arial Black", 25, 300, true, false, "ItemsNameLabel", true, true)
  23.        
  24.         for key, side in pairs({trading.left, trading.right}) do                   
  25.             side.list = vgui.Create("DPanelList")
  26.             side.list:EnableHorizontal(false)
  27.             side.list:EnableVerticalScrollbar(true)
  28.             side.list:SetSpacing(0)
  29.        
  30.             side.name = vgui.Create("DLabel", side.list)
  31.             side.name:SetFont("ItemsNameLabel")
  32.             side.name:SetText(key)
  33.             side.name:NoClipping(true)
  34.             side.name:SetTextColor(Color(255,255,255))
  35.             side.name:SizeToContents()
  36.             side.name:SetZPos(1)
  37.            
  38.             side.coins = vgui.Create("DNumberWang", trading)
  39.             side.coins:SetDecimals(0)
  40.             side.coins:NoClipping(true)
  41.             side.coins:SetZPos(2)
  42.             side.coins:SetWide(100)
  43.             side.coins:SetMax(LocalPlayer():GetCoins())
  44.            
  45.             side.coinslabel = vgui.Create("DLabel", trading)
  46.             side.coinslabel:SetText("Coins")
  47.             side.coinslabel:SetFont("ChatFont")
  48.             side.coinslabel:SetTextColor(Color(255,255,255))
  49.            
  50.             side.coinslabel:SizeToContents()
  51.            
  52.             side.coins.TextEntry.OnCursorEntered = function()
  53.                 self:SetKeyboardInputEnabled(true)
  54.                 self:MakePopup()
  55.             end
  56.            
  57.             side.coins.TextEntry.OnCursorExited = function()
  58.                 self:SetKeyboardInputEnabled(false)
  59.                 self:KillFocus()
  60.             end
  61.            
  62.             function side.list:Paint()
  63.                 DPanelList.Paint(self)
  64.                 surface.SetDrawColor( 150, 150, 150, 255 )
  65.                 surface.DrawOutlinedRect( 0, 0, self:GetWide(), self:GetTall() )
  66.             end
  67.         end
  68.  
  69.         trading.left.coins.OnNewChange = function(_ ,value) -- Does this have an argument?
  70.             timer.Create("SendCoinsUpdate", 0.25, 1, function()
  71.                 RunConsoleCommand("items_trade", LocalPlayer():EntIndex(), "coins", value)
  72.             end)
  73.         end
  74.  
  75.         --[[trading.left.coins.TextEntry.OnEnter = function() -- This one :C
  76.             timer.Create("SendCoinsUpdate", 0.5, 1, function()
  77.                 RunConsoleCommand("items_trade", LocalPlayer():EntIndex(), "coins", trading.left.coins.TextEntry:GetValue())
  78.             end)
  79.         end]]
  80.         local oldValue = tonumber(trading.left.coins:GetValue()) or 0
  81.         hook.Add("Think", "items.Trading.Think", function()
  82.             if not ValidPanel(self) then
  83.                 hook.Remove("Think", "items.Trading.Think")
  84.                 return
  85.             end
  86.             local n = tonumber(trading.left.coins:GetValue()) or 0
  87.             if n ~= oldValue then
  88.                 local c = math.Clamp(n, 0, LocalPlayer():GetCoins())
  89.                 if c ~= n then
  90.                     trading.left.coins:SetValue(c)
  91.                     n = c
  92.                 end
  93.                 trading.left.coins:OnNewChange(n)
  94.                 oldValue = n
  95.             end
  96.         end)
  97.  
  98.         trading.right.coins.Wanger.OnMousePressed = function() end
  99.         trading.right.coins.TextEntry:SetEditable(false)
  100.        
  101.         trading.divider:SetLeft(trading.left.list)
  102.         trading.divider:SetRight(trading.right.list)
  103.         trading.divider.StartGrab = function() end
  104.  
  105.        
  106.         trading.trade = vgui.Create("DButton", trading)
  107.         trading.trade:SetText("Trade")
  108.         trading.trade:SetSize(130, 30)
  109.         trading.trade.DoClick = function()
  110.             RunConsoleCommand("items_trade", LocalPlayer():EntIndex(), "finished")
  111.             --self:Close()
  112.         end
  113.  
  114.        
  115.         trading.decline = vgui.Create("DButton", trading)
  116.         trading.decline:SetText("Cancel")
  117.         trading.decline:SetSize(130, 30)
  118.         trading.decline.DoClick = function()
  119.             RunConsoleCommand("items_trade", LocalPlayer():EntIndex(), "cancel")
  120.             self:Close()
  121.         end
  122.  
  123.        
  124.     self.sheet:AddSheet("Trading", trading, "gui/silkicons/arrow_refresh", false, false, "Trading")
  125.            
  126.         self.inventory = vgui.Create("DPanelList", self)
  127.         local inventory = self.inventory
  128.         inventory:EnableHorizontal(false)
  129.         inventory:EnableVerticalScrollbar(true)
  130.         inventory:SetSpacing(5)
  131.         inventory.items = {}
  132.        
  133.     self.sheet:AddSheet("Inventory", inventory, "gui/silkicons/folder_go", false, false, "Inventory")
  134.            
  135.     self:SetTitle("Trade")
  136.     self:SetSize(ScrW()/1.5,500)
  137.     self:Center()
  138.     self:AlignTop(50)
  139.     self:ShowCloseButton(false)
  140.     self:SetSizable(true)
  141.    
  142.     self:UpdateInventory()
  143.     self:SetLeftName(LocalPlayer():Nick())
  144. end
  145.  
  146. function PANEL:Think()
  147.     gui.EnableScreenClicker(true)
  148. end
  149.  
  150. AccessorFunc(PANEL, "trader", "Trader")
  151.  
  152. function PANEL:UpdateInventory()
  153.     self.inventory:Clear()
  154.     local inventory = LocalPlayer():GetInventory()
  155.     for class, table in pairs(inventory) do
  156.         if class ~= "" then
  157.             if not table.data then table.data = items.GetItemDataFromClass(class) end
  158.            
  159.             if table.data then
  160.                 local item = vgui.Create("items.ItemPanel", self)
  161.                 local text = items.GetInventoryInfo(class)
  162.                
  163.                 item:SetCount(table.count)
  164.                 item:SetItemInfo(items.Get(class).WorldModel or blank, text.name, text.info)
  165.                 item:SetMenu(function()
  166.                     local menu = DermaMenu()
  167.                     menu:MakePopup()
  168.                     menu:SetPos(gui.MousePos())
  169.                     menu:AddOption("Add", function()
  170.                         self:AddLeftItem(item, class)
  171.                         RunConsoleCommand("items_trade", LocalPlayer():EntIndex(), "addition", class, 1)
  172.                     end)
  173.                 end)
  174.                 self.inventory:AddItem(item)
  175.                 self.inventory.items[class] = table.count
  176.             end
  177.         end
  178.     end
  179. end
  180.  
  181. function PANEL:SetLeftName(name)
  182.     local panel = self.trading.left.name
  183.     panel:SetText(name)
  184.     panel:SizeToContents()
  185. end
  186.  
  187. function PANEL:SetRightName(name)
  188.     local panel = self.trading.right.name
  189.     panel:SetText(name)
  190.     panel:SizeToContents()
  191. end
  192.    
  193. function PANEL:AddLeftItem(item, class)
  194.     local left = self.trading.left
  195.     local oldpanel = IsValid(left.items[class]) and left.items[class]
  196.     local panel = oldpanel or vgui.Create("items.ItemPanel")
  197.     panel:SetCount(panel:GetCount()+1)
  198.     left.items[class] = panel
  199.    
  200.     local model = items.Get(class).WorldModel
  201.     local info = items.GetInventoryInfo(class)
  202.    
  203.     panel:SetItemInfo(model, info.name, info.info)
  204.    
  205.     self.inventory.items[class] = self.inventory.items[class] - 1
  206.     item:SetCount(self.inventory.items[class])
  207.     if self.inventory.items[class] < 1 then
  208.         self.inventory:RemoveItem(item)
  209.     end
  210.     panel:SetMenu(function()
  211.         local menu = DermaMenu()
  212.         menu:MakePopup()
  213.         menu:SetPos(gui.MousePos())
  214.         menu:AddOption("Remove", function()
  215.             RunConsoleCommand("items_trade", self:GetTrader():EntIndex(), "addition", class, -1)
  216.             left.items[class]:SetCount(left.items[class]:GetCount() - 1)
  217.             if left.items[class] and left.items[class]:GetCount() < 1 then
  218.                 panel:Remove()
  219.                 self:UpdateInventory()
  220.                 local width = left.list:GetWide()
  221.                 left.list:SetWide(width+1)
  222.                 left.list:SetWide(width) -- dammit
  223.             end
  224.         end)
  225.     end)
  226.     if not oldpanel then left.list:AddItem(panel) end
  227. end
  228.  
  229. function PANEL:SetRightItem(class, count)
  230.     local right = self.trading.right
  231.     local oldpanel = IsValid(right.items[class]) and right.items[class]
  232.     if oldpanel and count < 1 then oldpanel:Remove() return end
  233.     if count < 1 then return end
  234.     local panel = oldpanel or vgui.Create("items.ItemPanel")
  235.     panel:SetCount(count)
  236.     local item = items.Get(class)
  237.     panel:SetItemInfo(item.WorldModel or blank, item.Inventory.name, item.Inventory.info)
  238.     right.items[class] = panel
  239.     if not oldpanel then right.list:AddItem(panel) end
  240. end
  241.  
  242. function PANEL:Close()
  243.     gui.EnableScreenClicker(false)
  244.     self:Remove()
  245. end
  246.  
  247. function PANEL:PerformLayout()
  248.     derma.SkinHook( "Layout", "Frame", self )  
  249.    
  250.     local trading = self.trading
  251.    
  252.     self.sheet:StretchToParent(5,25,5,5)
  253.     trading:StretchToParent(5,5,5,5)
  254.    
  255.     trading.divider:StretchToParent(5,35,5,100)
  256.     local center = trading.divider:GetWide()/2-4
  257.     trading.divider:SetLeftWidth(center)
  258.    
  259.     trading.trade:AlignLeft(8)
  260.     trading.trade:AlignBottom(25)
  261.    
  262.     trading.decline:MoveRightOf(trading.trade, 5)
  263.     trading.decline:AlignBottom(25)
  264.  
  265.     local left = trading.left
  266.     left.coins:AlignLeft(8)
  267.     left.coins:AlignBottom(70)
  268.    
  269.     left.coinslabel:CopyPos(left.coins)
  270.     left.coinslabel:MoveRightOf(left.coins, 5)
  271.    
  272.     local right = trading.right
  273.     right.coins:AlignRight(center - trading.right.coins:GetWide() + 2)
  274.     right.coins:AlignBottom(70)
  275.    
  276.     right.coinslabel:CopyPos(right.coins)
  277.     right.coinslabel:MoveRightOf(right.coins, 5)
  278.    
  279.     for key, side in pairs({trading.left, trading.right}) do
  280.         side.name:AlignTop(-13)
  281.     end
  282. end
  283.    
  284. function items.ShowNotify(player)
  285.     local frame = vgui.Create( "DFrame" )
  286.     frame:Center()
  287.     frame:AlignTop()
  288.     frame:ShowCloseButton(true)
  289.     frame:SetTitle("Trading invitation")
  290.  
  291.     local starttime = RealTime()
  292.    
  293.     local text = vgui.Create("DLabel", frame)
  294.         local c = math.ceil(30-(RealTime()-starttime))
  295.     local t = player:Nick() .. " wants to trade with you!\nDo you want to accept?\nIgnoring in "..c.." second"..(c != 1 and "s" or "").."\n(hold c to get to this window)"
  296.     text:SetText(t)
  297.     function text:Think()
  298.         c = math.ceil(30-(RealTime()-starttime))
  299.         if c <= 0 then
  300.             frame:Remove()
  301.             return
  302.         end
  303.         local nt = player:Nick() .. " wants to trade with you!\nDo you want to accept?\nIgnoring in "..c.." second"..(c != 1 and "s" or "").."\n(hold c to get to this window)"
  304.         if nt ~= t then
  305.             text:SetText(nt)
  306.             text:SizeToContents()
  307.             t = nt
  308.         end
  309.     end
  310.     text:SizeToContents()
  311.     frame:SetSize(30 + text:GetWide(), 60 + text:GetTall())
  312.     text:Center()
  313.     text:AlignTop(25)
  314.    
  315.     local accept = vgui.Create("DButton", frame)
  316.     accept:SetText("Accept")
  317.     accept:AlignLeft(5)
  318.     accept:AlignBottom(5)
  319.     accept.DoClick = function()
  320.         RunConsoleCommand("items_trade", player:EntIndex(), "accepted")
  321.         frame:Remove()
  322.         g_ItemsTradingMenu = vgui.Create("items.Trading")
  323.         g_ItemsTradingMenu:SetRightName(player:Nick())
  324.     end
  325.    
  326.     local decline = vgui.Create("DButton", frame)
  327.     decline:SetText("Decline")
  328.     decline:CopyPos(accept)
  329.     decline:MoveRightOf(accept, 5)
  330.     decline.DoClick = function()
  331.         RunConsoleCommand("items_trade", LocalPlayer():EntIndex(), "decline")
  332.         frame:Remove()
  333.         timer.Destroy("RemoveTradeRequest")
  334.     end
  335. end
  336.    
  337. usermessage.Hook("items.Trading", function(umsg)
  338.     local type = umsg:ReadString()
  339.    
  340.     if type == "notify" then
  341.         items.ShowNotify(umsg:ReadEntity())
  342.     elseif type == "accepted" then
  343.         local trader = umsg:ReadEntity()
  344.         items.CurrentTrader = trader
  345.         g_ItemsTradingMenu = vgui.Create("items.Trading")
  346.         g_ItemsTradingMenu:SetRightName(trader:Nick())
  347.         g_ItemsTradingMenu:SetTrader(trader)
  348.     elseif type == "declined" then
  349.  
  350.     elseif type == "cancel" then
  351.         if ValidPanel(g_ItemsTradingMenu) then
  352.             g_ItemsTradingMenu:Close() -- disables screen clicker too, which reminds me: why does it not enable it in the first place?
  353.         end
  354.     elseif type == "addition" then
  355.         local menu = g_ItemsTradingMenu
  356.         if IsValid(menu) then
  357.             local class = umsg:ReadString()
  358.             local amount = umsg:ReadLong()
  359.             menu:SetRightItem(class, amount)
  360.         end
  361.     elseif type == "coins" then
  362.         g_ItemsTradingMenu.trading.right.coins:SetValue(tonumber(umsg:ReadString()) or 0)
  363.     elseif type == "finished" then
  364.         g_ItemsTradingMenu:Close()
  365.     elseif type == "message" then
  366.         chat.AddText(umsg:ReadBool() and Color(0,255,0) or Color(255,0,0), umsg:ReadString())
  367.     end
  368. end)
  369.  
  370.  
  371. local function CheckDistance(a, b)
  372.     return a and a:GetShootPos():Distance(b:GetShootPos()) < 80
  373. end
  374.  
  375. local function Notify(ply, positive, message)
  376.     umsg.Start("items.Trading", ply)
  377.         umsg.String("message")
  378.         umsg.Bool(positive)
  379.         umsg.String(message)
  380.     umsg.End()
  381. end
  382.  
  383. concommand.Add("items_trade", function(player, _, arguments)
  384.     local target = Entity(tonumber(arguments[1]))
  385.     target = IsValid(target) and target
  386.        
  387.     if not target then return end
  388.     local ttype = arguments[2]
  389.    
  390.     if ttype == "request" and CheckDistance(target, player) then
  391.         if player.Trading then
  392.             Notify(player, false, "You are already trading!")
  393.             return
  394.         end
  395.         player.TradeRequests = player.TradeRequests or {}
  396.         for k,v in pairs(player.TradeRequests) do
  397.             if IsValid(Entity(k)) then
  398.                 if CurTime()-v <= 0 then
  399.                     player.TradeRequests[k] = nil
  400.                     return
  401.                 elseif CurTime()-v <= 30 then
  402.                     Notify(player, false, "You already have an open trade request!")
  403.                     return
  404.                 else
  405.                     Notify(player, false, "Cancelled your trade request with " .. target:Nick() .."!")
  406.                 end
  407.             end
  408.             player.TradeRequests[k] = nil
  409.         end
  410.         target.TradeRequests = target.TradeRequests or {}
  411.         for k,v in pairs(target.TradeRequests) do
  412.             if CurTime()-v <= 30 and IsValid(Entity(k)) then
  413.                 Notify(player, false, target:Nick().." is busy!")
  414.                 return
  415.             else
  416.                 player.TradeRequests[k] = nil
  417.             end
  418.         end
  419.         umsg.Start("items.Trading", target)
  420.             umsg.String("notify")
  421.             umsg.Entity(player)
  422.         umsg.End()
  423.         player.TradeRequests[target:EntIndex()] = CurTime()
  424.         print(player:Nick() .. " requested a trade with " .. target:Nick())
  425.         Notify(player, true, "You have invitied " .. target:Nick() .. " to trade")
  426.     elseif ttype == "accepted" then
  427.         if type(target.TradeRequests) ~= "table" or
  428.             type(target.TradeRequests[player:EntIndex()]) ~= "number"
  429.         then
  430.             player:ChatPrint(target:Nick() .. " is busy!")
  431.             return
  432.         elseif CurTime()-target.TradeRequests[player:EntIndex()] > 30 then
  433.             Notify(player, false, "Your trade request with " .. target:Nick() .. " expired!")
  434.         return end
  435.         umsg.Start("items.Trading", target)
  436.             umsg.String("accepted")
  437.             umsg.Entity(player)
  438.         umsg.End()
  439.         player.TradeRequests = player.TradeRequests or {}
  440.         for k,v in pairs(player.TradeRequests) do
  441.             player.TradeRequests[k] = nil
  442.         end
  443.         target.TradeRequests = target.TradeRequests or {}
  444.         for k,v in pairs(target.TradeRequests) do
  445.             target.TradeRequests[k] = nil
  446.         end
  447.         target.Trading = true
  448.         player.Trading = true
  449.         player.TradeItems = nil
  450.         target.TradeItems = nil
  451.         target.TradingWith = player
  452.         player.TradingWith = target
  453.         print(player:Nick() .. " and " .. target:Nick() .. " are now trading")
  454.     elseif ttype == "declined" then
  455.         player:ChatPrint(target:Nick().." declined your request!")
  456.     elseif ttype == "cancel" then
  457.         if not player.Trading then
  458.             Notify(player, false, "You are not trading!")
  459.             return
  460.         end
  461.         local target = player.TradingWith
  462.         umsg.Start("items.Trading", target)
  463.             umsg.String("cancel")
  464.         umsg.End()
  465.         target.Trading = false
  466.         player.Trading = false
  467.         target.Finished = nil
  468.         player.Finished = nil
  469.         Notify(target, false, player:Nick().." cancelled the trade!")
  470.         Notify(player, false, "Trade cancelled!")
  471.         print(player:Nick() .. " cancelled trade with " .. target:Nick())
  472.     elseif ttype == "coins" then
  473.         if not player.Trading or not IsValid(player.TradingWith) then return end
  474.         local target = player.TradingWith
  475.         local amount = tonumber(arguments[3])
  476.         if not amount or amount < 0 then return end
  477.         player.TradeCoins = amount
  478.         umsg.Start("items.Trading", target)
  479.             umsg.String("coins")
  480.             umsg.String(amount)
  481.         umsg.End()
  482.     elseif ttype == "addition" then
  483.         if not player.Trading or not IsValid(player.TradingWith) then return end
  484.         player.TradeItems = player.TradeItems or {}
  485.         local target = player.TradingWith
  486.         local class = arguments[3]
  487.         if not class then return end
  488.         if not items.Classes[class] then
  489.             Notify(player, false, class .. " is not a valid item!")
  490.             return
  491.         end
  492.         local amount = tonumber(arguments[4])
  493.         if not amount or amount == 0 then return end
  494.         if amount < 0 then
  495.             player.TradeItems[class] = player.TradeItems[class] or 0
  496.             if player.TradeItems[class]-amount < 0 then
  497.                 Notify(player, false, "You do not have that many items to remove!")
  498.                 return
  499.             end
  500.         elseif amount > 0 then
  501.             player.TradeItems[class] = player.TradeItems[class] or 0
  502.             local pamount = player:GetInventory()[class] or 0
  503.             if pamount < player.TradeItems[class]+amount then
  504.                 Notify(player, false, "You do not have that many items to add!")
  505.                 return
  506.             end
  507.         end
  508.         player.TradeItems[class] = player.TradeItems[class]+amount
  509.         umsg.Start("items.Trading", player.TradingWith)
  510.             umsg.String("addition")
  511.             umsg.String(class)
  512.             umsg.Long(player.TradeItems[class] or 0)
  513.         umsg.End()
  514.         player.Finished = nil
  515.         target.Finished = nil
  516.     elseif ttype == "finished" then
  517.         if not player.Trading or not IsValid(player.TradingWith) then return end
  518.         local target = player.TradingWith
  519.         if player.Finished then
  520.             Notify(player, false, "You are already finished. Please wait on the other player.")
  521.             return
  522.         end
  523.         if not target.Finished then
  524.             Notify(player, true, "Waiting on other player...")
  525.             Notify(target, true, "Other player is done.")
  526.             player.Finished = true
  527.             return
  528.         end
  529.         print("Finishing trade:")
  530.         for k,v in pairs(player.TradeItems or {}) do
  531.             target:AddToInventory(k, v)
  532.             print("\tAdded "..tostring(v).." "..tostring(k).." to "..target:Nick().."'s inventory")
  533.             player:RemoveFromInventory(k, v)
  534.             print("\tRemoved "..tostring(v).." "..tostring(k).." from "..target:Nick().."'s inventory")
  535.         end
  536.         for k,v in pairs(target.TradeItems or {}) do
  537.             player:AddToInventory(k, v)
  538.             print("\tAdded "..tostring(v).." "..tostring(k).." to "..player:Nick().."'s inventory")
  539.             target:RemoveFromInventory(k, v)
  540.             print("\tRemoved "..tostring(v).." "..tostring(k).." from "..target:Nick().."'s inventory")
  541.         end
  542.         local c, c2 = player.TradeCoins or 0, target.TradeCoins or 0
  543.         target:SetCoins(target:GetCoins()+(c-c2))
  544.         print("\tGave "..target:Nick().." "..(c-c2).." coins")
  545.         player:SetCoins(player:GetCoins()+(c2-c))
  546.         print("\tGave "..player:Nick().." "..(c2-c).." coins")
  547.         local RF = RecipientFilter()
  548.         RF:AddPlayer(target)
  549.         RF:AddPlayer(player)
  550.         umsg.Start("items.Trading", RF)
  551.             umsg.String("finished")
  552.         umsg.End()
  553.         target.Finished = nil
  554.         player.Finished = nil
  555.         target.TradeItems = nil
  556.         player.TradeItems = nil
  557.         target.Trading = nil
  558.         player.Trading = nil
  559.         target.TradingWith = nil
  560.         player.TradingWith = nil
  561.         target.TradeCoins = nil
  562.         player.TradeCoins = nil
  563.         print(player:Nick() .. " and " .. target:Nick() .. " finished trading")
  564.     elseif not CheckDistance(target, player) then
  565.         player:ChatPrint("You are too far away to start trading")
  566.     end
  567. end)
Advertisement
Add Comment
Please, Sign In to add comment