VGUI Screen Creation
Getting it to load
First Step
Create a .res file in your mod's scripts\screens
folder. This example is called vgui_test_screen.res
:
"screen_basic.res" { "Background" { "ControlName" "MaterialImage" "fieldName" "Background" "xpos" "0" "ypos" "0" "zpos" "-2" "wide" "480" "tall" "240" "material" "vgui/screens/vgui_overlay" } "OwnerReadout" { "ControlName" "Label" "fieldName" "OwnerReadout" "xpos" "10" "ypos" "20" "wide" "240" "tall" "34" "autoResize" "0" "pinCorner" "0" "visible" "1" "enabled" "1" "tabPosition" "0" "labelText" "No Owner" "textAlignment" "center" "dulltext" "0" "paintBackground" "0" } "HealthReadout" { "ControlName" "Label" "fieldName" "HealthReadout" "xpos" "240" "ypos" "20" "wide" "240" "tall" "34" "autoResize" "0" "pinCorner" "0" "visible" "1" "enabled" "1" "tabPosition" "0" "labelText" "Health: 100%" "textAlignment" "center" "dulltext" "0" "paintBackground" "0" } "DismantleButton" { "ControlName" "MaterialButton" "fieldName" "Dismantle" "xpos" "78" "ypos" "160" "wide" "324" "tall" "48" "autoResize" "0" "pinCorner" "0" "visible" "1" "enabled" "1" "tabPosition" "2" "labelText" "Dismantle" "textAlignment" "center" "dulltext" "0" "brighttext" "0" "Default" "0" "command" "quit" "paintborder" "0" "enabledImage" { "material" "vgui/screens/vgui_button_enabled" "color" "255 255 255 255" } "mouseOverImage" { "material" "vgui/screens/vgui_button_hover" "color" "255 255 255 255" } "pressedImage" { "material" "vgui/screens/vgui_button_pushed" "color" "255 255 255 255" } "disabledImage" { "material" "vgui/screens/vgui_button_disabled" "color" "255 255 255 255" } } }
Second Step
The materials used in the .res file can be found in source material.gcf
using Nem's GCFScape. Extract the files in hl2\materials\vgui\screens
to your mod's materials\vgui\screens
folder.
Third Step
In your mod's scripts
folder create or open the text file vgui_screens.txt
and add a new entry for the screen.
ex.
"VGUI_Screens" { "vgui_test_screen" { // This is our example screen "type" "vgui_screen_panel" "pixelswide" "480" "pixelshigh" "240" // This must be the file you created in step 1 "resfile" "scripts/screens/vgui_test_screen.res" } "teleport_countdown_screen" { "type" "teleport_countdown_screen" "pixelswide" "480" "pixelshigh" "240" "resfile" "scripts/screens/teleport_countdown_screen.res" } }
Fourth Step
Open Hammer create a small square map with a spawn, a light, and a vgui_screen.
Change the vgui_screen's properties like so:
- Panel Name = vgui_test_screen
- Panel Width in World = 64
- Panel Height in World = 32
Height and Width can be changed to whatever you need. Those values define the actual size of the screen in the world.
Fifth Step
Save your files, build your map, launch your mod, and whala! you have a vgui_screen in game.
Getting Input to work
Here is the proper way of fixing vgui input:
Modifications to in_buttons.h
Where the other flags are defined add:
#define IN_VALIDVGUIINPUT (1 << 23) //bitflag for vgui fix
Modifications to in_main.cpp
Inside the function CInput::CreateMove(...)
add:
cmd->buttons |= IN_VALIDVGUIINPUT;
right above:
g_pClientMode->CreateMove( input_sample_frametime, cmd );
Modifications to c_baseplayer.cpp
CreateMove
Inside the function C_BasePlayer::CreateMove( ... )
add:
if(pCmd->buttons & IN_VALIDVGUIINPUT)
right above:
DetermineVguiInputMode( pCmd );
So it only calls DetermineVguiInputMode
if the buttons include our flag
DetermineVguiInputMode
Inside the function C_BasePlayer::DetermineVguiInputMode(...)
change both instances of:
pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2);
to read:
pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2 | IN_VALIDVGUIINPUT);
The reason we do this is because CInput::ExtraMouseSample
calls g_pClientMode->CreateMove()
without initializing the button flags, thus the VGui screen is updated with bad button input. Since IN_VALIDVGUIINPUTM
is only set from within CInput::CreateMove
, the VGui screens only update when the button flags are valid.
Alternative Fix
An alternative fix would be to add a new variable to CUserCmd such as bButtonFlagsValid that can be set to either true or false depending on the validity of the button flags. This would allow the structure to internally store this information for its whole lifetime while freeing up that extra button bit.
Further Possibilities
- Make it so that when a player is viewing the screen, all input is sent to the screen, including movement keys. The player will not be able to move again, until they look outside the bounds of the screen.