Prefixed mk_math classes for cross-compat with any other mods that use them. Fixed incorrect uses of gametic. Fixed crash caused by incorrect ordering of PendingWeapon checks.
263 lines
7.5 KiB
Text
263 lines
7.5 KiB
Text
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);
|
|
UTMainHandler.DoSwing(self,(FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1)),0.6,-0.2,2,SWING_Spring);
|
|
invoker.sawcnt += 1./TICRATE;
|
|
if ( invoker.sawcnt < 0.15 ) return;
|
|
invoker.sawcnt = 0;
|
|
invoker.FireEffect();
|
|
A_AlertMonsters();
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_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( bool initial = false )
|
|
{
|
|
A_QuakeEx(2,2,2,3,0,1,"",QF_RELATIVE,rollIntensity:0.15);
|
|
UTMainHandler.DoSwing(self,(FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1)),0.6,-0.2,2,SWING_Spring);
|
|
if ( initial ) invoker.FireEffect();
|
|
A_AlertMonsters();
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x-2.0*z;
|
|
FLineTraceData d;
|
|
double ang = (angle-60)+120*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.1;
|
|
}
|
|
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);
|
|
UTMainHandler.DoSwing(self,(FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1)),0.25,-0.1,2,SWING_Spring);
|
|
if ( bAlt || Random[Chainsaw](0,2) ) return;
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_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);
|
|
UTMainHandler.DoSwing(self,(FRandom[Chainsaw](-0.8,-1.2),FRandom[Chainsaw](-0.4,-0.7)),0,1,5,SWING_Spring,6,3);
|
|
}
|
|
CSWA ABCDE 2 A_Vibrate(true);
|
|
CSWA F 2
|
|
{
|
|
A_Overlay(PSP_WEAPON+1,"AltFireSwipes");
|
|
UTMainHandler.DoSwing(self,(FRandom[Chainsaw](0.8,1.2),0),0,2,6,SWING_Spring,1,3);
|
|
}
|
|
CSWA GHIJ 2;
|
|
CSWA K 2 A_Vibrate(true);
|
|
CSWA K 0 A_PlaySound("chainsaw/idle",CHAN_6,looping:true);
|
|
Goto Ready;
|
|
AltFireSwipes:
|
|
TNT1 A 1 A_SawSwipe(true);
|
|
TNT1 AAAAAAAAA 1 A_SawSwipe();
|
|
Stop;
|
|
Deselect:
|
|
CSWD A 0 A_PlaySound("chainsaw/lower",CHAN_6);
|
|
CSWD ABCDEF 1;
|
|
CSWD F 1 A_Lower(int.max);
|
|
Wait;
|
|
}
|
|
}
|