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)) )
|
||||
SetStateLabel("See2");
|
||||
if ( !player || (player.mo != self) ) return;
|
||||
if ( (waterlevel >= 2) && (lastwaterlevel < 2) )
|
||||
if ( waterlevel && !lastwaterlevel )
|
||||
PlaySplash(1.);
|
||||
else if ( (waterlevel < 2) && (lastwaterlevel >= 2) )
|
||||
else if ( !waterlevel && lastwaterlevel )
|
||||
PlaySurface();
|
||||
if ( (waterlevel >= 3) && !underwatersnd )
|
||||
{
|
||||
|
|
@ -522,7 +522,80 @@ Class UTPlayer : DoomPlayer
|
|||
}
|
||||
}
|
||||
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 )
|
||||
{
|
||||
|
|
@ -586,7 +659,7 @@ Class UTPlayer : DoomPlayer
|
|||
else player.vel = player.vel*.8+vel.xy*.2;
|
||||
}
|
||||
}
|
||||
else if ( !bNoGravity && (waterlevel < 1) )
|
||||
else
|
||||
{
|
||||
// air acceleration when falling
|
||||
float maxaccel = accelrate/TICRATE;
|
||||
|
|
@ -617,79 +690,6 @@ Class UTPlayer : DoomPlayer
|
|||
player.jumptics = -2;
|
||||
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 )
|
||||
{
|
||||
player.cheats &= ~CF_REVERTPLEASE;
|
||||
|
|
@ -765,40 +765,7 @@ Class UTPlayer : DoomPlayer
|
|||
return;
|
||||
// unreal physics while dead
|
||||
double friction = FrictionToUnreal();
|
||||
if ( !bNoGravity && player.onground && (waterlevel < 3) )
|
||||
{
|
||||
// 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
|
||||
if ( waterlevel )
|
||||
{
|
||||
// swimming is pretty much like ground movement, but with much reduced friction and lower speed
|
||||
friction *= fluidfriction/groundfriction;
|
||||
|
|
@ -815,6 +782,61 @@ Class UTPlayer : DoomPlayer
|
|||
if ( vel.length() > maxvel ) vel = vel.unit()*maxvel;
|
||||
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 )
|
||||
|
|
@ -971,7 +993,7 @@ Class UTPlayer : DoomPlayer
|
|||
|| InStateSequence(CurState,FindState("Turn")) )
|
||||
SetStateLabel("See2");
|
||||
}
|
||||
else if ( !bNoGravity && (waterlevel < 1) && abs(pos.z-floorz) > maxstepheight )
|
||||
else if ( !bNoGravity && (waterlevel < 1) && (abs(pos.z-floorz) > maxstepheight) )
|
||||
{
|
||||
// Falling
|
||||
if ( InStateSequence(CurState,FindState("Spawn"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue