Add separate player classes for separate sounds and whatnot.

Fully implement UT movement for all modes (walk, swim, fly).
This commit is contained in:
Marisa the Magician 2018-12-28 19:10:35 +01:00
commit 35ee056d7a
20 changed files with 321 additions and 84 deletions

View file

@ -11,14 +11,29 @@ Class UTPlayer : DoomPlayer
int last_tap_fm, last_tap_sm;
int last_jump_held;
int dolltype;
Property DollType : dolltype;
enum EDollType
{
DOLL_Male,
DOLL_Female,
DOLL_Boss
};
const groundspeed = 400.;
const swimspeed = 200.;
const baseaccelrate = 2048.;
const walkfactor = 0.3;
const utaircontrol = 0.35;
const swimspeed_doomish = 400.;
const groundspeed_doomish = 600.;
const terminalvelocity = 2500.;
const dodgez = 210.;
const utjumpz = 325.;
const groundfriction = 8.;
const fluidfriction = 1.2;
const terminalvelocity = 2500.;
Default
{
@ -28,6 +43,12 @@ Class UTPlayer : DoomPlayer
Player.DamageScreenColor "FF 00 00";
Player.ViewHeight 46;
Player.GruntSpeed 20;
MaxDropoffHeight 18;
MaxStepHeight 18;
+NOFRICTION;
+NOFRICTIONBOUNCE;
+NOMENU;
UTPlayer.DollType DOLL_Male;
}
// Have to modify the give cheat to handle UT armor
@ -188,7 +209,7 @@ Class UTPlayer : DoomPlayer
if ( !footsteps.GetBool() ) return;
double ang = level.time/(20*TICRATE/35.)*360.;
bool forcefootstep = false;
if ( player.onground && !bNoGravity && !lastground && (waterlevel < 3) )
if ( player.onground && !bNoGravity && !lastground && (waterlevel < 2) )
{
player.jumptics = 0;
if ( lastvelz < -8 )
@ -199,16 +220,17 @@ Class UTPlayer : DoomPlayer
}
else forcefootstep = true;
}
if ( forcefootstep || ((abs(sin(ang)) >= 1.0) && player.onground && lastground && (player.jumptics == 0) && (player.cmd.forwardmove || player.cmd.sidemove) && (waterlevel < 3)) )
if ( forcefootstep || ((abs(sin(ang)) >= 1.0) && player.onground && lastground && (player.jumptics == 0) && (player.cmd.forwardmove || player.cmd.sidemove) && (waterlevel < 2)) )
{
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);
else PlayFootstep(vol);
}
lastground = player.onground;
lastvelz = prevvelz;
prevvelz = vel.z;
// TODO exit/entry sounds for water
}
double FrictionToUnreal()
@ -235,7 +257,7 @@ Class UTPlayer : DoomPlayer
else Angle += cmd.yaw*(360./65536.);
player.onground = (pos.z <= floorz) || bOnMobj || bMBFBouncer || (player.cheats & CF_NOCLIP2);
if ( player.onground ) lastgroundtic = gametic;
if ( !player.onground && !bNoGravity && (waterlevel < 3) && (abs(pos.z-floorz) <= maxdropoffheight) && (player.jumptics == 0) )
if ( !player.onground && !bNoGravity && (waterlevel < 2) && (abs(pos.z-floorz) <= maxdropoffheight) && (player.jumptics == 0) && (vel.z < 0) )
{
SetOrigin(Vec2OffsetZ(0,0,floorz),true);
player.onground = true;
@ -277,7 +299,7 @@ Class UTPlayer : DoomPlayer
}
}
last_sm = sm;
if ( !bNoGravity && player.onground && (waterlevel < 3) )
if ( !bNoGravity && player.onground && (waterlevel < 2) )
{
if ( dodge.length() > 0 )
{
@ -329,7 +351,7 @@ Class UTPlayer : DoomPlayer
player.vel = vel.xy;
}
}
else if ( !bNoGravity && (waterlevel < 3) )
else if ( !bNoGravity && (waterlevel < 2) )
{
// air acceleration when falling
float maxaccel = accelrate/TICRATE;
@ -348,6 +370,7 @@ Class UTPlayer : DoomPlayer
double maxvel;
if ( flak_doomspeed ) maxvel = (groundspeed_doomish*fs)/TICRATE;
else maxvel = (groundspeed*fs)/TICRATE;
// TODO attempt to replicate walk on ice velocity increase glitch
// if new velocity is higher than ground speed, steer but don't increase it
if ( (vel.xy+acceleration/TICRATE).length() > maxvel )
{
@ -359,41 +382,70 @@ Class UTPlayer : DoomPlayer
player.vel *= 0;
player.jumptics = -2;
}
else if ( bFly || (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_Matrix4.GetAxes(pitch,angle,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 *= 0;
player.jumptics = -2;
if ( !(player.cheats & CF_PREDICTING) ) PlayIdle();
}
else
{
// 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) )
// 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_Matrix4.GetAxes(pitch,angle,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 )
{
fm *= player.crouchfactor;
sm *= player.crouchfactor;
bobfactor *= player.crouchfactor;
Vector3 oldvel = vel;
vel = vel-(2*dir)*vel.length()*friction/TICRATE;
if ( oldvel dot vel < 0.0 ) vel *= 0;
}
forwardmove = fm*movefactor*(35/TICRATE);
sidemove = sm*movefactor*(35/TICRATE);
if ( forwardmove )
else
{
Bob(Angle, cmd.forwardmove*bobfactor/256.,true);
ForwardThrust(forwardmove,Angle);
Vector3 acceldir = acceleration3.unit();
acceleration3 = acceldir*Min(acceleration3.length(),accelrate/TICRATE);
vel = vel-(dir-acceldir)*vel.length()*friction/TICRATE;
}
if ( sidemove )
vel = vel+acceleration3/TICRATE;
double maxvel;
if ( flak_doomspeed ) maxvel = swimspeed_doomish/TICRATE;
else maxvel = swimspeed/TICRATE;
maxvel *= fs*doomfriction;
if ( vel.length() > maxvel ) vel = vel.unit()*maxvel;
player.vel = vel.xy;
player.jumptics = -2;
if ( !(player.cheats & CF_PREDICTING) )
{
let a = Angle-90;
Bob(a,cmd.sidemove*bobfactor/256.,false);
Thrust(sidemove,a);
if ( acceleration3.length() <= double.epsilon ) PlayIdle();
else PlayRunning();
}
if ( !(player.cheats&CF_PREDICTING) && ((forwardmove != 0) || (sidemove != 0)) )
PlayRunning();
}
if ( player.cheats & CF_REVERTPLEASE )
{
@ -401,6 +453,30 @@ Class UTPlayer : DoomPlayer
player.camera = player.mo;
}
}
override void CheckCrouch( bool totallyfrozen )
{
if ( !flak_utmovement || !player || (player.mo != self) )
{
Super.CheckCrouch(totallyfrozen);
return;
}
if ( player.cmd.buttons&BT_JUMP ) player.cmd.buttons &= ~BT_CROUCH;
if ( CanCrouch() && (player.health > 0) && level.IsCrouchingAllowed() && player.onground ) // in UT you can't crouch unless you're on the ground
{
if ( !totallyfrozen )
{
int crouchdir = player.crouching;
if ( !crouchdir ) crouchdir = (player.cmd.buttons&BT_CROUCH)?-1:1;
else if ( player.cmd.buttons&BT_CROUCH ) player.crouching = 0;
if ( (crouchdir == 1) && (player.crouchfactor < 1) && (pos.Z+height < ceilingz) )
CrouchMove(1);
else if ( (crouchdir == -1) && (player.crouchfactor > 0.5 ))
CrouchMove(-1);
}
}
else player.Uncrouch();
player.crouchoffset = -(ViewHeight)*(1-player.crouchfactor);
}
override void CheckJump()
{
if ( !flak_utmovement || !player || (player.mo != self) )
@ -411,9 +487,7 @@ Class UTPlayer : DoomPlayer
if ( player.cmd.buttons&BT_JUMP )
{
if ( player.crouchoffset ) player.crouching = 1;
else if ( waterlevel >= 2 ) Vel.z = 4*Speed;
else if ( bNoGravity ) Vel.z = 3.;
else if ( level.IsJumpingAllowed() && player.onground && (player.jumpTics == 0) && (last_jump_held < gametic-1) )
else if ( level.IsJumpingAllowed() && player.onground && (player.jumpTics == 0) && (last_jump_held < gametic-1) && !bNoGravity && (waterlevel < 2) && !(player.cheats&(CF_FLY|CF_NOCLIP2)) )
{
double jumpvelz;
if ( flak_doomspeed ) jumpvelz = jumpz;
@ -438,6 +512,76 @@ Class UTPlayer : DoomPlayer
if ( !player.onground || player.jumptics )
last_jump_held = gametic;
}
virtual void PlayFootstep( double vol )
{
A_PlaySound("ut/playerfootstep",CHAN_5,vol);
}
}
// these only exist for sound
// female classes have identical sounds, so they use the same soundclass here
Class UTPlayerTMale1 : UTPlayer
{
Default
{
Player.SoundClass "tmale1";
Player.DisplayName "M Commando";
Player.Portrait "Blake";
-NOMENU;
}
}
Class UTPlayerTMale2 : UTPlayer
{
Default
{
Player.SoundClass "tmale2";
Player.DisplayName "M Soldier";
Player.Portrait "Brock";
-NOMENU;
}
}
Class UTPlayerTFemale1 : UTPlayer
{
Default
{
Player.SoundClass "tfemale";
Player.DisplayName "F Commando";
Player.Portrait "Ivana";
UTPlayer.DollType DOLL_Female;
-NOMENU;
}
}
Class UTPlayerTFemale2 : UTPlayer
{
Default
{
Player.SoundClass "tfemale";
Player.DisplayName "F Soldier";
Player.Portrait "Lauren";
UTPlayer.DollType DOLL_Female;
-NOMENU;
}
}
Class UTPlayerTBoss : UTPlayer
{
transient CVar bossfootsteps;
Default
{
Player.SoundClass "tboss";
Player.DisplayName "Boss";
Player.Portrait "Xan";
UTPlayer.DollType DOLL_Boss;
// should have NOBLOOD, but Xan did bleed in vanilla UT so...
// (this is what gave birth to the theory that Xan was actually Jerl Liandri himself)
-NOMENU;
}
override void PlayFootstep( double vol )
{
if ( !bossfootsteps ) bossfootsteps = CVar.GetCVar('flak_bossfootsteps',players[consoleplayer]);
if ( bossfootsteps.GetBool() ) A_PlaySound("ut/bossfootstep",CHAN_5,vol);
else Super.PlayFootstep(vol);
}
}
Class UTWeapon : Weapon