diff --git a/language.version b/language.version index 31c61004a..22d8b366d 100644 --- a/language.version +++ b/language.version @@ -1,2 +1,2 @@ [default] -SWWM_MODVER="\cxSWWM GZ\c- r291 (Wed 3 Jun 11:16:04 CEST 2020)"; +SWWM_MODVER="\cxSWWM GZ\c- r292 (Wed 3 Jun 12:12:48 CEST 2020)"; diff --git a/zscript/swwm_blazeit.zsc b/zscript/swwm_blazeit.zsc index 8ab9c763d..517499493 100644 --- a/zscript/swwm_blazeit.zsc +++ b/zscript/swwm_blazeit.zsc @@ -1320,14 +1320,13 @@ Class Hellblazer : SWWMWeapon A_QuakeEx(qstr,qstr,qstr,bAlt?4:12,0,8,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.12*qstr); A_ZoomFactor(bAlt?.96:.93,ZOOM_INSTANT); A_ZoomFactor(1.); - A_Recoil(bAlt?.3:.5); invoker.clipcount = max(0,invoker.clipcount-1); invoker.magstate[invoker.magpos] = true; invoker.spinskipped++; Vector3 x, y, z, x2, y2, z2, dir, origin; double a, s; [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); - SWWMHandler.DoKnockback(self,-x,22000.); + SWWMHandler.DoKnockback(self,-x,bAlt?22000.:32000.); [x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll); origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+3*y-5*z); a = FRandom[Hellblazer](0,360); diff --git a/zscript/swwm_cbt.zsc b/zscript/swwm_cbt.zsc index 0977fbcbc..34e276992 100644 --- a/zscript/swwm_cbt.zsc +++ b/zscript/swwm_cbt.zsc @@ -388,7 +388,6 @@ Class Wallbuster : SWWMWeapon bool timing; int reloadtime[2], rnum; transient bool cancelreload; - double srecoil; transient ui TextureID WeaponBox, AmmoIcon[4], LoadIcon[4], UsedIcon[4], EmptyIcon; transient ui Font TewiFont; @@ -710,8 +709,6 @@ Class Wallbuster : SWWMWeapon l.target = self; } // third pass, actually fire them - A_Overlay(-9999,"InvRecoil"); - invoker.srecoil = 0.; Vector3 base = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+8*y-10*z); SpreadgunTracer st; SpreadSlugTracer sst; @@ -781,9 +778,7 @@ Class Wallbuster : SWWMWeapon s.alpha *= .4; s.vel += vel*.5+x*FRandom[Wallbuster](4.,8.)+y*FRandom[Wallbuster](-1,1)+z*FRandom[Wallbuster](-1,1); } - SWWMHandler.DoKnockback(self,-x,6000.); - A_Recoil(2.); - invoker.srecoil += -.8; + SWWMHandler.DoKnockback(self,-x,24000.); break; case 2: // saltshot @@ -821,9 +816,7 @@ Class Wallbuster : SWWMWeapon s.alpha *= .4; s.vel += vel*.5+x*FRandom[Wallbuster](4.,8.)+y*FRandom[Wallbuster](-2,2)+z*FRandom[Wallbuster](-2,2); } - SWWMHandler.DoKnockback(self,-x,4000.); - A_Recoil(1.4); - invoker.srecoil += -.5; + SWWMHandler.DoKnockback(self,-x,20000.); break; case 3: // lead ball @@ -858,9 +851,7 @@ Class Wallbuster : SWWMWeapon s.alpha *= .4; s.vel += vel*.5+x*FRandom[Wallbuster](4.,8.)+y*FRandom[Wallbuster](-1,1)+z*FRandom[Wallbuster](-1,1); } - SWWMHandler.DoKnockback(self,-x,2500.); - A_Recoil(1.); - invoker.srecoil += -.35; + SWWMHandler.DoKnockback(self,-x,9000.); break; default: // buckshot @@ -901,9 +892,7 @@ Class Wallbuster : SWWMWeapon s.alpha *= .4; s.vel += vel*.5+x*FRandom[Wallbuster](4.,8.)+y*FRandom[Wallbuster](-2,2)+z*FRandom[Wallbuster](-2,2); } - SWWMHandler.DoKnockback(self,-x,4000.); - A_Recoil(1.4); - invoker.srecoil += -.5; + SWWMHandler.DoKnockback(self,-x,18000.); break; } } @@ -1098,10 +1087,6 @@ Class Wallbuster : SWWMWeapon Zoom: XZW2 A 0 A_FireShells(25); Goto FireTwentyFive; - InvRecoil: - TNT1 A 3; - TNT1 A 1 A_Recoil(invoker.srecoil); - Stop; FireOne: XZW2 AQRSTUVWX 1; XZW2 A 0 diff --git a/zscript/swwm_common.zsc b/zscript/swwm_common.zsc index 7baedbe63..15e17dfcd 100644 --- a/zscript/swwm_common.zsc +++ b/zscript/swwm_common.zsc @@ -3187,9 +3187,7 @@ Class SWWMHandler : EventHandler dir = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt)); } dir = dir/dist; - Vector3 momentum = dir*damagescale*(MomentumTransfer/Thinker.TICRATE); - momentum /= max(50,a.mass); // cap minimum mass to prevent ridiculously strong pushing - a.vel += momentum; + DoKnockback(a,dir,MomentumTransfer*damagescale); } } @@ -3202,7 +3200,11 @@ Class SWWMHandler : EventHandler return; if ( Victim.bCANNOTPUSH || (Victim.Mass >= 10000000) ) return; - Victim.vel += HitDirection*(MomentumTransfer/(Thinker.TICRATE*max(50,Victim.Mass))); + Vector3 Momentum = HitDirection*MomentumTransfer; + if ( (Victim.pos.z <= Victim.floorz) || !Victim.TestMobjZ() ) + Momentum.z = max(Momentum.z,.1*Momentum.length()); + Momentum /= Thinker.TICRATE*max(50,Victim.Mass); + Victim.vel += Momentum; } static void DoSwing( Actor target, Vector2 dir, double initial, double inc, int steps, int mode = 0, int delay = 0, double rmul = 1.0 ) diff --git a/zscript/swwm_danmaku.zsc b/zscript/swwm_danmaku.zsc index c851cdec6..7802dcd93 100644 --- a/zscript/swwm_danmaku.zsc +++ b/zscript/swwm_danmaku.zsc @@ -588,11 +588,10 @@ Class Eviscerator : SWWMWeapon A_SWWMFlash(); SWWMHandler.DoFlash(self,Color(64,255,224,96),3); A_AlertMonsters(4500); - A_Recoil(2.); Vector3 x, y, z, x2, y2, z2, dir, origin; double a, s; [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); - SWWMHandler.DoKnockback(self,-x,15000.); + SWWMHandler.DoKnockback(self,-x,25000.); [x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll); origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+3*y-5*z); for ( int i=0; i<40; i++ ) @@ -645,11 +644,10 @@ Class Eviscerator : SWWMWeapon A_SWWMFlash(); SWWMHandler.DoFlash(self,Color(16,255,224,96),3); A_AlertMonsters(4000); - A_Recoil(2.2); Vector3 x, y, z, x2, y2, z2, dir, origin; double a, s; [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); - SWWMHandler.DoKnockback(self,-x,22000.); + SWWMHandler.DoKnockback(self,-x,32000.); [x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll); origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+3*y-5*z); a = FRandom[Eviscerator](0,360); @@ -780,15 +778,11 @@ Class Eviscerator : SWWMWeapon A_EvisceratorFire(); return A_JumpIf(invoker.extended,"FireExt"); } - XZW3 EFGH 1; - XZW3 I 1 A_Recoil(-.8); - XZW3 JKLMNOPQR 1; + XZW3 EFGHIJKLMNOPQR 1; Goto Eject; FireExt: XZW4 Z 1; - XZW6 DEFG 1; - XZW6 H 1 A_Recoil(-.8); - XZW6 IJKLMNOPQ 1; + XZW6 DEFGHIJKLMNOPQ 1; Goto EjectExt; Eject: XZW2 A 4; diff --git a/zscript/swwm_deepdarkimpact.zsc b/zscript/swwm_deepdarkimpact.zsc index 85304282c..9b27fc99c 100644 --- a/zscript/swwm_deepdarkimpact.zsc +++ b/zscript/swwm_deepdarkimpact.zsc @@ -29,8 +29,8 @@ Class AirBullet : FastProjectile if ( target == lasthit ) return 0; lasthit = target; } - SWWMHandler.DoKnockback(target,vel.unit(),10000*specialf1); - return int(damage*specialf1); + SWWMHandler.DoKnockback(target,vel.unit(),10000); + return damage; } override void Effect() { @@ -62,6 +62,17 @@ Class AirBullet : FastProjectile void A_Splode() { A_AlertMonsters(8000); + if ( target && SWWMUtility.SphereIntersect(target,pos,120) ) + { + // push away + Vector3 dir = level.Vec3Diff(pos,target.Vec3Offset(0,0,target.height/2)); + double dist = dir.length(); + dir /= dist; + double mm = 8000000./max(20.,dist); + if ( (target.pos.z > target.floorz) && target.TestMobjZ() ) mm *= 1.6; + SWWMHandler.DoKnockback(target,dir,mm); + } + SWWMHandler.DoBlast(self,400,100000); A_QuakeEx(6,6,6,20,0,250,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.); A_StartSound("deepimpact/bullethit",CHAN_VOICE,CHANF_DEFAULT,1.,.3); A_SprayDecal("ImpactMark"); @@ -263,17 +274,20 @@ Class DeepImpact : SWWMWeapon if ( !weap ) return; A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.05); A_StartSound("deepimpact/fire",CHAN_WEAPON,CHANF_OVERLAP); - A_Recoil(.05); A_AlertMonsters(300); invoker.clipcount = max(0,invoker.clipcount-3); Vector3 x, y, z, dir; [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); + SWWMHandler.DoKnockback(self,-x,2000.); Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+2*y-3*z); DeepTracer t = new("DeepTracer"); t.ignoreme = self; Array list; list.Clear(); int rings = 1; + int wallhits = 0; + Vector3 hitnormal; + Vector3 wnorm = (0,0,0); for ( double i=0; i<1.; i+=.05 ) { for ( int j=0; j<360; j+=(360/rings) ) @@ -301,10 +315,37 @@ Class DeepImpact : SWWMWeapon list[inl].avgdir += dir; list[inl].avgdist += t.hitdist[i]; } - if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos); + if ( t.Results.HitType == TRACE_HitWall ) + { + t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos); + wallhits++; + hitnormal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit(); + if ( !t.Results.Side ) hitnormal *= -1; + wnorm += (hitnormal*.2-dir)/max(50.,t.Results.Distance); + } + else if ( t.Results.HitType == TRACE_HitFloor ) + { + wallhits++; + if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.top.Normal; + else hitnormal = t.Results.HitSector.floorplane.Normal; + wnorm += (hitnormal*.2-dir)/max(50.,t.Results.Distance); + } + else if ( t.Results.HitType == TRACE_HitCeiling ) + { + wallhits++; + if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.bottom.Normal; + else hitnormal = t.Results.HitSector.ceilingplane.Normal; + wnorm += (hitnormal*.2-dir)/max(50.,t.Results.Distance); + } } rings += 5; } + if ( wallhits > 0 ) + { + wnorm /= wallhits; + if ( (pos.z > floorz) && TestMobjZ() ) wnorm *= 2.4; + SWWMHandler.DoKnockback(self,wnorm.unit(),wnorm.length()*5000000.); + } for ( int i=0; i loadammo, nextammo; // currently loaded shell, next shell to load - double srecoil; transient ui TextureID WeaponBox, AmmoIcon[7], LoadedIcon[7]; transient ui Font TewiFont; @@ -2140,9 +2139,7 @@ Class Spreadgun : SWWMWeapon s.alpha *= .4; s.vel += vel*.5+x*FRandom[Spreadgun](4.,8.)+y*FRandom[Spreadgun](-1,1)+z*FRandom[Spreadgun](-1,1); } - SWWMHandler.DoKnockback(self,-x,6000.); - A_Recoil(2.); - invoker.srecoil = -.8; + SWWMHandler.DoKnockback(self,-x,25000.); break; case 2: for ( int j=0; j<9; j++ ) @@ -2179,9 +2176,7 @@ Class Spreadgun : SWWMWeapon s.alpha *= .4; s.vel += vel*.5+x*FRandom[Spreadgun](4.,8.)+y*FRandom[Spreadgun](-2,2)+z*FRandom[Spreadgun](-2,2); } - SWWMHandler.DoKnockback(self,-x,2000.); - A_Recoil(.4); - invoker.srecoil = -.15; + SWWMHandler.DoKnockback(self,-x,13000.); break; case 3: for ( int j=0; j<8; j++ ) @@ -2217,9 +2212,7 @@ Class Spreadgun : SWWMWeapon s.alpha *= .4; s.vel += vel*.5+x*FRandom[Spreadgun](4.,8.)+y*FRandom[Spreadgun](-2,2)+z*FRandom[Spreadgun](-2,2); } - SWWMHandler.DoKnockback(self,-x,4000.); - A_Recoil(1.4); - invoker.srecoil = -.5; + SWWMHandler.DoKnockback(self,-x,23000.); break; case 4: for ( int j=0; j<10; j++ ) @@ -2257,9 +2250,7 @@ Class Spreadgun : SWWMWeapon s.alpha *= .4; s.vel += vel*.5+x*FRandom[Spreadgun](4.,12.)+y*FRandom[Spreadgun](-2,2)+z*FRandom[Spreadgun](-2,2); } - SWWMHandler.DoKnockback(self,-x,3500.); - A_Recoil(.7); - invoker.srecoil = -.24; + SWWMHandler.DoKnockback(self,-x,14000.); break; case 5: a = FRandom[Spreadgun](0,360); @@ -2293,9 +2284,7 @@ Class Spreadgun : SWWMWeapon s.alpha *= .4; s.vel += vel*.5+x*FRandom[Spreadgun](4.,8.)+y*FRandom[Spreadgun](-1,1)+z*FRandom[Spreadgun](-1,1); } - SWWMHandler.DoKnockback(self,-x,2500.); - A_Recoil(1.); - invoker.srecoil = -.35; + SWWMHandler.DoKnockback(self,-x,9500.); break; case 6: a = FRandom[Spreadgun](0,360); @@ -2360,9 +2349,7 @@ Class Spreadgun : SWWMWeapon s.bAMBUSH = true; s.vel += vel*.5+x*FRandom[Spreadgun](1.,20.)+y*FRandom[Spreadgun](-2,2)+z*FRandom[Spreadgun](-2,2); } - SWWMHandler.DoKnockback(self,-x,12000.); - A_Recoil(3.6); - invoker.srecoil = -2.; + SWWMHandler.DoKnockback(self,-x,30000.); break; default: st = new("SpreadgunTracer"); @@ -2402,9 +2389,7 @@ Class Spreadgun : SWWMWeapon s.alpha *= .4; s.vel += vel*.5+x*FRandom[Spreadgun](4.,8.)+y*FRandom[Spreadgun](-2,2)+z*FRandom[Spreadgun](-2,2); } - SWWMHandler.DoKnockback(self,-x,4000.); - A_Recoil(1.4); - invoker.srecoil = -.5; + SWWMHandler.DoKnockback(self,-x,20000.); break; } break; @@ -2580,9 +2565,7 @@ Class Spreadgun : SWWMWeapon A_FireShell(); return ResolveState(null); } - XZW2 RS 1; - XZW2 T 1 A_Recoil(invoker.srecoil); - XZW2 U 1; + XZW2 RSTU 1; XZW2 VWXY 2; Goto ReadyFired; AltFire: diff --git a/zscript/swwm_sparkyboi.zsc b/zscript/swwm_sparkyboi.zsc index 5bb4ec49a..405ba7308 100644 --- a/zscript/swwm_sparkyboi.zsc +++ b/zscript/swwm_sparkyboi.zsc @@ -1832,7 +1832,7 @@ Class Sparkster : SWWMWeapon A_ZoomFactor(.94,ZOOM_INSTANT); A_ZoomFactor(1.); A_AlertMonsters(1200); - A_Recoil(.6); + SWWMHandler.DoKnockback(self,-x,2500.); a = FRandom[Spread](0,360); s = FRandom[Spread](0,.012); [x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll); diff --git a/zscript/swwm_splode.zsc b/zscript/swwm_splode.zsc index ddf7ec249..e11db8de2 100644 --- a/zscript/swwm_splode.zsc +++ b/zscript/swwm_splode.zsc @@ -301,9 +301,9 @@ Class ExplodiumGun : SWWMWeapon A_SWWMFlash(); SWWMHandler.DoFlash(self,Color(64,255,224,64),3); A_AlertMonsters(5000); - A_Recoil(1.2); Vector3 x, y, z, x2, y2, z2; [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); + SWWMHandler.DoKnockback(self,-x,12000.); Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+3*y-2*z); double a = FRandom[Spread](0,360), s = FRandom[Spread](0,.002); [x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll); @@ -449,9 +449,7 @@ Class ExplodiumGun : SWWMWeapon Wait; Fire: XZW2 A 1 A_Schutt(); - XZW2 IJKLM 1; - XZW2 N 1 A_Recoil(-.7); - XZW2 OPQR 1; + XZW2 IJKLMNOPQR 1; XZW2 S 2 A_DropCasing(); Goto Ready; AltFire: diff --git a/zscript/swwm_tastytreat.zsc b/zscript/swwm_tastytreat.zsc index 2fb5558ed..6baf361c8 100644 --- a/zscript/swwm_tastytreat.zsc +++ b/zscript/swwm_tastytreat.zsc @@ -896,9 +896,9 @@ Class CandyGun : SWWMWeapon A_SWWMFlash(); SWWMHandler.DoFlash(self,Color(64,224,64,255),5); A_AlertMonsters(9000); - A_Recoil(2.2); Vector3 x, y, z, x2, y2, z2; [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); + SWWMHandler.DoKnockback(self,-x,18000.); Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+3*y-2*z); double a = FRandom[Spread](0,360), s = FRandom[Spread](0,.005); [x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll); @@ -1091,9 +1091,7 @@ Class CandyGun : SWWMWeapon Wait; Fire: XZW2 A 1 A_Schutt(); - XZW2 IJKLM 1; - XZW2 N 1 A_Recoil(-1.2); - XZW2 OPQR 1; + XZW2 IJKLMNOPQR 1; XZW2 S 2 A_DropCasing(); Goto Ready; AltFire: