swwmgz_m/zscript/swwm_blazeit.zsc
Marisa Kirisame 0acdce0327 Eviscerator chunks leave visible trails, sparks also, sparkles from Ynykron singularity explosions too, this looks absolutely amazing let me tell ya.
Alternate sprites for Hellblazer explosion trails.
Alternate sprites for Eviscerator explosion ring.
A couple extra things that will be needed in the future.
2021-01-14 20:27:21 +01:00

2103 lines
54 KiB
Text

// Imanaki Corp Hellfire Cannon Mk3, aka "Hellblazer" (from SWWM series, originally inspired by the Hellraiser from OMGWEAPONS)
// Slot 6, replaces Rocket Launcher, Phoenix Rod, Firestorm
Class HellblazerExplLight : PaletteLight
{
Default
{
Tag "HellExpl";
Args 0,0,0,200;
ReactionTime 25;
}
}
Class HellblazerExplLight2 : PaletteLight
{
Default
{
Tag "HellExpl";
Args 0,0,0,120;
ReactionTime 20;
}
}
Class HellblazerExplLight3 : PaletteLight
{
Default
{
Tag "HellExpl";
Args 0,0,0,900;
ReactionTime 60;
}
}
Class HellblazerSubExpl : Actor
{
Default
{
RenderStyle "Add";
Scale 2.2;
Radius 0.1;
Height 0;
Alpha .75;
+NOGRAVITY;
+NOBLOCKMAP;
+FORCEXYBILLBOARD;
+NOTELEPORT;
+NOINTERACTION;
+ROLLSPRITE;
+ROLLCENTER;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
roll = FRandom[ExploS](0,360);
scale.x *= RandomPick[ExploS](-1,1);
scale.y *= RandomPick[ExploS](-1,1);
}
override void Tick()
{
if ( isFrozen() ) return;
if ( !CheckNoDelay() || (tics == -1) ) return;
if ( tics > 0 ) tics--;
while ( !tics )
{
if ( !SetState(CurState.NextState) )
return;
}
}
States
{
Spawn:
XEX0 ABCDEFGHIJKLMNOPQRS 1 Bright;
Stop;
}
}
Class HellblazerRing : Actor
{
Default
{
RenderStyle "Add";
Scale 2.;
Radius 0.1;
Height 0;
+NOGRAVITY;
+NOBLOCKMAP;
+FORCEXYBILLBOARD;
+NOTELEPORT;
+NOINTERACTION;
}
override void Tick()
{
if ( isFrozen() ) return;
if ( !CheckNoDelay() || (tics == -1) ) return;
if ( tics > 0 ) tics--;
while ( !tics )
{
if ( !SetState(CurState.NextState) )
return;
}
}
States
{
Spawn:
XRG3 ACEGIKMOQSUW 1 Bright A_SetScale(scale.x*1.15);
Stop;
}
}
Class HellblazerRing2 : Actor
{
Default
{
RenderStyle "Add";
Scale 3.;
Radius 0.1;
Height 0;
+NOGRAVITY;
+NOBLOCKMAP;
+FORCEXYBILLBOARD;
+NOTELEPORT;
+NOINTERACTION;
}
override void Tick()
{
if ( isFrozen() ) return;
if ( !CheckNoDelay() || (tics == -1) ) return;
if ( tics > 0 ) tics--;
while ( !tics )
{
if ( !SetState(CurState.NextState) )
return;
}
}
States
{
Spawn:
XRG3 ABCDEFGHIJKLMNOPQRSTUVWX 1 Bright A_SetScale(scale.x*1.1);
Stop;
}
}
Class HellblazerTrail : Actor
{
Default
{
RenderStyle "Add";
Radius .1;
Height 0.;
Scale .2;
Alpha .3;
+NOGRAVITY;
+NOBLOCKMAP;
+DONTSPLASH;
+NOTELEPORT;
+FORCEXYBILLBOARD;
+NOINTERACTION;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
SetState(FindState("Spawn")+Random[ExploS](0,7));
}
override void Tick()
{
if ( isFrozen() ) return;
if ( !CheckNoDelay() || (tics == -1) ) return;
if ( tics > 0 ) tics--;
while ( !tics )
{
if ( !SetState(CurState.NextState) )
return;
}
}
States
{
Spawn:
JFLR ABCDEFGH 1 Bright
{
A_FadeOut(.06);
A_SetScale(scale.x*.95);
if ( waterlevel > 0 )
{
let b = Spawn("SWWMBubble",pos);
b.vel = vel;
b.scale *= scale.x;
Destroy();
}
}
Loop;
}
}
Class HellblazerFlare : Actor
{
Default
{
RenderStyle "Add";
Radius .1;
Height 0.;
+NOGRAVITY;
+NOBLOCKMAP;
+DONTSPLASH;
+NOTELEPORT;
+FORCEXYBILLBOARD;
+NOINTERACTION;
}
override void PostBeginPlay()
{
if ( !master ) return;
State sp = FindState("Spawn");
if ( master is 'HellblazerCrackshot' ) SetState(sp+1);
else if ( master is 'HellblazerRavager' ) SetState(sp+2);
else if ( master is 'HellblazerWarhead' ) SetState(sp+3);
}
override void Tick()
{
if ( isFrozen() ) return;
if ( !master || !master.bMISSILE )
{
Destroy();
return;
}
Vector3 traildir = -(cos(master.angle)*cos(master.pitch),sin(master.angle)*cos(master.pitch),sin(-master.pitch));
SetOrigin(level.Vec3Offset(master.pos,traildir*3),true);
}
States
{
Spawn:
HFLR ABCD -1 Bright;
Stop;
}
}
// rockets
Class HellblazerMissile : Actor
{
int deto;
Default
{
Obituary "$O_HELLBLAZER";
DamageType 'Exploded';
Radius 4;
Height 8;
Speed 50;
PROJECTILE;
+EXPLODEONWATER;
+FORCERADIUSDMG;
+NODAMAGETHRUST;
+HITTRACER;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( bNOGRAVITY )
{
A_StartSound("hellblazer/fly",CHAN_BODY,CHANF_LOOP,1.,2.);
let t = Spawn("HellblazerFlare",pos);
t.master = self;
}
}
void A_BlazerTick( Color smokecol )
{
Vector3 traildir = -(cos(angle)*cos(pitch),sin(angle)*cos(pitch),sin(-pitch));
for ( int i=0; i<3; i++ )
{
let s = Spawn("SWWMHalfSmoke",level.Vec3Offset(pos,traildir*3));
s.SetShade(smokecol*Random[Hellblazer](48,63));
s.scale *= FRandom[Hellblazer](.8,1.2);
s.special1 = Random[Hellblazer](0,2);
s.alpha *= .5;
s.vel = .3*vel + (traildir+(FRandom[Hellblazer](-.4,.4),FRandom[Hellblazer](-.4,.4),FRandom[Hellblazer](-.4,.4))).unit()*FRandom[Hellblazer](1.,2.);
}
if ( bNOGRAVITY )
{
for ( double i=0.; i<vel.length(); i+= 5. )
{
let t = Spawn("HellblazerTrail",level.Vec3Offset(pos,-vel.unit()*i+traildir*3));
t.vel = traildir*4.;
}
}
if ( deto > 1 )
{
ExplodeMissile();
return;
}
// proximity check
let bt = BlockThingsIterator.Create(self,200);
while ( bt.Next() )
{
let t = bt.Thing;
if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),bNOGRAVITY?50:90) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
deto++;
tracer = t;
break;
}
}
void A_BlazerMissileExplode()
{
bForceXYBillboard = true;
bRollSprite = false;
A_SetRenderStyle(1.0,STYLE_Add);
A_SprayDecal("BigRocketBlast",50);
A_SetScale(4.5);
SWWMUtility.DoExplosion(self,200,320000,200,90);
A_NoGravity();
A_QuakeEx(5,5,5,15,0,1500,"",QF_RELATIVE|QF_SCALEDOWN,falloff:500,rollIntensity:.8);
A_StopSound(CHAN_BODY);
A_StartSound("hellblazer/hitm",CHAN_WEAPON,attenuation:.8);
A_StartSound("hellblazer/hitm",CHAN_VOICE,attenuation:.5);
A_AlertMonsters(swwm_uncapalert?0:2500);
Spawn("HellblazerExplLight",pos);
int numpt = Random[Hellblazer](12,24);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](2,8);
let s = Spawn("SWWMSmoke",pos);
s.vel = pvel;
s.SetShade(Color(4,2,1)*Random[Hellblazer](48,63));
s.special1 = Random[Hellblazer](1,4);
s.scale *= 2.8;
s.alpha *= .4;
}
numpt = Random[Hellblazer](8,12);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](4,12);
let s = Spawn("SWWMSpark",pos);
s.vel = pvel;
}
numpt = Random[Hellblazer](12,16);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](10,20);
let s = Spawn("SWWMChip",pos);
s.vel = pvel;
s.scale *= FRandom[Hellblazer](0.9,1.8);
}
Spawn("HellblazerRing",pos);
if ( swwm_omnibust ) BusterWall.ProjectileBust(self,350,(cos(angle)*cos(pitch),sin(angle)*cos(pitch),sin(-pitch)));
}
void A_SubExpl( double xscale = 1. )
{
special1++;
if ( (special1 > 8) || !(special1%2) ) return;
int numpt = Random[Hellblazer](0,8-special1);
double ang, pt;
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Hellblazer](0,360);
pt = FRandom[Hellblazer](-90,90);
FLineTraceData d;
Vector3 HitNormal;
LineTrace(ang,FRandom[Hellblazer](10,20)+10*special1*xscale,pt,TRF_THRUACTORS,data:d);
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("HellblazerSubExpl",d.HitLocation+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = target;
p.scale *= xscale*(2-special1*.1);
p.alpha *= 1-special1*.1;
}
}
States
{
Spawn:
XZW1 A 1 A_BlazerTick(Color(4,3,2));
Wait;
Death:
TNT1 A 0 A_BlazerMissileExplode();
HEXP ABCDEFGHIJKLMNOPQR 1 Bright A_SubExpl();
Stop;
}
}
Class HellblazerCrackshot : HellblazerMissile
{
void A_BlazerCrackshotExplode()
{
bForceXYBillboard = true;
bRollSprite = false;
A_SetRenderStyle(1.0,STYLE_Add);
A_SprayDecal("BigRocketBlast",50);
A_SetScale(6.);
SWWMUtility.DoExplosion(self,200,320000,250,100);
A_NoGravity();
A_QuakeEx(6,6,6,20,0,2000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:800,rollIntensity:1.);
A_StopSound(CHAN_BODY);
A_StartSound("hellblazer/hitc",CHAN_WEAPON,attenuation:.7);
A_StartSound("hellblazer/hitc",CHAN_VOICE,attenuation:.4);
A_AlertMonsters(swwm_uncapalert?0:3000);
Spawn("HellblazerExplLight",pos);
int numpt = Random[Hellblazer](12,24);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](2,8);
let s = Spawn("SWWMSmoke",pos);
s.vel = pvel;
s.SetShade(Color(4,2,1)*Random[Hellblazer](48,63));
s.special1 = Random[Hellblazer](1,4);
s.scale *= 2.8;
s.alpha *= .4;
}
numpt = Random[Hellblazer](8,12);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](4,12);
let s = Spawn("SWWMSpark",pos);
s.vel = pvel;
}
numpt = Random[Hellblazer](12,16);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](10,20);
let s = Spawn("SWWMChip",pos);
s.vel = pvel;
s.scale *= FRandom[Hellblazer](0.9,1.8);
}
Spawn("HellblazerRing",pos);
for ( int i=0; i<8; i++ )
{
double ang = FRandom[Hellblazer](0,360);
double pt = FRandom[Hellblazer](-90,90);
let c = Spawn("HellblazerClusterMini",pos);
c.angle = ang;
c.pitch = pt;
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),sin(-pt))*c.speed*FRandom[Hellblazer](.8,1.2);
c.target = target;
c.ReactionTime += Random[Hellblazer](-10,10);
HellblazerClusterMini(c).A_Steer(tracer);
}
if ( swwm_omnibust ) BusterWall.ProjectileBust(self,300,(cos(angle)*cos(pitch),sin(angle)*cos(pitch),sin(-pitch)));
}
States
{
Spawn:
XZW1 A 1 A_BlazerTick(Color(2,4,2));
Wait;
Death:
TNT1 A 0 A_BlazerCrackshotExplode();
HEXP ABCDEFGHIJKLMNOPQR 1 Bright A_SubExpl(1.25);
Stop;
}
}
Class HellblazerRavager : HellblazerMissile
{
void A_BlazerRavagerExplode()
{
bForceXYBillboard = true;
bRollSprite = false;
A_SetRenderStyle(1.0,STYLE_Add);
A_SprayDecal("HugeRocketBlast",50);
A_SetScale(8.);
SWWMUtility.DoExplosion(self,350,320000,300,120);
A_NoGravity();
A_QuakeEx(6,6,6,30,0,2000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:800,rollIntensity:1.);
A_StopSound(CHAN_BODY);
A_StartSound("hellblazer/hitr",CHAN_WEAPON,attenuation:.6);
A_StartSound("hellblazer/hitr",CHAN_VOICE,attenuation:.3);
A_AlertMonsters(swwm_uncapalert?0:4500);
Spawn("HellblazerExplLight",pos);
int numpt = Random[Hellblazer](16,28);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](4,12);
let s = Spawn("SWWMSmoke",pos);
s.vel = pvel;
s.SetShade(Color(4,2,1)*Random[Hellblazer](48,63));
s.special1 = Random[Hellblazer](2,5);
s.scale *= 3.2;
s.alpha *= .3;
}
numpt = Random[Hellblazer](8,12);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](4,12);
let s = Spawn("SWWMSpark",pos);
s.vel = pvel;
}
numpt = Random[Hellblazer](12,20);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](10,20);
let s = Spawn("SWWMChip",pos);
s.vel = pvel;
s.scale *= FRandom[Hellblazer](0.9,1.8);
}
Spawn("HellblazerRing",pos);
if ( swwm_omnibust ) BusterWall.ProjectileBust(self,400,(cos(angle)*cos(pitch),sin(angle)*cos(pitch),sin(-pitch)));
}
void A_RavagerSub()
{
special2++;
if ( (special2 > 10) || (special2%3) ) return;
int numpt = 11-special2;
for ( int i=0; i<numpt; i++ )
{
double ang = FRandom[Hellblazer](0,360);
double pt = FRandom[Hellblazer](-90,90);
let c = Spawn("HellblazerRavagerArm",pos);
c.angle = ang;
c.pitch = pt;
c.target = target;
}
}
States
{
Spawn:
XZW1 A 1 A_BlazerTick(Color(4,2,2));
Wait;
Death:
TNT1 A 0 A_BlazerRavagerExplode();
HEXP ABCDEFGHIJKLMNOPQR 1 Bright
{
A_SubExpl(2.);
A_RavagerSub();
}
Stop;
}
}
Class HellblazerWarhead : HellblazerMissile
{
void A_BlazerWarheadExplode()
{
bForceXYBillboard = true;
bRollSprite = false;
A_SetRenderStyle(1.0,STYLE_Add);
A_SprayDecal("WumboRocketBlast",150);
A_SetScale(7.);
SWWMUtility.DoExplosion(self,1500,600000,400,200);
A_NoGravity();
A_QuakeEx(9,9,9,150,0,12000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:4000,rollIntensity:2.);
A_StopSound(CHAN_BODY);
A_StartSound("hellblazer/hitw",CHAN_WEAPON,attenuation:.4);
A_StartSound("hellblazer/hitw",CHAN_VOICE,attenuation:.1);
A_AlertMonsters(swwm_uncapalert?0:40000);
Spawn("HellblazerExplLight3",pos);
int numpt = Random[Hellblazer](20,30);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](4,20);
let s = Spawn("SWWMSmoke",pos);
s.vel = pvel;
s.SetShade(Color(4,2,1)*Random[Hellblazer](48,63));
s.special1 = Random[Hellblazer](3,8);
s.scale *= 4.;
s.alpha *= .4;
}
numpt = Random[Hellblazer](10,20);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](4,28);
let s = Spawn("SWWMSpark",pos);
s.vel = pvel;
}
numpt = Random[Hellblazer](20,25);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](10,40);
let s = Spawn("SWWMChip",pos);
s.vel = pvel;
s.scale *= FRandom[Hellblazer](0.9,1.8);
}
Spawn("HellblazerRing2",pos);
if ( swwm_omnibust ) BusterWall.ProjectileBust(self,2000,(cos(angle)*cos(pitch),sin(angle)*cos(pitch),sin(-pitch)));
}
void A_WarheadSub()
{
if ( special1 < 40 )
SWWMUtility.DoExplosion(self,320-special1*8,600000-special1*12000,200+special1*30);
special1++;
if ( (special1 <= 30) && !(special1%2) )
{
int numpt = 30-special1/2;
double ang, pt;
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Hellblazer](0,360);
pt = FRandom[Hellblazer](-90,90);
FLineTraceData d;
Vector3 HitNormal;
LineTrace(ang,FRandom[Hellblazer](30,40)+12*special1,pt,TRF_THRUACTORS,data:d);
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("HellblazerSubExpl",d.HitLocation+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = target;
p.scale *= (3-special1*.04);
p.alpha *= 1-special1*.02;
}
}
special2++;
if ( (special2 <= 15) && !(special2%3) )
{
int numpt = 5-special2/5;
for ( int i=0; i<numpt; i++ )
{
double ang = FRandom[Hellblazer](0,360);
double pt = FRandom[Hellblazer](-90,90);
let c = Spawn("HellblazerWarheadArm",pos);
c.angle = ang;
c.pitch = pt;
c.target = target;
}
}
}
States
{
Spawn:
XZW1 A 1 A_BlazerTick(Color(3,2,4));
Wait;
Death:
TNT1 A 0 A_BlazerWarheadExplode();
HEXP AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRR 1 Bright A_WarheadSub();
TNT1 A 1
{
A_WarheadSub();
A_FadeOut(.05);
}
Stop;
}
}
Mixin Class HellblazerGrenade
{
double rollvel, anglevel, pitchvel;
Vector3 oldvel;
Default
{
BounceFactor 1.;
WallBounceFactor 1.;
Gravity .35;
ReactionTime 85;
-NOGRAVITY;
+USEBOUNCESTATE;
+BOUNCEONWALLS;
+BOUNCEONFLOORS;
+BOUNCEONCEILINGS;
+ALLOWBOUNCEONACTORS;
+DONTBOUNCEONSKY;
+CANBOUNCEWATER;
+INTERPOLATEANGLES;
+ROLLSPRITE;
+ROLLCENTER;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
rollvel = FRandom[Hellblazer](-4,4);
anglevel = FRandom[Hellblazer](-4,4);
pitchvel = FRandom[Hellblazer](-4,4);
oldvel = vel;
}
override void Tick()
{
oldvel = vel;
Super.Tick();
if ( isFrozen() || !InStateSequence(CurState,FindState("Spawn")) ) return;
roll += rollvel;
angle += anglevel;
pitch += pitchvel;
ReactionTime--;
if ( ReactionTime <= 0 ) ExplodeMissile();
}
virtual void A_HandleBounce()
{
Vector3 HitNormal = -vel.unit();
F3DFloor ff;
if ( BlockingFloor )
{
// find closest 3d floor for its normal
for ( int i=0; i<BlockingFloor.Get3DFloorCount(); i++ )
{
if ( !(BlockingFloor.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(BlockingFloor.Get3DFloor(i).top.ZAtPoint(pos.xy) ~== floorz) ) continue;
ff = BlockingFloor.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.top.Normal;
else HitNormal = BlockingFloor.floorplane.Normal;
}
else if ( BlockingCeiling )
{
// find closest 3d floor for its normal
for ( int i=0; i<BlockingCeiling.Get3DFloorCount(); i++ )
{
if ( !(BlockingCeiling.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(BlockingCeiling.Get3DFloor(i).bottom.ZAtPoint(pos.xy) ~== ceilingz) ) continue;
ff = BlockingCeiling.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.bottom.Normal;
else HitNormal = BlockingCeiling.ceilingplane.Normal;
}
else if ( BlockingLine )
{
HitNormal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
if ( !SWWMUtility.PointOnLineSide(pos.xy,BlockingLine) )
HitNormal *= -1;
}
else if ( BlockingMobj )
{
Vector3 diff = level.Vec3Diff(BlockingMobj.Vec3Offset(0,0,BlockingMobj.Height/2),pos);
HitNormal = diff.unit();
}
// undo the bounce, we need to hook in our own
vel = oldvel;
// re-do the bounce with our formula
Vector3 RealHitNormal = HitNormal;
HitNormal = (HitNormal+(FRandom[Hellblazer](-.1,.1),FRandom[Hellblazer](-.1,.1),FRandom[Hellblazer](-.1,.1))).unit();
if ( (HitNormal dot RealHitNormal) < 0 ) HitNormal *= -.5;
vel = FRandom[Hellblazer](.8,.9)*((vel dot HitNormal)*HitNormal*(FRandom[Hellblazer](-2.,-1.6))+vel);
if ( vel.z > 10 ) vel.z = 0.5*(10+vel.z);
bHITOWNER = true;
if ( vel.length() < 4. )
{
ClearBounce();
ExplodeMissile();
return;
}
if ( swwm_extraalert ) A_AlertMonsters(swwm_uncapalert?0:300);
A_StartSound("hellblazer/bounce",CHAN_ITEM);
rollvel = FRandom[Hellblazer](-16,16);
anglevel = FRandom[Hellblazer](-16,16);
pitchvel = FRandom[Hellblazer](-16,16);
}
States
{
Bounce:
XZW1 A 0 A_HandleBounce();
Goto Spawn;
}
}
// grenades
Class HellblazerMissile2 : HellblazerMissile
{
Mixin HellblazerGrenade;
}
Class HellblazerCrackshot2 : HellblazerCrackshot
{
Mixin HellblazerGrenade;
}
Class HellblazerRavager2 : HellblazerRavager
{
Mixin HellblazerGrenade;
}
Class HellblazerWarhead2 : HellblazerWarhead
{
Mixin HellblazerGrenade;
}
Class HellblazerClusterMini : HellblazerMissile2
{
Default
{
Radius 2;
Height 4;
Speed 20;
ReactionTime 30;
}
void A_ClusterTick( Color smokecol )
{
special2++;
Vector3 traildir = -(cos(angle)*cos(pitch),sin(angle)*cos(pitch),sin(-pitch));
for ( int i=0; i<2; i++ )
{
let s = Spawn("SWWMHalfSmoke",level.Vec3Offset(pos,traildir*3));
s.SetShade(smokecol*Random[Hellblazer](48,63));
s.scale *= FRandom[Hellblazer](.6,.8);
s.special1 = Random[Hellblazer](0,1);
s.alpha *= .4;
s.vel = .3*vel + (traildir+(FRandom[Hellblazer](-.4,.4),FRandom[Hellblazer](-.4,.4),FRandom[Hellblazer](-.4,.4))).unit()*FRandom[Hellblazer](1.,2.);
}
if ( (deto > 1) && (special2 > 5) )
{
ExplodeMissile();
return;
}
// proximity check
let bt = BlockThingsIterator.Create(self,200);
while ( bt.Next() )
{
let t = bt.Thing;
if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),60) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
deto++;
break;
}
}
void A_ClusterExplode()
{
bForceXYBillboard = true;
bRollSprite = false;
A_SetRenderStyle(1.0,STYLE_Add);
A_SprayDecal("BigRocketBlast",50);
A_SetScale(2.5);
SWWMUtility.DoExplosion(self,50,200000,150,60);
A_NoGravity();
A_QuakeEx(4,4,4,12,0,1000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:400,rollIntensity:.6);
A_StopSound(CHAN_BODY);
A_StartSound("hellblazer/hitcs",CHAN_WEAPON,attenuation:.9);
A_StartSound("hellblazer/hitcs",CHAN_VOICE,attenuation:.5);
A_AlertMonsters(swwm_uncapalert?0:2000);
Spawn("HellblazerExplLight2",pos);
int numpt = Random[Hellblazer](4,8);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](1,5);
let s = Spawn("SWWMSmoke",pos);
s.vel = pvel;
s.SetShade(Color(4,2,1)*Random[Hellblazer](48,63));
s.special1 = Random[Hellblazer](1,3);
s.scale *= 1.5;
s.alpha *= .4;
}
numpt = Random[Hellblazer](4,6);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](2,5);
let s = Spawn("SWWMSpark",pos);
s.vel = pvel;
}
numpt = Random[Hellblazer](4,6);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](5,10);
let s = Spawn("SWWMChip",pos);
s.vel = pvel;
s.scale *= FRandom[Hellblazer](0.8,1.4);
}
let r = Spawn("HellblazerRing",pos);
r.scale *= .4;
}
void A_ClusterSubExpl()
{
special1++;
if ( (special1 > 5) || !(special1%2) ) return;
int numpt = Random[Hellblazer](0,5-special1);
double ang, pt;
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Hellblazer](0,360);
pt = FRandom[Hellblazer](-90,90);
FLineTraceData d;
Vector3 HitNormal;
LineTrace(ang,FRandom[Hellblazer](6,12)+6*special1,pt,TRF_THRUACTORS,data:d);
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("HellblazerSubExpl",d.HitLocation+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = target;
p.scale *= 1.5-special1*.1;
p.alpha *= 1-special1*.1;
}
}
void A_Steer( Actor ignoreme = null )
{
if ( !bMISSILE ) return;
// try to steer towards a target
let bt = BlockThingsIterator.Create(self,800);
double closest = double.infinity;
Actor whomst = null;
while ( bt.Next() )
{
let t = bt.Thing;
if ( !t || (ignoreme && (t == ignoreme)) || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || (target && t.IsFriend(target)) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),800) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
double dist = Distance3D(t);
if ( dist > closest ) continue;
closest = dist;
whomst = t;
}
if ( !whomst ) return;
Vector3 dirto = level.Vec3Diff(pos,whomst.Vec3Offset(0,0,whomst.Height/2));
dirto /= dirto.length();
dirto.z += .3;
double spd = vel.length();
vel /= spd;
vel = (vel*.3+dirto*.7)*spd;
}
override void A_HandleBounce()
{
Super.A_HandleBounce();
A_Steer();
}
States
{
Spawn:
XZW1 A 1 A_ClusterTick(Color(2,4,2));
Wait;
Bounce:
XZW1 A 0 A_HandleBounce();
Goto Spawn;
Death:
TNT1 A 0 A_ClusterExplode();
HEXP ABCDEFGHIJKLMNOPQR 1 Bright A_ClusterSubExpl();
Stop;
}
}
Class RavagerLight : PaletteLight
{
Default
{
Tag "DRed";
Args 0,0,0,250;
}
}
Class RavagerPuff : Actor
{
Vector2 initsc;
Default
{
RenderStyle "Add";
Scale .8;
Alpha .7;
+NOGRAVITY;
+NOBLOCKMAP;
+DONTSPLASH;
+NOINTERACTION;
+NOTELEPORT;
+ROLLSPRITE;
+ROLLCENTER;
+FORCEXYBILLBOARD;
}
override void PostBeginPlay()
{
scale *= FRandom[Hellblazer](.8,1.);
alpha *= FRandom[Hellblazer](.8,1.);
roll = FRandom[Hellblazer](0,360);
SetState(FindState("Spawn")+Random[Hellblazer](0,19));
initsc = scale;
}
override void Tick()
{
if ( isFrozen() ) return;
A_FadeOut((waterlevel>0)?.1:.02);
scale += initsc*.2;
if ( !CheckNoDelay() || (tics == -1) ) return;
if ( tics > 0 ) tics--;
while ( !tics )
{
if ( !SetState(CurState.NextState) )
return;
}
}
States
{
Spawn:
RFLM ABCDEFGHIJKLMNOPQRST -1 Bright;
Stop;
}
}
Class HellblazerRavagerArm : Actor
{
Vector3 oldvel;
Default
{
Obituary "$O_HELLBLAZER";
DamageType 'Fire';
PROJECTILE;
+THRUACTORS;
+BOUNCEONWALLS;
+BOUNCEONFLOORS;
+BOUNCEONCEILINGS;
+USEBOUNCESTATE;
+NODAMAGETHRUST;
+FORCERADIUSDMG;
-NOGRAVITY;
Gravity 0.35;
BounceFactor 1.0;
Radius 2;
Height 2;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
reactiontime = Random[ExploS](15,25);
vel = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch))*FRandom[ExploS](10.,15.);
}
override void Tick()
{
oldvel = vel;
Super.Tick();
}
void A_HandleBounce()
{
Vector3 HitNormal = -vel.unit();
F3DFloor ff;
if ( BlockingFloor )
{
// find closest 3d floor for its normal
for ( int i=0; i<BlockingFloor.Get3DFloorCount(); i++ )
{
if ( !(BlockingFloor.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(BlockingFloor.Get3DFloor(i).top.ZAtPoint(pos.xy) ~== floorz) ) continue;
ff = BlockingFloor.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.top.Normal;
else HitNormal = BlockingFloor.floorplane.Normal;
}
else if ( BlockingCeiling )
{
// find closest 3d floor for its normal
for ( int i=0; i<BlockingCeiling.Get3DFloorCount(); i++ )
{
if ( !(BlockingCeiling.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(BlockingCeiling.Get3DFloor(i).bottom.ZAtPoint(pos.xy) ~== ceilingz) ) continue;
ff = BlockingCeiling.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.bottom.Normal;
else HitNormal = BlockingCeiling.ceilingplane.Normal;
}
else if ( BlockingLine )
{
HitNormal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
if ( !SWWMUtility.PointOnLineSide(pos.xy,BlockingLine) )
HitNormal *= -1;
}
else if ( BlockingMobj )
{
Vector3 diff = level.Vec3Diff(pos,BlockingMobj.pos);
if ( (pos.x+radius) <= (BlockingMobj.pos.x-BlockingMobj.radius) )
HitNormal = (-1,0,0);
else if ( (pos.x-radius) >= (BlockingMobj.pos.x+BlockingMobj.radius) )
HitNormal = (1,0,0);
else if ( (pos.y+radius) <= (BlockingMobj.pos.y-BlockingMobj.radius) )
HitNormal = (0,-1,0);
else if ( (pos.y-radius) >= (BlockingMobj.pos.y+BlockingMobj.radius) )
HitNormal = (0,1,0);
else if ( pos.z >= (BlockingMobj.pos.z+BlockingMobj.height) )
HitNormal = (0,0,1);
else if ( (pos.z+height) <= BlockingMobj.pos.z )
HitNormal = (0,0,-1);
}
// undo the bounce, we need to hook in our own
vel = oldvel;
// re-do the bounce with our formula
vel = (vel dot HitNormal)*HitNormal*FRandom[Hellblazer](-1.5,-1.)+vel;
}
States
{
Spawn:
TNT1 A 1
{
if ( waterlevel > 0 ) ReactionTime -= 2;
let p = Spawn("RavagerPuff",pos);
p.alpha *= .4+.6*(ReactionTime/25.);
p.scale *= 2.5-1.5*(ReactionTime/25.);
if ( !(ReactionTime%3) )
{
let l = Spawn("RavagerLight",pos);
l.Args[3] = int(90+50*(ReactionTime/25.));
l.ReactionTime = int(2+8*(ReactionTime/25.));
l.target = p;
}
SWWMUtility.DoExplosion(self,15+reactiontime/2,2000+400*reactiontime,300-4*reactiontime,100);
double spd = min(vel.length()*1.1,50);
vel = (vel*.1+(FRandom[ExploS](-1.,1.),FRandom[ExploS](-1.,1.),FRandom[ExploS](-1.,1.))).unit()*spd;
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,5);
let s = Spawn("SWWMHalfSmoke",pos);
s.vel = pvel+vel*.2;
s.SetShade(Color(4,2,1)*Random[ExploS](48,63));
s.special1 = Random[ExploS](4,8);
s.scale *= 4.;
s.alpha *= .2+.3*(ReactionTime/25.);
if ( !(ReactionTime%2) )
{
int numpt = Random[Hellblazer](-2,4);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = vel+(FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1),FRandom[Hellblazer](-1,1)).unit()*FRandom[Hellblazer](2,4);
let s2 = Spawn("SWWMSpark",pos);
s2.scale *= .4;
s2.vel = pvel;
}
}
A_CountDown();
}
Wait;
Bounce:
TNT1 A 0 A_HandleBounce();
Goto Spawn;
}
}
Class HellblazerWarheadTrail : Actor
{
Default
{
RenderStyle "Add";
+NOBLOCKMAP;
+NOGRAVITY;
+FORCEXYBILLBOARD;
+NOTELEPORT;
+NOINTERACTION;
Scale 2.4;
}
override void Tick()
{
if ( isFrozen() ) return;
if ( !CheckNoDelay() || (tics == -1) ) return;
if ( tics > 0 ) tics--;
while ( !tics )
{
if ( !SetState(CurState.NextState) )
return;
}
}
States
{
Spawn:
XEX0 ABCDEFGHIJKLMNOPQRS 1 Bright;
Stop;
}
}
Class HellblazerWarheadArm : Actor
{
Default
{
Obituary "$O_HELLBLAZER";
DamageType 'Exploded';
PROJECTILE;
+THRUACTORS;
+BOUNCEONWALLS;
+BOUNCEONFLOORS;
+BOUNCEONCEILINGS;
+NODAMAGETHRUST;
+FORCERADIUSDMG;
-NOGRAVITY;
Gravity 0.35;
BounceFactor 1.0;
Radius 4;
Height 4;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
reactiontime = Random[ExploS](20,25);
double ang, pt;
ang = FRandom[ExploS](0,360);
pt = FRandom[ExploS](-90,90);
vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[ExploS](20.,35.);
}
States
{
Spawn:
TNT1 A 1
{
Spawn("HellblazerWarheadTrail",pos);
SWWMUtility.DoExplosion(self,20+reactiontime*4,3000+500*reactiontime,120+4*reactiontime);
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,5);
let s = Spawn("SWWMHalfSmoke",pos);
s.vel = pvel+vel*.2;
s.SetShade(Color(4,2,1)*Random[ExploS](48,63));
s.special1 = Random[ExploS](1,3);
s.scale *= 6.;
s.alpha *= 0.1+.4*(ReactionTime/25.);
A_CountDown();
}
Wait;
}
}
Class HellblazerX : GhostArtifactX
{
States
{
Spawn:
XZW1 A -1; // not fullbright
Stop;
}
}
Class HellblazerXSub : GhostArtifactX
{
Hellblazer weap;
int ridx;
Default
{
RenderStyle "Normal";
}
void UpdateMe()
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
int curtype = -1;
for ( int i=0; i<4; i++ )
{
if ( weap.loadammo != types[i] ) continue;
curtype = i;
break;
}
static const int sofs[] = {1,7,10,13}; // offsets from SpawnState for each ammo type state label
int idx;
switch ( curtype )
{
case 0:
idx = ridx-weap.magpos;
if ( idx > 5 ) idx -= 6;
else if ( idx < 0 ) idx += 6;
if ( weap.magstate[ridx] ) SetState(SpawnState);
else SetState(SpawnState+sofs[0]+idx);
break;
case 1:
idx = ridx-weap.magpos;
if ( idx > 2 ) idx -= 3;
else if ( idx < 0 ) idx += 3;
if ( (ridx > 2) || weap.magstate[ridx] ) SetState(SpawnState);
else SetState(SpawnState+sofs[1]+idx);
break;
case 2:
idx = ridx-weap.magpos;
if ( idx > 2 ) idx -= 3;
else if ( idx < 0 ) idx += 3;
if ( (ridx > 2) || weap.magstate[ridx] ) SetState(SpawnState);
else SetState(SpawnState+sofs[2]+idx);
break;
case 3:
idx = ridx-weap.magpos;
if ( idx > 1 ) idx -= 2;
else if ( idx < 0 ) idx += 2;
if ( (ridx > 1) || weap.magstate[ridx] ) SetState(SpawnState);
else SetState(SpawnState+sofs[3]+idx);
break;
default:
// uninitialized pickup (3 blazers)
idx = ridx;
if ( idx > 2 ) SetState(SpawnState);
else SetState(SpawnState+sofs[0]+idx);
break;
}
}
States
{
Spawn:
TNT1 A -1;
Missiles:
XZW1 ABCDEF -1;
Crackshots:
XZW2 ABC -1;
Ravagers:
XZW3 ABC -1;
Nukes:
XZW4 AB -1;
Stop;
}
}
Class Hellblazer : SWWMWeapon
{
int clipcount;
bool magstate[6]; // true: rocket was spent
int magpos; // current rotation
Class<Ammo> loadammo, nextammo;
int spinskipped;
HellblazerXSub pickuprockets[6];
Property ClipCount : clipcount;
transient ui TextureID WeaponBox, AmmoIcon[4], LoadedIcon[4];
transient ui Font TewiFont;
override void DrawWeapon( double TicFrac, double bx, double by, Vector2 hs, Vector2 ss )
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
if ( !TewiFont ) TewiFont = Font.GetFont('TewiShaded');
if ( !WeaponBox )
{
WeaponBox = TexMan.CheckForTexture("graphics/HUD/HellblazerDisplay.png",TexMan.Type_Any);
AmmoIcon[0] = TexMan.CheckForTexture("graphics/HUD/HellblazerMissile.png",TexMan.Type_Any);
AmmoIcon[1] = TexMan.CheckForTexture("graphics/HUD/HellblazerCrackshot.png",TexMan.Type_Any);
AmmoIcon[2] = TexMan.CheckForTexture("graphics/HUD/HellblazerRavager.png",TexMan.Type_Any);
AmmoIcon[3] = TexMan.CheckForTexture("graphics/HUD/HellblazerWarhead.png",TexMan.Type_Any);
LoadedIcon[0] = TexMan.CheckForTexture("graphics/HUD/HellblazerMissileLoaded.png",TexMan.Type_Any);
LoadedIcon[1] = TexMan.CheckForTexture("graphics/HUD/HellblazerCrackshotLoaded.png",TexMan.Type_Any);
LoadedIcon[2] = TexMan.CheckForTexture("graphics/HUD/HellblazerRavagerLoaded.png",TexMan.Type_Any);
LoadedIcon[3] = TexMan.CheckForTexture("graphics/HUD/HellblazerWarheadLoaded.png",TexMan.Type_Any);
}
double xx = -56, yy = -49;
Screen.DrawTexture(WeaponBox,false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
int curtype = 0;
for ( int i=0; i<4; i++ )
{
if ( loadammo != types[i] ) continue;
curtype = i;
break;
}
xx += 2;
yy += 1;
for ( int i=0; i<4; i++ )
{
int amt = Owner.CountInv(types[i]);
String amtstr = String.Format("%3d",amt);
Screen.DrawText(TewiFont,Font.CR_FIRE,bx+xx,by+yy,amtstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(types[i]==nextammo)?Color(0,0,0,0):Color(128,0,0,0));
Screen.DrawTexture(AmmoIcon[i],false,bx+xx+19,by+yy+1,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(types[i]==nextammo)?Color(0,0,0,0):Color(128,0,0,0));
yy += 13;
if ( i%2 )
{
yy -= 26;
xx += 28;
}
}
yy = -18;
switch ( curtype )
{
case 0:
xx = -54;
for ( int i=0; i<6; i++ )
{
Screen.DrawTexture(LoadedIcon[0],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i==magpos)?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
xx += 9;
}
break;
case 1:
xx = -49;
for ( int i=0; i<3; i++ )
{
Screen.DrawTexture(LoadedIcon[1],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i==magpos)?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
xx += 18;
}
break;
case 2:
xx = -49;
for ( int i=0; i<3; i++ )
{
Screen.DrawTexture(LoadedIcon[2],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i==magpos)?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
xx += 18;
}
break;
case 3:
xx = -45;
for ( int i=0; i<2; i++ )
{
Screen.DrawTexture(LoadedIcon[3],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i==magpos)?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
xx += 27;
}
break;
}
}
override Vector3 GetTraceOffset()
{
return (10.,3.5,-5.);
}
action void A_HellblazerFire( int type = 0, bool bAlt = false )
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
static const Class<Actor> projs[] = {"HellblazerMissile","HellblazerCrackshot","HellblazerRavager","HellblazerWarhead",
"HellblazerMissile2","HellblazerCrackshot2","HellblazerRavager2","HellblazerWarhead2"};
static const Color cols[] = {Color(4,3,2),Color(2,4,2),Color(4,2,2),Color(3,2,4)};
A_StartSound(bAlt?"hellblazer/altfire":"hellblazer/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:(bAlt?1.7:.8));
A_AlertMonsters(swwm_uncapalert?0:bAlt?400:1200);
int qstr = bAlt?4:5;
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_PlayerFire();
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);
SWWMUtility.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.5*y-5*z);
a = FRandom[Hellblazer](0,360);
s = FRandom[Hellblazer](0,bAlt?.02:.005);
dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
let p = Spawn(projs[type+4*bAlt],origin);
p.target = self;
p.angle = atan2(dir.y,dir.x);
p.pitch = asin(-dir.z);
p.vel = dir*p.speed;
if ( bAlt )
{
p.vel.z += 3.5;
return;
}
for ( int i=0; i<5; i++ )
{
let s = Spawn("SWWMSmoke",origin);
s.special1 = 1;
s.scale *= 2.4;
s.alpha *= .4;
s.SetShade(cols[type]*Random[Hellblazer](48,63));
s.vel += vel*.5+x*FRandom[Hellblazer](6.,10.)+y*FRandom[Hellblazer](-2,2)+z*FRandom[Hellblazer](-2,2);
}
for ( int i=0; i<6; i++ )
{
let s = Spawn("SWWMSpark",origin);
s.scale *= .7;
s.alpha *= .4;
s.vel += vel*.5+x*FRandom[Hellblazer](4.,8.)+y*FRandom[Hellblazer](-2,2)+z*FRandom[Hellblazer](-2,2);
}
}
override bool ReportHUDAmmo()
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
for ( int i=0; i<4; i++ ) if ( Owner.CountInv(types[i]) > 0 ) return true;
return (clipcount>0);
}
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
if ( (firemode == PrimaryFire) || (firemode == AltFire) )
{
if ( clipcount > 0 ) return true;
for ( int i=0; i<4; i++ ) if ( Owner.CountInv(types[i]) > 0 ) return true;
return false;
}
return Super.CheckAmmo(firemode,autoswitch,requireammo,ammocount);
}
override bool UsesAmmo( Class<Ammo> kind )
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
for ( int i=0; i<4; i++ ) if ( kind is types[i] ) return true;
return false;
}
action void A_GlassOverlay( StateLabel g )
{
if ( !player.FindPSprite(PSP_WEAPON+1) )
{
A_Overlay(PSP_WEAPON+1,g);
A_OverlayFlags(PSP_WEAPON+1,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
A_OverlayRenderStyle(PSP_WEAPON+1,STYLE_Add);
}
else player.SetPSprite(PSP_WEAPON+1,invoker.FindState(g));
}
action state A_JumpByAmmoType( StateLabel a, StateLabel b, StateLabel c, StateLabel d, StateLabel g, StateLabel o = null )
{
A_Overlay(-9999,o);
A_GlassOverlay(g);
if ( invoker.loadammo is "HellblazerMissiles" ) return invoker.FindState(a);
if ( invoker.loadammo is "HellblazerCrackshots" ) return invoker.FindState(b);
if ( invoker.loadammo is "HellblazerRavagers" ) return invoker.FindState(c);
if ( invoker.loadammo is "HellblazerWarheads" ) return invoker.FindState(d);
return invoker.FindState(a);
}
override void AttachToOwner( Actor other )
{
Super.AttachToOwner(other);
if ( !loadammo )
{
// 3 hellblazer missiles loaded
loadammo = "HellblazerMissiles";
clipcount = 3;
magpos = 0;
for ( int i=0; i<6; i++ )
magstate[i] = (i>2);
}
nextammo = loadammo;
}
clearscope int LoadedCapacity() const
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
static const int typeclipcount[] = {6,3,3,2};
for ( int i=0; i<4; i++ )
{
if ( loadammo != types[i] ) continue;
let a = Owner.FindInventory(types[i]);
return min(a.Amount+clipcount,typeclipcount[i]);
break;
}
return 0;
}
action void A_PickNextAmmo()
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
int curidx = 0;
for ( int i=0; i<4; i++ )
{
if ( invoker.nextammo != types[i] ) continue;
curidx = (i+1)%4;
break;
}
Class<Ammo> oldammo = invoker.nextammo, newammo = invoker.loadammo;
for ( int i=0; i<4; i++ )
{
int nidx = (i+curidx)%4;
if ( CountInv(types[nidx]) <= 0 ) continue;
newammo = types[nidx];
break;
}
if ( newammo != oldammo ) A_StartSound("misc/invchange",CHAN_WEAPONEXTRA,CHANF_UI|CHANF_LOCAL);
invoker.nextammo = newammo;
}
action void A_ZoomHold()
{
A_WeaponReady(WRF_NOFIRE);
if ( player.cmd.buttons&BT_ZOOM ) return;
player.SetPSPrite(PSP_WEAPON,invoker.FindState("Ready"));
}
action void A_SwapAmmo()
{
let amo = FindInventory(invoker.loadammo);
// if we're loading the same ammo type, we only need to remove the needed ammo
if ( invoker.loadammo == invoker.nextammo )
{
int takeamt = invoker.LoadedCapacity()-invoker.clipcount;
invoker.clipcount = invoker.LoadedCapacity();
if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
amo.Amount = max(0,amo.Amount-takeamt);
invoker.magpos = 0;
for ( int i=0; i<6; i++ )
invoker.magstate[i] = !(invoker.clipcount > i);
return;
}
// re-add/drop any still loaded
int maxgiveamt = min(amo.MaxAmount-amo.Amount,invoker.clipcount);
int dropamt = invoker.clipcount-maxgiveamt;
if ( (dropamt > 0) && !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) ) amo.CreateTossable(dropamt);
amo.Amount = min(amo.MaxAmount,amo.Amount+invoker.clipcount);
// swap
invoker.clipcount = 0;
invoker.loadammo = invoker.nextammo;
invoker.clipcount = invoker.LoadedCapacity();
invoker.magpos = 0;
for ( int i=0; i<6; i++ )
invoker.magstate[i] = !(invoker.clipcount > i);
if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
{
let namo = FindInventory(invoker.loadammo);
namo.Amount = max(0,namo.Amount-invoker.clipcount);
}
}
action void A_HellblazerReady()
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
int flg = WRF_ALLOWRELOAD|WRF_ALLOWZOOM|WRF_ALLOWUSER1;
// can we fire?
bool canfire = (invoker.clipcount > 0);
for ( int i=0; i<4; i++ )
{
if ( CountInv(types[i]) <= 0 ) continue;
canfire = true;
break;
}
if ( !canfire ) flg |= WRF_NOPRIMARY|WRF_NOSECONDARY;
A_WeaponReady(flg);
if ( player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK) )
invoker.CheckAmmo(EitherFire,true);
}
// check if weapon was dropped or interrupted in some way before the mag spin could be done
action void A_CheckSpinSkip()
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
static const int magcap[] = {6,3,3,2};
for ( int i=0; i<4; i++ )
{
if ( invoker.loadammo != types[i] ) continue;
invoker.magpos = (invoker.magpos+invoker.spinskipped)%magcap[i];
invoker.spinskipped = 0;
break;
}
}
action void A_UpdatePickup()
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
for ( int i=0; i<6; i++ )
{
if ( !invoker.pickuprockets[i] )
{
invoker.pickuprockets[i] = HellblazerXSub(Spawn("HellblazerXSub",pos));
invoker.pickuprockets[i].angle = angle;
invoker.pickuprockets[i].target = invoker;
invoker.pickuprockets[i].weap = invoker;
invoker.pickuprockets[i].FloatBobPhase = FloatBobPhase;
invoker.pickuprockets[i].ridx = i;
}
invoker.pickuprockets[i].UpdateMe();
}
int curtype = 0;
for ( int i=0; i<4; i++ )
{
if ( invoker.loadammo != types[i] ) continue;
curtype = i;
break;
}
SetState(SpawnState+curtype+1);
}
override void Travelled()
{
Super.Travelled();
if ( !tracer )
{
tracer = Spawn("HellblazerX",pos);
tracer.angle = angle;
tracer.target = self;
tracer.FloatBobPhase = FloatBobPhase;
}
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
tracer = Spawn("HellblazerX",pos);
tracer.angle = angle;
tracer.target = self;
tracer.FloatBobPhase = FloatBobPhase;
}
Default
{
Tag "$T_HELLBLAZER";
Inventory.PickupMessage "$I_HELLBLAZER";
Obituary "$O_HELLBLAZER";
Inventory.Icon "graphics/HUD/Icons/W_Hellblazer.png";
Weapon.SlotNumber 6;
Weapon.SelectionOrder 700;
Weapon.UpSound "hellblazer/select";
Stamina 90000;
Weapon.AmmoType1 "HellblazerMissiles";
Weapon.AmmoGive1 3;
SWWMWeapon.DropAmmoType "RocketAmmo";
Hellblazer.ClipCount 6;
+SWWMWEAPON.NOFIRSTGIVE;
+WEAPON.EXPLOSIVE;
Radius 24;
Height 32;
}
States
{
Spawn:
XZW1 A -1 NoDelay A_UpdatePickup();
XZW1 ABCD -1;
Stop;
Select:
XZW2 I 0
{
A_CheckSpinSkip();
A_FullRaise();
return A_JumpByAmmoType("Select_1","Select_2","Select_3","Select_4","Select_G");
}
Select_1:
XZW2 IJKLMNOP 2;
Goto Ready_1;
Select_2:
XZW7 DEFGHIJK 2;
Goto Ready_2;
Select_3:
XZWC BCDEFGHI 2;
Goto Ready_3;
Select_4:
XZWG Z 2;
XZWH ABCDEFG 2;
Goto Ready_4;
Select_G:
XZWM ABCDEFGH 2;
Goto Ready_G;
Deselect:
XZW2 A 0
{
A_StartSound("hellblazer/deselect",CHAN_WEAPON,CHANF_OVERLAP);
return A_JumpByAmmoType("Deselect_1","Deselect_2","Deselect_3","Deselect_4","Deselect_G");
}
Deselect_1:
XZW2 ABCDEFGHI 2;
XZW2 I -1 A_FullLower();
Stop;
Deselect_2:
XZW6 VWXYZ 2;
XZW7 ABCD 2;
XZW7 D -1 A_FullLower();
Stop;
Deselect_3:
XZWB TUVWXYZ 2;
XZWC AB 2;
XZWC B -1 A_FullLower();
Stop;
Deselect_4:
XZWG RSTUVWXYZ 2;
XZWG Z -1 A_FullLower();
Stop;
Deselect_G:
XZWL STUVWXYZ 2;
XZWM A 2;
Stop;
Ready:
XZW2 A 0 A_JumpByAmmoType("Ready_1","Ready_2","Ready_3","Ready_4","Ready_G");
Ready_1:
XZW2 A 1 A_HellblazerReady();
Wait;
Ready_2:
XZW6 V 1 A_HellblazerReady();
Wait;
Ready_3:
XZWB T 1 A_HellblazerReady();
Wait;
Ready_4:
XZWG R 1 A_HellblazerReady();
Wait;
Ready_G:
XZWL S 1;
Wait;
Fire:
XZW2 A 0
{
if ( invoker.clipcount <= 0 )
{
if ( CountInv(invoker.nextammo) <= 0 ) A_PickNextAmmo();
return A_JumpByAmmoType("Unload_1","Unload_2","Unload_3","Unload_4","Unload_G");
}
return A_JumpByAmmoType("Fire_1","Fire_2","Fire_3","Fire_4","Fire_G");
}
Fire_1:
XZW2 A 1 A_HellblazerFire(0);
XZW2 QRSTUVW 2;
Goto Cycle_1;
Fire_2:
XZW6 V 1 A_HellblazerFire(1);
XZW7 LMNOPQR 2;
Goto Cycle_2;
Fire_3:
XZWB T 1 A_HellblazerFire(2);
XZWC JKLMNOP 2;
Goto Cycle_3;
Fire_4:
XZWG R 1 A_HellblazerFire(3);
XZWH HIJKLMN 2;
Goto Cycle_4;
Fire_G:
XZWL S 1;
XZWM IJKLMNO 2;
Goto Ready_G; // state jump to cycling is done elsewhere
AltFire:
XZW2 A 0
{
if ( invoker.clipcount <= 0 )
{
if ( CountInv(invoker.nextammo) <= 0 ) A_PickNextAmmo();
return A_JumpByAmmoType("Unload_1","Unload_2","Unload_3","Unload_4","Unload_G");
}
return A_JumpByAmmoType("AltFire_1","AltFire_2","AltFire_3","AltFire_4","AltFire_G");
}
AltFire_1:
XZW2 A 1 A_HellblazerFire(0,true);
XZW2 XYZ 2;
XZW3 ABCD 2;
Goto Cycle_1;
AltFire_2:
XZW6 V 1 A_HellblazerFire(1,true);
XZW7 STUVWXY 2;
Goto Cycle_2;
AltFire_3:
XZWB T 1 A_HellblazerFire(2,true);
XZWC QRSTUVW 2;
Goto Cycle_3;
AltFire_4:
XZWG R 1 A_HellblazerFire(3,true);
XZWH OPQRSTU 2;
Goto Cycle_4;
AltFire_G:
XZWL S 1;
XZWM PQRSTUV 2;
Goto Ready_G; // state jump to cycling is done elsewhere
Cycle_1:
XZW2 A 2
{
invoker.spinskipped--;
invoker.magpos = (invoker.magpos+1)%6;
A_GlassOverlay("Cycle_G1");
}
XZW3 E 2;
XZW3 FGHI 2;
XZW3 I 0;
XZW3 FE 2;
Goto Ready_1;
Cycle_2:
XZW6 V 2
{
invoker.spinskipped--;
invoker.magpos = (invoker.magpos+1)%3;
A_GlassOverlay("Cycle_G2");
}
XZW7 Z 2;
XZW8 ABCDEFG 2;
XZW8 G 0;
XZW8 A 2;
XZW7 Z 2;
Goto Ready_2;
Cycle_3:
XZWB T 2
{
invoker.spinskipped--;
invoker.magpos = (invoker.magpos+1)%3;
A_GlassOverlay("Cycle_G2");
}
XZWC X 2;
XZWC YZ 2;
XZWD ABCDE 2;
XZWD E 0;
XZWC YX 2;
Goto Ready_3;
Cycle_4:
XZWG R 2
{
invoker.spinskipped--;
invoker.magpos = (invoker.magpos+1)%2;
A_GlassOverlay("Cycle_G3");
}
XZWH V 2;
XZWH WXYZ 2;
XZWI ABCDEF 2;
XZWI F 0;
XZWH WV 2;
Goto Ready_4;
Cycle_G1:
XZWL S 2 A_StartSound("hellblazer/shift",CHAN_WEAPON,CHANF_OVERLAP);
XZWM W 2;
XZWM X 2 A_StartSound("hellblazer/spin",CHAN_WEAPON,CHANF_OVERLAP);
XZWM YZ 2;
XZWN A 2;
XZWN A 0 A_StartSound("hellblazer/shift",CHAN_WEAPON,CHANF_OVERLAP);
XZWM XW 2;
Goto Ready_G;
Cycle_G2:
XZWL S 2 A_StartSound("hellblazer/shift",CHAN_WEAPON,CHANF_OVERLAP);
XZWM W 2;
XZWN B 2 A_StartSound("hellblazer/spin",CHAN_WEAPON,CHANF_OVERLAP);
XZWN CD 2;
XZWN E 2 A_StartSound("hellblazer/spin",CHAN_WEAPON,CHANF_OVERLAP);
XZWN FGH 2;
XZWN H 0 A_StartSound("hellblazer/shift",CHAN_WEAPON,CHANF_OVERLAP);
XZWN B 2;
XZWM W 2;
Goto Ready_G;
Cycle_G3:
XZWL S 2 A_StartSound("hellblazer/shift",CHAN_WEAPON,CHANF_OVERLAP);
XZWM W 2;
XZWN I 2 A_StartSound("hellblazer/spin",CHAN_WEAPON,CHANF_OVERLAP);
XZWN JK 2;
XZWN L 2 A_StartSound("hellblazer/spin",CHAN_WEAPON,CHANF_OVERLAP);
XZWN MN 2;
XZWN O 2 A_StartSound("hellblazer/spin",CHAN_WEAPON,CHANF_OVERLAP);
XZWN PQR 2;
XZWN R 0 A_StartSound("hellblazer/shift",CHAN_WEAPON,CHANF_OVERLAP);
XZWN I 2;
XZWM W 2;
Goto Ready_G;
Reload:
XZW2 A 2
{
if ( (invoker.clipcount <= 0) && (CountInv(invoker.nextammo) <= 0) ) A_PickNextAmmo();
if ( (invoker.clipcount >= invoker.LoadedCapacity()) && (invoker.loadammo == invoker.nextammo) )
return A_JumpByAmmoType("Idle_1","Idle_2","Idle_3","Idle_4","Idle_G");
return A_JumpByAmmoType("Unload_1","Unload_2","Unload_3","Unload_4","Unload_G");
}
Goto Ready;
Unload_1:
XZW2 A 2;
XZW3 JKLMNOPQRSTUVWXYZ 2;
XZW4 ABCDEFGHIJ 2;
XZWR JKLMN 3;
XZW4 J 2
{
A_SwapAmmo();
return A_JumpByAmmoType("Load_1","Load_2","Load_3","Load_4","Load_G");
}
Goto Load_1;
Unload_2:
XZW6 V 2;
XZW8 HIJKLMNOPQRSTUVWXYZ 2;
XZW9 ABCDEFGH 2;
XZWR JKLMN 3;
XZW9 H 2
{
A_SwapAmmo();
return A_JumpByAmmoType("Load_1","Load_2","Load_3","Load_4","Load_G");
}
Goto Load_2;
Unload_3:
XZWB T 2;
XZWD FGHIJKLMNOPQRSTUVWXYZ 2;
XZWE ABCDEF 2;
XZWR JKLMN 3;
XZWE F 2
{
A_SwapAmmo();
return A_JumpByAmmoType("Load_1","Load_2","Load_3","Load_4","Load_G");
}
Goto Load_3;
Unload_4:
XZWG R 2;
XZWI GHIJKLMNOPQRSTUVWXYZ 2;
XZWJ ABCDEFG 2;
XZWR JKLMN 3;
XZWJ G 2
{
A_SwapAmmo();
return A_JumpByAmmoType("Load_1","Load_2","Load_3","Load_4","Load_G");
}
Goto Load_4;
Unload_G:
XZWL S 2 A_StartSound("hellblazer/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
XZWN STU 2;
XZWN V 2 A_StartSound("hellblazer/open",CHAN_WEAPON,CHANF_OVERLAP);
XZWN WXYZ 2;
XZWO ABCDEFGH 2;
XZWO I 2 A_StartSound("hellblazer/magout",CHAN_WEAPON,CHANF_OVERLAP);
XZWO JKLMNOPQRS 2;
XZWR EFGHI 3;
Goto Load_G;
Load_1:
XZW4 JKLMNOPQRSTUVWXYZ 2;
XZW5 ABCDEFGHIJ 2;
Goto Ready_1;
Load_2:
XZW9 HIJKLMNOPQRSTUVWXYZ 2;
XZWA ABCDEFGH 2;
Goto Ready_2;
Load_3:
XZWE FGHIJKLMNOPQRSTUVWXYZ 2;
XZWF ABCDEF 2;
Goto Ready_3;
Load_4:
XZWJ GHIJKLMNOPQRSTUVWXYZ 2;
XZWK ABCDEFG 2;
Goto Ready_4;
Load_G:
XZWO S 2 A_PlayerReload();
XZWO TUVWXY 2;
XZWO Z 2 A_StartSound("hellblazer/magin",CHAN_WEAPON,CHANF_OVERLAP);
XZWP ABCDEFG 2;
XZWP H 2 A_StartSound("hellblazer/close",CHAN_WEAPON,CHANF_OVERLAP);
XZWP IJKL 2;
XZWP M 2 A_StartSound("hellblazer/meleestop",CHAN_WEAPON,CHANF_OVERLAP);
XZWP NOPQRS 2;
Goto Ready_G;
Idle_1:
XZW2 A 2;
XZW5 KLMNOPQRSTUVWXYZ 2;
XZW6 A 2;
Goto Ready_1;
Idle_2:
XZW6 V 2;
XZWA IJKLMNOPQRSTUVWXY 2;
Goto Ready_2;
Idle_3:
XZWB T 2;
XZWF GHIJKLMNOPQRSTUVW 2;
Goto Ready_3;
Idle_4:
XZWG R 2;
XZWK HIJKLMNOPQRSTUVWX 2;
Goto Ready_4;
Idle_G:
XZWL S 2
{
A_StartSound("hellblazer/idle",CHAN_WEAPON,CHANF_OVERLAP);
A_PlayerCheckGun();
}
XZWP TUVWX 2;
XZWP Y 2 A_StartSound("hellblazer/dustoff",CHAN_WEAPON,CHANF_OVERLAP);
XZWP Z 2;
XZWQ ABCDEFGHIJ 2;
Goto Ready_G;
Zoom:
#### # 1
{
A_PickNextAmmo();
A_WeaponReady(WRF_NOFIRE);
}
#### # 1 A_ZoomHold();
Wait;
User1:
XZW2 A 0 A_JumpByAmmoType("User1_1","User1_2","User1_3","User1_4","User1_G");
User1_1:
XZW2 A 2;
XZW6 BCDE 2;
XZW6 FGH 1;
XZW6 IJK 2;
XZW6 LMNOPQRSTU 2;
Goto Ready_1;
User1_2:
XZW6 V 2;
XZWA Z 2;
XZWB ABC 2;
XZWB DEF 1;
XZWB GHI 2;
XZWB JKLMNOPQRS 2;
Goto Ready_2;
User1_3:
XZWB T 2;
XZWF XYZ 2;
XZWG A 2;
XZWG BCD 1;
XZWG EFG 2;
XZWG HIJKLMNOPQ 2;
Goto Ready_3;
User1_4:
XZWG R 2;
XZWK YZ 2;
XZWL AB 2;
XZWL CDE 1;
XZWL FGH 2;
XZWL IJKLMNOPQR 2;
Goto Ready_4;
User1_G:
XZWL S 2
{
A_StartSound("hellblazer/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
A_StartSound("demolitionist/wswing",CHAN_WEAPON,CHANF_OVERLAP);
A_PlayerMelee();
}
XZWQ KLM 2;
XZWQ N 2 A_Parry(9);
XZWQ OP 1;
XZWQ Q 1 A_Melee(75,"demolitionist/whitl",1.05);
XZWQ RSTUV 2;
XZWQ W 2 A_StartSound("hellblazer/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
XZWQ XYZ 2;
XZWR ABCD 2;
Goto Ready_G;
}
}