Hiding default voice panels under certain conditions

I’m making a radio addon which under certain conditions should remove a certain player’s VC panel (or prevents it from being rendered/added). Now there’s a problem, when I simply “remove the panel” it still appears for a split second before being hidden. In other words, the root of the problem is that the player has to be in g_VoicePanelList in order to be removed, and there’s absolutely no way to prevent them being added

unless

I simply copied cl_voice.lua and overrode it. I would just run a hook right before a player’s panel is displayed, call it “ShouldDrawPlayerVoicePanel” with the player as the argument. if the hook returns false, it’s not rendered. Easy.

But is this really the only way? Overriding a file which the base game uses? Will this work with custom huds?

What gamemode are you doing this for? Can you link the exact cl_voice.lua you’re deriving?

There are definitely solutions that don’t involve overwriting the FILE

1 Like

I’ll respond assuming you’re using the base gamemode:

Since the g_VoicePanelList is a DPanel, you can just use https://wiki.facepunch.com/gmod/PANEL:OnChildAdded

From there you can get access to all the data of the voice and also promptly REMOVE IT ( or just hide the paint under conditions with a simple detour )

1 Like

It’s the worst case cause if I’m going with this solution I’d need to overwrite the base gzmdmode’s cl_voice. Or I guess I could also overwrite the panel definition

You don’t need to overwrite anything in any gamemode, so long as the voice is still a DPanel or at least derives from it. Which it should be.

Just run some hook after InitPostEntity on the client since that’s when it’s being made ( or just run it in a think and wait for the panel to be made ) and then define the OnChildAdded parameter.

function g_VoicePanelList:OnChildAdded( chld )
  DO ME AND REMOVE HERE
end

Since it’s a GLOBAL panel you can add whatever you need onto it in any hook

1 Like

Since we’re not preventing addition but rather instantly removing, isn’t there a risk that it will still appear for a split second

The hook looks to be called the same frame as the child being added, it shouldn’t draw based on the render order, hopefully.

The wiki bug report says it’s called BEFORE meta table is set on the child meaning you will probably be able to have that removed before anything actually gets to draw. That’s just a bug though so I don’t know the longetivity.

If anything, you can redefine the paint hook here to be:

child.Paint = function() end

which will prevent it from drawing entirely, even if it’s on the next frame. I’ve used this method numerous times on panels and they will NEVER draw because even if it forces it up the stack it will be sending a blank function

1 Like

Won’t adding another paint function prevent it from ever being drawn again? Should I store the old function somewhere to be able to restore it later? Also what about custom huds? Will this be reliable for them?

The paint function is attached to the panel. I was under the impression you wanted to just remove, but if you want conditional it’s just as easy and exactly as you suggested: Store as a member of the panel.

child.OrigPaint = child.Paint
child.Paint = function( pan, ww, hh )
      if STOPME then return end
      pan.OrigPaint( pan, ww, hh )
end

Plenty of different syntax so have fun with it.

As for custom HUDs, it should THEORETICALLY work. You see the problem comes down to whether they are creating their own functions or changing the panels being constructed by the global voice panel. If there are fully custom ones you’d need to have a handler for whatever THEIR voice panel is, but the method in this thread is pretty much the same

1 Like

Another problem I’m having is when my function runs before the panel is created. So it doesn’t exist at the time when i want to modify it. Should I run the function in a ‘while’ loop until the panel is created and successfully deleted?

Edit: made a pull request to get a Should hook in there. We really are making advanced workarounds for something that has a simple solution. https://github.com/Facepunch/garrysmod/pull/1752.
But I’m still going to need this workaround until it gets merged.