Class ASMDAmmo : Ammo { Default { Tag "$T_ASMDAMMO"; Inventory.Icon "I_ASMD"; Inventory.PickupMessage "$I_ASMDAMMO"; Inventory.Amount 10; Inventory.MaxAmount 50; Ammo.BackpackAmount 5; Ammo.BackpackMaxAmount 100; Ammo.DropAmount 5; } override void PostBeginPlay() { Super.PostBeginPlay(); tracer = Spawn("ASMDAmmoX",pos); tracer.angle = angle; tracer.target = self; tracer = Spawn("ASMDAmmoXX",pos); tracer.angle = angle; tracer.target = self; } States { Spawn: SHOA A -1; Stop; } } Class ASMDAmmoX : Actor { Default { RenderStyle "Add"; +NOGRAVITY; +NOCLIP; +DONTSPLASH; Radius 0.1; Height 0; } override void Tick() { Super.Tick(); if ( !target ) { Destroy(); return; } Warp(target,flags:WARPF_COPYINTERPOLATION|WARPF_NOCHECKPOSITION); bInvisible = target.bInvisible||!target.InStateSequence(target.CurState,target.FindState("Spawn")); } States { Spawn: SHOA A -1 Bright; Stop; } } Class ASMDAmmoXX : ASMDAmmoX { States { Spawn: SHOA A -1; Stop; } } Class ASMDAmmo2X : ASMDAmmoX { States { Spawn: SHOA B -1 Bright; Stop; } } Class ASMDAmmo2 : ASMDAmmo { Default { Tag "$T_ASMDAMMO2"; Inventory.Icon "I_ASMD"; Inventory.PickupMessage "$I_ASMDAMMO2"; Inventory.Amount 5; Ammo.DropAmount 3; } override void PostBeginPlay() { Ammo.PostBeginPlay(); tracer = Spawn("ASMDAmmo2X",pos); tracer.angle = angle; tracer.target = self; } States { Spawn: SHOA B -1; Stop; } } Class ASMDLight : EnforcerLight { Default { Args 64,32,255,70; } } Class ASMDBeamRing : Actor { Default { RenderStyle "Add"; +NOGRAVITY; +NOCLIP; +DONTSPLASH; Radius 0.1; Height 0; } override void Tick() { Super.Tick(); if ( isFrozen() ) return; A_FadeOut(0.05,0); } States { Spawn: RNGX ABCDEF 4 Bright; Stop; } } Class ASMDSBeamRing : ASMDBeamRing {} Class ASMDBlastRing : ASMDBeamRing { override void Tick() { Actor.Tick(); if ( isFrozen() ) return; A_FadeOut(0.028,0); } States { Spawn: RNGX ABCDEF 7 Bright; Stop; } } Class ASMDRingTrail : Actor { Default { RenderStyle "Add"; +NOGRAVITY; +NOCLIP; +DONTSPLASH; +INTERPOLATEANGLES; Radius 0.1; Height 0; } override void Tick() { Super.Tick(); if ( isFrozen() ) return; A_FadeOut(0.05,0); } States { Spawn: RNGX ABCDEF 4 Bright; Stop; } } Class ASMDBeamLight : PaletteLight { Default { Tag "Blue2"; Args 0,0,0,50; ReactionTime 30; } } Class ASMDSBeamLight : PaletteLight { Default { Tag "Ampd"; Args 0,0,0,50; ReactionTime 30; } } Class ASMDBlastLight : PaletteLight { Default { Tag "Purple"; ReactionTime 40; Args 0,0,0,300; } } Class ASMDSpark : Actor { Default { RenderStyle "Add"; Radius 2; Height 2; +NOBLOCKMAP; +NOGRAVITY; +MISSILE; +FORCEXYBILLBOARD; +THRUACTORS; +ROLLSPRITE; +ROLLCENTER; +NOTELEPORT; +DONTSPLASH; +CANBOUNCEWATER; -BOUNCEAUTOOFF; BounceType "Hexen"; BounceFactor 1.0; WallBounceFactor 1.0; Scale 0.1; } override void PostBeginPlay() { Super.PostBeginPlay(); roll = FRandom[ASMD](0,360); } States { Spawn: AFLA A 1 Bright { A_FadeOut(FRandom[ASMD](0.0,0.1)); vel *= 0.98; } Wait; } } Class ViewASMDSpark : 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_CoordUtil.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 ( isFrozen() ) return; ofs += vvel; vvel *= 0.9; scale *= 0.8; if ( scale.x <= 0.01 ) Destroy(); } States { Spawn: AFLA A 1 Bright A_FadeOut(FRandom[ASMD](0.0,0.1)); Wait; } } Class ASMDHitbox : ShockHitbox { Default { Health 1; +SHOOTABLE; +NOBLOOD; } override void Die( Actor source, Actor inflictor, int dmgflags, Name MeansOfDeath ) { if ( target && target.InStateSequence(target.CurState,target.FindState("Spawn")) ) { target.bAMBUSH = true; target.ExplodeMissile(); } Super.Die(source,inflictor,dmgflags,MeansOfDeath); } } Class ASMDBall : Actor { Actor b; double mult; double startangle, startpitch; override int SpecialMissileHit( Actor victim ) { if ( victim == b ) return 1; return -1; } override void PostBeginPlay() { Super.PostBeginPlay(); b = Spawn("ASMDHitbox",pos); b.target = self; startpitch = pitch; startangle = angle; } action void A_BallExplode() { if ( bAMBUSH ) return; pitch = invoker.startpitch; angle = invoker.startangle; roll = 0; UTMainHandler.DoBlast(self,70,70000); int dmg = int(55*(1+invoker.mult)); A_Explode(dmg,70); A_SprayDecal("ShockMarkBig",16); Actor r; if ( dmg > 60 ) { SetStateLabel("AmpDeath"); A_SetScale(0.7); let l = Spawn("ASMDSBeamLight",pos); l.Args[3] = 120; r = Spawn("ASMDSBeamRing",pos); } else { A_SetScale(1.3); let l = Spawn("ASMDBeamLight",pos); l.Args[3] = 120; r = Spawn("ASMDBeamRing",pos); } Vector3 HitNormal = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)); if ( BlockingLine ) HitNormal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit(); else if ( BlockingFloor ) { HitNormal = BlockingFloor.floorplane.Normal; r.SetOrigin(r.Vec3Offset(0,0,2),false); } else if ( BlockingCeiling ) HitNormal = BlockingCeiling.ceilingplane.Normal; r.angle = atan2(HitNormal.y,HitNormal.x); r.pitch = asin(-HitNormal.z); r.scale *= 1.5; A_PlaySound("shock/hit",CHAN_VOICE); A_PlaySound("shock/ball",CHAN_WEAPON,pitch:FRandom[ASMD](0.5,1.5)); 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= 10000.0 ) { // reposition and explode on air SetOrigin(t.Results.HitPos-t.Results.HitVector*4,false); double mult = Amplifier.GetMult(target,100); BeamExplode(mult>1.5); Actor r; if ( mult > 1.5 ) r = Spawn("ASMDSBeamRing",pos); else r = Spawn("ASMDBeamRing",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,false); 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,false); double mult = Amplifier.GetMult(target,100); Actor r; if ( t.Results.HitActor is 'ASMDHitbox' ) { BeamExplode(true); if ( target ) { target.TakeInventory('ASMDAmmo',2); 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; b.pitch = 90; b.angle = 0; b.roll = 0; UTMainHandler.DoBlast(b,240,140000); b.A_Explode(int(55*3.9*mult),240); b.A_SprayDecal("BigShockMark1",100); b.A_SprayDecal("SBigShockMark2",100); b.SetStateLabel("SuperDeath"); b.A_SetScale(1.8); let l = Spawn("ASMDBlastLight",pos); let r = Spawn("ASMDBlastRing",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,pitch:0.6); int numpt = Random[ASMD](200,300); for ( int i=0; i1.5); t.Results.HitActor.DamageMobj(self,target,int(35*mult),'jolted',DMG_USEANGLE,atan2(t.Results.HitVector.y,t.Results.HitVector.x)); UTMainHandler.DoKnockback(t.Results.HitActor,t.Results.HitVector,60000); if ( mult > 1.5 ) r = Spawn("ASMDSBeamRing",pos); else r = Spawn("ASMDBeamRing",pos); r.angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x); r.pitch = asin(-t.Results.HitVector.z); } } else { // reposition and explode on wall SetOrigin(t.Results.HitPos-t.Results.HitVector*4,false); A_SprayDecal("ShockMark",16); 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 ) HitNormal = t.Results.HitSector.floorplane.Normal; else if ( t.Results.HitType == TRACE_HitCeiling ) HitNormal = t.Results.HitSector.ceilingplane.Normal; double mult = Amplifier.GetMult(target,100); BeamExplode(mult>1.5); Actor r; if ( mult > 1.5 ) r = Spawn("ASMDSBeamRing",pos); else r = Spawn("ASMDBeamRing",pos); r.angle = atan2(HitNormal.y,HitNormal.x); r.pitch = asin(-HitNormal.z); } } void BeamExplode( bool amped = false ) { moving = false; if ( amped ) { Scale *= 0.3; SetStateLabel("AmpExplode"); Spawn("ASMDSBeamLight",pos); } else { SetStateLabel("Explode"); Spawn("ASMDBeamLight",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 0.5) ) player.SetPSPrite(PSP_WEAPON,invoker.FindState("Sway")); } Wait; Vapour: #### # 8 A_Overlay(-9999,"Dummy"); ASMI A 6 { A_PlaySound("asmd/vapour",CHAN_6,0.5); A_Overlay(PSP_FLASH,"VapourFlash"); A_OverlayFlags(PSP_FLASH,PSPF_RenderStyle,true); A_OverlayRenderstyle(PSP_FLASH,STYLE_Add); } ASMV ABCDEFGHIJ 4; Goto Idle; VapourFlash: ASVI A 6; ASVF ABCDEFGHIJ 4; Stop; Sway: #### # 4; ASMI C 10 A_JumpIf((!player.cmd.forwardmove && !player.cmd.sidemove) || (player.vel.length() < 0.5),4); ASMI D 10 A_JumpIf((!player.cmd.forwardmove && !player.cmd.sidemove) || (player.vel.length() < 0.5),5); ASMI E 10 A_JumpIf((!player.cmd.forwardmove && !player.cmd.sidemove) || (player.vel.length() < 0.5),6); ASMI F 10 A_JumpIf((!player.cmd.forwardmove && !player.cmd.sidemove) || (player.vel.length() < 0.5),7); Goto Sway+1; ASMI C 4; ASMI A 0 A_Jump(32,"Vapour"); Goto Idle; ASMI D 4; ASMI A 0 A_Jump(32,"Vapour"); Goto Idle; ASMI E 4; ASMI A 0 A_Jump(32,"Vapour"); Goto Idle; ASMI F 4; ASMI A 0 A_Jump(32,"Vapour"); Goto Idle; Fire: #### # 1 { A_ShockFire(); A_Overlay(-9999,"Null"); } ASMF ABCDEFGH 3; ASMF H 0 A_Jump(48,"Vapour"); Goto Idle; AltFire: #### # 1 { A_ShockAlt(); A_Overlay(-9999,"Null"); } ASMA ABCDFGHIJ 2; ASMA J 0 A_Jump(48,"Vapour"); Goto Idle; Deselect: ASMD A 1 A_Overlay(-9999,"Null"); ASMD BCDEFGHIJ 1; ASMD J 1 A_Lower(int.max); Wait; Select: ASMS A 1 A_Raise(int.max); Wait; Flash: ASFF A 2 Bright { let l = Spawn("ASMDLight",pos); l.target = self; } Stop; } }