Changed Pulse Beam size to be the same as in UT99 (10 81-unit segments).

Tweaked Starter Bolt textures to look better in first person.
Tweaked Pulse Beam model UVs to reduce seams.
Switched Chainsaw alt-fire to damage in an arc.
Rebalanced damages of Chainsaw, Enforcer, Biorifle, Pulsegun, Minigun, Flak Cannon.
Adjusted Redeemer damage formula.
Added view flash to Redeemer shockwave.
Reduced Enforcer fire speed.
Reduced delay of Minigun altfire. Should happen after exactly one cycle.
Increased knockback of Impact Hammer.
This commit is contained in:
Marisa the Magician 2018-08-12 01:49:00 +02:00
commit 36a3598826
17 changed files with 52 additions and 101 deletions

View file

@ -409,7 +409,7 @@ 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](20,40)*Scale.x),Min(150,int(Scale.x*25)));
A_Explode(int(Random[GES](10,15)*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++ )
@ -435,13 +435,13 @@ Class BioGel : Actor
{
Obituary "%o drank a glass of %k's dripping green load.";
DamageType 'Slime';
DamageFunction int(Random[GES](20,40)*Scale.x);
DamageFunction int(Random[GES](10,15)*max(1,(Scale.x-1)**2));
RenderStyle "Add";
Radius 3;
Height 3;
Scale 2;
Speed 18;
ProjectileKickback 220;
ProjectileKickback 120;
PROJECTILE;
-NOGRAVITY;
+SKYEXPLODE;
@ -529,7 +529,7 @@ Class BioGlob : BioGel
d.scale *= FRandom[GES](0.5,0.7);
d.angle = atan2(dir.y,dir.x);
d.pitch = -asin(dir.z);
d.vel = (cos(d.angle)*cos(d.pitch),sin(d.angle)*cos(d.pitch),-sin(d.pitch))*d.speed*FRandom[GES](0.25,0.35);
d.vel = (cos(d.angle)*cos(d.pitch),sin(d.angle)*cos(d.pitch),-sin(d.pitch))*d.speed*FRandom[GES](0.3,0.4);
d.vel.z -= 3;
}
}
@ -572,7 +572,7 @@ Class BioRifle : UTWeapon
if ( alt )
{
p = Spawn("BioGlob",origin);
p.A_SetScale(1+0.8*invoker.charge);
p.A_SetScale(1.0+invoker.charge*0.8);
}
else p = Spawn("BioGel",origin);
p.angle = angle;

View file

@ -101,10 +101,11 @@ Class UTChainsaw : UTWeapon
[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);
double ang = (angle-45)+90*invoker.sawcnt;
LineTrace(ang,90,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType == TRACE_HitActor )
{
int dmg = Random[Chainsaw](50,60);
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));
@ -130,6 +131,7 @@ Class UTChainsaw : UTWeapon
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.2;
}
override void DetachFromOwner()
{
@ -139,6 +141,7 @@ Class UTChainsaw : UTWeapon
}
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);
@ -239,9 +242,9 @@ Class UTChainsaw : UTWeapon
Goto Idle;
AltFire:
CSWA A 0 A_PlaySound("chainsaw/fire",CHAN_6);
CSWA ABCDEFG 2 A_Vibrate(true);
CSWA H 2 A_SawSwipe();
CSWA IJK 2 A_Vibrate(true);
CSWA ABCDE 2 A_Vibrate(true);
CSWA FGHIJ 2 A_SawSwipe();
CSWA K 2 A_Vibrate(true);
CSWA K 0 A_PlaySound("chainsaw/idle",CHAN_6,looping:true);
Goto Ready;
Deselect:

View file

@ -312,7 +312,7 @@ Class Enforcer : UTWeapon replaces Pistol
LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType == TRACE_HitActor )
{
int dmg = Random[Enforcer](15,20);
int dmg = Random[Enforcer](12,17);
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE,atan2(d.HitDir.y,d.HitDir.x));
if ( d.HitActor.bNOBLOOD )
{
@ -458,18 +458,20 @@ Class Enforcer : UTWeapon replaces Pistol
Hold:
ENFF A 0 A_EnforcerFire();
ENFF ABCDEFGHIJ 1;
ENFF J 5;
ENFF J 0 A_EnforcerRefire();
ENFF J 2;
ENFI A 0;
Goto Idle;
LeftFire:
2NFI A 0 A_Overlay(-9998,"Null");
2NFI A 1 A_SetTics(Random[Enforcer](5,6));
2NFI A 8;
2NFI A 0 A_EnforcerRefire(1,true);
Goto LeftIdle;
LeftHold:
2NFF A 0 A_EnforcerFire(false,true);
2NFF ABCDEFGHIJ 1;
2NFF J 5;
2NFF J 0 A_EnforcerRefire("LeftHold",true);
2NFF J 2;
2NFI A 0;
@ -480,18 +482,20 @@ Class Enforcer : UTWeapon replaces Pistol
AltHold:
ENFA G 0 A_EnforcerFire(true);
ENFA GHIJKLMN 1;
ENFA N 3;
ENFA G 0 A_EnforcerRefire();
ENFA OPQRSTU 1;
Goto Idle;
LeftAltFire:
2NFI A 0 A_Overlay(-9998,"Null");
2NFI A 1 A_SetTics(Random[Enforcer](5,6));
2NFI A 7;
2NFI A 0 A_EnforcerRefire(1,true);
Goto LeftIdle;
2NFA ABCDEF 1;
LeftAltHold:
2NFA G 0 A_EnforcerFire(true,true);
2NFA GHIJKLMN 1;
2NFA N 3;
2NFA G 0 A_EnforcerRefire("LeftAltHold",true);
2NFA OPQRSTU 1;
Goto LeftIdle;

View file

@ -140,7 +140,7 @@ Class FlakChunk : Actor
Radius 2;
Height 2;
Speed 50;
DamageFunction Random[Flak](25,35);
DamageFunction int(Random[Flak](15,20)*max(0.1,1.0-lifetime*4.1));
DamageType 'Shredded';
BounceType "Doom";
BounceFactor 0.8;
@ -189,7 +189,7 @@ Class FlakChunk : Actor
if ( frame < 11 ) frame++;
}
lifetime += lifespeed;
if ( (waterlevel <= 0) && (frame < 10) )
if ( (waterlevel <= 0) && (frame < 10) && !(lifetics%2) )
{
let s = Spawn("UTSmoke",pos);
s.vel = (FRandom[Flak](-0.1,0.1),FRandom[Flak](-0.1,0.1),FRandom[Flak](-0.1,0.1));
@ -212,7 +212,7 @@ Class FlakChunk : Actor
{
invoker.hasbounced = true;
A_SprayDecal("WallCrack",-8);
int numpt = Random[Flak](3,6);
int numpt = Random[Flak](2,3);
if ( frame < 10 )
{
for ( int i=0; i<numpt; i++ )
@ -359,7 +359,7 @@ Class FlakSlug : Actor
{
Obituary "%o was ripped to shreds by %k's Flak Cannon.";
DamageType 'FlakDeath';
DamageFunction Random[Flak](80,90);
DamageFunction Random[Flak](100,110);
Radius 2;
Height 2;
Speed 40;
@ -397,7 +397,7 @@ Class FlakSlug : Actor
double a, s;
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
Actor p;
for ( int i=0; i<8; i++ )
for ( int i=0; i<6; i++ )
{
p = Spawn("FlakChunk",pos);
a = FRandom[Flak](0,360);
@ -408,14 +408,14 @@ Class FlakSlug : Actor
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed*FRandom[Flak](0.5,1.5);
p.target = target;
}
int numpt = Random[Flak](10,20);
int numpt = Random[Flak](8,12);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Flak](-1,1),FRandom[Flak](-1,1),FRandom[Flak](-1,1)).unit()*FRandom[Flak](2,8);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
numpt = Random[Flak](40,80);
numpt = Random[Flak](15,30);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Flak](-1,1),FRandom[Flak](-1,1),FRandom[Flak](-1,1)).unit()*FRandom[Flak](6,16);
@ -488,13 +488,13 @@ Class FlakCannon : UTWeapon
Vector3 x, y, z;
double a, s;
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-3.0*z;
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+4.0*y-3.0*z;
A_Overlay(-2,"MuzzleFlash");
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
A_OverlayRenderstyle(-2,STYLE_Add);
[x, y, z] = Matrix4.GetAxes(BulletSlope(),angle,roll);
Actor p;
for ( int i=0; i<12; i++ )
for ( int i=0; i<10; i++ )
{
p = Spawn("FlakChunk",origin);
a = FRandom[Flak](0,360);

View file

@ -77,7 +77,7 @@ Class ImpactHammer : UTWeapon replaces Fist
{
int dmg = int(Random[Impact](90,120)*realcharge);
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'impact',DMG_THRUSTLESS);
d.HitActor.vel = x*(2000/d.HitActor.mass)*realcharge;
d.HitActor.vel = x*(8000/d.HitActor.mass)*realcharge;
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("HammerImpact",d.HitLocation-d.HitDir*4);
@ -139,7 +139,7 @@ Class ImpactHammer : UTWeapon replaces Fist
{
int dmg = int(Random[Impact](25,35)*dscale);
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'impact',DMG_THRUSTLESS);
d.HitActor.vel = x*(900/d.HitActor.mass)*dscale;
d.HitActor.vel = x*(4000/d.HitActor.mass)*dscale;
}
else if ( d.HitType != TRACE_HitNone )
{

View file

@ -123,7 +123,7 @@ Class Minigun : UTWeapon
LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType == TRACE_HitActor )
{
int dmg = Random[Minigun](12,18); // fun fact: the Minigun is one of the few weapons that has actual RNG damage in UT
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));
if ( d.HitActor.bNOBLOOD )
{
@ -161,11 +161,12 @@ Class Minigun : UTWeapon
t.pitch = asin(-dir.z);
MinigunTracer(t).dest = d.HitLocation;
}
for ( int i=0; i<8; i++ )
for ( int i=0; i<4; i++ )
{
let s = Spawn("UTViewSmoke",origin);
UTViewSmoke(s).ofs = (10,2,-2);
s.scale *= 1.5;
s.alpha *= 0.6;
UTViewSmoke(s).vvel += (FRandom[Minigun](0.2,0.8),FRandom[Minigun](-0.3,0.3),FRandom[Minigun](-0.3,0.3));
s.target = self;
}
@ -306,64 +307,6 @@ Class Minigun : UTWeapon
else A_MinigunRefire("Hold");
}
Goto Unwind;
AltFire2:
MGNF A 1 A_FireBullet();
MGNF B 0 A_MinigunRefire(1);
Goto Unwind;
MGNF B 1 A_FireBullet();
MGNF C 0 A_MinigunRefire(1);
Goto Unwind;
MGNF C 1 A_FireBullet();
MGNF D 0 A_MinigunRefire(1);
Goto Unwind;
MGNF D 1 A_FireBullet();
MGNF E 0 A_MinigunRefire(1);
Goto Unwind;
MGNF E 1 A_FireBullet();
MGNF F 0 A_MinigunRefire(1);
Goto Unwind;
MGNF F 1 A_FireBullet();
MGNF G 0 A_MinigunRefire(1);
Goto Unwind;
MGNF G 1 A_FireBullet();
MGNF H 0 A_MinigunRefire(1);
Goto Unwind;
MGNF H 1 A_FireBullet();
MGNF I 0 A_MinigunRefire(1);
Goto Unwind;
MGNF I 1 A_FireBullet();
MGNF J 0 A_MinigunRefire(1);
Goto Unwind;
MGNF J 1 A_FireBullet();
MGNF K 0 A_MinigunRefire(1);
Goto Unwind;
MGNF K 1 A_FireBullet();
MGNF L 0 A_MinigunRefire(1);
Goto Unwind;
MGNF L 1 A_FireBullet();
MGNF M 0 A_MinigunRefire(1);
Goto Unwind;
MGNF M 1 A_FireBullet();
MGNF N 0 A_MinigunRefire(1);
Goto Unwind;
MGNF N 1 A_FireBullet();
MGNF O 0 A_MinigunRefire(1);
Goto Unwind;
MGNF O 1 A_FireBullet();
MGNF P 0 A_MinigunRefire(1);
Goto Unwind;
MGNF P 1 A_FireBullet();
MGNF Q 0 A_MinigunRefire(1);
Goto Unwind;
MGNF Q 1 A_FireBullet();
MGNF R 0 A_MinigunRefire(1);
Goto Unwind;
MGNF R 1 A_FireBullet();
MGNF S 0 A_MinigunRefire(1);
Goto Unwind;
MGNF S 1 A_FireBullet();
MGNF A 0 A_MinigunRefire(1);
Goto Unwind;
AltHold:
MGNF A 1
{

View file

@ -241,7 +241,7 @@ Class PulseBoltLight : DynamicLight
Default
{
DynamicLight.Type "Point";
Args 32,128,0,40;
Args 32,128,0,80;
}
override void Tick()
{
@ -252,7 +252,7 @@ Class PulseBoltLight : DynamicLight
return;
}
SetOrigin(target.pos,true);
args[LIGHT_INTENSITY] = Random[Pulse](30,50);
args[LIGHT_INTENSITY] = Random[Pulse](60,100);
}
}
@ -307,7 +307,7 @@ Class PulseBoltCap : Actor
+NOCLIP;
+DONTSPLASH;
+FORCEXYBILLBOARD;
Scale 0.15;
Scale 0.3;
}
States
{
@ -345,7 +345,7 @@ Class PulseBoltHit : Actor
+NOCLIP;
+DONTSPLASH;
+FORCEXYBILLBOARD;
Scale 0.15;
Scale 0.3;
}
States
{
@ -357,7 +357,7 @@ Class PulseBoltHit : Actor
Class PulseBolt : Actor
{
const beamsize = 40.5;
const beamsize = 81.0;
PulseBoltTracer t;
double accdamage;
@ -391,20 +391,20 @@ Class PulseBolt : Actor
if ( !damagedactor )
{
accdamage = min(0.5*(level.time-lasthit),0.1);
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](70,80)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](70,90)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
accdamage = 0;
}
else if ( t.Results.HitActor != damagedactor )
{
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](70,80)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](70,90)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
accdamage = 0;
}
lasthit = level.time;
damagedactor = t.Results.HitActor;
accdamage += 1./TICRATE;
if ( accdamage > 0.16 )
if ( accdamage > 0.17 )
{
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](70,80)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](70,90)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
accdamage = 0;
}
}
@ -450,7 +450,7 @@ Class PulseBolt : Actor
accdamage = 0;
damagedactor = null;
}
if ( position >= 19 )
if ( position >= 9 )
{
int numpt = Random[Pulse](5,10)*!Random[Pulse](0,5);
for ( int i=0; i<numpt; i++ )
@ -534,7 +534,7 @@ Class StarterBolt : PulseBolt
if ( target.player )
{
[x, y, z] = Matrix4.GetAxes(target.pitch,target.angle,target.roll);
origin = target.Vec2OffsetZ(0,0,target.player.viewz)+10.0*x+4.1*y-2.7*z;
origin = target.Vec2OffsetZ(0,0,target.player.viewz)+8.0*x+4.1*y-2.7*z;
}
else origin = target.Vec3Offset(0,0,target.missileheight);
SetOrigin(origin,true);

View file

@ -66,11 +66,12 @@ Class ShockWave : Actor
double dist = max(1,dir.length());
dir = dir/dist+(0,0,0.3);
double moscale = max(0,1100-0.22*dist);
if ( (dist > olddmgradius) || (dir dot a.vel < 0) )
if ( (dist > olddmgradius-a.radius) || (dir dot a.vel <= 0) )
{
if ( !a.bDONTTHRUST ) a.vel += dir*((moscale+20)/a.mass);
a.DamageMobj(self,target,int(moscale),'RedeemerDeath',DMG_THRUSTLESS);
}
if ( a.player ) UTMainHandler.DoFlash(a,Color(32,255,255,255),80);
}
olddmgradius = dmgradius;
}