flak_m/zscript/sniperrifle.zsc
Marisa Kirisame cbb498378e Removal of all RNG damage (excluding minigun).
Enhanced Shock Rifle is now actually instakill as it's meant to be.
Enhanced Shock Rifle is disabled by default for deathmatch (toggleable).
Implemented Instagib Deathmatch through flak_instagib cvar.
Fixed a small typo in the modeldef entry of the enhanced shock ball shockwave.
2019-04-07 21:37:24 +02:00

257 lines
6.4 KiB
Text

Class RifleAmmo : Ammo
{
Default
{
Tag "Box of Rifle Rounds";
Inventory.PickupMessage "You picked up a Box of Rifle Rounds.";
Inventory.Amount 10;
Inventory.MaxAmount 50;
Ammo.BackpackAmount 20;
Ammo.BackpackMaxAmount 100;
Ammo.DropAmount 5;
}
States
{
Spawn:
SBOX A -1;
Stop;
}
}
Class RifleAmmo2 : RifleAmmo
{
Default
{
Tag "Rifle Round";
Inventory.PickupMessage "You got a Rifle Round.";
Inventory.Amount 1;
Ammo.DropAmount 1;
+INVENTORY.IGNORESKILL;
}
States
{
Spawn:
SRND A -1;
Stop;
}
}
Class SniperLight : EnforcerLight
{
Default
{
args 255,224,64,120;
}
}
Class SniperRifle : UTWeapon
{
double sniperzoom;
TextureID reticle;
override void PostBeginPlay()
{
Super.PostBeginPlay();
reticle = TexMan.CheckForTexture("RReticle",Texman.Type_Any);
}
override void PreRender( double lbottom )
{
if ( sniperzoom <= 1.0 ) return;
Screen.DrawTexture(reticle,false,320,240,DTA_VirtualWidth,640,DTA_VirtualHeight,480,DTA_RenderStyle,(1|2<<8|1<<16));
Screen.DrawText(confont,Font.CR_DARKGREEN,192,160,String.Format("X%.1f",sniperzoom),DTA_Clean,true);
}
override void Tick()
{
Super.Tick();
if ( !Owner ) return;
if ( sniperzoom > 1.0 ) crosshair = 99;
else crosshair = 0;
}
action void A_SniperFire( bool zoomed = false )
{
Weapon weap = Weapon(invoker);
if ( !weap ) return;
if ( weap.Ammo1.Amount <= 0 ) return;
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
invoker.FireEffect();
UTMainHandler.DoFlash(self,Color(32,0,0,255),1);
A_PlaySound("sniper/fire",CHAN_WEAPON);
A_AlertMonsters();
if ( zoomed )
{
A_QuakeEx(2,2,2,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.09);
for ( int i=0; i<3; i++ )
UTMainHandler.DoSwing(self,(FRandom[Sniper](-0.3,0.05),FRandom[Sniper](-0.3,0.1)),2,-0.5,Random[Sniper](3,4),SWING_Spring,Random[Sniper](3,4),Random[Sniper](4,5));
}
else
{
A_QuakeEx(3,3,3,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.12);
for ( int i=0; i<3; i++ )
UTMainHandler.DoSwing(self,(FRandom[Sniper](-0.3,0.05),FRandom[Sniper](-0.3,0.1)),4,-1,Random[Sniper](3,4),SWING_Spring,Random[Sniper](3,4),Random[Sniper](4,5));
A_Overlay(-2,"MuzzleFlash");
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
A_OverlayRenderstyle(-2,STYLE_Add);
}
let l = Spawn("SniperLight",pos);
l.target = self;
Vector3 x, y, z;
[x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll);
Vector3 origin = Vec2OffsetZ(0,0,player.viewz)+10.0*x;
if ( !zoomed ) origin = origin+y*4.0-z*2.0;
FLineTraceData d;
LineTrace(angle,10000,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType == TRACE_HitActor )
{
int dmg = 45;
if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.81) )
{
dmg = d.HitActor.DamageMobj(invoker,self,100,'Decapitated',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,35000);
}
else
{
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,30000);
}
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("BulletImpact",d.HitLocation);
p.scale *= 1.5;
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 ) hitnormal = d.HitSector.floorplane.Normal;
else if ( d.HitType == TRACE_HitCeiling ) 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 *= 1.5;
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);
}
for ( int i=0; i<24; i++ )
{
let s = Spawn("UTStaticViewSmoke",origin);
UTViewSmoke(s).ofs = (10,1,-1);
UTViewSmoke(s).vvel += (FRandom[Sniper](-0.05,0.15),FRandom[Sniper](-0.4,0.4),FRandom[Sniper](-0.1,0.1));
s.target = self;
s.scale *= 1.8;
s.alpha *= 0.3;
}
origin += x*8.0+y*6.0-z*9.0;
let c = Spawn("UTCasing",origin);
c.scale *= 1.25;
c.vel = x*FRandom[Junk](-1.5,1.5)+y*FRandom[Junk](2,4)+z*FRandom[Junk](2,3);
}
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
{
if ( mod == 'Decapitated' ) return "%k put a bullet through %o's head.";
return Obituary;
}
Default
{
Tag "Sniper Rifle";
Obituary "%k put a bullet through %o.";
Inventory.PickupMessage "You got the Sniper Rifle.";
Weapon.UpSound "sniper/select";
Weapon.SlotNumber 0;
Weapon.SelectionOrder 5;
Weapon.AmmoType "RifleAmmo";
Weapon.AmmoUse 1;
Weapon.AmmoType2 "RifleAmmo";
Weapon.AmmoUse2 1;
Weapon.AmmoGive 8;
Weapon.Kickback 250;
UTWeapon.DropAmmo 2;
+NOEXTREMEDEATH;
}
States
{
Spawn:
SRFP A -1;
Stop;
SRFP B -1;
Stop;
Select:
SRFS A 1 A_Raise(int.max);
Wait;
Ready:
SRFS A 1
{
A_ZoomFactor(invoker.sniperzoom=1.0,ZOOM_INSTANT);
A_WeaponReady(WRF_NOFIRE);
}
SRFS BCDEFGHIJKLMNOPQ 1 A_WeaponReady(WRF_NOFIRE);
Idle:
SRFI A 1
{
A_CheckReload();
A_WeaponReady();
}
Wait;
ZoomedIdle:
TNT1 A 1
{
A_CheckReload();
A_WeaponReady();
}
Wait;
Fire:
SRFI A 0 A_JumpIf(invoker.sniperzoom>1.0,"ZoomedFire");
SRFI A 0
{
A_SniperFire();
return A_Jump(256,1,11,21,31,41);
}
Goto Idle;
SRF1 ABCDEFGHIJ 2;
Goto Idle;
SRF2 ABCDEFGHIJ 2;
Goto Idle;
SRF3 ABCDEFGHIJ 2;
Goto Idle;
SRF4 ABCDEFGHIJ 2;
Goto Idle;
SRF5 ABCDEFGHIJ 2;
Goto Idle;
ZoomedFire:
TNT1 A 20 A_SniperFire(true);
Goto ZoomedIdle;
AltFire:
SRFI A 0 A_JumpIf(invoker.sniperzoom>1.0,"AltHold2");
AltHold:
TNT1 A 1
{
if ( invoker.sniperzoom <= 8.0 )
A_ZoomFactor(invoker.sniperzoom*=1.1);
invoker.sniperzoom = min(invoker.sniperzoom,8.1);
}
TNT1 A 0 A_Refire("AltHold");
Goto ZoomedIdle;
AltHold2:
SRFI A 1 A_ZoomFactor(invoker.sniperzoom=1.0,ZOOM_INSTANT);
SRFI A 0 A_Refire("AltHold2");
Goto Idle;
Deselect:
SRFD A 0 A_ZoomFactor(invoker.sniperzoom=1.0,ZOOM_INSTANT);
SRFD ABCDEFG 1;
SRFD G 1 A_Lower(int.max);
Wait;
MuzzleFlash:
SMUZ A 3 Bright;
Stop;
}
}