Fix UT player swimming physics.
This commit is contained in:
parent
7c1cf8bacc
commit
86e4571f7d
1 changed files with 117 additions and 95 deletions
|
|
@ -305,9 +305,9 @@ Class UTPlayer : DoomPlayer
|
||||||
if ( InStateSequence(CurState,FindState("See",true)) )
|
if ( InStateSequence(CurState,FindState("See",true)) )
|
||||||
SetStateLabel("See2");
|
SetStateLabel("See2");
|
||||||
if ( !player || (player.mo != self) ) return;
|
if ( !player || (player.mo != self) ) return;
|
||||||
if ( (waterlevel >= 2) && (lastwaterlevel < 2) )
|
if ( waterlevel && !lastwaterlevel )
|
||||||
PlaySplash(1.);
|
PlaySplash(1.);
|
||||||
else if ( (waterlevel < 2) && (lastwaterlevel >= 2) )
|
else if ( !waterlevel && lastwaterlevel )
|
||||||
PlaySurface();
|
PlaySurface();
|
||||||
if ( (waterlevel >= 3) && !underwatersnd )
|
if ( (waterlevel >= 3) && !underwatersnd )
|
||||||
{
|
{
|
||||||
|
|
@ -522,7 +522,80 @@ Class UTPlayer : DoomPlayer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last_sm = sm;
|
last_sm = sm;
|
||||||
if ( !bNoGravity && player.onground && (waterlevel < 3) )
|
if ( (bFly && bFlyCheat) || (player.cheats&CF_NOCLIP2) )
|
||||||
|
{
|
||||||
|
// fly cheat has infinite friction (player stops moving when movement keys are released)
|
||||||
|
Vector3 dir = (0,0,0);
|
||||||
|
if ( vel.length() > double.epsilon ) dir = vel.unit();
|
||||||
|
Vector3 x, y;
|
||||||
|
[x, y] = dt_Utility.GetAxes(angle,pitch,0);
|
||||||
|
acceleration3 = x*player.cmd.forwardmove+y*player.cmd.sidemove;
|
||||||
|
if ( player.cmd.buttons&BT_JUMP ) acceleration3.z = 0x500;
|
||||||
|
else if ( player.cmd.buttons&BT_CROUCH ) acceleration3.z = -0x500;
|
||||||
|
if ( acceleration3.length() <= double.epsilon ) vel *= 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vector3 acceldir = acceleration3.unit();
|
||||||
|
acceleration3 = acceldir*Min(acceleration3.length(),accelrate/TICRATE);
|
||||||
|
vel = vel-(dir-acceldir)*vel.length();
|
||||||
|
}
|
||||||
|
vel = vel+acceleration3/TICRATE;
|
||||||
|
double maxvel;
|
||||||
|
if ( flak_doomspeed ) maxvel = groundspeed_doomish/TICRATE;
|
||||||
|
else maxvel = groundspeed/TICRATE;
|
||||||
|
maxvel *= fs;
|
||||||
|
if ( vel.length() > maxvel ) vel = vel.unit()*maxvel;
|
||||||
|
player.vel *= .8;
|
||||||
|
player.jumptics = -2;
|
||||||
|
if ( !(player.cheats & CF_PREDICTING) ) PlayIdle();
|
||||||
|
}
|
||||||
|
else if ( (waterlevel || bNoGravity) && !player.GetClassicFlight() )
|
||||||
|
{
|
||||||
|
// swimming is pretty much like ground movement, but with much reduced friction and lower speed
|
||||||
|
friction *= fluidfriction/groundfriction;
|
||||||
|
Vector3 dir = (0,0,0);
|
||||||
|
if ( vel.length() > double.epsilon ) dir = vel.unit();
|
||||||
|
double doomfriction = clamp(GetFriction()/ORIG_FRICTION,0.0,1.0);
|
||||||
|
Vector3 x, y;
|
||||||
|
[x, y] = dt_Utility.GetAxes(angle,pitch,0);
|
||||||
|
acceleration3 = x*player.cmd.forwardmove+y*player.cmd.sidemove;
|
||||||
|
if ( player.cmd.buttons&BT_JUMP ) acceleration3.z = 0x500;
|
||||||
|
else if ( player.cmd.buttons&BT_CROUCH ) acceleration3.z = -0x500;
|
||||||
|
if ( acceleration3.length() <= double.epsilon )
|
||||||
|
{
|
||||||
|
Vector3 oldvel = vel;
|
||||||
|
vel = vel-(2*dir)*vel.length()*friction/TICRATE;
|
||||||
|
if ( oldvel dot vel < 0.0 ) vel *= 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vector3 acceldir = acceleration3.unit();
|
||||||
|
acceleration3 = acceldir*Min(acceleration3.length(),accelrate/TICRATE);
|
||||||
|
vel = vel-(dir-acceldir)*vel.length()*friction/TICRATE;
|
||||||
|
}
|
||||||
|
vel = vel+acceleration3/TICRATE;
|
||||||
|
double maxvel;
|
||||||
|
if ( bNoGravity ) // flying uses ground speed
|
||||||
|
{
|
||||||
|
if ( flak_doomspeed ) maxvel = groundspeed_doomish/TICRATE;
|
||||||
|
else maxvel = groundspeed/TICRATE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( flak_doomspeed ) maxvel = swimspeed_doomish/TICRATE;
|
||||||
|
else maxvel = swimspeed/TICRATE;
|
||||||
|
}
|
||||||
|
maxvel *= fs*doomfriction;
|
||||||
|
if ( vel.length() > maxvel ) vel = vel.unit()*maxvel;
|
||||||
|
player.vel = player.vel*.8+vel.xy*.2;
|
||||||
|
player.jumptics = -2;
|
||||||
|
if ( !(player.cheats & CF_PREDICTING) )
|
||||||
|
{
|
||||||
|
if ( acceleration3.length() <= double.epsilon ) PlayIdle();
|
||||||
|
else PlayRunning();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( player.onground )
|
||||||
{
|
{
|
||||||
if ( flak_tapdodge && (dodge.length() > 0) && !tempslide )
|
if ( flak_tapdodge && (dodge.length() > 0) && !tempslide )
|
||||||
{
|
{
|
||||||
|
|
@ -586,7 +659,7 @@ Class UTPlayer : DoomPlayer
|
||||||
else player.vel = player.vel*.8+vel.xy*.2;
|
else player.vel = player.vel*.8+vel.xy*.2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( !bNoGravity && (waterlevel < 1) )
|
else
|
||||||
{
|
{
|
||||||
// air acceleration when falling
|
// air acceleration when falling
|
||||||
float maxaccel = accelrate/TICRATE;
|
float maxaccel = accelrate/TICRATE;
|
||||||
|
|
@ -617,79 +690,6 @@ Class UTPlayer : DoomPlayer
|
||||||
player.jumptics = -2;
|
player.jumptics = -2;
|
||||||
if ( !(player.cheats & CF_PREDICTING) ) PlayIdle();
|
if ( !(player.cheats & CF_PREDICTING) ) PlayIdle();
|
||||||
}
|
}
|
||||||
else if ( (bFly && bFlyCheat) || (player.cheats&CF_NOCLIP2) )
|
|
||||||
{
|
|
||||||
// fly cheat has infinite friction (player stops moving when movement keys are released)
|
|
||||||
Vector3 dir = (0,0,0);
|
|
||||||
if ( vel.length() > double.epsilon ) dir = vel.unit();
|
|
||||||
Vector3 x, y;
|
|
||||||
[x, y] = dt_Utility.GetAxes(angle,pitch,0);
|
|
||||||
acceleration3 = x*player.cmd.forwardmove+y*player.cmd.sidemove;
|
|
||||||
if ( player.cmd.buttons&BT_JUMP ) acceleration3.z = 0x500;
|
|
||||||
else if ( player.cmd.buttons&BT_CROUCH ) acceleration3.z = -0x500;
|
|
||||||
if ( acceleration3.length() <= double.epsilon ) vel *= 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Vector3 acceldir = acceleration3.unit();
|
|
||||||
acceleration3 = acceldir*Min(acceleration3.length(),accelrate/TICRATE);
|
|
||||||
vel = vel-(dir-acceldir)*vel.length();
|
|
||||||
}
|
|
||||||
vel = vel+acceleration3/TICRATE;
|
|
||||||
double maxvel;
|
|
||||||
if ( flak_doomspeed ) maxvel = groundspeed_doomish/TICRATE;
|
|
||||||
else maxvel = groundspeed/TICRATE;
|
|
||||||
maxvel *= fs;
|
|
||||||
if ( vel.length() > maxvel ) vel = vel.unit()*maxvel;
|
|
||||||
player.vel *= .8;
|
|
||||||
player.jumptics = -2;
|
|
||||||
if ( !(player.cheats & CF_PREDICTING) ) PlayIdle();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// swimming is pretty much like ground movement, but with much reduced friction and lower speed
|
|
||||||
friction *= fluidfriction/groundfriction;
|
|
||||||
Vector3 dir = (0,0,0);
|
|
||||||
if ( vel.length() > double.epsilon ) dir = vel.unit();
|
|
||||||
double doomfriction = clamp(GetFriction()/ORIG_FRICTION,0.0,1.0);
|
|
||||||
Vector3 x, y;
|
|
||||||
[x, y] = dt_Utility.GetAxes(angle,pitch,0);
|
|
||||||
acceleration3 = x*player.cmd.forwardmove+y*player.cmd.sidemove;
|
|
||||||
if ( player.cmd.buttons&BT_JUMP ) acceleration3.z = 0x500;
|
|
||||||
else if ( player.cmd.buttons&BT_CROUCH ) acceleration3.z = -0x500;
|
|
||||||
if ( acceleration3.length() <= double.epsilon )
|
|
||||||
{
|
|
||||||
Vector3 oldvel = vel;
|
|
||||||
vel = vel-(2*dir)*vel.length()*friction/TICRATE;
|
|
||||||
if ( oldvel dot vel < 0.0 ) vel *= 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Vector3 acceldir = acceleration3.unit();
|
|
||||||
acceleration3 = acceldir*Min(acceleration3.length(),accelrate/TICRATE);
|
|
||||||
vel = vel-(dir-acceldir)*vel.length()*friction/TICRATE;
|
|
||||||
}
|
|
||||||
vel = vel+acceleration3/TICRATE;
|
|
||||||
double maxvel;
|
|
||||||
if ( waterlevel < 2 ) // flying uses ground speed
|
|
||||||
{
|
|
||||||
if ( flak_doomspeed ) maxvel = groundspeed_doomish/TICRATE;
|
|
||||||
else maxvel = groundspeed/TICRATE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( flak_doomspeed ) maxvel = swimspeed_doomish/TICRATE;
|
|
||||||
else maxvel = swimspeed/TICRATE;
|
|
||||||
}
|
|
||||||
maxvel *= fs*doomfriction;
|
|
||||||
if ( vel.length() > maxvel ) vel = vel.unit()*maxvel;
|
|
||||||
player.vel = player.vel*.8+vel.xy*.2;
|
|
||||||
player.jumptics = -2;
|
|
||||||
if ( !(player.cheats & CF_PREDICTING) )
|
|
||||||
{
|
|
||||||
if ( acceleration3.length() <= double.epsilon ) PlayIdle();
|
|
||||||
else PlayRunning();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( player.cheats & CF_REVERTPLEASE )
|
if ( player.cheats & CF_REVERTPLEASE )
|
||||||
{
|
{
|
||||||
player.cheats &= ~CF_REVERTPLEASE;
|
player.cheats &= ~CF_REVERTPLEASE;
|
||||||
|
|
@ -765,40 +765,7 @@ Class UTPlayer : DoomPlayer
|
||||||
return;
|
return;
|
||||||
// unreal physics while dead
|
// unreal physics while dead
|
||||||
double friction = FrictionToUnreal();
|
double friction = FrictionToUnreal();
|
||||||
if ( !bNoGravity && player.onground && (waterlevel < 3) )
|
if ( waterlevel )
|
||||||
{
|
|
||||||
// Hook in Unreal physics
|
|
||||||
Vector2 dir = (0,0);
|
|
||||||
if ( vel.xy.length() > double.epsilon ) dir = vel.xy.unit();
|
|
||||||
double doomfriction = clamp(GetFriction()/ORIG_FRICTION,0.0,1.0);
|
|
||||||
Vector2 oldvel = vel.xy;
|
|
||||||
vel.xy = vel.xy - (2 * dir) * vel.xy.length() * friction/TICRATE;
|
|
||||||
if ( oldvel dot vel.xy < 0.0 ) vel.xy *= 0;
|
|
||||||
double maxvel;
|
|
||||||
if ( flak_doomspeed ) maxvel = groundspeed_doomish/TICRATE;
|
|
||||||
else maxvel = groundspeed/TICRATE;
|
|
||||||
maxvel *= doomfriction;
|
|
||||||
if ( vel.xy.length() > maxvel ) vel.xy = vel.xy.unit()*maxvel;
|
|
||||||
player.vel *= 0;
|
|
||||||
}
|
|
||||||
else if ( !bNoGravity && (waterlevel < 1) )
|
|
||||||
{
|
|
||||||
// air acceleration when falling
|
|
||||||
Vector2 dir = (0,0);
|
|
||||||
if ( vel.xy.length() > double.epsilon ) dir = vel.xy.unit();
|
|
||||||
double maxvel;
|
|
||||||
if ( flak_doomspeed ) maxvel = groundspeed_doomish/TICRATE;
|
|
||||||
else maxvel = groundspeed/TICRATE;
|
|
||||||
// if new velocity is higher than ground speed, steer but don't increase it
|
|
||||||
if ( vel.xy.length() > maxvel )
|
|
||||||
{
|
|
||||||
double vsiz = vel.xy.length();
|
|
||||||
vel.xy = vel.xy.unit()*vsiz;
|
|
||||||
}
|
|
||||||
if ( vel.length() > terminalvelocity/TICRATE ) vel = vel.unit()*(terminalvelocity/TICRATE);
|
|
||||||
player.vel *= 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// swimming is pretty much like ground movement, but with much reduced friction and lower speed
|
// swimming is pretty much like ground movement, but with much reduced friction and lower speed
|
||||||
friction *= fluidfriction/groundfriction;
|
friction *= fluidfriction/groundfriction;
|
||||||
|
|
@ -815,6 +782,61 @@ Class UTPlayer : DoomPlayer
|
||||||
if ( vel.length() > maxvel ) vel = vel.unit()*maxvel;
|
if ( vel.length() > maxvel ) vel = vel.unit()*maxvel;
|
||||||
player.vel *= 0;
|
player.vel *= 0;
|
||||||
}
|
}
|
||||||
|
else if ( player.onground )
|
||||||
|
{
|
||||||
|
// Hook in Unreal physics
|
||||||
|
Vector2 dir = (0,0);
|
||||||
|
if ( vel.xy.length() > double.epsilon ) dir = vel.xy.unit();
|
||||||
|
double doomfriction = clamp(GetFriction()/ORIG_FRICTION,0.0,1.0);
|
||||||
|
Vector2 oldvel = vel.xy;
|
||||||
|
vel.xy = vel.xy - (2 * dir) * vel.xy.length() * friction/TICRATE;
|
||||||
|
if ( oldvel dot vel.xy < 0.0 ) vel.xy *= 0;
|
||||||
|
double maxvel;
|
||||||
|
if ( flak_doomspeed ) maxvel = groundspeed_doomish/TICRATE;
|
||||||
|
else maxvel = groundspeed/TICRATE;
|
||||||
|
maxvel *= doomfriction;
|
||||||
|
if ( vel.xy.length() > maxvel ) vel.xy = vel.xy.unit()*maxvel;
|
||||||
|
player.vel *= 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// air acceleration when falling
|
||||||
|
Vector2 dir = (0,0);
|
||||||
|
if ( vel.xy.length() > double.epsilon ) dir = vel.xy.unit();
|
||||||
|
double maxvel;
|
||||||
|
if ( flak_doomspeed ) maxvel = groundspeed_doomish/TICRATE;
|
||||||
|
else maxvel = groundspeed/TICRATE;
|
||||||
|
// if new velocity is higher than ground speed, steer but don't increase it
|
||||||
|
if ( vel.xy.length() > maxvel )
|
||||||
|
{
|
||||||
|
double vsiz = vel.xy.length();
|
||||||
|
vel.xy = vel.xy.unit()*vsiz;
|
||||||
|
}
|
||||||
|
if ( vel.length() > terminalvelocity/TICRATE ) vel = vel.unit()*(terminalvelocity/TICRATE);
|
||||||
|
player.vel *= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// backported from DEMOLITIONIST, needed to fix quirks in swimming behavior
|
||||||
|
override void FallAndSink( double grav, double oldfloorz )
|
||||||
|
{
|
||||||
|
if ( !flak_utmovement || !player || (player.mo != self) || (player.cheats&(CF_FROZEN|CF_TOTALLYFROZEN)) )
|
||||||
|
{
|
||||||
|
Super.FallAndSink(grav,oldfloorz);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// do nothing if standing on ground or "floating"
|
||||||
|
if ( player.onground || bNOGRAVITY ) return;
|
||||||
|
// ensure we don't pass terminal velocity just from falling
|
||||||
|
if ( vel.z < -50 ) return;
|
||||||
|
// we don't care about "the doom way" here, gravity is
|
||||||
|
// ALWAYS in effect when not standing on solid ground
|
||||||
|
if ( waterlevel > 1 )
|
||||||
|
{
|
||||||
|
// UT buoyancy, reduces gravity in water by 99%
|
||||||
|
grav *= .01;
|
||||||
|
}
|
||||||
|
vel.z -= grav;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void PlayFootstep( double vol )
|
virtual void PlayFootstep( double vol )
|
||||||
|
|
@ -971,7 +993,7 @@ Class UTPlayer : DoomPlayer
|
||||||
|| InStateSequence(CurState,FindState("Turn")) )
|
|| InStateSequence(CurState,FindState("Turn")) )
|
||||||
SetStateLabel("See2");
|
SetStateLabel("See2");
|
||||||
}
|
}
|
||||||
else if ( !bNoGravity && (waterlevel < 1) && abs(pos.z-floorz) > maxstepheight )
|
else if ( !bNoGravity && (waterlevel < 1) && (abs(pos.z-floorz) > maxstepheight) )
|
||||||
{
|
{
|
||||||
// Falling
|
// Falling
|
||||||
if ( InStateSequence(CurState,FindState("Spawn"))
|
if ( InStateSequence(CurState,FindState("Spawn"))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue