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.