View Full Version : Correct walk speed?
stefanhendriks
06-04-2004, 00:00
I have noticed that simply deviding the current movespeed by 2 does NOT give you the actual walk speed used by CS. I can even hear my bots walk while they move slower , and they say in debug console that they are 'walking'.
Currently i have this:
// walk only when NOT holding duck (is same as walking, combination makes bot super slow)
if (f_walk_time > gpGlobals->time && !(pEdict->v.button & IN_DUCK))
f_move_speed = f_max_speed / 2.0;
This makes bots walk slower, true, but it does not make them walk as slow as they should! DId anyone already fixed this? Or perhaps i am using 'out-dated' info?
Pierre-Marie Baty
06-04-2004, 00:42
I am using something similar but I always suspected it was wrong too... glad to be certain of it at last.
What you can do is to use PMTools to print your player's velocity when you're running and when you're walking, using different weapons, and see if one is always the half of the other (and if not, what fraction of it).
In order to keep pressing the forward key when you're in the console, enter "+forward" in the console. When you want to stop going forward, enter "-forward". Same for walking. You can use this to check your player's velocity while in movement.
*edit* P.S: be sure to do this when you're on a flat ground.
stefanhendriks
06-04-2004, 11:41
I have run a little test:
Pistol/Knife:
Running speed = 250
Walking = 130
M4A1
Running speed = 230
Walking = 125
MP5
Running speed = 250
Walking = 130
There is no simple 'devide to' formula in this one. You could do with the MP5 and such , devide by 1.913 or something, but then it would not match with the M4A1
I bet there are different walk speeds for all weapons.
When I tried to make a bot for cs1.5 I got into this problem also.
I did experiments with the player and came up with this:
float ABotBody::BodySpeed2RealSpeed( BODY_SPEED s, float flMaxSpeed ) const
{
switch (s)
{
case BODYSPEED_STAND:
return 0.0f;
case BODYSPEED_WALK:
//Experiments on human player with CS1.5 gives these velocities:
//Pistol Run:250 Walk:130
//Knife Run:260 Walk:135
//Kalash+Armor&Helmet Run:221 Walk:114
//so it seems the formula is linear and integer:
// Walk = (int)Run/2 + (int)(Run/50).
return (float) (((int)flMaxSpeed)/2 + ((int)flMaxSpeed)/50);
case BODYSPEED_RUN:
default:
return flMaxSpeed;
}
}
(crap I use DevC++ ide indentation and had to redo it there by hand...)
It semeed like a good approximation but did not investigate much.
IIRC casting to int before the divisions was important and more accurate than using floats.
The thing is you have to always keep track of the actual max speed (passed as a parameter here flMaxSpeed). I don't remember if intercepting engine's pfnSetClientMaxspeed always worked or not. Thanks I don't have this kind of variable maxspeed problems in IOS :)
Hope this helps.
stefanhendriks
06-04-2004, 13:54
i have tried your code, and it also lets the bots walk slow. But the strange thing is, you can still hear this player walking. I think its a bug in CS or something. THe bots 'walk hearing speed' is faster then the actual walk animation.
Cpl. Shrike
06-04-2004, 14:53
What i did is this.
I checked out which speed the game dll assigns to players when,
walking, croucing, proneing, running, walking slow
Then i used those speeds to give to the bots.
So instead of deviding the max_speeds.
I assign speeds the game.dll would do.
That way they move the same speed as clients do
And the footstep sounds will be fixed then also.
Cos the game.dll checks for client move speed and sets evironmental sounds to the player walking. running. etc etc.
Well the safest way would be to record all speeds for the player in a big table to have a relation [equipment] -> {speeds}, because in CS speed depends on your equipment, so you'll have to measure every combination possible...
Stefan IIRC you also have to set the proper buttons pushed or released like a player would do (IN_RUN etc...). Just hang a minute I'll see if I can resurect my bot and check the sound thing under CS 1.5...
Edit: Ok. The bots are walking and don't make walking sound and are playing the proper animation. At least with the starting equipment. Maybe my trick doesn't work for all kind of equipment or the version of CS you are running, dunno. In addition I have the following code to make sure the right walk buttons are pressed, just before sending the orders to the engine:
if (m_IdealSpeed == BODYSPEED_WALK) m_ActButtons &= (~IN_RUN);
else if (m_IdealSpeed == BODYSPEED_RUN) m_ActButtons |= IN_RUN;
If this still doesn't work then I can't help you more since I can't test equipment with my unfinished cs 1.5 bot sorry :(
stefanhendriks
06-04-2004, 16:16
In CS 1.5 normally the players would recieve their max speed from the game dll. In CS 1.6 it seems not to work that well anymore. I also found some glitches with health updates too. Anyway, i am going to try this 'IN_RUN' thingy and let you know if it worked.
stefanhendriks
06-04-2004, 16:56
i have this code:
// walk only when NOT holding duck (is same as walking, combination makes bot super slow)
if (f_walk_time > gpGlobals->time && !(pEdict->v.button & IN_DUCK))
{
// From "KickBot"
// return (float) (((int)flMaxSpeed)/2 + ((int)flMaxSpeed)/50);
//OLD: f_move_speed = f_max_speed / 2.0; // this is not correct
pEdict->v.button &= (~IN_RUN);
f_move_speed = (float) (((int)f_max_speed)/2 + ((int)f_max_speed)/50);
}
The walk speed is slower, i don't know if its correct, but i assume that KickBots speed calculation is better then the simple "devide by 2" thingy. yet, i still hear faster footsteps by bots. Its like the animation is not set right?
stefanhendriks
06-04-2004, 16:58
What i did is this.
I checked out which speed the game dll assigns to players when,
walking, croucing, proneing, running, walking slow
Then i used those speeds to give to the bots.
So instead of deviding the max_speeds.
I assign speeds the game.dll would do.
That way they move the same speed as clients do
And the footstep sounds will be fixed then also.
Cos the game.dll checks for client move speed and sets evironmental sounds to the player walking. running. etc etc.
Hmm, perhaps you also know what message is sent when the speed is changed? I'll dig into this too, but if you know it by hearth it might help. I am going to 'investigate' this a bit more with the PMTools. This is very strange!
Cpl. Shrike
06-04-2004, 17:23
I don't know that from the top of my head.
I'll post the messages later today.
Cpl. Shrike
06-04-2004, 21:58
void pfnSetClientMaxspeed(const edict_t *pEdict, float fNewMaxspeed)
{
int client_index;
if (debug_engine) { fp=fopen("HPB_bot.txt","a");
fprintf(fp,"pfnSetClientMaxspeed: edict=%x speed=%f\n",pEdict,fNewMaxspeed); fclose(fp); }
for (client_index = 1; client_index < MAX_CLIENTS; client_index++)
{
if (clients[client_index].is_used)
clients[client_index].max_speed = fNewMaxspeed;
}
(*g_engfuncs.pfnSetClientMaxspeed)(pEdict, fNewMaxspeed);
}
This is what im using for TOD and DOD.
Although TOD is spamming the system continiosly with the pfnSetClientMaxspeed, DOD only sends it when the clients speed changes.
In dod the speed also depends what gun and if the gun is deployed.
In that case there are more speeds to recorded for each class and gun. crouching etc etc.
=================
edit.
I recorded only the main speeds like when a client crouches.
It may varie a little but when the speed is below a certain level.
The game dll knows it's slow enuf to stop footstep sounds.
Or when the speed is low enuf the game knows it can't move because it is like zoomed or deployed.
However im not sure fo CS code. (as i don't code for cs)
There is a CVAR named cl_movespeedkey which influences the speed while you walk. It defaults to 0.520 which might be a faktor to the normal speed.
Pierre-Marie Baty
06-04-2004, 22:57
@Stefan: never forget your bot is a SERVER-SIDE bot ! Hence you can completely drop off the hooking for Health, Battery, WeapPickup messages and such, because you have direct access to them whenever you want in pEdict->v.health, pEdict->v.armorvalue and pEdict->v.weapons respectively !
In CS 1.6, the max speed is available in pEdict->v.maxspeed
In CS 1.5, the max speed was sent to the clients through a pfnSetClientMaxSpeed() call.
Hence the fix is to always look in pEdict->v.maxspeed, and use pfnSetClientMaxSpeed() like this:
void SetClientMaxspeed (const edict_t *pEdict, float fNewMaxspeed)
{
// this function tells the client whose player entity is pointed to by pEdict to update its
// maximal running speed to fNewMaxspeed. I don't really get why this function is necessary,
// since the entvars of an entity already feature a "maxspeed" variable, which must be
// trackable in the network pack. There are a lot of weirdosities like this one in the Half-
// Life engine.
// is this client a bot ?
if (players[ENTINDEX ((edict_t *) pEdict) - 1].is_racc_bot)
((edict_t *) pEdict)->v.maxspeed = fNewMaxspeed; // update its max speed (CS 1.5 doesn't)
#ifdef METAMOD
RETURN_META (MRES_IGNORED);
#else
(*g_engfuncs.pfnSetClientMaxSpeed) (pEdict, fNewMaxspeed);
#endif
}
stefanhendriks
07-04-2004, 12:25
omg. You are right. I always forget that when coding for CS 1.6. I got so used to hooking and such, i forgot its now the other way around. I checked my code and saw that i do not use direct accessing when running RB for CS 1.6. I will fix them immidiatly and then hope it works :) i'll let ya know.
stefanhendriks
07-04-2004, 12:47
yeeeeeeeeeeeeeeeeeehaw, fixed! This is l33t. THanks guys!
ow, did i already mentioned it worked? :P ;)
Whistler
08-04-2004, 05:45
if (players[ENTINDEX ((edict_t *) pEdict) - 1].is_racc_bot)
I don't think this is necessary; you can use this for all players (whether it's a bot or not) without problems
Pierre-Marie Baty
08-04-2004, 10:49
Good point indeed Whistler ! :)
Whistler
19-04-2004, 07:44
I've found this in Q1 engine code:
if (in_speed.state & 1)
speed = cl_movespeedkey.value;
else
speed = 1;
...and about the cl_movespeedkey thing:
cvar_t cl_movespeedkey = {"cl_movespeedkey","2.0"};
Note: the shift key in Quake1 is speed UP (not speed down) which is different from HL.
In CS the default value of cl_movespeedkey CVAR is usually 0.52, but the plain HL is 0.3. For each MOD you can type "cl_movespeedkey" in the console and you'll get the value. Note you can't use CVAR_GET_FLOAT("cl_movespeedkey") in the bot code because this CVAR is client-side.
Pierre-Marie Baty
19-04-2004, 13:17
aha, so that would mean:
if (pEdict->v.button & IN_RUN)
move_speed = pEdict->v.maxspeed * CVAR_GET_FLOAT ("cl_movespeedkey");
am I right ?
*edit* I'm dumb as f*ck sometimes, I didn't read Whistler's post until the end. DOH! Okay so that would need a #define for each MOD the bot supports, or perhaps a bot config file setting then. Gwaaah.
Whistler
19-04-2004, 13:38
Note you can't use CVAR_GET_FLOAT("cl_movespeedkey") in the bot code because this CVAR is client-side.
You HAVE to get the value manually ! :)
vBulletin® v3.7.1, Copyright ©2000-2009, Jelsoft Enterprises Ltd.