Use it sparingly in places where it should have been needed (Hellblazer and Biospark pre/post fire, Hammer alt charge, MR overpressure charge). Also, replace all instances of A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH) with it, since that was basically the same thing but with extra steps (and with the side effect of potentially resetting psprite offsets).
1279 lines
36 KiB
Text
1279 lines
36 KiB
Text
// Munch Innovations Explodium Gun (from SWWM series)
|
|
// Slot 2, replaces Pistol, Elven Wand, Hexen starting weapons
|
|
|
|
Class ExplodiumGun : SWWMWeapon
|
|
{
|
|
int clipcount;
|
|
bool chambered;
|
|
bool preinit;
|
|
bool firstselect;
|
|
double casex, casey;
|
|
int deadeyecnt;
|
|
|
|
Property ClipCount : ClipCount;
|
|
|
|
override Vector3 GetTraceOffset( int index )
|
|
{
|
|
return (10.,3.,-2.);
|
|
}
|
|
|
|
override bool HandlePickup( Inventory item )
|
|
{
|
|
// can't hold both weapons at once
|
|
if ( swwm_swapweapons && IsSwapWeapon(item) )
|
|
return true;
|
|
if ( (item.GetClass() == 'ExplodiumGun') && !item.ShouldStay() )
|
|
{
|
|
if ( !deathmatch && (Amount+item.Amount > MaxAmount) && (item.Stamina != 0) )
|
|
{
|
|
// sell excess
|
|
if ( Owner.player )
|
|
{
|
|
int sellprice = abs(item.Stamina)/2;
|
|
SWWMCredits.Give(Owner.player,sellprice);
|
|
if ( Owner.player == players[consoleplayer] )
|
|
{
|
|
SWWMScoreObj.SpawnAtActorBunch(sellprice,Owner);
|
|
Console.Printf(StringTable.Localize(SWWMUtility.SellFemaleItem(item)?"$SWWM_SELLEXTRA_FEM":"$SWWM_SELLEXTRA"),GetTag(),sellprice);
|
|
}
|
|
else Console.Printf(StringTable.Localize(SWWMUtility.SellFemaleItem(item)?"$SWWM_SELLEXTRAREM_FEM":"$SWWM_SELLEXTRAREM"),Owner.player.GetUserName(),GetTag(),sellprice);
|
|
}
|
|
item.bPickupGood = true;
|
|
}
|
|
// give a spare
|
|
if ( Amount < MaxAmount )
|
|
{
|
|
Amount++;
|
|
// if the gun has status info, override our sister
|
|
let eg = ExplodiumGun(item);
|
|
if ( eg && eg.preinit )
|
|
{
|
|
DualExplodiumGun(SisterWeapon).chambered = eg.chambered;
|
|
DualExplodiumGun(SisterWeapon).clipcount = eg.clipcount;
|
|
}
|
|
else
|
|
{
|
|
// otherwise use defaults
|
|
DualExplodiumGun(SisterWeapon).chambered = false;
|
|
DualExplodiumGun(SisterWeapon).clipcount = DualExplodiumGun(SisterWeapon).default.clipcount;
|
|
}
|
|
// autoswitch if enabled
|
|
if ( Owner.player && !Owner.player.GetNeverSwitch() )
|
|
Owner.player.PendingWeapon = SisterWeapon;
|
|
// add the oneliner
|
|
let demo = Demolitionist(Owner);
|
|
if ( demo && demo.mystats && !demo.mystats.GotWeapon(SisterWeapon.GetClass()) && (Owner.player == players[consoleplayer]) && !demo.ingivecheat )
|
|
{
|
|
SWWMHandler.AddOneliner(SWWMWeapon(SisterWeapon).GetLine,2);
|
|
demo.facegrin = true;
|
|
}
|
|
item.bPickupGood = true;
|
|
}
|
|
return true;
|
|
}
|
|
return Weapon.HandlePickup(item);
|
|
}
|
|
|
|
action void A_Schutt()
|
|
{
|
|
let weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
invoker.chambered = invoker.clipcount;
|
|
invoker.clipcount = max(invoker.clipcount-1,0);
|
|
A_StartSound("explodium/fire",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_QuakeEx(4.5,4.5,4.5,3,0,10,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:1.5);
|
|
A_BumpFOV(.96);
|
|
A_BumpView(-.2);
|
|
A_SWWMFlash();
|
|
SWWMHandler.DoFlash(self,Color(64,255,224,64),3);
|
|
A_AlertMonsters(swwm_uncapalert?0:5000);
|
|
A_PlayerFire();
|
|
Vector3 x = SWWMUtility.GetPlayerViewDir(self);
|
|
SWWMUtility.DoKnockback(self,-x,4000.);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,3,-2);
|
|
double a = FRandom[Spread](0,360), s = FRandom[Spread](0,.002);
|
|
let [x2, y2, z2] = SWWMUtility.GetPlayerAxesAutoAimed(self);
|
|
Vector3 dir = SWWMUtility.ConeSpread(x2,y2,z2,a,s);
|
|
FLineTraceData d;
|
|
LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
|
SWWMBulletTrail.DoTrail(self,origin,dir,10000,2);
|
|
if ( d.HitType == TRACE_HitActor )
|
|
{
|
|
if ( d.HitActor.IsHostile(self) )
|
|
{
|
|
invoker.deadeyecnt++;
|
|
SWWMUtility.AchievementProgress("deadeye",invoker.deadeyecnt,player);
|
|
}
|
|
int dmg = 15;
|
|
// might as well apply explosion on top
|
|
if ( dmg >= d.HitActor.Health ) dmg += 25;
|
|
SWWMUtility.DoKnockback(d.HitActor,d.HitDir,48000);
|
|
let p = SWWMPuff.Setup(d.HitLocation,d.HitDir,invoker,self,d.HitActor);
|
|
dmg = d.HitActor.DamageMobj(p,self,dmg,'Explodium',DMG_THRUSTLESS|DMG_INFLICTOR_IS_PUFF);
|
|
if ( !d.HitActor || d.HitActor.bNOBLOOD || d.HitActor.bDORMANT || d.HitActor.bINVULNERABLE )
|
|
{
|
|
let p = Spawn("SWWMBulletImpact",d.HitLocation);
|
|
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
|
|
p.pitch = asin(d.HitDir.z);
|
|
p.target = self;
|
|
}
|
|
else if ( dmg > 0 )
|
|
{
|
|
d.HitActor.TraceBleed(dmg,self);
|
|
d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg);
|
|
}
|
|
let b = Spawn("ExplodiumBulletImpact",d.HitLocation-d.HitDir*4.);
|
|
b.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
|
|
b.pitch = asin(d.HitDir.z);
|
|
b.target = self;
|
|
}
|
|
else if ( d.HitType != TRACE_HitNone )
|
|
{
|
|
invoker.deadeyecnt = 0;
|
|
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
|
|
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
|
|
p.angle = atan2(hitnormal.y,hitnormal.x);
|
|
p.pitch = asin(-hitnormal.z);
|
|
p.target = self;
|
|
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
|
|
let b = Spawn("ExplodiumBulletImpact",d.HitLocation+hitnormal*4.);
|
|
b.angle = atan2(hitnormal.y,hitnormal.x);
|
|
b.pitch = asin(-hitnormal.z);
|
|
b.target = self;
|
|
if ( swwm_omnibust ) BusterWall.BustLinetrace(d,50,self,d.HitDir,d.HitLocation.z);
|
|
}
|
|
else invoker.deadeyecnt = 0;
|
|
for ( int i=0; i<6; i++ )
|
|
{
|
|
let s = Spawn("SWWMSmoke",origin);
|
|
s.scale *= .15;
|
|
s.alpha *= .5;
|
|
s.speed *= .2;
|
|
s.vel += vel*.5+x*FRandom[Explodium](.2,.5);
|
|
}
|
|
}
|
|
|
|
action void A_ThrowMag()
|
|
{
|
|
invoker.deadeyecnt = 0;
|
|
let weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,-2,-3);
|
|
double a = FRandom[Spread](0,360), s = FRandom[Spread](0,.005);
|
|
let [x2, y2, z2] = SWWMUtility.GetPlayerAxesAutoAimed(self);
|
|
Vector3 dir = SWWMUtility.ConeSpread(x2,y2,z2,a,s);
|
|
let p = Spawn("ExplodiumMagProj",origin);
|
|
p.special1 = invoker.special1;
|
|
p.target = self;
|
|
p.angle = atan2(dir.y,dir.x);
|
|
p.pitch = asin(-dir.z);
|
|
p.vel = dir*p.speed;
|
|
if ( FindInventory("RagekitPower") )
|
|
{
|
|
p.vel *= 4.;
|
|
p.ClearBounce();
|
|
}
|
|
if ( p.waterlevel <= 0 ) p.vel.z += 5.;
|
|
p.vel += vel*.5;
|
|
}
|
|
|
|
action void A_DropMag()
|
|
{
|
|
invoker.deadeyecnt = 0;
|
|
if ( swwm_nomagdrop ) return;
|
|
let [x, y, z] = SWWMUtility.GetPlayerAxes(self);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,-2,-10);
|
|
let c = Spawn("ExplodiumMag",origin);
|
|
c.angle = angle;
|
|
c.pitch = pitch;
|
|
c.vel = x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](-1.2,.3)-(0,0,FRandom[Junk](2,3));
|
|
c.vel += vel*.5;
|
|
}
|
|
|
|
action void A_DropCasing()
|
|
{
|
|
let [x, y, z] = SWWMUtility.GetPlayerAxes(self);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,8,-10);
|
|
let c = Spawn("ExplodiumCasing",origin);
|
|
c.angle = angle;
|
|
c.pitch = pitch;
|
|
c.vel = x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](2,4)-(0,0,FRandom[Junk](2,3));
|
|
c.vel += vel*.5;
|
|
}
|
|
|
|
override bool ReportHUDAmmo()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
override bool Use( bool pickup )
|
|
{
|
|
// switch to dual if already selected or if first selecting (unless disabled)
|
|
if ( Owner.player && (Amount > 1) && ((Owner.player.ReadyWeapon == self) || ((Owner.player.ReadyWeapon != SisterWeapon) && !swwm_singlefirst)) )
|
|
{
|
|
// if the player's current weapon is a gesture, set sister as the former weapon, to avoid breaking gesture sequences
|
|
if ( Owner.player.ReadyWeapon is 'SWWMGesture' )
|
|
{
|
|
let g = SWWMGesture(Owner.player.ReadyWeapon);
|
|
g.formerweapon = SisterWeapon;
|
|
}
|
|
else if ( Owner.player.PendingWeapon is 'SWWMGesture' )
|
|
{
|
|
let g = SWWMGesture(Owner.player.PendingWeapon);
|
|
g.formerweapon = SisterWeapon;
|
|
}
|
|
else if ( Owner.player.ReadyWeapon is 'SWWMItemGesture' )
|
|
{
|
|
let ig = SWWMItemGesture(Owner.player.ReadyWeapon);
|
|
ig.gest.formerweapon = SisterWeapon;
|
|
}
|
|
else if ( Owner.player.PendingWeapon is 'SWWMItemGesture' )
|
|
{
|
|
let ig = SWWMItemGesture(Owner.player.PendingWeapon);
|
|
ig.gest.formerweapon = SisterWeapon;
|
|
}
|
|
else Owner.player.PendingWeapon = self;
|
|
Owner.player.PendingWeapon = SisterWeapon;
|
|
return false;
|
|
}
|
|
return Super.Use(pickup);
|
|
}
|
|
|
|
override Inventory CreateTossable( int amt )
|
|
{
|
|
// disallow dropping if weapon isn't ready for switching
|
|
if ( (Owner.player.ReadyWeapon == self) && (!(Owner.player.WeaponState&WF_WEAPONSWITCHOK) || (Owner.player.WeaponState&WF_DISABLESWITCH)) )
|
|
return null;
|
|
let copy = ExplodiumGun(Inventory.CreateTossable(1));
|
|
if ( !copy ) return null;
|
|
// destroy sister weapon if we're removing ourselves
|
|
if ( copy == self )
|
|
{
|
|
preinit = true; // need this in case we get picked up again out of order
|
|
if ( SisterWeapon )
|
|
{
|
|
SisterWeapon.SisterWeapon = null;
|
|
SisterWeapon.Destroy();
|
|
}
|
|
// reattach our glow if we became a pickup
|
|
if ( PickupFlash is 'SWWMPickupFlash' )
|
|
{
|
|
let p = Spawn(PickupFlash,pos);
|
|
p.target = self;
|
|
p.SetStateLabel("Pickup");
|
|
}
|
|
}
|
|
else if ( SisterWeapon )
|
|
{
|
|
// pass sister's clipcount and chamber status to copy
|
|
copy.chambered = DualExplodiumGun(SisterWeapon).chambered;
|
|
copy.clipcount = DualExplodiumGun(SisterWeapon).clipcount;
|
|
copy.preinit = true; // signal that this copy has preset info
|
|
// forcibly switch back from sister weapon
|
|
if ( Owner.player.ReadyWeapon == SisterWeapon )
|
|
{
|
|
Owner.player.ReadyWeapon = self;
|
|
Owner.player.SetPSprite(PSP_WEAPON,FindState("Ready"));
|
|
Owner.player.SetPSprite(PSP_WEAPON+1,null); // delete left weapon psprite
|
|
}
|
|
}
|
|
return copy;
|
|
}
|
|
|
|
override void MarkPrecacheSounds()
|
|
{
|
|
Super.MarkPrecacheSounds();
|
|
MarkSound("explodium/casing1");
|
|
MarkSound("explodium/casing2");
|
|
MarkSound("explodium/casing3");
|
|
MarkSound("explodium/casing4");
|
|
MarkSound("explodium/checkout");
|
|
MarkSound("explodium/fire1");
|
|
MarkSound("explodium/fire2");
|
|
MarkSound("explodium/fire3");
|
|
MarkSound("explodium/hit1");
|
|
MarkSound("explodium/hit2");
|
|
MarkSound("explodium/hit3");
|
|
MarkSound("explodium/jamitin");
|
|
MarkSound("explodium/mag1");
|
|
MarkSound("explodium/mag2");
|
|
MarkSound("explodium/mag3");
|
|
MarkSound("explodium/maghit1");
|
|
MarkSound("explodium/maghit2");
|
|
MarkSound("explodium/magin");
|
|
MarkSound("explodium/magout");
|
|
MarkSound("explodium/magpin");
|
|
MarkSound("explodium/select");
|
|
MarkSound("explodium/deselect");
|
|
MarkSound("explodium/slideback");
|
|
MarkSound("explodium/slideforward");
|
|
MarkSound("explodium/speen");
|
|
MarkSound("explodium/throwmag");
|
|
}
|
|
|
|
override void PlayUpSound( Actor origin )
|
|
{
|
|
if ( firstselect ) return;
|
|
Super.PlayUpSound(origin);
|
|
}
|
|
|
|
override void SetTags( String colname )
|
|
{
|
|
A_ChangeModel("",1,"","",0,"models","DemoTags"..colname..".png",CMDL_USESURFACESKIN,-1);
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_EXPLODIUM";
|
|
Inventory.Icon "graphics/HUD/Icons/W_ExplodiumGun.png";
|
|
Inventory.PickupMessage "$T_EXPLODIUM";
|
|
Obituary "$O_EXPLODIUM";
|
|
SWWMWeapon.Tooltip "$TT_EXPLODIUM";
|
|
SWWMWeapon.GetLine "getexplodiumgun1";
|
|
Weapon.UpSound "explodium/select";
|
|
Weapon.SlotNumber 2;
|
|
Weapon.SelectionOrder 1000;
|
|
Inventory.MaxAmount 2;
|
|
Weapon.SisterWeapon "DualExplodiumGun";
|
|
Stamina 8000;
|
|
ExplodiumGun.ClipCount 7;
|
|
+WEAPON.EXPLOSIVE;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
Select:
|
|
XZW2 B 2
|
|
{
|
|
invoker.deadeyecnt = 0;
|
|
A_FullRaise();
|
|
return A_JumpIf(invoker.firstselect,"FirstSelect");
|
|
}
|
|
XZW2 CDE 2 A_BumpView(-.1,tics:2);
|
|
XZW2 FGH 2 A_BumpView(.05,tics:2);
|
|
Goto Ready;
|
|
FirstSelect:
|
|
XZW2 B 1 A_JumpIf(level.maptime>8,1);
|
|
Wait;
|
|
XZW2 B 2
|
|
{
|
|
invoker.firstselect = false;
|
|
invoker.PlayUpSound(self);
|
|
}
|
|
XZW2 CDE 2 A_BumpView(-.1,tics:2);
|
|
XZW2 FGH 2 A_BumpView(.05,tics:2);
|
|
XZW2 A 2;
|
|
Goto Slide;
|
|
Ready:
|
|
XZW2 A 1
|
|
{
|
|
if ( invoker.firstselect ) player.SetPSprite(PSP_WEAPON,ResolveState("FirstSelect"));
|
|
else if ( (invoker.clipcount > 0) && !invoker.chambered ) player.SetPSprite(PSP_WEAPON,ResolveState("Slide"));
|
|
else A_WeaponReady(WRF_ALLOWZOOM|WRF_ALLOWUSER1|WRF_ALLOWRELOAD);
|
|
}
|
|
Wait;
|
|
Fire:
|
|
XZW2 A 1
|
|
{
|
|
A_Schutt();
|
|
return A_JumpIf((invoker.clipcount<=0)&&!invoker.chambered,"FireLast");
|
|
}
|
|
XZW2 I 1;
|
|
XZW2 J 1
|
|
{
|
|
int layer = PSP_WEAPON+2;
|
|
while ( player.FindPSprite(layer) ) layer++;
|
|
A_Overlay(layer,"Casing");
|
|
}
|
|
XZW2 KLMNOP 1;
|
|
XZW2 Q 2;
|
|
Goto Ready;
|
|
FireLast:
|
|
XZW2 A 1;
|
|
XZWA K 1;
|
|
XZWA L 1
|
|
{
|
|
int layer = PSP_WEAPON+2;
|
|
while ( player.FindPSprite(layer) ) layer++;
|
|
A_Overlay(layer,"Casing");
|
|
}
|
|
XZWA M 1;
|
|
XZWA N 1 A_StartSound("explodium/slidelock",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWA OPQR 1;
|
|
XZWA S 2;
|
|
Goto ReloadLast;
|
|
ReloadLast:
|
|
XZW9 X 1 A_PlayerReload();
|
|
XZW9 Z 1;
|
|
XZWA XYZ 1;
|
|
XZWB ABCD 1;
|
|
XZWB E 1 { invoker.clipcount = 0; }
|
|
XZWB F 1;
|
|
XZWB G 1 A_StartSound("explodium/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWB H 1 A_BumpView(.3);
|
|
XZWB IJK 1;
|
|
XZWB L 1 A_DropMag();
|
|
XZWB MNOPQR 1;
|
|
XZWB S 1
|
|
{
|
|
A_BumpView(-.1);
|
|
A_StartSound("explodium/magin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZWB TUVWXYZ 1;
|
|
XZWC ABCD 1;
|
|
XZWC E 1
|
|
{
|
|
A_BumpView(-.4);
|
|
A_StartSound("explodium/jamitin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.clipcount = invoker.default.clipcount;
|
|
}
|
|
XZWC FGHI 1;
|
|
XZWC J 1
|
|
{
|
|
A_StartSound("explodium/slideforward",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.clipcount--;
|
|
invoker.chambered = true;
|
|
}
|
|
XZWC K 1;
|
|
XZWC L 3;
|
|
XZWC MNOP 1;
|
|
Goto Ready;
|
|
Casing:
|
|
XZWA A 1
|
|
{
|
|
A_OverlayOffset(OverlayID(),0,0);
|
|
invoker.casex = FRandom[Explodium](-1.,5.);
|
|
invoker.casey = FRandom[Explodium](-2.,1.);
|
|
}
|
|
XZWA BCDEFGHIJ 1 A_OverlayOffset(OverlayID(),invoker.casex,invoker.casey,WOF_ADD|WOF_INTERPOLATE);
|
|
TNT1 A 1 A_DropCasing();
|
|
Stop;
|
|
AltFire:
|
|
XZW2 A 2
|
|
{
|
|
A_PlayerReload();
|
|
return A_JumpIf(invoker.clipcount<=0,"Reload");
|
|
}
|
|
XZW5 NO 2;
|
|
XZW5 P 1 A_StartSound("explodium/magpin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 QRSTUVWXYZ 1;
|
|
XZW6 AB 1;
|
|
XZW6 C 1
|
|
{
|
|
A_StartSound("explodium/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.special1 = invoker.clipcount;
|
|
invoker.clipcount = 0;
|
|
}
|
|
XZW6 D 1
|
|
{
|
|
A_StartSound("explodium/throwmag",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_PlayerMelee();
|
|
}
|
|
XZW6 EFGHI 1 A_BumpView(.25);
|
|
XZW6 JKLMNO 1;
|
|
XZW6 PRS 1 A_BumpView(-1.5);
|
|
XZW6 T 1 A_ThrowMag();
|
|
XZW6 UV 2;
|
|
XZW6 W 2
|
|
{
|
|
A_PlayerReload();
|
|
A_StartSound("explodium/magget",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZW6 XY 2;
|
|
XZW6 Z 4;
|
|
Goto ReloadEnd;
|
|
Reload:
|
|
XZW2 A 1
|
|
{
|
|
if ( invoker.clipcount >= invoker.default.clipcount ) return ResolveState("CheckBullet");
|
|
A_PlayerReload();
|
|
if ( invoker.clipcount <= 0 ) return ResolveState("ReloadEmpty");
|
|
return ResolveState(null);
|
|
}
|
|
XZW2 TUVWXYZ 1;
|
|
XZW3 A 1;
|
|
XZW3 B 1 { invoker.clipcount = 0; }
|
|
XZW3 C 1;
|
|
XZW3 D 1 A_StartSound("explodium/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW3 E 1 A_BumpView(.3);
|
|
XZW3 FGH 1;
|
|
XZW3 I 1 A_DropMag();
|
|
Goto ReloadEnd;
|
|
ReloadEmpty:
|
|
XZW2 A 1;
|
|
XZW3 JKLMNOPQRS 1;
|
|
XZW3 T 1 A_StartSound("explodium/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW3 U 1 A_BumpView(.3);
|
|
XZW3 VWX 1;
|
|
XZW3 Y 1 A_DropMag();
|
|
Goto ReloadEnd;
|
|
ReloadEnd:
|
|
XZW3 Z 1;
|
|
XZW4 ABCDE 1;
|
|
XZW4 F 1
|
|
{
|
|
A_BumpView(-.1);
|
|
A_StartSound("explodium/magin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZW4 GHIJKLMNOPQ 1;
|
|
XZW4 R 1
|
|
{
|
|
A_BumpView(-.4);
|
|
A_StartSound("explodium/jamitin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.clipcount = invoker.default.clipcount;
|
|
}
|
|
XZW4 STUV 1;
|
|
XZW2 A 1 A_JumpIf(!invoker.chambered,"Slide");
|
|
Goto Ready;
|
|
Slide:
|
|
XZW2 A 1;
|
|
XZW4 WXY 1 A_BumpView(-.1);
|
|
XZW5 A 1 A_StartSound("explodium/slideback",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 BC 1;
|
|
XZW5 D 1 { invoker.chambered = true; invoker.clipcount--; }
|
|
XZW5 EFG 1 A_BumpView(.1);
|
|
XZW5 H 1 A_StartSound("explodium/slideforward",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 IJKLM 1;
|
|
Goto Ready;
|
|
Zoom:
|
|
XZW2 A 1
|
|
{
|
|
A_PlayerCheckGun();
|
|
return A_Jump(256,"Zoom1","Zoom2","Zoom2");
|
|
}
|
|
Goto Ready;
|
|
CheckBullet:
|
|
XZW2 A 1;
|
|
XZW7 A 1 A_Overlay(PSP_WEAPON+1,"CheckBulletCasing");
|
|
XZW7 BCDE 1 A_BumpView(-.2);
|
|
XZW7 F 1 A_StartSound("explodium/slideback",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW7 GHIJKLMNOP 1;
|
|
XZW7 Q 1
|
|
{
|
|
A_BumpView(.6);
|
|
A_StartSound("explodium/slideforward",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZW7 RS 1;
|
|
Goto Ready;
|
|
CheckBulletCasing:
|
|
XZWC QRSTUVWXYZ 1;
|
|
XZWD ABCDEFGHI 1;
|
|
Stop;
|
|
User1:
|
|
XZW2 A 1;
|
|
XZW7 TU 1 A_BumpView(.1);
|
|
User1Hold:
|
|
XZW7 V 1
|
|
{
|
|
A_BumpAngle(1.);
|
|
A_PlayerMelee(true);
|
|
A_StartSound("demolitionist/swing",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_Parry(9);
|
|
}
|
|
XZW7 WX 1 A_BumpAngle(-.5);
|
|
XZW7 Y 1 A_Melee();
|
|
XZW7 Z 2;
|
|
XZW8 ABCDE 2;
|
|
XZW8 F 1 A_JumpIf(player.cmd.buttons&BT_USER1,"User1Hold");
|
|
XZW2 B 0 { invoker.PlayUpSound(self); }
|
|
Goto Select;
|
|
Zoom1:
|
|
XZW2 A 2 A_StartSound("explodium/checkout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW8 GHIJ 2 A_BumpView(-.2);
|
|
XZW8 KLMNO 2 A_BumpView(-.3);
|
|
XZW8 PQR 2 A_BumpView(.5);
|
|
XZW8 STUV 2 A_BumpView(.2);
|
|
XZW8 WXYZ 2;
|
|
Goto Ready;
|
|
Zoom2:
|
|
XZW2 A 1 A_StartSound("explodium/speen",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW9 ABCD 1 A_BumpView(.2);
|
|
XZW9 EFGHIJ 1 A_BumpView(-.2);
|
|
XZW9 KLMNOP 1 A_BumpView(-.1);
|
|
XZW9 QRST 1 A_BumpView(.3);
|
|
XZW9 UVW 1;
|
|
Goto Ready;
|
|
Deselect:
|
|
XZW2 A 2 A_StartSound("explodium/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWA TUVW 2 A_BumpView(.1,tics:2);
|
|
XZW2 B -1 A_FullLower();
|
|
Stop;
|
|
Flash:
|
|
XZWZ A 2 Bright
|
|
{
|
|
let psp = player.GetPSprite(PSP_FLASH);
|
|
psp.frame = Random[GunFlash](0,9);
|
|
let l = Spawn("SWWMWeaponLight",pos);
|
|
l.target = self;
|
|
}
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// Dual Explodium Guns
|
|
Class DualExplodiumGun : SWWMWeapon
|
|
{
|
|
int clipcount;
|
|
bool chambered;
|
|
double casex, casey, lcasex, lcasey;
|
|
|
|
Property ClipCount : ClipCount;
|
|
|
|
override Vector3 GetTraceOffset( int index )
|
|
{
|
|
if ( index == 1 ) return (10.,3.5,-2.);
|
|
return (10.,-3.5,-2.);
|
|
}
|
|
|
|
action void A_LeftFlash( StateLabel flashlabel = null )
|
|
{
|
|
if ( !player || !player.ReadyWeapon )
|
|
return;
|
|
Weapon weap = player.ReadyWeapon;
|
|
State flashstate = null;
|
|
if ( !flashlabel )
|
|
{
|
|
if ( weap.bAltFire )
|
|
flashstate = weap.FindState('LeftAltFlash');
|
|
if ( !flashstate )
|
|
flashstate = weap.FindState('LeftFlash');
|
|
}
|
|
else flashstate = weap.FindState(flashlabel);
|
|
player.SetPSprite(PSP_FLASH+1,flashstate);
|
|
A_OverlayFlags(PSP_FLASH+1,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
|
|
A_OverlayRenderStyle(PSP_FLASH+1,STYLE_Add);
|
|
}
|
|
|
|
action void A_Schutt( int side = 1 )
|
|
{
|
|
let weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( side == 1 )
|
|
{
|
|
ExplodiumGun(invoker.SisterWeapon).chambered = ExplodiumGun(invoker.SisterWeapon).clipcount;
|
|
ExplodiumGun(invoker.SisterWeapon).clipcount = max(ExplodiumGun(invoker.SisterWeapon).clipcount-1,0);
|
|
}
|
|
else if ( side == -1 )
|
|
{
|
|
invoker.chambered = invoker.clipcount;
|
|
invoker.clipcount = max(invoker.clipcount-1,0);
|
|
}
|
|
A_StartSound("explodium/fire",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_QuakeEx(4.5,4.5,4.5,3,0,10,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:1.5);
|
|
A_BumpFOV(.96);
|
|
A_BumpView(-.2);
|
|
if ( side == 1 )
|
|
A_SWWMFlash("Flash");
|
|
else if ( side == -1 )
|
|
A_LeftFlash("LeftFlash");
|
|
SWWMHandler.DoFlash(self,Color(64,255,224,64),3);
|
|
A_AlertMonsters(swwm_uncapalert?0:5000);
|
|
A_PlayerFire();
|
|
Vector3 x = SWWMUtility.GetPlayerViewDir(self);
|
|
SWWMUtility.DoKnockback(self,-x,4000.);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,3.5*side,-2);
|
|
double a = FRandom[Spread](0,360), s = FRandom[Spread](0,.002);
|
|
let [x2, y2, z2] = SWWMUtility.GetPlayerAxesAutoAimed(self);
|
|
Vector3 dir = SWWMUtility.ConeSpread(x2,y2,z2,a,s);
|
|
FLineTraceData d;
|
|
LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
|
SWWMBulletTrail.DoTrail(self,origin,dir,10000,2);
|
|
if ( d.HitType == TRACE_HitActor )
|
|
{
|
|
if ( d.HitActor.IsHostile(self) )
|
|
{
|
|
ExplodiumGun(invoker.SisterWeapon).deadeyecnt++;
|
|
SWWMUtility.AchievementProgress("deadeye",ExplodiumGun(invoker.SisterWeapon).deadeyecnt,player);
|
|
}
|
|
int dmg = 15;
|
|
// might as well apply explosion on top
|
|
if ( dmg >= d.HitActor.Health ) dmg += 25;
|
|
SWWMUtility.DoKnockback(d.HitActor,d.HitDir,48000);
|
|
let p = SWWMPuff.Setup(d.HitLocation,d.HitDir,invoker,self,d.HitActor);
|
|
dmg = d.HitActor.DamageMobj(p,self,dmg,'Explodium',DMG_THRUSTLESS|DMG_INFLICTOR_IS_PUFF);
|
|
if ( d.HitActor.bNOBLOOD || d.HitActor.bDORMANT || d.HitActor.bINVULNERABLE )
|
|
{
|
|
let p = Spawn("SWWMBulletImpact",d.HitLocation);
|
|
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
|
|
p.pitch = asin(d.HitDir.z);
|
|
p.target = self;
|
|
}
|
|
else if ( dmg > 0 )
|
|
{
|
|
d.HitActor.TraceBleed(dmg,self);
|
|
d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg);
|
|
}
|
|
let b = Spawn("ExplodiumBulletImpact",d.HitLocation-d.HitDir*4.);
|
|
b.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
|
|
b.pitch = asin(d.HitDir.z);
|
|
b.target = self;
|
|
}
|
|
else if ( d.HitType != TRACE_HitNone )
|
|
{
|
|
ExplodiumGun(invoker.SisterWeapon).deadeyecnt = 0;
|
|
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
|
|
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
|
|
p.angle = atan2(hitnormal.y,hitnormal.x);
|
|
p.pitch = asin(-hitnormal.z);
|
|
p.target = self;
|
|
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
|
|
let b = Spawn("ExplodiumBulletImpact",d.HitLocation+hitnormal*4.);
|
|
b.angle = atan2(hitnormal.y,hitnormal.x);
|
|
b.pitch = asin(-hitnormal.z);
|
|
b.target = self;
|
|
if ( swwm_omnibust ) BusterWall.BustLinetrace(d,50,self,d.HitDir,d.HitLocation.z);
|
|
}
|
|
else ExplodiumGun(invoker.SisterWeapon).deadeyecnt = 0;
|
|
for ( int i=0; i<6; i++ )
|
|
{
|
|
let s = Spawn("SWWMSmoke",origin);
|
|
s.scale *= .15;
|
|
s.alpha *= .5;
|
|
s.speed *= .2;
|
|
s.vel += vel*.5+x*FRandom[Explodium](.2,.5);
|
|
}
|
|
}
|
|
|
|
action void A_DropMag( int side = 1 )
|
|
{
|
|
ExplodiumGun(invoker.SisterWeapon).deadeyecnt = 0;
|
|
if ( swwm_nomagdrop ) return;
|
|
let [x, y, z] = SWWMUtility.GetPlayerAxes(self);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,-2*side,-10);
|
|
let c = Spawn("ExplodiumMag",origin);
|
|
c.angle = angle;
|
|
c.pitch = pitch;
|
|
c.vel = x*FRandom[Junk](-.5,.5)+y*side*FRandom[Junk](-1.2,.3)-(0,0,FRandom[Junk](2,3));
|
|
c.vel += vel*.5;
|
|
}
|
|
|
|
action void A_DropCasing( int side = 1 )
|
|
{
|
|
let [x, y, z] = SWWMUtility.GetPlayerAxes(self);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,8*side,-10);
|
|
let c = Spawn("ExplodiumCasing",origin);
|
|
c.angle = angle;
|
|
c.pitch = pitch;
|
|
c.vel = x*FRandom[Junk](-.5,.5)+y*side*FRandom[Junk](2,4)-(0,0,FRandom[Junk](2,3));
|
|
c.vel += vel*.5;
|
|
}
|
|
|
|
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
|
|
{
|
|
return (SisterWeapon&&(SisterWeapon.Amount > 1));
|
|
}
|
|
override bool Use( bool pickup )
|
|
{
|
|
// need to override here because other mods could screw it up
|
|
if ( !SisterWeapon || (SisterWeapon.Amount < 2) )
|
|
return false;
|
|
return Super.Use(pickup);
|
|
}
|
|
|
|
override bool ReportHUDAmmo()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
override Inventory CreateTossable( int amt )
|
|
{
|
|
// disallow dropping if weapon isn't ready for switching
|
|
if ( (Owner.player.ReadyWeapon == self) && (!(Owner.player.WeaponState&WF_WEAPONSWITCHOK) || (Owner.player.WeaponState&WF_DISABLESWITCH)) )
|
|
return null;
|
|
// call toss on sister
|
|
return SisterWeapon.CreateTossable(amt);
|
|
}
|
|
|
|
override void SetTags( String colname )
|
|
{
|
|
Super.SetTags(colname);
|
|
// also set tag for the second gun
|
|
A_ChangeModel("",3,"","",0,"models","DemoTags"..colname..".png",CMDL_USESURFACESKIN,-1);
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_EXPLODIUM2";
|
|
Obituary "$O_EXPLODIUM";
|
|
SWWMWeapon.Tooltip "$TT_EXPLODIUM2";
|
|
SWWMWeapon.GetLine "getexplodiumgun2";
|
|
SWWMWeapon.NumCrosshairs 2;
|
|
Weapon.UpSound "explodium/select";
|
|
Weapon.SisterWeapon "ExplodiumGun";
|
|
Weapon.SlotNumber 2;
|
|
Weapon.SelectionOrder 950;
|
|
Weapon.SlotPriority 2.;
|
|
DualExplodiumGun.ClipCount 7;
|
|
+WEAPON.EXPLOSIVE;
|
|
+SWWMWEAPON.HIDEINMENU;
|
|
+SWWMWEAPON.NOSWAPWEAPON;
|
|
}
|
|
States
|
|
{
|
|
Select:
|
|
XZW2 B 2
|
|
{
|
|
ExplodiumGun(invoker.SisterWeapon).deadeyecnt = 0;
|
|
A_FullRaise();
|
|
ExplodiumGun(invoker.SisterWeapon).firstselect = false;
|
|
}
|
|
XZW2 C 2 A_BumpView(-.1,tics:2);
|
|
XZW2 D 2
|
|
{
|
|
A_BumpView(-.1,tics:2);
|
|
player.SetPSprite(PSP_WEAPON+1,ResolveState("LeftSelect"));
|
|
}
|
|
XZW2 E 2 A_BumpView(-.1,tics:2);
|
|
XZW2 FGH 2 A_BumpView(.05,tics:2);
|
|
XZW2 AA 2;
|
|
Goto Ready;
|
|
LeftSelect:
|
|
XZWB B 2;
|
|
XZWB CDE 2 A_BumpView(-.1,tics:2);
|
|
XZWB FGH 2 A_BumpView(.05,tics:2);
|
|
Goto LeftReady;
|
|
Ready:
|
|
XZW2 A 1
|
|
{
|
|
ExplodiumGun(invoker.SisterWeapon).firstselect = false;
|
|
let sis = player.FindPSprite(PSP_WEAPON+1);
|
|
if ( !sis )
|
|
{
|
|
player.SetPSprite(PSP_WEAPON+1,ResolveState("LeftReady"));
|
|
sis = player.FindPSprite(PSP_WEAPON+1);
|
|
}
|
|
if ( sis.CurState.InStateSequence(ResolveState("LeftReady")) )
|
|
{
|
|
if ( (ExplodiumGun(invoker.SisterWeapon).clipcount > 0) && !ExplodiumGun(invoker.SisterWeapon).chambered )
|
|
player.SetPSprite(PSP_WEAPON,ResolveState("Slide"));
|
|
else if ( (invoker.clipcount > 0) && !invoker.chambered )
|
|
player.SetPSprite(PSP_WEAPON+1,ResolveState("LeftSlide"));
|
|
else if ( (player.cmd.buttons&BT_RELOAD) && (ExplodiumGun(invoker.SisterWeapon).clipcount < ExplodiumGun(invoker.SisterWeapon).default.clipcount) )
|
|
player.SetPSprite(PSP_WEAPON,ResolveState("Reload"));
|
|
else A_WeaponReady(WRF_ALLOWZOOM|WRF_ALLOWUSER1);
|
|
}
|
|
else
|
|
{
|
|
// left weapon isn't ready, but we can still reload right weapon if needed
|
|
if ( (player.cmd.buttons&BT_RELOAD) && (ExplodiumGun(invoker.SisterWeapon).clipcount < ExplodiumGun(invoker.SisterWeapon).default.clipcount) )
|
|
player.SetPSprite(PSP_WEAPON,ResolveState("Reload"));
|
|
else
|
|
{
|
|
int flg = WRF_NOSWITCH|WRF_NOSECONDARY;
|
|
if ( !ExplodiumGun(invoker.SisterWeapon).chambered )
|
|
flg |= WRF_NOPRIMARY;
|
|
// don't bob while the left weapon is firing
|
|
if ( sis.CurState.InStateSequence(ResolveState("LeftFire")) || sis.CurState.InStateSequence(ResolveState("LeftFireLast")) )
|
|
flg |= WRF_NOBOB;
|
|
A_WeaponReady(flg);
|
|
}
|
|
}
|
|
}
|
|
Wait;
|
|
LeftReady:
|
|
XZWB A 1
|
|
{
|
|
let sis = player.FindPSprite(PSP_WEAPON);
|
|
if ( (invoker.clipcount <= 0) && !invoker.chambered )
|
|
player.SetPSprite(PSP_WEAPON+1,ResolveState("LeftReloadLast"));
|
|
else if ( (player.cmd.buttons&BT_RELOAD) && (invoker.clipcount < invoker.default.clipcount) )
|
|
player.SetPSprite(PSP_WEAPON+1,ResolveState("LeftReload"));
|
|
else if ( player.cmd.buttons&BT_ALTATTACK && invoker.chambered )
|
|
player.SetPSprite(PSP_WEAPON+1,ResolveState("LeftFire"));
|
|
// allow bobbing while the right weapon reloads
|
|
if ( !sis.CurState.InStateSequence(ResolveState("Fire")) && !sis.CurState.InStateSequence(ResolveState("FireLast")) )
|
|
A_CanBob();
|
|
}
|
|
Wait;
|
|
Fire:
|
|
XZW2 A 1
|
|
{
|
|
A_Schutt();
|
|
return A_JumpIf((ExplodiumGun(invoker.SisterWeapon).clipcount<=0)&&!ExplodiumGun(invoker.SisterWeapon).chambered,"FireLast");
|
|
}
|
|
XZW2 I 1;
|
|
XZW2 J 1
|
|
{
|
|
int layer = PSP_WEAPON+2;
|
|
while ( player.FindPSprite(layer) ) layer++;
|
|
A_Overlay(layer,"Casing");
|
|
}
|
|
XZW2 KLMNOP 1;
|
|
XZW2 Q 2;
|
|
Goto Ready;
|
|
FireLast:
|
|
XZW2 A 1;
|
|
XZWI K 1;
|
|
XZWI L 1
|
|
{
|
|
int layer = PSP_WEAPON+1;
|
|
while ( player.FindPSprite(layer) ) layer++;
|
|
A_Overlay(layer,"Casing");
|
|
}
|
|
XZWI M 1;
|
|
XZWI N 1 A_StartSound("explodium/slidelock",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWI OPQR 1;
|
|
XZWI S 2;
|
|
Goto ReloadLast;
|
|
ReloadLast:
|
|
XZWI V 1
|
|
{
|
|
A_PlayerReload();
|
|
A_StartSound("explodium/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZWI WXY 2 A_BumpView(.2,tics:2);
|
|
XZWI Z 2 A_BumpView(.1,tics:2);
|
|
XZWJ AB 2 A_BumpView(.1,tics:2);
|
|
XZWJ CD 1;
|
|
XZWJ E 1 { ExplodiumGun(invoker.SisterWeapon).clipcount = 0; }
|
|
XZWJ F 1;
|
|
XZWJ G 1 A_StartSound("explodium/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWJ H 1 A_BumpView(.2);
|
|
XZWJ IJ 1;
|
|
XZWJ K 0 A_DropMag();
|
|
XZWJ LMN 3;
|
|
XZWJ O 2 A_StartSound("explodium/magin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWJ PQR 2;
|
|
XZWJ S 1
|
|
{
|
|
A_BumpView(-.2);
|
|
A_StartSound("explodium/jamitin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
ExplodiumGun(invoker.SisterWeapon).clipcount = ExplodiumGun(invoker.SisterWeapon).default.clipcount;
|
|
}
|
|
XZWJ TUVW 1;
|
|
XZWJ X 2 A_StartSound("explodium/select",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWJ Y 2
|
|
{
|
|
A_StartSound("explodium/slideforward",CHAN_WEAPON,CHANF_OVERLAP);
|
|
ExplodiumGun(invoker.SisterWeapon).clipcount--;
|
|
ExplodiumGun(invoker.SisterWeapon).chambered = true;
|
|
}
|
|
XZWJ Z 2;
|
|
XZWK ABCD 2;
|
|
Goto Ready;
|
|
LeftFire:
|
|
XZWB A 1
|
|
{
|
|
A_Schutt(-1);
|
|
return A_JumpIf((invoker.clipcount<=0)&&!invoker.chambered,"LeftFireLast");
|
|
}
|
|
XZWB I 1;
|
|
XZWB J 1
|
|
{
|
|
int layer = PSP_WEAPON+12;
|
|
while ( player.FindPSprite(layer) ) layer++;
|
|
A_Overlay(layer,"LeftCasing");
|
|
}
|
|
XZWB KLMNOP 1;
|
|
XZWB Q 2;
|
|
Goto LeftReady;
|
|
LeftFireLast:
|
|
XZWB A 1;
|
|
XZWK Q 1;
|
|
XZWK R 1
|
|
{
|
|
int layer = PSP_WEAPON+1;
|
|
while ( player.FindPSprite(layer) ) layer++;
|
|
A_Overlay(layer,"Casing");
|
|
}
|
|
XZWK S 1;
|
|
XZWK T 1 A_StartSound("explodium/slidelock",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWK UVWX 1;
|
|
XZWK Y 2;
|
|
Goto LeftReloadLast;
|
|
LeftReloadLast:
|
|
XZWK Z 4
|
|
{
|
|
let sis = player.FindPSprite(PSP_WEAPON);
|
|
if ( !sis.CurState.InStateSequence(ResolveState("Reload")) && !sis.CurState.InStateSequence(ResolveState("ReloadEmpty")) && !sis.CurState.InStateSequence(ResolveState("ReloadLast")) )
|
|
return ResolveState("LeftReloadLast")+1;
|
|
return ResolveState(null);
|
|
}
|
|
XZWK Z 1
|
|
{
|
|
A_PlayerReload();
|
|
A_StartSound("explodium/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZWL ABC 2 A_BumpView(.2,tics:2);
|
|
XZWL DEF 2 A_BumpView(.1,tics:2);
|
|
XZWL GH 1;
|
|
XZWL I 1 { invoker.clipcount = 0; }
|
|
XZWL J 1;
|
|
XZWL K 1 A_StartSound("explodium/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWL L 1 A_BumpView(.2);
|
|
XZWL MN 1;
|
|
XZWL O 0 A_DropMag();
|
|
XZWL PQR 3;
|
|
XZWL S 2 A_StartSound("explodium/magin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWL TUV 2;
|
|
XZWL W 1
|
|
{
|
|
A_BumpView(-.2);
|
|
A_StartSound("explodium/jamitin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.clipcount = invoker.default.clipcount;
|
|
}
|
|
XZWL XYZ 1;
|
|
XZWM A 1;
|
|
XZWM B 2 A_StartSound("explodium/select",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWM C 2
|
|
{
|
|
A_StartSound("explodium/slideforward",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.clipcount--;
|
|
invoker.chambered = true;
|
|
}
|
|
XZWM DEFGH 2;
|
|
Goto LeftReady;
|
|
Casing:
|
|
XZWA A 1
|
|
{
|
|
A_OverlayOffset(OverlayID(),0,0);
|
|
invoker.casex = FRandom[Explodium](-1.,5.);
|
|
invoker.casey = FRandom[Explodium](-2.,1.);
|
|
}
|
|
XZWA BCDEFGHIJ 1 A_OverlayOffset(OverlayID(),invoker.casex,invoker.casey,WOF_ADD|WOF_INTERPOLATE);
|
|
TNT1 A 1 A_DropCasing();
|
|
Stop;
|
|
LeftCasing:
|
|
XZWI A 1
|
|
{
|
|
A_OverlayOffset(OverlayID(),0,0);
|
|
invoker.lcasex = FRandom[Explodium](-5.,1.);
|
|
invoker.lcasey = FRandom[Explodium](-1.,2.);
|
|
}
|
|
XZWI BCDEFGHIJ 1 A_OverlayOffset(OverlayID(),invoker.lcasex,invoker.lcasey,WOF_ADD|WOF_INTERPOLATE);
|
|
TNT1 A 1 A_DropCasing(-1);
|
|
Stop;
|
|
Lower:
|
|
XZW2 A 2;
|
|
XZW7 TUV 2 A_BumpView(.1,tics:2);
|
|
XZW2 B -1;
|
|
Stop;
|
|
LeftLower:
|
|
XZWB A 2;
|
|
XZWG TUV 2 A_BumpView(.1,tics:2);
|
|
XZWB B -1;
|
|
Stop;
|
|
Raise:
|
|
XZW2 B 2;
|
|
XZW7 VUT 2 A_BumpView(-.1,tics:2);
|
|
XZW2 A 1;
|
|
Goto Ready;
|
|
LeftRaise:
|
|
XZWB B 2;
|
|
XZWG VUT 2 A_BumpView(-.1,tics:2);
|
|
XZWB A 1;
|
|
Goto LeftReady;
|
|
Reload:
|
|
XZW2 A 1
|
|
{
|
|
A_PlayerReload();
|
|
A_StartSound("explodium/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
if ( ExplodiumGun(invoker.SisterWeapon).clipcount <= 0 ) return ResolveState("ReloadEmpty");
|
|
return ResolveState(null);
|
|
}
|
|
XZW2 TUV 2 A_BumpView(.2,tics:2);
|
|
XZW2 WXY 2 A_BumpView(.1,tics:2);
|
|
XZW2 Z 1;
|
|
XZW3 A 1;
|
|
XZW3 B 1 { ExplodiumGun(invoker.SisterWeapon).clipcount = 0; }
|
|
XZW3 C 1;
|
|
XZW3 D 1 A_StartSound("explodium/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW3 E 1 A_BumpView(.2);
|
|
XZW3 FG 1;
|
|
XZW3 H 0 A_DropMag();
|
|
Goto ReloadEnd;
|
|
ReloadEmpty:
|
|
XZW2 A 1;
|
|
XZW3 IJK 2 A_BumpView(.2,tics:2);
|
|
XZW3 LMN 2 A_BumpView(.1,tics:2);
|
|
XZW3 OPQR 1;
|
|
XZW3 S 1 A_StartSound("explodium/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW3 T 1 A_BumpView(.2);
|
|
XZW3 UV 1;
|
|
XZW3 W 0 A_DropMag();
|
|
Goto ReloadEnd;
|
|
ReloadEnd:
|
|
XZW3 XYZ 3;
|
|
XZW4 A 2 A_StartSound("explodium/magin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW4 BCD 2;
|
|
XZW4 E 1
|
|
{
|
|
A_BumpView(-.2);
|
|
A_StartSound("explodium/jamitin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
ExplodiumGun(invoker.SisterWeapon).clipcount = ExplodiumGun(invoker.SisterWeapon).default.clipcount;
|
|
}
|
|
XZW4 FGHI 1;
|
|
XZW4 J 2 A_StartSound("explodium/select",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW4 KLM 2 A_BumpView(-.2,tics:2);
|
|
XZW4 NOP 2 A_BumpView(.1,tics:2);
|
|
Goto Ready;
|
|
Slide:
|
|
XZW2 A 9 { player.SetPSPrite(PSP_WEAPON+1,ResolveState("LeftLower")); }
|
|
XZW2 A 1;
|
|
XZW4 WXY 1 A_BumpView(-.1);
|
|
XZW5 A 1 A_StartSound("explodium/slideback",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 BC 1;
|
|
XZW5 D 1
|
|
{
|
|
ExplodiumGun(invoker.SisterWeapon).chambered = true;
|
|
ExplodiumGun(invoker.SisterWeapon).clipcount--;
|
|
}
|
|
XZW5 EFG 1 A_BumpView(.1);
|
|
XZW5 H 1 A_StartSound("explodium/slideforward",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 IJKLM 1;
|
|
XZW2 A 0 { player.SetPSPrite(PSP_WEAPON+1,ResolveState("LeftRaise")); }
|
|
Goto Ready;
|
|
LeftReload:
|
|
XZWB A 4
|
|
{
|
|
let sis = player.FindPSprite(PSP_WEAPON);
|
|
if ( !sis.CurState.InStateSequence(ResolveState("Reload")) && !sis.CurState.InStateSequence(ResolveState("ReloadEmpty")) && !sis.CurState.InStateSequence(ResolveState("ReloadLast")) )
|
|
return ResolveState("LeftReload")+1;
|
|
return ResolveState(null);
|
|
}
|
|
XZWB A 1
|
|
{
|
|
A_PlayerReload();
|
|
A_StartSound("explodium/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
if ( invoker.clipcount <= 0 ) return ResolveState("LeftReloadEmpty");
|
|
return ResolveState(null);
|
|
}
|
|
XZWB TUV 2 A_BumpView(.2,tics:2);
|
|
XZWB WXY 2 A_BumpView(.1,tics:2);
|
|
XZWB Z 1;
|
|
XZWC A 1;
|
|
XZWC B 1 { invoker.clipcount = 0; }
|
|
XZWC C 1;
|
|
XZWC D 1 A_StartSound("explodium/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWC E 1 A_BumpView(.2);
|
|
XZWC FG 1;
|
|
XZWC H 0 A_DropMag();
|
|
Goto LeftReloadEnd;
|
|
LeftReloadEmpty:
|
|
XZWB A 1;
|
|
XZWC IJK 2 A_BumpView(.2,tics:2);
|
|
XZWC LMN 2 A_BumpView(.1,tics:2);
|
|
XZWC OPQR 1;
|
|
XZWC S 1 A_StartSound("explodium/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWC T 1 A_BumpView(.2);
|
|
XZWC UV 1;
|
|
XZWC W 0 A_DropMag();
|
|
Goto LeftReloadEnd;
|
|
LeftReloadEnd:
|
|
XZWC XYZ 3;
|
|
XZWD A 2 A_StartSound("explodium/magin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWD BCD 2;
|
|
XZWD E 1
|
|
{
|
|
A_BumpView(-.2);
|
|
A_StartSound("explodium/jamitin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.clipcount = invoker.default.clipcount;
|
|
}
|
|
XZWD FGHI 1;
|
|
XZWD J 2 A_StartSound("explodium/select",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWD KLM 2 A_BumpView(-.2,tics:2);
|
|
XZWD NOP 2 A_BumpView(.1,tics:2);
|
|
Goto LeftReady;
|
|
LeftSlide:
|
|
XZWB A 9 { player.SetPSPrite(PSP_WEAPON,ResolveState("Lower")); }
|
|
XZWB A 1;
|
|
XZWD WXY 1 A_BumpView(-.1);
|
|
XZWE A 1 A_StartSound("explodium/slideback",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWE BC 1;
|
|
XZWE D 1
|
|
{
|
|
invoker.chambered = true;
|
|
invoker.clipcount--;
|
|
}
|
|
XZWE EFG 1 A_BumpView(.1);
|
|
XZWE H 1 A_StartSound("explodium/slideforward",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWE IJKLM 1;
|
|
XZWB A 0 { player.SetPSPrite(PSP_WEAPON,ResolveState("Raise")); }
|
|
Goto LeftReady;
|
|
Zoom:
|
|
XZW2 A 1
|
|
{
|
|
A_PlayerCheckGun();
|
|
A_StartSound("explodium/speen",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZW9 ABCD 1 A_BumpView(.2);
|
|
XZW9 EFG 1 A_BumpView(-.2);
|
|
XZW9 H 1
|
|
{
|
|
A_BumpView(-.2);
|
|
player.SetPSPrite(PSP_WEAPON+1,ResolveState("LeftZoom"));
|
|
}
|
|
XZW9 IJ 1 A_BumpView(-.2);
|
|
XZW9 KLMNOP 1 A_BumpView(-.1);
|
|
XZW9 QRST 1 A_BumpView(.3);
|
|
XZW9 UVW 1;
|
|
Goto Ready;
|
|
LeftZoom:
|
|
XZWB A 1;
|
|
XZWH ABCD 1 A_BumpView(.2);
|
|
XZWH EFGHIJ 1 A_BumpView(-.2);
|
|
XZWH KLMNOP 1 A_BumpView(-.1);
|
|
XZWH QRST 1 A_BumpView(.3);
|
|
XZWH UVW 1;
|
|
Goto LeftReady;
|
|
User1:
|
|
XZW2 A 1 { player.SetPSPrite(PSP_WEAPON+1,ResolveState("LeftUser1")); }
|
|
XZW7 TU 1 A_BumpView(.1);
|
|
User1Hold:
|
|
XZW7 V 1
|
|
{
|
|
A_BumpAngle(1.);
|
|
A_PlayerMelee(true);
|
|
A_StartSound("demolitionist/swing",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_Parry(9);
|
|
}
|
|
XZW7 WX 1 A_BumpAngle(-.5);
|
|
XZW7 Y 1 A_Melee();
|
|
XZW7 Z 2;
|
|
XZW8 ABCDE 2;
|
|
XZW8 F 1 A_JumpIf(player.cmd.buttons&BT_USER1,"User1Hold");
|
|
XZW2 B 0 { invoker.PlayUpSound(self); player.SetPSPrite(PSP_WEAPON+1,ResolveState("LeftSelect")); }
|
|
Goto Select;
|
|
LeftUser1:
|
|
XZWB A 1;
|
|
XZWG TUV 1;
|
|
XZWB B -1;
|
|
Stop;
|
|
Deselect:
|
|
XZW2 A 2 A_StartSound("explodium/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWA T 2 A_BumpView(.1,tics:2);
|
|
XZWA U 2
|
|
{
|
|
A_BumpView(.1,tics:2);
|
|
player.SetPSPrite(PSP_WEAPON+1,ResolveState("LeftDeselect"));
|
|
}
|
|
XZWA VW 2 A_BumpView(.1,tics:2);
|
|
XZW2 B -1 A_FullLower();
|
|
Stop;
|
|
LeftDeselect:
|
|
XZWB A 2;
|
|
XZWA PQRS 2 A_BumpView(.1,tics:2);
|
|
XZWB B 0;
|
|
Stop;
|
|
Flash:
|
|
XZWZ A 2 Bright
|
|
{
|
|
let psp = player.GetPSprite(PSP_FLASH);
|
|
psp.frame = Random[GunFlash](0,9);
|
|
let l = Spawn("SWWMWeaponLight",pos);
|
|
l.target = self;
|
|
}
|
|
Stop;
|
|
LeftFlash:
|
|
XZWZ K 2 Bright
|
|
{
|
|
let psp = player.GetPSprite(PSP_FLASH+1);
|
|
psp.frame = Random[GunFlash](10,19);
|
|
let l = Spawn("SWWMWeaponLight",pos);
|
|
l.target = self;
|
|
}
|
|
Stop;
|
|
}
|
|
}
|