Fully implemented UT-style player movement (optional).
"Disable boss telefragging" now toggleable. Menu background now displays whenever the menu is open, rather than just on the title screen. Now it matches the expected UT behaviour.
This commit is contained in:
parent
b4abb2e2ae
commit
1b7a288bf5
4 changed files with 195 additions and 82 deletions
|
|
@ -2,16 +2,26 @@ Class UTPlayer : DoomPlayer
|
|||
{
|
||||
bool lastground;
|
||||
double lastvelz, prevvelz;
|
||||
transient CVar footsteps;
|
||||
transient CVar footsteps, utmovement, doomspeed, doomaircontrol, nowalkdrop;
|
||||
Vector2 acceleration;
|
||||
Vector3 acceleration3;
|
||||
int last_fm_tap, last_sm_tap;
|
||||
int last_fm, last_sm;
|
||||
|
||||
const groundspeed = 400.;
|
||||
const accelrate = 2048.;
|
||||
const walkfactor = 0.3;
|
||||
const utaircontrol = 0.35;
|
||||
const groundspeed_doomish = 600.;
|
||||
|
||||
Default
|
||||
{
|
||||
Player.StartItem "Enforcer";
|
||||
Player.StartItem "ImpactHammer";
|
||||
Player.StartItem "MiniAmmo", 30;
|
||||
Player.DamageScreenColor "FF 00 00", 1.0;
|
||||
Player.DamageScreenColor "FF 00 00";
|
||||
Player.ViewHeight 46;
|
||||
Player.GruntSpeed 20;
|
||||
}
|
||||
|
||||
// Have to modify the give cheat to handle UT armor
|
||||
|
|
@ -171,23 +181,48 @@ Class UTPlayer : DoomPlayer
|
|||
if ( !footsteps ) footsteps = CVar.GetCVar('flak_footsteps',players[consoleplayer]);
|
||||
if ( !footsteps.GetBool() ) return;
|
||||
double ang = level.time/(20*TICRATE/35.)*360.;
|
||||
if ( (abs(sin(ang)) >= 1.0) && player.onground && (player.cmd.forwardmove || player.cmd.sidemove) && (waterlevel < 3) )
|
||||
bool forcefootstep = false;
|
||||
if ( player.onground && !bNoGravity && !lastground && (waterlevel < 3) )
|
||||
{
|
||||
if ( (waterlevel > 0) || GetFloorTerrain().IsLiquid && !bOnMobj ) A_PlaySound("ut/playerfootstepwet",CHAN_5,abs(vel.xy.length())*0.03);
|
||||
else A_PlaySound("ut/playerfootstep",CHAN_5,abs(vel.xy.length())*0.03);
|
||||
if ( lastvelz < -4 )
|
||||
{
|
||||
double vol = clamp((-lastvelz-4)*0.05,0.01,1.0);
|
||||
if ( ((waterlevel > 0) || GetFloorTerrain().IsLiquid) && !bOnMobj ) A_PlaySound("ut/wetsplash",CHAN_AUTO,vol);
|
||||
else A_PlaySound("*uland",CHAN_AUTO,vol);
|
||||
}
|
||||
else forcefootstep = true;
|
||||
}
|
||||
if ( player.onground && !bNoGravity && !lastground && (lastvelz < -4) && (lastvelz >= -8) && (waterlevel < 3) )
|
||||
if ( forcefootstep || ((abs(sin(ang)) >= 1.0) && player.onground && (player.cmd.forwardmove || player.cmd.sidemove) && (waterlevel < 3)) )
|
||||
{
|
||||
if ( ((waterlevel > 0) || GetFloorTerrain().IsLiquid) && !bOnMobj ) A_PlaySound("ut/wetsplash",CHAN_AUTO,abs(lastvelz*0.03));
|
||||
else A_PlaySound("*land",CHAN_AUTO,abs(lastvelz*0.03));
|
||||
double vol = abs(vel.xy.length())*0.03;
|
||||
if ( forcefootstep ) vol = clamp(-lastvelz*0.05,0.01,1.0);
|
||||
if ( (waterlevel > 0) || GetFloorTerrain().IsLiquid && !bOnMobj ) A_PlaySound("ut/playerfootstepwet",CHAN_5,vol);
|
||||
else A_PlaySound("ut/playerfootstep",CHAN_5,vol);
|
||||
}
|
||||
lastground = player.onground;
|
||||
lastvelz = prevvelz;
|
||||
prevvelz = vel.z;
|
||||
}
|
||||
|
||||
double FrictionToUnreal()
|
||||
{
|
||||
double fin = GetFriction();
|
||||
if ( fin >= 1.0 ) return 0.0;
|
||||
return 734.2969*fin*fin-1485.0868*fin+750.7899;
|
||||
}
|
||||
|
||||
override void MovePlayer()
|
||||
{
|
||||
if ( !utmovement ) utmovement = CVar.GetCVar('flak_utmovement');
|
||||
if ( !doomspeed ) doomspeed = CVar.GetCVar('flak_doomspeed');
|
||||
if ( !doomaircontrol ) doomaircontrol = CVar.GetCVar('flak_doomaircontrol');
|
||||
if ( !nowalkdrop ) nowalkdrop = CVar.GetCVar('flak_nowalkdrop');
|
||||
bNODROPOFF = false;
|
||||
if ( !utmovement.GetBool() )
|
||||
{
|
||||
Super.MovePlayer();
|
||||
return;
|
||||
}
|
||||
UserCmd cmd = player.cmd;
|
||||
if ( player.turnticks )
|
||||
{
|
||||
|
|
@ -196,74 +231,95 @@ Class UTPlayer : DoomPlayer
|
|||
}
|
||||
else Angle += cmd.yaw*(360./65536.);
|
||||
player.onground = (pos.z <= floorz) || bOnMobj || bMBFBouncer || (player.cheats & CF_NOCLIP2);
|
||||
double friction, movefactor;
|
||||
double forwardmove, sidemove;
|
||||
double fm, sm;
|
||||
double bobfactor;
|
||||
[friction, movefactor] = GetFriction();
|
||||
bobfactor = friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR;
|
||||
if ( !player.onground && !bNoGravity && !waterlevel )
|
||||
double friction = FrictionToUnreal();
|
||||
double fs = TweakSpeeds(1.0,0.0);
|
||||
if ( !doomspeed.GetBool() )
|
||||
{
|
||||
// TODO replicate Unreal air control
|
||||
movefactor *= level.aircontrol;
|
||||
bobfactor *= level.aircontrol;
|
||||
if ( cmd.buttons&BT_SPEED ) fs *= walkfactor;
|
||||
}
|
||||
fm = cmd.forwardmove;
|
||||
sm = cmd.sidemove;
|
||||
[fm, sm] = TweakSpeeds (fm, sm);
|
||||
fm *= Speed / 256;
|
||||
sm *= Speed / 256;
|
||||
if ( CanCrouch() && player.crouchfactor != 1 )
|
||||
{
|
||||
fm *= player.crouchfactor;
|
||||
sm *= player.crouchfactor;
|
||||
bobfactor *= player.crouchfactor;
|
||||
}
|
||||
forwardmove = fm*movefactor*(35/TICRATE);
|
||||
sidemove = sm*movefactor*(35/TICRATE);
|
||||
if ( forwardmove ) Bob(Angle,cmd.forwardmove*bobfactor/256.,true);
|
||||
if ( sidemove ) Bob(Angle-90,cmd.sidemove*bobfactor/256.,false);
|
||||
else fs *= max(abs(cmd.forwardmove/12800.),abs(cmd.sidemove/10240.));
|
||||
if ( CanCrouch() && (player.crouchfactor != -1) ) fs *= player.crouchfactor;
|
||||
acceleration = rotatevector((cmd.forwardmove,-cmd.sidemove),angle);
|
||||
if ( player.onground )
|
||||
{
|
||||
// Hook in Unreal physics (code totally not shamelessly copied from any source code leaks no sir)
|
||||
// TODO find a way to properly "convert" Doom friction values into Unreal friction values (where default ground friction is 8)
|
||||
if ( nowalkdrop.GetBool() )
|
||||
bNODROPOFF = ((acceleration.length() > double.epsilon) && (cmd.buttons&BT_SPEED));
|
||||
// Hook in Unreal physics
|
||||
Vector2 dir = (0,0);
|
||||
if ( vel.xy.length() > double.epsilon ) dir = vel.xy.unit();
|
||||
acceleration = rotatevector((cmd.forwardmove,-cmd.sidemove),angle);
|
||||
if ( acceleration.length() <= double.epsilon )
|
||||
{
|
||||
Vector2 oldvel = vel.xy;
|
||||
vel.xy = vel.xy - (2 * dir) * vel.xy.length() * (1./TICRATE) * friction;
|
||||
vel.xy = vel.xy - (2 * dir) * vel.xy.length() * friction/TICRATE;
|
||||
if ( oldvel dot vel.xy < 0.0 ) vel.xy *= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 acceldir = acceleration.unit();
|
||||
acceleration = acceldir * Min(acceleration.length(), 2048./TICRATE);
|
||||
vel.xy = vel.xy - (dir - acceldir) * vel.xy.length() * (1./TICRATE) * friction;
|
||||
acceleration = acceldir * Min(acceleration.length(), accelrate/TICRATE);
|
||||
vel.xy = vel.xy - (dir - acceldir) * vel.xy.length() * friction/TICRATE;
|
||||
}
|
||||
vel.xy = vel.xy + acceleration * (1./TICRATE);
|
||||
double maxvel = 400./TICRATE;
|
||||
if ( CanCrouch() && player.crouchfactor != 1 )
|
||||
maxvel *= player.crouchfactor;
|
||||
if ( cmd.buttons&BT_SPEED )
|
||||
maxvel *= 0.35;
|
||||
double maxvel;
|
||||
if ( doomspeed.GetBool() ) maxvel = (groundspeed_doomish*fs)/TICRATE;
|
||||
else maxvel = (groundspeed*fs)/TICRATE;
|
||||
double doomfriction = clamp(GetFriction()/ORIG_FRICTION,0.0,1.0);
|
||||
maxvel *= doomfriction;
|
||||
if ( vel.xy.length() > maxvel ) vel.xy = vel.xy.unit()*maxvel;
|
||||
double b = vel.x*cos(angle)+vel.y*sin(angle);
|
||||
Bob(Angle,b/256.,true);
|
||||
b = vel.x*cos(angle-90)+vel.y*sin(angle-90);
|
||||
Bob(Angle-90,b/256.,false);
|
||||
if ( !(player.cheats & CF_PREDICTING) )
|
||||
{
|
||||
if ( acceleration.length() <= double.epsilon ) PlayIdle();
|
||||
else PlayRunning();
|
||||
}
|
||||
player.vel = vel.xy;
|
||||
}
|
||||
else if ( !bNoGravity && !waterlevel )
|
||||
{
|
||||
// air acceleration when falling
|
||||
float maxaccel = accelrate/TICRATE;
|
||||
if ( vel.xy.length() < (40./TICRATE) )
|
||||
maxaccel += (40.-vel.xy.length())/TICRATE;
|
||||
if ( acceleration.length() > maxaccel )
|
||||
acceleration = acceleration.unit()*maxaccel;
|
||||
acceleration *= doomaircontrol.GetBool()?level.aircontrol:0.35;
|
||||
vel.xy += acceleration/TICRATE;
|
||||
player.vel *= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO replicate Unreal air friction
|
||||
if ( forwardmove ) ForwardThrust(forwardmove,Angle);
|
||||
if ( sidemove ) Thrust(sidemove,Angle-90);
|
||||
// swimming uses standard physics, otherwise things break
|
||||
double forwardmove, sidemove;
|
||||
double bobfactor;
|
||||
double friction, movefactor;
|
||||
double fm, sm;
|
||||
[friction, movefactor] = GetFriction();
|
||||
bobfactor = (friction<ORIG_FRICTION)?movefactor:ORIG_FRICTION_FACTOR;
|
||||
fm = cmd.forwardmove;
|
||||
sm = cmd.sidemove;
|
||||
[fm, sm] = TweakSpeeds(fm,sm);
|
||||
fm *= Speed/256;
|
||||
sm *= Speed/256;
|
||||
if ( CanCrouch() && (player.crouchfactor != 1) )
|
||||
{
|
||||
fm *= player.crouchfactor;
|
||||
sm *= player.crouchfactor;
|
||||
bobfactor *= player.crouchfactor;
|
||||
}
|
||||
forwardmove = fm*movefactor*(35/TICRATE);
|
||||
sidemove = sm*movefactor*(35/TICRATE);
|
||||
if ( forwardmove )
|
||||
{
|
||||
Bob(Angle, cmd.forwardmove*bobfactor/256.,true);
|
||||
ForwardThrust(forwardmove,Angle);
|
||||
}
|
||||
if ( sidemove )
|
||||
{
|
||||
let a = Angle-90;
|
||||
Bob(a,cmd.sidemove*bobfactor/256.,false);
|
||||
Thrust(sidemove,a);
|
||||
}
|
||||
if ( !(player.cheats&CF_PREDICTING) && ((forwardmove != 0) || (sidemove != 0)) )
|
||||
PlayRunning();
|
||||
}
|
||||
if ( player.cheats & CF_REVERTPLEASE )
|
||||
{
|
||||
|
|
@ -271,6 +327,45 @@ Class UTPlayer : DoomPlayer
|
|||
player.camera = player.mo;
|
||||
}
|
||||
}
|
||||
|
||||
override void CheckJump()
|
||||
{
|
||||
if ( !utmovement ) utmovement = CVar.GetCVar('flak_utmovement');
|
||||
if ( !doomspeed ) doomspeed = CVar.GetCVar('flak_doomspeed');
|
||||
if ( utmovement.GetBool() && player.onground && !bNoGravity && !waterlevel && (player.jumptics == 0) && (player.cmd.forwardmove || player.cmd.sidemove) )
|
||||
{
|
||||
int fm = player.cmd.forwardmove;
|
||||
int sm = player.cmd.sidemove;
|
||||
Vector2 dodge = (0,0);
|
||||
if ( fm )
|
||||
{
|
||||
int clk = abs(gametic-last_fm_tap);
|
||||
if ( (clk < 5) && (clk > 1) && (last_fm*fm>0) )
|
||||
dodge += RotateVector((fm,0),angle).unit();
|
||||
last_fm_tap = gametic;
|
||||
last_fm = fm;
|
||||
}
|
||||
if ( sm )
|
||||
{
|
||||
int clk = abs(gametic-last_sm_tap);
|
||||
if ( (clk < 5) && (clk > 1) && (last_sm*sm>0) )
|
||||
dodge += RotateVector((0,-sm),angle).unit();
|
||||
last_sm_tap = gametic;
|
||||
last_sm = sm;
|
||||
}
|
||||
if ( dodge.length() > 0 )
|
||||
{
|
||||
if ( doomspeed.GetBool() ) vel += dodge.unit()*(groundspeed_doomish*1.5)/TICRATE;
|
||||
else vel += dodge.unit()*(groundspeed*1.5)/TICRATE;
|
||||
vel.z += jumpz*0.5;
|
||||
bOnMobj = false;
|
||||
player.jumpTics = -1;
|
||||
if ( !(player.cheats&CF_PREDICTING) )
|
||||
A_PlaySound("*jump",CHAN_BODY);
|
||||
}
|
||||
}
|
||||
Super.CheckJump();
|
||||
}
|
||||
}
|
||||
|
||||
// Random Spawner that passes through dropped status to items
|
||||
|
|
@ -904,6 +999,7 @@ Class UTMainHandler : StaticEventHandler
|
|||
{
|
||||
ui TextureID tex;
|
||||
Array<QueuedFlash> flashes;
|
||||
transient CVar nobosstelefrag;
|
||||
|
||||
override void WorldLoaded( WorldEvent e )
|
||||
{
|
||||
|
|
@ -920,23 +1016,25 @@ Class UTMainHandler : StaticEventHandler
|
|||
|
||||
override void WorldThingSpawned( WorldEvent e )
|
||||
{
|
||||
if ( e.Thing.bBOSS ) e.Thing.bNOTELEFRAG = true;
|
||||
if ( !nobosstelefrag ) nobosstelefrag = CVar.GetCVar('flak_nobosstelefrag');
|
||||
if ( nobosstelefrag.GetBool() && e.Thing.bBOSS ) e.Thing.bNOTELEFRAG = true;
|
||||
}
|
||||
|
||||
ui void StartMenu()
|
||||
{
|
||||
if ( gamestate != GS_TITLELEVEL ) return;
|
||||
int proto = CVar.GetCVar('flak_protomenu',players[consoleplayer]).GetInt();
|
||||
if ( proto )
|
||||
{
|
||||
tex = TexMan.CheckForTexture("protobg",TexMan.Type_Any);
|
||||
if ( gamestate != GS_TITLELEVEL ) return;
|
||||
if ( proto > 1 ) S_ChangeMusic("menu2");
|
||||
else S_ChangeMusic("xyzdMenu");
|
||||
tex = TexMan.CheckForTexture("protobg",TexMan.Type_Any);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_ChangeMusic("utmenu23");
|
||||
tex = TexMan.CheckForTexture("finalbg",TexMan.Type_Any);
|
||||
if ( gamestate != GS_TITLELEVEL ) return;
|
||||
S_ChangeMusic("utmenu23");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -995,7 +1093,7 @@ Class UTMainHandler : StaticEventHandler
|
|||
|
||||
override void RenderOverlay( RenderEvent e )
|
||||
{
|
||||
if ( gamestate != GS_TITLELEVEL ) return;
|
||||
if ( !menuactive ) return;
|
||||
if ( tex.IsNull() || !tex.IsValid() ) return;
|
||||
if ( !CVar.GetCVar('flak_showmenu',players[consoleplayer]).GetBool() ) return;
|
||||
Screen.Dim("Black",1.0,0,0,Screen.GetWidth(),Screen.GetHeight());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue