Xeno Clash isn't multiplayer, what Micheal is doing is.
Micheal, as you know I'm doing something rather similar. I've gotten it
working reasonably well, but in truth I don't like the way I have it
working. It's laggy and a bit jumpy, and plays terribly for players with
latency more than 50. But I can basically show you how it works, here's the
abridged version:
void CCFGameMovement::FullBodyAnimationMove( void )
{
trace_t pm;
bool bFinished;
Vector vecNewPosition;
QAngle angNewAngles;
float flFrameTime = gpGlobals->frametime;
m_pCFPlayer->SetAbsAngles(m_pCFPlayer->m_angEyeAngles);
m_pCFPlayer->GetIntervalMovement(flFrameTime, bFinished, vecNewPosition,
angNewAngles);
if (bFinished || (m_pCFPlayer->GetLocalOrigin() -
vecNewPosition).LengthSqr() == 0)
{
mv->m_vecVelocity = Vector(0,0,0);
return;
}
Vector vecDelta, vecInternalDelta = vecNewPosition -
m_pCFPlayer->GetLocalOrigin();
float flPitch = -mv->m_vecAbsViewAngles[0];
while (flPitch > 180)
flPitch -= 360;
while (flPitch < -180)
flPitch += 360;
float flLength = vecInternalDelta.Length2D(); // Only need 2d because
z is not extracted from anim data.
float flZ = sin(DEG2RAD(flPitch))*flLength; // Find z based on
where the player is looking.
// Modify it based on the player's direction of movement. (Looking up
but moving backwards actually means moving down.)
Vector vecForward, vecForward2D, vecInternalDeltaNormalized =
vecInternalDelta;
m_pCFPlayer->GetVectors(&vecForward, NULL, NULL);
vecForward2D = vecForward;
vecForward2D.z = vecInternalDeltaNormalized.z = 0;
VectorNormalize(vecForward2D);
VectorNormalize(vecInternalDeltaNormalized);
float flNewLength = RemapVal(fabs(DotProduct(vecInternalDeltaNormalized,
vecForward2D)), 0, 1, flLength, flZ / tan(DEG2RAD(flPitch)));
vecDelta = vecInternalDelta;
VectorNormalize(vecDelta);
vecDelta *= flNewLength;
vecDelta.z = flZ * DotProduct(vecInternalDeltaNormalized, vecForward2D);
Vector vecDestination = mv->GetAbsOrigin()+vecDelta;
mv->m_vecVelocity = vecDelta/gpGlobals->frametime;
// first try moving directly to the next spot
TracePlayerBBox( mv->GetAbsOrigin(), vecDestination, PlayerSolidMask(),
COLLISION_GROUP_PLAYER_MOVEMENT, pm );
if ( pm.fraction == 1 )
{
mv->SetAbsOrigin( pm.endpos );
return;
}
// We are using the animation's velocity to force velocity consistent
with the animation.
mv->m_vecVelocity += player->GetBaseVelocity();
StepMove( vecDestination, pm );
// Now pull the base velocity back out.
mv->m_vecVelocity -= player->GetBaseVelocity();
}
Now like I said it's laggy and skippy and I haven't figured out yet how to
make it not so. Part of the problem is that gpGlobals->frametime is
different on the client than on the server. Part of the problem is that
GetInternalMovement returns different results on client and server for some
reason, even though I copied the code straight into a client function (it
didn't exist before.) The reason it skips is because the client and server
disagree on the constantly changing value of the player's real position and
velocity.
I haven't gotten around to redoing the code, but what I'm thinking of doing
is, instead of constantly updating the player's velocity, not using LX/LY
and instead having the animation playing without the player actually moving
around, and then update his position at the end of the animation to wherever
the player has ended up moving. This might be prone to penetration errors
though. The other option is to somehow refactor the code so that it takes a
delta of the animation movement from the beginning of the animation, instead
of from the last frame of the animation.
Either way it's a challenging issue that I haven't quite figured out yet, so
if you want to help tackle we could probably figure it out.
--
Jorge "Vino" Rodriguez
_______________________________________________
To unsubscribe, edit your list preferences, or view the list archives, please
visit:
http://list.valvesoftware.com/mailman/listinfo/hlcoders