diff --git a/cvarinfo.txt b/cvarinfo.txt index 6473a5c..12949f1 100644 --- a/cvarinfo.txt +++ b/cvarinfo.txt @@ -21,3 +21,4 @@ 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) diff --git a/menudef.txt b/menudef.txt index 7312d7e..4e2d10d 100644 --- a/menudef.txt +++ b/menudef.txt @@ -25,6 +25,7 @@ OptionMenu "UTOptionMenu" Option "Redeemer Target Visuals", "flak_redeemerreadout", "YesNo" Option "Redeemer View Shader", "flak_deemershader", "YesNo" Option "No Redeemer Autoswitch", "flak_noswitchdeemer", "YesNo" + Option "Classic Enh. Shock Rifle", "flak_classicsshock", "YesNo" StaticText " " Option "Enable Translocator", "flak_translocator", "YesNo" Command "Apply Changes", "event refreshtrans" diff --git a/zscript/biorifle.zsc b/zscript/biorifle.zsc index c437d28..9453c80 100644 --- a/zscript/biorifle.zsc +++ b/zscript/biorifle.zsc @@ -411,7 +411,8 @@ Class BioGel : Actor s.args[3] = int(s.args[3]*Scale.x); invoker.deadtimer = -2; if ( invoker.atline ) invoker.atline.RemoteActivate(target,invoker.atside,SPAC_Impact,pos); - A_Explode(int(Random[GES](10,15)*max(1,(Scale.x-1)**2)),Min(150,int(Scale.x*25))); + UTMainHandler.DoBlast(self,Min(150,int(Scale.x*25)),200000); + A_Explode(int(Random[GES](18,22)*max(1,(Scale.x-1)**2)),Min(150,int(Scale.x*25))); A_PlaySound("ges/explode",CHAN_VOICE); int numpt = Min(300,int(Scale.x*30))+Random[GES](-10,10); for ( int i=0; i 0 ) Amount--; + } Default { Tag "Enhanced Shock Core"; @@ -1132,17 +1157,6 @@ Class ViewSuperShockSpark : ViewShockSpark Class EnhancedShockRifle : UTWeapon replaces InvulnerabilitySphere { - int ticcnt; - - override void Tick() - { - Super.Tick(); - if ( !Owner ) return; - ticcnt++; - if ( ticcnt < 105 ) return; - ticcnt = 0; - DepleteAmmo(false,true,1); - } action void A_SShockFire() { Weapon weap = Weapon(invoker); @@ -1259,6 +1273,7 @@ Class EnhancedShockRifle : UTWeapon replaces InvulnerabilitySphere ASMF BCDEFGHIJJ 2; Goto Idle; AltFire: + ASMI A 0 A_JumpIf(CVar.GetCVar('flak_classicsshock').GetBool(),"Fire"); ASMI A 0 A_JumpIfNoAmmo("DryFire"); ASMA A 1 A_SShockAlt(); ASMA BCDFGHIJ 2; diff --git a/zscript/sniperrifle.zsc b/zscript/sniperrifle.zsc index 35aa0ab..c1e2abe 100644 --- a/zscript/sniperrifle.zsc +++ b/zscript/sniperrifle.zsc @@ -96,8 +96,15 @@ Class SniperRifle : UTWeapon { int dmg = Random[Sniper](45,60); if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.8) ) - dmg = d.HitActor.DamageMobj(invoker,self,dmg+70,'Decapitated',DMG_USEANGLE,atan2(d.HitDir.y,d.HitDir.x)); - else dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE,atan2(d.HitDir.y,d.HitDir.x)); + { + dmg = d.HitActor.DamageMobj(invoker,self,dmg+70,'Decapitated',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x)); + UTMainHandler.DoKnockback(d.HitActor,d.HitDir,35000); + } + else + { + dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x)); + UTMainHandler.DoKnockback(d.HitActor,d.HitDir,30000); + } if ( d.HitActor.bNOBLOOD ) { let p = Spawn("BulletImpact",d.HitLocation); diff --git a/zscript/utcommon.zsc b/zscript/utcommon.zsc index 54ede08..dc68027 100644 --- a/zscript/utcommon.zsc +++ b/zscript/utcommon.zsc @@ -925,4 +925,25 @@ Class UTMainHandler : StaticEventHandler let hnd = UTMainHandler(StaticEventHandler.Find("UTMainHandler")); hnd.flashes.push(qf); } + + // Doom's explosions aren't fully 3D + static void DoBlast( Actor Source, double ExplosionRadius, double MomentumTransfer ) + { + BlockThingsIterator bi = BlockThingsIterator.Create(Source,ExplosionRadius); + while ( bi.Next() ) + { + Actor a = bi.Thing; + if ( !a || !a.bSHOOTABLE || !Source.CheckSight(a,0xf) || (a == Source) ) + continue; + Vector3 midpoint = a.Vec3Offset(0,0,a.height*0.5); + a.vel += Level.Vec3Diff(Source.pos,midpoint).unit()*(MomentumTransfer/(Thinker.TICRATE*a.mass)); + } + } + + // Same for this + static void DoKnockback( Actor Victim, Vector3 HitDirection, double MomentumTransfer ) + { + if ( !Victim ) return; + Victim.vel += HitDirection*(MomentumTransfer/(Thinker.TICRATE*Victim.Mass)); + } } diff --git a/zscript/warheadlauncher.zsc b/zscript/warheadlauncher.zsc index 301a9b3..4a0c89d 100644 --- a/zscript/warheadlauncher.zsc +++ b/zscript/warheadlauncher.zsc @@ -42,7 +42,7 @@ Class ShockWave : Actor { lifespan = ReactionTime; A_PlaySound("warhead/explode",CHAN_VOICE,attenuation:ATTN_NONE); - A_QuakeEx(9,9,9,100,0,12000,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.5); + A_QuakeEx(9,9,9,100,0,12000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:1200,rollIntensity:0.5); } override void Tick() { @@ -61,7 +61,7 @@ Class ShockWave : Actor t.Reinit(); while ( a = Actor(t.Next()) ) { - if ( !a.bShootable || !CheckSight(a) || (Distance3D(a) > dmgradius) ) continue; + if ( !a.bShootable || !CheckSight(a,0xf) || (Distance3D(a) > dmgradius) ) continue; Vector3 dir = Vec3To(a); double dist = max(1,dir.length()); dir = dir/dist+(0,0,0.3);