Mortal Rifle cluster shot mode implemented.

This commit is contained in:
Mari the Deer 2022-09-18 12:56:05 +02:00
commit 8f04064672
8 changed files with 217 additions and 13 deletions

View file

@ -146,6 +146,7 @@ Class HeavyMahSheenGun : SWWMWeapon
let p = Spawn("SWWMBulletImpact",st.HitList[i].HitLocation);
p.angle = atan2(st.HitList[i].x.y,st.HitList[i].x.x)+180;
p.pitch = asin(st.HitList[i].x.z);
p.target = self;
}
else
{
@ -175,6 +176,7 @@ Class HeavyMahSheenGun : SWWMWeapon
let p = Spawn("SWWMBulletImpact",st.Results.HitPos+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( st.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40);
if ( st.Results.HitLine ) st.Results.HitLine.RemoteActivate(self,st.Results.Side,SPAC_Impact,st.Results.HitPos);
}

View file

@ -419,7 +419,7 @@ Class MisterRifle : SWWMWeapon
A_StartSound("mister/firestream",CHAN_WEAPON,CHANF_OVERLAP);
SWWMHandler.DoFlash(self,Color(32,64,224,255),2);
A_AlertMonsters(swwm_uncapalert?0:4000);
A_MisterFireStream(true);
A_MisterFireStream(0);
return ResolveState("FireStream");
}
SWWMHandler.DoFlash(self,Color(48,64,224,255),3);
@ -434,6 +434,98 @@ Class MisterRifle : SWWMWeapon
A_QuakeEx(6,6,6,8,0,10,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:1.3);
A_BumpFOV(.92);
A_AlertMonsters(swwm_uncapalert?0:8000);
for ( int i=0; i<10; i++ )
{
let s = Spawn("SWWMSmoke",origin);
s.scale *= .6;
s.alpha *= .15;
s.speed *= .8;
s.vel += vel*.5+x*FRandom[Mister](1.,4.);
s.SetShade(Color(0,3,4)*Random[ExploS](48,63));
}
Vector3 x2, y2, z2;
[x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll);
double a, s;
Vector3 dir;
for ( int i=0; i<15; i++ )
{
// initial shot
if ( i == 0 )
{
a = FRandom[Mister](0,360);
s = .01;
dir = SWWMUtility.ConeSpread(x2,y2,z2,a,s);
}
// next three shots, triangle
else if ( i < 4 )
{
a = 90+120*(i-1)+FRandom[Mister](-15,15);
s = .04+FRandom[Mister](-.01,.01);
dir = SWWMUtility.ConeSpread(x2,y2,z2,a,s);
}
// next five shots, pentagon
else if ( i < 9 )
{
a = -90+72*(i-4)+FRandom[Mister](-20,20);
s = .08+FRandom[Mister](-.02,.02);
dir = SWWMUtility.ConeSpread(x2,y2*1.2,z2,a,s);
}
// final six shots, wide hexagon
else
{
a = 60*(i-9)+FRandom[Mister](-25,25);
s = .12+FRandom[Mister](-.03,.03);
dir = SWWMUtility.ConeSpread(x2,y2*1.6,z2,a,s);
}
FLineTraceData d;
LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION|TRF_NOSKY,origin.z,origin.x,origin.y,d);
SWWMBulletTrail.DoTrail(self,origin,dir,10000,6);
if ( d.HitType == TRACE_HitActor )
{
if ( d.HitActor.bNOBLOOD || d.HitActor.bDORMANT )
{
let p = Spawn("SpreadImpact",d.HitLocation);
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
p.pitch = asin(d.HitDir.z);
p.target = self;
}
let b = Spawn("MisterBuckshotImpact",d.HitLocation-d.HitDir*4.);
b.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
b.pitch = asin(d.HitDir.z);
b.target = self;
MisterBulletImpact(b).A_BulletExplode();
}
else if ( d.HitType != TRACE_HitNone )
{
Vector3 hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
let p = Spawn("SpreadImpact",d.HitLocation+hitnormal*0.01);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
let b = Spawn("MisterBuckshotImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);
b.pitch = asin(-hitnormal.z);
b.target = self;
MisterBulletImpact(b).A_BulletExplode();
if ( swwm_omnibust ) BusterWall.BustLinetrace(d,44,self,d.HitDir,d.HitLocation.z);
}
}
return ResolveState("FireCluster");
}
// precision shot
@ -463,6 +555,7 @@ Class MisterRifle : SWWMWeapon
let p = Spawn("SWWMBulletImpact",d.HitLocation);
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
p.pitch = asin(d.HitDir.z);
p.target = self;
}
let b = Spawn("MisterBulletImpact",d.HitLocation-d.HitDir*4.);
b.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
@ -491,6 +584,7 @@ Class MisterRifle : SWWMWeapon
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
let b = Spawn("MisterBulletImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);
@ -502,9 +596,9 @@ Class MisterRifle : SWWMWeapon
return ResolveState(null);
}
action void A_MisterFireStream( bool bFromMain = false )
action void A_MisterFireStream( int index )
{
if ( !bFromMain )
if ( index != 0 )
{
A_PlayerFire();
SWWMHandler.DoFlash(self,Color(32,64,224,255),2);
@ -805,9 +899,10 @@ Class MisterRifle : SWWMWeapon
XZW3 OPQRS 2;
Goto AutoCycle;
FireStream:
XZW2 A 1 A_MisterFireStream();
XZW3 TUV 1 A_MisterFireStream();
XZW3 WXY 1;
XZW2 A 1 A_MisterFireStream(1);
XZW3 T 1 A_MisterFireStream(2);
XZW3 U 1 A_MisterFireStream(3);
XZW3 VWXY 1;
XZW3 Z 2;
XZW4 ABC 2;
Goto AutoCycle;

View file

@ -127,6 +127,22 @@ Class MisterExLightBig : MisterExLight
Args 0,0,0,500;
}
}
Class MisterExLightSmall : MisterExLight
{
Default
{
ReactionTime 25;
Args 0,0,0,120;
}
}
Class MisterExLightTiny : MisterExLight
{
Default
{
ReactionTime 20;
Args 0,0,0,80;
}
}
Class MisterBulletImpactPop : Actor
{
@ -193,12 +209,13 @@ Class MisterFuzzy : Actor
override void PostBeginPlay()
{
special1 += Random[ExploS](4,8);
specialf1 = special1;
vel = SWWMUtility.Vec3FromAngles(angle,pitch)*FRandom[ExploS](8,24);
}
override void Tick()
{
if ( isFrozen() ) return;
SWWMUtility.DoExplosion(self,44,10000,80,80,DE_EXTRAZTHRUST);
SWWMUtility.DoExplosion(self,(special2==1)?444:(special2==0)?44:4,3000,80,80,DE_EXTRAZTHRUST);
special1--;
if ( special1 <= 0 )
{
@ -270,7 +287,7 @@ Class MisterFuzzy : Actor
{
let p = Spawn("MisterFuzzyTrail",level.Vec3Offset(oldpos,traildir*i));
p.vel = dir*FRandom[ExploS](1.,4.);
p.scale *= special1/6.;
p.scale *= special1/specialf1;
}
}
nstep++;
@ -357,7 +374,7 @@ Class MisterPop : Actor
Scale.y *= RandomPick[ExploS](-1,1);
roll = FRandom[ExploS](0,360);
}
BLPF C 2 Bright { SWWMUtility.DoExplosion(self,4,8000,50,50,DE_EXTRAZTHRUST); }
BLPF C 2 Bright { SWWMUtility.DoExplosion(self,4,2000,50,50,DE_EXTRAZTHRUST); }
TNT1 A 1
{
let p = Spawn("MisterFuzzyTrail",pos);
@ -387,7 +404,7 @@ Class MisterBulletImpact : Actor
+FOILINVUL;
+NOINTERACTION;
}
void A_BulletExplode()
virtual void A_BulletExplode()
{
A_AlertMonsters(swwm_uncapalert?0:4000);
SWWMUtility.DoExplosion(self,444,80000,150,150,DE_EXTRAZTHRUST);
@ -434,7 +451,7 @@ Class MisterBulletImpact : Actor
Spawn("MisterExLight",pos);
Spawn("MisterBulletImpactPop",pos);
}
void A_BulletSubExplode()
virtual void A_BulletSubExplode()
{
if ( special1 && (special1 <= 10) )
{
@ -471,6 +488,86 @@ Class MisterBulletImpact : Actor
}
}
Class MisterBuckshotImpact : MisterBulletImpact
{
Default
{
Scale .8;
}
override void A_BulletExplode()
{
A_AlertMonsters(swwm_uncapalert?0:1000);
SWWMUtility.DoExplosion(self,44,4000,80,80,DE_EXTRAZTHRUST);
A_QuakeEx(2,2,2,5,0,200,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,falloff:60,rollintensity:.2);
A_StartSound("mister/hitscatter",CHAN_VOICE,attenuation:.35);
A_SprayDecal("ShockMark",-172);
Scale *= FRandom[ExploS](0.8,1.1);
Scale.x *= RandomPick[ExploS](-1,1);
Scale.y *= RandomPick[ExploS](-1,1);
int numpt = Random[ExploS](5,10);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](1,4);
let s = Spawn("SWWMSmoke",pos);
s.vel = pvel;
s.SetShade(Color(0,3,4)*Random[ExploS](48,63));
s.special1 = Random[ExploS](0,2);
s.scale *= 2.5;
s.alpha *= .3;
}
numpt = Random[ExploS](2,6);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](4,6);
let s = Spawn("SWWMSpark",pos);
s.vel = pvel;
}
numpt = Random[ExploS](2,4);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](2,8);
let s = Spawn("SWWMChip",pos);
s.vel = pvel;
}
numpt = Random[ExploS](6,8);
for ( int i=0; i<numpt; i++ )
{
let s = Spawn("MisterFuzzy",pos);
s.angle = FRandom[ExploS](0,360);
s.pitch = FRandom[ExploS](-90,90);
s.target = target;
s.special1 -= 2;
s.special2 = -1;
}
Spawn("MisterExLightTiny",pos);
let p = Spawn("MisterBulletImpactPop",pos);
p.A_SetScale(1.5);
}
override void A_BulletSubExplode()
{
if ( special1 && (special1 <= 10) )
{
SWWMUtility.DoExplosion(self,4,300+special1*20,60+special1*6,60+special1*6,DE_EXTRAZTHRUST);
int numpt = Random[ExploS](0,special1/2);
for ( int i=0; i<numpt; i++ )
{
Vector3 np = level.Vec3Offset(pos,SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](2,16)*special1);
if ( !level.IsPointInLevel(np) ) continue;
let p = Spawn("MisterPop",np);
p.target = target;
}
}
special1++;
}
States
{
Spawn:
TNT1 A 0;
XEX7 ACEGIKMOQSUWY[] 1 Bright A_BulletSubExplode();
Stop;
}
}
Class MisterGrenadeFlare : Actor
{
Default

View file

@ -244,6 +244,7 @@ Class Wallbuster : SWWMWeapon
let p = Spawn(impact,t.HitList[i].HitLocation);
p.angle = atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180;
p.pitch = asin(t.HitList[i].x.z);
p.target = self;
p.special1 = max(0,(bc-5)/4);
}
else
@ -276,6 +277,7 @@ Class Wallbuster : SWWMWeapon
let p = Spawn(impact,t.Results.HitPos+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
p.special1 = max(0,(bc-5)/4);
if ( t.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40);
}

View file

@ -318,6 +318,7 @@ Class Spreadgun : SWWMWeapon
let p = Spawn(impact,t.HitList[i].HitLocation);
p.angle = atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180;
p.pitch = asin(t.HitList[i].x.z);
p.target = self;
}
else
{
@ -348,6 +349,7 @@ Class Spreadgun : SWWMWeapon
let p = Spawn(impact,t.Results.HitPos+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( t.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40);
if ( t.Results.HitLine ) t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos);
}

View file

@ -113,6 +113,7 @@ Class ExplodiumGun : SWWMWeapon
let p = Spawn("SWWMBulletImpact",d.HitLocation);
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
p.pitch = asin(d.HitDir.z);
p.target = self;
}
else
{
@ -146,6 +147,7 @@ Class ExplodiumGun : SWWMWeapon
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
let b = Spawn("ExplodiumBulletImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);
@ -657,6 +659,7 @@ Class DualExplodiumGun : SWWMWeapon
let p = Spawn("SWWMBulletImpact",d.HitLocation);
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
p.pitch = asin(d.HitDir.z);
p.target = self;
}
else
{
@ -690,6 +693,7 @@ Class DualExplodiumGun : SWWMWeapon
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
let b = Spawn("ExplodiumBulletImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);

View file

@ -154,6 +154,7 @@ Class CandyGun : SWWMWeapon
let p = Spawn("SWWMBulletImpact",d.HitLocation);
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
p.pitch = asin(d.HitDir.z);
p.target = self;
}
else
{
@ -186,6 +187,7 @@ Class CandyGun : SWWMWeapon
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
let b = Spawn("CandyBulletImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);