Double capacity with backpack for all ammo (except Redeemer, it just gets one extra). Made Enhanced Shock Rifle ammo drain over time (1 unit per second). Uncapped health and armor numbers in the HUD. Fixed Jump Boots not persisting between levels. Increased duration of invisibility. Made translocator toggleable (currently requires manually selecting "apply changes" under the menu option).
251 lines
6.5 KiB
Text
251 lines
6.5 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');
|
|
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;
|
|
LineTrace(angle,90,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
|
if ( d.HitType == TRACE_HitActor )
|
|
{
|
|
int dmg = Random[Chainsaw](50,60);
|
|
if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.8) )
|
|
dmg = d.HitActor.DamageMobj(invoker,self,dmg*2,'Decapitated');
|
|
else dmg = d.HitActor.DamageMobj(invoker,self,dmg,'slashed');
|
|
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);
|
|
}
|
|
}
|
|
override void DetachFromOwner()
|
|
{
|
|
if ( Owner ) Owner.A_StopSound(CHAN_6);
|
|
A_PlaySound("chainsaw/lower",CHAN_6);
|
|
Super.DetachFromOwner();
|
|
}
|
|
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_WeaponReady(WRF_NOFIRE);
|
|
A_AlertMonsters();
|
|
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
|
|
}
|
|
Idle:
|
|
CSWI A 0 A_PlaySound("chainsaw/idle",CHAN_6,looping:true);
|
|
CSWI ABCDEFGHIJ 1
|
|
{
|
|
A_AlertMonsters();
|
|
A_WeaponReady();
|
|
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
|
|
}
|
|
Goto Idle+1;
|
|
Fire:
|
|
CSWJ A 1 A_PlaySound("chainsaw/fire",CHAN_6,looping:true);
|
|
CSWJ BCDEF 1
|
|
{
|
|
A_AlertMonsters();
|
|
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
|
|
}
|
|
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_AlertMonsters();
|
|
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
|
|
}
|
|
Goto Idle;
|
|
AltFire:
|
|
CSWA A 0 A_PlaySound("chainsaw/fire",CHAN_6);
|
|
CSWA ABCDEFG 2
|
|
{
|
|
A_AlertMonsters();
|
|
A_QuakeEx(2,2,2,3,0,1,"",QF_RELATIVE,rollIntensity:0.15);
|
|
}
|
|
CSWA H 2 A_SawSwipe();
|
|
CSWA IJK 2
|
|
{
|
|
A_AlertMonsters();
|
|
A_QuakeEx(2,2,2,3,0,1,"",QF_RELATIVE,rollIntensity:0.15);
|
|
}
|
|
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;
|
|
}
|
|
}
|