From e5362f673ae89887e919f061b7fb11f08e028d86 Mon Sep 17 00:00:00 2001 From: Marisa the Magician Date: Wed, 20 Mar 2024 13:45:22 +0100 Subject: [PATCH] Analog player movement toggle, for gamepad users. --- cvarinfo.base | 1 + language.def_menu | 2 ++ language.es_menu | 2 ++ language.version | 4 ++-- menudef.txt | 1 + zscript/player/swwm_player.zsc | 2 ++ zscript/player/swwm_player_anim.zsc | 13 +++++++--- zscript/player/swwm_player_move.zsc | 37 +++++++++++++++++++++++++---- zscript/player/swwm_player_tick.zsc | 3 ++- 9 files changed, 55 insertions(+), 10 deletions(-) diff --git a/cvarinfo.base b/cvarinfo.base index 1fd2d67bb..4e4e96f28 100644 --- a/cvarinfo.base +++ b/cvarinfo.base @@ -83,6 +83,7 @@ nosave int swwm_hudscale0 = 0; // force the "zero minus" scale of the HUD (use nosave int swwm_hudscale1 = 0; // force the "one minus" scale of the HUD (used by healthbars, score numbers) nosave int swwm_hudscale2 = 0; // force the "two minus" scale of the HUD (used by interest points) server bool swwm_altclear = false; // use an alternate, less graphically demanding "All Clear" effect +user bool swwm_analogmove = false; // for gamepad users, player movement is adapted for analog sticks // minimap settings nosave bool swwm_mm_enable = true; // show a minimap on the top right corner of the hud diff --git a/language.def_menu b/language.def_menu index 2b22c4984..aea8358ad 100644 --- a/language.def_menu +++ b/language.def_menu @@ -193,6 +193,7 @@ SWWM_HS_AUTO = "Auto"; SWWM_HS_AUTOL = "Auto Loose"; SWWM_HS_AUTOT = "Auto Tight"; SWWM_ALTCLEAR = "Alternate 100% FX"; +SWWM_ANALOGMOVE = "Analog Movement"; SWWM_MM_ENABLE = "Show Minimap"; SWWM_MM_MISSILES = "Projectiles In Minimap"; SWWM_MM_USECANVAS = "Fixed Scale Minimap"; @@ -285,6 +286,7 @@ TOOLTIP_SWWM_HUDSCALE0 = "If higher than zero, manually set the scale of auxilia TOOLTIP_SWWM_HUDSCALE1 = "If higher than zero, manually set the scale of Healthbars, Score Numbers and Item Sense. Usually, this is one less than the primary HUD scale."; TOOLTIP_SWWM_HUDSCALE2 = "If higher than zero, manually set the scale of Interest Points. Usually, this is two less than the primary HUD scale."; TOOLTIP_SWWM_ALTCLEAR = "Use an alternate, less visually intense effect for getting 100% completion on a level."; +TOOLTIP_SWWM_ANALOGMOVE = "For gamepad users, this is a must. For keyboard and mouse users, this should be disabled."; TOOLTIP_SWWMACHIEVEMENTMENU = "View your achievements."; TOOLTIP_SWWM_MM_ENABLE = "Displays a minimap on the top right corner of the screen."; TOOLTIP_SWWM_MM_MISSILES = "Displays projectiles in the minimap. Can be toggled if this clutters too much."; diff --git a/language.es_menu b/language.es_menu index 6d4aa7d56..79fe0f03d 100644 --- a/language.es_menu +++ b/language.es_menu @@ -187,6 +187,7 @@ SWWM_HUDSCALE2 = "Escala Cuaternaria de HUD"; SWWM_HS_AUTOL = "Auto. Holgado"; SWWM_HS_AUTOT = "Auto. Ceñido"; SWWM_ALTCLEAR = "Efecto Alternativo de 100%"; +SWWM_ANALOGMOVE = "Movimiento Analógico"; SWWM_MM_ENABLE = "Mostrar Minimapa"; SWWM_MM_MISSILES = "Proyectiles en Minimapa"; SWWM_MM_USECANVAS = "Minimapa a Escala Fija"; @@ -280,6 +281,7 @@ TOOLTIP_SWWM_HUDSCALE0 = "Si es mayor que cero, especifica manualmente la escala TOOLTIP_SWWM_HUDSCALE1 = "Si es mayor que cero, especifica manualmente la escala de las Barras de Salud, Números de Puntuación y Sensor de Ítems. Normalmente, es igual a dos menos que la escala primaria del HUD."; TOOLTIP_SWWM_HUDSCALE2 = "Si es mayor que cero, especifica manualmente la escala de los Puntos de Interés. Normalmente, es igual a tres menos que la escala primaria del HUD."; TOOLTIP_SWWM_ALTCLEAR = "Usa un efecto alternativo de menor intensidad visual al completar un nivel al 100%."; +TOOLTIP_SWWM_ANALOGMOVE = "Para usuarios de mando, esto es esencial. Para usuarios de teclado y ratón, esto debería estar desactivado."; TOOLTIP_SWWMACHIEVEMENTMENU = "Revisa tus logros."; TOOLTIP_SWWM_MM_ENABLE = "Muestra un minimapa en la esquina superior derecha de la pantalla."; TOOLTIP_SWWM_MM_MISSILES = "Muestra proyectiles en el minimapa. Puede ser desactivado si causa problemas de visibilidad."; diff --git a/language.version b/language.version index aafda6b2d..f0d691cb2 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r1113 \cu(Wed 20 Mar 13:43:38 CET 2024)\c-"; -SWWM_SHORTVER="\cw1.3pre r1113 \cu(2024-03-20 13:43:38)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r1114 \cu(Wed 20 Mar 13:45:22 CET 2024)\c-"; +SWWM_SHORTVER="\cw1.3pre r1114 \cu(2024-03-20 13:45:22)\c-"; diff --git a/menudef.txt b/menudef.txt index a20cec16f..7a8ec8afa 100644 --- a/menudef.txt +++ b/menudef.txt @@ -120,6 +120,7 @@ OptionMenu "SWWMOptionMenu" Slider "$SWWM_VOICEAMP", "swwm_voiceamp", 1, 4, 1, 0 Option "$SWWM_VOICELOG", "swwm_voicelog", "YesNo" Option "$SWWM_BEEPBOOP", "swwm_beepboop", "YesNo" + Option "$SWWM_ANALOGMOVE", "swwm_analogmove", "YesNo" Option "$SWWM_REVIVE", "swwm_revive", "YesNo" ScaleSliderFix "$SWWM_REVIVECOOLDOWN", "swwm_revivecooldown", -1, 300, 30, "$SWWM_UNLIMITED", "$SWWM_ONERETRY" Submenu "$SWWM_ATITLE", "SWWMAchievementMenu" diff --git a/zscript/player/swwm_player.zsc b/zscript/player/swwm_player.zsc index f3f683358..891e3fc3f 100644 --- a/zscript/player/swwm_player.zsc +++ b/zscript/player/swwm_player.zsc @@ -123,6 +123,8 @@ Class Demolitionist : PlayerPawn double bobtime, oldbobtime, oldbob; + bool isAnalogMoving; + SWWMHandler hnd; Default diff --git a/zscript/player/swwm_player_anim.zsc b/zscript/player/swwm_player_anim.zsc index a1f9dc317..ac917cfcd 100644 --- a/zscript/player/swwm_player_anim.zsc +++ b/zscript/player/swwm_player_anim.zsc @@ -537,9 +537,16 @@ extend Class Demolitionist int FastCheck() { if ( !player ) return 1; - if ( bWalking || (NormalizedMove().length() <= 8000.) ) return 0; // walk - if ( player.cmd.buttons&BT_RUN ) return 2; // sprint - return 1; // walk + if ( isAnalogMoving ) + { + double mscale = NormalizedMove().length(); + if ( mscale < (gameinfo.normforwardmove[0]*256.) ) return 0; // walking + if ( mscale < (gameinfo.normforwardmove[1]*256.) ) return 1; // running + return 2; // sprinting + } + if ( bWalking ) return 0; // walking + if ( isRunning() ) return 2; // sprinting + return 1; // running } State A_FastJump( StateLabel walk = null, StateLabel run = null, StateLabel sprint = null ) diff --git a/zscript/player/swwm_player_move.zsc b/zscript/player/swwm_player_move.zsc index 8a3c2b98d..1425022d9 100644 --- a/zscript/player/swwm_player_move.zsc +++ b/zscript/player/swwm_player_move.zsc @@ -1,6 +1,14 @@ // general movement code extend Class Demolitionist { + bool isRunning() + { + // for analog move, use midpoint between run/sprint + if ( isAnalogMoving ) + return (NormalizedMove().length() >= (gameinfo.normforwardmove[1]*256.)); + return !!(player.cmd.buttons&BT_RUN); + } + // directional movement without straferunning Vector2 NormalizedMove() { @@ -11,13 +19,34 @@ extend Class Demolitionist double fs = gameinfo.normforwardmove[idx]/gameinfo.normsidemove[idx]; // raw axes scaled to 1:1 ratio Vector2 mvec = (player.cmd.forwardmove,-player.cmd.sidemove*fs); + // should we use raw analog movement? + if ( isAnalogMoving ) + { + // straferun cap (lol sorry) + if ( mvec.length() > gameinfo.normforwardmove[idx]*256. ) + mvec = mvec.unit()*gameinfo.normforwardmove[idx]*256.; + return mvec; // passed as-is otherwise + } // multiply unit vector back to "raw" running speed (as TweakSpeed handles the "true" scaling for us later) return mvec.unit()*gameinfo.normforwardmove[1]*256.; } double TweakSpeed() { - double fact = bWalking?.08:(player.cmd.buttons&BT_RUN)?1.1:.4; + double fact; + // when analog moving, lerp between factors (should feel ok?) + if ( isAnalogMoving ) + { + double mscale = NormalizedMove().length(); + double rspeed = gameinfo.normforwardmove[0]*256.; + double sspeed = gameinfo.normforwardmove[1]*256.; + if ( mscale < rspeed ) // between walking/running + fact = SWWMUtility.MapRange(0,rspeed,.08,.4,mscale); + else if ( mscale < sspeed ) // between running/sprinting + fact = SWWMUtility.MapRange(rspeed,sspeed,.4,1.1,mscale); + else fact = 1.1; // sprinting + } + else fact = bWalking?.08:(player.cmd.buttons&BT_RUN)?1.1:.4; for ( Inventory i=Inv; i; i=i.Inv ) fact *= i.GetSpeedFactor(); return fact; } @@ -111,7 +140,7 @@ extend Class Demolitionist if ( m != n ) { int side = (sin(bobtime*180.)>0.)?1:-1; - int spd = bWalking?0:(player.cmd.buttons&BT_RUN)?2:1; + int spd = bWalking?0:isRunning()?2:1; PlayFootstep(side,spd); } } @@ -622,7 +651,7 @@ extend Class Demolitionist // bhop, z vel relative to vel size if ( vel.z < 25. ) // don't ramp up too hard { - vel.z += jumpvelz*(((player.cmd.buttons&BT_RUN)?1.2:.65)+vel.length()*.01); + vel.z += jumpvelz*((isRunning()?1.2:.65)+vel.length()*.01); // add part of last landing z velocity too vel.z += max(0,-landvelz*(raging?.45:.35)); } @@ -634,7 +663,7 @@ extend Class Demolitionist // first jump if ( vel.z < 10. ) // don't ramp up too hard { - vel.z += jumpvelz*(bWalking?.75:(player.cmd.buttons&BT_RUN)?1.25:1.); + vel.z += jumpvelz*(bWalking?.75:isRunning()?1.25:1.); // add part of last landing z velocity too vel.z += max(0,-landvelz*(raging?.35:.25)); } diff --git a/zscript/player/swwm_player_tick.zsc b/zscript/player/swwm_player_tick.zsc index 79aa7ffec..a0a7709e0 100644 --- a/zscript/player/swwm_player_tick.zsc +++ b/zscript/player/swwm_player_tick.zsc @@ -206,6 +206,7 @@ extend Class Demolitionist if ( !TryMove(pos.xy,false) ) SetZ(oldz); } if ( (gamestate != GS_LEVEL) || !player || (player.mo != self) || (freezetics > 0) ) return; + isAnalogMoving = CVar.GetCVar('swwm_analogmove',player).GetBool(); UpdateFace(); UpdateTags(); if ( !hnd ) hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); @@ -347,7 +348,7 @@ extend Class Demolitionist if ( FindInventory("RagekitPower") ) { // stop for just a split second UNLESS bunnyhopping - if ( !(player.cmd.buttons&BT_RUN) || (level.maptime >= (lastairtic+10)) ) + if ( !isRunning() || (level.maptime >= (lastairtic+10)) ) ReactionTime = 6; } else