stinger_m/zscript/olsmp.zsc

425 lines
10 KiB
Text

/*
usaar33 is a wiener
now watch as I turn this trash fire into a better weapon
*/
Class OLSMPAmmo : Ammo
{
override bool TryPickup( in out Actor toucher )
{
if ( !sting_olsmp ) return false; // not allowed
return Super.TryPickup(toucher);
}
override void Tick()
{
Super.Tick();
if ( sting_olsmp ) return;
if ( !Owner )
{
let r = Spawn("CellPack",pos,ALLOW_REPLACE);
r.spawnangle = spawnangle;
r.spawnpoint = spawnpoint;
r.angle = angle;
r.pitch = pitch;
r.roll = roll;
r.special = special;
r.args[0] = args[0];
r.args[1] = args[1];
r.args[2] = args[2];
r.args[3] = args[3];
r.args[4] = args[4];
r.ChangeTid(tid);
r.SpawnFlags = SpawnFlags&~MTF_SECRET;
r.HandleSpawnFlags();
r.SpawnFlags = SpawnFlags;
r.bCountSecret = SpawnFlags&MTF_SECRET;
r.vel = vel;
r.master = master;
r.target = target;
r.tracer = tracer;
r.bDropped = bDropped;
r.bNeverRespawn = bNeverRespawn;
}
else Owner.RemoveInventory(self);
Destroy();
}
Default
{
Tag "$T_OLSMPAMMO";
Inventory.Icon "I_OLSMP";
Inventory.PickupMessage "$I_OLSMPAMMO";
Inventory.Amount 100;
Inventory.MaxAmount 300;
Ammo.BackpackAmount 0;
Ammo.BackpackMaxAmount 900;
Ammo.DropAmount 100;
}
States
{
Spawn:
UCLP A -1;
Stop;
}
}
Class OLSMPMag : EnforcerMag
{
}
Class OLSMP : UnrealWeapon
{
int ClipCount;
double AltAccuracy;
bool ClipOut;
property ClipCount : ClipCount;
override int, int, bool, bool GetClipAmount()
{
return ClipOut?-1:ClipCount, -1, (ClipCount<35), false;
}
override bool TryPickup( in out Actor toucher )
{
if ( !sting_olsmp ) return false; // not allowed
return Super.TryPickup(toucher);
}
override void Tick()
{
Super.Tick();
if ( sting_olsmp ) return;
if ( !Owner )
{
let r = Spawn("BFG9000",pos,ALLOW_REPLACE);
r.spawnangle = spawnangle;
r.spawnpoint = spawnpoint;
r.angle = angle;
r.pitch = pitch;
r.roll = roll;
r.special = special;
r.args[0] = args[0];
r.args[1] = args[1];
r.args[2] = args[2];
r.args[3] = args[3];
r.args[4] = args[4];
r.ChangeTid(tid);
r.SpawnFlags = SpawnFlags&~MTF_SECRET;
r.HandleSpawnFlags();
r.SpawnFlags = SpawnFlags;
r.bCountSecret = SpawnFlags&MTF_SECRET;
r.vel = vel;
r.master = master;
r.target = target;
r.tracer = tracer;
r.bDropped = bDropped;
r.bNeverRespawn = bNeverRespawn;
}
else Owner.RemoveInventory(self);
Destroy();
}
override void PlayUpSound( Actor origin )
{
origin.A_StartSound(upsound,CHAN_WEAPON,volume:Dampener.Active(origin)?.1:1.,pitch:0.8);
}
action void A_OLSMPRefire( statelabel flash = null, bool slave = false )
{
Weapon weap = Weapon(invoker);
if ( !weap || !player ) return;
if ( invoker.altaccuracy < 0.2 ) invoker.altaccuracy += 0.01;
if ( invoker.clipcount < 35 ) A_StartSound("automag/click",CHAN_WEAPONMISC,CHANF_OVERLAP,!Dampener.Active(self)?1.:.35,pitch:1.6);
if ( invoker.clipcount <= 0 )
{
A_ClearRefire();
return;
}
A_Refire(flash);
}
action void A_OLSMPFire( bool alt = false )
{
Weapon weap = Weapon(invoker);
if ( !weap ) return;
if ( invoker.clipcount <= 0 ) return;
invoker.clipcount--;
invoker.FireEffect();
UTMainHandler.DoFlash(self,Color(32,255,128,0),1);
A_StartSound("automag/fire",CHAN_WEAPON,CHANF_OVERLAP,!Dampener.Active(self)?1.:.2,pitch:FRandom[Automag](1.2,1.8)*(alt?2.5:1.));
if ( !Dampener.Active(self) ) A_AlertMonsters();
A_QuakeEx(1,1,1,8,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.15);
A_Overlay(-2,"MuzzleFlash");
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
A_OverlayRenderstyle(-2,STYLE_Add);
Vector3 x, y, z, x2, y2, z2;
[x, y, z] = dt_Utility.GetPlayerAxes(self);
if ( alt )
{
vel -= x*(player.onground?2.:0.8);
vel.z += (player.onground?.3:.08);
}
else
{
vel -= x*(player.onground?2.2:1.);
vel.z += (player.onground?.5:.15);
}
Vector3 origin = dt_Utility.GetFireOffset(self,10,-4,-1);
double a = FRandom[Automag](0,360), s = FRandom[Automag](0,alt?(0.05+invoker.altaccuracy):0.05);
[x2, y2, z2] = dt_Utility.GetPlayerAxesAutoAimed(self);
Vector3 dir = dt_Utility.ConeSpread(x2,y2,z2,a,s);
FLineTraceData d;
LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
UTBulletTrail.DoTrail(self,origin,dir,10000,alt?6:4);
if ( d.HitType == TRACE_HitActor )
{
int dmg = 17;
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
double mm = 3000;
if ( FRandom[Automag](0,1) < 0.2 ) mm *= 5;
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,mm);
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("BulletImpact",d.HitLocation);
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.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<3; i++ )
{
let s = Spawn("UTViewSmoke",origin);
UTViewSmoke(s).ofs = (10,-4,-1);
s.target = self;
s.alpha *= 0.5;
}
origin = level.Vec3Offset(origin,x*8-y*6-z*2);
let c = Spawn("UCasing",origin);
c.angle = angle;
c.pitch = pitch;
c.vel = x*FRandom[Junk](-1.5,1.5)-y*FRandom[Junk](2,4)+z*FRandom[Junk](2,3);
}
override bool CheckAmmo( int fireMode, bool autoSwitch, bool requireAmmo, int ammocount )
{
if ( ClipCount > 0 ) return true;
return Super.CheckAmmo(firemode,autoswitch,requireammo,ammocount);
}
Default
{
Tag "$T_OLSMP";
Inventory.PickupMessage "$I_OLSMP";
Weapon.UpSound "automag/select";
Weapon.SlotNumber 0;
Weapon.SelectionOrder 800;
Weapon.SlotPriority 0.95;
Weapon.AmmoType "OLSMPAmmo";
Weapon.AmmoUse 1;
Weapon.AmmoType2 "OLSMPAmmo";
Weapon.AmmoUse2 1;
Weapon.AmmoGive 100;
Weapon.Kickback 320;
UTWeapon.DropAmmo 50;
OLSMP.ClipCount 100;
+UNREALWEAPON.NOFIRSTGIVE;
+INVENTORY.ALWAYSPICKUP;
}
States
{
Spawn:
AUTP A -1;
Stop;
AUTP B -1;
Stop;
Select:
AUTS A 1 A_Raise(int.max);
Ready:
AUTS ABCDEFGHIJKLMNOPQRSTUVWXYZ 1 A_WeaponReady(WRF_NOFIRE);
AUS2 ABCD 1 A_WeaponReady(WRF_NOFIRE);
Idle:
AUTI A 0 A_Overlay(-9999,"Dummy");
AUTI AB 30;
AUTI A 0 A_Jump(50,"Twiddle");
Goto Idle+1;
Twiddle:
AUTT ABCDEFGHIJKLMNOPQRSTUVWXY 2;
Goto Idle+1;
Dummy:
TNT1 A 1
{
A_CheckReload();
if ( (invoker.clipcount <= 0) && (invoker.Ammo1.Amount > 0) ) A_Overlay(PSP_WEAPON,"Reload");
else if ( invoker.clipcount < min(invoker.default.clipcount,invoker.Ammo1.Amount) ) A_WeaponReady(WRF_ALLOWRELOAD);
else A_WeaponReady();
}
Wait;
Fire:
AUTF A 1 A_Overlay(-9999,null);
AUTF BCD 1;
Hold:
AUTF E 1 A_OLSMPFire();
AUTF F 1;
AUTF G 0 A_OLSMPRefire(1);
Goto Release1;
AUTF G 1;
AUTF H 1 A_OLSMPFire();
AUTF I 1;
AUTF J 0 A_OLSMPRefire(1);
Goto Release2;
AUTF J 1;
AUTF K 1 A_OLSMPFire();
AUTF L 1;
AUTF M 0 A_OLSMPRefire(1);
Goto Release3;
AUTF M 1;
Goto Hold;
Release1:
AUTF G 1;
Goto Release;
Release2:
AUTF J 1;
Goto Release;
Release3:
AUTF M 1;
Goto Release;
Release:
AUTF NOPQRST 1;
AUTI A 0;
Goto Idle;
AltFire:
AUTF A 1 A_Overlay(-9999,null);
AUTF BCD 1;
AltHold:
AUTF E 1 A_OLSMPFire(true);
AUTF H 0 A_OLSMPRefire(1);
Goto AltRelease1;
AUTF H 1 A_OLSMPFire(true);
AUTF K 0 A_OLSMPRefire(1);
Goto AltRelease2;
AUTF K 1 A_OLSMPFire(true);
AUTF E 0 A_OLSMPRefire("AltHold");
Goto AltRelease3;
AltRelease1:
AUTF FG 1;
Goto Release;
AltRelease2:
AUTF IJ 1;
Goto Release;
AltRelease3:
AUTF LM 1;
Goto Release;
Reload:
AUTR A 0 A_JumpIf(invoker.clipcount>=min(invoker.default.clipcount,invoker.Ammo1.Amount),"Idle");
AUTR A 0
{
invoker.clipout = true;
A_Overlay(-9999,null);
A_WeaponOffset(0,32); // fix sudden psprite lowering
A_StartSound("automag/click",CHAN_WEAPONMISC,volume:!Dampener.Active(self)?1.:.1,pitch:0.8);
}
AUTR ABCDEFGHIJKLMNOPQRSTUVWXY 1;
AUTD ABCD 1;
AUTD E 30
{
invoker.clipout = false;
let aadd = min(invoker.Ammo1.Amount,invoker.default.clipcount-invoker.clipcount);
invoker.clipcount += aadd;
if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
invoker.Ammo1.Amount -= aadd;
A_StartSound("automag/reload",CHAN_WEAPONMISC,volume:!Dampener.Active(self)?1.:.1,pitch:0.8);
if ( self is 'UTPlayer' )
UTPlayer(self).PlayReloading();
Vector3 x, y, z, origin;
[x,y,z] = dt_Utility.GetPlayerAxes(self);
origin = dt_Utility.GetFireOffset(self,4,-4,-18);
let c = Spawn("OLSMPMag",origin);
c.angle = angle;
c.pitch = pitch;
c.vel = vel*.5+x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](-.5,.5)-z*FRandom[Junk](1,2);
}
AUTS A 0 A_StartSound("automag/select",CHAN_WEAPON,volume:!Dampener.Active(self)?1.:.1,pitch:0.8);
Goto Ready;
Deselect:
AUTD A 1 A_Overlay(-9999,null);
AUTD BCD 1;
AUTD E 1 A_Lower(int.max);
Wait;
MuzzleFlash:
TNT1 A 0 A_Jump(256,1,2,3,4,5,6,7,8,9);
AMUZ A 2 Bright
{
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
AMUZ B 2 Bright
{
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
AMUZ C 2 Bright
{
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
AMUZ D 2 Bright
{
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
AMUZ E 2 Bright
{
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
AMUZ F 2 Bright
{
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
AMUZ G 2 Bright
{
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
AMUZ H 2 Bright
{
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
AMUZ I 2 Bright
{
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
}
}