User:Maven/sandbox: Difference between revisions
No edit summary |
(attempting rewrite of vgui_screen article) |
||
Line 1: | Line 1: | ||
This is my personal sandbox area. | This is my personal sandbox area. | ||
---- | |||
{{ | [[Category:Programming]][[Category:Tutorials]][[Category:VGUI]] | ||
< | |||
==Adding a VGUI screen to a map== | |||
Create a [[vgui_screen]] with the following properties: | |||
*'''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. | |||
==Creating a VGUI script== | |||
==VGUI code modifications== | |||
=== Getting it to load === | |||
1) Create a .res file in <codE>''steamdir''\SourceMods\''yourmod''\scripts\screens</code>. This example is called <code>vgui_test_screen.res</code>: | |||
"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" | |||
} | |||
} | |||
} | |||
2) The materials used in the .res file can be found in source material.gcf using [[GCFScape]]. Extract the files in hl2\materials\vgui\screens to ''steamdir''\SourceMods\''moddir''\materials\vgui\screens. | |||
3) In ''steamdir''\SourceMods\''moddir''\scripts 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" | |||
} | |||
} | |||
=== Getting Input to work === | |||
Here is the proper way of fixing vgui input: | |||
In '''in_buttons.h''', where the other flags are defined add: | |||
#define IN_VALIDVGUIINPUT (1 << 23) //bitflag for vgui fix | |||
next, in '''in_main.cpp''' inside the method - CInput::CreateMove(...) | |||
add: | |||
cmd->buttons |= IN_VALIDVGUIINPUT; | |||
right above: | |||
g_pClientMode->CreateMove( input_sample_frametime, cmd ); | |||
next, in '''c_baseplayer.cpp''' inside the method - C_BasePlayer::CreateMove( ... ) | |||
add: | |||
if(pCmd->buttons & IN_VALIDVGUIINPUT) | |||
right above: | |||
DetermineVguiInputMode( pCmd ); | |||
''(So it only calls DetermineVguiInputMode if the buttons include our flag)'' | |||
and finally, inside the method - 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 <code>CInput::ExtraMouseSample</code> calls <code>g_pClientMode->CreateMove()</code> without initializing the button flags, thus the VGui screen is updated with bad button input. Since IN_VALIDVGUIINPUT is only set from within <code>CInput::CreateMove</code>, 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 === | |||
1) 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. | |||
== External links == | |||
* [http://www.jakoavain.net/helk/granted.jpg Screenshot of working panels in the mod Hostile Planet] |
Revision as of 13:22, 23 September 2005
This is my personal sandbox area.
Adding a VGUI screen to a map
Create a vgui_screen with the following properties:
- 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.
Creating a VGUI script
VGUI code modifications
Getting it to load
1) Create a .res file in steamdir\SourceMods\yourmod\scripts\screens
. 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" } } }
2) The materials used in the .res file can be found in source material.gcf using GCFScape. Extract the files in hl2\materials\vgui\screens to steamdir\SourceMods\moddir\materials\vgui\screens.
3) In steamdir\SourceMods\moddir\scripts 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" } }
Getting Input to work
Here is the proper way of fixing vgui input:
In in_buttons.h, where the other flags are defined add:
#define IN_VALIDVGUIINPUT (1 << 23) //bitflag for vgui fix
next, in in_main.cpp inside the method - CInput::CreateMove(...) add:
cmd->buttons |= IN_VALIDVGUIINPUT;
right above:
g_pClientMode->CreateMove( input_sample_frametime, cmd );
next, in c_baseplayer.cpp inside the method - C_BasePlayer::CreateMove( ... )
add:
if(pCmd->buttons & IN_VALIDVGUIINPUT)
right above:
DetermineVguiInputMode( pCmd );
(So it only calls DetermineVguiInputMode if the buttons include our flag)
and finally, inside the method - 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_VALIDVGUIINPUT 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
1) 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.