stinger_m/zscript/uminigun.zsc
Marisa Kirisame 40a48f6a27 Added nicer looking glass to the Biorifle model.
Fix minigun breakage when tapping fire.
Updated Blender project files to 2.8.
Update for new DT backpack mesh.
2019-09-12 14:59:11 +02:00

231 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.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;
}
}