701 lines
18 KiB
Text
701 lines
18 KiB
Text
// Imanaki Corp Hellfire Cannon Mk3, aka "Hellblazer" (from SWWM series, originally inspired by the Hellraiser from OMGWEAPONS)
|
|
// Slot 6, replaces Rocket Launcher, Phoenix Rod, Firestorm
|
|
|
|
Class HellblazerX : SWWMItemOverlay
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle 'Translucent';
|
|
Alpha .5;
|
|
+INTERPOLATEANGLES;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1; // not fullbright
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class Hellblazer : SWWMWeapon
|
|
{
|
|
int clipcount;
|
|
bool magstate[6]; // true: rocket was spent
|
|
int magpos; // current rotation
|
|
int spinskipped;
|
|
int preload; // additional loaded missiles (up to 2)
|
|
Actor seektarget[3];
|
|
int seekcnt;
|
|
int preloadcnt;
|
|
|
|
transient ui SWWMProjectionData projdata;
|
|
ui TextureID LockIcon;
|
|
|
|
override void RenderUnderlay( RenderEvent e )
|
|
{
|
|
Super.RenderUnderlay(e);
|
|
if ( !LockIcon ) LockIcon = TexMan.CheckForTexture("graphics/HUD/HellblazerMissileLock.png");
|
|
SWWMUtility.PrepareProjData(projdata,e.ViewPos,e.ViewAngle,e.ViewPitch,e.ViewRoll,players[consoleplayer].fov);
|
|
Screen.SetClipRect(projdata.viewx,projdata.viewy,projdata.vieww,projdata.viewh);
|
|
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/360.)),1.);
|
|
Vector2 ss = (Screen.GetWidth()/hs,Screen.GetHeight()/hs);
|
|
for ( int i=0; i<3; i++ )
|
|
{
|
|
if ( !seektarget[i] ) continue;
|
|
Vector3 tpos = SWWMUtility.LerpVector3(seektarget[i].prev,seektarget[i].pos,e.FracTic);
|
|
Vector3 ndc = SWWMUtility.ProjectPoint(projdata,e.viewpos+level.Vec3Diff(e.viewpos,tpos+(0,0,seektarget[i].Height/2)));
|
|
if ( ndc.z <= 0. ) continue;
|
|
Vector2 vpos = SWWMUtility.NDCToViewport(projdata,ndc);
|
|
Screen.DrawTexture(LockIcon,false,vpos.x/hs,vpos.y/hs,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_CenterOffset,true);
|
|
}
|
|
Screen.ClearClipRect();
|
|
}
|
|
|
|
override Vector3 GetTraceOffset( int index )
|
|
{
|
|
return (10.,3.5,-5.);
|
|
}
|
|
|
|
action void A_HellblazerFire( bool bAlt = false )
|
|
{
|
|
A_StartSound(bAlt?"hellblazer/altfire":"hellblazer/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:(bAlt?1.7:.8));
|
|
A_AlertMonsters(swwm_uncapalert?0:bAlt?400:1200);
|
|
double qstr = bAlt?4.:5.;
|
|
A_QuakeEx(qstr,qstr,qstr,bAlt?4:12,0,15,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.12*qstr);
|
|
A_BumpFOV(bAlt?.96:.93);
|
|
A_BumpView(bAlt?-2:-3);
|
|
A_PlayerFire();
|
|
invoker.clipcount = max(0,invoker.clipcount-1);
|
|
invoker.magstate[invoker.magpos-invoker.preload] = true;
|
|
invoker.spinskipped++;
|
|
let [x, y, z] = SWWMUtility.GetPlayerAxes(self);
|
|
SWWMUtility.DoKnockback(self,-x,bAlt?22000.:32000.);
|
|
let [x2, y2, z2] = SWWMUtility.GetPlayerAxesAutoAimed(self);
|
|
Vector3 origin = SWWMUtility.GetFireOffset(self,10,3.5,-5);
|
|
double a = FRandom[Hellblazer](0,360);
|
|
double s = FRandom[Hellblazer](0,bAlt?.02:.005);
|
|
Vector3 dir = SWWMUtility.ConeSpread(x2,y2,z2,a,s);
|
|
let p = Spawn(bAlt?'HellblazerMissile2':'HellblazerMissile',origin);
|
|
p.target = self;
|
|
int tidx = max(0,invoker.seekcnt-(invoker.preload+1));
|
|
if ( invoker.seektarget[tidx] ) HellblazerMissile(p).seektarget = invoker.seektarget[tidx];
|
|
if ( invoker.preload <= 0 ) for ( int i=0; i<3; i++ ) invoker.seektarget[i] = null;
|
|
p.angle = atan2(dir.y,dir.x);
|
|
p.pitch = asin(-dir.z);
|
|
p.vel = dir*p.speed;
|
|
if ( bAlt )
|
|
{
|
|
if ( p.waterlevel <= 0 ) p.vel.z += 3.5;
|
|
return;
|
|
}
|
|
for ( int i=0; i<5; i++ )
|
|
{
|
|
let s = Spawn('SWWMSmoke',origin);
|
|
s.special1 = 1;
|
|
s.scale *= 2.4;
|
|
s.alpha *= .4;
|
|
s.SetShade(Color(4,3,2)*Random[Hellblazer](48,63));
|
|
s.vel += vel*.5+x*FRandom[Hellblazer](6.,10.)+y*FRandom[Hellblazer](-2,2)+z*FRandom[Hellblazer](-2,2);
|
|
}
|
|
for ( int i=0; i<6; i++ )
|
|
{
|
|
let s = Spawn('SWWMSpark',origin);
|
|
s.scale *= .7;
|
|
s.alpha *= .4;
|
|
s.vel += vel*.5+x*FRandom[Hellblazer](4.,8.)+y*FRandom[Hellblazer](-2,2)+z*FRandom[Hellblazer](-2,2);
|
|
}
|
|
}
|
|
|
|
override bool ReportHUDAmmo()
|
|
{
|
|
return (clipcount>0)||(Ammo1.Amount>0);
|
|
}
|
|
|
|
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
|
|
{
|
|
if ( (firemode == PrimaryFire) || (firemode == AltFire) )
|
|
return (clipcount>0)||(Ammo1.Amount>0);
|
|
return Super.CheckAmmo(firemode,autoswitch,requireammo,ammocount);
|
|
}
|
|
|
|
action void A_GlassOverlay( StateLabel g )
|
|
{
|
|
player.SetPSprite(PSP_WEAPON+1,invoker.FindState(g));
|
|
// we have to still use A_Overlay* functions for these
|
|
A_OverlayFlags(PSP_WEAPON+1,PSPF_RENDERSTYLE|PSPF_FORCESTYLE|PSPF_ALPHA|PSPF_FORCEALPHA,true);
|
|
A_OverlayRenderStyle(PSP_WEAPON+1,STYLE_Translucent);
|
|
A_OverlayAlpha(PSP_WEAPON+1,.5);
|
|
}
|
|
|
|
action state A_JumpX( StateLabel a, StateLabel g )
|
|
{
|
|
A_GlassOverlay(g);
|
|
return invoker.FindState(a);
|
|
}
|
|
|
|
override bool PickupForAmmoSWWM( SWWMWeapon ownedWeapon )
|
|
{
|
|
bool good = Super.PickupForAmmoSWWM(ownedWeapon);
|
|
let Owner = ownedWeapon.Owner;
|
|
if ( (AmmoGive1 == 0) && (clipcount > 0) )
|
|
{
|
|
// let's get this bread
|
|
Inventory cur = Owner.FindInventory(AmmoType1);
|
|
if ( !cur )
|
|
{
|
|
cur = Inventory(Spawn(AmmoType1));
|
|
cur.Amount = 0;
|
|
cur.AttachToOwner(Owner);
|
|
}
|
|
int maxgiveamt = min(cur.MaxAmount-cur.Amount,clipcount);
|
|
int dropamt = clipcount-maxgiveamt;
|
|
if ( dropamt > 0 ) cur.CreateTossable(dropamt);
|
|
cur.Amount = min(cur.MaxAmount,cur.Amount+clipcount);
|
|
good = true;
|
|
}
|
|
return good;
|
|
}
|
|
|
|
override void InitializeWeapon()
|
|
{
|
|
// 3 hellblazer missiles loaded
|
|
clipcount = 3;
|
|
magpos = 0;
|
|
for ( int i=0; i<6; i++ )
|
|
magstate[i] = (i>2);
|
|
}
|
|
|
|
clearscope int LoadedCapacity() const
|
|
{
|
|
return min(Ammo1.Amount+clipcount,6);
|
|
}
|
|
|
|
action void A_SwapAmmo()
|
|
{
|
|
int takeamt = invoker.LoadedCapacity()-invoker.clipcount;
|
|
invoker.clipcount = invoker.LoadedCapacity();
|
|
if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
|
|
invoker.Ammo1.Amount = max(0,invoker.Ammo1.Amount-takeamt);
|
|
invoker.magpos = 0;
|
|
for ( int i=0; i<6; i++ )
|
|
invoker.magstate[i] = !(invoker.clipcount > i);
|
|
return;
|
|
}
|
|
|
|
action void A_HellblazerReady()
|
|
{
|
|
int flg = WRF_ALLOWRELOAD|WRF_ALLOWZOOM|WRF_ALLOWUSER1;
|
|
// can we fire?
|
|
bool canfire = (invoker.clipcount > 0) || (invoker.Ammo1.Amount > 0);
|
|
if ( !canfire ) flg |= WRF_NOPRIMARY|WRF_NOSECONDARY;
|
|
A_WeaponReady(flg);
|
|
if ( player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK) )
|
|
invoker.CheckAmmo(EitherFire,true);
|
|
}
|
|
|
|
// check if weapon was dropped or interrupted in some way before the mag spin could be done
|
|
action void A_CheckSpinSkip()
|
|
{
|
|
for ( int i=0; i<3; i++ ) invoker.seektarget[i] = null;
|
|
// check preloaded rockets first (note, this theoretically would never go below zero)
|
|
invoker.magpos = max(0,invoker.magpos-invoker.preload);
|
|
invoker.preload = 0;
|
|
// do the spin
|
|
invoker.magpos = (invoker.magpos+invoker.spinskipped)%6;
|
|
invoker.spinskipped = 0;
|
|
}
|
|
|
|
action void A_UpdatePickup()
|
|
{
|
|
// if not initialized, default to 3 loaded rockets
|
|
int loaded = invoker.bInitialized?invoker.clipcount:3;
|
|
for ( int i=0; i<6; i++ )
|
|
A_ChangeModel("",0,"","",2+i,"models",(i>=loaded)?"":"HellblazerMissile.png",CMDL_USESURFACESKIN,-1);
|
|
}
|
|
|
|
action void A_CheckLockOn()
|
|
{
|
|
if ( invoker.seekcnt > invoker.preload ) return;
|
|
Vector3 origin = SWWMUtility.GetPlayerEye(self);
|
|
// try to catch target in cone of vision
|
|
Vector3 dir;
|
|
let [x, y, z] = SWWMUtility.GetPlayerAxes(self);
|
|
Array<HHitList> hits;
|
|
hits.Clear();
|
|
int rings = 1;
|
|
FLineTraceData d;
|
|
for ( double i=0; i<.1; i+=.02 )
|
|
{
|
|
for ( int j=0; j<360; j+=(360/rings) )
|
|
{
|
|
dir = SWWMUtility.ConeSpread(x,y,z,j,i);
|
|
LineTrace(atan2(dir.y,dir.x),8000.,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
|
if ( d.HitType != TRACE_HitActor ) continue;
|
|
if ( (d.HitActor == invoker.seektarget[0])
|
|
|| (d.HitActor == invoker.seektarget[1])
|
|
|| (d.HitActor == invoker.seektarget[2]) ) continue;
|
|
if ( !d.HitActor.bISMONSTER && !(d.HitActor is 'BossBrain') && !d.HitActor.player )
|
|
continue;
|
|
if ( d.HitActor.IsFriend(self) ) continue;
|
|
bool addme = true;
|
|
for ( int k=0; k<hits.Size(); k++ )
|
|
{
|
|
if ( hits[k].a != d.HitActor ) continue;
|
|
if ( (hits[k].dir dot x) < (dir dot x) )
|
|
hits[k].dir = dir; // closer to centerpoint
|
|
addme = false;
|
|
break;
|
|
}
|
|
if ( !addme ) continue;
|
|
let nhit = new('HHitList');
|
|
nhit.a = d.HitActor;
|
|
nhit.dir = dir;
|
|
hits.Push(nhit);
|
|
}
|
|
rings += 5;
|
|
}
|
|
int closest = -1;
|
|
double closestdot = -1;
|
|
for ( int i=0; i<hits.Size(); i++ )
|
|
{
|
|
double thisdot = (hits[i].dir dot x);
|
|
if ( thisdot < closestdot ) continue;
|
|
closest = i;
|
|
closestdot = thisdot;
|
|
}
|
|
if ( closest != -1 )
|
|
{
|
|
if ( invoker.seekcnt == 0 )
|
|
{
|
|
for ( int i=0; i<3; i++ )
|
|
invoker.seektarget[i] = hits[closest].a;
|
|
}
|
|
else invoker.seektarget[invoker.seekcnt] = hits[closest].a;
|
|
invoker.seekcnt++;
|
|
A_StartSound("hellblazer/lock",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
}
|
|
|
|
override void PreTravelled()
|
|
{
|
|
Super.PreTravelled();
|
|
if ( tracer ) tracer.Destroy();
|
|
}
|
|
override void Travelled()
|
|
{
|
|
Super.Travelled();
|
|
if ( tracer ) return;
|
|
tracer = Spawn('HellblazerX',pos);
|
|
tracer.angle = angle;
|
|
tracer.target = self;
|
|
tracer.FloatBobPhase = FloatBobPhase;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
tracer = Spawn('HellblazerX',pos);
|
|
tracer.angle = angle;
|
|
tracer.target = self;
|
|
tracer.FloatBobPhase = FloatBobPhase;
|
|
}
|
|
|
|
override void MarkPrecacheSounds()
|
|
{
|
|
Super.MarkPrecacheSounds();
|
|
MarkSound("hellblazer/select");
|
|
MarkSound("hellblazer/deselect");
|
|
MarkSound("hellblazer/fire");
|
|
MarkSound("hellblazer/altfire");
|
|
MarkSound("hellblazer/meleestart");
|
|
MarkSound("hellblazer/meleeend");
|
|
MarkSound("hellblazer/idle");
|
|
MarkSound("hellblazer/dustoff");
|
|
MarkSound("hellblazer/shift");
|
|
MarkSound("hellblazer/spin");
|
|
MarkSound("hellblazer/open");
|
|
MarkSound("hellblazer/magout");
|
|
MarkSound("hellblazer/magin");
|
|
MarkSound("hellblazer/close");
|
|
MarkSound("hellblazer/hit1");
|
|
MarkSound("hellblazer/hit2");
|
|
MarkSound("hellblazer/hit3");
|
|
MarkSound("hellblazer/bounce");
|
|
MarkSound("hellblazer/fly");
|
|
MarkSound("hellblazer/preload");
|
|
MarkSound("hellblazer/hold");
|
|
MarkSound("hellblazer/lock");
|
|
MarkSound("hellblazer/clear");
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_HELLBLAZER";
|
|
Inventory.Icon "graphics/HUD/Icons/W_Hellblazer.png";
|
|
Inventory.PickupMessage "$I_HELLBLAZER";
|
|
Obituary "$O_HELLBLAZER";
|
|
SWWMWeapon.Tooltip "$TT_HELLBLAZER";
|
|
SWWMWeapon.GetLine "gethellblazer";
|
|
Weapon.SlotNumber 6;
|
|
Weapon.SelectionOrder 700;
|
|
Weapon.UpSound "hellblazer/select";
|
|
Stamina 90000;
|
|
Weapon.AmmoType1 'HellblazerMissiles';
|
|
Weapon.AmmoGive1 3;
|
|
SWWMWeapon.DropAmmoType 'SWWMRocketAmmoSmall';
|
|
+SWWMWEAPON.NOFIRSTGIVE;
|
|
+WEAPON.EXPLOSIVE;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
XZW1 A -1 NoDelay A_UpdatePickup();
|
|
Stop;
|
|
Select:
|
|
XZW2 I 2
|
|
{
|
|
A_CheckSpinSkip();
|
|
A_FullRaise();
|
|
A_GlassOverlay('Select_G');
|
|
}
|
|
XZW2 JKLMNOP 2;
|
|
Goto Ready;
|
|
Select_G:
|
|
XZW7 IJKLMNOP 2;
|
|
Goto Ready_G;
|
|
Deselect:
|
|
XZW2 A 2
|
|
{
|
|
A_StartSound("hellblazer/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_GlassOverlay('Deselect_G');
|
|
}
|
|
XZW2 BCDEFGH 2;
|
|
XZW2 I -1 A_FullLower();
|
|
Stop;
|
|
Deselect_G:
|
|
XZW7 ABCDEFGHI 2;
|
|
Stop;
|
|
Ready:
|
|
XZW2 A 0 A_GlassOverlay('Ready_G');
|
|
XZW2 A 1 A_HellblazerReady();
|
|
Wait;
|
|
Ready_G:
|
|
XZW7 A 1;
|
|
Wait;
|
|
Fire:
|
|
#### # 0
|
|
{
|
|
invoker.preloadcnt = 0;
|
|
invoker.preload = 0;
|
|
}
|
|
#### # 1
|
|
{
|
|
if ( invoker.clipcount <= 0 )
|
|
return A_JumpX('Unload','Unload_G');
|
|
if ( player.cmd.buttons&BT_ATTACK )
|
|
{
|
|
A_CanBob();
|
|
invoker.preloadcnt++;
|
|
if ( (player.cmd.buttons&BT_ALTATTACK) || ((invoker.clipcount < 2) && (invoker.preloadcnt >= 10)) )
|
|
{
|
|
invoker.preloadcnt = 0;
|
|
return A_JumpX('PreFire','Ready_G');
|
|
}
|
|
if ( invoker.preloadcnt >= 10 )
|
|
{
|
|
invoker.preloadcnt = 0;
|
|
return A_JumpX('PreLoad','Ready_G');
|
|
}
|
|
return ResolveState(null);
|
|
}
|
|
return A_JumpX('DoFire','DoFire_G');
|
|
}
|
|
Wait;
|
|
DoFire:
|
|
XZW2 A 1 A_HellblazerFire();
|
|
XZW2 QRSTUVW 2;
|
|
XZW2 A 0
|
|
{
|
|
// chain-fire
|
|
if ( invoker.preload > 0 )
|
|
{
|
|
invoker.preload--;
|
|
invoker.spinskipped--;
|
|
return A_JumpX('DoFire','DoFire_G');
|
|
}
|
|
return ResolveState(null);
|
|
}
|
|
Goto Cycle;
|
|
DoFire_G:
|
|
XZW7 A 1;
|
|
XZW7 QRSTUVW 2;
|
|
Goto Ready_G; // state jump to cycling is done elsewhere
|
|
AltFire:
|
|
#### # 0
|
|
{
|
|
invoker.preloadcnt = 0;
|
|
invoker.preload = 0;
|
|
}
|
|
#### # 1
|
|
{
|
|
if ( invoker.clipcount <= 0 )
|
|
return A_JumpX('Unload','Unload_G');
|
|
if ( player.cmd.buttons&BT_ALTATTACK )
|
|
{
|
|
A_CanBob();
|
|
invoker.preloadcnt++;
|
|
if ( (player.cmd.buttons&BT_ATTACK) || ((invoker.clipcount < 2) && (invoker.preloadcnt >= 10)) )
|
|
{
|
|
invoker.preloadcnt = 0;
|
|
return A_JumpX('PreAltFire','Ready_G');
|
|
}
|
|
if ( invoker.preloadcnt >= 10 )
|
|
{
|
|
invoker.preloadcnt = 0;
|
|
return A_JumpX('PreAltLoad','Ready_G');
|
|
}
|
|
return ResolveState(null);
|
|
}
|
|
return A_JumpX('DoAltFire','DoAltFire_G');
|
|
}
|
|
Wait;
|
|
DoAltFire:
|
|
XZW2 A 1 A_HellblazerFire(true);
|
|
XZW2 XYZ 2;
|
|
XZW3 ABCD 2;
|
|
XZW2 A 0
|
|
{
|
|
// chain-fire
|
|
if ( invoker.preload > 0 )
|
|
{
|
|
invoker.preload--;
|
|
invoker.spinskipped--;
|
|
return A_JumpX('DoAltFire','DoAltFire_G');
|
|
}
|
|
return ResolveState(null);
|
|
}
|
|
Goto Cycle;
|
|
DoAltFire_G:
|
|
XZW7 A 1;
|
|
XZW7 XYZ 2;
|
|
XZW8 ABCD 2;
|
|
Goto Ready_G; // state jump to cycling is done elsewhere
|
|
PreLoad:
|
|
XZW2 A 10
|
|
{
|
|
A_StartSound("hellblazer/preload",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_CanBob();
|
|
}
|
|
XZW2 A 2
|
|
{
|
|
invoker.magpos = (invoker.magpos+1)%6;
|
|
invoker.preload++;
|
|
A_GlassOverlay('Cycle_G');
|
|
A_CanBob();
|
|
}
|
|
XZW3 E 2 A_CanBob();
|
|
XZW3 FGHI 2 A_CanBob();
|
|
XZW3 I 0 A_CanBob();
|
|
XZW3 FE 2 A_CanBob();
|
|
XZW2 A 1
|
|
{
|
|
A_CanBob();
|
|
if ( !(player.cmd.buttons&BT_ATTACK) )
|
|
return A_JumpX('DoFire','DoFire_G');
|
|
if ( (player.cmd.buttons&BT_ALTATTACK) || (invoker.preload >= min(invoker.clipcount-1,2)) )
|
|
return A_JumpX('PreFire','Ready_G');
|
|
return A_JumpX('PreLoad','Ready_G');
|
|
}
|
|
Wait;
|
|
PreAltLoad:
|
|
XZW2 A 10
|
|
{
|
|
A_StartSound("hellblazer/preload",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_CanBob();
|
|
}
|
|
XZW2 A 2
|
|
{
|
|
invoker.magpos = (invoker.magpos+1)%6;
|
|
invoker.preload++;
|
|
A_GlassOverlay('Cycle_G');
|
|
A_CanBob();
|
|
}
|
|
XZW3 E 2 A_CanBob();
|
|
XZW3 FGHI 2 A_CanBob();
|
|
XZW3 I 0 A_CanBob();
|
|
XZW3 FE 2 A_CanBob();
|
|
XZW2 A 1
|
|
{
|
|
A_CanBob();
|
|
if ( !(player.cmd.buttons&BT_ALTATTACK) )
|
|
return A_JumpX('DoAltFire','DoAltFire_G');
|
|
if ( (player.cmd.buttons&BT_ATTACK) || (invoker.preload >= min(invoker.clipcount-1,2)) )
|
|
return A_JumpX('PreAltFire','Ready_G');
|
|
return A_JumpX('PreAltLoad','Ready_G');
|
|
}
|
|
Wait;
|
|
PreFire:
|
|
XZW2 A 0
|
|
{
|
|
invoker.seekcnt = 0;
|
|
A_StartSound("hellblazer/hold",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZW2 A 1
|
|
{
|
|
if ( !(player.cmd.buttons&BT_ATTACK) )
|
|
return A_JumpX('DoFire','DoFire_G');
|
|
A_CanBob();
|
|
if ( (player.cmd.buttons&BT_ZOOM) && !(player.oldbuttons&BT_ZOOM) )
|
|
A_CheckLockOn();
|
|
if ( (player.cmd.buttons&BT_RELOAD) && !(player.oldbuttons&BT_RELOAD) )
|
|
{
|
|
for ( int i=0; i<3; i++ ) invoker.seektarget[i] = null;
|
|
if ( invoker.seekcnt > 0 ) A_StartSound("hellblazer/clear",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.seekcnt = 0;
|
|
}
|
|
return ResolveState(null);
|
|
}
|
|
Wait;
|
|
PreAltFire:
|
|
XZW2 A 0
|
|
{
|
|
invoker.seekcnt = 0;
|
|
A_StartSound("hellblazer/hold",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZW2 A 1
|
|
{
|
|
if ( !(player.cmd.buttons&BT_ALTATTACK) )
|
|
return A_JumpX('DoAltFire','DoAltFire_G');
|
|
A_CanBob();
|
|
if ( (player.cmd.buttons&BT_ZOOM) && !(player.oldbuttons&BT_ZOOM) )
|
|
A_CheckLockOn();
|
|
if ( (player.cmd.buttons&BT_RELOAD) && !(player.oldbuttons&BT_RELOAD) )
|
|
{
|
|
for ( int i=0; i<3; i++ ) invoker.seektarget[i] = null;
|
|
if ( invoker.seekcnt > 0 ) A_StartSound("hellblazer/clear",CHAN_WEAPON,CHANF_OVERLAP);
|
|
invoker.seekcnt = 0;
|
|
}
|
|
return ResolveState(null);
|
|
}
|
|
Wait;
|
|
Cycle:
|
|
XZW2 A 2
|
|
{
|
|
A_CanBob();
|
|
invoker.spinskipped--;
|
|
invoker.magpos = (invoker.magpos+1)%6;
|
|
A_GlassOverlay('Cycle_G');
|
|
}
|
|
XZW3 E 2 A_CanBob();
|
|
XZW3 FGHI 2 A_CanBob();
|
|
XZW3 I 0 A_CanBob();
|
|
XZW3 FE 2 A_CanBob();
|
|
Goto Ready;
|
|
Cycle_G:
|
|
XZW7 A 2 A_StartSound("hellblazer/shift",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW8 E 2;
|
|
XZW8 F 2 A_StartSound("hellblazer/spin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW8 GH 2;
|
|
XZW8 I 2;
|
|
XZW8 I 0 A_StartSound("hellblazer/shift",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW8 FE 2;
|
|
Goto Ready_G;
|
|
Reload:
|
|
XZW2 A 2
|
|
{
|
|
if ( invoker.clipcount >= invoker.LoadedCapacity() )
|
|
return A_JumpX('Zoom','Zoom_G');
|
|
return A_JumpX('Unload','Unload_G');
|
|
}
|
|
Goto Ready;
|
|
Unload:
|
|
XZW2 A 2;
|
|
XZW3 JKLMNOPQRSTUVWXYZ 2;
|
|
XZW4 ABCDEFGHIJ 1;
|
|
XZW6 VWXYZ 3;
|
|
XZW4 J 0 A_SwapAmmo();
|
|
Goto Load;
|
|
Unload_G:
|
|
XZW7 A 2 A_StartSound("hellblazer/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW8 JKL 2;
|
|
XZW8 M 2 A_StartSound("hellblazer/open",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW8 NOPQ 2;
|
|
XZW8 R 2 A_QuakeEx(.8,.8,.8,6,0,15,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.2);
|
|
XZW8 STUVWXY 2;
|
|
XZW8 Z 2
|
|
{
|
|
A_BumpView(-1.);
|
|
A_StartSound("hellblazer/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZW9 ABCDEFGHIJ 1;
|
|
XZWB VW 3 A_BumpView(.3,tics:3);
|
|
XZWB X 3;
|
|
XZWB YZ 3 A_BumpView(-.3,tics:3);
|
|
Goto Load_G;
|
|
Load:
|
|
XZW4 JKLMNOPQRS 1;
|
|
XZW4 TUVWXYZ 2;
|
|
XZW5 ABCDEFGHIJ 2;
|
|
Goto Ready;
|
|
Load_G:
|
|
XZW9 J 1 A_PlayerReload();
|
|
XZW9 KLMNOP 1;
|
|
XZW9 Q 1
|
|
{
|
|
A_BumpView(1.);
|
|
A_StartSound("hellblazer/magin",CHAN_WEAPON,CHANF_OVERLAP);
|
|
}
|
|
XZW9 RS 1;
|
|
XZW9 TUVWX 2;
|
|
XZW9 Y 2 A_StartSound("hellblazer/close",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZW9 Z 2;
|
|
XZWA A 2 A_QuakeEx(1.2,1.2,1.2,8,0,15,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.3);
|
|
XZWA BC 2;
|
|
XZWA D 2 A_StartSound("hellblazer/meleestop",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWA EFGHIJ 2;
|
|
Goto Ready_G;
|
|
Zoom:
|
|
XZW2 A 2 A_GlassOverlay('Zoom_G');
|
|
XZW5 KLMNOPQRSTUVWXYZ 2;
|
|
XZW6 A 2;
|
|
Goto Ready;
|
|
Zoom_G:
|
|
XZW7 A 2
|
|
{
|
|
A_StartSound("hellblazer/idle",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_PlayerCheckGun();
|
|
}
|
|
XZWA KLMNO 2;
|
|
XZWA P 2 A_StartSound("hellblazer/dustoff",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWA Q 2;
|
|
XZWA RSTUVWXYZ 2;
|
|
XZWB A 2;
|
|
Goto Ready_G;
|
|
User1:
|
|
XZW2 A 2 A_GlassOverlay('User1_G');
|
|
XZW6 BCDE 2;
|
|
XZW6 FGH 1;
|
|
XZW6 IJK 2;
|
|
XZW6 LMNOPQRSTU 2;
|
|
Goto Ready;
|
|
User1_G:
|
|
XZW7 A 2
|
|
{
|
|
A_StartSound("hellblazer/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_StartSound("demolitionist/wswing",CHAN_WEAPON,CHANF_OVERLAP);
|
|
A_PlayerMelee();
|
|
}
|
|
XZWB BCD 2 A_BumpView(.5,tics:2);
|
|
XZWB E 2
|
|
{
|
|
A_BumpFOV(.96);
|
|
A_QuakeEx(1.2,1.2,1.2,8,0,15,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.4);
|
|
A_Parry(9);
|
|
}
|
|
XZWB FG 1 A_BumpView(-3);
|
|
XZWB H 1 A_Melee(75,"demolitionist/whitl",1.05,1.2,1.2);
|
|
XZWB IJKLM 2;
|
|
XZWB N 2 A_StartSound("hellblazer/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
|
XZWB OPQRSTU 2;
|
|
Goto Ready_G;
|
|
}
|
|
}
|