Sheen HMG fully functional. May need touchups later.

This commit is contained in:
Mari the Deer 2022-07-22 20:19:57 +02:00
commit 57253d5434
36 changed files with 528 additions and 94 deletions

View file

@ -67,8 +67,8 @@ Class SheenAmmo : SWWMAmmo
+FLOATBOB;
FloatBobStrength 0.25;
Accuracy 35;
Radius 4;
Height 24;
Radius 2;
Height 22;
}
States
{
@ -82,7 +82,7 @@ Class SheenAmmo2 : SheenAmmo
Default
{
Inventory.Amount 2;
Radius 6;
Radius 4;
}
}
Class SheenAmmo3 : SheenAmmo
@ -90,7 +90,7 @@ Class SheenAmmo3 : SheenAmmo
Default
{
Inventory.Amount 3;
Radius 6;
Radius 4;
}
}
Class SheenSmallAmmo : SheenAmmo
@ -98,7 +98,7 @@ Class SheenSmallAmmo : SheenAmmo
Default
{
Inventory.Amount 10;
Radius 6;
Radius 4;
}
}
Class SheenBigAmmo : SheenAmmo
@ -106,7 +106,7 @@ Class SheenBigAmmo : SheenAmmo
Default
{
Inventory.Amount 50;
Radius 16;
Radius 12;
}
}

View file

@ -3,7 +3,7 @@
// Sheen HMG
extend Class HeavyMahSheenGun
{
ui TextureID WeaponBox, BulletTex[2], SpeedTex, BarTex[4];
ui TextureID WeaponBox, BulletTex[2], SpeedTex, BarTex;
override void DrawWeapon( double TicFrac, double bx, double by, double hs, Vector2 ss )
{
@ -11,16 +11,16 @@ extend Class HeavyMahSheenGun
if ( !BulletTex[0] ) BulletTex[0] = TexMan.CheckForTexture("graphics/HUD/SheenRound.png",TexMan.Type_Any);
if ( !BulletTex[1] ) BulletTex[1] = TexMan.CheckForTexture("graphics/HUD/SheenCasing.png",TexMan.Type_Any);
if ( !SpeedTex ) SpeedTex = TexMan.CheckForTexture("graphics/HUD/SheenSpeed.png",TexMan.Type_Any);
if ( !BarTex[0] ) BarTex[0] = TexMan.CheckForTexture("graphics/HUD/SheenBar0.png",TexMan.Type_Any);
if ( !BarTex[1] ) BarTex[1] = TexMan.CheckForTexture("graphics/HUD/SheenBar1.png",TexMan.Type_Any);
if ( !BarTex[2] ) BarTex[2] = TexMan.CheckForTexture("graphics/HUD/SheenBar2.png",TexMan.Type_Any);
if ( !BarTex[3] ) BarTex[3] = TexMan.CheckForTexture("graphics/HUD/SheenBar3.png",TexMan.Type_Any);
if ( !BarTex ) BarTex = TexMan.CheckForTexture("graphics/HUD/SheenBar.png",TexMan.Type_Any);
Screen.DrawTexture(WeaponBox,false,bx-23,by-24,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
if ( firespeed == 0 ) for ( int i=0; i<2; i++ ) Screen.DrawTexture(SpeedTex,false,bx-21,(by-14)+i*8,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
else if ( firespeed == 1 ) for ( int i=0; i<3; i++ ) Screen.DrawTexture(SpeedTex,false,bx-21,(by-14)+i*4,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
else if ( firespeed == 2 ) for ( int i=0; i<5; i++ ) Screen.DrawTexture(SpeedTex,false,bx-21,(by-14)+i*2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
// TODO heat bar
Screen.DrawText(NewConsoleFont,Font.CR_RED,64,64,String.Format("heat: %g\nshake: %g\nspread: %g\ntimer: %d",barrelheat,vibrate,aimerror,firetimer?((gametic-firetimer)/GameTicRate):0));
double ht = clamp(HeatInter?HeatInter.GetValue(TicFrac):barrelheat,0.,100.);
double hw = ht*.18;
bool blinking = (incooldown)&&(gametic%8>=4);
Screen.DrawTexture(BarTex,false,bx-20,by-21,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_SrcWidth,hw,DTA_DestWidthF,hw,DTA_ColorOverlay,Color(255,0,0,0));
Screen.DrawTexture(BarTex,false,bx-21,by-22,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_SrcWidth,hw,DTA_DestWidthF,hw,DTA_ColorOverlay,blinking?Color(128,0,0,0):Color(0,0,0,0));
bool isfired = !!fired;
double firefact = 0.;
if ( firespeed == 0 )

View file

@ -7,37 +7,192 @@ Class HeavyMahSheenGun : SWWMWeapon
int firespeed;
double barrelheat, aimerror, vibrate;
bool incooldown, stopfire, firstshot;
int firetimer;
int firetimer, shotcnt;
transient ui SmoothDynamicValueInterpolator HeatInter;
transient SpreadSlugTracer st;
override void HudTick()
{
Super.HudTick();
if ( !HeatInter ) HeatInter = SmoothDynamicValueInterpolator.Create(barrelheat,.5,1.,25.);
HeatInter.Update(barrelheat);
}
action void A_DropCasing()
{
Vector3 x, y, z;
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),4*x+8*y-12*z);
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;
}
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, y, z;
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x-4*z);
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. ) invoker.stopfire = invoker.incooldown = true;
if ( invoker.barrelheat > 100. )
{
A_StartSound("sheen/overheat",CHAN_WEAPONEXTRA2,CHANF_LOOPING,attenuation:3.);
invoker.stopfire = invoker.incooldown = true;
}
invoker.firstshot = true;
if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
invoker.Ammo1.Amount--;
invoker.fired = gametic;
// TODO the actual firing itself
// dakka dakka dakka
Vector3 x2, y2, z2;
[x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll);
double a = FRandom[Sheen](0,360), s = FRandom[Sheen](.002,.02)*spreadfct;
Vector3 dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
if ( !invoker.st ) invoker.st = new("SpreadSlugTracer");
let st = invoker.st; // thanks zscript
st.ignoreme = self;
st.penetration = 80.;
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);
}
for ( int i=0; i<st.ShootThroughList.Size(); i++ )
{
st.ShootThroughList[i].Activate(self,0,SPAC_PCross);
st.ShootThroughList[i].Activate(self,0,SPAC_Impact);
}
for ( int i=0; i<st.WaterHitList.Size(); i++ )
{
let b = Spawn("InvisibleSplasher",st.WaterHitList[i].hitpos);
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);
}
for ( int i=0; i<st.HitList.Size(); i++ )
{
int realdmg = st.HitList[i].HitDamage;
let p = SWWMPuff.Setup(st.HitList[i].HitLocation,st.HitList[i].x,invoker,self,st.HitList[i].HitActor);
SWWMDamageAccumulator.Accumulate(st.HitList[i].HitActor,realdmg,p,self,'shot',flags:DMG_INFLICTOR_IS_PUFF);
SWWMUtility.DoKnockback(st.HitList[i].HitActor,st.HitList[i].x+(0,0,0.025),15000.*FRandom[Sheen](0.4,1.2));
if ( st.HitList[i].HitActor.bNOBLOOD || st.HitList[i].HitActor.bDORMANT || st.HitList[i].HitActor.bINVULNERABLE )
{
let p = Spawn("SWWMBulletImpact",st.HitList[i].HitLocation);
p.angle = atan2(st.HitList[i].x.y,st.HitList[i].x.x)+180;
p.pitch = asin(st.HitList[i].x.z);
}
else
{
st.HitList[i].HitActor.TraceBleed(realdmg,self);
st.HitList[i].HitActor.SpawnBlood(st.HitList[i].HitLocation,atan2(st.HitList[i].x.y,st.HitList[i].x.x)+180,realdmg);
st.HitList[i].HitActor.A_StartSound("spreadgun/slugf",CHAN_DAMAGE,CHANF_OVERLAP,1.,2.);
}
}
if ( (st.Results.HitType != TRACE_HitNone) && (st.Results.HitType != TRACE_HasHitSky) && (st.Results.HitType != TRACE_HitActor) )
{
Vector3 hitnormal = -st.Results.HitVector;
if ( st.Results.HitType == TRACE_HitFloor )
{
if ( st.Results.FFloor ) hitnormal = -st.Results.FFloor.top.Normal;
else hitnormal = st.Results.HitSector.floorplane.Normal;
}
else if ( st.Results.HitType == TRACE_HitCeiling )
{
if ( st.Results.FFloor ) hitnormal = -st.Results.FFloor.bottom.Normal;
else hitnormal = st.Results.HitSector.ceilingplane.Normal;
}
else if ( st.Results.HitType == TRACE_HitWall )
{
hitnormal = (-st.Results.HitLine.delta.y,st.Results.HitLine.delta.x,0).unit();
if ( !st.Results.Side ) hitnormal *= -1;
}
let p = Spawn("SWWMBulletImpact",st.Results.HitPos+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
if ( st.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40);
if ( st.Results.HitLine ) 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.);
}
if ( st.Results.Distance > 200. )
{
int trail = CVar.GetCVar('swwm_funtrails',player).GetInt();
if ( trail == 8 ) trail = Random[Sheen](1,7);
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.frame = trail;
}
invoker.shotcnt++;
}
action void A_CheckContinueFire()
{
@ -46,11 +201,6 @@ Class HeavyMahSheenGun : SWWMWeapon
}
override void OwnerDied()
{
if ( Owner.IsActorPlayingSound(CHAN_WEAPONEXTRA) )
{
A_StopSound(CHAN_WEAPONEXTRA);
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
}
Super.OwnerDied();
aimerror = 0.;
vibrate = 0.;
@ -64,21 +214,32 @@ Class HeavyMahSheenGun : SWWMWeapon
override void DoEffect()
{
Super.DoEffect();
barrelheat = max(0.,barrelheat*.99-.15);
if ( barrelheat <= 0. ) incooldown = false;
if ( incooldown ) barrelheat = max(0.,barrelheat*.995-.1);
else barrelheat = max(0.,barrelheat*.99-.15);
bool hascooled = false;
if ( barrelheat <= 0. )
{
hascooled = incooldown;
incooldown = false;
}
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 *= .95;
aimerror *= .9;
}
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
{
@ -128,7 +289,11 @@ Class HeavyMahSheenGun : SWWMWeapon
XZW1 A -1;
Stop;
Select:
XZW2 K 3 A_FullRaise();
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;
@ -136,6 +301,7 @@ Class HeavyMahSheenGun : SWWMWeapon
Ready:
XZW2 A 1
{
invoker.shotcnt = 0;
invoker.firetimer = gametic;
invoker.aimerror = 0.;
invoker.vibrate = 0.;
@ -149,7 +315,7 @@ Class HeavyMahSheenGun : SWWMWeapon
}
Wait;
Fire:
XZW2 A 1;
XZW2 A 2;
XZW2 Z 1
{
invoker.firstshot = false;
@ -320,29 +486,29 @@ Class HeavyMahSheenGun : SWWMWeapon
XZW4 L 0;
Goto VeryFastFireHold;
EndFireFast7:
XZW4 MNO 1 { invoker.vibrate *= .25; }
XZW4 MNO 2 { invoker.vibrate *= .25; }
Goto Ready;
EndFireFast6:
XZW4 PQR 1 { invoker.vibrate *= .25; }
XZW4 PQR 2 { invoker.vibrate *= .25; }
Goto Ready;
EndFireFast5:
XZW4 STU 1 { invoker.vibrate *= .25; }
XZW4 STU 2 { invoker.vibrate *= .25; }
Goto Ready;
EndFireFast4:
XZW4 VWX 1 { invoker.vibrate *= .25; }
XZW4 VWX 2 { invoker.vibrate *= .25; }
Goto Ready;
EndFireFast3:
XZW4 YZ 1 { invoker.vibrate *= .25; }
XZW5 A 1 { invoker.vibrate *= .25; }
XZW4 YZ 2 { invoker.vibrate *= .25; }
XZW5 A 2 { invoker.vibrate *= .25; }
Goto Ready;
EndFireFast2:
XZW5 BCD 1 { invoker.vibrate *= .25; }
XZW5 BCD 2 { invoker.vibrate *= .25; }
Goto Ready;
EndFireFast1:
XZW5 EFG 1 { invoker.vibrate *= .25; }
XZW5 EFG 2 { invoker.vibrate *= .25; }
Goto Ready;
StopFire:
XZW2 Z 1 A_StopSound(CHAN_WEAPONEXTRA); // just in case
XZW2 Z 2 A_StopSound(CHAN_WEAPONEXTRA); // just in case
Goto Ready;
EjectRound7:
TNT1 A 7;
@ -351,10 +517,10 @@ Class HeavyMahSheenGun : SWWMWeapon
TNT1 A 3;
Goto EjectRound;
EjectRound1:
TNT1 A 7;
TNT1 A 1;
Goto EjectRound;
EjectRound:
TNT1 A 1; // TODO
TNT1 A 1 A_DropCasing();
Stop;
AltFire:
XZW2 A 3 A_StartSound("sheen/crankin",CHAN_WEAPON,CHANF_OVERLAP);
@ -403,7 +569,21 @@ Class HeavyMahSheenGun : SWWMWeapon
Deselect:
XZW2 A 2 A_StartSound("sheen/deselect",CHAN_WEAPON,CHANF_OVERLAP);
XZW2 BCDEFGHIJK 2;
XZW2 K -1 A_FullLower();
XZW2 K -1
{
A_StopSound(CHAN_WEAPONEXTRA2);
A_FullLower();
}
Stop;
Flash:
XZW0 A 2
{
let psp = player.GetPSprite(PSP_FLASH);
psp.frame = Random[GunFlash](0,7);
let l = Spawn("SWWMWeaponLight",pos);
l.target = self;
l.Args[3] -= psp.frame*5;
}
Stop;
}
}

View file

@ -1 +1,108 @@
// Sheen HMG projectiles and effects
Class SheenCasing : SWWMCasing
{
Default
{
BounceSound "sheen/casing";
}
}
Class SheenPhantom : Actor
{
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
+DONTSPLASH;
+NOTELEPORT;
+NOINTERACTION;
+INTERPOLATEANGLES;
Radius .1;
Height 0.;
Alpha .5;
RenderStyle "Add";
}
override void Tick()
{
if ( isFrozen() ) return;
A_FadeOut(frame?.02:.05);
}
States
{
Spawn:
XZW1 A -1 Bright;
Stop;
}
}
Class SheenTrail : Actor
{
Default
{
Obituary "$O_SHEENHMG";
+NOBLOCKMAP;
+NOGRAVITY;
+DONTSPLASH;
+NOTELEPORT;
+NOINTERACTION;
+INTERPOLATEANGLES;
+FORCERADIUSDMG;
+NODAMAGETHRUST;
Speed 200;
Radius .1;
Height 0.;
RenderStyle "Add";
}
override void Tick()
{
Vector3 oldpos = pos;
if ( isFrozen() ) return;
if ( CurState == SpawnState )
{
Vector3 dir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
Vector3 newpos = level.Vec3Offset(pos,dir*min(speed,specialf1));
special1++;
for ( int i=0; i<4; i++ )
{
let p = Spawn("SheenPhantom",level.Vec3Offset(pos,dir*(i+1)*50.));
p.angle = angle;
p.pitch = pitch;
p.frame = frame;
p.alpha *= clamp((special1+i*.25)/2.,.25,1.);
}
// burn the air throughout
Vector3 tdir = level.Vec3Diff(pos,newpos);
double dist = tdir.length();
tdir /= dist;
for ( int i=0; i<dist; i+=25 )
{
SetOrigin(level.Vec3Offset(pos,tdir*i),true);
SWWMUtility.DoExplosion(self,min(5*special1,30),2000,50,damagetype:'Fire',ignoreme:target);
}
prev = oldpos; // interpolation
SetOrigin(newpos,true);
specialf1 -= speed;
if ( specialf1 <= 0 ) SetStateLabel("Death");
return;
}
if ( !CheckNoDelay() || (tics == -1) ) return;
if ( tics > 0 ) tics--;
while ( !tics )
{
if ( !SetState(CurState.NextState) )
return;
}
}
States
{
Spawn:
XZW1 A -1 Bright;
Stop;
Death:
TNT1 A 5;
Stop;
}
}

View file

@ -350,37 +350,6 @@ extend Class SWWMHandler
if ( SWWMCredits.Take(players[e.Args[0]],e.Args[1]) )
{
let def = GetDefaultByType(item);
SWWMWeapon sw;
// drop the swapweapon if we own it first
if ( swwm_swapweapons && (item is 'SWWMWeapon') && (sw = SWWMWeapon(def).HasSwapWeapon(players[e.Args[0]].mo)) )
{
// special case, otherwise candy gun won't drop itself
if ( sw is 'CandyGun' ) CandyGun(sw).swapdrop = true;
bool swapto = (sw == players[e.Args[0]].ReadyWeapon) || (sw.SisterWeapon && (sw.Sisterweapon == players[e.Args[0]].ReadyWeapon));
int ngun = sw.Amount;
if ( ngun == 2 )
{
// create a dual giver to drop
let dg = SWWMDualWeaponGiver(Actor.Spawn("SWWMDualWeaponGiver",players[e.Args[0]].mo.pos+(0,0,10)));
dg.angle = players[e.Args[0]].mo.angle;
dg.VelFromAngle(5.);
dg.vel.z += 1.;
dg.vel += players[e.Args[0]].mo.vel;
// transfer both guns
dg.giveme[0] = SWWMWeapon(sw.CreateTossable(1));
dg.giveme[0].AttachToOwner(dg);
dg.giveme[1] = SWWMWeapon(sw.CreateTossable(1));
dg.giveme[1].AttachToOwner(dg);
dg.SetPickupState();
}
else players[e.Args[0]].mo.DropInventory(sw); // just drop it
// don't autoswitch just yet (hacky)
if ( swapto )
{
players[e.Args[0]].ReadyWeapon = null;
players[e.Args[0]].PendingWeapon = WP_NOCHANGE;
}
}
if ( (item is 'ArmorNuggetItem') || (item is 'HealthNuggetItem') )
{
// these have to be given in a loop because fun reasons

View file

@ -598,6 +598,19 @@ Class DemolitionistMenuStoreItem : DemolitionistMenuListItem
master.tmsgtic = Menu.MenuTime()+70;
return;
}
if ( (inv is 'SWWMWeapon') && swwm_swapweapons )
{
// check swapweapon
let wpn = GetDefaultByType((Class<SWWMWeapon>)(inv));
let sw = wpn.HasSwapWeapon(players[consoleplayer].mo);
if ( sw )
{
master.MenuSound("menu/noinvuse");
master.tmsg = String.Format(StringTable.Localize("$SWWM_STORESWAP"),sw.GetTag());
master.tmsgtic = Menu.MenuTime()+70;
return;
}
}
let cur = players[consoleplayer].mo.FindInventory(inv);
int camt, max;
if ( cur )

View file

@ -2813,8 +2813,11 @@ Class Demolitionist : PlayerPawn
// weapon get oneliner
if ( (item is 'Weapon') && !(item is 'SWWMGesture') && !(item is 'SWWMItemGesture') && mystats && !mystats.GotWeapon(Weapon(item).GetClass()) && (player == players[consoleplayer]) && !ingivecheat )
{
if ( (item is 'HeavyMahSheenGun') && Random[DemoLines](0,2) && SWWMHandler.AddOneliner("sheenspecial",2,20) )
if ( (item is 'HeavyMahSheenGun') && !Random[DemoLines](0,2) && SWWMHandler.AddOneliner("sheenspecial",2,20) )
{
A_StartSound("sheen/specialpick",CHAN_ITEM,CHANF_OVERLAP,1.,.5);
A_StartSound("sheen/specialpick",CHAN_ITEM,CHANF_OVERLAP,1.,.5);
}
else if ( (item is 'SWWMWeapon') && (SWWMWeapon(item).GetLine != "") )
{
// fall back to generic weapon get if voicepack lacks weapon-specific lines

View file

@ -170,6 +170,7 @@ Class SWWMStats : SWWMStaticThinker
else if ( ((inflictor is 'SaltImpact') && !inflictor.Args[0]) || ((inflictor is 'SaltBeam') && !inflictor.Args[1]) || (inflictor is 'CorrodeDebuff') || (inflictor is 'CorrosiveFlechette') || ((inflictor is 'TheBall') && !inflictor.special1) || (inflictor is 'GoldenImpact') || (inflictor is 'GoldenSubImpact') || (inflictor is 'GoldenSubSubImpact') ) which = 'Spreadgun';
else if ( ((inflictor is 'SaltImpact') && inflictor.Args[0]) || ((inflictor is 'SaltBeam') && inflictor.Args[1]) || ((inflictor is 'TheBall') && inflictor.special1) ) which = 'Wallbuster';
else if ( (inflictor is 'EvisceratorChunk') || (inflictor is 'EvisceratorProj') ) which = 'Eviscerator';
else if ( inflictor is 'SheenTrail' ) which = 'HeavyMahSheenGun';
else if ( (inflictor is 'HellblazerMissile') || (inflictor is 'HellblazerRavagerArm') || (inflictor is 'HellblazerWarheadArm') ) which = 'Hellblazer';
else if ( (inflictor is 'BigBiospark') || (inflictor is 'BiosparkBall') || (inflictor is 'BiosparkBeamImpact') || (inflictor is 'BiosparkComboImpact') || (inflictor is 'BiosparkComboImpactSub') || (inflictor is 'BiosparkBeam') || (inflictor is 'BiosparkArc') || (inflictor is 'BiosparkCore') ) which = 'Sparkster';
else if ( (inflictor is 'SilverAirRip') || (inflictor is 'SilverAirRip2') || (inflictor is 'SilverImpact') || (inflictor is 'FatChodeImpact') || (inflictor is 'FatChodeExplosionArm') ) which = 'SilverBullet';

View file

@ -100,7 +100,7 @@ Class SWWMWeapon : Weapon abstract
// if the toucher owns our SwapWeapon, drop it before picking us up
bool swapto = false;
SWWMWeapon sw;
if ( swwm_swapweapons && (sw = HasSwapWeapon(user)) )
if ( swwm_swapweapons && (sw = HasSwapWeapon(user)) && (user.player.WeaponState&WF_WEAPONSWITCHOK) && !(user.player.WeaponState&WF_DISABLESWITCH) )
{
// special case, otherwise candy gun won't drop itself
if ( sw is 'CandyGun' ) CandyGun(sw).swapdrop = true;