diff --git a/cvarinfo.txt b/cvarinfo.txt index 12949f1..754624b 100644 --- a/cvarinfo.txt +++ b/cvarinfo.txt @@ -1,24 +1,29 @@ -user int flak_protomenu = 0; -user bool flak_showmenu = true; -server bool flak_pulsereload = false; -server bool flak_enforcerreload = false; -user bool flak_redeemerreadout = true; -user int flak_colorprefs = 2; -user color flak_colorcustom = "00 80 ff"; -user int flak_opacity = 15; // UT's opacity is 1 <-> 16 in steps of 1 (default 15) - // 16 means fully opaque, everything else is just additive with gradually lowering alpha - // status is never fully opaque (clamped under 16) - // currently selected weapon and numbers are fully opaque until 8 opacity (their opacity is bumped by 7 basically) -user bool flak_showweapons = true; // if disabled, frags and ammo are shown centered, with a gap for armor and health -user bool flak_showstatus = true; // if disabled armor and health show on the top right (or center between frags and ammo if weapon display is disabled) -user bool flak_showammo = true; -user bool flak_showfrags = true; -user bool flak_showinfo = true; -user float flak_hudsize = 1.0; // 0.2 <-> 1.0 in steps of 0.2 (default 1.0) -user float flak_weaponsize = 0.8; // 0.2 <-> 1.0 in steps of 0.2 (default 0.8) -user float flak_statussize = 1.0; // 0.5 <-> 1.5 in steps of 0.1 (default 1.0) -user bool flak_footsteps = true; -server bool flak_translocator = false; -user bool flak_noswitchdeemer = true; // don't switch to redeemer when out of ammo -user bool flak_deemershader = false; -server bool flak_classicsshock = false; // classic enhanced shock rifle (no altfire, beams don't have splash damage) +user int flak_protomenu = 0; // version of main menu (0: final, 1: 22x betas, 2: same as 1, but with extended menu music) +user bool flak_showmenu = true; // show the UT main menu background whenever the menu is open +server bool flak_pulsereload = false; // pulsegun can reload (features unused animation from early versions) +server bool flak_enforcerreload = false; // enforcer can reload +user bool flak_redeemerreadout = true; // enable target readout, may cause slowdowns on weak CPUs +user int flak_colorprefs = 2; // 0: team color, 1: player color, 2: custom color +user color flak_colorcustom = "00 80 ff"; // custom hud color +user int flak_opacity = 15; // UT's opacity is 1 <-> 16 in steps of 1 (default 15) + // 16 means fully opaque, everything else is just additive with gradually lowering alpha + // status is never fully opaque (clamped under 16) + // currently selected weapon and numbers are fully opaque until 8 opacity (their opacity is bumped by 7 basically) +user bool flak_showweapons = true; // if disabled, frags and ammo are shown centered, with a gap for armor and health +user bool flak_showstatus = true; // if disabled armor and health show on the top right (or center between frags and ammo if weapon display is disabled) +user bool flak_showammo = true; // show ammo counters +user bool flak_showfrags = true; // show kill/frag count +user bool flak_showinfo = true; // show name of aimed at player in mp (and their health if in coop or same team) +user float flak_hudsize = 1.0; // 0.2 <-> 1.0 in steps of 0.2 (default 1.0) +user float flak_weaponsize = 0.8; // 0.2 <-> 1.0 in steps of 0.2 (default 0.8) +user float flak_statussize = 1.0; // 0.5 <-> 1.5 in steps of 0.1 (default 1.0) +user bool flak_footsteps = true; // players make footstep sounds +server bool flak_translocator = false; // translocator is enabled (hello, sequence breaking) +user bool flak_noswitchdeemer = true; // don't switch to redeemer when out of ammo +user bool flak_deemershader = false; // fancy blur/grain/tint shader +server bool flak_classicsshock = false; // classic enhanced shock rifle (no altfire, beams don't have splash damage) +server bool flak_utmovement = false; // emulate UE1's air/ground movement physics +server bool flak_doomspeed = false; // keep Doomguy run speed when using UT movement +server bool flak_doomaircontrol = false; // keep Doom's limited air control when using UT movement +server bool flak_nobosstelefrag = false; // disable telefragging of boss monsters (useful when translocator is enabled) +server bool flak_nowalkdrop = false; // don't drop off ledges while holding walk key (glitchy) diff --git a/menudef.txt b/menudef.txt index 4e2d10d..e445485 100644 --- a/menudef.txt +++ b/menudef.txt @@ -27,9 +27,17 @@ OptionMenu "UTOptionMenu" Option "No Redeemer Autoswitch", "flak_noswitchdeemer", "YesNo" Option "Classic Enh. Shock Rifle", "flak_classicsshock", "YesNo" StaticText " " + StaticText "Translocator (Potentially Game-Breaking)", "Gold" + Option "Prevent Boss Telefrag", "flak_nobosstelefrag", "YesNo" Option "Enable Translocator", "flak_translocator", "YesNo" Command "Apply Changes", "event refreshtrans" StaticText " " + StaticText "Player Options", "Gold" + Option "Enable UT Movement", "flak_utmovement", "YesNo" + Option "Doom Player Speed", "flak_doomspeed", "YesNo", "flak_utmovement" + Option "Doom Air Control", "flak_doomaircontrol", "YesNo", "flak_utmovement" + Option "Walk Disables Dropoff (Glitchy)", "flak_nowalkdrop", "YesNo", "flak_utmovement" + StaticText " " StaticText "HUD Options", "Gold" Option "Show Weapon Bar", "flak_showweapons", "YesNo" Option "Show Status Doll", "flak_showstatus", "YesNo" diff --git a/sndinfo.txt b/sndinfo.txt index 92965c6..620e361 100644 --- a/sndinfo.txt +++ b/sndinfo.txt @@ -33,7 +33,8 @@ $playeralias player male *pain75 ut/malepain2 $playeralias player male *pain50 ut/malepain3 $playeralias player male *pain25 ut/malepain4 $playeralias player male *grunt ut/malegrunt -$playeralias player male *land ut/land +$playeralias player male *land DSEMPTY +$playeralias player male *uland ut/land $playeralias player male *jump ut/malejump $playeralias player male *usefail ut/malehump $playeralias player male *surface ut/malesurface @@ -74,7 +75,8 @@ $playeralias player female *pain75 ut/femalepain2 $playeralias player female *pain50 ut/femalepain3 $playeralias player female *pain25 ut/femalepain4 $playeralias player female *grunt ut/femalegrunt -$playeralias player female *land ut/land +$playeralias player female *land DSEMPTY +$playeralias player female *uland ut/land $playeralias player female *jump ut/femalejump $playeralias player female *usefail ut/femalegrunt $playeralias player female *surface ut/femalesurf diff --git a/zscript/utcommon.zsc b/zscript/utcommon.zsc index 128ce7e..e4a51a3 100644 --- a/zscript/utcommon.zsc +++ b/zscript/utcommon.zsc @@ -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 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 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());