Reduced spread of grenades. Increased size of rocket trail (looks a bit closer to UT now). Increased radius of single bullet pickup, might have been too small for collision to work properly.
1111 lines
24 KiB
Text
1111 lines
24 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 50;
|
|
Ammo.DropAmount 5;
|
|
Radius 4;
|
|
Height 23;
|
|
}
|
|
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) )
|
|
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 0;
|
|
+NOBLOCKMAP;
|
|
+NOGRAVITY;
|
|
+MISSILE;
|
|
+FORCEXYBILLBOARD;
|
|
+THRUACTORS;
|
|
+ROLLSPRITE;
|
|
+ROLLCENTER;
|
|
+NOTELEPORT;
|
|
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;
|
|
}
|
|
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);
|
|
let b = t.Results.HitActor.target;
|
|
b.ExplodeMissile(null,self);
|
|
b.A_Explode(Random[ASMD](150,160),300);
|
|
b.A_QuakeEx(6,6,6,60,0,1200,"",QF_RELATIVE|QF_SCALEDOWN,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');
|
|
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 == 1 ) HitNormal *= -1;
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitFloor )
|
|
HitNormal = t.Results.HitSector.floorplane.Normal;
|
|
else if ( t.Results.HitType == TRACE_HitCeiling )
|
|
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,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();
|
|
AEXP ABCDEFGHIJKL 1 Bright;
|
|
TNT1 A 100;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class SuperShockSpark : Actor
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
Radius 2;
|
|
Height 0;
|
|
+NOBLOCKMAP;
|
|
+NOGRAVITY;
|
|
+MISSILE;
|
|
+FORCEXYBILLBOARD;
|
|
+THRUACTORS;
|
|
+ROLLSPRITE;
|
|
+ROLLCENTER;
|
|
+NOTELEPORT;
|
|
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 'jolted';
|
|
RenderStyle "Add";
|
|
Radius 0.1;
|
|
Height 0;
|
|
Scale 0.7;
|
|
+NOGRAVITY;
|
|
+NOCLIP;
|
|
+DONTSPLASH;
|
|
+FORCEXYBILLBOARD;
|
|
+FORCERADIUSDMG;
|
|
+EXTREMEDEATH;
|
|
}
|
|
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',2);
|
|
let b = t.Results.HitActor.target;
|
|
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,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
|
|
{
|
|
t.Results.HitActor.DamageMobj(self,target,Random[ASMD](3500,5000),'jolted');
|
|
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 )
|
|
HitNormal = t.Results.HitSector.floorplane.Normal;
|
|
else if ( t.Results.HitType == TRACE_HitCeiling )
|
|
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);
|
|
A_Explode(Random[ASMD](500,800),90);
|
|
A_QuakeEx(6,6,6,5,0,200,"",QF_RELATIVE|QF_SCALEDOWN,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();
|
|
SEXP 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] = 160*lifetime;
|
|
args[LIGHT_GREEN] = 128*lifetime;
|
|
args[LIGHT_BLUE] = 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] = 255*lifetime;
|
|
args[LIGHT_GREEN] = 160*lifetime;
|
|
args[LIGHT_BLUE] = 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);
|
|
}
|
|
}
|
|
|
|
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()
|
|
{
|
|
A_Explode(Random[ASMD](40,50),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,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';
|
|
DamageFunction Random[ASMD](50,60);
|
|
Radius 2;
|
|
Height 2;
|
|
Scale 0.4;
|
|
Speed 20;
|
|
PROJECTILE;
|
|
+FORCEXYBILLBOARD;
|
|
+SKYEXPLODE;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
ABAL ABCD 2 Bright;
|
|
Loop;
|
|
Death:
|
|
TNT1 A 0 A_BallExplode();
|
|
AEXP 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()
|
|
{
|
|
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,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 'jolted';
|
|
DamageFunction Random[ASMD](5000,6000);
|
|
Radius 2;
|
|
Height 2;
|
|
Scale 0.5;
|
|
Speed 25;
|
|
PROJECTILE;
|
|
+FORCEXYBILLBOARD;
|
|
+SKYEXPLODE;
|
|
+FORCERADIUSDMG;
|
|
+EXTREMEDEATH;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SBAL ABCD 2 Bright;
|
|
Loop;
|
|
Death:
|
|
TNT1 A 0 A_BallExplode();
|
|
SEXP ABCDEFGHIJKL 2 Bright;
|
|
TNT1 A 300;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
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);
|
|
A_AlertMonsters();
|
|
A_QuakeEx(3,3,3,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+3.0*y-4.0*z;
|
|
Actor p = Spawn("ShockBeam",origin);
|
|
p.angle = angle;
|
|
p.pitch = BulletSlope();
|
|
p.target = self;
|
|
}
|
|
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);
|
|
A_AlertMonsters();
|
|
A_QuakeEx(3,3,3,8,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+3.0*y-4.0*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;
|
|
}
|
|
|
|
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;
|
|
Radius 20;
|
|
Height 16;
|
|
UTWeapon.DroppedHeight 8;
|
|
}
|
|
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 BCDEFGHIJ 2;
|
|
Goto Idle;
|
|
AltFire:
|
|
ASMA A 1 A_ShockAlt();
|
|
ASMA BCDEFGHIJ 2;
|
|
Goto Idle;
|
|
Deselect:
|
|
ASMD ABCDEFG 2;
|
|
ASMD G 1 A_Lower(int.max);
|
|
Wait;
|
|
Select:
|
|
ASMS A 1 A_Raise(int.max);
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
Class EnhancedShockAmmo : Ammo
|
|
{
|
|
Default
|
|
{
|
|
Tag "Enhanced Shock Core";
|
|
Inventory.PickupMessage "You picked up an Enhanced Shock Core.";
|
|
Inventory.Amount 5;
|
|
Inventory.MaxAmount 25;
|
|
Ammo.BackpackAmount 0;
|
|
Ammo.BackpackMaxAmount 25;
|
|
Ammo.DropAmount 2;
|
|
Radius 4;
|
|
Height 23;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SHOA A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class EnhancedShockRifle : UTWeapon replaces InvulnerabilitySphere
|
|
{
|
|
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);
|
|
A_AlertMonsters();
|
|
A_QuakeEx(8,8,8,12,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+3.0*y-4.0*z;
|
|
Actor p = Spawn("SuperShockBeam",origin);
|
|
p.angle = angle;
|
|
p.pitch = BulletSlope();
|
|
p.target = self;
|
|
}
|
|
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);
|
|
A_AlertMonsters();
|
|
A_QuakeEx(8,8,8,16,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+3.0*y-4.0*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;
|
|
}
|
|
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 25;
|
|
Radius 20;
|
|
Height 16;
|
|
UTWeapon.DroppedHeight 8;
|
|
}
|
|
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_SShockFire();
|
|
ASMF BCDEFGHIJ 2;
|
|
Goto Idle;
|
|
AltFire:
|
|
ASMA A 1 A_SShockAlt();
|
|
ASMA BCDEFGHIJ 2;
|
|
Goto Idle;
|
|
Deselect:
|
|
ASMD ABCDEFG 2;
|
|
ASMD G 1 A_Lower(int.max);
|
|
Wait;
|
|
Select:
|
|
ASMS A 1 A_Raise(int.max);
|
|
Wait;
|
|
}
|
|
}
|