diff --git a/zscript/utcommon.zsc b/zscript/utcommon.zsc index 9c8957c..9f34ec1 100644 --- a/zscript/utcommon.zsc +++ b/zscript/utcommon.zsc @@ -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"))