Various rebalances. Corrected some things that weren't 1:1 with UT.
Restored original flak chunk damage function (no longer falls off with distance). Fixed the minigun altfire shooting bullets at the same speed as the primary fire. Small hackaround for janky player movement while moving down slopes. [WIP] The very beginning of an UT gore system (toggleable).
This commit is contained in:
parent
c8774f0a11
commit
1c0f7d08a5
11 changed files with 99 additions and 34 deletions
|
|
@ -306,6 +306,7 @@ Class Enforcer : UTWeapon
|
|||
if ( alt ) origin = origin-z*3.0+ydir*y*1.0;
|
||||
else origin = origin-z*1.0+ydir*y*4.0;
|
||||
double a = FRandom[Enforcer](0,360), s = FRandom[Enforcer](0,alt?0.08:0.004);
|
||||
if ( invoker.SlaveActive ) s *= 3;
|
||||
[x2, y2, z2] = Matrix4.GetAxes(BulletSlope(),angle,roll);
|
||||
Vector3 dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
|
||||
FLineTraceData d;
|
||||
|
|
@ -314,7 +315,9 @@ Class Enforcer : UTWeapon
|
|||
{
|
||||
int dmg = Random[Enforcer](12,17);
|
||||
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);
|
||||
double mm = 3000;
|
||||
if ( FRandom[Enforcer](0,1) < 0.2 ) mm *= 5;
|
||||
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,mm);
|
||||
if ( d.HitActor.bNOBLOOD )
|
||||
{
|
||||
let p = Spawn("BulletImpact",d.HitLocation);
|
||||
|
|
|
|||
|
|
@ -107,7 +107,6 @@ Class ChunkTrail : Actor
|
|||
|
||||
Class FlakChunk : Actor
|
||||
{
|
||||
Actor lasthit;
|
||||
ChunkTrail trail;
|
||||
double rollvel, pitchvel, yawvel;
|
||||
double lifetime, lifespeed;
|
||||
|
|
@ -118,7 +117,7 @@ Class FlakChunk : Actor
|
|||
Radius 2;
|
||||
Height 2;
|
||||
Speed 50;
|
||||
DamageFunction int(Random[Flak](15,20)*max(0.1,1.0-lifetime*4.1));
|
||||
DamageFunction Random[Flak](15,20);
|
||||
DamageType 'Shredded';
|
||||
BounceType "Doom";
|
||||
BounceFactor 0.8;
|
||||
|
|
@ -130,10 +129,6 @@ Class FlakChunk : Actor
|
|||
+SKYEXPLODE;
|
||||
Scale 0.3;
|
||||
}
|
||||
override bool CanCollideWith( Actor other, bool passive )
|
||||
{
|
||||
return (vel.length()>4.0);
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
|
|
@ -208,17 +203,17 @@ Class FlakChunk : Actor
|
|||
A_PlaySound("flak/bounce",volume:0.3);
|
||||
A_AlertMonsters();
|
||||
bBOUNCEAUTOOFFFLOORONLY = true;
|
||||
if ( vel.length() < 4.0 ) ExplodeMissile();
|
||||
if ( vel.length() < 5.0 ) ExplodeMissile();
|
||||
}
|
||||
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
|
||||
{
|
||||
if ( vel.length() <= 5.0 ) return 0;
|
||||
if ( !target.bNOBLOOD )
|
||||
{
|
||||
if ( target != lasthit ) target.SpawnBlood(pos,AngleTo(target),damage);
|
||||
target.SpawnBlood(pos,AngleTo(target),damage);
|
||||
A_PlaySound("flak/meat",volume:0.3);
|
||||
A_AlertMonsters();
|
||||
}
|
||||
lasthit = target;
|
||||
return damage;
|
||||
}
|
||||
States
|
||||
|
|
@ -377,7 +372,7 @@ Class FlakSlug : Actor
|
|||
double a, s;
|
||||
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
|
||||
Actor p;
|
||||
for ( int i=0; i<6; i++ )
|
||||
for ( int i=0; i<5; i++ )
|
||||
{
|
||||
p = Spawn("FlakChunk",pos);
|
||||
p.bHITOWNER = true;
|
||||
|
|
@ -475,7 +470,7 @@ Class FlakCannon : UTWeapon
|
|||
A_OverlayRenderstyle(-2,STYLE_Add);
|
||||
[x, y, z] = Matrix4.GetAxes(BulletSlope(),angle,roll);
|
||||
Actor p;
|
||||
for ( int i=0; i<10; i++ )
|
||||
for ( int i=0; i<6; i++ )
|
||||
{
|
||||
p = Spawn("FlakChunk",origin);
|
||||
a = FRandom[Flak](0,360);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ Class ImpactHammer : UTWeapon
|
|||
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+3.0*y-4.0*z;
|
||||
double realcharge = min(1.5,invoker.chargesize);
|
||||
FLineTraceData d;
|
||||
LineTrace(angle,80,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
||||
LineTrace(angle,60,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
||||
if ( d.HitType == TRACE_HitActor )
|
||||
{
|
||||
int dmg = int(Random[Impact](90,120)*realcharge);
|
||||
|
|
@ -133,8 +133,8 @@ Class ImpactHammer : UTWeapon
|
|||
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+3.0*y-4.0*z;
|
||||
FLineTraceData d;
|
||||
LineTrace(angle,180,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
||||
double dscale = d.Distance/180.;
|
||||
LineTrace(angle,120,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
||||
double dscale = d.Distance/120.;
|
||||
if ( d.HitType == TRACE_HitActor )
|
||||
{
|
||||
int dmg = int(Random[Impact](25,35)*dscale);
|
||||
|
|
@ -156,10 +156,10 @@ Class ImpactHammer : UTWeapon
|
|||
if ( !m.bMISSILE ) continue;
|
||||
double rdist = level.Vec3Diff(origin,m.pos).length();
|
||||
Vector3 rdir = level.Vec3Diff(origin,m.pos).unit();
|
||||
if ( LineTrace(atan2(rdir.y,rdir.x),rdist,asin(-rdir.z),TRF_THRUACTORS|TRF_ABSPOSITION,origin.z,origin.x,origin.y) || (rdist > 550) || (rdir dot x < 0.9) ) continue;
|
||||
if ( LineTrace(atan2(rdir.y,rdir.x),rdist,asin(-rdir.z),TRF_THRUACTORS|TRF_ABSPOSITION,origin.z,origin.x,origin.y) || (rdist > 400) || (rdir dot x < 0.9) ) continue;
|
||||
m.speed = m.vel.length();
|
||||
if ( m.vel dot y > 0 ) m.vel = m.speed*(m.vel+(750-rdist)*y*0.01).unit();
|
||||
else m.vel = m.speed*(m.vel-(750-rdist)*y*0.01).unit();
|
||||
if ( m.vel dot y > 0 ) m.vel = m.speed*(m.vel+(560-rdist)*y*0.01).unit();
|
||||
else m.vel = m.speed*(m.vel-(560-rdist)*y*0.01).unit();
|
||||
if ( m.target == self ) continue;
|
||||
if ( m.bSEEKERMISSILE ) m.tracer = m.target;
|
||||
m.target = self;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ Class MinigunTracer : Actor
|
|||
|
||||
Class Minigun : UTWeapon
|
||||
{
|
||||
int bcnt;
|
||||
int bcnt, tcnt;
|
||||
|
||||
action void A_FireBullet( bool alt = false )
|
||||
{
|
||||
|
|
@ -79,7 +79,8 @@ Class Minigun : UTWeapon
|
|||
A_Overlay(-2,"MuzzleFlash",true);
|
||||
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
|
||||
A_OverlayRenderstyle(-2,STYLE_Add);
|
||||
if ( (alt && (invoker.bcnt++ < 2)) || (invoker.bcnt++ < 4) ) return;
|
||||
invoker.bcnt++;
|
||||
if ( (alt && (invoker.bcnt < 2)) || (!alt && (invoker.bcnt < 4)) ) return;
|
||||
invoker.bcnt = 0;
|
||||
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
||||
invoker.FireEffect();
|
||||
|
|
@ -100,9 +101,11 @@ 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](16,20); // fun fact: the Minigun is one of the few weapons that has actual RNG damage in UT
|
||||
int dmg = Random[Minigun](9,18); // 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|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
|
||||
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,dmg*500);
|
||||
double mm = 500;
|
||||
if ( FRandom[Minigun](0,1) < 0.2 ) mm *= 2.5;
|
||||
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,dmg*mm);
|
||||
if ( d.HitActor.bNOBLOOD )
|
||||
{
|
||||
let p = Spawn("BulletImpact",d.HitLocation);
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ Class Razor2 : Actor
|
|||
{
|
||||
Radius 2;
|
||||
Height 2;
|
||||
Speed 40; // should be 26 but it looks way too slow
|
||||
DamageFunction (Random[Ripper](30,40)*((DamageType=='Decapitated')?3.5:1.0));
|
||||
DamageType 'Ripper';
|
||||
Speed 27;
|
||||
DamageFunction (Random[Ripper](25,35)*((DamageType=='Decapitated')?3.5:1.0));
|
||||
DamageType 'Shredded';
|
||||
Obituary "%k ripped a chunk of meat out of %o with the Ripper.";
|
||||
BounceType "Doom";
|
||||
ReactionTime 7;
|
||||
|
|
@ -84,7 +84,7 @@ Class Razor2 : Actor
|
|||
}
|
||||
override int SpecialMissileHit( Actor victim )
|
||||
{
|
||||
if ( pos.z > victim.pos.z+victim.height*0.75 ) DamageType = 'Decapitated';
|
||||
if ( pos.z > victim.pos.z+victim.height*0.81 ) DamageType = 'Decapitated';
|
||||
return -1;
|
||||
}
|
||||
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
|
||||
|
|
@ -135,7 +135,7 @@ Class Razor2 : Actor
|
|||
Bounce:
|
||||
RAZB A 0
|
||||
{
|
||||
bHITOWNER = true;
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ Class SniperRifle : UTWeapon
|
|||
if ( d.HitType == TRACE_HitActor )
|
||||
{
|
||||
int dmg = Random[Sniper](45,60);
|
||||
if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.8) )
|
||||
if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.81) )
|
||||
{
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Class UTPlayer : DoomPlayer
|
||||
{
|
||||
bool lastground;
|
||||
int lastgroundtic;
|
||||
double lastvelz, prevvelz;
|
||||
transient CVar footsteps, utmovement, doomspeed, doomaircontrol, nowalkdrop;
|
||||
Vector2 acceleration;
|
||||
|
|
@ -190,15 +191,15 @@ Class UTPlayer : DoomPlayer
|
|||
if ( player.onground && !bNoGravity && !lastground && (waterlevel < 3) )
|
||||
{
|
||||
player.jumptics = 0;
|
||||
if ( lastvelz < -4 )
|
||||
if ( lastvelz < -8 )
|
||||
{
|
||||
double vol = clamp((-lastvelz-4)*0.05,0.01,1.0);
|
||||
double vol = clamp((-lastvelz-8)*0.05,0.01,1.0);
|
||||
if ( ((waterlevel > 0) || GetFloorTerrain().IsLiquid) && !bOnMobj ) A_PlaySound("ut/wetsplash",CHAN_AUTO,vol);
|
||||
else A_PlaySound("*uland",CHAN_AUTO,vol);
|
||||
}
|
||||
else forcefootstep = true;
|
||||
}
|
||||
if ( forcefootstep || ((abs(sin(ang)) >= 1.0) && player.onground && (player.cmd.forwardmove || player.cmd.sidemove) && (waterlevel < 3)) )
|
||||
if ( forcefootstep || ((abs(sin(ang)) >= 1.0) && player.onground && lastground && (player.jumptics == 0) && (player.cmd.forwardmove || player.cmd.sidemove) && (waterlevel < 3)) )
|
||||
{
|
||||
double vol = abs(vel.xy.length())*0.03;
|
||||
if ( forcefootstep ) vol = clamp(-lastvelz*0.05,0.01,1.0);
|
||||
|
|
@ -237,6 +238,8 @@ Class UTPlayer : DoomPlayer
|
|||
}
|
||||
else Angle += cmd.yaw*(360./65536.);
|
||||
player.onground = (pos.z <= floorz) || bOnMobj || bMBFBouncer || (player.cheats & CF_NOCLIP2);
|
||||
if ( player.onground ) lastgroundtic = gametic;
|
||||
if ( (abs(lastgroundtic-gametic) < 4) && (player.jumptics == 0) ) player.onground = true;
|
||||
double friction = FrictionToUnreal();
|
||||
double fs = TweakSpeeds(1.0,0.0);
|
||||
if ( !doomspeed.GetBool() )
|
||||
|
|
@ -289,6 +292,7 @@ Class UTPlayer : DoomPlayer
|
|||
player.camera = player.mo;
|
||||
}
|
||||
player.vel *= 0;
|
||||
player.jumptics = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1102,6 +1106,54 @@ Class UTBlueKey : BlueCard
|
|||
}
|
||||
}
|
||||
|
||||
Class ShredCorpseHitbox : Actor
|
||||
{
|
||||
int accdamage;
|
||||
|
||||
Default
|
||||
{
|
||||
+NOGRAVITY;
|
||||
-SOLID;
|
||||
+DONTSPLASH;
|
||||
+SHOOTABLE;
|
||||
Health int.max;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
if ( !target )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
accdamage = target.Health;
|
||||
A_SetSize(target.radius,target.height);
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
if ( !target || (target.Health > 0) || target.InStateSequence(target.CurState,target.FindState("XDeath")) )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
SetOrigin(target.pos,true);
|
||||
A_SetSize(target.radius,target.height);
|
||||
}
|
||||
override int DamageMobj( Actor inflictor, Actor source, int damage, Name mod, int flags, double angle )
|
||||
{
|
||||
accdamage -= damage;
|
||||
int gibhealth = (target.GibHealth==int.min)?-target.SpawnHealth():target.GibHealth;
|
||||
if ( accdamage < gibhealth )
|
||||
{
|
||||
// force gib (cheap ATM)
|
||||
State gib = target.FindState("XDeath");
|
||||
if ( gib ) target.SetState(gib);
|
||||
Destroy();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Class GenericFlash : HUDMessageBase
|
||||
{
|
||||
Color col;
|
||||
|
|
@ -1445,6 +1497,15 @@ Class UTMainHandler : StaticEventHandler
|
|||
Screen.DrawTexture(tex,true,0,0,DTA_VirtualWidth,1024,DTA_VirtualHeight,768);
|
||||
}
|
||||
|
||||
override void WorldThingDied( WorldEvent e )
|
||||
{
|
||||
if ( e.Thing.bDONTGIB ) return;
|
||||
// attach damage accumulator for corpses
|
||||
if ( !CVar.GetCVar('flak_corpsedamage').GetBool() ) return;
|
||||
let a = Actor.Spawn("ShredCorpseHitbox",e.Thing.pos);
|
||||
a.target = e.Thing;
|
||||
}
|
||||
|
||||
static void DoFlash( Actor camera, Color c, int duration )
|
||||
{
|
||||
QueuedFlash qf = new("QueuedFlash");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue