From 84fb9c036f29193e6925c9408e974fc755acd3fe Mon Sep 17 00:00:00 2001 From: Marisa the Magician Date: Sat, 24 Sep 2022 21:33:48 +0200 Subject: [PATCH] Decouple precise crosshairs from weapons. 100% smoother now. --- language.version | 4 +- zscript.txt | 1 + zscript/dlc1/swwm_blastin.zsc | 1 + zscript/dlc1/swwm_heavymahsheengun.zsc | 2 +- zscript/dlc1/swwm_mister.zsc | 2 +- zscript/dlc1/swwm_notashotgun.zsc | 2 +- zscript/handler/swwm_handler_crosshair.zsc | 154 ++++++++++++++++++ zscript/swwm_gesture.zsc | 20 --- zscript/swwm_handler.zsc | 2 + zscript/weapons/swwm_baseweapon.zsc | 4 + .../weapons/swwm_baseweapon_precisechair.zsc | 120 +------------- zscript/weapons/swwm_blazeit.zsc | 2 +- zscript/weapons/swwm_cbt.zsc | 124 +------------- zscript/weapons/swwm_danmaku.zsc | 2 +- zscript/weapons/swwm_deathlydeathcannon.zsc | 2 +- zscript/weapons/swwm_deepdarkimpact.zsc | 2 +- zscript/weapons/swwm_shot.zsc | 2 +- zscript/weapons/swwm_sparkyboi.zsc | 2 +- zscript/weapons/swwm_splode.zsc | 15 +- zscript/weapons/swwm_tastytreat.zsc | 2 +- zscript/weapons/swwm_thiccboolet.zsc | 2 +- 21 files changed, 196 insertions(+), 271 deletions(-) create mode 100644 zscript/handler/swwm_handler_crosshair.zsc diff --git a/language.version b/language.version index faeaac7c4..326b7f792 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r502 \cu(Sat 24 Sep 14:56:35 CEST 2022)\c-"; -SWWM_SHORTVER="\cw1.3pre r502 \cu(2022-09-24 14:56:35)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r503 \cu(Sat 24 Sep 21:33:48 CEST 2022)\c-"; +SWWM_SHORTVER="\cw1.3pre r503 \cu(2022-09-24 21:33:48)\c-"; diff --git a/zscript.txt b/zscript.txt index 90d42fb69..f5970cad4 100644 --- a/zscript.txt +++ b/zscript.txt @@ -29,6 +29,7 @@ version "4.9" #include "zscript/swwm_blod.zsc" // handler code #include "zscript/handler/swwm_handler_cheats.zsc" +#include "zscript/handler/swwm_handler_crosshair.zsc" #include "zscript/handler/swwm_handler_damage.zsc" #include "zscript/handler/swwm_handler_debugrender.zsc" #include "zscript/handler/swwm_handler_flash.zsc" diff --git a/zscript/dlc1/swwm_blastin.zsc b/zscript/dlc1/swwm_blastin.zsc index bdb8c74d6..81c99d703 100644 --- a/zscript/dlc1/swwm_blastin.zsc +++ b/zscript/dlc1/swwm_blastin.zsc @@ -44,6 +44,7 @@ Class DualPlasmaBlast : SWWMWeapon Obituary "$O_PLASMABLAST"; SWWMWeapon.Tooltip "$TT_PLASMABLAST2"; SWWMWeapon.GetLine "getplasmablast2"; + SWWMWeapon.NumCrosshairs 2; Weapon.SlotNumber 2; Weapon.SlotPriority 4.; Weapon.SelectionOrder 1050; diff --git a/zscript/dlc1/swwm_heavymahsheengun.zsc b/zscript/dlc1/swwm_heavymahsheengun.zsc index 6e9d5fef6..1391f6222 100644 --- a/zscript/dlc1/swwm_heavymahsheengun.zsc +++ b/zscript/dlc1/swwm_heavymahsheengun.zsc @@ -45,7 +45,7 @@ Class HeavyMahSheenGun : SWWMWeapon c.vel += vel*.5; } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { return (10,0,-4); } diff --git a/zscript/dlc1/swwm_mister.zsc b/zscript/dlc1/swwm_mister.zsc index 02324c877..b0b66eaf6 100644 --- a/zscript/dlc1/swwm_mister.zsc +++ b/zscript/dlc1/swwm_mister.zsc @@ -200,7 +200,7 @@ Class MisterRifle : SWWMWeapon lastfiremode = firemode+1; } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { return (10,2.8,-2.4); } diff --git a/zscript/dlc1/swwm_notashotgun.zsc b/zscript/dlc1/swwm_notashotgun.zsc index 458f95d4d..27c6d78e6 100644 --- a/zscript/dlc1/swwm_notashotgun.zsc +++ b/zscript/dlc1/swwm_notashotgun.zsc @@ -35,7 +35,7 @@ Class Quadravol : SWWMWeapon else origin.A_StartSound(UpSound,CHAN_WEAPON,CHANF_OVERLAP); } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { return onehand?(10,3.5,-2):(10,3,-2.5); } diff --git a/zscript/handler/swwm_handler_crosshair.zsc b/zscript/handler/swwm_handler_crosshair.zsc new file mode 100644 index 000000000..9c536207c --- /dev/null +++ b/zscript/handler/swwm_handler_crosshair.zsc @@ -0,0 +1,154 @@ +// precise crosshair (now fully independent from weapons) + +const MAX_CROSSHAIRS = 25; + +Class SWWMCrosshairTracer : LineTracer +{ + Actor ignoreme; + + override ETraceStatus TraceCallback() + { + if ( Results.HitType == TRACE_HitActor ) + { + if ( Results.HitActor == ignoreme ) return TRACE_Skip; + if ( Results.HitActor.bSHOOTABLE ) return TRACE_Stop; + return TRACE_Skip; + } + else if ( (Results.HitType == TRACE_HitWall) && (Results.Tier == TIER_Middle) ) + { + if ( !Results.HitLine.sidedef[1] || (Results.HitLine.Flags&(Line.ML_BlockHitscan|Line.ML_BlockEverything)) ) + return TRACE_Stop; + return TRACE_Skip; + } + return TRACE_Stop; + } +} + +extend Class SWWMHandler +{ + transient ui SWWMCrosshairTracer ctr; // very simple crosshair tracer + transient ui int numcrosshairs; // how many crosshairs the current weapon has + transient ui Vector3 tpos[MAX_CROSSHAIRS]; // current trace positions in world space + transient ui Color tcol[MAX_CROSSHAIRS]; // current crosshair colors + transient ui SWWMProjectionData tprojdata; // cached Gutamatics projection data + transient ui Vector3 lagtndc[MAX_CROSSHAIRS]; // "lagged" NDC for crosshairs + transient ui Weapon lasttw; // last player weapon, to "reset" crosshair positions + transient ui double prevframe; // previous frame timestamp + + private ui void TraceCrosshairs( RenderEvent e ) + { + // trace precise crosshair(s) + Vector3 traceofs[MAX_CROSSHAIRS]; + let sw = SWWMWeapon(players[consoleplayer].ReadyWeapon); + if ( !sw ) + { + numcrosshairs = 1; + traceofs[0] = (0,0,0); + } + else + { + numcrosshairs = sw.NumCrosshairs; + for ( int i=0; i= 2 ) + { + int hp = Clamp(mo.Health,0,200); + double sat = (hp<150)?1.:(1.-(hp-150)/100.); + Vector3 rgb = SWWMUtility.HSVtoRGB((hp/300.,sat,1.)); + col = Color(int(rgb.x*255),int(rgb.y*255),int(rgb.z*255)); + } + else if ( chp == 1 ) + { + double hp = Clamp(mo.Health,0,100)/100.; + if ( hp <= 0 ) col = Color(255,0,0); + else if ( hp < .3 ) col = Color(255,int(hp*255/.3),0); + else if ( hp < .85 ) col = Color(int((.6-hp)*255/.3),255,0); + else col = Color(0,255,0); + } + else if ( (ctr.Results.HitType == TRACE_HitActor) && ctr.Results.HitActor.bSHOOTABLE ) + { + // show target health, rather than our own + double hp = ctr.Results.HitActor.Health/double(ctr.Results.HitActor.GetSpawnHealth()); + if ( hp <= 0 ) col = Color(255,0,0); + else if ( hp < .3 ) col = Color(255,int(hp*255/.3),0); + else if ( hp < .85 ) col = Color(int((.6-hp)*255/.3),255,0); + else col = Color(0,255,0); + } + else col = crosshaircolor; + if ( ctr.Results.HitType == TRACE_HitNone ) tpos[i] = level.Vec3Offset(origin,x*10000.); + else tpos[i] = ctr.Results.HitPos; + tcol[i] = col; + } + // copy over used slots to unused slots, so transition between weapons is smoother + int j = 0; + for ( int i=numcrosshairs; i 0. ) sz = Screen.GetHeight()*cs/200.; + if ( crosshairgrow ) sz *= StatusBar.CrosshairSize; + SWWMUtility.PrepareProjData(tprojdata,e.ViewPos,e.ViewAngle,e.ViewPitch,e.ViewRoll,players[consoleplayer].fov); + let w = players[consoleplayer].ReadyWeapon; + for ( int i=0; i= 1. ) continue; + Vector2 vpos = SWWMUtility.NDCToViewport(tprojdata,ndc); + if ( !prevframe ) lagtndc[i] = ndc; + if ( lagtndc[i].z >= 1. ) continue; + Vector2 oldvpos = SWWMUtility.NDCToViewport(tprojdata,lagtndc[i]); + lagtndc[i] = SWWMUtility.LerpVector3(lagtndc[i],ndc,theta); + if ( lagtndc[i].z >= 1. ) continue; + Vector2 lagvpos = SWWMUtility.NDCToViewport(tprojdata,lagtndc[i]); + 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 = (MSTimeF()-prevframe)/1000.; - double theta = clamp(15.*frametime,0.,.5); // naive, but whatever - Vector2 oldvpos = lagvpos; - if ( !prevframe || (lagvpos == (0,0)) ) oldvpos = lagvpos = vpos; - else lagvpos = SWWMUtility.LerpVector2(lagvpos,vpos,theta); - 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); - TextureID ctex = TexMan.CheckForTexture(tn,TexMan.Type_MiscPatch); - if ( !ctex.IsValid() ) ctex = TexMan.CheckForTexture(String.Format("XHAIR%s1",(Screen.GetWidth()<640)?"S":"B"),TexMan.Type_MiscPatch); - if ( !ctex.IsValid() ) ctex = TexMan.CheckForTexture("XHAIRS1",TexMan.Type_MiscPatch); - Vector2 ts = TexMan.GetScaledSize(ctex); - double cs = crosshairscale; - 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= 2 ) - { - int hp = Clamp(Owner.Health,0,200); - double sat = (hp<150)?1.:(1.-(hp-150)/100.); - Vector3 rgb = SWWMUtility.HSVtoRGB((hp/300.,sat,1.)); - col = Color(int(rgb.x*255),int(rgb.y*255),int(rgb.z*255)); - } - else if ( chp == 1 ) - { - double hp = Clamp(Owner.Health,0,100)/100.; - if ( hp <= 0 ) col = Color(255,0,0); - else if ( hp < .3 ) col = Color(255,int(hp*255/.3),0); - else if ( hp < .85 ) col = Color(int((.6-hp)*255/.3),255,0); - else col = Color(0,255,0); - } - else if ( (ctr.Results.HitType == TRACE_HitActor) && ctr.Results.HitActor.bSHOOTABLE ) - { - // show target health, rather than our own - double hp = ctr.Results.HitActor.Health/double(ctr.Results.HitActor.GetSpawnHealth()); - if ( hp <= 0 ) col = Color(255,0,0); - else if ( hp < .3 ) col = Color(255,int(hp*255/.3),0); - else if ( hp < .85 ) col = Color(int((.6-hp)*255/.3),255,0); - else col = Color(0,255,0); - } - if ( ctr.Results.HitType == TRACE_HitNone ) return level.Vec3Offset(origin,x*10000.), col; - else return ctr.Results.HitPos, col; - } // where the trace is coming from relative to eyes - virtual clearscope Vector3 GetTraceOffset() const + virtual clearscope Vector3 GetTraceOffset( int index ) const { return (0.,0.,0.); } diff --git a/zscript/weapons/swwm_blazeit.zsc b/zscript/weapons/swwm_blazeit.zsc index c254fd9d3..a997a1be3 100644 --- a/zscript/weapons/swwm_blazeit.zsc +++ b/zscript/weapons/swwm_blazeit.zsc @@ -155,7 +155,7 @@ Class Hellblazer : SWWMWeapon lastammo = nextammo; } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { return (10.,3.5,-5.); } diff --git a/zscript/weapons/swwm_cbt.zsc b/zscript/weapons/swwm_cbt.zsc index 11a2eb705..5e00f2e4c 100644 --- a/zscript/weapons/swwm_cbt.zsc +++ b/zscript/weapons/swwm_cbt.zsc @@ -15,8 +15,6 @@ Class Wallbuster : SWWMWeapon Class curobt; - ui Vector2 lagvpos25[25]; - override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack ) { if ( curobt is 'RedShell' ) return StringTable.Localize("$O_WALLBUSTER_RED"); @@ -40,118 +38,6 @@ Class Wallbuster : SWWMWeapon SelectionOrder = 1400; } - override void RenderUnderlay( RenderEvent e ) - { - Vector3 cpos; - Color ccol; - [cpos, ccol] = TraceForCrosshair(); - // avoid jumpy switching - if ( Owner.player.PendingWeapon is 'SWWMWeapon' ) - { - SWWMWeapon(Owner.player.PendingWeapon).lagvpos = lagvpos; - SWWMWeapon(Owner.player.PendingWeapon).prevframe = prevframe; - } - Vector3 cpos25[25]; - Color ccol25[25]; - // 25-trace - for ( int i=0; i<25; i++ ) - [cpos25[i], ccol25[i]] = TraceForCrosshair25(i); - // draw custom crosshair - if ( automapactive || !(players[consoleplayer].Camera is 'PlayerPawn') ) return; - if ( !swwm_precisecrosshair ) return; - if ( crosshairforce ) return; - if ( !crosshairon && (swwm_precisecrosshair <= 1) ) return; - let sb = SWWMStatusBar(StatusBar); - if ( !sb ) return; - SWWMUtility.PrepareProjData(sb.projdata,e.ViewPos,e.ViewAngle,e.ViewPitch,e.ViewRoll,players[consoleplayer].fov); - int cnum = abs(CVar.FindCVar('crosshair').GetInt()); - if ( !cnum ) return; - String tn = String.Format("XHAIR%s%d",(Screen.GetWidth()<640)?"S":"B",cnum); - TextureID ctex = TexMan.CheckForTexture(tn,TexMan.Type_MiscPatch); - if ( !ctex.IsValid() ) ctex = TexMan.CheckForTexture(String.Format("XHAIR%s1",(Screen.GetWidth()<640)?"S":"B"),TexMan.Type_MiscPatch); - if ( !ctex.IsValid() ) ctex = TexMan.CheckForTexture("XHAIRS1",TexMan.Type_MiscPatch); - Vector2 ts = TexMan.GetScaledSize(ctex); - double cs = crosshairscale; - double sz = 1.; - if ( cs > 0. ) sz = Screen.GetHeight()*cs/200.; - if ( crosshairgrow ) sz *= sb.CrosshairSize; - Vector3 tdir = level.Vec3Diff(e.ViewPos,cpos); - // project - Vector3 ndc = SWWMUtility.ProjectPoint(sb.projdata,e.ViewPos+tdir); - if ( ndc.z >= 1. ) return; - Vector2 vpos = SWWMUtility.NDCToViewport(sb.projdata,ndc); - double frametime = (MSTimeF()-prevframe)/1000.; - double theta = clamp(15.*frametime,0.,1.); // naive, but whatever - if ( !prevframe || (lagvpos == (0,0)) ) lagvpos = vpos; - else lagvpos = SWWMUtility.LerpVector2(lagvpos,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. ) continue; - vpos = SWWMUtility.NDCToViewport(sb.projdata,ndc); - oldvpos = lagvpos25[i]; - if ( !prevframe || (lagvpos25[i] == (0,0)) ) oldvpos = lagvpos25[i] = vpos; - else lagvpos25[i] = SWWMUtility.LerpVector2(lagvpos25[i],vpos,theta); - int streak = int(max(abs(oldvpos.x-lagvpos25[i].x),abs(oldvpos.y-lagvpos25[i].y))); - for ( int j=0; j= 2 ) - { - int hp = Clamp(Owner.Health,0,200); - double sat = (hp<150)?1.:(1.-(hp-150)/100.); - Vector3 rgb = SWWMUtility.HSVtoRGB((hp/300.,sat,1.)); - col = Color(int(rgb.x*255),int(rgb.y*255),int(rgb.z*255)); - } - else if ( chp == 1 ) - { - double hp = Clamp(Owner.Health,0,100)/100.; - if ( hp <= 0 ) col = Color(255,0,0); - else if ( hp < .3 ) col = Color(255,int(hp*255/.3),0); - else if ( hp < .85 ) col = Color(int((.6-hp)*255/.3),255,0); - else col = Color(0,255,0); - } - else if ( (ctr.Results.HitType == TRACE_HitActor) && ctr.Results.HitActor.bSHOOTABLE ) - { - // show target health, rather than our own - double hp = ctr.Results.HitActor.Health/double(ctr.Results.HitActor.GetSpawnHealth()); - if ( hp <= 0 ) col = Color(255,0,0); - else if ( hp < .3 ) col = Color(255,int(hp*255/.3),0); - else if ( hp < .85 ) col = Color(int((.6-hp)*255/.3),255,0); - else col = Color(0,255,0); - } - if ( ctr.Results.HitType == TRACE_HitNone ) return level.Vec3Offset(origin,x*10000.), col; - else return ctr.Results.HitPos, col; - } - - clearscope Vector3 GetTraceOffset25( int i ) const - { - double t1 = 90-int(i%5)*72; - double t2 = 360-int(i/5)*72; - Vector2 b = AngleToVector(t1,1.2); - b.y += 3.; - Vector2 n = RotateVector(b,t2); - return (10.,3.5+n.x,-6.+n.y); - } - override bool UsesAmmo( Class kind ) { static const Class types[] = {"RedShell","GreenShell","BlueShell","PurpleShell"}; @@ -283,9 +169,14 @@ Class Wallbuster : SWWMWeapon if ( t.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40); } } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { - return (10.,3.5,-6.); + double t1 = 90-int(index%5)*72; + double t2 = 360-int(index/5)*72; + Vector2 b = AngleToVector(t1,1.2); + b.y += 3.; + Vector2 n = RotateVector(b,t2); + return (10.,3.5+n.x,-6.+n.y); } action void A_FireShells( int num = 1 ) { @@ -764,6 +655,7 @@ Class Wallbuster : SWWMWeapon Obituary "$O_WALLBUSTER_RED"; SWWMWeapon.Tooltip "$TT_WALLBUSTER"; SWWMWeapon.GetLine "getwallbuster"; + SWWMWeapon.NumCrosshairs 25; Weapon.SlotNumber 4; Weapon.SelectionOrder 400; Weapon.UpSound "wallbuster/select"; diff --git a/zscript/weapons/swwm_danmaku.zsc b/zscript/weapons/swwm_danmaku.zsc index adc5ef773..48a1c72f0 100644 --- a/zscript/weapons/swwm_danmaku.zsc +++ b/zscript/weapons/swwm_danmaku.zsc @@ -77,7 +77,7 @@ Class Eviscerator : SWWMWeapon invoker.loadtics = -delay; } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { return (10.,4.,-5.); } diff --git a/zscript/weapons/swwm_deathlydeathcannon.zsc b/zscript/weapons/swwm_deathlydeathcannon.zsc index a71f007b2..4f044ed35 100644 --- a/zscript/weapons/swwm_deathlydeathcannon.zsc +++ b/zscript/weapons/swwm_deathlydeathcannon.zsc @@ -71,7 +71,7 @@ Class Ynykron : SWWMWeapon } } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { return (15.,4.,-1.); } diff --git a/zscript/weapons/swwm_deepdarkimpact.zsc b/zscript/weapons/swwm_deepdarkimpact.zsc index 095b8ada2..2431b0696 100644 --- a/zscript/weapons/swwm_deepdarkimpact.zsc +++ b/zscript/weapons/swwm_deepdarkimpact.zsc @@ -85,7 +85,7 @@ Class DeepImpact : SWWMWeapon } } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { return (10.,2.,-3.); } diff --git a/zscript/weapons/swwm_shot.zsc b/zscript/weapons/swwm_shot.zsc index 352d75b93..8433df92b 100644 --- a/zscript/weapons/swwm_shot.zsc +++ b/zscript/weapons/swwm_shot.zsc @@ -356,7 +356,7 @@ Class Spreadgun : SWWMWeapon } } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { return (10.,2.,-2.); } diff --git a/zscript/weapons/swwm_sparkyboi.zsc b/zscript/weapons/swwm_sparkyboi.zsc index 0c7951937..c28939254 100644 --- a/zscript/weapons/swwm_sparkyboi.zsc +++ b/zscript/weapons/swwm_sparkyboi.zsc @@ -24,7 +24,7 @@ Class Sparkster : SWWMWeapon return Super.ReportHUDAmmo(); } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { return (10.,4.5,-5.); } diff --git a/zscript/weapons/swwm_splode.zsc b/zscript/weapons/swwm_splode.zsc index 42b3e8c33..c6a115da2 100644 --- a/zscript/weapons/swwm_splode.zsc +++ b/zscript/weapons/swwm_splode.zsc @@ -12,9 +12,8 @@ Class ExplodiumGun : SWWMWeapon Property ClipCount : ClipCount; - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { - if ( Owner.player.ReadyWeapon == SisterWeapon ) return (10.,3.5,-2.); return (10.,3.,-2.); } @@ -575,16 +574,9 @@ Class DualExplodiumGun : SWWMWeapon Property ClipCount : ClipCount; - override void RenderUnderlay( RenderEvent e ) + override Vector3 GetTraceOffset( int index ) { - Super.RenderUnderlay(e); - // draw both crosshairs - SWWMWeapon(SisterWeapon).RenderUnderlay(e); - } - - override Vector3 GetTraceOffset() - { - if ( Owner.player.ReadyWeapon == SisterWeapon ) return (10.,-3.,-2.); + if ( index == 1 ) return (10.,3.5,-2.); return (10.,-3.5,-2.); } @@ -777,6 +769,7 @@ Class DualExplodiumGun : SWWMWeapon Obituary "$O_EXPLODIUM"; SWWMWeapon.Tooltip "$TT_EXPLODIUM2"; SWWMWeapon.GetLine "getexplodiumgun2"; + SWWMWeapon.NumCrosshairs 2; Weapon.UpSound "explodium/select"; Weapon.SisterWeapon "ExplodiumGun"; Weapon.SlotNumber 2; diff --git a/zscript/weapons/swwm_tastytreat.zsc b/zscript/weapons/swwm_tastytreat.zsc index d2aa7a5e9..1929de58f 100644 --- a/zscript/weapons/swwm_tastytreat.zsc +++ b/zscript/weapons/swwm_tastytreat.zsc @@ -113,7 +113,7 @@ Class CandyGun : SWWMWeapon return gotstuff, gotspares; } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { return (10.,3,-2.); } diff --git a/zscript/weapons/swwm_thiccboolet.zsc b/zscript/weapons/swwm_thiccboolet.zsc index b637637af..55461bef2 100644 --- a/zscript/weapons/swwm_thiccboolet.zsc +++ b/zscript/weapons/swwm_thiccboolet.zsc @@ -614,7 +614,7 @@ Class SilverBullet : SWWMWeapon s.Explode(); } } - override Vector3 GetTraceOffset() + override Vector3 GetTraceOffset( int index ) { if ( zoomed ) return (0.,0.,0.); return (10.,1,-1.);