Omnisight now handles 3d floors and midtextures, and exit line merging works properly. Reduced Pusher primary fire damage slightly. Cleared improper usages of GetAge().
546 lines
14 KiB
Text
546 lines
14 KiB
Text
// Dr. Locke's Mighty Wolf Breath Airgun aka "Deep Impact" Airblaster (from SWWM series)
|
|
// Slot 1, replaces Fist, Staff, Hexen starting weapons
|
|
|
|
Class AirBullet : FastProjectile
|
|
{
|
|
int tcnt;
|
|
Actor lasthit;
|
|
|
|
Default
|
|
{
|
|
Obituary "$O_DEEPIMPACT";
|
|
Radius 2;
|
|
Height 4;
|
|
DamageFunction 100;
|
|
DamageType 'AirRip';
|
|
Speed 400;
|
|
PROJECTILE;
|
|
+FORCERADIUSDMG;
|
|
+NODAMAGETHRUST;
|
|
+RIPPER;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
A_StartSound("deepimpact/bullet",CHAN_BODY,CHANF_LOOPING,1.,1.5);
|
|
}
|
|
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
|
|
{
|
|
if ( target.bBOSS ) damage = int(damage*.4);
|
|
if ( !bAMBUSH )
|
|
{
|
|
if ( target == lasthit ) return 0;
|
|
lasthit = target;
|
|
}
|
|
SWWMHandler.DoKnockback(target,vel.unit(),10000);
|
|
return damage;
|
|
}
|
|
override void Effect()
|
|
{
|
|
let r = Spawn("AirBulletRing",pos);
|
|
r.angle = angle;
|
|
r.pitch = pitch;
|
|
r.roll = FRandom[Impact](0,360);
|
|
r.scale *= .3;
|
|
r.alpha *= .6;
|
|
int numpt = Random[ExploS](2,4);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](.1,.8);
|
|
let s = Spawn("SWWMSmoke",pos);
|
|
s.vel = pvel+vel.unit()*3.;
|
|
s.SetShade(Color(1,1,1)*Random[ExploS](240,255));
|
|
s.special1 = Random[ExploS](1,2);
|
|
s.scale *= 1.8;
|
|
s.alpha *= .2;
|
|
}
|
|
bAMBUSH = true;
|
|
A_Explode(GetMissileDamage(0,0),80,0);
|
|
bAMBUSH = false;
|
|
tcnt++;
|
|
if ( tcnt < 2 ) return;
|
|
tcnt = 0;
|
|
Spawn("AirRingLight",pos);
|
|
}
|
|
void A_Splode()
|
|
{
|
|
A_AlertMonsters(8000);
|
|
if ( target && SWWMUtility.SphereIntersect(target,pos,120) )
|
|
{
|
|
// push away
|
|
Vector3 dir = level.Vec3Diff(pos,target.Vec3Offset(0,0,target.height/2));
|
|
double dist = dir.length();
|
|
dir /= dist;
|
|
double mm = 8000000./max(20.,dist);
|
|
if ( (target.pos.z > target.floorz) && target.TestMobjZ() ) mm *= 1.6;
|
|
SWWMHandler.DoKnockback(target,dir,mm);
|
|
}
|
|
SWWMHandler.DoBlast(self,400,100000);
|
|
A_QuakeEx(6,6,6,20,0,250,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.);
|
|
A_StartSound("deepimpact/bullethit",CHAN_VOICE,CHANF_DEFAULT,1.,.3);
|
|
A_SprayDecal("ImpactMark");
|
|
Spawn("AirBulletLight",pos);
|
|
int numpt = Random[ExploS](10,20);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,6);
|
|
let s = Spawn("SWWMSmoke",pos);
|
|
s.vel = pvel;
|
|
s.SetShade(Color(1,1,1)*Random[ExploS](240,255));
|
|
s.special1 = Random[ExploS](1,2);
|
|
s.scale *= 2.4;
|
|
s.alpha *= .4;
|
|
}
|
|
numpt = Random[ExploS](8,12);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,6);
|
|
let s = Spawn("SWWMSpark",pos);
|
|
s.vel = pvel;
|
|
}
|
|
numpt = Random[ExploS](6,16);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,12);
|
|
let s = Spawn("SWWMChip",pos);
|
|
s.vel = pvel;
|
|
}
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
TNT1 A -1;
|
|
Stop;
|
|
Death:
|
|
TNT1 A 1 A_Splode();
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class AirBulletLight : PaletteLight
|
|
{
|
|
Default
|
|
{
|
|
Tag "ImpactWav";
|
|
ReactionTime 5;
|
|
Args 0,0,0,150;
|
|
}
|
|
}
|
|
|
|
Class AirRingLight : PaletteLight
|
|
{
|
|
Default
|
|
{
|
|
Tag "ImpactWav2";
|
|
ReactionTime 30;
|
|
Args 0,0,0,120;
|
|
}
|
|
}
|
|
|
|
Class AirBulletRing : Actor
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
+NOGRAVITY;
|
|
+NOBLOCKMAP;
|
|
+DONTSPLASH;
|
|
+ROLLSPRITE;
|
|
+ROLLCENTER;
|
|
+FORCEXYBILLBOARD;
|
|
+NOINTERACTION;
|
|
Radius 0.1;
|
|
Height 0;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XRG1 ABCDEFGHIJKLMNOPQRSTUVWX 2;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class DeepTracer : LineTracer
|
|
{
|
|
Actor ignoreme;
|
|
Array<Actor> hitlist;
|
|
Array<double> hitdist;
|
|
|
|
override ETraceStatus TraceCallback()
|
|
{
|
|
if ( Results.HitType == TRACE_HitActor )
|
|
{
|
|
if ( Results.HitActor == ignoreme ) return TRACE_Skip;
|
|
if ( Results.HitActor.bSHOOTABLE )
|
|
{
|
|
hitlist.Push(Results.HitActor);
|
|
hitdist.Push(Results.Distance);
|
|
return TRACE_Skip;
|
|
}
|
|
return TRACE_Skip;
|
|
}
|
|
else if ( (Results.HitType == TRACE_HitWall) && (Results.Tier == TIER_Middle) )
|
|
{
|
|
if ( !Results.HitLine.sidedef[1] || (Results.HitLine.Flags&(Line.ML_BlockHitscan|Line.ML_BlockEverything)) )
|
|
return TRACE_Stop;
|
|
return TRACE_Skip;
|
|
}
|
|
return TRACE_Stop;
|
|
}
|
|
}
|
|
|
|
Class THitList
|
|
{
|
|
Actor a;
|
|
int nhits;
|
|
Vector3 avgdir;
|
|
double avgdist;
|
|
}
|
|
|
|
Class DeepImpact : SWWMWeapon
|
|
{
|
|
int clipcount;
|
|
double charge;
|
|
bool charging;
|
|
|
|
transient ui TextureID WeaponBox, AmmoBar;
|
|
transient ui DynamicValueInterpolator ChargeInter;
|
|
transient ui Font TewiFont;
|
|
|
|
Property ClipCount : clipcount;
|
|
|
|
override void DrawWeapon( double TicFrac, double bx, double by, Vector2 hs, Vector2 ss )
|
|
{
|
|
if ( !WeaponBox ) WeaponBox = TexMan.CheckForTexture("graphics/HUD/DeepImpactDisplay.png",TexMan.Type_Any);
|
|
if ( !TewiFont ) TewiFont = Font.GetFont('TewiShaded');
|
|
if ( !AmmoBar ) AmmoBar = TexMan.CheckForTexture("graphics/HUD/DeepImpactBar.png",TexMan.Type_Any);
|
|
Screen.DrawTexture(WeaponBox,false,bx-36,by-54,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
int chg = clamp(ChargeInter?ChargeInter.GetValue():clipcount,0,100);
|
|
int ct = int(((by-2)-(chg*50./100.))*hs.y);
|
|
Screen.DrawTexture(AmmoBar,false,bx-7,by-52,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ClipTop,ct);
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,bx-35,by-13,String.Format("%3d%%",chg),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
|
|
override void HudTick()
|
|
{
|
|
if ( !ChargeInter ) ChargeInter = DynamicValueInterpolator.Create(clipcount,.5,1,25);
|
|
ChargeInter.Update(clipcount);
|
|
}
|
|
|
|
override bool ReportHUDAmmo()
|
|
{
|
|
return (ClipCount>0);
|
|
}
|
|
|
|
action void A_BeginCharge()
|
|
{
|
|
invoker.charge = 0;
|
|
A_StartSound("deepimpact/charge",CHAN_WEAPONEXTRA);
|
|
A_QuakeEx(2,2,2,35,0,1,"",QF_RELATIVE|QF_SCALEUP,rollIntensity:.2);
|
|
A_AlertMonsters(100);
|
|
}
|
|
|
|
action void A_ChargeUp()
|
|
{
|
|
invoker.charge += 1./TICRATE;
|
|
A_WeaponOffset(FRandom[Impact](-1,1)*invoker.charge,32+FRandom[Impact](-1,1)*invoker.charge);
|
|
if ( invoker.charge >= (invoker.clipcount*.01) )
|
|
{
|
|
A_WeaponOffset(0,32);
|
|
player.SetPSprite(PSP_WEAPON,ResolveState("AltRelease"));
|
|
}
|
|
}
|
|
|
|
action void A_DryFire()
|
|
{
|
|
let weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
A_StartSound("deepimpact/dryfire",CHAN_WEAPON,CHANF_OVERLAP,.5);
|
|
A_AlertMonsters(70);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+2*y-3*z);
|
|
int numpt = Random[Impact](5,7);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (x+(FRandom[Impact](-.1,.1),FRandom[Impact](-.1,.1),FRandom[Impact](-.1,.1))).unit()*FRandom[Impact](.1,.4);
|
|
let s = Spawn("SWWMSmoke",origin);
|
|
s.vel = pvel;
|
|
s.scale *= .3;
|
|
s.alpha *= .05;
|
|
s.SetShade(Color(1,1,1)*Random[Impact](192,255));
|
|
}
|
|
}
|
|
|
|
action void A_Air()
|
|
{
|
|
let weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.05);
|
|
A_StartSound("deepimpact/fire",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_AlertMonsters(300);
|
|
A_PlayerFire();
|
|
invoker.clipcount = max(0,invoker.clipcount-3);
|
|
Vector3 x, y, z, dir;
|
|
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
|
SWWMHandler.DoKnockback(self,-x,2000.);
|
|
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+2*y-3*z);
|
|
DeepTracer t = new("DeepTracer");
|
|
t.ignoreme = self;
|
|
Array<THitList> list;
|
|
list.Clear();
|
|
int rings = 1;
|
|
int wallhits = 0;
|
|
Vector3 hitnormal;
|
|
Vector3 wnorm = (0,0,0);
|
|
for ( double i=0; i<1.; i+=.05 )
|
|
{
|
|
for ( int j=0; j<360; j+=(360/rings) )
|
|
{
|
|
dir = (x+y*cos(j)*i+z*sin(j)*i).unit();
|
|
t.hitlist.Clear();
|
|
t.hitdist.Clear();
|
|
t.Trace(origin,level.PointInSector(origin.xy),dir,150-i*50,0);
|
|
for ( int i=0; i<t.hitlist.Size(); i++ )
|
|
{
|
|
int inl = -1;
|
|
for ( int k=0; k<list.Size(); k++ )
|
|
{
|
|
if ( list[k].a != t.hitlist[i] ) continue;
|
|
inl = k;
|
|
break;
|
|
}
|
|
if ( inl == -1 )
|
|
{
|
|
THitList l = new("THitList");
|
|
l.a = t.hitlist[i];
|
|
inl = list.Push(l);
|
|
}
|
|
list[inl].nhits++;
|
|
list[inl].avgdir += dir;
|
|
list[inl].avgdist += t.hitdist[i];
|
|
}
|
|
if ( t.Results.HitType == TRACE_HitWall )
|
|
{
|
|
t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos);
|
|
wallhits++;
|
|
hitnormal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
|
|
if ( !t.Results.Side ) hitnormal *= -1;
|
|
wnorm += (hitnormal*.2-dir)/max(50.,t.Results.Distance);
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitFloor )
|
|
{
|
|
wallhits++;
|
|
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.top.Normal;
|
|
else hitnormal = t.Results.HitSector.floorplane.Normal;
|
|
wnorm += (hitnormal*.2-dir)/max(50.,t.Results.Distance);
|
|
}
|
|
else if ( t.Results.HitType == TRACE_HitCeiling )
|
|
{
|
|
wallhits++;
|
|
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.bottom.Normal;
|
|
else hitnormal = t.Results.HitSector.ceilingplane.Normal;
|
|
wnorm += (hitnormal*.2-dir)/max(50.,t.Results.Distance);
|
|
}
|
|
}
|
|
rings += 5;
|
|
}
|
|
if ( wallhits > 0 )
|
|
{
|
|
wnorm /= wallhits;
|
|
if ( (pos.z > floorz) && TestMobjZ() ) wnorm *= 2.4;
|
|
SWWMHandler.DoKnockback(self,wnorm.unit(),wnorm.length()*5000000.);
|
|
}
|
|
for ( int i=0; i<list.Size(); i++ )
|
|
{
|
|
Vector3 avgdir = list[i].avgdir/list[i].nhits;
|
|
double avgdist = list[i].avgdist/list[i].nhits;
|
|
double dmg = 4000.*(1.-clamp(avgdist/300.,0.,1.));
|
|
if ( !list[i].a.bCANNOTPUSH && (list[i].a.mass < LARGE_MASS) )
|
|
list[i].a.vel += ((avgdir+(0,0,.35))*dmg/max(50,list[i].a.mass));
|
|
list[i].a.DamageMobj(self,self,int(dmg/500.),'Push',DMG_THRUSTLESS);
|
|
}
|
|
let ti = ThinkerIterator.Create("Actor");
|
|
Actor m;
|
|
while ( m = Actor(ti.Next()) )
|
|
{
|
|
if ( !m.bMISSILE ) continue;
|
|
double rdist = level.Vec3Diff(origin,m.pos).length();
|
|
Vector3 rdir = level.Vec3Diff(origin,m.pos).unit();
|
|
if ( LineTrace(atan2(rdir.y,rdir.x),rdist,asin(-rdir.z),TRF_THRUACTORS|TRF_ABSPOSITION,origin.z,origin.x,origin.y) || (rdist > 150) || (rdir dot x < 0.7) ) continue;
|
|
m.speed = m.vel.length();
|
|
m.vel = m.speed*1.5*(m.vel.unit()*.2+rdir).unit();
|
|
Vector3 ndir = m.vel.unit();
|
|
m.angle = atan2(ndir.y,ndir.x);
|
|
m.pitch = asin(-ndir.z);
|
|
if ( m.target == self ) continue;
|
|
if ( m.bSEEKERMISSILE ) m.tracer = m.target;
|
|
m.target = self;
|
|
}
|
|
int numpt = Random[Impact](7,12);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (x+(FRandom[Impact](-.2,.2),FRandom[Impact](-.2,.2),FRandom[Impact](-.2,.2))).unit()*FRandom[Impact](.5,4);
|
|
let s = Spawn("SWWMSmoke",origin);
|
|
s.vel = pvel;
|
|
s.special1 = 1;
|
|
s.scale *= .5;
|
|
s.alpha *= .15;
|
|
s.SetShade(Color(1,1,1)*Random[Impact](192,255));
|
|
}
|
|
}
|
|
|
|
action void A_AltBullet()
|
|
{
|
|
let weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_QuakeEx(6,6,6,10,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.7);
|
|
A_StartSound("deepimpact/altfire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.5);
|
|
A_AlertMonsters(8000);
|
|
A_PlayerFire();
|
|
invoker.clipcount = 0;
|
|
Vector3 x, y, z, x2, y2, z2;
|
|
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
|
SWWMHandler.DoKnockback(self,-x,42000.);
|
|
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+2*y-3*z);
|
|
double a = FRandom[Spread](0,360), s = FRandom[Spread](0,.002);
|
|
[x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll);
|
|
Vector3 dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
|
|
let p = Spawn("AirBullet",origin);
|
|
p.target = self;
|
|
p.angle = atan2(dir.y,dir.x);
|
|
p.pitch = asin(-dir.z);
|
|
p.vel = dir*p.speed;
|
|
invoker.charge = 0;
|
|
int numpt = Random[Impact](14,18);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (x+(FRandom[Impact](-.5,.5),FRandom[Impact](-.5,.5),FRandom[Impact](-.5,.5))).unit()*FRandom[Impact](1,6);
|
|
let s = Spawn("SWWMSmoke",origin);
|
|
s.vel = pvel;
|
|
s.special1 = 2;
|
|
s.scale *= .7;
|
|
s.alpha *= .2;
|
|
s.SetShade(Color(1,1,1)*Random[Impact](192,255));
|
|
}
|
|
}
|
|
|
|
action void A_Crank()
|
|
{
|
|
invoker.clipcount = min(invoker.default.clipcount,invoker.clipcount+20);
|
|
A_StartSound("deepimpact/reload",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_QuakeEx(1,1,1,7,0,1,"",QF_RELATIVE|QF_SCALEUP,rollIntensity:.05);
|
|
}
|
|
|
|
action void A_NoCrank()
|
|
{
|
|
A_StartSound("deepimpact/noreload",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE|QF_SCALEUP,rollIntensity:.05);
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_DEEPIMPACT";
|
|
Inventory.PickupMessage "$I_DEEPIMPACT";
|
|
Obituary "$O_DEEPIMPACT_WEAK";
|
|
Inventory.Icon "graphics/HUD/Icons/W_DeepImpact.png";
|
|
Weapon.UpSound "deepimpact/select";
|
|
Weapon.SlotNumber 1;
|
|
Weapon.SelectionOrder 3000;
|
|
Stamina 6000;
|
|
DeepImpact.ClipCount 100;
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
Select:
|
|
XZW2 I 2 A_FullRaise();
|
|
XZW2 JKLMNOP 2;
|
|
Goto Ready;
|
|
Ready:
|
|
XZW2 A 1 A_WeaponReady(WRF_ALLOWRELOAD|WRF_ALLOWUSER1|WRF_ALLOWZOOM);
|
|
Wait;
|
|
DryFire:
|
|
XZW2 A 1 A_DryFire();
|
|
XZW2 QR 2;
|
|
XZW2 TU 3;
|
|
XZW2 A 4;
|
|
Goto Ready;
|
|
Fire:
|
|
XZW2 A 0 A_JumpIf(invoker.ClipCount<=0,"DryFire");
|
|
XZW2 A 1 A_Air();
|
|
XZW2 QR 2;
|
|
XZW2 STUA 3;
|
|
Goto Ready;
|
|
AltFire:
|
|
XZW2 A 0 A_JumpIf(invoker.ClipCount<100,"Reload");
|
|
XZW2 A 0 A_BeginCharge();
|
|
XZW2 A 1 A_ChargeUp();
|
|
Wait;
|
|
AltRelease:
|
|
XZW2 A 1 A_AltBullet();
|
|
XZW2 VW 1;
|
|
XZW2 X 2;
|
|
XZW2 YZ 3;
|
|
XZW3 AB 5;
|
|
XZW3 CD 4;
|
|
XZW3 EFG 3;
|
|
Goto Ready;
|
|
Reload:
|
|
XZW2 A 0 A_JumpIf(invoker.clipcount>=invoker.default.clipcount,"NoReload");
|
|
XZW2 A 2 A_StartSound("deepimpact/reloadbeg",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW3 HIJ 2;
|
|
ReloadHold:
|
|
XZW3 K 2 A_Crank();
|
|
XZW3 LM 2;
|
|
XZW3 NOPQ 3;
|
|
XZW3 K 0 A_JumpIf((player.cmd.buttons&(BT_RELOAD|BT_ALTATTACK))&&(invoker.clipcount<invoker.default.clipcount),"ReloadHold");
|
|
XZW3 K 2 A_StartSound("deepimpact/reloadend",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW3 RSTUV 2;
|
|
Goto Ready;
|
|
NoReload:
|
|
XZW2 A 2 A_StartSound("deepimpact/reloadbeg",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW3 HIJ 2;
|
|
NoReloadHold:
|
|
XZW3 K 2 A_NoCrank();
|
|
XZW3 L 2;
|
|
XZW3 M 5;
|
|
XZW3 L 3;
|
|
XZW3 K 2 A_StartSound("deepimpact/reloadend",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW3 RSTUV 2;
|
|
Goto Ready;
|
|
Zoom:
|
|
XZW2 A 3
|
|
{
|
|
A_StartSound("deepimpact/checkout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_PlayerCheckGun();
|
|
}
|
|
XZW3 WXYZ 3;
|
|
XZW4 AB 4;
|
|
XZW4 CD 3;
|
|
XZW4 EFG 2;
|
|
Goto Ready;
|
|
User1:
|
|
XZW2 A 2
|
|
{
|
|
A_StartSound("demolitionist/wswing",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_PlayerMelee();
|
|
}
|
|
XZW4 H 2 A_StartSound("demolitionist/reloadbeg",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW4 I 2;
|
|
XZW4 J 1 A_Parry(9);
|
|
XZW4 KLM 1;
|
|
XZW4 N 4 A_Melee(60,"demolitionist/whits");
|
|
XZW4 O 3 { invoker.PlayUpSound(self); }
|
|
XZW4 PQRSTUV 2;
|
|
Goto Ready;
|
|
Deselect:
|
|
XZW2 A 2 A_StartSound("deepimpact/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW2 BCDEFGHI 2;
|
|
XZW2 I -1 A_FullLower();
|
|
Stop;
|
|
}
|
|
}
|