- Migrated screen projection code to libeye. - Some pickups emit light, like in Doomreal. - Backported map revealer item from Doomreal. - Brand new Invulnerability and Night Vision powerups. - Add option to allow Shield Belt and armors simultaneously. - Backported armor bonus model from Doomreal. - Added Dual Enforcers icon for HUD. - Changed player class names to their character names, like in Doomreal. - Terrain splashes. - Translocator doesn't telefrag other players in coop. - Reduced view shake from Impact Hammer. - Various other updates and bug fixes.
309 lines
6.9 KiB
Text
309 lines
6.9 KiB
Text
Class RipperAmmo : Ammo
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_RIPPERAMO";
|
|
Inventory.PickupMessage "$I_RIPPERAMMO";
|
|
Inventory.Amount 10;
|
|
Inventory.MaxAmount 40;
|
|
Ammo.BackpackAmount 5;
|
|
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 (int(30*((DamageType=='Decapitated')?3.5:1.0)));
|
|
DamageType 'Shredded';
|
|
Obituary "$O_RIPPER";
|
|
BounceType "Hexen";
|
|
ReactionTime 7;
|
|
BounceFactor 1.0;
|
|
WallBounceFactor 1.0;
|
|
PROJECTILE;
|
|
+USEBOUNCESTATE;
|
|
+SKYEXPLODE;
|
|
+CANBOUNCEWATER;
|
|
+NODAMAGETHRUST;
|
|
+DONTBOUNCEONSHOOTABLES;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
let t = Spawn("Razor2Trail",pos);
|
|
t.target = self;
|
|
A_PlaySound("ripper/hum",CHAN_VOICE,1.0,true,3.0,pitch:3.125);
|
|
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 A_RazorHit();
|
|
XDeath:
|
|
TNT1 A 1 A_StopSound(CHAN_VOICE);
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class Razor2AltLight : PaletteLight
|
|
{
|
|
Default
|
|
{
|
|
Args 0,0,0,90;
|
|
ReactionTime 20;
|
|
}
|
|
}
|
|
|
|
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(34,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 "$T_RIPPER";
|
|
Inventory.PickupMessage "$I_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_CoordUtil.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+6*y-4*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;
|
|
}
|
|
}
|