• How do you override the default weapon selection menu?
    5 replies, posted
I know that you can use GM:HUDShouldDraw() to get rid of it, but what do I need to do if I want to override it? Is there a nice little hook I can use, or do I have to basically make my own from scratch?
Here's how it's done in TTT: [lua] -- we need our own weapon switcher because the hl2 one skips empty weapons local math = math local draw = draw local surface = surface local table = table WSWITCH = {} WSWITCH.Show = false WSWITCH.Selected = -1 WSWITCH.NextSwitch = -1 WSWITCH.WeaponCache = {} local delay = 0.075 local showtime = 2 local margin = 10 local width = 300 local height = 20 local barcorner = surface.GetTextureID( "gui/corner8" ) local col_active = { tip = Color(55, 170, 50, 255), bg = Color(20, 20, 20, 240), text_empty = Color(200, 20, 20, 255), text = Color(255, 255, 255, 255) }; local col_dark = { tip = Color(60, 160, 50, 155), bg = Color(20, 20, 20, 200), text_empty = Color(200, 20, 20, 100), text = Color(255, 255, 255, 100) }; -- Draw a bar in the style of the the weapon pickup ones function WSWITCH:DrawBarBg(x, y, w, h, c) local rx = math.Round(x - 4) local ry = math.Round(y - (h / 2)-4) local rw = math.Round(w + 9) local rh = math.Round(h + 8) local b = 8 --bordersize -- Draw the colour tip surface.SetTexture(barcorner) surface.SetDrawColor(clr(c.tip)) surface.DrawTexturedRectRotated( rx + b/2 , ry + b/2, b, b, 0 ) surface.DrawTexturedRectRotated( rx + b/2 , ry + rh -b/2, b, b, 90 ) surface.DrawRect( rx, ry+b, b, rh-b*2 ) surface.DrawRect( rx+b, ry, h - 4, rh ) -- Draw the remainder -- Could just draw a full roundedrect bg and overdraw it with the tip, but -- I don't have to do the hard work here anymore anyway surface.SetDrawColor(clr(c.bg)) surface.DrawRect( rx+b+h-4, ry, rw - (h - 4) - b*2, rh ) surface.DrawTexturedRectRotated( rx + rw - b/2 , ry + rh - b/2, b, b, 180 ) surface.DrawTexturedRectRotated( rx + rw - b/2 , ry + b/2, b, b, 270 ) surface.DrawRect( rx+rw-b, ry+b, b, rh-b*2 ) end function WSWITCH:DrawWeapon(x, y, c, wep) local tm = 2 if not ValidEntity(wep) then return end local name = wep:GetPrintName() local cl1, am1 = wep:Clip1(), wep:Ammo1() local ammo = false -- Clip1 will be -1 if a melee weapon -- Ammo1 will be false if weapon has no owner (was just dropped) if cl1 != -1 and am1 != false then ammo = string.format("%i + %02i", cl1, am1) end -- Slot local spec = {text=wep.Slot+1, font="Trebuchet22", pos={x+4, y}, xalign=0, yalign=TEXT_ALIGN_CENTER, color=c.text} draw.Text(spec) -- Name local spec = {text=name, font="TimeLeft", pos={x+8+tm+height, y}, xalign=0, yalign=TEXT_ALIGN_CENTER, color=c.text} draw.Text(spec) if ammo != false then local col = c.text if wep:Clip1() == 0 and wep:Ammo1() == 0 then col = c.text_empty end -- Ammo spec = {text=ammo, font="TimeLeft", pos={ScrW() - margin*3, y}, xalign=TEXT_ALIGN_RIGHT, yalign=TEXT_ALIGN_CENTER, color=col} draw.Text(spec) end end function WSWITCH:Draw(client) if not self.Show then return end local weps = self.WeaponCache local x = ScrW() - width - margin*2 local y = ScrH() - (#weps * (height + margin)) local col = col_dark for k, wep in pairs(weps) do if self.Selected == k then col = col_active else col = col_dark end self:DrawBarBg(x, y, width, height, col) self:DrawWeapon(x, y, col, wep) y = y + height + margin end end local function SlotSort(a, b) return a and b and a.Slot and b.Slot and a.Slot < b.Slot end local function CopyVals(src, dest) table.Empty(dest) for k, v in pairs(src) do if ValidEntity(v) then table.insert(dest, v) end end end function WSWITCH:SetSelected(idx) self.Selected = idx -- GetWeapons does not always return a proper numeric table it seems -- self.WeaponCache = LocalPlayer():GetWeapons() -- So copy over the weapon refs self.WeaponCache = {} CopyVals(LocalPlayer():GetWeapons(), self.WeaponCache) table.sort(self.WeaponCache, SlotSort) end function WSWITCH:SelectNext() if self.NextSwitch > CurTime() then return end self:Enable() local s = self.Selected + 1 if s > table.Count(LocalPlayer():GetWeapons()) then s = 1 end self:SetSelected(s) self.NextSwitch = CurTime() + delay end function WSWITCH:SelectPrev() if self.NextSwitch > CurTime() then return end self:Enable() local s = self.Selected - 1 if s < 1 then s = table.Count(LocalPlayer():GetWeapons()) end self:SetSelected(s) self.NextSwitch = CurTime() + delay end -- Numeric key access to direct slots function WSWITCH:SelectSlot(slot) self:Enable() local ply = LocalPlayer() local weps = {} CopyVals(ply:GetWeapons(), weps) table.sort(weps, SlotSort) slot = slot - 1 local toselect = 1 for k, w in pairs(weps) do if w.Slot == slot then toselect = k break end end self:SetSelected(toselect) self.NextSwitch = CurTime() + delay end function WSWITCH:Enable() if self.Show == false then self.Show = true local ply = LocalPlayer() local wep_active = ply:GetActiveWeapon() local weps = {} CopyVals(ply:GetWeapons(), weps) table.sort(weps, SlotSort) local toselect = 1 for k, w in pairs(weps) do if w == wep_active then toselect = k break end end self:SetSelected(toselect) end end function WSWITCH:Disable() WSWITCH.Show = false end function WSWITCH:ConfirmSelection() WSWITCH.Show = false local ply = LocalPlayer() for k, w in pairs(self.WeaponCache) do if k == self.Selected and ValidEntity(w) then RunConsoleCommand("wepswitch", w:GetClass()) return end end end function WSWITCH:Think() if WSWITCH.Show == false then return end if WSWITCH.NextSwitch < CurTime() - showtime then WSWITCH.Show = false end end [/lua]
That doesn't really show me much. It doesn't even show me how he cycled through weapons with the mouse scroll wheel because I tried input.IsMouseDown() or MOUSE_WHEEL_UP and MOUSE_WHEEL_DOWN and apparently they're broken.
[QUOTE=Chief Tiger;22740572]That doesn't really show me much. It doesn't even show me how he cycled through weapons with the mouse scroll wheel because I tried input.IsMouseDown() or MOUSE_WHEEL_UP and MOUSE_WHEEL_DOWN and apparently they're broken.[/QUOTE] Here's the chunk of code you need from TTT. [code] local function TTTWeaponSwitchCmds(ply, bind, pressed) if not ValidEntity(ply) then return end if bind == "invnext" and pressed then WSWITCH:SelectNext() return true elseif bind == "invprev" and pressed then WSWITCH:SelectPrev() return true elseif bind == "+attack" then if WSWITCH.Show then WSWITCH:ConfirmSelection() return true end elseif string.find(bind, "slot") and pressed then local idx = tonumber(string.sub(bind, 5, -1)) WSWITCH:SelectSlot(idx) end end hook.Add("PlayerBindPress", "TTTWeaponSwitchCmds", TTTWeaponSwitchCmds) [/code] Yeah, I haven't found a way to use anything from the mousewheel without having to bind the mousewheel to a custom command.
Thanks TB, that's what I needed. :D
Sorry, you need to Log In to post a reply to this thread.