This tutorial shows how to enable
you to set what speeds the player can go, and force them to remain
at those speeds. Most of the setting and checking is done on the
client side, so there should be no noticable increase in network
traffic. The system used should easily be altered to make use of
any player class system or take into account any special items that
can alter someone's speed.
File names are shown in
red. Existing code is shown in
yellow. Additions you have to make are
shown in green.
Server side
changes
First, we must modify the server to
send the speed information to the client. Let's start by adding a
variable to the player class so the server knows when it needs to
send an update to the client, as well as a function to determine
what the speed of the player should be:
PLAYER.H
(near the bottom):
void
SetCustomDecalFrames( int nFrames );
int
GetCustomDecalFrames( void );
int
m_iClientSpeed; // What the client thinks the player's max speed is
int
PlayerSpeed() {return 270;}
};
Change 270 to whatever speed you
want, or perform any calculations such as determining speed based on
the player's class or equipment, etc.
Next we need to set up the message
to the client:
PLAYER.CPP:
(near the top)
int
gmsgHealth = 0;
int
gmsgSpeed = 0;
int
gmsgDamage = 0;
(in CBasePlayer::Precache)
gmsgHealth = REG_USER_MSG( "Health", 1 );
gmsgSpeed = REG_USER_MSG( "Speed", 2);
gmsgDamage = REG_USER_MSG( "Damage", 12 );
Now we'll set the server-side
limitation on speed, and force an update to the client:
(in CBasePlayer::Spawn)
m_lastx
= m_lasty = 0;
g_engfuncs.pfnSetClientMaxspeed( ENT( pev ), PlayerSpeed() );
m_iClientSpeed = 0; // force speed update to client
g_pGameRules->PlayerSpawn( this );
}
Finally we need to actually send the
message, if necessary:
(in
CBasePlayer::UpdateClientData)
m_iClientHealth = pev->health;
}
int
iSpeed = PlayerSpeed();
if
(iSpeed != m_iClientSpeed)
{
// send
"Speed" update message
MESSAGE_BEGIN( MSG_ONE, gmsgSpeed, NULL, pev );
WRITE_SHORT( iSpeed );
MESSAGE_END();
m_iClientSpeed = iSpeed;
}
if
(pev->armorvalue != m_iClientBattery)
Whew! That's it for the server
side. All it basically does is send the speed to the client
whenever it's changed. Now on to the part that actually makes
things happen...
Client side
changes
The easy part is that you'll need to
download
SPEED.CPP and add it to your client's project. You'll want to
look at the CHudSpeed::SetSpeed function. Currently I have it
setting the side and back speeds to half the forward speed (because
I'm a realism nut), and the walk to run ratio is 0.5. You can alter
these as you wish, but if you do, be sure to change the
CHudSpeed::Think function in the same way. If you want the speeds
to be set independant of each other, you'll need to modify both the
server and client to send an individual message for each speed.
Before compiling, though, we need to
add a few lines to some other files. First let's add a new class
definition for the new CHudSpeed class, and add an instance of it to
the CHud class:
HUD.H
(add anywhere):
class
CHudSpeed: public CHudBase
{
public:
int
m_iSpeed;
int
Init( void );
void
Think( void );
void
SetSpeed( void );
int
MsgFunc_Speed(const char *pszName, int iSize, void *pbuf);
};
(in class CHud, near bottom of
file):
CHudBattery m_Battery;
CHudSpeed m_Speed;
CHudTrain m_Train;
And finally, we need to call the
Init function:
HUD.CPP
(in CHud::Init):
m_Menu.Init();
m_Speed.Init();
MsgFunc_ResetHUD(0, 0, NULL );
That's it! Hopefully everything
compiles, and you now have very rigid player speeds that can't be
modified. Some issues not covered in this tutorial are the numbers
used by Half-Life for determining things such as when to show the
player as running or walking, and how loud and frequently to play
footstep noises. Search for "speed" in PLAYER.CPP and you'll see
what I mean. You should be able to base these off the PlayerSpeed()
function instead of the existing hard-coded values pretty easily. |