671 lines
19 KiB
Text
671 lines
19 KiB
Text
// Cyrus Enterprises Sheen HMG (From SWWM Platinum Expansion Pack 2)
|
|
// Slot 5, spawns shared with Eviscerator
|
|
|
|
Class PiercingTracer : SpreadgunTracer
|
|
{
|
|
double penetration; // please don't laugh
|
|
double resist; // resistance against penetration loss (1.0 = don't lose)
|
|
|
|
override ETraceStatus TraceCallback()
|
|
{
|
|
// liquid splashes
|
|
if ( Results.CrossedWater )
|
|
{
|
|
let hl = new("WaterHit");
|
|
hl.sect = Results.CrossedWater;
|
|
hl.hitpos = Results.CrossedWaterPos;
|
|
WaterHitList.Push(hl);
|
|
}
|
|
else if ( Results.Crossed3DWater )
|
|
{
|
|
let hl = new("WaterHit");
|
|
hl.sect = Results.Crossed3DWater;
|
|
hl.hitpos = Results.Crossed3DWaterPos;
|
|
WaterHitList.Push(hl);
|
|
}
|
|
if ( Results.HitType == TRACE_HitActor )
|
|
{
|
|
if ( Results.HitActor == ignoreme ) return TRACE_Skip;
|
|
if ( Results.HitActor.bSHOOTABLE )
|
|
{
|
|
let ent = new("HitListEntry");
|
|
ent.hitactor = Results.HitActor;
|
|
ent.hitlocation = Results.HitPos;
|
|
ent.x = Results.HitVector;
|
|
if ( ((Results.HitActor.Health*(1.-resist)) >= penetration) || Results.HitActor.bNODAMAGE )
|
|
{
|
|
ent.hitdamage = int(penetration);
|
|
penetration = 0;
|
|
}
|
|
else
|
|
{
|
|
int gibh = (Results.HitActor.GibHealth!=int.min)?-abs(Results.HitActor.GibHealth):-int(Results.HitActor.GetSpawnHealth()*gameinfo.gibfactor);
|
|
ent.hitdamage = min(Results.HitActor.health+abs(gibh),int(penetration));
|
|
penetration = max(0,penetration-(ent.hitdamage*(1.-resist)));
|
|
}
|
|
hitlist.Push(ent);
|
|
if ( penetration <= 0 ) return TRACE_Stop;
|
|
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;
|
|
ShootThroughList.Push(Results.HitLine);
|
|
return TRACE_Skip;
|
|
}
|
|
return TRACE_Stop;
|
|
}
|
|
}
|
|
|
|
Class HeavyMahSheenGun : SWWMWeapon
|
|
{
|
|
transient int fired;
|
|
int firespeed;
|
|
double barrelheat, aimerror, vibrate;
|
|
bool incooldown, stopfire, firstshot;
|
|
int firetimer, shotcnt;
|
|
int tcol; // for random
|
|
|
|
transient ui SmoothDynamicValueInterpolator HeatInter;
|
|
transient PiercingTracer st;
|
|
|
|
override void HudTick()
|
|
{
|
|
Super.HudTick();
|
|
if ( !HeatInter ) HeatInter = SmoothDynamicValueInterpolator.Create(barrelheat,.5);
|
|
HeatInter.Update(barrelheat);
|
|
}
|
|
|
|
action void A_DropCasing()
|
|
{
|
|
Vector3 x, y, z;
|
|
[x, y, z] = SWWMUtility.GetPlayerAxes(self);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,4,8,-12);
|
|
let c = Spawn("SheenCasing",origin);
|
|
c.angle = angle;
|
|
c.pitch = pitch;
|
|
c.vel = x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](.5,2.)-(0,0,FRandom[Junk](2.,5.));
|
|
c.vel += vel*.5;
|
|
}
|
|
|
|
override Vector3 GetTraceOffset( int index )
|
|
{
|
|
return (10,0,-4);
|
|
}
|
|
|
|
action void A_SheenFire()
|
|
{
|
|
double spreadfct = (1.+invoker.aimerror+(invoker.barrelheat/50.)+invoker.firespeed**2.);
|
|
invoker.stopfire = ((invoker.Ammo1.Amount<=1)||!(player.cmd.buttons&BT_ATTACK)||(player.Health<=0));
|
|
invoker.barrelheat = invoker.barrelheat*(1.025-invoker.firespeed*.008)+3.-(invoker.firespeed**.8)*1.35;
|
|
invoker.aimerror = min(1.,invoker.aimerror*1.01+.01+invoker.firespeed*.01);
|
|
Vector3 x = SWWMUtility.GetPlayerViewDir(self);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,0,-4);
|
|
SWWMHandler.DoFlash(self,Color(32,255,224,64),3);
|
|
A_SWWMFlash();
|
|
if ( invoker.firespeed == 1 )
|
|
{
|
|
A_AlertMonsters(swwm_uncapalert?0:3000);
|
|
A_BumpFOV(.98);
|
|
A_QuakeEx(2,2,2,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.2);
|
|
A_StartSound("sheen/700rpm",CHAN_WEAPONEXTRA,CHANF_LOOPING,attenuation:.5);
|
|
invoker.vibrate = .25;
|
|
A_Overlay(-9999,"EjectRound3");
|
|
SWWMUtility.DoKnockback(self,-x,9000.);
|
|
SWWMUtility.AchievementProgress("dakka",(gametic-invoker.firetimer)/GameTicRate,player);
|
|
}
|
|
else if ( invoker.firespeed == 2 )
|
|
{
|
|
A_AlertMonsters(swwm_uncapalert?0:5000);
|
|
A_BumpFOV(.99+FRandom[Sheen](-.005,.005));
|
|
A_QuakeEx(2,2,2,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.15);
|
|
A_StartSound("sheen/2100rpm",CHAN_WEAPONEXTRA,CHANF_LOOPING,attenuation:.4);
|
|
invoker.vibrate = min(1.,invoker.vibrate*1.05+.05);
|
|
SWWMUtility.DoKnockback(self,-x,15000.);
|
|
A_Overlay(-9999,"EjectRound1");
|
|
}
|
|
else if ( invoker.firespeed == 0 )
|
|
{
|
|
A_AlertMonsters(swwm_uncapalert?0:2000);
|
|
A_BumpFOV(.97);
|
|
A_QuakeEx(2,2,2,8,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.25);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6);
|
|
SWWMUtility.DoKnockback(self,-x,6000.);
|
|
A_Overlay(-9999,"EjectRound7");
|
|
}
|
|
if ( invoker.barrelheat > 100. )
|
|
{
|
|
A_StartSound("sheen/overheat",CHAN_WEAPONEXTRA2,CHANF_LOOPING,attenuation:3.);
|
|
invoker.stopfire = invoker.incooldown = true;
|
|
}
|
|
if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
|
|
invoker.Ammo1.Amount--;
|
|
invoker.fired = gametic;
|
|
// dakka dakka dakka
|
|
Vector3 x2, y2, z2;
|
|
[x2, y2, z2] = SWWMUtility.GetPlayerAxesAutoAimed(self);
|
|
double a = FRandom[Sheen](0,360), s = FRandom[Sheen](.002,.02)*spreadfct;
|
|
Vector3 dir = SWWMUtility.ConeSpread(x2,y2,z2,a,s);
|
|
if ( !invoker.st ) invoker.st = new("PiercingTracer");
|
|
let st = invoker.st; // thanks zscript
|
|
st.ignoreme = self;
|
|
st.penetration = 60.+invoker.barrelheat/5.;
|
|
st.resist = .6+invoker.barrelheat/500.;
|
|
st.hitlist.Clear();
|
|
st.shootthroughlist.Clear();
|
|
st.waterhitlist.Clear();
|
|
st.Trace(origin,level.PointInSector(origin.xy),dir,8000.,TRACE_HitSky);
|
|
if ( swwm_omnibust )
|
|
{
|
|
// Wall busting
|
|
BusterWall.Bust(st.Results,int(st.penetration),self,st.Results.HitVector,st.Results.HitPos.z);
|
|
}
|
|
foreach ( l:st.ShootThroughList )
|
|
{
|
|
l.Activate(self,0,SPAC_PCross);
|
|
l.Activate(self,0,SPAC_Impact);
|
|
}
|
|
foreach ( w:st.WaterHitList )
|
|
{
|
|
let b = Spawn("InvisibleSplasher",w.hitpos);
|
|
b.target = self;
|
|
b.A_CheckTerrain();
|
|
}
|
|
for ( int i=5; i<st.Results.Distance; i+=10 )
|
|
{
|
|
if ( !Random[Boolet](0,2) ) continue;
|
|
let b = Actor.Spawn("SWWMBubble",level.Vec3Offset(origin,dir*i));
|
|
b.Scale *= FRandom[Boolet](.1,.3);
|
|
}
|
|
foreach ( hit:st.HitList )
|
|
{
|
|
int realdmg = hit.HitDamage;
|
|
let p = SWWMPuff.Setup(hit.HitLocation,hit.x,invoker,self,hit.HitActor);
|
|
SWWMDamageAccumulator.Accumulate(hit.HitActor,realdmg,p,self,'shot',flags:DMG_INFLICTOR_IS_PUFF);
|
|
SWWMUtility.DoKnockback(hit.HitActor,hit.x+(0,0,0.025),15000.*FRandom[Sheen](0.4,1.2));
|
|
if ( hit.HitActor.bNOBLOOD || hit.HitActor.bDORMANT || hit.HitActor.bINVULNERABLE )
|
|
{
|
|
let p = Spawn("SWWMBulletImpact",hit.HitLocation);
|
|
p.angle = atan2(hit.x.y,hit.x.x)+180;
|
|
p.pitch = asin(hit.x.z);
|
|
p.target = self;
|
|
}
|
|
else if ( realdmg > 0 )
|
|
{
|
|
hit.HitActor.TraceBleed(realdmg,self);
|
|
hit.HitActor.SpawnBlood(hit.HitLocation,atan2(hit.x.y,hit.x.x)+180,realdmg);
|
|
hit.HitActor.A_StartSound("misc/slughitf",CHAN_DAMAGE,CHANF_OVERLAP,1.,2.);
|
|
}
|
|
}
|
|
if ( (st.Results.HitType != TRACE_HitNone) && (st.Results.HitType != TRACE_HasHitSky) && (st.Results.HitType != TRACE_HitActor) )
|
|
{
|
|
Vector3 hitnormal = SWWMUtility.GetLineTracerHitNormal(st.Results);
|
|
let p = Spawn("SWWMBulletImpact",st.Results.HitPos+hitnormal*4);
|
|
p.angle = atan2(hitnormal.y,hitnormal.x);
|
|
p.pitch = asin(-hitnormal.z);
|
|
p.target = self;
|
|
if ( st.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40);
|
|
else if ( st.Results.HitType == TRACE_HitWall ) st.Results.HitLine.RemoteActivate(self,st.Results.Side,SPAC_Impact,st.Results.HitPos);
|
|
}
|
|
for ( int i=0; i<(5-invoker.firespeed); i++ )
|
|
{
|
|
let s = Spawn("SWWMSmoke",origin);
|
|
s.scale *= .5;
|
|
s.alpha *= .1;
|
|
s.speed *= .7;
|
|
s.vel += vel*.5+x*FRandom[Sheen](1.,3.);
|
|
}
|
|
int trail = CVar.GetCVar('swwm_funtrails',player).GetInt();
|
|
if ( trail == 8 )
|
|
{
|
|
if ( !invoker.firstshot ) invoker.tcol = Random[Sheen](1,7);
|
|
trail = invoker.tcol;
|
|
}
|
|
else if ( trail == 9 ) trail = 2+(invoker.shotcnt%6);
|
|
else if ( trail == 10 ) switch ( invoker.shotcnt%5 )
|
|
{
|
|
case 0:
|
|
case 3:
|
|
trail = 8;
|
|
break;
|
|
case 1:
|
|
case 4:
|
|
trail = 9;
|
|
break;
|
|
case 2:
|
|
trail = 1;
|
|
break;
|
|
}
|
|
let t = Spawn("SheenTrail",origin);
|
|
t.target = self;
|
|
t.angle = atan2(dir.y,dir.x);
|
|
t.pitch = asin(-dir.z);
|
|
t.specialf1 = st.Results.Distance;
|
|
t.specialf2 = invoker.barrelheat;
|
|
t.special2 = trail;
|
|
invoker.firstshot = true;
|
|
invoker.shotcnt++;
|
|
}
|
|
action void A_CheckContinueFire()
|
|
{
|
|
if ( invoker.incooldown || (invoker.Ammo1.Amount <= 0) || (player.Health <= 0) ) return;
|
|
invoker.stopfire = !(player.cmd.buttons&BT_ATTACK);
|
|
}
|
|
override void OwnerDied()
|
|
{
|
|
Super.OwnerDied();
|
|
aimerror = 0.;
|
|
vibrate = 0.;
|
|
}
|
|
override void Travelled()
|
|
{
|
|
Super.Travelled();
|
|
aimerror = 0.;
|
|
vibrate = 0.;
|
|
}
|
|
override void DoEffect()
|
|
{
|
|
Super.DoEffect();
|
|
barrelheat = max(0.,barrelheat*.99-.15);
|
|
bool hascooled = false;
|
|
if ( barrelheat <= 0. )
|
|
{
|
|
hascooled = incooldown;
|
|
incooldown = false;
|
|
if ( hascooled && Owner && Owner.player && (Owner.player.ReadyWeapon != self) && (Owner.player == players[consoleplayer]) )
|
|
Console.Printf(StringTable.Localize("$SWWM_SHEENREADY"));
|
|
}
|
|
if ( !Owner || !Owner.player || (Owner.player.ReadyWeapon != self) )
|
|
{
|
|
aimerror = 0.;
|
|
vibrate = 0.;
|
|
return;
|
|
}
|
|
if ( hascooled )
|
|
{
|
|
Owner.A_StopSound(CHAN_WEAPONEXTRA2);
|
|
Owner.A_StartSound("sheen/unlock",CHAN_WEAPONEXTRA2,CHANF_OVERLAP,attenuation:3.);
|
|
}
|
|
let pspm = Owner.player.FindPSprite(PSP_WEAPON);
|
|
if ( pspm )
|
|
{
|
|
pspm.x = FRandom[Shivers](-1.,1.)*vibrate*4.;
|
|
pspm.y = 32+FRandom[Shivers](-1.,1.)*vibrate*4.;
|
|
}
|
|
aimerror *= .9;
|
|
}
|
|
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
|
|
{
|
|
if ( sv_infiniteammo || Owner.FindInventory('PowerInfiniteAmmo',true) ) return true;
|
|
if ( (fireMode == PrimaryFire) || (fireMode == EitherFire) )
|
|
{
|
|
if ( Ammo1.Amount > 0 ) return true;
|
|
if ( autoswitch ) PlayerPawn(Owner).PickNewWeapon(null);
|
|
return false;
|
|
}
|
|
return Super.CheckAmmo(firemode,autoswitch,requireammo,ammocount);
|
|
}
|
|
override void InitializeWeapon()
|
|
{
|
|
firespeed = 1; // default to 700 RPM
|
|
}
|
|
|
|
override void MarkPrecacheSounds()
|
|
{
|
|
Super.MarkPrecacheSounds();
|
|
MarkSound("sheen/specialpick");
|
|
MarkSound("sheen/select");
|
|
MarkSound("sheen/deselect");
|
|
MarkSound("sheen/meleestart");
|
|
MarkSound("sheen/meleeend");
|
|
MarkSound("sheen/fire1");
|
|
MarkSound("sheen/fire2");
|
|
MarkSound("sheen/fire3");
|
|
MarkSound("sheen/700rpm");
|
|
MarkSound("sheen/2100rpm");
|
|
MarkSound("sheen/crankin");
|
|
MarkSound("sheen/crankout");
|
|
MarkSound("sheen/overheat");
|
|
MarkSound("sheen/unlock");
|
|
MarkSound("sheen/casing1");
|
|
MarkSound("sheen/casing2");
|
|
MarkSound("sheen/casing3");
|
|
MarkSound("sheen/casing4");
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_SHEENHMG";
|
|
Inventory.PickupMessage "$I_SHEENHMG";
|
|
Obituary "$O_SHEENHMG";
|
|
SWWMWeapon.Tooltip "$TT_SHEENHMG";
|
|
SWWMWeapon.GetLine "getheavymahsheengun";
|
|
SWWMWeapon.BobFactor 1., .0001;
|
|
Weapon.UpSound "sheen/select";
|
|
Weapon.SlotNumber 5;
|
|
Weapon.SlotPriority 2.;
|
|
Weapon.SelectionOrder 250;
|
|
Weapon.AmmoType1 "SheenAmmo";
|
|
Weapon.AmmoGive1 30;
|
|
SWWMWeapon.DropAmmoType "SWWMClipAmmoMed";
|
|
+SWWMWEAPON.HASSCRTEX;
|
|
Stamina 100000;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
Select:
|
|
XZW2 K 3
|
|
{
|
|
A_FullRaise();
|
|
if ( invoker.incooldown ) A_StartSound("sheen/overheat",CHAN_WEAPONEXTRA2,CHANF_LOOPING,attenuation:3.);
|
|
}
|
|
XZW2 LMNOP 3;
|
|
XZW2 QRSTUV 2;
|
|
XZW2 WX 3;
|
|
Goto Ready;
|
|
Ready:
|
|
XZW2 A 1
|
|
{
|
|
invoker.shotcnt = 0;
|
|
invoker.firetimer = gametic;
|
|
invoker.aimerror = 0.;
|
|
invoker.vibrate = 0.;
|
|
int flg = WRF_ALLOWRELOAD|WRF_ALLOWUSER1;
|
|
if ( invoker.firespeed > 0 ) flg |= WRF_ALLOWZOOM;
|
|
if ( invoker.firespeed >= 2 ) flg |= WRF_NOSECONDARY;
|
|
if ( (invoker.Ammo1.Amount <= 0) || invoker.incooldown ) flg |= WRF_NOPRIMARY;
|
|
A_WeaponReady(flg);
|
|
if ( player.cmd.buttons&BT_ATTACK )
|
|
invoker.CheckAmmo(EitherFire,true);
|
|
}
|
|
Wait;
|
|
Fire:
|
|
XZW2 A 2;
|
|
XZW2 Z 1
|
|
{
|
|
invoker.firstshot = false;
|
|
if ( (invoker.firespeed == 0) || (invoker.Ammo1.Amount <= 1) && !(player.cmd.buttons&BT_ATTACK) )
|
|
return A_Jump(256,"SlowFire1","SlowFire2","SlowFire3");
|
|
if ( invoker.firespeed == 1 )
|
|
return A_Jump(256,"FastFire1","FastFire2","FastFire3");
|
|
if ( invoker.firespeed == 2 )
|
|
return ResolveState("VeryFastFire");
|
|
return ResolveState(null);
|
|
}
|
|
Goto Ready;
|
|
SlowFire1:
|
|
XZW2 Z 1 A_SheenFire();
|
|
XZW3 ABCDEF 1;
|
|
XZW3 G 0;
|
|
XZW2 Z 0
|
|
{
|
|
if ( !invoker.incooldown && (invoker.Ammo1.Amount > 0) && (player.cmd.buttons&BT_ATTACK) )
|
|
return A_Jump(256,"SlowFire2","SlowFire3");
|
|
return ResolveState(null);
|
|
}
|
|
Goto StopFire;
|
|
SlowFire2:
|
|
XZW2 Z 1 A_SheenFire();
|
|
XZW3 HIJKLM 1;
|
|
XZW3 N 0;
|
|
XZW2 Z 0
|
|
{
|
|
if ( !invoker.incooldown &&(invoker.Ammo1.Amount > 0) && (player.cmd.buttons&BT_ATTACK) )
|
|
return A_Jump(256,"SlowFire1","SlowFire3");
|
|
return ResolveState(null);
|
|
}
|
|
Goto StopFire;
|
|
SlowFire3:
|
|
XZW2 Z 1 A_SheenFire();
|
|
XZW3 OPQRST 1;
|
|
XZW3 U 0
|
|
{
|
|
if ( !invoker.incooldown &&(invoker.Ammo1.Amount > 0) && (player.cmd.buttons&BT_ATTACK) )
|
|
return A_Jump(256,"SlowFire1","SlowFire2");
|
|
return ResolveState(null);
|
|
}
|
|
Goto StopFire;
|
|
FastFire1:
|
|
XZW2 Z 1 A_SheenFire();
|
|
XZW3 VW 1 A_CheckContinueFire();
|
|
XZW3 X 0
|
|
{
|
|
A_CheckContinueFire();
|
|
if ( !invoker.stopfire ) return A_Jump(256,"FastFire2","FastFire3");
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
|
return ResolveState(null);
|
|
}
|
|
Goto StopFire;
|
|
FastFire2:
|
|
XZW2 Z 1 A_SheenFire();
|
|
XZW3 YZ 1 A_CheckContinueFire();
|
|
XZW4 A 0
|
|
{
|
|
A_CheckContinueFire();
|
|
if ( !invoker.stopfire ) return A_Jump(256,"FastFire1","FastFire3");
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
|
return ResolveState(null);
|
|
}
|
|
Goto StopFire;
|
|
FastFire3:
|
|
XZW2 Z 1 A_SheenFire();
|
|
XZW4 BC 1 A_CheckContinueFire();
|
|
XZW4 D 0
|
|
{
|
|
A_CheckContinueFire();
|
|
if ( !invoker.stopfire ) return A_Jump(256,"FastFire1","FastFire2");
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
|
return ResolveState(null);
|
|
}
|
|
Goto StopFire;
|
|
VeryFastFire:
|
|
XZW2 Z 1 A_SheenFire();
|
|
XZW4 E 1
|
|
{
|
|
A_CheckContinueFire();
|
|
if ( invoker.stopfire )
|
|
{
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
|
return ResolveState("EndFireFast1");
|
|
}
|
|
A_SheenFire();
|
|
return ResolveState(null);
|
|
}
|
|
XZW4 F 1
|
|
{
|
|
A_CheckContinueFire();
|
|
if ( invoker.stopfire )
|
|
{
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
|
return ResolveState("EndFireFast2");
|
|
}
|
|
A_SheenFire();
|
|
return ResolveState(null);
|
|
}
|
|
XZW4 G 1
|
|
{
|
|
A_CheckContinueFire();
|
|
if ( invoker.stopfire )
|
|
{
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
|
return ResolveState("EndFireFast3");
|
|
}
|
|
A_SheenFire();
|
|
return ResolveState(null);
|
|
}
|
|
XZW4 H 1
|
|
{
|
|
A_CheckContinueFire();
|
|
if ( invoker.stopfire )
|
|
{
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
|
return ResolveState("EndFireFast4");
|
|
}
|
|
A_SheenFire();
|
|
return ResolveState(null);
|
|
}
|
|
XZW4 I 1
|
|
{
|
|
A_CheckContinueFire();
|
|
if ( invoker.stopfire )
|
|
{
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
|
return ResolveState("EndFireFast5");
|
|
}
|
|
A_SheenFire();
|
|
return ResolveState(null);
|
|
}
|
|
XZW4 J 1
|
|
{
|
|
A_CheckContinueFire();
|
|
if ( invoker.stopfire )
|
|
{
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
|
return ResolveState("EndFireFast6");
|
|
}
|
|
A_SheenFire();
|
|
return ResolveState(null);
|
|
}
|
|
VeryFastFireHold:
|
|
XZW4 K 1
|
|
{
|
|
A_CheckContinueFire();
|
|
if ( invoker.stopfire )
|
|
{
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
|
return ResolveState("EndFireFast7");
|
|
}
|
|
A_SheenFire();
|
|
return ResolveState(null);
|
|
}
|
|
XZW4 L 0;
|
|
Goto VeryFastFireHold;
|
|
EndFireFast7:
|
|
XZW4 MNO 2 { invoker.vibrate *= .25; }
|
|
Goto Ready;
|
|
EndFireFast6:
|
|
XZW4 PQR 2 { invoker.vibrate *= .25; }
|
|
Goto Ready;
|
|
EndFireFast5:
|
|
XZW4 STU 2 { invoker.vibrate *= .25; }
|
|
Goto Ready;
|
|
EndFireFast4:
|
|
XZW4 VWX 2 { invoker.vibrate *= .25; }
|
|
Goto Ready;
|
|
EndFireFast3:
|
|
XZW4 YZ 2 { invoker.vibrate *= .25; }
|
|
XZW5 A 2 { invoker.vibrate *= .25; }
|
|
Goto Ready;
|
|
EndFireFast2:
|
|
XZW5 BCD 2 { invoker.vibrate *= .25; }
|
|
Goto Ready;
|
|
EndFireFast1:
|
|
XZW5 EFG 2 { invoker.vibrate *= .25; }
|
|
Goto Ready;
|
|
StopFire:
|
|
XZW2 Z 2 A_StopSound(CHAN_WEAPONEXTRA); // just in case
|
|
Goto Ready;
|
|
EjectRound7:
|
|
TNT1 A 7;
|
|
Goto EjectRound;
|
|
EjectRound3:
|
|
TNT1 A 3;
|
|
Goto EjectRound;
|
|
EjectRound1:
|
|
TNT1 A 1;
|
|
Goto EjectRound;
|
|
EjectRound:
|
|
TNT1 A 1 A_DropCasing();
|
|
Stop;
|
|
AltFire:
|
|
XZW2 A 3 A_StartSound("sheen/crankin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 IJ 2;
|
|
XZW5 K 3
|
|
{
|
|
invoker.firespeed = min(2,invoker.firespeed+1);
|
|
EventHandler.SendInterfaceEvent(PlayerNumber(),"swwmnametag.$SWWM_SHEENSPEED"..(invoker.firespeed+1));
|
|
}
|
|
XZW5 L 4 A_StartSound("sheen/crankout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 M 5;
|
|
Goto Ready;
|
|
Zoom:
|
|
XZW2 A 3 A_StartSound("sheen/crankin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 NO 2;
|
|
XZW5 P 3
|
|
{
|
|
invoker.firespeed = max(0,invoker.firespeed-1);
|
|
EventHandler.SendInterfaceEvent(PlayerNumber(),"swwmnametag.$SWWM_SHEENSPEED"..(invoker.firespeed+1));
|
|
}
|
|
XZW5 Q 4 A_StartSound("sheen/crankout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 R 5;
|
|
Goto Ready;
|
|
Reload:
|
|
XZW2 A 3
|
|
{
|
|
A_StartSound("sheen/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_PlayerCheckGun();
|
|
}
|
|
XZW5 TUVW 3;
|
|
XZW5 XYZ 4;
|
|
XZW6 A 4;
|
|
XZW6 B 3 A_StartSound("sheen/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW6 CDE 3;
|
|
XZW6 FGHIJKL 2;
|
|
Goto Ready;
|
|
User1:
|
|
XZW2 A 3 A_StartSound("sheen/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW6 MNOPQR 3;
|
|
XZW6 S 3 A_StartSound("demolitionist/wswing",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW6 T 3;
|
|
XZW6 U 2
|
|
{
|
|
A_Parry(9);
|
|
A_PlayerMelee();
|
|
}
|
|
XZW6 V 2;
|
|
XZW6 W 2 A_Melee(80+int(invoker.barrelheat/4.),"demolitionist/whitl",1.25,1.3,1.4);
|
|
XZW6 XYZ 3;
|
|
XZW7 AB 4;
|
|
XZW7 C 4 A_StartSound("sheen/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW7 DEFGHIJKL 2;
|
|
Goto Ready;
|
|
Deselect:
|
|
XZW2 A 2 A_StartSound("sheen/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW2 BCDEFGHIJK 2;
|
|
XZW2 K -1
|
|
{
|
|
A_StopSound(CHAN_WEAPONEXTRA2);
|
|
A_FullLower();
|
|
}
|
|
Stop;
|
|
Flash:
|
|
XZW0 A 2 Bright
|
|
{
|
|
let psp = player.FindPSprite(PSP_FLASH);
|
|
psp.frame = Random[GunFlash](0,23);
|
|
if ( (invoker.firespeed != 2) || !(invoker.shotcnt%3) )
|
|
{
|
|
let l = Spawn("SWWMWeaponLight",pos);
|
|
l.target = self;
|
|
l.Args[3] -= (psp.frame%3)*20;
|
|
}
|
|
}
|
|
Stop;
|
|
}
|
|
}
|