Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /var/sites/a/ on line 20
Wavelength | Your Game Editing Resource | How to make a key that toggles
Welcome, Guest! Login | Register

How to make a key that toggles [Print this Article]
Posted by: sluggo
Date posted: Sep 14 2003
User Rating: 5 out of 5.0
Number of views: 6763
Number of comments: 11
Description: Many Halflife movement keys require the player to hold the key down to achieve their effect. If players want to remain in a position (such as crouch or prone) for extended periods of time, this could lead to fatigue, here's how you can alleviate that with some clever manipulation of the button code.
When we created our prone system for Tour of Duty, we had decided to make the prone key work just like any other key in Halflife (for example the crouch key). Unfortunately, while that made sense and allowed us to avoid many bugs that prone systems have -- in Day of Defeat, you historically couldn't stand->crouch->prone, you had to be standing in order to go prone, which is not very realistic for a realistic war modification in our view.

The unfortunate side effect of this is that players often want to remain in a position such as prone for extended periods of time, so for gameplay purposes, a toggling key is really best. Initially, we used a script to 'toggle' the key, but that is buggy and error prone, as you cannot control such from the code.

Here's how you could go ahead and make any normal Halflife key 'toggle'. This is all client side, and just ends up setting the proper button state bits, and the engine forwards everything onto the server for you in each update.

The first step is to declare a new boolean value, the top of hud.cpp is a good place for this:

 CODE (c++) 
bool g_bDuckToggled;

Now, you'll need to set the state of this value properly, the times you need to reset this value are whenever the Player spawns, or the HUD is initialized (i.e. level changes). First in CHud::Init (called when DLL is loaded into memory or at level change:

 CODE (c++) 
g_bDuckToggled  = false;

Now the server is going to tell the HUD to initialize itself at certain points, usually when players spawn or such, so I decided to use MsgFunc_ResetHUD to do this, because that's sent for us when appropriate, in that function, just set to false again:

 CODE (c++) 
extern bool g_bDuckToggled; // (needs to go at the top of the hud_msg.cpp file as well)
g_bDuckToggled  = false;

Believe it or not, we're nearly done. Next we have to move onto input.cpp, and setup the new command, first another extern declaration:

 CODE (c++) 
extern bool g_bDuckToggled; // (somewhere near g_iAlive would do)

Ok, now search for IN_DuckUp, and under that, let's put our only function for this whole process:

 CODE (c++) 
void IN_DuckToggle( void )
    g_bDuckToggled = !g_bDuckToggled;

All we're doing here is setting the toggle to the opposite of it's current state. False becomes true, &c.

Ok, now we're going to set this up as a 'command', in InitInput, search for IN_DuckUp, and again underneath, let's associate the above function with a new command:

 CODE (c++) 
gEngfuncs.pfnAddCommand ( "duck_t", IN_DuckToggle );

Now we're setup for the player to type duck_t (or bind a key to it), and the engine will call our function for us.

The last step is simply setting button states, which is normally done in CL_ButtonBits, we'll just add some new code underneath the following bit:

 CODE (c++) 
if (in_duck.state & 3)
    bits |= IN_DUCK;

That's a normal duck key, if held down the button bits will have IN_DUCK's bit turned on, here we're going to fake out the player holding the duck key, by setting the bit if the boolean value is true:

 CODE (c++) 
if ( g_bDuckToggled )
    bits |= IN_DUCK;

And that's it, if you bind a key to duck_t, you'll now be able to remain ducking for extended periods of time, with no extra work required by the player, hit the key again, and it toggles off. The button state is sent every frame by the engine, whether or not the bit is on, so we've added no new network traffic either, which is always a good thing.

A lot of prone systems I've seen generate extra network traffic to activate it, and you can get cases where things are out of sync client to server as a result. Here we're no more laggy than Halflife itself was, so we can't go wrong.

Rate This Article
This article is currently rated: 5 out of 5.0 (3 Votes)

You have to register to rate this article.
User Comments Showing comments 1-11

Posted By: pplante on Sep 14 2003 at 03:31:01
Very nice tutorial there sluggo. Its short and gets to the point without much copy and paste code.

Hope to see more of these soon!

Posted By: Ratking on Sep 15 2003 at 01:18:26
C:\SIERRA\Half-Life\SDK\Multiplayer Source\cl_dll\input.cpp(1000) : error C2017: illegal escape sequence
C:\SIERRA\Half-Life\SDK\Multiplayer Source\cl_dll\input.cpp(1000) : error C2001: newline in constant
C:\SIERRA\Half-Life\SDK\Multiplayer Source\cl_dll\input.cpp(1002) : error C2146: syntax error : missing ')' before identifier 'lookstrafe'
C:\SIERRA\Half-Life\SDK\Multiplayer Source\cl_dll\input.cpp(1002) : error C2198: 'int (__cdecl *)(char *,void (__cdecl *)(void))' : too few actual parameters
Error executing cl.exe.

input.obj - 4 error(s), 0 warning(s)

most probably me...

Posted By: sluggo on Sep 15 2003 at 03:45:54
Yup, remove the \" before the quotes.. my code as it appears above won't compile if you just copy and paste :p. It was because I edited the thing and the board stuck in some \'s to escape for the php i guess.

If that gets munged by the board, it's backslashes that you don't need in pfnAddCommand().

Posted By: pplante on Sep 15 2003 at 04:44:14
I fixed that in the tutorial so that no one else would have that error.

Posted By: Bulk on Sep 15 2003 at 04:52:02
We might have a bug to do with stripping slashes. I'll look in to it.

Posted By: rkzad on Sep 15 2003 at 05:40:52
I see no problem with it... though then again bulk may have fixed it already.

Posted By: kapalkaudi on Sep 21 2003 at 19:38:22
Simple ;)

Posted By: Ratking on Sep 26 2003 at 17:41:09
5 out of 5

how about some sprites on the HUD so that player can identify what state he/she is in.

Posted By: sluggo on Oct 06 2003 at 12:52:49
Sure, trivial stuff, just check the value of FL_DUCK (FL_DUCK? FL_CROUCHED.. ok I forget..) in pev->flags, if that bit is set, they're ducked, so switch to the 'ducked' spirte in the Draw function, otherwise, in your else block, just draw the standing one. Add to other states you invent..Edited by sluggo on Oct 06 2003, 12:53:17

Posted By: Ratking on Oct 07 2003 at 13:45:18
thanks sluggo, keep them coming!

Posted By: turkish on Nov 18 2005 at 00:21:22
I want to be able to toggle the walk command. I get to the part where I have to make the edit in cl_buttonbits and there is no in_speed for the speedup or speeddown. do i have to something extra?

You must register to post a comment. If you have already registered, you must login.

Latest Articles
3rd person View in Multiplayer
Half-Life 2 | Coding | Client Side Tutorials
How to enable it in HL2DM

By: cct | Nov 13 2006

Making a Camera
Half-Life 2 | Level Design
This camera is good for when you join a map, it gives you a view of the map before you join a team

By: slackiller | Mar 05 2006

Making a camera , Part 2
Half-Life 2 | Level Design
these cameras are working monitors that turn on when a button is pushed.

By: slackiller | Mar 04 2006

Storing weapons on ladder
Half-Life 2 | Coding | Snippets
like Raven Sheild or BF2

By: British_Bomber | Dec 24 2005

Implementation of a string lookup table
Half-Life 2 | Coding | Snippets
A string lookup table is a set of functions that is used to convert strings to pre-defined values

By: deathz0rz | Nov 13 2005

Latest Comments
knock knock
General | News
By: MIFUNE | Dec 31 2017
knock knock
General | News
By: omega | Dec 22 2016
knock knock
General | News
By: MIFUNE | Oct 10 2015
New HL HUD Message System
Half-Life | Coding | Shared Tutorials
By: chbrules | Dec 31 2011
knock knock
General | News
By: Whistler | Nov 05 2011
Particle Engine tutorial part 4
Half-Life | Coding | Client Side Tutorials
By: darkPhoenix | Feb 18 2010
Particle Engine tutorial part 2
Half-Life | Coding | Client Side Tutorials
By: darkPhoenix | Feb 11 2010
Particle Engine tutorial part 3
Half-Life | Coding | Client Side Tutorials
By: darkPhoenix | Feb 11 2010
Game Movement Series #2: Analog Jumping and Floating
Half-Life 2 | Coding | Shared Tutorials
By: mars3554 | Oct 26 2009
Particle Engine tutorial part 5
Half-Life | Coding | Client Side Tutorials
By: Deadpool | Aug 02 2009

Site Info
297 Approved Articless
8 Pending Articles
3940 Registered Members
0 People Online (2 guests)
About - Credits - Contact Us

Wavelength version:
Valid XHTML 1.0! Valid CSS!