TTT - Making the Equipment menu 3 icons wide

Zombie Master is pretty dead most of the time so I figured I would get a better answer here. Is it possible to make the Detective and Traitor equipment menus, 3 icons wide instead of 2?

Yes it is possible. I don’t feel like pawing through the code right now to find it but if you’re not comfortable editing it yourself you could check into these:

Oh I am totally comfortable editing it myself and would rather not resort to coderhire. I just need to know what modifications to make and where because I’ve seen it before in screenshots

I’d start poking around in the cl_equip.lua

Replace cl_equip.lua with this
[lua]---- Traitor equipment menu

local GetTranslation = LANG.GetTranslation
local GetPTranslation = LANG.GetParamTranslation

– Buyable weapons are loaded automatically. Buyable items are defined in
– equip_items_shd.lua

local Equipment = nil
function GetEquipmentForRole(role)
– need to build equipment cache?
if not Equipment then
– start with all the non-weapon goodies
local tbl = table.Copy(EquipmentItems)

  -- find buyable weapons to load info from
  for k, v in pairs(weapons.GetList()) do
     if v and v.CanBuy then
        local data = v.EquipMenuData or {}
        local base = {
           id       = WEPS.GetClass(v),
           name     = v.PrintName or "Unnamed",
           limited  = v.LimitedStock,
           kind     = v.Kind or WEAPON_NONE,
           slot     = (v.Slot or 0) + 1,
           material = v.Icon or "vgui/ttt/icon_id",
           -- the below should be specified in EquipMenuData, in which case
           -- these values are overwritten
           type     = "Type not specified",
           model    = "models/weapons/w_bugbait.mdl",
           desc     = "No description specified."
        };

        -- Force material to nil so that model key is used when we are
        -- explicitly told to do so (ie. material is false rather than nil).
        if data.modelicon then
           base.material = nil
        end

        table.Merge(base, data)

        -- add this buyable weapon to all relevant equipment tables
        for _, r in pairs(v.CanBuy) do
           table.insert(tbl[r], base)
        end
     end
  end

  -- mark custom items
  for r, is in pairs(tbl) do
     for _, i in pairs(is) do
        if i and i.id then
           i.custom = not table.HasValue(DefaultEquipment[r], i.id)
        end
     end
  end

  Equipment = tbl

end

return Equipment and Equipment[role] or {}
end

local function ItemIsWeapon(item) return not tonumber(item.id) end
local function CanCarryWeapon(item) return LocalPlayer():CanCarryType(item.kind) end

local color_bad = Color(220, 60, 60, 255)
local color_good = Color(0, 200, 0, 255)

– Creates tabel of labels showing the status of ordering prerequisites
local function PreqLabels(parent, x, y)
local tbl = {}

tbl.credits = vgui.Create(“DLabel”, parent)
tbl.credits:SetToolTip(GetTranslation(“equip_help_cost”))
tbl.credits:SetPos(x, y)
tbl.credits.Check = function(s, sel)
local credits = LocalPlayer():GetCredits()
return credits > 0, GetPTranslation(“equip_cost”, {num = credits})
end

tbl.owned = vgui.Create(“DLabel”, parent)
tbl.owned:SetToolTip(GetTranslation(“equip_help_carry”))
tbl.owned:CopyPos(tbl.credits)
tbl.owned:MoveBelow(tbl.credits, y)
tbl.owned.Check = function(s, sel)
if ItemIsWeapon(sel) and (not CanCarryWeapon(sel)) then
return false, GetPTranslation(“equip_carry_slot”, {slot = sel.slot})
elseif (not ItemIsWeapon(sel)) and LocalPlayer():HasEquipmentItem(sel.id) then
return false, GetTranslation(“equip_carry_own”)
else
return true, GetTranslation(“equip_carry”)
end
end

tbl.bought = vgui.Create(“DLabel”, parent)
tbl.bought:SetToolTip(GetTranslation(“equip_help_stock”))
tbl.bought:CopyPos(tbl.owned)
tbl.bought:MoveBelow(tbl.owned, y)
tbl.bought.Check = function(s, sel)
if sel.limited and LocalPlayer():HasBought(tostring(sel.id)) then
return false, GetTranslation(“equip_stock_deny”)
else
return true, GetTranslation(“equip_stock_ok”)
end
end

for k, pnl in pairs(tbl) do
pnl:SetFont(“TabLarge”)
end

return function(selected)
local allow = true
for k, pnl in pairs(tbl) do
local result, text = pnl:Check(selected)
pnl:SetTextColor(result and color_good or color_bad)
pnl:SetText(text)
pnl:SizeToContents()

            allow = allow and result
         end
         return allow
      end

end

– quick, very basic override of DPanelSelect
local PANEL = {}
local function DrawSelectedEquipment(pnl)
surface.SetDrawColor(255, 200, 0, 255)
surface.DrawOutlinedRect(0, 0, pnl:GetWide(), pnl:GetTall())
end

function PANEL:SelectPanel(pnl)
self.BaseClass.SelectPanel(self, pnl)
if pnl then
pnl.PaintOver = DrawSelectedEquipment
end
end
vgui.Register(“EquipSelect”, PANEL, “DPanelSelect”)

local SafeTranslate = LANG.TryTranslation

local color_darkened = Color(255,255,255, 80)
– TODO: make set of global role colour defs, these are same as wepswitch
local color_slot = {
[ROLE_TRAITOR] = Color(180, 50, 40, 255),
[ROLE_DETECTIVE] = Color(50, 60, 180, 255)
};

local eqframe = nil
local function TraitorMenuPopup()
local ply = LocalPlayer()
if not IsValid(ply) or not ply:IsActiveSpecial() then
return
end

– Close any existing traitor menu
if eqframe and ValidPanel(eqframe) then eqframe:Close() end

local credits = ply:GetCredits()
local can_order = credits > 0

local dframe = vgui.Create(“DFrame”)
local w, h = 600, 350 --Default 500, 350. Changed to make 3 columns
dframe:SetSize(w, h)
dframe:Center()
dframe:SetTitle(GetTranslation(“equip_title”))
dframe:SetVisible(true)
dframe:ShowCloseButton(true)
dframe:SetMouseInputEnabled(true)
dframe:SetDeleteOnClose(true)

local m = 5

local dsheet = vgui.Create(“DPropertySheet”, dframe)

– Add a callback when switching tabs
local oldfunc = dsheet.SetActiveTab
dsheet.SetActiveTab = function(self, new)
if self.m_pActiveTab != new and self.OnTabChanged then
self:OnTabChanged(self.m_pActiveTab, new)
end
oldfunc(self, new)
end

dsheet:SetPos(0,0)
dsheet:StretchToParent(m,m + 25,m,m)
local padding = dsheet:GetPadding()

local dequip = vgui.Create(“DPanel”, dsheet)
dequip:SetPaintBackground(false)
dequip:StretchToParent(padding,padding,padding,padding)

– Determine if we already have equipment
local owned_ids = {}
for _, wep in pairs(ply:GetWeapons()) do
if IsValid(wep) and wep:IsEquipment() then
table.insert(owned_ids, wep:GetClass())
end
end

– Stick to one value for no equipment
if #owned_ids == 0 then
owned_ids = nil
end

— Construct icon listing
local dlist = vgui.Create(“EquipSelect”, dequip)
dlist:SetPos(0,0)
dlist:SetSize(220, h - 75)
dlist:EnableVerticalScrollbar(true)
dlist:EnableHorizontal(true)
dlist:SetPadding(4)

local items = GetEquipmentForRole(ply:GetRole())

local to_select = nil
for k, item in pairs(items) do
local ic = nil

  -- Create icon panel
  if item.material then
     if item.custom then
        -- Custom marker icon
        ic = vgui.Create("LayeredIcon", dlist)

        local marker = vgui.Create("DImage")
        marker:SetImage("vgui/ttt/custom_marker")
        marker.PerformLayout = function(s)
                                  s:AlignBottom(2)
                                  s:AlignRight(2)
                                  s:SetSize(16, 16)
                               end
        marker:SetTooltip(GetTranslation("equip_custom"))

        ic:AddLayer(marker)

        ic:EnableMousePassthrough(marker)
     elseif not ItemIsWeapon(item) then
        ic = vgui.Create("SimpleIcon", dlist)
     else
        ic = vgui.Create("LayeredIcon", dlist)
     end

     -- Slot marker icon
     if ItemIsWeapon(item) then
        local slot = vgui.Create("SimpleIconLabelled")
        slot:SetIcon("vgui/ttt/slotcap")
        slot:SetIconColor(color_slot[ply:GetRole()] or COLOR_GREY)
        slot:SetIconSize(16)

        slot:SetIconText(item.slot)

        slot:SetIconProperties(COLOR_WHITE,
                               "DefaultBold",
                               {opacity=220, offset=1},
                               {10, 8})

        ic:AddLayer(slot)
        ic:EnableMousePassthrough(slot)
     end

     ic:SetIconSize(64)
     ic:SetIcon(item.material)
  elseif item.model then
     ic = vgui.Create("SpawnIcon", dlist)
     ic:SetModel(item.model)
  else
     ErrorNoHalt("Equipment item does not have model or material specified: " .. tostring(item) .. "

")
end

  ic.item = item

  local tip = SafeTranslate(item.name) .. " (" .. SafeTranslate(item.type) .. ")"
  ic:SetTooltip(tip)

  -- If we cannot order this item, darken it
  if ((not can_order) or
      -- already owned
      table.HasValue(owned_ids, item.id) or
      (tonumber(item.id) and ply:HasEquipmentItem(tonumber(item.id))) or
      -- already carrying a weapon for this slot
      (ItemIsWeapon(item) and (not CanCarryWeapon(item))) or
      -- already bought the item before
      (item.limited and ply:HasBought(tostring(item.id)))) then

     ic:SetIconColor(color_darkened)
  end

  dlist:AddPanel(ic)

end

local dlistw = 230

local bw, bh = 90, 25

local dih = h - bh - m5
local diw = w - dlistw - m
6 - 2
local dinfobg = vgui.Create(“DPanel”, dequip)
dinfobg:SetPaintBackground(false)
dinfobg:SetSize(diw, dih)
dinfobg:SetPos(dlistw + m, 0)

local dinfo = vgui.Create(“ColoredBox”, dinfobg)
dinfo:SetColor(Color(90, 90, 95))
dinfo:SetPos(0,0)
dinfo:StretchToParent(0, 0, 0, dih - 135)

local dfields = {}
for , k in pairs({“name”, “type”, “desc”}) do
dfields[k] = vgui.Create(“DLabel”, dinfo)
dfields[k]:SetTooltip(GetTranslation("equip_spec
" … k))
dfields[k]:SetPos(m3, m2)
end

dfields.name:SetFont(“TabLarge”)

dfields.type:SetFont(“DermaDefault”)
dfields.type:MoveBelow(dfields.name)

dfields.desc:SetFont(“DermaDefaultBold”)
dfields.desc:SetContentAlignment(7)
dfields.desc:MoveBelow(dfields.type, 1)

local iw, ih = dinfo:GetSize()

local dhelp = vgui.Create(“ColoredBox”, dinfobg)
dhelp:SetColor(Color(90, 90, 95))
dhelp:SetSize(diw, dih - 205)
dhelp:MoveBelow(dinfo, m)

local update_preqs = PreqLabels(dhelp, m3, m2)

dhelp:SizeToContents()

local dconfirm = vgui.Create(“DButton”, dinfobg)
dconfirm:SetPos(0, dih - bh*2)
dconfirm:SetSize(bw, bh)
dconfirm:SetDisabled(true)
dconfirm:SetText(GetTranslation(“equip_confirm”))

dsheet:AddSheet(GetTranslation(“equip_tabtitle”), dequip, “icon16/bomb.png”, false, false, “Traitor equipment menu”)

– Item control
if ply:HasEquipmentItem(EQUIP_RADAR) then
local dradar = RADAR.CreateMenu(dsheet, dframe)
dsheet:AddSheet(GetTranslation(“radar_name”), dradar, “icon16/magnifier.png”, false,false, “Radar control”)
end

if ply:HasEquipmentItem(EQUIP_DISGUISE) then
local ddisguise = DISGUISE.CreateMenu(dsheet)
dsheet:AddSheet(GetTranslation(“disg_name”), ddisguise, “icon16/user.png”, false,false, “Disguise control”)
end

– Weapon/item control
if IsValid(ply.radio) or ply:HasWeapon(“weapon_ttt_radio”) then
local dradio = TRADIO.CreateMenu(dsheet)
dsheet:AddSheet(GetTranslation(“radio_name”), dradio, “icon16/transmit.png”, false,false, “Radio control”)
end

– Credit transferring
if credits > 0 then
local dtransfer = CreateTransferMenu(dsheet)
dsheet:AddSheet(GetTranslation(“xfer_name”), dtransfer, “icon16/group_gear.png”, false,false, “Transfer credits”)
end

– couple panelselect with info
dlist.OnActivePanelChanged = function(self, _, new)
for k,v in pairs(new.item) do
if dfields[k] then
dfields[k]:SetText(SafeTranslate(v))
dfields[k]:SizeToContents()
end
end

                               -- Trying to force everything to update to
                               -- the right size is a giant pain, so just
                               -- force a good size.
                               dfields.desc:SetTall(70)

                               can_order = update_preqs(new.item)

                               dconfirm:SetDisabled(not can_order)
                            end

– select first
dlist:SelectPanel(to_select or dlist:GetItems()[1])

– prep confirm action
dconfirm.DoClick = function()
local pnl = dlist.SelectedPanel
if not pnl or not pnl.item then return end
local choice = pnl.item
RunConsoleCommand(“ttt_order_equipment”, choice.id)
dframe:Close()
end

– update some basic info, may have changed in another tab
– specifically the number of credits in the preq list
dsheet.OnTabChanged = function(s, old, new)
if not IsValid(new) then return end

                        if new:GetPanel() == dequip then
                           can_order = update_preqs(dlist.SelectedPanel.item)
                           dconfirm:SetDisabled(not can_order)
                        end
                     end

local dcancel = vgui.Create(“DButton”, dframe)
dcancel:SetPos(w - 13 - bw, h - bh - 16)
dcancel:SetSize(bw, bh)
dcancel:SetDisabled(false)
dcancel:SetText(GetTranslation(“close”))
dcancel.DoClick = function() dframe:Close() end

dframe:MakePopup()
dframe:SetKeyboardInputEnabled(false)

eqframe = dframe
end
concommand.Add(“ttt_cl_traitorpopup”, TraitorMenuPopup)

local function ForceCloseTraitorMenu(ply, cmd, args)
if ValidPanel(eqframe) then
eqframe:Close()
end
end
concommand.Add(“ttt_cl_traitorpopup_close”, ForceCloseTraitorMenu)

function GM:OnContextMenuOpen()
local r = GetRoundState()
if r == ROUND_ACTIVE and not (LocalPlayer():GetTraitor() or LocalPlayer():GetDetective()) then
return
elseif r == ROUND_POST or r == ROUND_PREP then
CLSCORE:Reopen()
return
end

RunConsoleCommand(“ttt_cl_traitorpopup”)
end

local function ReceiveEquipment()
local ply = LocalPlayer()
if not IsValid(ply) then return end

ply.equipment_items = net.ReadUInt(16)
end
net.Receive(“TTT_Equipment”, ReceiveEquipment)

local function ReceiveCredits()
local ply = LocalPlayer()
if not IsValid(ply) then return end

ply.equipment_credits = net.ReadUInt(8)
end
net.Receive(“TTT_Credits”, ReceiveCredits)

local r = 0
local function ReceiveBought()
local ply = LocalPlayer()
if not IsValid(ply) then return end

ply.bought = {}
local num = net.ReadUInt(8)
for i=1,num do
local s = net.ReadString()
if s != “” then
table.insert(ply.bought, s)
end
end

– This usermessage sometimes fails to contain the last weapon that was
– bought, even though resending then works perfectly. Possibly a bug in
– bf_read. Anyway, this hack is a workaround: we just request a new umsg.
if num != #ply.bought and r < 10 then – r is an infinite loop guard
RunConsoleCommand(“ttt_resend_bought”)
r = r + 1
else
r = 0
end
end
net.Receive(“TTT_Bought”, ReceiveBought)

– Player received the item he has just bought, so run clientside init
local function ReceiveBoughtItem()
local is_item = net.ReadBit() == 1
local id = is_item and net.ReadUInt(16) or net.ReadString()

– I can imagine custom equipment wanting this, so making a hook
hook.Run(“TTTBoughtItem”, is_item, id)
end
net.Receive(“TTT_BoughtItem”, ReceiveBoughtItem)

[/lua]

This worked in single player just fine but in Multiplayer even after a server restart, it doesnt work

If you aren’t even going try to understand the code, giving something not just a “Doesn’t work”, code it by yourself or buy a built menu, i don’t think that you would get something…

Impossible, the exact same code works on my server. All I changed was the width of the buying columns to for three. Only three or so numbers were changed. Use a website like http://diffnow.com to compare stock cl_equip.lua and the one I put.

You dont have to be a condescending ass about it. I was in a hurry and it did not work. The code changes one line with width and for whatever reason it was not working in multiplayer. I had restarted the server and changed maps plenty of times and that was hours ago. I am going to try this again but you seriously need to lighten up.

I’m trying to help you, all I said was it not working is impossible as long as you have a stock TTT and put that code in cl_equip.lua. It’s really not nice to call someone an ass who is giving you their code and support free.

I was referring to the other guy, I meant no disrespect to you. Thank you very much for the code. My issue was FTP denying me access to edit cl_equip and the file would reset every time I edited it, its fixed now.