Sheen HMG fully functional. May need touchups later.
This commit is contained in:
parent
4ec3a595c4
commit
57253d5434
36 changed files with 528 additions and 94 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue