Reduced the smoke on the minigun and casings for better performance. Corrected the number of chunks (was 6, should be 8) fired by the flak cannon. Reduced flak chunk spread (should be ~5.5 degrees, was double of that) on the weapon and slugs. Reduced the size of the shock rifle combo shockwave mesh to be closer to vanilla UT. Misc. tweaks to health item textures. Reduced the blur in the Redeemer view shader, it was too strong. Fix expiration messages on powerups appearing on level changes. Address complaints about how I change Kinsie's test map. Shouldn't be too dark now.
329 lines
7.4 KiB
Text
329 lines
7.4 KiB
Text
Class RipperAmmo : Ammo
|
|
{
|
|
Default
|
|
{
|
|
Tag "Razor Blades";
|
|
Inventory.PickupMessage "You picked up Razor Blades.";
|
|
Inventory.Amount 10;
|
|
Inventory.MaxAmount 40;
|
|
Ammo.BackpackAmount 20;
|
|
Ammo.BackpackMaxAmount 80;
|
|
Ammo.DropAmount 5;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
BHOP A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class Razor2Trail : Actor
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
+NOGRAVITY;
|
|
+NOCLIP;
|
|
+DONTSPLASH;
|
|
+NOTELEPORT;
|
|
Radius 0.1;
|
|
Height 0;
|
|
}
|
|
override void Tick()
|
|
{
|
|
if ( !target || target.InStateSequence(target.CurState,target.ResolveState("Death")) )
|
|
{
|
|
Destroy();
|
|
return;
|
|
}
|
|
SetOrigin(target.pos,true);
|
|
angle = target.angle;
|
|
pitch = target.pitch;
|
|
alpha = target.vel.length()/target.speed;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
RAZB A -1 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class Razor2 : Actor
|
|
{
|
|
Default
|
|
{
|
|
Radius 2;
|
|
Height 2;
|
|
Speed 25;
|
|
DamageFunction (Random[Ripper](20,25)*((DamageType=='Decapitated')?3:1.0));
|
|
DamageType 'Shredded';
|
|
Obituary "%k ripped a chunk of meat out of %o with the Ripper.";
|
|
BounceType "Hexen";
|
|
ReactionTime 7;
|
|
BounceFactor 1.0;
|
|
WallBounceFactor 1.0;
|
|
PROJECTILE;
|
|
+USEBOUNCESTATE;
|
|
+SKYEXPLODE;
|
|
+CANBOUNCEWATER;
|
|
+NODAMAGETHRUST;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
let t = Spawn("Razor2Trail",pos);
|
|
t.target = self;
|
|
A_PlaySound("ripper/hum",CHAN_VOICE,1.0,true,3.0);
|
|
Vector3 dir = vel.unit();
|
|
A_SetAngle(atan2(dir.y,dir.x));
|
|
A_SetPitch(asin(-dir.z));
|
|
}
|
|
override int SpecialMissileHit( Actor victim )
|
|
{
|
|
if ( pos.z > victim.pos.z+victim.height*0.81 ) DamageType = 'Decapitated';
|
|
return -1;
|
|
}
|
|
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
|
|
{
|
|
if ( !target.bNOBLOOD )
|
|
{
|
|
target.SpawnBlood(pos,AngleTo(target),damage);
|
|
A_PlaySound("ripper/flesh");
|
|
A_AlertMonsters();
|
|
}
|
|
UTMainHandler.DoKnockback(target,vel.unit(),15000);
|
|
return damage;
|
|
}
|
|
action void A_RazorHit()
|
|
{
|
|
A_PlaySound("ripper/hit");
|
|
A_AlertMonsters();
|
|
A_SprayDecal("WallCrack",-20);
|
|
int numpt = Random[Ripper](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[Ripper](-.8,.8),FRandom[Ripper](-.8,.8),FRandom[Ripper](-.8,.8))).unit()*FRandom[Ripper](0.1,1.2);
|
|
let s = Spawn("UTSmoke",pos);
|
|
s.vel = pvel;
|
|
s.SetShade(Color(1,1,1)*Random[Ripper](128,192));
|
|
}
|
|
numpt = Random[Ripper](4,12);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[Ripper](-1,1),FRandom[Ripper](-1,1),FRandom[Ripper](-1,1)).unit()*FRandom[Ripper](2,8);
|
|
let s = Spawn("UTSpark",pos);
|
|
s.vel = pvel;
|
|
}
|
|
numpt = Random[Ripper](4,8);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[Ripper](-1,1),FRandom[Ripper](-1,1),FRandom[Ripper](-1,1)).unit()*FRandom[Ripper](2,8);
|
|
let s = Spawn("UTChip",pos);
|
|
s.vel = pvel;
|
|
}
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
RAZB A -1;
|
|
Stop;
|
|
Bounce:
|
|
RAZB A 0
|
|
{
|
|
bHITOWNER = true; // technically the UT version sets this 0.2 seconds after being fired, but this works better
|
|
Vector3 dir = vel.unit();
|
|
A_SetAngle(atan2(dir.y,dir.x));
|
|
A_SetPitch(asin(-dir.z));
|
|
A_RazorHit();
|
|
A_CountDown();
|
|
}
|
|
Goto Spawn;
|
|
Death:
|
|
TNT1 A 0
|
|
{
|
|
angle += 180;
|
|
pitch *= -1;
|
|
A_RazorHit();
|
|
}
|
|
XDeath:
|
|
TNT1 A 1 A_StopSound(CHAN_VOICE);
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class Razor2AltLight : DynamicLight
|
|
{
|
|
double lifetime;
|
|
Default
|
|
{
|
|
DynamicLight.Type "Point";
|
|
Args 255,240,224,90;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
lifetime = 1.0;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
args[LIGHT_RED] = int(255*lifetime);
|
|
args[LIGHT_GREEN] = int(240*lifetime);
|
|
args[LIGHT_BLUE] = int(224*lifetime);
|
|
lifetime -= 0.05;
|
|
if ( lifetime <= 0 ) Destroy();
|
|
}
|
|
}
|
|
|
|
Class Razor2Alt : Razor2
|
|
{
|
|
Default
|
|
{
|
|
BounceType "None";
|
|
-CANBOUNCEWATER;
|
|
+EXPLODEONWATER;
|
|
+FORCERADIUSDMG;
|
|
+NODAMAGETHRUST;
|
|
}
|
|
action void A_RazorExplode()
|
|
{
|
|
A_SetRenderStyle(1.0,STYLE_Add);
|
|
bFORCEXYBILLBOARD = true;
|
|
Scale *= 0.65;
|
|
A_StopSound(CHAN_VOICE);
|
|
A_PlaySound("ripper/althit");
|
|
Spawn("Razor2AltLight",pos);
|
|
A_AlertMonsters();
|
|
A_SprayDecal("RazorBlast",20);
|
|
UTMainHandler.DoBlast(self,90,87000);
|
|
A_Explode(Random[Ripper](30,50),90,damagetype:'RipperAltDeath');
|
|
A_QuakeEx(3,3,3,10,0,140,"",QF_RELATIVE|QF_SCALEDOWN,falloff:90,rollIntensity:0.1);
|
|
int numpt = Random[Ripper](10,20);
|
|
Vector3 x = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (-x+(FRandom[Ripper](-.8,.8),FRandom[Ripper](-.8,.8),FRandom[Ripper](-.8,.8))).unit()*FRandom[Ripper](0.1,1.2);
|
|
let s = Spawn("UTSmoke",pos);
|
|
s.vel = pvel;
|
|
s.SetShade(Color(1,1,1)*Random[Ripper](128,192));
|
|
}
|
|
numpt = Random[Ripper](8,16);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[Ripper](-1,1),FRandom[Ripper](-1,1),FRandom[Ripper](-1,1)).unit()*FRandom[Ripper](2,8);
|
|
let s = Spawn("UTSpark",pos);
|
|
s.vel = pvel;
|
|
}
|
|
numpt = Random[Ripper](8,12);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[Ripper](-1,1),FRandom[Ripper](-1,1),FRandom[Ripper](-1,1)).unit()*FRandom[Ripper](2,8);
|
|
let s = Spawn("UTChip",pos);
|
|
s.vel = pvel;
|
|
}
|
|
}
|
|
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
|
|
{
|
|
return damage;
|
|
}
|
|
override int SpecialMissileHit( Actor victim )
|
|
{
|
|
return -1;
|
|
}
|
|
States
|
|
{
|
|
Death:
|
|
XDeath:
|
|
TNT1 A 0 A_RazorExplode();
|
|
RIPX ABCDEFG 2 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class Ripper2 : UTWeapon
|
|
{
|
|
Default
|
|
{
|
|
Tag "Ripper";
|
|
Inventory.PickupMessage "You got the Ripper.";
|
|
Weapon.UpSound "ripper/select";
|
|
Weapon.SlotNumber 6;
|
|
Weapon.SelectionOrder 4;
|
|
Weapon.AmmoType "RipperAmmo";
|
|
Weapon.AmmoUse 1;
|
|
Weapon.AmmoType2 "RipperAmmo";
|
|
Weapon.AmmoUse2 1;
|
|
Weapon.AmmoGive 10;
|
|
UTWeapon.DropAmmo 5;
|
|
}
|
|
action void A_RazorFire( bool alt = false )
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( weap.Ammo1.Amount <= 0 ) return;
|
|
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
|
if ( alt ) A_PlaySound("ripper/altfire",CHAN_WEAPON);
|
|
else A_PlaySound("ripper/fire",CHAN_WEAPON);
|
|
invoker.FireEffect();
|
|
UTMainHandler.DoFlash(self,Color(8,0,255,255),1);
|
|
A_AlertMonsters();
|
|
if ( alt )
|
|
{
|
|
A_QuakeEx(3,3,3,8,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
|
|
UTMainHandler.DoSwing(self,(FRandom[Ripper](-0.3,-0.6),FRandom[Ripper](0.2,0.6)),3,-0.5,3,SWING_Spring,5,4);
|
|
}
|
|
else
|
|
{
|
|
A_QuakeEx(1,1,1,5,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.08);
|
|
UTMainHandler.DoSwing(self,(FRandom[Ripper](-0.3,-0.6),FRandom[Ripper](0.2,0.6)),1,-0.3,2,SWING_Spring,2,2);
|
|
}
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+6.0*y-4.0*z;
|
|
Actor p;
|
|
if ( alt ) p = Spawn("Razor2Alt",origin);
|
|
else p = Spawn("Razor2",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;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
RZRP A -1;
|
|
Stop;
|
|
RZRP B -1;
|
|
Stop;
|
|
Select:
|
|
RZRS A 1 A_Raise(int.max);
|
|
Wait;
|
|
Ready:
|
|
RZRS ABCDEFGHIJKLMNOPQRSTUVWXYZ 1 A_WeaponReady(WRF_NOFIRE);
|
|
RZS2 ABCD 1 A_WeaponReady(WRF_NOFIRE);
|
|
Idle:
|
|
RZRI ABCDEFGHIJKLMNOPQRS 2
|
|
{
|
|
A_CheckReload();
|
|
A_WeaponReady();
|
|
}
|
|
Loop;
|
|
Fire:
|
|
RZRF A 0 A_RazorFire();
|
|
RZRF ABCDEFGHIJKLMNO 1;
|
|
Goto Idle;
|
|
AltFire:
|
|
RZRF A 0 A_RazorFire(true);
|
|
RZRF ABCDEFG 3;
|
|
RZRF HIJKLMNO 1;
|
|
Goto Idle;
|
|
Deselect:
|
|
RZRD ABCDEF 1;
|
|
RZRD F 1 A_Lower(int.max);
|
|
Wait;
|
|
}
|
|
}
|