678 lines
19 KiB
Text
678 lines
19 KiB
Text
// Blackmann "Rhino Stopper" Spreadgun (from Instant Action 3, also planned for Zanaveth Ultra Suite 2)
|
|
// Slot 3, replaces Shotgun, Ethereal Crossbow, Serpent Staff
|
|
|
|
Class SpreadgunTracer : LineTracer
|
|
{
|
|
Array<HitListEntry> hitlist;
|
|
Array<Line> shootthroughlist;
|
|
Array<WaterHit> waterhitlist;
|
|
|
|
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.bSHOOTABLE )
|
|
{
|
|
int amt = SWWMDamageAccumulator.GetAmount(Results.HitActor);
|
|
// getgibhealth isn't clearscope and that's a problem
|
|
int gibh = (Results.HitActor.GibHealth!=int.min)?-abs(Results.HitActor.GibHealth):-int(Results.HitActor.GetSpawnHealth()*gameinfo.gibfactor);
|
|
// if gibbed, go through without dealing more damage
|
|
if ( Results.HitActor.health-amt <= gibh ) return TRACE_Skip;
|
|
let ent = new("HitListEntry");
|
|
ent.hitactor = Results.HitActor;
|
|
ent.hitlocation = Results.HitPos;
|
|
ent.x = Results.HitVector;
|
|
hitlist.Push(ent);
|
|
// go right on through if dead
|
|
if ( Results.HitActor.health-amt <= 0 ) return TRACE_Skip;
|
|
// stap
|
|
return TRACE_Stop;
|
|
}
|
|
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 Spreadgun : SWWMWeapon
|
|
{
|
|
bool fired; // shell was used
|
|
bool wasfired; // for hammer priming
|
|
bool chambered; // a shell is actually loaded
|
|
bool goldload; // a golden shell is loaded (buckshot otherwise)
|
|
bool wasgold; // for what ammo/shell to drop
|
|
bool loadgold; // hint for switching to gold shells on next load
|
|
|
|
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
|
|
{
|
|
if ( goldload ) return StringTable.Localize("$O_SPREADGUN_GOLD");
|
|
return Super.GetObituary(victim,inflictor,mod,playerattack);
|
|
}
|
|
|
|
override void DoEffect()
|
|
{
|
|
Super.DoEffect();
|
|
// push back selection order if weapon is unloaded (or has a golden shell loaded)
|
|
if ( !bInitialized ) SelectionOrder = default.SelectionOrder;
|
|
else SelectionOrder = (chambered&&!fired&&!goldload)?default.SelectionOrder:1500;
|
|
}
|
|
|
|
override bool ReportHUDAmmo()
|
|
{
|
|
if ( !fired && chambered ) return true;
|
|
return Super.ReportHUDAmmo();
|
|
}
|
|
|
|
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
|
|
{
|
|
if ( (firemode == PrimaryFire) || (firemode == EitherFire) )
|
|
{
|
|
if ( !fired && chambered ) return true;
|
|
if ( (Ammo1.Amount > 0) || (Ammo2.Amount > 0) ) return true;
|
|
if ( autoswitch ) PlayerPawn(Owner).PickNewWeapon(null);
|
|
return false;
|
|
}
|
|
return Super.CheckAmmo(firemode,autoswitch,requireammo,ammocount);
|
|
}
|
|
|
|
action void A_SelectUnloadState()
|
|
{
|
|
if ( invoker.fired ) player.SetPSprite(PSP_WEAPON,invoker.FindState("UnloadFired"));
|
|
else player.SetPSprite(PSP_WEAPON,invoker.FindState("Unload"));
|
|
if ( invoker.chambered )
|
|
{
|
|
A_ChangeModel("",1,"","",4,"models",String.Format("Shell_%s%s.png",invoker.wasgold?"Gold":"Normal",invoker.fired?"_Used":""),CMDL_USESURFACESKIN,-1);
|
|
A_Overlay(-9999,"UnloadDummy");
|
|
}
|
|
else
|
|
{
|
|
A_ChangeModel("",1,"","",4,"models","",CMDL_USESURFACESKIN,-1);
|
|
A_Overlay(-9999,"UnloadDummyEmpty");
|
|
}
|
|
A_StartSound("spreadgun/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
|
|
action void A_SelectLoadState()
|
|
{
|
|
invoker.wasfired = false;
|
|
A_ChangeModel("",1,"","",4,"models","",CMDL_USESURFACESKIN,-1);
|
|
A_ChangeModel("",1,"","",5,"models",String.Format("Shell_%s.png",invoker.loadgold?"Gold":"Normal"),CMDL_USESURFACESKIN,-1);
|
|
if ( invoker.fired )
|
|
{
|
|
invoker.wasfired = true;
|
|
player.SetPSprite(PSP_WEAPON,invoker.FindState("LoadFired"));
|
|
}
|
|
else player.SetPSprite(PSP_WEAPON,invoker.FindState("Load"));
|
|
A_Overlay(-9999,"LoadDummy");
|
|
}
|
|
|
|
action void A_DropShell()
|
|
{
|
|
if ( !invoker.fired )
|
|
{
|
|
let amo = invoker.wasgold?invoker.Ammo2:invoker.Ammo1;
|
|
let amotype = invoker.wasgold?invoker.AmmoType2:invoker.AmmoType1;
|
|
if ( (amo.Amount >= amo.MaxAmount) && !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
|
|
invoker.BufferAmmo(amotype,1);
|
|
else amo.Amount = min(amo.Amount+1,amo.MaxAmount);
|
|
return;
|
|
}
|
|
let [x, y, z] = SWWMUtility.GetPlayerAxes(self);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,0,-10);
|
|
let c = Spawn(invoker.wasgold?"GoldShellCasing":"RedShellCasing",origin);
|
|
c.angle = angle;
|
|
c.pitch = pitch;
|
|
c.vel = x*FRandom[Junk](-.2,.2)+y*FRandom[Junk](-.2,.2)-(0,0,FRandom[Junk](2,3));
|
|
c.vel += vel*.5;
|
|
}
|
|
|
|
action void ProcessTraceHit( SpreadgunTracer t, Vector3 origin, Vector3 dir, int dmg, double mm, Class<Actor> impact = "SpreadImpact", int bc = 1 )
|
|
{
|
|
if ( swwm_omnibust )
|
|
{
|
|
// Wall busting
|
|
int bustdmg = dmg;
|
|
BusterWall.Bust(t.Results,bustdmg,self,t.Results.HitVector,t.Results.HitPos.z);
|
|
}
|
|
foreach ( l:t.ShootThroughList )
|
|
{
|
|
l.Activate(self,0,SPAC_PCross);
|
|
l.Activate(self,0,SPAC_Impact);
|
|
}
|
|
foreach ( w:t.WaterHitList )
|
|
{
|
|
let b = Spawn("SmolInvisibleSplasher",w.hitpos);
|
|
b.target = self;
|
|
b.A_CheckTerrain();
|
|
}
|
|
for ( int i=5; i<t.Results.Distance; i+=10 )
|
|
{
|
|
if ( !Random[Boolet](0,bc) ) continue;
|
|
let b = Actor.Spawn("SWWMBubble",level.Vec3Offset(origin,dir*i));
|
|
b.Scale *= FRandom[Boolet](.1,.3);
|
|
}
|
|
foreach( hit:t.HitList )
|
|
{
|
|
int realdmg = dmg?dmg:hit.HitDamage;
|
|
let p = SWWMPuff.Setup(hit.HitLocation,hit.x,invoker,self,hit.HitActor);
|
|
SWWMDamageAccumulator.Accumulate(hit.HitActor,realdmg,p,self,'shot',false,DMG_INFLICTOR_IS_PUFF);
|
|
SWWMUtility.DoKnockback(hit.HitActor,hit.x+(0,0,0.025),mm*FRandom[Spreadgun](0.4,1.2));
|
|
if ( hit.HitActor.bNOBLOOD || hit.HitActor.bDORMANT || hit.HitActor.bINVULNERABLE )
|
|
{
|
|
let p = Spawn(impact,hit.HitLocation);
|
|
p.angle = atan2(hit.x.y,hit.x.x)+180;
|
|
p.pitch = asin(hit.x.z);
|
|
p.target = self;
|
|
}
|
|
else
|
|
{
|
|
hit.HitActor.TraceBleed(realdmg,self);
|
|
hit.HitActor.SpawnBlood(hit.HitLocation,atan2(hit.x.y,hit.x.x)+180,realdmg);
|
|
hit.HitActor.A_StartSound("spreadgun/pelletf",CHAN_DAMAGE,CHANF_OVERLAP,.4,4.);
|
|
}
|
|
}
|
|
if ( (t.Results.HitType != TRACE_HitNone) && (t.Results.HitType != TRACE_HitActor) )
|
|
{
|
|
Vector3 hitnormal = SWWMUtility.GetLineTracerHitNormal(t.Results);
|
|
let p = Spawn(impact,t.Results.HitPos+hitnormal*4);
|
|
p.angle = atan2(hitnormal.y,hitnormal.x);
|
|
p.pitch = asin(-hitnormal.z);
|
|
p.target = self;
|
|
if ( t.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40);
|
|
if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos);
|
|
}
|
|
}
|
|
|
|
override Vector3 GetTraceOffset( int index )
|
|
{
|
|
return (10.,2.,-2.);
|
|
}
|
|
|
|
action void A_FireShell()
|
|
{
|
|
if ( invoker.goldload )
|
|
{
|
|
A_SWWMFlash("FlashGold");
|
|
A_StartSound("spreadgun/goldfire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6);
|
|
A_AlertMonsters(swwm_uncapalert?0:2500);
|
|
A_QuakeEx(6.,6.,6.,12,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:1.2);
|
|
A_BumpFOV(.76);
|
|
A_BumpView(-4);
|
|
SWWMHandler.DoFlash(self,Color(96,255,224,16),5);
|
|
}
|
|
else
|
|
{
|
|
A_SWWMFlash("FlashRed");
|
|
A_StartSound("spreadgun/redfire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6);
|
|
A_AlertMonsters(swwm_uncapalert?0:800);
|
|
A_QuakeEx(2.5,2.5,2.5,8,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.6);
|
|
A_BumpFOV(.93);
|
|
A_BumpView(-1);
|
|
SWWMHandler.DoFlash(self,Color(40,255,192,64),5);
|
|
}
|
|
A_PlayerFire();
|
|
let [x, y, z] = SWWMUtility.GetPlayerAxes(self);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,2,-2);
|
|
let [x2, y2, z2] = SWWMUtility.GetPlayerAxesAutoAimed(self);
|
|
double a, s;
|
|
Vector3 dir;
|
|
if ( invoker.goldload )
|
|
{
|
|
a = FRandom[Spreadgun](0,360);
|
|
s = FRandom[Spreadgun](0,.01);
|
|
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,true);
|
|
if ( d.HitType != TRACE_HitNone )
|
|
{
|
|
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
|
|
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal);
|
|
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("GoldenImpact",d.HitLocation+hitnormal*4.);
|
|
b.angle = atan2(hitnormal.y,hitnormal.x);
|
|
b.pitch = asin(-hitnormal.z);
|
|
b.target = self;
|
|
}
|
|
for ( int i=0; i<6; i++ )
|
|
{
|
|
let s = Spawn("SWWMSmoke",origin);
|
|
s.scale *= .8;
|
|
s.alpha *= .3;
|
|
s.SetShade(Color(1,1,1)*Random[Spreadgun](96,192));
|
|
s.vel += vel*.5+x*FRandom[Spreadgun](3.,5.);
|
|
}
|
|
for ( int i=0; i<10; i++ )
|
|
{
|
|
let s = Spawn("SWWMSpark",origin);
|
|
s.scale *= .2;
|
|
s.alpha *= .4;
|
|
s.vel += vel*.5+x*FRandom[Spreadgun](4.,8.)+y*FRandom[Spreadgun](-1,1)+z*FRandom[Spreadgun](-1,1);
|
|
}
|
|
for ( int i=0; i<50; i++ )
|
|
{
|
|
let s = Spawn("FancyConfetti",origin);
|
|
s.bAMBUSH = true;
|
|
s.vel += vel*.5+x*FRandom[Spreadgun](1.,20.)+y*FRandom[Spreadgun](-2,2)+z*FRandom[Spreadgun](-2,2);
|
|
}
|
|
SWWMUtility.DoKnockback(self,-x,30000.);
|
|
SWWMUtility.AchievementProgressInc("golden",1,player);
|
|
}
|
|
else
|
|
{
|
|
SpreadgunTracer st = new("SpreadgunTracer");
|
|
for ( int j=0; j<20; j++ )
|
|
{
|
|
a = FRandom[Spreadgun](0,360);
|
|
s = FRandom[Spreadgun](0,.12);
|
|
dir = SWWMUtility.ConeSpread(x2,y2,z2,a,s);
|
|
st.hitlist.Clear();
|
|
st.shootthroughlist.Clear();
|
|
st.waterhitlist.Clear();
|
|
st.Trace(origin,level.PointInSector(origin.xy),dir,8000.,0,ignore:self);
|
|
ProcessTraceHit(st,origin,dir,10,7000,bc:5);
|
|
}
|
|
for ( int i=0; i<16; i++ )
|
|
{
|
|
let s = Spawn("SWWMSmoke",origin);
|
|
s.special1 = 1;
|
|
s.scale *= .9;
|
|
s.alpha *= .3;
|
|
s.SetShade(Color(1,1,1)*Random[Spreadgun](96,192));
|
|
s.vel += vel*.5+x*FRandom[Spreadgun](3.,5.)+y*FRandom[Spreadgun](-1,1)+z*FRandom[Spreadgun](-1,1);
|
|
}
|
|
for ( int i=0; i<20; i++ )
|
|
{
|
|
let s = Spawn("SWWMSpark",origin);
|
|
s.scale *= .3;
|
|
s.alpha *= .4;
|
|
s.vel += vel*.5+x*FRandom[Spreadgun](4.,8.)+y*FRandom[Spreadgun](-2,2)+z*FRandom[Spreadgun](-2,2);
|
|
}
|
|
SWWMUtility.DoKnockback(self,-x,20000.);
|
|
}
|
|
A_StartSound("spreadgun/hammer",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.fired = true;
|
|
}
|
|
|
|
action void A_LoadShell()
|
|
{
|
|
A_ChangeModel("",1,"","",5,"models","",CMDL_USESURFACESKIN,-1);
|
|
A_ChangeModel("",1,"","",4,"models",String.Format("Shell_%s.png",invoker.loadgold?"Gold":"Normal"),CMDL_USESURFACESKIN,-1);
|
|
A_StartSound("spreadgun/shellin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.goldload = invoker.loadgold;
|
|
invoker.loadgold = false;
|
|
let amot = invoker.goldload?invoker.AmmoType2:invoker.AmmoType1;
|
|
if ( !invoker.FetchBufferedAmmo(amot,1) && !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
|
|
{
|
|
let amo = invoker.goldload?invoker.Ammo2:invoker.Ammo1;
|
|
if ( amo.Amount > 0 ) amo.Amount--;
|
|
}
|
|
invoker.chambered = true;
|
|
invoker.fired = false;
|
|
invoker.ClearBufferedAmmo();
|
|
}
|
|
|
|
action void A_Prime()
|
|
{
|
|
if ( invoker.fired || invoker.wasfired )
|
|
A_StartSound("spreadgun/hammer",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_ChangeModel("",1,"","",5,"models","",CMDL_USESURFACESKIN,-1);
|
|
}
|
|
|
|
action State A_SpreadgunReady()
|
|
{
|
|
int flg = WRF_ALLOWZOOM|WRF_ALLOWUSER1|WRF_NOSECONDARY;
|
|
if ( ((invoker.Ammo1.Amount > 0) || sv_infiniteammo || FindInventory('PowerInfiniteAmmo',true)) && (invoker.fired || !invoker.chambered || invoker.goldload) )
|
|
flg |= WRF_ALLOWRELOAD;
|
|
if ( ((invoker.Ammo2.Amount > 0) || sv_infiniteammo || FindInventory('PowerInfiniteAmmo',true)) && (invoker.fired || !invoker.chambered || !invoker.goldload) )
|
|
flg &= ~WRF_NOSECONDARY;
|
|
if ( ((invoker.Ammo1.Amount <= 0) && !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true)) && (invoker.fired || !invoker.chambered) )
|
|
flg |= WRF_NOPRIMARY;
|
|
A_WeaponReady(flg);
|
|
if ( player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK) )
|
|
invoker.CheckAmmo(EitherFire,true);
|
|
return ResolveState(null);
|
|
}
|
|
|
|
override bool PickupForAmmoSWWM( SWWMWeapon ownedWeapon )
|
|
{
|
|
bool good = Super.PickupForAmmoSWWM(ownedWeapon);
|
|
let Owner = ownedWeapon.Owner;
|
|
if ( (AmmoGive1 == 0) && !fired && chambered )
|
|
{
|
|
let loadammo = goldload?AmmoType2:AmmoType1;
|
|
let cur = Owner.FindInventory(loadammo);
|
|
if ( !cur )
|
|
{
|
|
cur = Inventory(Spawn(loadammo));
|
|
cur.Amount = 0;
|
|
cur.AttachToOwner(Owner);
|
|
}
|
|
// give the loaded shell (or drop)
|
|
if ( cur.Amount >= cur.MaxAmount ) cur.CreateTossable(1);
|
|
cur.Amount++;
|
|
good = true;
|
|
}
|
|
return good;
|
|
}
|
|
|
|
override void InitializeWeapon()
|
|
{
|
|
fired = false;
|
|
chambered = true;
|
|
goldload = false;
|
|
}
|
|
|
|
override void ModifyDropAmount( int dropamount )
|
|
{
|
|
Super.ModifyDropAmount(dropamount);
|
|
// toss some ammo while we're at it
|
|
if ( Random[Spreadgun](0,1) )
|
|
A_DropItem("RedShell",Random[Spreadgun](1,2));
|
|
}
|
|
|
|
action void A_UpdatePickup()
|
|
{
|
|
frame = invoker.fired;
|
|
}
|
|
|
|
override void MarkPrecacheSounds()
|
|
{
|
|
Super.MarkPrecacheSounds();
|
|
MarkSound("spreadgun/open");
|
|
MarkSound("spreadgun/hammer");
|
|
MarkSound("spreadgun/close");
|
|
MarkSound("spreadgun/shellin");
|
|
MarkSound("spreadgun/select");
|
|
MarkSound("spreadgun/deselect");
|
|
MarkSound("spreadgun/redfire1");
|
|
MarkSound("spreadgun/redfire2");
|
|
MarkSound("spreadgun/goldfire1");
|
|
MarkSound("spreadgun/goldfire2");
|
|
MarkSound("spreadgun/checkgun");
|
|
MarkSound("spreadgun/casing1");
|
|
MarkSound("spreadgun/casing2");
|
|
MarkSound("spreadgun/casing3");
|
|
MarkSound("spreadgun/casing4");
|
|
MarkSound("spreadgun/casing5");
|
|
MarkSound("spreadgun/casing6");
|
|
MarkSound("spreadgun/gcasing1");
|
|
MarkSound("spreadgun/gcasing2");
|
|
MarkSound("spreadgun/gcasing3");
|
|
MarkSound("spreadgun/pellet1");
|
|
MarkSound("spreadgun/pellet2");
|
|
MarkSound("spreadgun/pellet3");
|
|
MarkSound("spreadgun/pellet4");
|
|
MarkSound("spreadgun/pellet5");
|
|
MarkSound("spreadgun/pellet6");
|
|
MarkSound("spreadgun/pellet7");
|
|
MarkSound("spreadgun/pellet8");
|
|
MarkSound("spreadgun/pelletf1");
|
|
MarkSound("spreadgun/pelletf2");
|
|
MarkSound("spreadgun/pelletf3");
|
|
MarkSound("spreadgun/pelletf4");
|
|
MarkSound("spreadgun/pelletf5");
|
|
MarkSound("spreadgun/pelletf6");
|
|
MarkSound("spreadgun/goldexpl1");
|
|
MarkSound("spreadgun/goldexpl2");
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_SPREADGUN";
|
|
Inventory.PickupMessage "$I_SPREADGUN";
|
|
Obituary "$O_SPREADGUN";
|
|
SWWMWeapon.Tooltip "$TT_SPREADGUN";
|
|
SWWMWeapon.GetLine "getspreadgun";
|
|
Weapon.UpSound "spreadgun/select";
|
|
Weapon.SlotNumber 3;
|
|
Weapon.SelectionOrder 500;
|
|
Weapon.AmmoType1 "RedShell";
|
|
Weapon.AmmoGive1 1;
|
|
Weapon.AmmoType2 "GoldShell";
|
|
Weapon.AmmoGive2 0;
|
|
SWWMWeapon.DropAmmoType "SWWMShellAmmoSmall";
|
|
Stamina 15000;
|
|
+SWWMWEAPON.NOFIRSTGIVE;
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1 NoDelay A_UpdatePickup();
|
|
Stop;
|
|
Deselect:
|
|
XZW2 A 1
|
|
{
|
|
A_StartSound("spreadgun/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_BumpView(-.1);
|
|
return A_JumpIf(invoker.fired,"DeselectFired");
|
|
}
|
|
XZW2 BCD 1 A_BumpView(.1);
|
|
XZW2 EF 1 A_BumpView(.2);
|
|
XZW2 GH 1 A_BumpView(.3);
|
|
XZW2 I -1 A_FullLower();
|
|
Stop;
|
|
DeselectFired:
|
|
XZW2 Z 1 A_BumpView(-.1);
|
|
XZW3 ABC 1 A_BumpView(.1);
|
|
XZW3 DE 1 A_BumpView(.2);
|
|
XZW3 FG 1 A_BumpView(.3);
|
|
XZW3 H -1 A_FullLower();
|
|
Stop;
|
|
Select:
|
|
XZW2 I 1
|
|
{
|
|
A_FullRaise();
|
|
A_BumpView(.2);
|
|
return A_JumpIf(invoker.fired,"SelectFired");
|
|
}
|
|
XZW2 JKL 1 A_BumpView(-.1);
|
|
XZW2 MNO 1 A_BumpView(-.2);
|
|
XZW2 PQ 1 A_BumpView(.1);
|
|
Goto Ready;
|
|
SelectFired:
|
|
XZW3 H 1 A_BumpView(.2);
|
|
XZW3 IJK 1 A_BumpView(-.1);
|
|
XZW3 LMN 1 A_BumpView(-.2);
|
|
XZW3 OP 1 A_BumpView(.1);
|
|
Goto ReadyFired;
|
|
Ready:
|
|
XZW2 A 1 A_SpreadgunReady();
|
|
Wait;
|
|
ReadyFired:
|
|
XZW2 Z 1 A_SpreadgunReady();
|
|
Wait;
|
|
Fire:
|
|
XZW2 A 1
|
|
{
|
|
if ( invoker.fired || !invoker.chambered ) return ResolveState("Reload");
|
|
A_FireShell();
|
|
return ResolveState(null);
|
|
}
|
|
XZW2 RSTU 1;
|
|
XZW2 VWXY 2;
|
|
Goto ReadyFired;
|
|
AltFire:
|
|
#### # -1
|
|
{
|
|
A_PlayerReload();
|
|
invoker.wasgold = invoker.goldload;
|
|
invoker.loadgold = true;
|
|
A_SelectUnloadState();
|
|
}
|
|
Stop;
|
|
Reload:
|
|
#### # -1
|
|
{
|
|
A_PlayerReload();
|
|
invoker.wasgold = invoker.goldload;
|
|
invoker.loadgold = false;
|
|
A_SelectUnloadState();
|
|
}
|
|
Stop;
|
|
UnloadDummy: // overlay with shared functions for all unload anims
|
|
TNT1 A 11;
|
|
TNT1 A 14
|
|
{
|
|
invoker.chambered = false;
|
|
A_StartSound("spreadgun/open",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
TNT1 A 1 A_DropShell();
|
|
Stop;
|
|
UnloadDummyEmpty:
|
|
TNT1 A 11;
|
|
TNT1 A 14 A_StartSound("spreadgun/open",CHAN_WEAPON,CHANF_OVERLAP);
|
|
Stop;
|
|
UnloadFired:
|
|
XZW2 Z 2;
|
|
XZW3 QRST 2;
|
|
XZW3 UVWXYZ 1;
|
|
XZW4 ABCDEFGH 1;
|
|
XZW4 I 1;
|
|
Goto Reload2;
|
|
Unload:
|
|
XZW2 A 2;
|
|
XZW9 PQRS 2;
|
|
XZW9 TUVWXYZ 1;
|
|
XZWA ABCDEFG 1;
|
|
XZWA H 1;
|
|
Goto Reload2;
|
|
Reload2:
|
|
#### # -1 A_SelectLoadState();
|
|
Stop;
|
|
LoadDummy:
|
|
TNT1 A 9;
|
|
TNT1 A 12 A_LoadShell();
|
|
TNT1 A 2 A_StartSound("spreadgun/close",CHAN_WEAPON,CHANF_OVERLAP);
|
|
TNT1 A 2 A_Prime();
|
|
TNT1 A 1 { invoker.PlayUpSound(self); }
|
|
Stop;
|
|
LoadDummyEmpty:
|
|
TNT1 A 9;
|
|
TNT1 A 2 A_StartSound("spreadgun/close",CHAN_WEAPON,CHANF_OVERLAP);
|
|
TNT1 A 2 A_Prime();
|
|
TNT1 A 1 { invoker.PlayUpSound(self); }
|
|
Stop;
|
|
LoadFired:
|
|
XZW4 IJKLMNOPQRSTUVWXYZ 1;
|
|
XZW5 ABCDEFGHIJKLMNO 1;
|
|
Goto Ready;
|
|
Load:
|
|
XZWA HIJKLMNOPQRSTUVWXYZ 1;
|
|
XZWB ABCDEFGHIJKLMN 1;
|
|
Goto Ready;
|
|
Zoom:
|
|
XZW2 A 1
|
|
{
|
|
A_StartSound("spreadgun/checkgun",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_PlayerCheckGun();
|
|
return A_JumpIf(invoker.fired,"ZoomFired");
|
|
}
|
|
XZW5 PQR 1 A_BumpView(.1);
|
|
XZW5 STUVWXYZ 1 A_BumpView(-.2);
|
|
XZW6 ABCDEF 2 A_BumpView(-.15,tics:2);
|
|
XZW6 GHI 2 A_BumpView(-.1,tics:2);
|
|
XZW6 JKL 1 A_BumpView(.2);
|
|
XZW6 MNO 1 A_BumpView(.1);
|
|
Goto Ready;
|
|
ZoomFired:
|
|
XZW2 Z 1;
|
|
XZW8 CDEFGHIJKLM 1;
|
|
XZW8 NOPQRSTUV 2;
|
|
XZW8 WXYZ 1;
|
|
XZW9 AB 1;
|
|
Goto ReadyFired;
|
|
DummyMelee:
|
|
TNT1 A 3
|
|
{
|
|
A_Parry(9);
|
|
A_PlayerMelee(true);
|
|
}
|
|
TNT1 A 1 A_Melee();
|
|
Stop;
|
|
User1:
|
|
XZW2 A 2
|
|
{
|
|
A_StartSound("spreadgun/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
return A_JumpIf(invoker.fired,"User1Fired");
|
|
}
|
|
XZW7 PQ 2 A_BumpView(.05,tics:2);
|
|
User1Hold:
|
|
XZW7 R 1
|
|
{
|
|
A_BumpAngle(1.);
|
|
A_StartSound("demolitionist/swing",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_Overlay(-9999,"DummyMelee");
|
|
}
|
|
XZW7 ST 2 A_BumpAngle(-.25,tics:2);
|
|
XZW7 UV 2;
|
|
XZW7 WX 3;
|
|
XZW7 Y 0 A_JumpIf(player.cmd.buttons&BT_USER1,"User1Hold");
|
|
XZW7 Y 0 { invoker.PlayUpSound(self); }
|
|
XZW7 Y 2 A_BumpView(.2,tics:2);
|
|
XZW7 Z 2 A_BumpView(.1,tics:2);
|
|
XZW8 AB 2 A_BumpView(-.1,tics:2);
|
|
Goto Ready;
|
|
User1Fired:
|
|
XZW2 Z 2;
|
|
XZW9 CD 2 A_BumpView(.05,tics:2);
|
|
User1FiredHold:
|
|
XZW9 E 1
|
|
{
|
|
A_BumpAngle(1.);
|
|
A_StartSound("demolitionist/swing",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_Overlay(-9999,"DummyMelee");
|
|
}
|
|
XZW9 FG 2 A_BumpAngle(-.25,tics:2);
|
|
XZW9 HI 2;
|
|
XZW9 JK 3;
|
|
XZW9 L 0 A_JumpIf(player.cmd.buttons&BT_USER1,"User1FiredHold");
|
|
XZW9 L 0 { invoker.PlayUpSound(self); }
|
|
XZW9 L 2 A_BumpView(.2,tics:2);
|
|
XZW9 M 2 A_BumpView(.1,tics:2);
|
|
XZW9 NO 2 A_BumpView(-.1,tics:2);
|
|
Goto ReadyFired;
|
|
FlashRed:
|
|
XZW0 A 2 Bright
|
|
{
|
|
let l = Spawn("SWWMWeaponLight",pos);
|
|
l.args[3] = 120;
|
|
l.target = self;
|
|
}
|
|
Stop;
|
|
FlashGold:
|
|
XZW0 B 2 Bright
|
|
{
|
|
let l = Spawn("SWWMWeaponLight",pos);
|
|
l.args[3] = 300;
|
|
l.target = self;
|
|
}
|
|
Stop;
|
|
}
|
|
}
|