[page=Introduction]
Hello!
This tut shows you how to manage speeds for player classes in Q2.
Please note that this code hacks ClientThink which will not always work!
There are many bugs with this code, mostly the one where you will not be able to jump at times. Try it out, and if you're good, fix it!
[page=Structures]
Head to your gclient_s struct in g_local.h (NOT THE ONE IN GAME.H!), and add this to the end:
int ClassSpeed;
Easy!
[page=Meat]
Head down to ClientThink. Time for some EXTREME hacking!
Find this at the beginning:
pmove_t pm;
Starting from below that line, add this:
float ClassSpeedModifer, t;
vec3_t velo;
vec3_t end, forward, right, up, add;
ClassSpeedModifer = ent->client->ClassSpeed * 0.2;
//Figure out speed
VectorClear (velo);
AngleVectors (ent->client->v_angle, forward, right, up);
VectorScale(forward, ucmd->forwardmove*ClassSpeedModifer, end);
VectorAdd(end,velo,velo);
AngleVectors (ent->client->v_angle, forward, right, up);
VectorScale(right, ucmd->sidemove*ClassSpeedModifer, end);
VectorAdd(end,velo,velo);
//if not in water set it up so they aren't moving up or down when they press forward
if (ent->waterlevel == 0)
velo[2] = 0;
if (ent->waterlevel==1)//feet are in the water
{
//Water slows you down or at least I think it should
velo[0] *= 0.875;
velo[1] *= 0.875;
velo[2] *= 0.875;
ClassSpeedModifer *= 0.875;
}
else if (ent->waterlevel==2)//waist is in the water
{
//Water slows you down or at least I think it should
velo[0] *= 0.75;
velo[1] *= 0.75;
velo[2] *= 0.75;
ClassSpeedModifer *= 0.75;
}
else if (ent->waterlevel==3)//whole body is in the water
{
//Water slows you down or at least I think it should
velo[0] *= 0.6;
velo[1] *= 0.6;
velo[2] *= 0.6;
ClassSpeedModifer *= 0.6;
}
if (ent->groundentity)//add
VectorAdd(velo,ent->velocity,ent->velocity);
else if (ent->waterlevel)
VectorAdd(velo,ent->velocity,ent->velocity);
else
{
//Allow for a little movement but not as much
velo[0] *= 0.25;
velo[1] *= 0.25;
velo[2] *= 0.25;
VectorAdd(velo,ent->velocity,ent->velocity);
}
//Make sure not going to fast. This slows down grapple too
t = VectorLength(ent->velocity);
if (t > 300*ClassSpeedModifer || t < -300*ClassSpeedModifer)
{
VectorScale (ent->velocity, 300 * ClassSpeedModifer / t, ent->velocity);
}
//Set these to 0 so pmove thinks we aren't pressing forward or sideways since we are handling all the player forward and sideways speeds
ucmd->forwardmove = 0;
ucmd->sidemove = 0;
[page=Setting them]
Head to your class changing functions or commands, and add this
ent->client->ClassSpeed = 5;
That's the normal speed, hopefully, if I did it right.
You could also set up some other stuff so instead of a variable on the edict it is controlled by a console variable but this is not necessary. I think I got most of the bugs worked out but it seems whenever the ClassSpeed is 0 or real slow it seems to make the player view spot move still. I might have forgot some other stuff but I think I got it all.
This comment is currently awaiting admin approval, join now to view.
float ClassSpeedModifer, t;
vec3_t velo;
vec3_t end, forward, right, up, add;
ClassSpeedModifer = ent->client->ClassSpeed * 0.2;
//Figure out speed
VectorClear (velo);
AngleVectors (ent->client->v_angle, forward, right, up);
VectorScale(forward, ucmd->forwardmove*ClassSpeedModifer, end);
VectorAdd(end,velo,velo);
AngleVectors (ent->client->v_angle, forward, right, up);
VectorScale(right, ucmd->sidemove*ClassSpeedModifer, end);
VectorAdd(end,velo,velo);
//if not in water set it up so they aren't moving up or down when they press forward
if (ent->waterlevel == 0)
velo[2] = 0;
if (ent->waterlevel==1)//feet are in the water
{
//Water slows you down or at least I think it should
velo[0] *= 0.875;
velo[1] *= 0.875;
velo[2] *= 0.875;
ClassSpeedModifer *= 0.875;
}
else if (ent->waterlevel==2)//waist is in the water
{
//Water slows you down or at least I think it should
velo[0] *= 0.75;
velo[1] *= 0.75;
velo[2] *= 0.75;
ClassSpeedModifer *= 0.75;
}
else if (ent->waterlevel==3)//whole body is in the water
{
//Water slows you down or at least I think it should
velo[0] *= 0.6;
velo[1] *= 0.6;
velo[2] *= 0.6;
ClassSpeedModifer *= 0.6;
}
if (ent->groundentity)//add
VectorAdd(velo,ent->velocity,ent->velocity);
else if (ent->waterlevel)
VectorAdd(velo,ent->velocity,ent->velocity);
else
{
//Allow for a little movement but not as much
velo[0] *= 0.25;
velo[1] *= 0.25;
velo[2] *= 0.25;
VectorAdd(velo,ent->velocity,ent->velocity);
}
//Make sure not going to fast. This slows down grapple too
t = VectorLength(ent->velocity);
if (t > 300*ClassSpeedModifer || t < -300*ClassSpeedModifer)
{
VectorScale (ent->velocity, 300 * ClassSpeedModifer / t, ent->velocity);
}
//Set these to 0 so pmove thinks we aren't pressing forward or sideways since we are handling all the player forward and sideways speeds
ucmd->forwardmove = 0;
ucmd->sidemove = 0;
this was the key to deciphering it:
& # 1 1 1 ; == o
& # 6 2 ; == >
& # 4 0 ; == (
& # 4 1 ; == )
& # 9 1 ; == [
& # 9 3 ; == ]