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; +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 = level.Vec3Offset(target.Vec2OffsetZ(0,0,target.player.viewz),x*ofs.x+y*ofs.y+z*ofs.z); SetOrigin(origin,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 { Radius 6; Height 12; } } Class ASMDBall : Actor { Actor b; double mult; double startangle, startpitch; override int SpecialMissileHit( Actor victim ) { if ( victim is 'ASMDHitbox' ) 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 = dt_Utility.Vec3FromAngle(angle,pitch); if ( BlockingLine ) HitNormal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit(); else if ( BlockingFloor ) { // find closest 3d floor for its normal F3DFloor ff = null; 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(mult>1.5); if ( target && !sv_infiniteammo && !target.FindInventory('PowerInfiniteAmmo',true) ) target.TakeInventory('ASMDAmmo',2); let b = t.Results.HitActor.target; b.bAMBUSH = true; b.ExplodeMissile(); 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_StartSound("asmd/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 ) { if ( t.Results.ffloor ) HitNormal = -t.Results.ffloor.top.Normal; else HitNormal = t.Results.HitSector.floorplane.Normal; } else if ( t.Results.HitType == TRACE_HitCeiling ) { if ( t.Results.ffloor ) HitNormal = -t.Results.ffloor.bottom.Normal; else HitNormal = t.Results.HitSector.ceilingplane.Normal; } 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_StartSound("asmd/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_StartSound("asmd/vapour",CHAN_WEAPONMISC,CHANF_DEFAULT,.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; } }