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 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 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; } 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= 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= 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); 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