flak_m/zscript/chainsaw.zsc
Marisa Kirisame 36a3598826 Changed Pulse Beam size to be the same as in UT99 (10 81-unit segments).
Tweaked Starter Bolt textures to look better in first person.
Tweaked Pulse Beam model UVs to reduce seams.
Switched Chainsaw alt-fire to damage in an arc.
Rebalanced damages of Chainsaw, Enforcer, Biorifle, Pulsegun, Minigun, Flak Cannon.
Adjusted Redeemer damage formula.
Added view flash to Redeemer shockwave.
Reduced Enforcer fire speed.
Reduced delay of Minigun altfire. Should happen after exactly one cycle.
Increased knockback of Impact Hammer.
2018-08-12 01:49:00 +02:00

256 lines
6.9 KiB
Text

Class Tier1Weapon : RandomSpawner2 replaces Chainsaw
{
Default
{
DropItem "UTChainsaw", 255, 1;
DropItem "Enforcer", 255, 1;
}
}
Class SawImpact : Actor
{
Default
{
Radius 0.1;
Height 0;
+NOGRAVITY;
+NOCLIP;
+DONTSPLASH;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_SprayDecal("WallCrack",20);
int numpt = Random[Chainsaw](5,10);
Vector3 x = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (-x+(FRandom[Chainsaw](-.8,.8),FRandom[Chainsaw](-.8,.8),FRandom[Chainsaw](-.8,.8))).unit()*FRandom[Chainsaw](0.1,1.2);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
s.SetShade(Color(1,1,1)*Random[Chainsaw](128,192));
}
numpt = Random[Chainsaw](4,12);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1)).unit()*FRandom[Chainsaw](2,8);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
numpt = Random[Chainsaw](4,8);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1)).unit()*FRandom[Chainsaw](2,8);
let s = Spawn("UTChip",pos);
s.vel = pvel;
}
Destroy();
}
}
Class UTChainsaw : UTWeapon
{
double sawcnt;
action void A_SawHit()
{
A_QuakeEx(2,2,2,2,0,1,"",QF_RELATIVE,rollIntensity:0.15);
invoker.sawcnt += 1./TICRATE;
if ( invoker.sawcnt < 0.15 ) return;
invoker.sawcnt = 0;
invoker.FireEffect();
A_AlertMonsters();
Vector3 x, y, z;
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x-4.0*z;
FLineTraceData d;
LineTrace(angle,90,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType == TRACE_HitActor )
{
int dmg = Random[Chainsaw](20,30);
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'slashed',DMG_USEANGLE,atan2(d.HitDir.y,d.HitDir.x));
d.HitActor.vel -= x*(500/d.HitActor.mass);
vel += x*(100/mass);
if ( d.HitActor.player ) d.HitActor.A_QuakeEx(5,5,5,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("SawImpact",d.HitLocation-d.HitDir*4);
p.angle = atan2(d.HitDir.y,d.HitDir.x);
p.pitch = asin(-d.HitDir.z);
}
else
{
d.HitActor.TraceBleed(dmg,invoker);
d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg);
}
}
else if ( d.HitType != TRACE_HitNone )
{
let p = Spawn("SawImpact",d.HitLocation-d.HitDir*4);
p.angle = atan2(d.HitDir.y,d.HitDir.x);
p.pitch = asin(-d.HitDir.z);
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation-d.HitDir*4);
}
}
action void A_SawSwipe()
{
A_QuakeEx(2,2,2,3,0,1,"",QF_RELATIVE,rollIntensity:0.15);
invoker.FireEffect();
A_AlertMonsters();
Vector3 x, y, z;
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x-2.0*z;
FLineTraceData d;
double ang = (angle-45)+90*invoker.sawcnt;
LineTrace(ang,90,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType == TRACE_HitActor )
{
int dmg = Random[Chainsaw](20,30);
if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.8) )
dmg = d.HitActor.DamageMobj(invoker,self,dmg*2,'Decapitated',DMG_USEANGLE,atan2(d.HitDir.y,d.HitDir.x));
else dmg = d.HitActor.DamageMobj(invoker,self,dmg,'slashed',DMG_USEANGLE,atan2(d.HitDir.y,d.HitDir.x));
d.HitActor.vel = -y*(1200/d.HitActor.mass);
vel += x*(100/mass);
if ( d.HitActor.player ) d.HitActor.A_QuakeEx(5,5,5,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("SawImpact",d.HitLocation-d.HitDir*4);
p.angle = atan2(d.HitDir.y,d.HitDir.x);
p.pitch = asin(-d.HitDir.z);
}
else
{
d.HitActor.TraceBleed(dmg,invoker);
d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg);
}
}
else if ( d.HitType != TRACE_HitNone )
{
let p = Spawn("SawImpact",d.HitLocation-d.HitDir*4);
p.angle = atan2(d.HitDir.y,d.HitDir.x);
p.pitch = asin(-d.HitDir.z);
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation-d.HitDir*4);
}
invoker.sawcnt += 0.2;
}
override void DetachFromOwner()
{
if ( Owner ) Owner.A_StopSound(CHAN_6);
A_PlaySound("chainsaw/lower",CHAN_6);
Super.DetachFromOwner();
}
action void A_Vibrate( bool bAlt = false )
{
invoker.sawcnt = 0;
A_AlertMonsters();
if ( bAlt ) A_QuakeEx(1,1,1,3,0,1,"",QF_RELATIVE,rollIntensity:0.4);
else A_QuakeEx(0,0,0,2,0,1,"",QF_RELATIVE,rollIntensity:0.2);
if ( bAlt || Random[Chainsaw](0,2) ) return;
Vector3 x, y, z;
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
Vector3 origin = (pos.x,pos.y,player.viewz)+5.0*x+1.0*y-3.0*z;
for ( int i=0; i<5; i++ )
{
let s = Spawn("UTViewSmoke",origin);
UTViewSmoke(s).ofs = (5,1,-3);
s.scale *= 1.2;
s.alpha *= 0.2;
s.SetShade("202020");
s.target = self;
UTViewSmoke(s).vvel += (0,-0.2,0);
}
}
Default
{
Tag "Chainsaw";
Obituary "%k ripped into %o with a blood soaked Chainsaw.";
Inventory.PickupMessage "It's been twenty five years since I've seen one of these."; // was five years in UT99
Weapon.UpSound "chainsaw/select";
Weapon.SlotNumber 1;
Weapon.SelectionOrder 9;
+WEAPON.MELEEWEAPON;
+FORCEPAIN;
}
States
{
Spawn:
CSWP A -1;
Stop;
CSWP B -1;
Stop;
Select:
CSWS A 1 A_Raise(int.max);
Wait;
Ready:
CSWS ABCDEFGHIJLMNO 1
{
A_Vibrate();
A_WeaponReady(WRF_NOFIRE);
}
Idle:
CSWI A 0 A_PlaySound("chainsaw/idle",CHAN_6,looping:true);
CSWI ABCDEFGHIJ 1
{
A_Vibrate();
A_WeaponReady();
}
Goto Idle+1;
Fire:
CSWJ A 1 A_PlaySound("chainsaw/fire",CHAN_6,looping:true);
CSWJ BCDEF 1 A_Vibrate();
Hold:
CSWJ G 1 A_SawHit();
CSWJ H 0 A_Refire(1);
Goto Release;
CSWJ H 1 A_SawHit();
CSWJ I 0 A_Refire(1);
Goto Release;
CSWJ I 1 A_SawHit();
CSWJ J 0 A_Refire(1);
Goto Release;
CSWJ J 1 A_SawHit();
CSWJ K 0 A_Refire(1);
Goto Release;
CSWJ K 1 A_SawHit();
CSWJ L 0 A_Refire(1);
Goto Release;
CSWJ L 1 A_SawHit();
CSWJ M 0 A_Refire(1);
Goto Release;
CSWJ M 1 A_SawHit();
CSWJ N 0 A_Refire(1);
Goto Release;
CSWJ N 1 A_SawHit();
CSWJ O 0 A_Refire(1);
Goto Release;
CSWJ O 1 A_SawHit();
CSWJ P 0 A_Refire(1);
Goto Release;
CSWJ P 1 A_SawHit();
CSWJ Q 0 A_Refire(1);
Goto Release;
CSWJ Q 1 A_SawHit();
CSWJ R 0 A_Refire(1);
Goto Release;
CSWJ R 1 A_SawHit();
CSWJ S 0 A_Refire(1);
Goto Release;
CSWJ S 1 A_SawHit();
CSWJ G 0 A_Refire("Hold");
Release:
CSWJ FEDCBA 1 A_Vibrate();
Goto Idle;
AltFire:
CSWA A 0 A_PlaySound("chainsaw/fire",CHAN_6);
CSWA ABCDE 2 A_Vibrate(true);
CSWA FGHIJ 2 A_SawSwipe();
CSWA K 2 A_Vibrate(true);
CSWA K 0 A_PlaySound("chainsaw/idle",CHAN_6,looping:true);
Goto Ready;
Deselect:
CSWD A 0 A_PlaySound("chainsaw/lower",CHAN_6);
CSWD ABCDEF 1;
CSWD F 1 A_Lower(int.max);
Wait;
}
}