flak_m/zscript/pulsegun.zsc
Marisa Kirisame 5248ac8fd6 A couple more things, including an ambient glow shader effect, some more item replacements, and menu options.
Damage Amplifier has been implemented. Armor items are being worked on. Powerups will come later, then I'll continue doing more weapons.
2018-05-20 02:10:30 +02:00

545 lines
14 KiB
Text

Class Tier4Ammo : RandomSpawner replaces ClipBox
{
Default
{
DropItem "PulseAmmo", 255, 1;
//DropItem "RipperAmmo", 255, 1;
}
}
Class Tier4Weapon : RandomSpawner replaces Chaingun
{
Default
{
DropItem "PulseGun", 255, 1;
//DropItem "Ripper", 255, 1;
}
}
Class PulseAmmo : Ammo
{
Default
{
Tag "Pulse Cell";
Inventory.PickupMessage "You picked up a Pulse Cell.";
Inventory.Amount 25;
Inventory.MaxAmount 200;
Ammo.BackpackAmount 50;
Ammo.BackpackMaxAmount 400;
Ammo.DropAmount 25;
}
States
{
Spawn:
PAMO A -1;
Stop;
}
}
Class PulseBallLight : DynamicLight
{
double pulseofs;
Default
{
DynamicLight.Type "Point";
Args 64,255,0,10;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
pulseofs = FRandom[Pulse](0,360);
}
override void Tick()
{
Super.Tick();
if ( !target || target.InStateSequence(target.CurState,target.ResolveState("Death")) )
{
Destroy();
return;
}
SetOrigin(target.pos,true);
args[LIGHT_INTENSITY] = 10+sin(gametic*80+pulseofs)*5;
}
}
Class PulseExplLight : DynamicLight
{
double lifetime;
Default
{
DynamicLight.Type "Point";
ReactionTime 20;
Args 64,255,0,30;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
lifetime = 1.0;
}
override void Tick()
{
Super.Tick();
if ( globalfreeze || level.frozen ) return;
args[LIGHT_RED] = 64*lifetime;
args[LIGHT_GREEN] = 255*lifetime;
lifetime -= 1./ReactionTime;
if ( lifetime <= 0 ) Destroy();
}
}
Class PulseBall : Actor
{
Default
{
Obituary "%o ate %k's burning plasma death.";
DamageType 'Pulsed';
RenderStyle "Add";
DamageFunction Random[Pulse](15,25);
PROJECTILE;
Scale 0.2;
Speed 30;
Radius 4;
Height 4;
}
override void PostBeginPlay()
{
A_PlaySound("pulse/fly",CHAN_BODY,0.8,true,8.0);
let l = Spawn("PulseBallLight",pos);
l.target = self;
}
action void A_BallExp()
{
A_SetScale(0.45);
A_PlaySound("pulse/hit",CHAN_BODY);
A_SprayDecal("BoltScorch");
Spawn("PulseExplLight",pos);
int numpt = Random[Pulse](20,40);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Pulse](-1,1),FRandom[Pulse](-1,1),FRandom[Pulse](-1,1)).unit()*FRandom[Pulse](2,4);
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,Random[Pulse](20,40),FRandom[Pulse](2.4,4.8),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-0.1);
A_SpawnParticle("40FF00",SPF_FULLBRIGHT,Random[Pulse](30,50),FRandom[Pulse](4.8,7.2),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-0.1);
}
}
action void A_Trail()
{
if ( Random[Pulse](0,4) ) return;
int numpt = Random[Pulse](2,5);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Pulse](-1,1),FRandom[Pulse](-1,1),FRandom[Pulse](-1,1)).unit()*FRandom[Pulse](2,4);
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,Random[Pulse](10,20),FRandom[Pulse](1.2,2.4),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-0.1);
A_SpawnParticle("40FF00",SPF_FULLBRIGHT,Random[Pulse](15,25),FRandom[Pulse](2.4,3.6),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-0.1);
}
}
States
{
Spawn:
PBAL ABCDE 1 Bright A_Trail();
Loop;
Death:
TNT1 A 0 A_BallExp();
PBAL ABCDE 3 Bright;
Stop;
}
}
Class PulseBoltLight : DynamicLight
{
bool lived;
Default
{
DynamicLight.Type "Point";
Args 64,255,0,50;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
args[LIGHT_INTENSITY] = Random[Pulse](50,60);
}
override void Tick()
{
Super.Tick();
if ( globalfreeze || level.frozen ) return;
if ( lived ) Destroy();
lived = true;
}
}
Class PulseBoltTracer : LineTracer
{
Actor ignore;
override ETraceStatus TraceCallback()
{
if ( Results.HitType == TRACE_HitActor )
{
if ( Results.HitActor == ignore ) return TRACE_Skip;
if ( Results.HitActor.bSHOOTABLE ) return TRACE_Stop;
return TRACE_Skip;
}
else if ( (Results.HitType == TRACE_HitWall) && (Results.Tier == TIER_Middle) )
{
if ( !Results.HitLine.sidedef[1] || (Results.HitLine.Flags&Line.ML_BlockHitscan) )
return TRACE_Stop;
return TRACE_Skip;
}
return TRACE_Stop;
}
}
Class PulseBolt : Actor
{
PulseBoltTracer t;
double accdamage;
int lasthit;
Actor damagedactor;
double beamsize;
Actor weffect;
double phase;
override void OnDestroy()
{
Super.OnDestroy();
if ( weffect ) weffect.Destroy();
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
t = new("PulseBoltTracer");
t.ignore = target;
beamsize = 40;
}
override void Tick()
{
Super.Tick();
if ( globalfreeze || level.frozen ) return;
if ( !target )
{
Destroy();
return;
}
phase += 10;
// update beam
int numpt;
Vector3 x, y, z;
Vector3 origin;
if ( target.player )
{
[x, y, z] = Matrix4.GetAxes(target.pitch,target.angle,target.roll);
origin = (0,0,target.player.viewz-target.pos.z)+5.0*x+3.0*y-1.5*z;
}
else origin = (0,0,target.missileheight);
SetOrigin(target.Vec3Offset(origin.x,origin.y,origin.z),true);
A_SetAngle(target.angle,SPF_INTERPOLATE);
A_SetPitch(target.BulletSlope(),SPF_INTERPOLATE);
// draw beam
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
for ( double i=0; i<=beamsize; i+=0.5 )
{
origin = Level.Vec3Diff(pos,pos+x*i
+sin(i*0.834-phase)*y*0.1435*min(1,(i*0.1)**.5)
+sin(i*0.836-phase)*y*0.1342*min(1,(i*0.1)**.5)
+sin(i*0.843-phase)*z*0.1463*min(1,(i*0.1)**.5)
+sin(i*0.863-phase)*z*0.1345*min(1,(i*0.1)**.5));
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,1,FRandom[Pulse](0.6,1.2),0,origin.x,origin.y,origin.z,0,0,0,0,0,0,2);
A_SpawnParticle("40FF00",SPF_FULLBRIGHT,1,FRandom[Pulse](2.4,4.8),0,origin.x,origin.y,origin.z,0,0,0,0,0,0,.1);
}
for ( int i=50; i<beamsize; i+=100 )
{
origin = Vec3Offset(x.x*i,x.y*i,x.z*i);
Spawn("PulseBoltLight",origin);
}
// check beam
t.Trace(pos,cursector,x,beamsize,0);
if ( t.Results.HitType != TRACE_HitNone )
{
if ( t.Results.HitType == TRACE_HitActor )
{
if ( !damagedactor )
{
accdamage = min(0.5*(level.time-lasthit),0.1);
t.Results.HitActor.DamageMobj(self,target,Random[Pulse](65,75)*accdamage,'zapped');
accdamage = 0;
}
else if ( t.Results.HitActor != damagedactor )
{
t.Results.HitActor.DamageMobj(self,target,Random[Pulse](65,75)*accdamage,'zapped');
accdamage = 0;
}
lasthit = level.time;
damagedactor = t.Results.HitActor;
accdamage += 1./TICRATE;
if ( accdamage > 0.22 )
{
t.Results.HitActor.DamageMobj(self,target,Random[Pulse](65,75)*accdamage,'zapped');
accdamage = 0;
}
}
origin = Level.Vec3Diff(pos,t.Results.HitPos);
numpt = Random[Pulse](10,20)*!Random[Pulse](0,2);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = ((FRandom[Pulse](-.4,.5),FRandom[Pulse](-.4,.4),FRandom[Pulse](-.4,.4))-x).unit()*FRandom[Pulse](2,4);
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,Random[Pulse](20,40),FRandom[Pulse](2.4,4.8),0,origin.x,origin.y,origin.z,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-0.1);
A_SpawnParticle("40FF00",SPF_FULLBRIGHT,Random[Pulse](30,50),FRandom[Pulse](4.8,7.2),0,origin.x,origin.y,origin.z,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-0.1);
}
beamsize = t.Results.Distance;
A_SprayDecal("BoltScorch",beamsize+8);
return;
}
else if ( damagedactor )
{
damagedactor.DamageMobj(self,target,Random[Pulse](65,75)*accdamage,'zapped');
accdamage = 0;
damagedactor = null;
}
origin = Level.Vec3Diff(pos,t.Results.HitPos);
numpt = Random[Pulse](5,10)*!Random[Pulse](0,5);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (t.Results.HitVector+(FRandom[Pulse](-.5,.5),FRandom[Pulse](-.5,.5),FRandom[Pulse](-.5,.5))).unit()*FRandom[Pulse](2,4);
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,Random[Pulse](20,40),FRandom[Pulse](2.4,4.8),0,origin.x,origin.y,origin.z,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-0.1);
A_SpawnParticle("40FF00",SPF_FULLBRIGHT,Random[Pulse](30,50),FRandom[Pulse](4.8,7.2),0,origin.x,origin.y,origin.z,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-0.1);
}
beamsize = min(400,beamsize+40);
}
Default
{
Obituary "%o ate %k's burning plasma death.";
RenderStyle "Add";
Radius 0.1;
Height 0;
+NOGRAVITY;
+NOCLIP;
+DONTSPLASH;
}
States
{
Spawn:
PBLT A 1 Bright;
Loop;
}
}
Class PulseGun : UTWeapon
{
int clipcount;
double sangle;
Actor beam;
Property ClipCount : clipcount;
action void A_Reloading()
{
Weapon weap = Weapon(invoker);
if ( !weap ) return;
invoker.clipcount = Min(50,weap.Ammo1.Amount);
A_PlaySound("pulse/reload",CHAN_WEAPON);
}
action void A_DrainAmmo()
{
Weapon weap = Weapon(invoker);
if ( !weap ) return;
if ( weap.Ammo1.Amount <= 0 ) return;
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
invoker.clipcount--;
if ( CVar.GetCVar('flak_pulsereload').GetBool() && (invoker.clipcount <=0) ) invoker.clipcount = Min(50,weap.Ammo1.Amount);
invoker.FireEffect();
A_AlertMonsters();
Vector3 x, y, z;
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
Vector3 origin = pos+(0,0,player.viewheight)+10.0*x+4.5*y-2.4*z;
int numpt = Random[Pulse](2,5);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (x+(FRandom[Pulse](-.5,.5),FRandom[Pulse](-.5,.5),FRandom[Pulse](-.5,.5))).unit()*FRandom[Pulse](2,4);
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,Random[Pulse](10,20),FRandom[Pulse](1.2,2.4),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-0.1);
A_SpawnParticle("40FF00",SPF_FULLBRIGHT,Random[Pulse](15,25),FRandom[Pulse](2.4,3.6),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-0.1);
}
}
action void A_PulseRefire( statelabel flash = null )
{
Weapon weap = Weapon(invoker);
if ( !weap || !player ) return;
if ( (invoker.clipcount <= 0) || (weap.Ammo1.Amount <= 0) )
{
A_ClearRefire();
if ( weap.bAltFire ) player.setpsprite(PSP_WEAPON,weap.FindState("AltRelease"));
else player.setpsprite(PSP_WEAPON,weap.FindState("Release"));
return;
}
A_Refire(flash);
}
action void A_PulseFire()
{
Weapon weap = Weapon(invoker);
if ( !weap ) return;
if ( weap.Ammo1.Amount <= 0 ) return;
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
invoker.clipcount--;
if ( CVar.GetCVar('flak_pulsereload').GetBool() && (invoker.clipcount <=0) ) invoker.clipcount = Min(50,weap.Ammo1.Amount);
invoker.FireEffect();
A_AlertMonsters();
A_QuakeEx(1,1,1,2,0,64,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.05);
A_Overlay(-2,"MuzzleFlash");
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
A_OverlayRenderstyle(-2,STYLE_Add);
Vector3 x, y, z;
double a;
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
Vector3 origin = pos+(0,0,player.viewheight)+10.0*x+4.0*y-2.0*z;
origin += y*cos(invoker.sangle)*2.0+z*sin(invoker.sangle)*2.0;
invoker.sangle += 100;
Actor p = Spawn("PulseBall",origin);
p.angle = angle;
p.pitch = BulletSlope();
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed;
p.target = self;
int numpt = Random[Pulse](2,5);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (x+(FRandom[Pulse](-.5,.5),FRandom[Pulse](-.5,.5),FRandom[Pulse](-.5,.5))).unit()*FRandom[Pulse](2,4);
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,Random[Pulse](10,20),FRandom[Pulse](1.2,2.4),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-0.1);
A_SpawnParticle("40FF00",SPF_FULLBRIGHT,Random[Pulse](15,25),FRandom[Pulse](2.4,3.6),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-0.1);
}
}
action void A_StartBeam()
{
A_PlaySound("pulse/bolt",CHAN_WEAPON,1.0,true);
invoker.beam = Spawn("PulseBolt",pos);
invoker.beam.target = self;
}
action void A_StopBeam()
{
A_StopSound(CHAN_WEAPON);
if ( invoker.beam ) invoker.beam.Destroy();
}
Default
{
Tag "Pulse Gun";
Inventory.PickupMessage "You got a Pulse Gun";
Weapon.UpSound "pulse/select";
Weapon.SlotNumber 5;
Weapon.AmmoType "PulseAmmo";
Weapon.AmmoUse 1;
Weapon.AmmoType2 "PulseAmmo";
Weapon.AmmoUse2 1;
Weapon.AmmoGive 60;
PulseGun.ClipCount 50;
}
States
{
Spawn:
PGNP A -1;
Stop;
PGNP B -1;
Stop;
Ready:
PGNS ABCDEFGHIJKLMNOPQRSTUVW 1;
Idle:
PGNI A 1
{
A_CheckReload();
if ( CVar.GetCVar('flak_pulsereload').GetBool() )
{
if ( (invoker.clipcount <= 0) && (invoker.Ammo1.Amount > 0) ) return A_Jump(255,"Reload");
A_WeaponReady(WRF_ALLOWRELOAD);
}
else A_WeaponReady();
return A_JumpIf(!Random[Pulse](0,300),1);
}
Wait;
PGNI ABCDEFGHIJKLMNOPQRSTUVWXYZ 1
{
A_CheckReload();
A_WeaponReady(WRF_ALLOWRELOAD);
}
Goto Idle;
Fire:
PGNI A 0 A_PlaySound("pulse/fire",CHAN_WEAPON,1.0,true);
Hold:
PGNF A 1 A_PulseFire();
PGNF BCDEF 1;
PNGF G 0 A_PulseRefire(1);
Goto Release;
PGNF G 1 A_PulseFire();
PGNF HIJKL 1;
PNGF M 0 A_PulseRefire(1);
Goto Release;
PGNF N 1 A_PulseFire();
PGNF OPQRS 1;
PNGF T 0 A_PulseRefire(1);
Goto Release;
PGNF U 1 A_PulseFire();
PGNF VWXYZ 1;
PGF2 A 0 A_PulseRefire(1);
Goto Release;
PGF2 A 1 A_PulseFire();
PGF2 BCDEF 1;
PGF2 G 0 A_PulseRefire(1);
Goto Release;
PGF2 H 1 A_PulseFire();
PGF2 IJKLM 1;
PGF2 N 0 A_PulseRefire();
Goto Release;
Release:
PGNC A 0 A_PlaySound("pulse/down",CHAN_WEAPON);
PGNC ABCDEFGHIJKLMNOPQRSTUVWXY 1;
PGNI A 1;
Goto Idle;
AltFire:
PGBS ABCDE 1;
PGBL A 0 A_StartBeam();
AltHold:
PGBL A 1 A_DrainAmmo();
PGBL B 0 A_PulseRefire(1);
Goto AltRelease;
PGBL B 1;
PGBL C 0 A_PulseRefire(1);
Goto AltRelease;
PGBL C 1;
PGBL D 0 A_PulseRefire(1);
Goto AltRelease;
PGBL D 1;
PGBL E 0 A_PulseRefire(1);
Goto AltRelease;
PGBL E 1;
PGBL F 0 A_PulseRefire(1);
Goto AltRelease;
PGBL F 1;
PGBL G 0 A_PulseRefire(1);
Goto AltRelease;
PGBL G 1;
PGBL H 0 A_PulseRefire(1);
Goto AltRelease;
PGBL H 1;
PGBL I 0 A_PulseRefire(1);
Goto AltRelease;
PGBL I 1;
PGBL J 0 A_PulseRefire(1);
Goto AltRelease;
PGBL J 1;
PGBL A 0 A_PulseRefire();
AltRelease:
PGBE A 0 A_StopBeam();
PGBE ABCDE 1;
Goto Idle;
Reload:
PGNI A 1 A_JumpIf(invoker.clipcount >= 50,"Idle");
PGNR A 1 A_Reloading();
PGNR BCDEFGHIJKLMNOPQRSTUVWXYZ 1;
PGR2 ABCDEFGHIJKLMNOPQRSTUVWX 1;
Goto Idle;
Deselect:
PGNS WVUTSRQPONMLKJIHGFEDCBA 1;
PGNS A 1 A_Lower(int.max);
Wait;
Select:
PGNS A 1 A_Raise(int.max);
Wait;
MuzzleFlash:
PMUZ A 2 Bright;
Stop;
}
}