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).
376 lines
11 KiB
Text
376 lines
11 KiB
Text
// Itamex Reinforced Combat Hammer (from UnSX 5)
|
|
// Slot 1, spawns shared with Deep Impact
|
|
|
|
Class ItamexHammer : SWWMWeapon
|
|
{
|
|
double charge;
|
|
int hitcnt, spintime;
|
|
transient ui SmoothDynamicValueInterpolator ChargeInter;
|
|
|
|
override void HudTick()
|
|
{
|
|
Super.HudTick();
|
|
if ( !ChargeInter ) ChargeInter = SmoothDynamicValueInterpolator.Create(charge,.5);
|
|
ChargeInter.Update(charge);
|
|
}
|
|
|
|
action State A_HammerHit( bool nojump = false )
|
|
{
|
|
Vector3 x = SWWMUtility.Vec3FromAngles(angle,pitch);
|
|
SWWMUtility.DoKnockback(self,x,120000.);
|
|
if ( A_Melee(100,"itamex/hit",1.6,1.1,1.,MELEE_Rip|MELEE_FleshSound|MELEE_HammerHit) )
|
|
{
|
|
A_BumpFOV(.9);
|
|
A_QuakeEx(5.,5.,5.,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.35);
|
|
A_AlertMonsters(swwm_uncapalert?0:800);
|
|
return nojump?ResolveState(null):ResolveState("FireHit");
|
|
}
|
|
A_BumpFOV(.95);
|
|
A_QuakeEx(.5,.5,.5,15,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.1);
|
|
return ResolveState(null);
|
|
}
|
|
action void A_HammerAltHit()
|
|
{
|
|
Vector3 x = SWWMUtility.Vec3FromAngles(angle,pitch);
|
|
SWWMUtility.DoKnockback(self,x,3000.*invoker.charge);
|
|
if ( A_Melee(int(100+invoker.charge*2.),"itamex/hit",2.,1.1,1.2,MELEE_Rip|MELEE_FleshSound|MELEE_HammerHit|MELEE_Vertical|MELEE_ExtraWide|MELEE_ForceBust) )
|
|
{
|
|
A_BumpFOV(.9);
|
|
A_QuakeEx(5.,5.,5.,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.35);
|
|
A_AlertMonsters(swwm_uncapalert?0:800);
|
|
return;
|
|
}
|
|
A_BumpFOV(.95);
|
|
A_QuakeEx(.5,.5,.5,15,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.1);
|
|
}
|
|
|
|
override void DoEffect()
|
|
{
|
|
Super.DoEffect();
|
|
if ( !Owner && !Owner.player && (Owner.player.ReadyWeapon != self) ) return;
|
|
let psp = Owner.player.FindPSprite(PSP_WEAPON);
|
|
if ( !psp ) return;
|
|
if ( Owner.IsActorPlayingSound(CHAN_WEAPONEXTRA,"itamex/spin") )
|
|
psp.x += charge*.05;
|
|
psp.x *= .8;
|
|
}
|
|
|
|
action void A_ChargeUp()
|
|
{
|
|
A_SetAngle(angle+invoker.charge*.2,SPF_INTERPOLATE);
|
|
A_SetPitch(pitch*.9,SPF_INTERPOLATE);
|
|
invoker.charge = min(100.,invoker.charge+20.);
|
|
if ( !IsActorPlayingSound(CHAN_WEAPONEXTRA,"itamex/spin") )
|
|
A_StartSound("itamex/spin",CHAN_WEAPONEXTRA,CHANF_LOOP,.2);
|
|
A_SoundVolume(CHAN_WEAPONEXTRA,(invoker.charge/100.)**.5);
|
|
A_BumpFOV(1.+invoker.charge*.001);
|
|
Vector3 x = SWWMUtility.Vec3FromAngles(angle,pitch);
|
|
SWWMUtility.DoKnockback(self,x,500.*invoker.charge);
|
|
invoker.hitcnt = 0;
|
|
invoker.spintime = 0;
|
|
}
|
|
|
|
action void A_SpinReact()
|
|
{
|
|
if ( Random[Demolitionist](0,1) ) return;
|
|
if ( SWWMHandler.AddOneliner("spinning",2,5) )
|
|
Demolitionist(self).facegrin = true;
|
|
}
|
|
|
|
action State A_SpinMove()
|
|
{
|
|
A_SetAngle(angle+invoker.charge*.4,SPF_INTERPOLATE);
|
|
A_SetPitch(pitch*.9,SPF_INTERPOLATE);
|
|
invoker.charge = max(30.,invoker.charge-2.);
|
|
if ( (player.cmd.buttons&BT_ZOOM) && !(player.oldbuttons&BT_ZOOM) )
|
|
invoker.charge = min(100.,invoker.charge+20.);
|
|
A_SoundVolume(CHAN_WEAPONEXTRA,(invoker.charge/100.)**.5);
|
|
A_BumpFOV(1.+invoker.charge*.001);
|
|
Vector3 x = SWWMUtility.Vec3FromAngles(angle,pitch);
|
|
SWWMUtility.DoKnockback(self,(x.x,x.y,x.z*.1),1500.*invoker.charge);
|
|
if ( vel.z < 0 ) vel.z *= 1.-invoker.charge*.008;
|
|
A_QuakeEx(.5,.5,.5,15,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.1);
|
|
A_PlayerFire();
|
|
invoker.spintime++;
|
|
if ( invoker.hitcnt > 0 ) invoker.hitcnt--;
|
|
else if ( A_Melee(int(100+invoker.charge*1.5),"itamex/hit",2.4,2.,1.1,MELEE_Rip|MELEE_FleshSound|MELEE_ExtraWide|MELEE_HammerHit) )
|
|
{
|
|
A_BumpFOV(.9);
|
|
A_QuakeEx(5.,5.,5.,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.35);
|
|
A_AlertMonsters(swwm_uncapalert?0:800);
|
|
A_WeaponOffset(32,0,WOF_ADD|WOF_INTERPOLATE);
|
|
SWWMUtility.DoKnockback(self,-(x.x,x.y,x.z*.1),4500.*invoker.charge);
|
|
invoker.hitcnt = 3;
|
|
}
|
|
if ( invoker.charge <= 30. )
|
|
{
|
|
A_StartSound("itamex/swing",CHAN_WEAPON,CHANF_OVERLAP);
|
|
return ResolveState("ZoomEnd");
|
|
}
|
|
return ResolveState(null);
|
|
}
|
|
|
|
action void A_ChargeDown()
|
|
{
|
|
A_SetAngle(angle+invoker.charge*.6,SPF_INTERPOLATE);
|
|
A_SetPitch(pitch*.9,SPF_INTERPOLATE);
|
|
A_SoundVolume(CHAN_WEAPONEXTRA,(invoker.charge/100.)**.5);
|
|
invoker.charge = max(0.,invoker.charge-6.);
|
|
A_WeaponOffset(-16,0,WOF_ADD|WOF_INTERPOLATE);
|
|
A_BumpFOV(1.+invoker.charge*.001);
|
|
Vector3 x = SWWMUtility.Vec3FromAngles(angle,pitch);
|
|
SWWMUtility.DoKnockback(self,x,4000.*invoker.charge);
|
|
if ( invoker.charge <= 0 ) A_StopSound(CHAN_WEAPONEXTRA);
|
|
}
|
|
|
|
action void A_AltCharge()
|
|
{
|
|
A_CanBob();
|
|
invoker.charge = min(100.,invoker.charge+SWWMUtility.Lerp(4.,.5,(invoker.charge/100.)**.25));
|
|
double vibe = (invoker.charge/100.)**2.;
|
|
A_WeaponOffset(FRandom[Hammer](-.5,.5)*vibe,32+FRandom[Hammer](-.5,.5)*vibe,WOF_INTERPOLATE);
|
|
}
|
|
|
|
action State A_AltHold()
|
|
{
|
|
A_CanBob();
|
|
invoker.charge = min(100.,invoker.charge+SWWMUtility.Lerp(4.,.5,(invoker.charge/100.)**.25));
|
|
double vibe = (invoker.charge/100.)**2.;
|
|
A_WeaponOffset(FRandom[Hammer](-.5,.5)*vibe,32+FRandom[Hammer](-.5,.5)*vibe,WOF_INTERPOLATE);
|
|
if ( !(player.cmd.buttons&BT_ALTATTACK) )
|
|
{
|
|
A_WeaponOffset(0,32,WOF_INTERPOLATE);
|
|
return ResolveState("AltRelease");
|
|
}
|
|
return ResolveState(null);
|
|
}
|
|
|
|
action void A_AltRelease()
|
|
{
|
|
Vector3 x = SWWMUtility.Vec3FromAngles(angle,pitch);
|
|
SWWMUtility.DoKnockback(self,x-(0,0,3.),120000.);
|
|
A_BumpFOV(.9);
|
|
A_StartSound("itamex/drop",CHAN_WEAPONEXTRA2);
|
|
A_StartSound("itamex/drop",CHAN_WEAPONEXTRA3);
|
|
}
|
|
|
|
action void A_AltHit()
|
|
{
|
|
if ( (pos.z <= floorz+16) && (pitch > -15) )
|
|
{
|
|
A_StopSound(CHAN_WEAPONEXTRA2);
|
|
A_StopSound(CHAN_WEAPONEXTRA3);
|
|
A_StartSound("itamex/slam",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_StartSound("itamex/slam",CHAN_WEAPON,CHANF_OVERLAP);
|
|
vel.z += invoker.charge*.03;
|
|
A_BumpFOV(.85);
|
|
A_QuakeEx(8.,8.,8.,10,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:1.);
|
|
A_AlertMonsters(swwm_uncapalert?0:2500);
|
|
let s = Spawn("HammerShockwave",(pos.x,pos.y,floorz));
|
|
s.target = self;
|
|
s.special1 = int(invoker.charge*3);
|
|
}
|
|
invoker.charge = 0.;
|
|
}
|
|
|
|
override void OwnerDied()
|
|
{
|
|
Super.OwnerDied();
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
charge = 0.;
|
|
}
|
|
override void Travelled()
|
|
{
|
|
Super.Travelled();
|
|
A_StopSound(CHAN_WEAPONEXTRA);
|
|
charge = 0.;
|
|
}
|
|
|
|
override void MarkPrecacheSounds()
|
|
{
|
|
Super.MarkPrecacheSounds();
|
|
MarkSound("itamex/select");
|
|
MarkSound("itamex/deselect");
|
|
MarkSound("itamex/meleestart");
|
|
MarkSound("itamex/meleeend");
|
|
MarkSound("itamex/swing1");
|
|
MarkSound("itamex/swing2");
|
|
MarkSound("itamex/swing3");
|
|
MarkSound("itamex/hit1");
|
|
MarkSound("itamex/hit2");
|
|
MarkSound("itamex/hit3");
|
|
MarkSound("itamex/hitf1");
|
|
MarkSound("itamex/hitf2");
|
|
MarkSound("itamex/hitf3");
|
|
MarkSound("itamex/drop");
|
|
MarkSound("itamex/slam");
|
|
MarkSound("itamex/spin");
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_HAMMER";
|
|
Inventory.Icon "graphics/HUD/Icons/W_ItamexHammer.png";
|
|
Inventory.PickupMessage "$I_HAMMER";
|
|
Obituary "$O_HAMMER";
|
|
SWWMWeapon.Tooltip "$TT_HAMMER";
|
|
SWWMWeapon.GetLine "getitamexhammer";
|
|
Weapon.SlotNumber 1;
|
|
Weapon.SlotPriority 2.;
|
|
Weapon.SelectionOrder 1200;
|
|
Weapon.UpSound "itamex/select";
|
|
Stamina 9000;
|
|
+WEAPON.MELEEWEAPON;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1;
|
|
Stop;
|
|
Select:
|
|
XZW2 I 3 A_FullRaise();
|
|
XZW2 JK 3 A_BumpView(-.1,tics:3);
|
|
XZW2 LMNO 2 A_BumpView(.2,tics:2);
|
|
XZW2 PQRST 3;
|
|
Goto Ready;
|
|
Ready:
|
|
XZW2 A 1
|
|
{
|
|
A_WeaponOffset(0,32,WOF_INTERPOLATE); // ensure we're back to normal offsets just in case
|
|
A_WeaponReady(WRF_ALLOWRELOAD|WRF_ALLOWZOOM|WRF_ALLOWUSER1);
|
|
}
|
|
Wait;
|
|
Fire:
|
|
XZW2 A 2 A_StartSound("itamex/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW2 UVWXYZ 1 A_BumpAngle(-1);
|
|
XZW3 A 1
|
|
{
|
|
A_StartSound("itamex/swing",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_PlayerMelee();
|
|
}
|
|
XZW3 BCDE 1 A_BumpAngle(4);
|
|
XZW3 F 1 A_HammerHit();
|
|
XZW3 GHIJK 2;
|
|
XZW3 L 2 A_StartSound("itamex/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW3 MNOPQR 2;
|
|
Goto Ready;
|
|
FireHit:
|
|
XZW3 F 2;
|
|
XZW3 STUVW 2;
|
|
XZW3 XYZ 1;
|
|
XZW4 A 2;
|
|
XZW4 B 2 A_StartSound("itamex/meleeend",CHAN_WEAPON,CHANF_OVERLAP,starttime:.42);
|
|
XZW4 C 2;
|
|
Goto Ready;
|
|
AltFire:
|
|
XZW2 A 2 A_StartSound("itamex/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW4 DEFG 2
|
|
{
|
|
A_BumpView(.4,tics:2);
|
|
A_AltCharge();
|
|
}
|
|
XZW4 HIJKLMN 1
|
|
{
|
|
A_BumpView(-.2);
|
|
A_AltCharge();
|
|
}
|
|
XZW4 OPQRSTU 1 A_AltCharge();
|
|
XZW4 V 1 A_AltHold();
|
|
Wait;
|
|
AltRelease:
|
|
XZW4 V 1 A_AltRelease();
|
|
XZW4 WXYZ 1 A_BumpView(2.);
|
|
XZW5 A 1 A_BumpView(3.);
|
|
XZW5 B 1
|
|
{
|
|
A_BumpView(3.);
|
|
A_HammerAltHit();
|
|
}
|
|
XZW5 CD 1 A_BumpView(4.);
|
|
XZW5 E 1 A_AltHit();
|
|
XZW5 FGHIJKLMN 2;
|
|
XZW5 O 2 A_StartSound("itamex/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 PQRS 2;
|
|
XZW5 TUVW 3;
|
|
Goto Ready;
|
|
Zoom:
|
|
XZW2 A 2 A_StartSound("itamex/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW5 XYZ 2 A_BumpAngle(-2,tics:2);
|
|
XZW6 ABCDEF 1 A_ChargeUp();
|
|
XZW6 G 0 A_SpinReact();
|
|
XZW6 G 1 A_SpinMove();
|
|
Wait;
|
|
ZoomEnd:
|
|
XZW6 GHIJ 1
|
|
{
|
|
A_ChargeDown();
|
|
A_BumpAngle(10);
|
|
}
|
|
XZW6 K 1
|
|
{
|
|
A_ChargeDown();
|
|
A_HammerHit(true);
|
|
}
|
|
XZW6 LM 1 A_ChargeDown();
|
|
XZW6 N 2 A_StartSound("itamex/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW6 OPQRST 2;
|
|
XZW6 UVW 3;
|
|
Goto Ready;
|
|
Reload:
|
|
XZW2 A 2 A_StartSound("itamex/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW6 XYZ 2 A_BumpView(-.1,tics:2);
|
|
XZW7 ABCDEF 2;
|
|
XZW7 G 1
|
|
{
|
|
A_PlayerCheckGun();
|
|
A_QuakeEx(.3,.3,.3,6,0,15,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.1);
|
|
A_StartSound("itamex/meleeend",CHAN_WEAPONEXTRA,pitch:.7,starttime:.2);
|
|
}
|
|
XZW7 HIJ 1 A_BumpView(-.05);
|
|
XZW7 K 1
|
|
{
|
|
A_QuakeEx(.3,.3,.3,6,0,15,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.1);
|
|
A_StartSound("itamex/meleeend",CHAN_WEAPONEXTRA,pitch:.8,starttime:.2);
|
|
}
|
|
XZW7 LMNO 1 A_BumpView(-.05);
|
|
XZW7 P 1
|
|
{
|
|
A_QuakeEx(.3,.3,.3,6,0,15,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.1);
|
|
A_StartSound("itamex/meleeend",CHAN_WEAPONEXTRA,pitch:.9,starttime:.2);
|
|
}
|
|
XZW7 QRST 1 A_BumpView(-.05);
|
|
XZW7 U 1 A_StopSound(CHAN_WEAPONEXTRA);
|
|
XZW7 VWXYZ 1 A_BumpView(.05);
|
|
XZW8 A 0 A_StartSound("itamex/meleeend",CHAN_WEAPON,CHANF_OVERLAP,starttime:.42);
|
|
XZW8 BCDE 3 A_BumpView(-.1,tics:3);
|
|
XZW8 FGHI 2 A_BumpView(.05,tics:2);
|
|
Goto Ready;
|
|
User1:
|
|
XZW2 A 1;
|
|
XZW8 J 1 A_StartSound("itamex/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW8 KLM 1;
|
|
XZW8 N 2 A_StartSound("demolitionist/wswing",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW8 OPQ 2 A_BumpView(.5,tics:2);
|
|
XZW8 R 1
|
|
{
|
|
A_BumpFOV(.97);
|
|
A_QuakeEx(1.,1.,1.,8,0,15,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.4);
|
|
A_Parry(9);
|
|
A_PlayerMelee(true);
|
|
}
|
|
XZW8 S 1 A_BumpView(-6);
|
|
XZW8 T 3 A_Melee(50,"demolitionist/whitm",1.2,1.4);
|
|
XZW8 UVWXYZ 2;
|
|
XZW9 ABC 2;
|
|
XZW9 D 1 A_StartSound("itamex/meleeend",CHAN_WEAPON,CHANF_OVERLAP,starttime:.42);
|
|
XZW9 EFGH 1;
|
|
XZW9 IJKL 2;
|
|
Goto Ready;
|
|
Deselect:
|
|
XZW2 A 3 A_StartSound("itamex/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW2 BCD 3 A_BumpView(.1,tics:3);
|
|
XZW2 EFGHI 2 A_BumpView(.2,tics:2);
|
|
XZW2 J -1 A_FullLower();
|
|
Stop;
|
|
}
|
|
}
|