Merge branch 'master' into utmovement

This commit is contained in:
Marisa the Magician 2018-08-17 21:12:58 +02:00
commit aa63ab7555
12 changed files with 98 additions and 47 deletions

View file

@ -21,3 +21,4 @@ user bool flak_footsteps = true;
server bool flak_translocator = false;
user bool flak_noswitchdeemer = true; // don't switch to redeemer when out of ammo
user bool flak_deemershader = false;
server bool flak_classicsshock = false; // classic enhanced shock rifle (no altfire, beams don't have splash damage)

View file

@ -25,6 +25,7 @@ OptionMenu "UTOptionMenu"
Option "Redeemer Target Visuals", "flak_redeemerreadout", "YesNo"
Option "Redeemer View Shader", "flak_deemershader", "YesNo"
Option "No Redeemer Autoswitch", "flak_noswitchdeemer", "YesNo"
Option "Classic Enh. Shock Rifle", "flak_classicsshock", "YesNo"
StaticText " "
Option "Enable Translocator", "flak_translocator", "YesNo"
Command "Apply Changes", "event refreshtrans"

View file

@ -411,7 +411,8 @@ Class BioGel : Actor
s.args[3] = int(s.args[3]*Scale.x);
invoker.deadtimer = -2;
if ( invoker.atline ) invoker.atline.RemoteActivate(target,invoker.atside,SPAC_Impact,pos);
A_Explode(int(Random[GES](10,15)*max(1,(Scale.x-1)**2)),Min(150,int(Scale.x*25)));
UTMainHandler.DoBlast(self,Min(150,int(Scale.x*25)),20000*Scale.x);
A_Explode(int(Random[GES](18,22)*max(1,(Scale.x-1)**2)),Min(150,int(Scale.x*25)));
A_PlaySound("ges/explode",CHAN_VOICE);
int numpt = Min(300,int(Scale.x*30))+Random[GES](-10,10);
for ( int i=0; i<numpt; i++ )
@ -437,13 +438,11 @@ Class BioGel : Actor
{
Obituary "%o drank a glass of %k's dripping green load.";
DamageType 'Slime';
DamageFunction int(Random[GES](10,15)*max(1,(Scale.x-1)**2));
RenderStyle "Add";
Radius 3;
Height 3;
Scale 2;
Speed 18;
ProjectileKickback 120;
Gravity 0.5;
PROJECTILE;
-NOGRAVITY;
@ -452,6 +451,7 @@ Class BioGel : Actor
+FORCERADIUSDMG;
+FORCEXYBILLBOARD;
+MOVEWITHSECTOR;
+NODAMAGETHRUST;
}
States
{

View file

@ -105,16 +105,16 @@ Class UTRocket : Actor
Default
{
Obituary "%o was smacked down by %k's Rocket Launcher.";
DamageFunction Random[Eightball](90,115);
DamageType 'RocketDeath';
Radius 2;
Height 2;
Speed 18;
ProjectileKickback 400;
PROJECTILE;
+SKYEXPLODE;
+EXPLODEONWATER;
+SEEKERMISSILE;
+FORCERADIUSDMG;
+NODAMAGETHRUST;
}
override void PostBeginPlay()
{
@ -123,15 +123,16 @@ Class UTRocket : Actor
l.target = self;
A_PlaySound("utrl/fly",CHAN_VOICE,1.0,true,2.5);
}
action void A_RocketExplode()
action void A_RocketExplode( int dmg )
{
bFORCEXYBILLBOARD = true;
A_SetRenderStyle(1.0,STYLE_Add);
A_SprayDecal("RocketBlast",150);
A_NoGravity();
A_SetScale(0.75);
A_Explode(Random[Eightball](80,100),100);
A_QuakeEx(3,3,3,8,0,250,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.2);
UTMainHandler.DoBlast(self,100,80000);
A_Explode(dmg,100);
A_QuakeEx(3,3,3,8,0,250,"",QF_RELATIVE|QF_SCALEDOWN,falloff:100,rollIntensity:0.2);
A_PlaySound("utrl/explode",CHAN_VOICE);
A_AlertMonsters();
Spawn("RocketExplLight",pos);
@ -178,7 +179,7 @@ Class UTRocket : Actor
}
Wait;
Death:
TNT1 A 0 A_RocketExplode();
TNT1 A 0 A_RocketExplode(Random[Eightball](90,115));
SSMX ABCDEFGHIJ 2 Bright;
Stop;
}
@ -190,7 +191,6 @@ Class UTGrenade : UTRocket
Default
{
DamageFunction Random[Eightball](90,120);
DamageType 'GrenadeDeath';
-NOGRAVITY;
+USEBOUNCESTATE;
@ -231,6 +231,9 @@ Class UTGrenade : UTRocket
anglevel = FRandom[Eightball](-16,16);
}
Goto Spawn;
Death:
TNT1 A 0 A_RocketExplode(Random[Eightball](90,120));
Goto Super::Death+1;
}
}

View file

@ -313,7 +313,8 @@ Class Enforcer : UTWeapon replaces Pistol
if ( d.HitType == TRACE_HitActor )
{
int dmg = Random[Enforcer](12,17);
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE,atan2(d.HitDir.y,d.HitDir.x));
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,3000);
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("BulletImpact",d.HitLocation);

View file

@ -133,7 +133,6 @@ Class FlakChunk : Actor
double rollvel, pitchvel, yawvel;
double lifetime, lifespeed;
int lifetics;
bool hasbounced;
Default
{
Obituary "%o was ripped to shreds by %k's Flak Cannon.";
@ -210,7 +209,6 @@ Class FlakChunk : Actor
}
action void A_HandleBounce()
{
invoker.hasbounced = true;
A_SprayDecal("WallCrack",-8);
int numpt = Random[Flak](2,3);
if ( frame < 10 )
@ -359,16 +357,16 @@ Class FlakSlug : Actor
{
Obituary "%o was ripped to shreds by %k's Flak Cannon.";
DamageType 'FlakDeath';
DamageFunction Random[Flak](100,110);
Radius 2;
Height 2;
Speed 40;
ProjectileKickback 320;
PROJECTILE;
-NOGRAVITY;
+SKYEXPLODE;
+EXPLODEONWATER;
+HITTRACER;
+FORCERADIUSDMG;
+NODAMAGETHRUST;
}
override void PostBeginPlay()
{
@ -387,8 +385,9 @@ Class FlakSlug : Actor
A_SprayDecal("RocketBlast",150);
A_NoGravity();
A_SetScale(1.2);
UTMainHandler.DoBlast(self,80,75000);
A_Explode(Random[Flak](70,80),80);
A_QuakeEx(4,4,4,8,0,200,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.2);
A_QuakeEx(4,4,4,8,0,200,"",QF_RELATIVE|QF_SCALEDOWN,falloff:80,rollIntensity:0.2);
A_PlaySound("flak/explode",CHAN_VOICE);
A_AlertMonsters();
if ( !Tracer ) Spawn("SlugSmoke",pos);

View file

@ -124,7 +124,8 @@ Class Minigun : UTWeapon
if ( d.HitType == TRACE_HitActor )
{
int dmg = Random[Minigun](16,20); // fun fact: the Minigun is one of the few weapons that has actual RNG damage in UT
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE,atan2(d.HitDir.y,d.HitDir.x));
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,dmg*500);
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("BulletImpact",d.HitLocation);

View file

@ -70,6 +70,7 @@ Class Razor2 : Actor
-BOUNCEAUTOOFF;
+SKYEXPLODE;
+CANBOUNCEWATER;
+NODAMAGETHRUST;
}
override void PostBeginPlay()
{
@ -95,6 +96,7 @@ Class Razor2 : Actor
A_PlaySound("ripper/flesh");
A_AlertMonsters();
}
UTMainHandler.DoKnockback(target,vel.unit(),15000);
return damage;
}
action void A_RazorHit()
@ -183,12 +185,13 @@ Class Razor2Alt : Razor2
{
Default
{
DamageFunction Random[Ripper](40,60);
DamageFunction 0;
DamageType 'RipperAltDealth';
BounceType "None";
ProjectileKickback 350;
-CANBOUNCEWATER;
+EXPLODEONWATER;
+FORCERADIUSDMG;
+NODAMAGETHRUST;
}
action void A_RazorExplode()
{
@ -200,8 +203,9 @@ Class Razor2Alt : Razor2
Spawn("Razor2AltLight",pos);
A_AlertMonsters();
A_SprayDecal("RazorBlast",20);
UTMainHandler.DoBlast(self,120,87000);
A_Explode(Random[Ripper](30,50),120);
A_QuakeEx(3,3,3,10,0,180,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
A_QuakeEx(3,3,3,10,0,180,"",QF_RELATIVE|QF_SCALEDOWN,falloff:120,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++ )

View file

@ -277,12 +277,12 @@ Class ShockBeam : Actor
Radius 0.1;
Height 0;
Scale 0.4;
ProjectileKickback 250;
+NOGRAVITY;
+NOCLIP;
+DONTSPLASH;
+FORCEXYBILLBOARD;
+FORCERADIUSDMG;
+NODAMAGETHRUST;
}
override void PostBeginPlay()
{
@ -336,9 +336,10 @@ Class ShockBeam : Actor
{
if ( target ) target.TakeInventory('ShockAmmo',2);
let b = t.Results.HitActor.target;
UTMainHandler.DoBlast(b,300,70000);
b.ExplodeMissile(null,self);
b.A_Explode(Random[ASMD](150,160),300);
b.A_QuakeEx(6,6,6,60,0,1200,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.2);
b.A_QuakeEx(6,6,6,60,0,1200,"",QF_RELATIVE|QF_SCALEDOWN,falloff:300,rollIntensity:0.2);
b.A_SprayDecal("BigShockMark1",100);
b.A_SprayDecal("BigShockMark2",100);
Spawn("ShockRifleWave",b.pos);
@ -358,6 +359,7 @@ Class ShockBeam : Actor
else
{
t.Results.HitActor.DamageMobj(self,target,Random[ASMD](35,50),'jolted',DMG_USEANGLE,atan2(t.Results.HitVector.y,t.Results.HitVector.x));
UTMainHandler.DoKnockback(t.Results.HitActor,t.Results.HitVector,60000);
let r = Spawn("ShockBeamRing",pos);
r.angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x);
r.pitch = asin(-t.Results.HitVector.z);
@ -391,7 +393,7 @@ Class ShockBeam : Actor
action void A_BeamExplode()
{
Spawn("ShockBeamLight",pos);
A_QuakeEx(2,2,2,5,0,120,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
A_QuakeEx(2,2,2,5,0,120,"",QF_RELATIVE|QF_SCALEDOWN,falloff:60,rollIntensity:0.1);
A_PlaySound("shock/hit",CHAN_VOICE);
A_AlertMonsters();
int numpt = Random[ASMD](20,50);
@ -503,6 +505,7 @@ Class SuperShockBeam : Actor
+FORCEXYBILLBOARD;
+FORCERADIUSDMG;
+EXTREMEDEATH;
+NODAMAGETHRUST;
}
override void PostBeginPlay()
{
@ -556,9 +559,10 @@ Class SuperShockBeam : Actor
{
if ( target ) target.TakeInventory('EnhancedShockAmmo',1);
let b = t.Results.HitActor.target;
UTMainHandler.DoBlast(b,400,70000);
b.ExplodeMissile(null,self);
b.A_Explode(Random[ASMD](15000,16000),400);
b.A_QuakeEx(9,9,9,60,0,2400,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.4);
b.A_QuakeEx(9,9,9,60,0,2400,"",QF_RELATIVE|QF_SCALEDOWN,falloff:400,rollIntensity:0.4);
b.A_SprayDecal("BigShockMark1",100);
b.A_SprayDecal("SBigShockMark2",100);
Spawn("SuperShockRifleWave",b.pos);
@ -578,7 +582,8 @@ Class SuperShockBeam : Actor
}
else
{
t.Results.HitActor.DamageMobj(self,target,Random[ASMD](3500,5000),'joltedX',DMG_USEANGLE,atan2(t.Results.HitVector.y,t.Results.HitVector.x));
t.Results.HitActor.DamageMobj(self,target,Random[ASMD](3500,5000),'joltedX',DMG_USEANGLE|DMG_THRUSTLESS,atan2(t.Results.HitVector.y,t.Results.HitVector.x));
UTMainHandler.DoKnockback(t.Results.HitActor,t.Results.HitVector,60000);
let r = Spawn("SuperShockBeamRing",pos);
r.angle = atan2(t.Results.HitVector.y,t.Results.HitVector.x);
r.pitch = asin(-t.Results.HitVector.z);
@ -612,8 +617,12 @@ Class SuperShockBeam : Actor
action void A_BeamExplode()
{
Spawn("SuperShockBeamLight",pos);
A_Explode(Random[ASMD](500,800),90);
A_QuakeEx(6,6,6,5,0,200,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.2);
if ( !CVar.GetCVar('flak_classicsshock').GetBool() )
{
UTMainHandler.DoBlast(self,90,60000);
A_Explode(Random[ASMD](500,800),90);
}
A_QuakeEx(6,6,6,5,0,200,"",QF_RELATIVE|QF_SCALEDOWN,falloff:90,rollIntensity:0.2);
A_PlaySound("shock/hit",CHAN_VOICE,attenuation:0.5);
A_PlaySound("sshock/blast",CHAN_6,attenuation:0.5);
A_AlertMonsters();
@ -819,6 +828,7 @@ Class ShockBall : Actor
}
action void A_BallExplode()
{
UTMainHandler.DoBlast(self,70,70000);
A_Explode(Random[ASMD](40,50),70);
A_SprayDecal("ShockMarkBig",16);
Spawn("ShockExplLight",pos);
@ -829,7 +839,7 @@ Class ShockBall : Actor
r.scale *= 1.5;
A_PlaySound("shock/hit",CHAN_VOICE);
A_PlaySound("shock/ball",CHAN_WEAPON);
A_QuakeEx(4,4,4,30,0,200,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.15);
A_QuakeEx(4,4,4,30,0,200,"",QF_RELATIVE|QF_SCALEDOWN,falloff:70,rollIntensity:0.15);
A_AlertMonsters();
int numpt = Random[ASMD](50,100);
for ( int i=0; i<numpt; i++ )
@ -844,16 +854,16 @@ Class ShockBall : Actor
Obituary "%k inflicted mortal damage upon %o with the Shock Rifle";
RenderStyle "Add";
DamageType 'jolted';
DamageFunction Random[ASMD](50,60);
Radius 2;
Height 2;
Scale 0.4;
Speed 20;
ProjectileKickback 250;
PROJECTILE;
+FORCEXYBILLBOARD;
+SKYEXPLODE;
+EXPLODEONWATER;
+FORCERADIUSDMG;
+NODAMAGETHRUST;
}
States
{
@ -882,6 +892,7 @@ Class SuperShockBall : Actor
}
action void A_BallExplode()
{
UTMainHandler.DoBlast(self,120,70000);
A_Explode(Random[ASMD](4000,5000),120);
A_SprayDecal("ShockMarkBig",16);
Spawn("SuperShockExplLight",pos);
@ -893,7 +904,7 @@ Class SuperShockBall : Actor
A_PlaySound("shock/hit",CHAN_VOICE,attenuation:0.5);
A_PlaySound("shock/ball",CHAN_WEAPON,attenuation:0.5);
A_PlaySound("sshock/blast",CHAN_6,attenuation:0.5);
A_QuakeEx(8,8,8,30,0,300,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
A_QuakeEx(8,8,8,30,0,300,"",QF_RELATIVE|QF_SCALEDOWN,falloff:120,rollIntensity:0.25);
A_AlertMonsters();
int numpt = Random[ASMD](50,100);
for ( int i=0; i<numpt; i++ )
@ -908,7 +919,6 @@ Class SuperShockBall : Actor
Obituary "%k electrified %o with the Enhanced Shock Rifle.";
RenderStyle "Add";
DamageType 'joltedX';
DamageFunction Random[ASMD](5000,6000);
Radius 2;
Height 2;
Scale 0.5;
@ -919,6 +929,8 @@ Class SuperShockBall : Actor
+FORCERADIUSDMG;
+EXTREMEDEATH;
+EXPLODEONWATER;
+FORCERADIUSDMG;
+NODAMAGETHRUST;
}
States
{
@ -1101,6 +1113,17 @@ Class ShockRifle : UTWeapon
Class EnhancedShockAmmo : Ammo
{
int ticcnt;
override void Tick()
{
Super.Tick();
if ( !Owner ) return;
ticcnt++;
if ( ticcnt < 105 ) return;
ticcnt = 0;
if ( Amount > 0 ) Amount--;
}
Default
{
Tag "Enhanced Shock Core";
@ -1132,17 +1155,6 @@ Class ViewSuperShockSpark : ViewShockSpark
Class EnhancedShockRifle : UTWeapon replaces InvulnerabilitySphere
{
int ticcnt;
override void Tick()
{
Super.Tick();
if ( !Owner ) return;
ticcnt++;
if ( ticcnt < 105 ) return;
ticcnt = 0;
DepleteAmmo(false,true,1);
}
action void A_SShockFire()
{
Weapon weap = Weapon(invoker);
@ -1259,6 +1271,7 @@ Class EnhancedShockRifle : UTWeapon replaces InvulnerabilitySphere
ASMF BCDEFGHIJJ 2;
Goto Idle;
AltFire:
ASMI A 0 A_JumpIf(CVar.GetCVar('flak_classicsshock').GetBool(),"Fire");
ASMI A 0 A_JumpIfNoAmmo("DryFire");
ASMA A 1 A_SShockAlt();
ASMA BCDFGHIJ 2;

View file

@ -96,8 +96,15 @@ Class SniperRifle : UTWeapon
{
int dmg = Random[Sniper](45,60);
if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.8) )
dmg = d.HitActor.DamageMobj(invoker,self,dmg+70,'Decapitated',DMG_USEANGLE,atan2(d.HitDir.y,d.HitDir.x));
else dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE,atan2(d.HitDir.y,d.HitDir.x));
{
dmg = d.HitActor.DamageMobj(invoker,self,dmg+70,'Decapitated',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,35000);
}
else
{
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,30000);
}
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("BulletImpact",d.HitLocation);

View file

@ -1012,4 +1012,25 @@ Class UTMainHandler : StaticEventHandler
let hnd = UTMainHandler(StaticEventHandler.Find("UTMainHandler"));
hnd.flashes.push(qf);
}
// Doom's explosions aren't fully 3D
static void DoBlast( Actor Source, double ExplosionRadius, double MomentumTransfer )
{
BlockThingsIterator bi = BlockThingsIterator.Create(Source,ExplosionRadius);
while ( bi.Next() )
{
Actor a = bi.Thing;
if ( !a || !a.bSHOOTABLE || !Source.CheckSight(a,0xf) || (a == Source) || (Source.Distance3D(a) > ExplosionRadius) )
continue;
Vector3 midpoint = a.Vec3Offset(0,0,a.height*0.5);
a.vel += Level.Vec3Diff(Source.pos,midpoint).unit()*(MomentumTransfer/(Thinker.TICRATE*a.mass));
}
}
// Same for this
static void DoKnockback( Actor Victim, Vector3 HitDirection, double MomentumTransfer )
{
if ( !Victim ) return;
Victim.vel += HitDirection*(MomentumTransfer/(Thinker.TICRATE*Victim.Mass));
}
}

View file

@ -42,7 +42,7 @@ Class ShockWave : Actor
{
lifespan = ReactionTime;
A_PlaySound("warhead/explode",CHAN_VOICE,attenuation:ATTN_NONE);
A_QuakeEx(9,9,9,100,0,12000,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.5);
A_QuakeEx(9,9,9,100,0,12000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:1200,rollIntensity:0.5);
}
override void Tick()
{
@ -61,7 +61,7 @@ Class ShockWave : Actor
t.Reinit();
while ( a = Actor(t.Next()) )
{
if ( !a.bShootable || !CheckSight(a) || (Distance3D(a) > dmgradius) ) continue;
if ( !a.bShootable || !CheckSight(a,0xf) || (Distance3D(a) > dmgradius) ) continue;
Vector3 dir = Vec3To(a);
double dist = max(1,dir.length());
dir = dir/dist+(0,0,0.3);