1338 lines
30 KiB
Text
1338 lines
30 KiB
Text
Class ShockAmmo : Ammo
|
|
{
|
|
Default
|
|
{
|
|
Tag "Shock Core";
|
|
Inventory.PickupMessage "You picked up a Shock Core.";
|
|
Inventory.Amount 10;
|
|
Inventory.MaxAmount 50;
|
|
Ammo.BackpackAmount 20;
|
|
Ammo.BackpackMaxAmount 100;
|
|
Ammo.DropAmount 5;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SHOA A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class ShockAmmo2 : ShockAmmo
|
|
{
|
|
Default
|
|
{
|
|
Tag "Used Shock Core";
|
|
Inventory.PickupMessage "You picked up a used Shock Core.";
|
|
Inventory.Amount 3;
|
|
Ammo.DropAmount 3;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SHOA A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class ShockBeamTracer : LineTracer
|
|
{
|
|
Actor owner, ignore, lasthit;
|
|
|
|
override ETraceStatus TraceCallback()
|
|
{
|
|
if ( Results.HitType == TRACE_HitActor )
|
|
{
|
|
if ( (Results.HitActor == owner) || (Results.HitActor == ignore) || (Results.HitActor == lasthit) ) return TRACE_Skip;
|
|
if ( Results.HitActor.bSHOOTABLE || Results.HitActor is 'ShockHitbox' ) 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;
|
|
}
|
|
}
|
|
|
|
Class ShockRifleWave : Actor
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
Radius 0.1;
|
|
Height 0;
|
|
Scale 0.7;
|
|
+NOBLOCKMAP;
|
|
+NOGRAVITY;
|
|
+DONTSPLASH;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
alpha -= 1/50.;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SWAV A 50 Bright;
|
|
SWAV B 0 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class SuperShockRifleWave : Actor
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
Radius 0.1;
|
|
Height 0;
|
|
Scale 1.2;
|
|
+NOBLOCKMAP;
|
|
+NOGRAVITY;
|
|
+DONTSPLASH;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
alpha -= 1/50.;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SWAV A 50 Bright;
|
|
SWAV B 0 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class ShockBeamRing : Actor
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
Radius 0.1;
|
|
Height 0;
|
|
Scale 0.5;
|
|
ReactionTime 18;
|
|
+NOBLOCKMAP;
|
|
+NOGRAVITY;
|
|
+DONTSPLASH;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
alpha -= 1./ReactionTime;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SRNG ABCDEFGHI 2 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class SuperShockBeamRing : Actor
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
Radius 0.1;
|
|
Height 0;
|
|
Scale 0.9;
|
|
ReactionTime 18;
|
|
+NOBLOCKMAP;
|
|
+NOGRAVITY;
|
|
+DONTSPLASH;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
alpha -= 1./ReactionTime;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SRNG ABCDEFGHI 2 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class ShockBlastRing : ShockBeamRing
|
|
{
|
|
Default
|
|
{
|
|
Scale 3.0;
|
|
ReactionTime 45;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SRNG ABCDEFGHI 5 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class SuperShockBlastRing : ShockBeamRing
|
|
{
|
|
Default
|
|
{
|
|
Scale 5.0;
|
|
ReactionTime 45;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SRNG ABCDEFGHI 5 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class ShockSpark : Actor
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
Radius 2;
|
|
Height 2;
|
|
+NOBLOCKMAP;
|
|
+NOGRAVITY;
|
|
+MISSILE;
|
|
+FORCEXYBILLBOARD;
|
|
+THRUACTORS;
|
|
+ROLLSPRITE;
|
|
+ROLLCENTER;
|
|
+NOTELEPORT;
|
|
+DONTSPLASH;
|
|
+CANBOUNCEWATER;
|
|
-BOUNCEAUTOOFF;
|
|
BounceType "Doom";
|
|
BounceFactor 1.0;
|
|
WallBounceFactor 1.0;
|
|
Scale 0.1;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
if ( !bAMBUSH )
|
|
{
|
|
roll = FRandom[ASMD](0,360);
|
|
let s = Spawn(GetClass(),pos);
|
|
s.bAMBUSH = true;
|
|
s.vel = vel;
|
|
s.scale = scale;
|
|
s.roll = roll;
|
|
}
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
ASMK A 1 Bright
|
|
{
|
|
A_FadeOut(FRandom[ASMD](0.0,0.1));
|
|
vel *= 0.98;
|
|
}
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
Class ShockSparkTrail : ShockSpark
|
|
{
|
|
Default
|
|
{
|
|
+AMBUSH;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
roll = FRandom[ASMD](0,360);
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
ASMK A 1 Bright A_FadeOut(FRandom[ASMD](0.0,0.2));
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
Class ShockBeam : Actor
|
|
{
|
|
ShockBeamTracer t;
|
|
Vector3 tracedir;
|
|
bool moving;
|
|
double totaldist;
|
|
|
|
Default
|
|
{
|
|
Obituary "%k inflicted mortal damage upon %o with the Shock Rifle";
|
|
DamageType 'jolted';
|
|
RenderStyle "Add";
|
|
Radius 0.1;
|
|
Height 0;
|
|
Scale 0.4;
|
|
+NOGRAVITY;
|
|
+NOCLIP;
|
|
+DONTSPLASH;
|
|
+FORCEXYBILLBOARD;
|
|
+FORCERADIUSDMG;
|
|
+NODAMAGETHRUST;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
t = new("ShockBeamTracer");
|
|
t.owner = target;
|
|
t.ignore = self;
|
|
moving = true;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
if ( !moving ) return;
|
|
// step trace
|
|
tracedir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
|
|
t.Trace(pos,cursector,tracedir,1000,0);
|
|
totaldist += t.Results.Distance;
|
|
// spawn particles
|
|
for ( int i=0; i<t.Results.Distance; i+=80 )
|
|
Spawn("ShockBeamLight",Vec3Offset(tracedir.x*i,tracedir.y*i,tracedir.z*i));
|
|
for ( int i=0; i<t.Results.Distance; i+=2 )
|
|
{
|
|
Vector3 pofs = tracedir*FRandom[ASMD](0,2)+(FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5));
|
|
let s = Spawn("ShockSparkTrail",Vec3Offset(tracedir.x*i+pofs.x,tracedir.y*i+pofs.y,tracedir.z*i+pofs.z));
|
|
s.vel = (FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03));
|
|
}
|
|
if ( totaldist >= 10000.0 )
|
|
{
|
|
// reposition and explode on air
|
|
SetOrigin(t.Results.HitPos-t.Results.HitVector*4,true);
|
|
ExplodeMissile(t.Results.HitLine,null);
|
|
moving = false;
|
|
let r = Spawn("ShockBeamRing",pos);
|
|
r.angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x);
|
|
r.pitch = asin(-t.Results.HitVector.z);
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitNone )
|
|
{
|
|
// reposition
|
|
SetOrigin(t.Results.HitPos+t.Results.HitVector,true);
|
|
angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x);
|
|
pitch = asin(-t.Results.HitVector.z);
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitActor )
|
|
{
|
|
// reposition and explode on actor
|
|
SetOrigin(t.Results.HitPos-t.Results.HitVector*4,true);
|
|
ExplodeMissile(null,t.Results.HitActor);
|
|
if ( t.Results.HitActor is 'ShockHitbox' )
|
|
{
|
|
if ( target )
|
|
{
|
|
target.TakeInventory('ShockAmmo',2);
|
|
UTMainHandler.DoSwing(target,(FRandom[ASMD](-0.1,-0.6),FRandom[ASMD](-0.1,0.5)),5,-1,3,SWING_Spring,3,6);
|
|
}
|
|
let b = t.Results.HitActor.target;
|
|
UTMainHandler.DoBlast(b,250,70000);
|
|
b.ExplodeMissile(null,self);
|
|
b.A_Explode(Random[ASMD](150,180),250);
|
|
b.A_QuakeEx(6,6,6,60,0,1200,"",QF_RELATIVE|QF_SCALEDOWN,falloff:250,rollIntensity:0.2);
|
|
b.A_SprayDecal("BigShockMark1",100);
|
|
b.A_SprayDecal("BigShockMark2",100);
|
|
Spawn("ShockRifleWave",b.pos);
|
|
Spawn("ShockBlastLight",b.pos);
|
|
let r = Spawn("ShockBlastRing",b.pos);
|
|
r.angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x);
|
|
r.pitch = asin(-t.Results.HitVector.z);
|
|
A_PlaySound("shock/blast",CHAN_WEAPON,attenuation:0.5);
|
|
int numpt = Random[ASMD](200,300);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](1,32);
|
|
let s = Spawn("ShockSpark",b.pos);
|
|
s.vel = pvel;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t.Results.HitActor.DamageMobj(self,target,Random[ASMD](35,50),'jolted',DMG_USEANGLE,atan2(t.Results.HitVector.y,t.Results.HitVector.x));
|
|
UTMainHandler.DoKnockback(t.Results.HitActor,t.Results.HitVector,60000);
|
|
let r = Spawn("ShockBeamRing",pos);
|
|
r.angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x);
|
|
r.pitch = asin(-t.Results.HitVector.z);
|
|
}
|
|
moving = false;
|
|
}
|
|
else
|
|
{
|
|
// reposition and explode on wall
|
|
SetOrigin(t.Results.HitPos-t.Results.HitVector*4,true);
|
|
A_SprayDecal("ShockMark",16);
|
|
ExplodeMissile(t.Results.HitLine,null);
|
|
moving = false;
|
|
Vector3 HitNormal = t.Results.HitVector;
|
|
if ( t.Results.HitType == TRACE_HitWall )
|
|
{
|
|
t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,pos);
|
|
// calculate normal
|
|
HitNormal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
|
|
if ( t.Results.Side == 0 ) HitNormal *= -1;
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitFloor )
|
|
{
|
|
if ( t.Results.ffloor ) HitNormal = -t.Results.ffloor.top.Normal;
|
|
else HitNormal = t.Results.HitSector.floorplane.Normal;
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitCeiling )
|
|
{
|
|
if ( t.Results.ffloor ) HitNormal = -t.Results.ffloor.bottom.Normal;
|
|
else HitNormal = t.Results.HitSector.ceilingplane.Normal;
|
|
}
|
|
let r = Spawn("ShockBeamRing",pos);
|
|
r.angle = atan2(HitNormal.y,HitNormal.x);
|
|
r.pitch = asin(-HitNormal.z);
|
|
}
|
|
}
|
|
action void A_BeamExplode()
|
|
{
|
|
Spawn("ShockBeamLight",pos);
|
|
A_QuakeEx(2,2,2,5,0,120,"",QF_RELATIVE|QF_SCALEDOWN,falloff:60,rollIntensity:0.1);
|
|
A_PlaySound("shock/hit",CHAN_VOICE);
|
|
A_AlertMonsters();
|
|
int numpt = Random[ASMD](20,50);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](3,12);
|
|
let s = Spawn("ShockSpark",pos);
|
|
s.vel = pvel;
|
|
}
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
TNT1 A 1;
|
|
Wait;
|
|
Death:
|
|
TNT1 A 0 A_BeamExplode();
|
|
ASMX ABCDEFGHIJKL 1 Bright;
|
|
TNT1 A 100;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class SuperShockSpark : Actor
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
Radius 2;
|
|
Height 2;
|
|
+NOBLOCKMAP;
|
|
+NOGRAVITY;
|
|
+MISSILE;
|
|
+FORCEXYBILLBOARD;
|
|
+THRUACTORS;
|
|
+ROLLSPRITE;
|
|
+ROLLCENTER;
|
|
+NOTELEPORT;
|
|
+DONTSPLASH;
|
|
+CANBOUNCEWATER;
|
|
-BOUNCEAUTOOFF;
|
|
BounceType "Doom";
|
|
BounceFactor 1.0;
|
|
WallBounceFactor 1.0;
|
|
Scale 0.1;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
if ( !bAMBUSH )
|
|
{
|
|
roll = FRandom[ASMD](0,360);
|
|
let s = Spawn(GetClass(),pos);
|
|
s.bAMBUSH = true;
|
|
s.vel = vel;
|
|
s.scale = scale;
|
|
s.roll = roll;
|
|
}
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SSMK A 1 Bright
|
|
{
|
|
A_FadeOut(FRandom[ASMD](0.0,0.1));
|
|
vel *= 0.98;
|
|
}
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
Class SuperShockSparkTrail : ShockSpark
|
|
{
|
|
Default
|
|
{
|
|
+AMBUSH;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
roll = FRandom[ASMD](0,360);
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SSMK A 1 Bright A_FadeOut(FRandom[ASMD](0.0,0.2));
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
Class SuperShockBeam : Actor
|
|
{
|
|
ShockBeamTracer t;
|
|
Vector3 tracedir;
|
|
bool moving;
|
|
double totaldist;
|
|
|
|
Default
|
|
{
|
|
Obituary "%k electrified %o with the Enhanced Shock Rifle.";
|
|
DamageType 'joltedX';
|
|
RenderStyle "Add";
|
|
Radius 0.1;
|
|
Height 0;
|
|
Scale 0.7;
|
|
+NOGRAVITY;
|
|
+NOCLIP;
|
|
+DONTSPLASH;
|
|
+FORCEXYBILLBOARD;
|
|
+FORCERADIUSDMG;
|
|
+EXTREMEDEATH;
|
|
+NODAMAGETHRUST;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
t = new("ShockBeamTracer");
|
|
t.owner = target;
|
|
t.ignore = self;
|
|
moving = true;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
if ( !moving ) return;
|
|
// step trace
|
|
tracedir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
|
|
t.Trace(pos,cursector,tracedir,2000,0);
|
|
totaldist += t.Results.Distance;
|
|
// spawn particles
|
|
for ( int i=0; i<t.Results.Distance; i+=80 )
|
|
Spawn("SuperShockBeamLight",Vec3Offset(tracedir.x*i,tracedir.y*i,tracedir.z*i));
|
|
for ( int i=0; i<t.Results.Distance; i++ )
|
|
{
|
|
Vector3 pofs = tracedir*FRandom[ASMD](0,2)+(FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5));
|
|
let s = Spawn("SuperShockSparkTrail",Vec3Offset(tracedir.x*i+pofs.x,tracedir.y*i+pofs.y,tracedir.z*i+pofs.z));
|
|
s.vel = (FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03));
|
|
}
|
|
if ( totaldist >= 10000.0 )
|
|
{
|
|
// reposition and explode on air
|
|
SetOrigin(t.Results.HitPos-t.Results.HitVector*4,true);
|
|
ExplodeMissile(t.Results.HitLine,null);
|
|
moving = false;
|
|
let r = Spawn("SuperShockBeamRing",pos);
|
|
r.angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x);
|
|
r.pitch = asin(-t.Results.HitVector.z);
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitNone )
|
|
{
|
|
// reposition
|
|
SetOrigin(t.Results.HitPos+t.Results.HitVector,true);
|
|
angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x);
|
|
pitch = asin(-t.Results.HitVector.z);
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitActor )
|
|
{
|
|
// reposition and explode on actor
|
|
SetOrigin(t.Results.HitPos-t.Results.HitVector*4,true);
|
|
ExplodeMissile(null,t.Results.HitActor);
|
|
if ( t.Results.HitActor is 'ShockHitbox' )
|
|
{
|
|
if ( target )
|
|
{
|
|
target.TakeInventory('EnhancedShockAmmo',1);
|
|
UTMainHandler.DoSwing(target,(FRandom[ASMD](-0.1,-0.6),FRandom[ASMD](-0.1,0.5)),10,-2,3,SWING_Spring,3,6);
|
|
}
|
|
let b = t.Results.HitActor.target;
|
|
UTMainHandler.DoBlast(b,400,70000);
|
|
b.ExplodeMissile(null,self);
|
|
b.A_Explode(Random[ASMD](15000,16000),400);
|
|
b.A_QuakeEx(9,9,9,60,0,2400,"",QF_RELATIVE|QF_SCALEDOWN,falloff:400,rollIntensity:0.4);
|
|
b.A_SprayDecal("BigShockMark1",100);
|
|
b.A_SprayDecal("SBigShockMark2",100);
|
|
Spawn("SuperShockRifleWave",b.pos);
|
|
Spawn("SuperShockBlastLight",b.pos);
|
|
let r = Spawn("SuperShockBlastRing",b.pos);
|
|
r.angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x);
|
|
r.pitch = asin(-t.Results.HitVector.z);
|
|
A_PlaySound("shock/blast",CHAN_WEAPON,attenuation:0.5);
|
|
A_PlaySound("sshock/blast",CHAN_6,attenuation:0.5);
|
|
int numpt = Random[ASMD](200,300);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](2,64);
|
|
let s = Spawn("SuperShockSpark",b.pos);
|
|
s.vel = pvel;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// the actor may "cease to exist" if it dies after the call to ExplodeMissile, so guard against that
|
|
if ( t.Results.HitActor )
|
|
{
|
|
t.Results.HitActor.DamageMobj(self,target,Random[ASMD](3500,5000),'joltedX',DMG_USEANGLE|DMG_THRUSTLESS,atan2(t.Results.HitVector.y,t.Results.HitVector.x));
|
|
UTMainHandler.DoKnockback(t.Results.HitActor,t.Results.HitVector,60000);
|
|
}
|
|
let r = Spawn("SuperShockBeamRing",pos);
|
|
r.angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x);
|
|
r.pitch = asin(-t.Results.HitVector.z);
|
|
}
|
|
t.lasthit = t.Results.HitActor;
|
|
}
|
|
else
|
|
{
|
|
// reposition and explode on wall
|
|
SetOrigin(t.Results.HitPos-t.Results.HitVector*4,true);
|
|
A_SprayDecal("ShockMark",16);
|
|
ExplodeMissile(t.Results.HitLine,null);
|
|
moving = false;
|
|
Vector3 HitNormal = t.Results.HitVector;
|
|
if ( t.Results.HitType == TRACE_HitWall )
|
|
{
|
|
t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,pos);
|
|
// calculate normal
|
|
HitNormal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
|
|
if ( t.Results.Side == 1 ) HitNormal *= -1;
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitFloor )
|
|
{
|
|
if ( t.Results.ffloor ) HitNormal = -t.Results.ffloor.top.Normal;
|
|
else HitNormal = t.Results.HitSector.floorplane.Normal;
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitCeiling )
|
|
{
|
|
if ( t.Results.ffloor ) HitNormal = -t.Results.ffloor.bottom.Normal;
|
|
else HitNormal = t.Results.HitSector.ceilingplane.Normal;
|
|
}
|
|
let r = Spawn("SuperShockBeamRing",pos);
|
|
r.angle = atan2(HitNormal.y,HitNormal.x);
|
|
r.pitch = asin(-HitNormal.z);
|
|
}
|
|
}
|
|
action void A_BeamExplode()
|
|
{
|
|
Spawn("SuperShockBeamLight",pos);
|
|
if ( !flak_classicsshock )
|
|
{
|
|
UTMainHandler.DoBlast(self,50,60000);
|
|
A_Explode(Random[ASMD](500,800),50);
|
|
}
|
|
A_QuakeEx(6,6,6,5,0,100,"",QF_RELATIVE|QF_SCALEDOWN,falloff:50,rollIntensity:0.2);
|
|
A_PlaySound("shock/hit",CHAN_VOICE,attenuation:0.5);
|
|
A_PlaySound("sshock/blast",CHAN_6,attenuation:0.5);
|
|
A_AlertMonsters();
|
|
int numpt = Random[ASMD](20,50);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](3,24);
|
|
let s = Spawn("SuperShockSpark",pos);
|
|
s.vel = pvel;
|
|
}
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
TNT1 A 1;
|
|
Wait;
|
|
Death:
|
|
TNT1 A 0 A_BeamExplode();
|
|
SSMX ABCDEFGHIJKL 1 Bright;
|
|
TNT1 A 100;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class ShockBallLight : DynamicLight
|
|
{
|
|
Default
|
|
{
|
|
DynamicLight.Type "Point";
|
|
Args 160,128,255,120;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( !target || target.InStateSequence(target.CurState,target.ResolveState("Death")) )
|
|
{
|
|
Destroy();
|
|
return;
|
|
}
|
|
SetOrigin(target.pos,true);
|
|
args[LIGHT_INTENSITY] = Random[ASMD](10,14)*10;
|
|
}
|
|
}
|
|
|
|
Class SuperShockBallLight : ShockBallLight
|
|
{
|
|
Default
|
|
{
|
|
DynamicLight.Type "Point";
|
|
Args 255,160,128,120;
|
|
}
|
|
}
|
|
|
|
Class ShockBeamLight : ShockExplLight
|
|
{
|
|
Default
|
|
{
|
|
+DYNAMICLIGHT.ATTENUATE;
|
|
ReactionTime 15;
|
|
Args 0,0,0,80;
|
|
}
|
|
}
|
|
|
|
Class SuperShockBeamLight : SuperShockExplLight
|
|
{
|
|
Default
|
|
{
|
|
+DYNAMICLIGHT.ATTENUATE;
|
|
ReactionTime 15;
|
|
Args 0,0,0,100;
|
|
}
|
|
}
|
|
|
|
Class ShockBeamHitLight : ShockExplLight
|
|
{
|
|
Default
|
|
{
|
|
ReactionTime 24;
|
|
Args 0,0,0,120;
|
|
}
|
|
}
|
|
|
|
Class SuperShockBeamHitLight : SuperShockExplLight
|
|
{
|
|
Default
|
|
{
|
|
ReactionTime 24;
|
|
Args 0,0,0,150;
|
|
}
|
|
}
|
|
|
|
Class ShockBlastLight : ShockExplLight
|
|
{
|
|
Default
|
|
{
|
|
ReactionTime 50;
|
|
Args 0,0,0,300;
|
|
}
|
|
}
|
|
|
|
Class SuperShockBlastLight : SuperShockExplLight
|
|
{
|
|
Default
|
|
{
|
|
ReactionTime 50;
|
|
Args 0,0,0,400;
|
|
}
|
|
}
|
|
|
|
Class ShockExplLight : DynamicLight
|
|
{
|
|
double lifetime;
|
|
Default
|
|
{
|
|
DynamicLight.Type "Point";
|
|
ReactionTime 30;
|
|
Args 160,128,255,150;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
lifetime = 1.0;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
args[LIGHT_RED] = int(160*lifetime);
|
|
args[LIGHT_GREEN] = int(128*lifetime);
|
|
args[LIGHT_BLUE] = int(255*lifetime);
|
|
lifetime -= 1./ReactionTime;
|
|
if ( lifetime <= 0 ) Destroy();
|
|
}
|
|
}
|
|
|
|
Class SuperShockExplLight : DynamicLight
|
|
{
|
|
double lifetime;
|
|
Default
|
|
{
|
|
DynamicLight.Type "Point";
|
|
ReactionTime 30;
|
|
Args 255,160,128,200;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
lifetime = 1.0;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
args[LIGHT_RED] = int(255*lifetime);
|
|
args[LIGHT_GREEN] = int(160*lifetime);
|
|
args[LIGHT_BLUE] = int(128*lifetime);
|
|
lifetime -= 1./ReactionTime;
|
|
if ( lifetime <= 0 ) Destroy();
|
|
}
|
|
}
|
|
|
|
Class ShockHitbox : Actor
|
|
{
|
|
Default
|
|
{
|
|
Radius 8;
|
|
Height 16;
|
|
+NOGRAVITY;
|
|
+NOCLIP;
|
|
+DONTSPLASH;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( !target || target.InStateSequence(target.CurState,target.ResolveState("Death")) )
|
|
{
|
|
Destroy();
|
|
return;
|
|
}
|
|
SetOrigin(target.pos-(0,0,height*0.5),true);
|
|
}
|
|
override bool CanCollideWith( Actor other, bool passive )
|
|
{
|
|
return ((other is 'ShockBeam') || (other is 'SuperShockBeam'));
|
|
}
|
|
}
|
|
|
|
Class ShockBall : Actor
|
|
{
|
|
Actor l, b;
|
|
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
l = Spawn("ShockBallLight",pos);
|
|
l.target = self;
|
|
b = Spawn("ShockHitbox",pos);
|
|
b.target = self;
|
|
}
|
|
action void A_BallExplode()
|
|
{
|
|
UTMainHandler.DoBlast(self,70,70000);
|
|
A_Explode(Random[ASMD](50,60),70);
|
|
A_SprayDecal("ShockMarkBig",16);
|
|
Spawn("ShockExplLight",pos);
|
|
A_SetScale(1.0);
|
|
let r = Spawn("ShockBeamRing",pos);
|
|
r.angle = angle;
|
|
r.pitch = pitch;
|
|
r.scale *= 1.5;
|
|
A_PlaySound("shock/hit",CHAN_VOICE);
|
|
A_PlaySound("shock/ball",CHAN_WEAPON);
|
|
A_QuakeEx(4,4,4,30,0,200,"",QF_RELATIVE|QF_SCALEDOWN,falloff:70,rollIntensity:0.15);
|
|
A_AlertMonsters();
|
|
int numpt = Random[ASMD](50,100);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](3,12);
|
|
let s = Spawn("ShockSpark",pos);
|
|
s.vel = pvel;
|
|
}
|
|
}
|
|
Default
|
|
{
|
|
Obituary "%k inflicted mortal damage upon %o with the Shock Rifle";
|
|
RenderStyle "Add";
|
|
DamageType 'jolted';
|
|
Radius 2;
|
|
Height 2;
|
|
Scale 0.4;
|
|
Speed 20;
|
|
PROJECTILE;
|
|
+FORCEXYBILLBOARD;
|
|
+SKYEXPLODE;
|
|
+EXPLODEONWATER;
|
|
+FORCERADIUSDMG;
|
|
+NODAMAGETHRUST;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
ASMB ABCD 2 Bright;
|
|
Loop;
|
|
Death:
|
|
TNT1 A 0 A_BallExplode();
|
|
ASMX ABCDEFGHIJKL 2 Bright;
|
|
TNT1 A 300;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class SuperShockBall : Actor
|
|
{
|
|
Actor l, b;
|
|
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
l = Spawn("SuperShockBallLight",pos);
|
|
l.target = self;
|
|
b = Spawn("ShockHitbox",pos);
|
|
b.target = self;
|
|
}
|
|
action void A_BallExplode()
|
|
{
|
|
UTMainHandler.DoBlast(self,120,70000);
|
|
A_Explode(Random[ASMD](4000,5000),120);
|
|
A_SprayDecal("ShockMarkBig",16);
|
|
Spawn("SuperShockExplLight",pos);
|
|
A_SetScale(1.5);
|
|
let r = Spawn("SuperShockBeamRing",pos);
|
|
r.angle = angle;
|
|
r.pitch = pitch;
|
|
r.scale *= 1.5;
|
|
A_PlaySound("shock/hit",CHAN_VOICE,attenuation:0.5);
|
|
A_PlaySound("shock/ball",CHAN_WEAPON,attenuation:0.5);
|
|
A_PlaySound("sshock/blast",CHAN_6,attenuation:0.5);
|
|
A_QuakeEx(8,8,8,30,0,300,"",QF_RELATIVE|QF_SCALEDOWN,falloff:120,rollIntensity:0.25);
|
|
A_AlertMonsters();
|
|
int numpt = Random[ASMD](50,100);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](3,24);
|
|
let s = Spawn("SuperShockSpark",pos);
|
|
s.vel = pvel;
|
|
}
|
|
}
|
|
Default
|
|
{
|
|
Obituary "%k electrified %o with the Enhanced Shock Rifle.";
|
|
RenderStyle "Add";
|
|
DamageType 'joltedX';
|
|
Radius 2;
|
|
Height 2;
|
|
Scale 0.5;
|
|
Speed 24;
|
|
PROJECTILE;
|
|
+FORCEXYBILLBOARD;
|
|
+SKYEXPLODE;
|
|
+FORCERADIUSDMG;
|
|
+EXTREMEDEATH;
|
|
+EXPLODEONWATER;
|
|
+FORCERADIUSDMG;
|
|
+NODAMAGETHRUST;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SSMB ABCD 2 Bright;
|
|
Loop;
|
|
Death:
|
|
TNT1 A 0 A_BallExplode();
|
|
SSMX ABCDEFGHIJKL 2 Bright;
|
|
TNT1 A 300;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class ViewShockSpark : ShockSpark
|
|
{
|
|
Vector3 ofs, vvel;
|
|
|
|
override void PostBeginPlay()
|
|
{
|
|
Actor.PostBeginPlay();
|
|
scale *= FRandom[Puff](0.4,0.9);
|
|
alpha *= FRandom[Puff](0.5,2.0);
|
|
roll = FRandom[ASMD](0,360);
|
|
}
|
|
|
|
override void Tick()
|
|
{
|
|
Actor.Tick();
|
|
if ( !target || !target.player )
|
|
{
|
|
Destroy();
|
|
return;
|
|
}
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_Matrix4.GetAxes(target.pitch,target.angle,target.roll);
|
|
Vector3 origin = x*ofs.x+y*ofs.y+z*ofs.z+(0,0,target.player.viewz);
|
|
SetOrigin(target.Vec2OffsetZ(origin.x,origin.y,origin.z),true);
|
|
bInvisible = (players[consoleplayer].camera != target);
|
|
if ( level.frozen || globalfreeze ) return;
|
|
ofs += vvel;
|
|
vvel *= 0.9;
|
|
scale *= 0.8;
|
|
if ( scale.x <= 0.01 ) Destroy();
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
ASMK A 1 Bright A_FadeOut(FRandom[ASMD](0.0,0.1));
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
Class ShockRifle : UTWeapon
|
|
{
|
|
action void A_ShockFire()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( weap.Ammo1.Amount <= 0 ) return;
|
|
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
|
A_PlaySound("shock/fire",CHAN_WEAPON);
|
|
invoker.FireEffect();
|
|
UTMainHandler.DoFlash(self,Color(128,128,0,255),1);
|
|
UTMainHandler.DoSwing(self,(FRandom[ASMD](-0.1,-0.6),FRandom[ASMD](-0.1,0.5)),2,-0.3,3,SWING_Spring,0,4);
|
|
A_AlertMonsters();
|
|
A_QuakeEx(2,2,2,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-1.5*z;
|
|
Actor p = Spawn("ShockBeam",origin);
|
|
p.angle = angle;
|
|
p.pitch = BulletSlope();
|
|
p.target = self;
|
|
for ( int i=0; i<12; i++ )
|
|
{
|
|
let s = Spawn("UTViewSmoke",origin);
|
|
UTViewSmoke(s).ofs = (10,2,-1.5);
|
|
s.scale *= 1.8;
|
|
s.target = self;
|
|
s.SetShade("C080FF");
|
|
s.A_SetRenderStyle(0.4,STYLE_AddShaded);
|
|
UTViewSmoke(s).vvel += (FRandom[ASMD](0.2,0.6),FRandom[ASMD](-0.2,0.2),FRandom[ASMD](-0.2,0.2));
|
|
}
|
|
int numpt = Random[ASMD](20,40);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
let s = Spawn("ViewShockSpark",origin);
|
|
ViewShockSpark(s).ofs = (10,2,-1.5);
|
|
s.target = self;
|
|
ViewShockSpark(s).vvel += (FRandom[ASMD](0.5,2.0),FRandom[ASMD](-1.5,1.5),FRandom[ASMD](-1.5,1.5));
|
|
}
|
|
}
|
|
action void A_ShockAlt()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( weap.Ammo1.Amount <= 0 ) return;
|
|
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
|
A_PlaySound("shock/altfire",CHAN_WEAPON);
|
|
invoker.FireEffect();
|
|
UTMainHandler.DoFlash(self,Color(128,128,0,255),1);
|
|
UTMainHandler.DoSwing(self,(FRandom[ASMD](-0.1,-0.6),FRandom[ASMD](-0.1,0.5)),3,-0.4,3,SWING_Spring,0,4);
|
|
A_AlertMonsters();
|
|
A_QuakeEx(2,2,2,8,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-1.5*z;
|
|
Actor p = Spawn("ShockBall",origin);
|
|
p.angle = angle;
|
|
p.pitch = BulletSlope();
|
|
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed;
|
|
p.target = self;
|
|
for ( int i=0; i<12; i++ )
|
|
{
|
|
let s = Spawn("UTViewSmoke",origin);
|
|
UTViewSmoke(s).ofs = (10,2,-1.5);
|
|
s.scale *= 2.2;
|
|
s.target = self;
|
|
s.SetShade("C080FF");
|
|
s.A_SetRenderStyle(0.4,STYLE_AddShaded);
|
|
UTViewSmoke(s).vvel += (FRandom[ASMD](0.4,1.2),FRandom[ASMD](-0.4,0.4),FRandom[ASMD](-0.4,0.4));
|
|
}
|
|
int numpt = Random[ASMD](20,40);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
let s = Spawn("ViewShockSpark",origin);
|
|
ViewShockSpark(s).ofs = (10,2,-1.5);
|
|
s.target = self;
|
|
ViewShockSpark(s).vvel += (FRandom[ASMD](0.5,2.0),FRandom[ASMD](-1.5,1.5),FRandom[ASMD](-1.5,1.5));
|
|
}
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "Shock Rifle";
|
|
Inventory.PickupMessage "You got the ASMD Shock Rifle.";
|
|
Weapon.UpSound "shock/select";
|
|
Weapon.SlotNumber 4;
|
|
Weapon.SelectionOrder 6;
|
|
Weapon.AmmoType "ShockAmmo";
|
|
Weapon.AmmoUse 1;
|
|
Weapon.AmmoType2 "ShockAmmo";
|
|
Weapon.AmmoUse2 1;
|
|
Weapon.AmmoGive 20;
|
|
UTWeapon.DropAmmo 5;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
ASMP A -1;
|
|
Stop;
|
|
ASMP B -1;
|
|
Stop;
|
|
Ready:
|
|
ASMS ABCDEFGHIJKLMNO 1 A_WeaponReady(WRF_NOFIRE);
|
|
Idle:
|
|
ASMI A 1
|
|
{
|
|
A_CheckReload();
|
|
A_WeaponReady();
|
|
}
|
|
Wait;
|
|
Fire:
|
|
ASMF A 1 A_ShockFire();
|
|
ASMF BCDEFGHIJJ 2;
|
|
Goto Idle;
|
|
AltFire:
|
|
ASMA A 1 A_ShockAlt();
|
|
ASMA BCDFGHIJ 2;
|
|
Goto Idle;
|
|
Deselect:
|
|
ASMD ABCDEFG 1;
|
|
ASMD G 1 A_Lower(int.max);
|
|
Wait;
|
|
Select:
|
|
ASMS A 1 A_Raise(int.max);
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
Class EnhancedShockAmmo : Ammo
|
|
{
|
|
int ticcnt;
|
|
|
|
override void BeginPlay()
|
|
{
|
|
Super.BeginPlay();
|
|
if ( deathmatch )
|
|
{
|
|
MaxAmount /= 2;
|
|
BackpackMaxAmount /= 2;
|
|
}
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( !Owner ) return;
|
|
ticcnt++;
|
|
if ( ticcnt < 105 ) return;
|
|
ticcnt = 0;
|
|
if ( Amount > 0 ) Amount--;
|
|
}
|
|
Default
|
|
{
|
|
Tag "Enhanced Shock Core";
|
|
Inventory.PickupMessage "You picked up an Enhanced Shock Core.";
|
|
Inventory.Amount 5;
|
|
Inventory.MaxAmount 50;
|
|
Ammo.BackpackAmount 0;
|
|
Ammo.BackpackMaxAmount 50;
|
|
Ammo.DropAmount 2;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SHOA A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class ViewSuperShockSpark : ViewShockSpark
|
|
{
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
SSMK A 1 Bright A_FadeOut(FRandom[ASMD](0.0,0.1));
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
Class EnhancedShockRifle : UTWeapon
|
|
{
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
}
|
|
action void A_SShockFire()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( weap.Ammo1.Amount <= 0 ) return;
|
|
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
|
A_PlaySound("shock/fire",CHAN_WEAPON);
|
|
invoker.FireEffect();
|
|
UTMainHandler.DoFlash(self,Color(128,255,128,0),1);
|
|
UTMainHandler.DoSwing(self,(FRandom[ASMD](-0.1,-0.6),FRandom[ASMD](-0.1,0.5)),4,-0.6,3,SWING_Spring,0,4);
|
|
A_AlertMonsters();
|
|
A_QuakeEx(3,3,3,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.15);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-1.5*z;
|
|
Actor p = Spawn("SuperShockBeam",origin);
|
|
p.angle = angle;
|
|
p.pitch = BulletSlope();
|
|
p.target = self;
|
|
for ( int i=0; i<12; i++ )
|
|
{
|
|
let s = Spawn("UTViewSmoke",origin);
|
|
UTViewSmoke(s).ofs = (10,2,-1.5);
|
|
s.scale *= 1.8;
|
|
s.target = self;
|
|
s.SetShade("FFC040");
|
|
s.A_SetRenderStyle(0.4,STYLE_AddShaded);
|
|
UTViewSmoke(s).vvel += (FRandom[ASMD](0.2,0.6),FRandom[ASMD](-0.2,0.2),FRandom[ASMD](-0.2,0.2));
|
|
}
|
|
int numpt = Random[ASMD](20,40);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
let s = Spawn("ViewSuperShockSpark",origin);
|
|
ViewShockSpark(s).ofs = (10,2,-1.5);
|
|
s.target = self;
|
|
ViewShockSpark(s).vvel += (FRandom[ASMD](0.5,2.0),FRandom[ASMD](-1.5,1.5),FRandom[ASMD](-1.5,1.5));
|
|
}
|
|
}
|
|
action void A_SShockAlt()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( weap.Ammo1.Amount <= 0 ) return;
|
|
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
|
A_PlaySound("shock/altfire",CHAN_WEAPON);
|
|
invoker.FireEffect();
|
|
UTMainHandler.DoFlash(self,Color(128,255,128,0),1);
|
|
UTMainHandler.DoSwing(self,(FRandom[ASMD](-0.1,-0.6),FRandom[ASMD](-0.1,0.5)),6,-0.8,3,SWING_Spring,0,4);
|
|
A_AlertMonsters();
|
|
A_QuakeEx(3,3,3,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.15);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-1.5*z;
|
|
Actor p = Spawn("SuperShockBall",origin);
|
|
p.angle = angle;
|
|
p.pitch = BulletSlope();
|
|
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed;
|
|
p.target = self;
|
|
for ( int i=0; i<12; i++ )
|
|
{
|
|
let s = Spawn("UTViewSmoke",origin);
|
|
UTViewSmoke(s).ofs = (10,2,-1.5);
|
|
s.scale *= 2.2;
|
|
s.target = self;
|
|
s.SetShade("FFC040");
|
|
s.A_SetRenderStyle(0.4,STYLE_AddShaded);
|
|
UTViewSmoke(s).vvel += (FRandom[ASMD](0.4,1.2),FRandom[ASMD](-0.4,0.4),FRandom[ASMD](-0.4,0.4));
|
|
}
|
|
int numpt = Random[ASMD](20,40);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
let s = Spawn("ViewSuperShockSpark",origin);
|
|
ViewShockSpark(s).ofs = (10,2,-1.5);
|
|
s.target = self;
|
|
ViewShockSpark(s).vvel += (FRandom[ASMD](0.5,2.0),FRandom[ASMD](-1.5,1.5),FRandom[ASMD](-1.5,1.5));
|
|
}
|
|
}
|
|
override bool CheckAmmo( int fireMode, bool autoSwitch, bool requireAmmo, int ammocount )
|
|
{
|
|
if ( (Owner.player.ReadyWeapon != self) && (Ammo1.Amount <= 0) ) return false;
|
|
return Super.CheckAmmo(fireMode,autoSwitch,requireAmmo,ammocount);
|
|
}
|
|
Default
|
|
{
|
|
Tag "Enhanced Shock Rifle";
|
|
Inventory.PickupMessage "You got an Enhanced Shock Rifle!";
|
|
Weapon.UpSound "shock/select";
|
|
Weapon.SlotNumber 4;
|
|
Weapon.SelectionOrder 6;
|
|
+INVENTORY.ALWAYSPICKUP;
|
|
Weapon.AmmoType "EnhancedShockAmmo";
|
|
Weapon.AmmoUse 1;
|
|
Weapon.AmmoType2 "EnhancedShockAmmo";
|
|
Weapon.AmmoUse2 1;
|
|
Weapon.AmmoGive 50;
|
|
UTWeapon.DropAmmo 5;
|
|
+WEAPON.AMMO_OPTIONAL;
|
|
+WEAPON.ALT_AMMO_OPTIONAL;
|
|
+WEAPON.CHEATNOTWEAPON;
|
|
+INVENTORY.IGNORESKILL;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
ASMP A -1;
|
|
Stop;
|
|
ASMP B -1;
|
|
Stop;
|
|
Ready:
|
|
ASMS ABCDEFGHIJKLMNO 1 A_WeaponReady(WRF_NOFIRE);
|
|
Idle:
|
|
ASMI A 1 A_WeaponReady();
|
|
Wait;
|
|
Fire:
|
|
ASMI A 0 A_JumpIfNoAmmo("DryFire");
|
|
ASMF A 1 A_SShockFire();
|
|
ASMF BCDEFGHIJJ 2;
|
|
Goto Idle;
|
|
AltFire:
|
|
ASMI A 0 A_JumpIf(flak_classicsshock,"Fire");
|
|
ASMI A 0 A_JumpIfNoAmmo("DryFire");
|
|
ASMA A 1 A_SShockAlt();
|
|
ASMA BCDFGHIJ 2;
|
|
Goto Idle;
|
|
DryFire:
|
|
ASMA I 3
|
|
{
|
|
A_PlaySound("sshock/dryfire",CHAN_WEAPON);
|
|
A_AlertMonsters();
|
|
}
|
|
ASMA J 4;
|
|
ASMI A 10;
|
|
Goto Idle;
|
|
Deselect:
|
|
ASMD ABCDEFG 1;
|
|
ASMD G 1 A_Lower(int.max);
|
|
Wait;
|
|
Select:
|
|
ASMS A 1 A_Raise(int.max);
|
|
Wait;
|
|
}
|
|
}
|