Hellblazer burst fire + lock-on.

This commit is contained in:
Mari the Deer 2021-05-09 02:36:46 +02:00
commit 9bd7670ce0
19 changed files with 528 additions and 47 deletions

View file

@ -95,11 +95,52 @@ Class Hellblazer : SWWMWeapon
ui Class<Ammo> lastammo;
int spinskipped;
HellblazerXSub pickuprockets[6];
int preload; // additional loaded missiles (up to 2)
Actor seektarget[3];
int seekcnt;
int preloadcnt;
Property ClipCount : clipcount;
transient ui TextureID WeaponBox, AmmoIcon[4], LoadedIcon[4];
transient ui TextureID WeaponBox, AmmoIcon[4], LoadedIcon[4], LockIcon[4];
transient ui Font TewiFont;
transient ui SWWMProjectionData projdata;
override void RenderUnderlay( RenderEvent e )
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
if ( !LockIcon[0] )
{
LockIcon[0] = TexMan.CheckForTexture("graphics/HUD/HellblazerMissileLock.png",TexMan.Type_Any);
LockIcon[1] = TexMan.CheckForTexture("graphics/HUD/HellblazerCrackshotLock.png",TexMan.Type_Any);
LockIcon[2] = TexMan.CheckForTexture("graphics/HUD/HellblazerRavagerLock.png",TexMan.Type_Any);
LockIcon[3] = TexMan.CheckForTexture("graphics/HUD/HellblazerWarheadLock.png",TexMan.Type_Any);
}
int curtype = 0;
for ( int i=0; i<4; i++ )
{
if ( loadammo != types[i] ) continue;
curtype = i;
break;
}
SWWMUtility.PrepareProjData(projdata,e.ViewPos,e.ViewAngle,e.ViewPitch,e.ViewRoll,players[consoleplayer].fov);
int cliptop = projdata.viewy, clipbottom = projdata.viewy+projdata.viewh,
clipleft = projdata.viewx, clipright = projdata.viewx+projdata.vieww;
Vector2 hs;
if ( swwm_hudscale <= 0 ) hs = StatusBar.GetHUDScale();
else hs.x = swwm_hudscale;
hs.y = hs.x;
Vector2 ss = (Screen.GetWidth()/hs.x,Screen.GetHeight()/hs.y);
for ( int i=0; i<3; i++ )
{
if ( !seektarget[i] ) continue;
Vector3 tpos = seektarget[i].prev*(1.-e.FracTic)+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 > 1. ) continue;
Vector2 vpos = SWWMUtility.NDCToViewport(projdata,ndc);
Screen.DrawTexture(LockIcon[curtype],false,vpos.x/hs.x,vpos.y/hs.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_CenterOffset,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
}
override void DrawWeapon( double TicFrac, double bx, double by, Vector2 hs, Vector2 ss )
{
@ -148,7 +189,7 @@ Class Hellblazer : SWWMWeapon
xx = -54;
for ( int i=0; i<6; i++ )
{
Screen.DrawTexture(LoadedIcon[0],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i==magpos)?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
Screen.DrawTexture(LoadedIcon[0],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,((i<=magpos)&&(i>=(magpos-preload)))?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
xx += 9;
}
break;
@ -156,7 +197,7 @@ Class Hellblazer : SWWMWeapon
xx = -49;
for ( int i=0; i<3; i++ )
{
Screen.DrawTexture(LoadedIcon[1],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i==magpos)?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
Screen.DrawTexture(LoadedIcon[1],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,((i<=magpos)&&(i>=(magpos-preload)))?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
xx += 18;
}
break;
@ -164,7 +205,7 @@ Class Hellblazer : SWWMWeapon
xx = -49;
for ( int i=0; i<3; i++ )
{
Screen.DrawTexture(LoadedIcon[2],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i==magpos)?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
Screen.DrawTexture(LoadedIcon[2],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,((i<=magpos)&&(i>=(magpos-preload)))?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
xx += 18;
}
break;
@ -172,7 +213,7 @@ Class Hellblazer : SWWMWeapon
xx = -45;
for ( int i=0; i<2; i++ )
{
Screen.DrawTexture(LoadedIcon[3],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i==magpos)?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
Screen.DrawTexture(LoadedIcon[3],false,bx+xx,by+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,((i<=magpos)&&(i>=(magpos-preload)))?magstate[i]?Color(192,0,0,0):Color(0,0,0,0):magstate[i]?Color(224,0,0,0):Color(96,0,0,0),DTA_Desaturate,magstate[i]?192:0);
xx += 27;
}
break;
@ -213,7 +254,7 @@ Class Hellblazer : SWWMWeapon
A_BumpFOV(bAlt?.96:.93);
A_PlayerFire();
invoker.clipcount = max(0,invoker.clipcount-1);
invoker.magstate[invoker.magpos] = true;
invoker.magstate[invoker.magpos-invoker.preload] = true;
invoker.spinskipped++;
Vector3 x, y, z, x2, y2, z2, dir, origin;
double a, s;
@ -226,6 +267,9 @@ Class Hellblazer : SWWMWeapon
dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
let p = Spawn(projs[type+4*bAlt],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;
@ -373,7 +417,7 @@ Class Hellblazer : SWWMWeapon
action void A_ZoomHold()
{
A_WeaponReady(WRF_NOFIRE);
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
if ( player.cmd.buttons&BT_ZOOM ) return;
player.SetPSPrite(PSP_WEAPON,invoker.FindState("Ready"));
}
@ -435,9 +479,14 @@ Class Hellblazer : SWWMWeapon
{
static const Class<Ammo> types[] = {"HellblazerMissiles","HellblazerCrackshots","HellblazerRavagers","HellblazerWarheads"};
static const int magcap[] = {6,3,3,2};
for ( int i=0; i<3; i++ ) invoker.seektarget[i] = null;
for ( int i=0; i<4; i++ )
{
if ( invoker.loadammo != types[i] ) continue;
// 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)%magcap[i];
invoker.spinskipped = 0;
break;
@ -470,6 +519,70 @@ Class Hellblazer : SWWMWeapon
SetState(SpawnState+curtype+1);
}
action void A_CheckLockOn()
{
if ( invoker.seekcnt > invoker.preload ) return;
Vector3 x, y, z, x2, y2, z2, dir;
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x);
// try to catch target in cone of vision
[x2, y2, z2] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
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 = (x2+y2*cos(j)*i+z2*sin(j)*i).unit();
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 x2) < (dir dot x2) )
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 x2);
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 Travelled()
{
Super.Travelled();
@ -584,22 +697,62 @@ Class Hellblazer : SWWMWeapon
XZWL S 1;
Wait;
Fire:
XZW2 A 0
#### # 0
{
invoker.preloadcnt = 0;
invoker.preload = 0;
}
#### # 1
{
if ( invoker.clipcount <= 0 )
{
if ( CountInv(invoker.nextammo) <= 0 ) A_PickNextAmmo();
return A_JumpByAmmoType("Unload_1","Unload_2","Unload_3","Unload_4","Unload_G");
}
if ( player.cmd.buttons&BT_ATTACK )
{
if ( (player.cmd.buttons&BT_ALTATTACK) || (invoker.clipcount < 2) )
return A_JumpByAmmoType("PreFire_1","PreFire_2","PreFire_3","PreFire_4","Ready_G");
invoker.preloadcnt++;
if ( invoker.preloadcnt >= 10 )
{
invoker.preloadcnt = 0;
return A_JumpByAmmoType("PreLoad_1","PreLoad_2","PreFire_3","PreFire_4","Ready_G");
}
return ResolveState(null);
}
return A_JumpByAmmoType("Fire_1","Fire_2","Fire_3","Fire_4","Fire_G");
}
Wait;
Fire_1:
XZW2 A 1 A_HellblazerFire(0);
XZW2 QRSTUVW 2;
XZW2 A 0
{
// chain-fire
if ( invoker.preload > 0 )
{
invoker.preload--;
invoker.spinskipped--;
return A_JumpByAmmoType("Fire_1","Fire_2","Fire_3","Fire_4","Fire_G");
}
return ResolveState(null);
}
Goto Cycle_1;
Fire_2:
XZW6 V 1 A_HellblazerFire(1);
XZW7 LMNOPQR 2;
XZW6 V 0
{
// chain-fire
if ( invoker.preload > 0 )
{
invoker.preload--;
invoker.spinskipped--;
return A_JumpByAmmoType("Fire_1","Fire_2","Fire_3","Fire_4","Fire_G");
}
return ResolveState(null);
}
Goto Cycle_2;
Fire_3:
XZWB T 1 A_HellblazerFire(2);
@ -614,23 +767,63 @@ Class Hellblazer : SWWMWeapon
XZWM IJKLMNO 2;
Goto Ready_G; // state jump to cycling is done elsewhere
AltFire:
XZW2 A 0
#### # 0
{
invoker.preloadcnt = 0;
invoker.preload = 0;
}
#### # 1
{
if ( invoker.clipcount <= 0 )
{
if ( CountInv(invoker.nextammo) <= 0 ) A_PickNextAmmo();
return A_JumpByAmmoType("Unload_1","Unload_2","Unload_3","Unload_4","Unload_G");
}
if ( player.cmd.buttons&BT_ALTATTACK )
{
if ( (player.cmd.buttons&BT_ATTACK) || (invoker.clipcount < 2) )
return A_JumpByAmmoType("PreAltFire_1","PreAltFire_2","PreAltFire_3","PreAltFire_4","Ready_G");
invoker.preloadcnt++;
if ( invoker.preloadcnt >= 10 )
{
invoker.preloadcnt = 0;
return A_JumpByAmmoType("PreAltLoad_1","PreAltLoad_2","PreAltFire_3","PreAltFire_4","Ready_G");
}
return ResolveState(null);
}
return A_JumpByAmmoType("AltFire_1","AltFire_2","AltFire_3","AltFire_4","AltFire_G");
}
Wait;
AltFire_1:
XZW2 A 1 A_HellblazerFire(0,true);
XZW2 XYZ 2;
XZW3 ABCD 2;
XZW2 A 0
{
// chain-fire
if ( invoker.preload > 0 )
{
invoker.preload--;
invoker.spinskipped--;
return A_JumpByAmmoType("AltFire_1","AltFire_2","AltFire_3","AltFire_4","AltFire_G");
}
return ResolveState(null);
}
Goto Cycle_1;
AltFire_2:
XZW6 V 1 A_HellblazerFire(1,true);
XZW7 STUVWXY 2;
XZW6 V 0
{
// chain-fire
if ( invoker.preload > 0 )
{
invoker.preload--;
invoker.spinskipped--;
return A_JumpByAmmoType("AltFire_1","AltFire_2","AltFire_3","AltFire_4","AltFire_G");
}
return ResolveState(null);
}
Goto Cycle_2;
AltFire_3:
XZWB T 1 A_HellblazerFire(2,true);
@ -644,6 +837,264 @@ Class Hellblazer : SWWMWeapon
XZWL S 1;
XZWM PQRSTUV 2;
Goto Ready_G; // state jump to cycling is done elsewhere
PreLoad_1:
XZW2 A 10 A_StartSound("hellblazer/preload",CHAN_WEAPON,CHANF_OVERLAP);
XZW2 A 2
{
invoker.spinskipped--;
invoker.magpos = (invoker.magpos+1)%6;
invoker.preload++;
A_GlassOverlay("Cycle_G1");
}
XZW3 E 2;
XZW3 FGHI 2;
XZW3 I 0;
XZW3 FE 2;
XZW2 A 1
{
if ( !(player.cmd.buttons&BT_ATTACK) )
return A_JumpByAmmoType("Fire_1","Fire_2","Fire_3","Fire_4","Fire_G");
if ( (player.cmd.buttons&BT_ALTATTACK) || (invoker.preload >= min(invoker.clipcount-1,2)) )
return A_JumpByAmmoType("PreFire_1","PreFire_2","PreFire_3","PreFire_4","Ready_G");
return ResolveState("PreLoad_1");
}
Wait;
PreLoad_2:
XZW6 V 10 A_StartSound("hellblazer/preload",CHAN_WEAPON,CHANF_OVERLAP);
XZW6 V 2
{
invoker.spinskipped--;
invoker.magpos = (invoker.magpos+1)%3;
invoker.preload++;
A_GlassOverlay("Cycle_G2");
}
XZW7 Z 2;
XZW8 ABCDEFG 2;
XZW8 G 0;
XZW8 A 2;
XZW7 Z 2;
XZW6 V 1
{
if ( !(player.cmd.buttons&BT_ATTACK) )
return A_JumpByAmmoType("Fire_1","Fire_2","Fire_3","Fire_4","Fire_G");
if ( (player.cmd.buttons&BT_ALTATTACK) || (invoker.preload >= min(invoker.clipcount-1,2)) )
return A_JumpByAmmoType("PreFire_1","PreFire_2","PreFire_3","PreFire_4","Ready_G");
return ResolveState("PreLoad_2");
}
Wait;
PreAltLoad_1:
XZW2 A 10 A_StartSound("hellblazer/preload",CHAN_WEAPON,CHANF_OVERLAP);
XZW2 A 2
{
invoker.spinskipped--;
invoker.magpos = (invoker.magpos+1)%6;
invoker.preload++;
A_GlassOverlay("Cycle_G1");
}
XZW3 E 2;
XZW3 FGHI 2;
XZW3 I 0;
XZW3 FE 2;
XZW2 A 1
{
if ( !(player.cmd.buttons&BT_ALTATTACK) )
return A_JumpByAmmoType("AltFire_1","AltFire_2","AltFire_3","AltFire_4","AltFire_G");
if ( (player.cmd.buttons&BT_ATTACK) || (invoker.preload >= min(invoker.clipcount-1,2)) )
return A_JumpByAmmoType("PreAltFire_1","PreAltFire_2","PreAltFire_3","PreAltFire_4","Ready_G");
return ResolveState("PreAltLoad_1");
}
Wait;
PreAltLoad_2:
XZW6 V 10 A_StartSound("hellblazer/preload",CHAN_WEAPON,CHANF_OVERLAP);
XZW6 V 2
{
invoker.spinskipped--;
invoker.magpos = (invoker.magpos+1)%3;
invoker.preload++;
A_GlassOverlay("Cycle_G2");
}
XZW7 Z 2;
XZW8 ABCDEFG 2;
XZW8 G 0;
XZW8 A 2;
XZW7 Z 2;
XZW6 V 1
{
if ( !(player.cmd.buttons&BT_ALTATTACK) )
return A_JumpByAmmoType("AltFire_1","AltFire_2","AltFire_3","AltFire_4","AltFire_G");
if ( (player.cmd.buttons&BT_ATTACK) || (invoker.preload >= min(invoker.clipcount-1,2)) )
return A_JumpByAmmoType("PreAltFire_1","PreAltFire_2","PreAltFire_3","PreAltFire_4","Ready_G");
return ResolveState("PreAltLoad_2");
}
Wait;
PreFire_1:
XZW2 A 0
{
invoker.seekcnt = 0;
}
XZW2 A 1
{
if ( !(player.cmd.buttons&BT_ATTACK) )
return A_JumpByAmmoType("Fire_1","Fire_2","Fire_3","Fire_4","Fire_G");
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
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;
PreFire_2:
XZW6 V 0
{
invoker.seekcnt = 0;
}
XZW6 V 1
{
if ( !(player.cmd.buttons&BT_ATTACK) )
return A_JumpByAmmoType("Fire_1","Fire_2","Fire_3","Fire_4","Fire_G");
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
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;
PreFire_3:
XZWB T 0
{
invoker.seekcnt = 0;
}
XZWB T 1
{
if ( !(player.cmd.buttons&BT_ATTACK) )
return A_JumpByAmmoType("Fire_1","Fire_2","Fire_3","Fire_4","Fire_G");
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
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;
PreFire_4:
XZWG R 0
{
invoker.seekcnt = 0;
}
XZWG R 1
{
if ( !(player.cmd.buttons&BT_ATTACK) )
return A_JumpByAmmoType("Fire_1","Fire_2","Fire_3","Fire_4","Fire_G");
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
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_1:
XZW2 A 0
{
invoker.seekcnt = 0;
}
XZW2 A 1
{
if ( !(player.cmd.buttons&BT_ALTATTACK) )
return A_JumpByAmmoType("AltFire_1","AltFire_2","AltFire_3","AltFire_4","AltFire_G");
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
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_2:
XZW6 V 0
{
invoker.seekcnt = 0;
}
XZW6 V 1
{
if ( !(player.cmd.buttons&BT_ALTATTACK) )
return A_JumpByAmmoType("AltFire_1","AltFire_2","AltFire_3","AltFire_4","AltFire_G");
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
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_3:
XZWB T 0
{
invoker.seekcnt = 0;
}
XZWB T 1
{
if ( !(player.cmd.buttons&BT_ALTATTACK) )
return A_JumpByAmmoType("AltFire_1","AltFire_2","AltFire_3","AltFire_4","AltFire_G");
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
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_4:
XZWG R 0
{
invoker.seekcnt = 0;
}
XZWG R 1
{
if ( !(player.cmd.buttons&BT_ALTATTACK) )
return A_JumpByAmmoType("AltFire_1","AltFire_2","AltFire_3","AltFire_4","AltFire_G");
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
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_1:
XZW2 A 2
{
@ -849,7 +1300,7 @@ Class Hellblazer : SWWMWeapon
#### # 1
{
A_PickNextAmmo();
A_WeaponReady(WRF_NOFIRE);
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
}
#### # 1 A_ZoomHold();
Wait;

View file

@ -236,6 +236,8 @@ Class HellblazerFlare : Actor
Class HellblazerMissile : Actor
{
int deto;
Actor seektarget;
Vector3 InitialDir, Acceleration;
Default
{
@ -281,12 +283,38 @@ Class HellblazerMissile : Actor
let t = Spawn("HellblazerTrail",level.Vec3Offset(pos,-vel.unit()*i+traildir*3));
t.vel = traildir*4.;
}
if ( InitialDir.length() < double.epsilon ) InitialDir = vel.unit();
vel += Acceleration/GameTicRate;
Vector3 dir = vel.unit();
if ( vel.length() > 50. ) vel = dir*50.;
}
if ( deto > 1 )
{
ExplodeMissile();
return;
}
if ( seektarget )
{
// seek tracer
if ( SWWMUtility.SphereIntersect(seektarget,level.Vec3Offset(pos,vel),bNOGRAVITY?50:90) )
{
deto++;
tracer = seektarget;
return;
}
if ( bNOGRAVITY )
{
Vector3 SeekingDir = level.Vec3Diff(pos,seektarget.Vec3Offset(0,0,seektarget.height/2)).unit();
if ( SeekingDir dot InitialDir > -1 )
{
double MagnitudeVel = Vel.length();
SeekingDir = (SeekingDir*.25*MagnitudeVel+Vel).unit();
Vel = MagnitudeVel*SeekingDir;
Acceleration = 25*SeekingDir;
}
}
return;
}
// proximity check
let bt = BlockThingsIterator.Create(self,200);
while ( bt.Next() )
@ -781,6 +809,16 @@ Mixin Class HellblazerGrenade
rollvel = FRandom[Hellblazer](-16,16);
anglevel = FRandom[Hellblazer](-16,16);
pitchvel = FRandom[Hellblazer](-16,16);
// steer towards seek target
if ( seektarget )
{
Vector3 dirto = level.Vec3Diff(pos,seektarget.Vec3Offset(0,0,seektarget.Height/2));
dirto /= dirto.length();
dirto.z += .1;
double spd = vel.length();
vel /= spd;
vel = (vel*.3+dirto*.7)*spd;
}
}
States
{
@ -950,7 +988,7 @@ Class HellblazerClusterMini : HellblazerMissile2
if ( !whomst ) return;
Vector3 dirto = level.Vec3Diff(pos,whomst.Vec3Offset(0,0,whomst.Height/2));
dirto /= dirto.length();
dirto.z += .3;
dirto.z += .1;
double spd = vel.length();
vel /= spd;
vel = (vel*.3+dirto*.7)*spd;

View file

@ -761,12 +761,12 @@ Class Spreadgun : SWWMWeapon
}
if ( invoker.nextammo != types[next] ) A_StartSound("misc/invchange",CHAN_WEAPONEXTRA,CHANF_UI|CHANF_LOCAL);
invoker.nextammo = types[next];
A_WeaponReady(WRF_NOFIRE);
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
}
action void A_AltHold()
{
A_WeaponReady(WRF_NOFIRE);
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
// tap fire to unload round
if ( invoker.chambered && (player.cmd.buttons&BT_ATTACK) )
{

View file

@ -828,11 +828,11 @@ Class SilverBullet : SWWMWeapon
else if ( !invoker.fcbselected && ((invoker.Ammo2.Amount > 0) || (CountInv("SilverBullets2") > 0)) )
invoker.fcbselected = (ifempty&&((invoker.Ammo1.Amount>0)||(CountInv("SilverBullets")>0)))?false:true;
if ( oldsel != invoker.fcbselected ) A_StartSound("misc/invchange",CHAN_WEAPONEXTRA,CHANF_UI|CHANF_LOCAL);
A_WeaponReady(WRF_NOFIRE);
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
}
action void A_AltHold()
{
A_WeaponReady(WRF_NOFIRE);
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
// tap fire to unload round
if ( player.cmd.buttons&BT_ATTACK )
{