Switched Impaler fire sound to something more appropriate (proto Skaarj fire). Add slot priorities to all weapons, final weapons come first. Adjust hud behavior to properly draw ammo bars by the order of their weapons.
232 lines
6.3 KiB
Text
232 lines
6.3 KiB
Text
Class UMiniAmmo : Ammo
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_MINIAMMO";
|
|
Inventory.Icon "I_ShellA";
|
|
Inventory.PickupMessage "";
|
|
Inventory.Amount 50;
|
|
Inventory.MaxAmount 200;
|
|
Ammo.BackpackAmount 100;
|
|
Ammo.BackpackMaxAmount 400;
|
|
Ammo.DropAmount 20;
|
|
}
|
|
override String PickupMessage()
|
|
{
|
|
if ( PickupMsg.Length() > 0 ) return Super.PickupMessage();
|
|
return String.Format("%s%d%s",StringTable.Localize("$I_MINIAMMOL"),Amount,StringTable.Localize("$I_MINIAMMOR"));
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
MAMO A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UMinigun : UnrealWeapon
|
|
{
|
|
int bcnt, tcnt;
|
|
|
|
action void A_FireBullet( bool alt = false )
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( weap.Ammo1.Amount <= 0 ) return;
|
|
A_Overlay(-2,"MuzzleFlash",true);
|
|
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
|
|
A_OverlayRenderstyle(-2,STYLE_Add);
|
|
invoker.bcnt++;
|
|
if ( (alt && (invoker.bcnt < 2)) || (!alt && (invoker.bcnt < 4)) ) return;
|
|
invoker.bcnt = 0;
|
|
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
|
invoker.FireEffect();
|
|
UTMainHandler.DoFlash(self,Color(32,255,255,0),1);
|
|
if ( !Dampener.Active(self) ) A_AlertMonsters();
|
|
A_SoundVolume(CHAN_WEAPON,Dampener.Active(self)?.1:1.);
|
|
if ( alt )
|
|
{
|
|
A_QuakeEx(2,2,2,8,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.12);
|
|
UTMainHandler.DoSwing(self,(FRandom[Minigun](-1,1),FRandom[Minigun](-1,1)),0.5,0,1,SWING_Spring,0,3);
|
|
}
|
|
else
|
|
{
|
|
A_QuakeEx(1,1,1,8,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.08);
|
|
UTMainHandler.DoSwing(self,(FRandom[Minigun](-1,1),FRandom[Minigun](-1,1)),0.3,0,1,SWING_Spring,0,3);
|
|
}
|
|
let l = Spawn("MinigunLight",pos);
|
|
l.target = self;
|
|
if ( !alt ) MinigunLight(l).cnt--;
|
|
Vector3 x, y, z, x2, y2, z2;
|
|
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = pos+(0,0,player.viewheight)+10.0*x+y*3.0-z*3.0;
|
|
double a = FRandom[Minigun](0,360), s = FRandom[Minigun](0,alt?0.05:0.02);
|
|
[x2, y2, z2] = dt_CoordUtil.GetAxes(BulletSlope(),angle,roll);
|
|
Vector3 dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
|
|
FLineTraceData d;
|
|
LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
|
if ( d.HitType == TRACE_HitActor )
|
|
{
|
|
int dmg = Random[Minigun](8,14); // fun fact: the Minigun is one of the few weapons that has actual RNG damage in Unreal
|
|
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
|
|
double mm = 500;
|
|
if ( FRandom[Minigun](0,1) < 0.2 ) mm *= 2.;
|
|
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,dmg*mm);
|
|
if ( d.HitActor.bNOBLOOD )
|
|
{
|
|
let p = Spawn("BulletImpact",d.HitLocation);
|
|
p.scale *= 0.75;
|
|
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
|
|
p.pitch = asin(d.HitDir.z);
|
|
}
|
|
else
|
|
{
|
|
d.HitActor.TraceBleed(dmg,self);
|
|
d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg);
|
|
}
|
|
}
|
|
else if ( d.HitType != TRACE_HitNone )
|
|
{
|
|
Vector3 hitnormal = -d.HitDir;
|
|
if ( d.HitType == TRACE_HitFloor )
|
|
{
|
|
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
|
|
else hitnormal = d.HitSector.floorplane.Normal;
|
|
}
|
|
else if ( d.HitType == TRACE_HitCeiling )
|
|
{
|
|
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
|
|
else hitnormal = d.HitSector.ceilingplane.Normal;
|
|
}
|
|
else if ( d.HitType == TRACE_HitWall )
|
|
{
|
|
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
|
|
if ( !d.LineSide ) hitnormal *= -1;
|
|
}
|
|
let p = Spawn("BulletImpact",d.HitLocation+hitnormal*0.01);
|
|
p.scale *= 0.75;
|
|
p.angle = atan2(hitnormal.y,hitnormal.x);
|
|
p.pitch = asin(-hitnormal.z);
|
|
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
|
|
}
|
|
if ( !Random[Minigun](0,1) )
|
|
{
|
|
let t = Spawn("MinigunTracer",origin+x*20.0);
|
|
t.angle = atan2(dir.y,dir.x);
|
|
t.pitch = asin(-dir.z);
|
|
MinigunTracer(t).dest = d.HitLocation;
|
|
}
|
|
for ( int i=0; i<2; i++ )
|
|
{
|
|
let s = Spawn("UTViewSmoke",origin);
|
|
UTViewSmoke(s).ofs = (10,3,-3);
|
|
s.scale *= 1.5;
|
|
s.alpha *= 0.6;
|
|
UTViewSmoke(s).vvel += (FRandom[Minigun](0.2,0.8),FRandom[Minigun](-0.3,0.3),FRandom[Minigun](-0.3,0.3));
|
|
s.target = self;
|
|
}
|
|
origin += x*4.0+y*3.0-z*12.0;
|
|
let c = Spawn("UCasing",origin);
|
|
c.vel = x*FRandom[Junk](-1.5,1.5)-y*FRandom[Junk](2,4)+z*FRandom[Junk](-2,1);
|
|
}
|
|
|
|
action void A_MinigunRefire()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap || !player ) return;
|
|
if ( weap.Ammo1.Amount <= 0 )
|
|
{
|
|
A_ClearRefire();
|
|
return;
|
|
}
|
|
weap.bAltFire = !!(player.cmd.buttons&BT_ALTATTACK);
|
|
A_Refire("Hold");
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_MINIGUN";
|
|
Inventory.PickupMessage "$I_MINIGUN";
|
|
Weapon.UpSound "minigun/select";
|
|
Weapon.SlotNumber 0;
|
|
Weapon.SelectionOrder 10;
|
|
Weapon.SlotPriority 1;
|
|
Weapon.AmmoType "UMiniAmmo";
|
|
Weapon.AmmoUse 1;
|
|
Weapon.AmmoType2 "UMiniAmmo";
|
|
Weapon.AmmoUse2 1;
|
|
Weapon.AmmoGive 50;
|
|
UTWeapon.DropAmmo 25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
MGNP A -1;
|
|
Stop;
|
|
MGNP B -1;
|
|
Stop;
|
|
Select:
|
|
MGNS A 1 A_Raise(int.max);
|
|
Wait;
|
|
Ready:
|
|
MGNS ABCDEFGHIJKLMNOPQRSTUVW 1 A_WeaponReady(WRF_NOFIRE);
|
|
Idle:
|
|
MGNI A 1
|
|
{
|
|
A_CheckReload();
|
|
A_WeaponReady();
|
|
}
|
|
Wait;
|
|
FireDummy:
|
|
TNT1 A 1
|
|
{
|
|
let weap = Weapon(invoker);
|
|
if ( !(player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK)) || (weap.Ammo1.Amount <= 0) )
|
|
{
|
|
player.SetPSprite(PSP_WEAPON,invoker.FindState("Release"));
|
|
return ResolveState("Null");
|
|
}
|
|
return ResolveState(null);
|
|
}
|
|
Wait;
|
|
Fire:
|
|
AltFire:
|
|
MGNW A 0 A_PlaySound("umini/wind",CHAN_WEAPON,Dampener.Active(self)?.1:1.);
|
|
MGNW ABCDEFGHIJKLMNO 1;
|
|
MGNW O 0 A_Refire(1);
|
|
Goto Release;
|
|
Hold:
|
|
MGNF A 0
|
|
{
|
|
A_Overlay(-9999,"FireDummy");
|
|
A_PlaySound("umini/fire",CHAN_WEAPON,Dampener.Active(self)?.1:1.,true);
|
|
}
|
|
MGNF ABCDEFGHIJKLMNO 1 A_FireBullet(false);
|
|
MGNF A 0 A_JumpIf(invoker.bAltFire,1);
|
|
Goto Hold+1;
|
|
AltHold:
|
|
MGNA A 0
|
|
{
|
|
A_Overlay(-9999,"FireDummy");
|
|
A_PlaySound("umini/altfire",CHAN_WEAPON,Dampener.Active(self)?.1:1.,true);
|
|
}
|
|
MGNA ABCDEFGHIJKLMNOPQRST 1 A_FireBullet(true);
|
|
Goto AltHold+1;
|
|
Release:
|
|
MGNU A 0 A_PlaySound("umini/unwind",CHAN_WEAPON,Dampener.Active(self)?.1:1.);
|
|
MGNU ABCDEFGHIJKLMNO 2 A_MinigunRefire();
|
|
Goto Idle;
|
|
Deselect:
|
|
MGND A 0 A_StopSound(CHAN_WEAPON);
|
|
MGND ABCDEFGHIJ 1;
|
|
MGND J 1 A_Lower(int.max);
|
|
Wait;
|
|
MuzzleFlash:
|
|
MMUZ # 2 Bright
|
|
{
|
|
let psp = player.FindPSprite(OverlayID());
|
|
psp.frame = Random[Minigun](0,8);
|
|
}
|
|
Stop;
|
|
}
|
|
}
|