From be9aba89ae3902cb7c5afb50d3454c2552500e77 Mon Sep 17 00:00:00 2001 From: Marisa the Magician Date: Sun, 29 May 2022 17:51:59 +0200 Subject: [PATCH] Add "smooth streaks" to projected crosshairs. --- language.version | 4 +-- zscript/swwm_gesture.zsc | 32 +++++++++++++++++++ zscript/utility/swwm_utility.zsc | 5 +++ .../weapons/swwm_baseweapon_precisechair.zsc | 12 ++++--- zscript/weapons/swwm_cbt.zsc | 13 +++++--- zscript/weapons/swwm_splode.zsc | 1 + 6 files changed, 55 insertions(+), 12 deletions(-) diff --git a/language.version b/language.version index 72b0b8c01..69129aaa5 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.2.20 r3 \cu(Wed 1 Jun 18:30:53 CEST 2022)\c-"; -SWWM_SHORTVER="\cw1.2.20 r3 \cu(2022-06-01 18:30:53)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.2.20 r4 \cu(Wed 1 Jun 18:31:07 CEST 2022)\c-"; +SWWM_SHORTVER="\cw1.2.20 r4 \cu(2022-06-01 18:31:07)\c-"; diff --git a/zscript/swwm_gesture.zsc b/zscript/swwm_gesture.zsc index cfeae5eac..ed6966035 100644 --- a/zscript/swwm_gesture.zsc +++ b/zscript/swwm_gesture.zsc @@ -45,6 +45,27 @@ Class SWWMGesture : SWWMWeapon { return false; } + override void HUDTick() + { + if ( !Owner ) return; + [cpos, ccol] = TraceForCrosshair(); + // avoid jumpy switching + if ( formerweapon is 'SWWMWeapon' ) + { + SWWMWeapon(formerweapon).lagvpos = lagvpos; + SWWMWeapon(formerweapon).prevframe = prevframe; + } + } + override void RenderUnderlay( RenderEvent e ) + { + Super.RenderUnderlay(e); + // avoid jumpy switching + if ( formerweapon is 'SWWMWeapon' ) + { + SWWMWeapon(formerweapon).lagvpos = lagvpos; + SWWMWeapon(formerweapon).prevframe = prevframe; + } + } override void DoEffect() { Super.DoEffect(); @@ -651,6 +672,17 @@ Class SWWMItemGesture : SWWMWeapon abstract { return false; } + override void HUDTick() + { + if ( !Owner ) return; + [cpos, ccol] = TraceForCrosshair(); + // avoid jumpy switching + if ( gest && (gest.formerweapon is 'SWWMWeapon') ) + { + SWWMWeapon(gest.formerweapon).lagvpos = lagvpos; + SWWMWeapon(gest.formerweapon).prevframe = prevframe; + } + } override void DoEffect() { Super.DoEffect(); diff --git a/zscript/utility/swwm_utility.zsc b/zscript/utility/swwm_utility.zsc index 5e36d1733..17eacece6 100644 --- a/zscript/utility/swwm_utility.zsc +++ b/zscript/utility/swwm_utility.zsc @@ -229,6 +229,11 @@ Class SWWMUtility return (a<0)?(a+floor(a)):(a-floor(a)); } + static clearscope double lerp( double a, double b, double theta ) + { + return a*(1.-theta)+b*theta; + } + static clearscope Color LerpColor( Color a, Color b, double theta ) { Color c = Color( diff --git a/zscript/weapons/swwm_baseweapon_precisechair.zsc b/zscript/weapons/swwm_baseweapon_precisechair.zsc index ce58febf7..044a4ab15 100644 --- a/zscript/weapons/swwm_baseweapon_precisechair.zsc +++ b/zscript/weapons/swwm_baseweapon_precisechair.zsc @@ -46,7 +46,6 @@ extend Class SWWMWeapon // avoid jumpy switching if ( Owner.player.PendingWeapon is 'SWWMWeapon' ) { - SWWMWeapon(Owner.player.PendingWeapon).cpos = cpos; SWWMWeapon(Owner.player.PendingWeapon).lagvpos = lagvpos; SWWMWeapon(Owner.player.PendingWeapon).prevframe = prevframe; } @@ -67,11 +66,12 @@ extend Class SWWMWeapon Vector3 ndc = SWWMUtility.ProjectPoint(sb.projdata,e.ViewPos+tdir); if ( ndc.z >= 1. ) return; Vector2 vpos = SWWMUtility.NDCToViewport(sb.projdata,ndc); - double frametime = ((gametic+e.fractic)-prevframe)/GameTicRate; - double theta = clamp(30.*frametime,0.,1.); // naive, but whatever - if ( !prevframe || (lagvpos == (0,0)) ) lagvpos = vpos; + double frametime = (MSTimeF()-prevframe)/1000.; + double theta = clamp(15.*frametime,0.,1.); // naive, but whatever + Vector2 oldvpos = lagvpos; + if ( !prevframe || (lagvpos == (0,0)) ) oldvpos = lagvpos = vpos; else lagvpos = lagvpos*(1.-theta)+vpos*theta; - prevframe = gametic+e.fractic; + prevframe = MSTimeF(); int cnum = abs(CVar.FindCVar('crosshair').GetInt()); if ( !cnum ) return; String tn = String.Format("XHAIR%s%d",(Screen.GetWidth()<640)?"S":"B",cnum); @@ -83,6 +83,8 @@ extend Class SWWMWeapon double sz = 1.; if ( cs > 0. ) sz = Screen.GetHeight()*cs/200.; if ( crosshairgrow ) sz *= sb.CrosshairSize; + int streak = int(max(abs(oldvpos.x-lagvpos.x),abs(oldvpos.y-lagvpos.y))); + for ( int i=0; i= 1. ) return; Vector2 vpos = SWWMUtility.NDCToViewport(sb.projdata,ndc); - double frametime = ((gametic+e.fractic)-prevframe)/GameTicRate; - double theta = clamp(30.*frametime,0.,1.); // naive, but whatever + double frametime = (MSTimeF()-prevframe)/1000.; + double theta = clamp(15.*frametime,0.,1.); // naive, but whatever if ( !prevframe || (lagvpos == (0,0)) ) lagvpos = vpos; else lagvpos = lagvpos*(1.-theta)+vpos*theta; + Vector2 oldvpos; for ( int i=0; i<25; i++ ) { - tdir = level.Vec3Diff(e.ViewPos,cpos25[i]); // project ndc = SWWMUtility.ProjectPoint(sb.projdata,e.ViewPos+tdir); if ( ndc.z >= 1. ) return; vpos = SWWMUtility.NDCToViewport(sb.projdata,ndc); - if ( !prevframe || (lagvpos25[i] == (0,0)) ) lagvpos25[i] = vpos; + oldvpos = lagvpos25[i]; + if ( !prevframe || (lagvpos25[i] == (0,0)) ) oldvpos = lagvpos25[i] = vpos; else lagvpos25[i] = lagvpos25[i]*(1.-theta)+vpos*theta; + int streak = int(max(abs(oldvpos.x-lagvpos25[i].x),abs(oldvpos.y-lagvpos25[i].y))); + for ( int j=0; j