Additional corpse hitbox features (zapping loop, land thumps, fall damage, etc.)
Corpse hitboxes and UT gibbing are enabled unconditionally for players. Added enter/exit sounds for swimming.
This commit is contained in:
parent
1535640c4a
commit
99edae06b9
6 changed files with 61 additions and 20 deletions
|
|
@ -166,6 +166,7 @@ ut/bossfootstep bfootstp
|
|||
|
||||
ut/playerfootstepwet lsplash
|
||||
ut/wetsplash dsplash
|
||||
ut/wetsurface wtrexit1
|
||||
|
||||
// everything else
|
||||
|
||||
|
|
@ -206,6 +207,7 @@ misc/gibp3 gibp4
|
|||
misc/gibp4 gibp5
|
||||
misc/gibp5 gibp6
|
||||
$random misc/gibp { misc/gibp1 misc/gibp2 misc/gibp3 misc/gibp4 misc/gibp5 }
|
||||
misc/corpsefall thump
|
||||
|
||||
impact/select imppick
|
||||
impact/pull impaltst
|
||||
|
|
|
|||
BIN
sounds/Thump.ogg
Normal file
BIN
sounds/Thump.ogg
Normal file
Binary file not shown.
BIN
sounds/WtrExit1.ogg
Normal file
BIN
sounds/WtrExit1.ogg
Normal file
Binary file not shown.
|
|
@ -142,13 +142,6 @@ Class Razor2 : Actor
|
|||
}
|
||||
Goto Spawn;
|
||||
Death:
|
||||
TNT1 A 0
|
||||
{
|
||||
angle += 180;
|
||||
pitch *= -1;
|
||||
A_RazorHit();
|
||||
}
|
||||
XDeath:
|
||||
TNT1 A 1 A_StopSound(CHAN_VOICE);
|
||||
Stop;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Class UTPlayer : DoomPlayer
|
||||
{
|
||||
bool lastground;
|
||||
int lastwaterlevel;
|
||||
int lastgroundtic;
|
||||
double lastvelz, prevvelz;
|
||||
transient CVar footsteps;
|
||||
|
|
@ -14,6 +15,7 @@ Class UTPlayer : DoomPlayer
|
|||
int tempslide;
|
||||
double ssup;
|
||||
int corpsetime;
|
||||
bool headless, legless;
|
||||
|
||||
int dolltype, voicetype;
|
||||
|
||||
|
|
@ -230,7 +232,7 @@ Class UTPlayer : DoomPlayer
|
|||
bNOFRICTIONBOUNCE = false;
|
||||
}
|
||||
if ( !footsteps ) footsteps = CVar.GetCVar('flak_footsteps',players[consoleplayer]);
|
||||
if ( !footsteps.GetBool() ) return;
|
||||
if ( !footsteps.GetBool() || (Health <= 0) ) return;
|
||||
double ang = level.time/(20*TICRATE/35.)*360.;
|
||||
bool forcefootstep = false;
|
||||
if ( player.onground && !bNoGravity && !lastground && (waterlevel < 2) )
|
||||
|
|
@ -241,9 +243,9 @@ Class UTPlayer : DoomPlayer
|
|||
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);
|
||||
PlayLanding();
|
||||
}
|
||||
else forcefootstep = true;
|
||||
if ( Health > 0 ) PlayLanding();
|
||||
}
|
||||
if ( tempslide )
|
||||
{
|
||||
|
|
@ -257,10 +259,14 @@ Class UTPlayer : DoomPlayer
|
|||
if ( (waterlevel > 0) || GetFloorTerrain().IsLiquid && !bOnMobj ) A_PlaySound("ut/playerfootstepwet",CHAN_5,vol);
|
||||
else PlayFootstep(vol);
|
||||
}
|
||||
if ( (waterlevel >= 2) && (lastwaterlevel < 2) )
|
||||
A_PlaySound("ut/wetsplash",CHAN_AUTO);
|
||||
else if ( (waterlevel < 2) && (lastwaterlevel >= 2) )
|
||||
A_PlaySound("ut/wetsurface",CHAN_AUTO);
|
||||
lastground = player.onground;
|
||||
lastvelz = prevvelz;
|
||||
prevvelz = vel.z;
|
||||
// TODO exit/entry sounds for water
|
||||
lastwaterlevel = waterlevel;
|
||||
}
|
||||
|
||||
double FrictionToUnreal()
|
||||
|
|
@ -873,6 +879,7 @@ Class UTPlayer : DoomPlayer
|
|||
|
||||
void A_HeadPop()
|
||||
{
|
||||
headless = true;
|
||||
Class<UTHead> hclass = "UTHeadMale";
|
||||
if ( DollType == DOLL_Boss ) hclass = "UTHeadBoss";
|
||||
else if ( DollType == DOLL_Female ) hclass = "UTHeadFemale";
|
||||
|
|
@ -904,6 +911,13 @@ Class UTPlayer : DoomPlayer
|
|||
if ( corpsetime > 350 ) A_FadeOut(0.03);
|
||||
}
|
||||
|
||||
override double GetDeathHeight()
|
||||
{
|
||||
// no height reduction while still being zapped
|
||||
if ( DamageType == 'Zapped' ) return height;
|
||||
return Super.GetDeathHeight();
|
||||
}
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
@ -1019,7 +1033,8 @@ Class UTPlayer : DoomPlayer
|
|||
PLD9 A 3 A_PlayerScream();
|
||||
PLD9 B 3 A_NoBlocking();
|
||||
PLD9 CDEFGHIJKLMNOPQRST 2;
|
||||
PD9B ABCDEFGHI 2;
|
||||
PD9B A 2 A_SetSize(-1,height*0.25); // reduce now
|
||||
PD9B BCDEFGHI 2;
|
||||
PD9B J 1 A_DMFade();
|
||||
Wait;
|
||||
Death8:
|
||||
|
|
@ -1058,7 +1073,7 @@ Class UTPlayer : DoomPlayer
|
|||
PLD1 M 1 A_DMFade();
|
||||
Wait;
|
||||
XDeath:
|
||||
TNT1 A 1
|
||||
TNT1 A 350
|
||||
{
|
||||
A_XScream();
|
||||
A_NoBlocking();
|
||||
|
|
@ -1120,6 +1135,7 @@ Class UTPlayerTFemale : UTPlayer
|
|||
|
||||
void A_LegPop()
|
||||
{
|
||||
legless = true;
|
||||
let a = Actor.Spawn("UTFemaleLegGibber",pos);
|
||||
a.vel = vel;
|
||||
a.Scale = Scale;
|
||||
|
|
@ -1154,7 +1170,8 @@ Class UTPlayerTFemale : UTPlayer
|
|||
PLD9 A 3 A_PlayerScream();
|
||||
PLD9 B 3 A_NoBlocking();
|
||||
PLD9 CDEFGHIJKLMNOPQRST 2;
|
||||
PD9B ABCDEFGHIJ 2;
|
||||
PD9B A 2 A_SetSize(-1,height*0.25); // reduce now
|
||||
PD9B BCDEFGHIJ 2;
|
||||
PD9B K 1 A_DMFade();
|
||||
Wait;
|
||||
Death:
|
||||
|
|
@ -1923,6 +1940,8 @@ Class UTBlueKey : BlueCard
|
|||
Class ShredCorpseHitbox : Actor
|
||||
{
|
||||
int accdamage;
|
||||
Vector3 lastvel;
|
||||
bool wasonair;
|
||||
|
||||
Default
|
||||
{
|
||||
|
|
@ -1946,16 +1965,37 @@ Class ShredCorpseHitbox : Actor
|
|||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
if ( !flak_corpsedamage || !target || (target.Health > 0) || target.InStateSequence(target.CurState,target.FindState("XDeath")) )
|
||||
if ( (!(target is 'UTPlayer') && !flak_corpsedamage) || !target || (target.Health > 0) || target.InStateSequence(target.CurState,target.FindState("XDeath")) )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
SetOrigin(target.pos,true);
|
||||
A_SetSize(target.radius,target.height);
|
||||
if ( target.pos.z > target.floorz ) wasonair = true;
|
||||
else
|
||||
{
|
||||
if ( wasonair )
|
||||
{
|
||||
A_PlaySound("misc/corpsefall",CHAN_BODY,clamp(-lastvel.z*0.2,0.1,1.0));
|
||||
if ( lastvel.z < -20 ) DamageMobj(null,null,int.max,'Falling');
|
||||
}
|
||||
wasonair = false;
|
||||
}
|
||||
lastvel = target.vel;
|
||||
}
|
||||
override int DamageMobj( Actor inflictor, Actor source, int damage, Name mod, int flags, double angle )
|
||||
{
|
||||
if ( (target is 'UTPlayer') && (mod == 'Zapped') && (target.sprite == target.GetSpriteIndex('PLD9')) )
|
||||
{
|
||||
// keep the zapping action on
|
||||
target.SetState(target.FindState("Death.Zapped")+Random[ZapMe](2,8));
|
||||
damage /= 4;
|
||||
// push the corpse
|
||||
target.vel.xy += RotateVector((1,0),angle)*damage*0.1;
|
||||
// keep it afloat
|
||||
target.vel.z = max(0.1,target.vel.z+0.1);
|
||||
}
|
||||
accdamage -= damage;
|
||||
int gibhealth = (target.GibHealth==int.min)?-target.SpawnHealth():target.GibHealth;
|
||||
if ( accdamage < gibhealth )
|
||||
|
|
@ -2613,7 +2653,7 @@ Class UTMainHandler : EventHandler
|
|||
return;
|
||||
}
|
||||
// attach damage accumulator for corpses
|
||||
if ( !flak_corpsedamage ) return;
|
||||
if ( !(e.Thing is 'UTPlayer') && !flak_corpsedamage ) return;
|
||||
let a = Actor.Spawn("ShredCorpseHitbox",e.Thing.pos);
|
||||
a.target = e.Thing;
|
||||
}
|
||||
|
|
@ -2644,7 +2684,9 @@ Class UTMainHandler : EventHandler
|
|||
double dist = max(1,dir.length());
|
||||
double damagescale = 1-max(0,(dist-a.radius)/ExplosionRadius);
|
||||
dir = dir/dist;
|
||||
a.vel += dir*damagescale*(MomentumTransfer/(Thinker.TICRATE*a.mass));
|
||||
if ( (a is 'ShredCorpseHitbox') && a.target )
|
||||
a.target.vel += dir*damagescale*(MomentumTransfer/(Thinker.TICRATE*a.target.mass));
|
||||
else a.vel += dir*damagescale*(MomentumTransfer/(Thinker.TICRATE*a.mass));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2652,7 +2694,9 @@ Class UTMainHandler : EventHandler
|
|||
static void DoKnockback( Actor Victim, Vector3 HitDirection, double MomentumTransfer )
|
||||
{
|
||||
if ( !Victim ) return;
|
||||
Victim.vel += HitDirection*(MomentumTransfer/(Thinker.TICRATE*Victim.Mass));
|
||||
if ( (Victim is 'ShredCorpseHitbox') && Victim.target )
|
||||
Victim.target.vel += HitDirection*(MomentumTransfer/(Thinker.TICRATE*Victim.target.Mass));
|
||||
else Victim.vel += HitDirection*(MomentumTransfer/(Thinker.TICRATE*Victim.Mass));
|
||||
}
|
||||
|
||||
static void DoSwing( Actor target, Vector2 dir, double initial, double inc, int steps, int mode = 0, int delay = 0, double rmul = 1.0 )
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ Class UTGibber : Actor
|
|||
ang = FRandom[Blod](0,360);
|
||||
pt = FRandom[Blod](-90,90);
|
||||
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
|
||||
a.vel = rvel*0.6+dir*FRandom[Blod](8.0,12.0);
|
||||
a.vel = rvel*0.6+dir*FRandom[Blod](3.0,6.0);
|
||||
}
|
||||
for ( int i=0; i<gibsize; i++ )
|
||||
{
|
||||
|
|
@ -309,7 +309,7 @@ Class UTFemaleLegGibber : UTGibber
|
|||
ang = FRandom[Blod](0,360);
|
||||
pt = FRandom[Blod](-90,90);
|
||||
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
|
||||
a.vel = rvel*0.6+dir*FRandom[Blod](8.0,12.0);
|
||||
a.vel = rvel*0.6+dir*FRandom[Blod](3.0,6.0);
|
||||
}
|
||||
}
|
||||
for ( int i=0; i<gibsize; i++ )
|
||||
|
|
@ -384,6 +384,8 @@ Class UTPlayerGibber : UTGibber
|
|||
firstgib = true;
|
||||
for ( int i=0; i<11; i++ )
|
||||
{
|
||||
if ( (i == 5) && UTPlayer(Gibbed).headless ) continue;
|
||||
if ( ((i == 2) || (i == 6)) && UTPlayer(Gibbed).legless ) continue;
|
||||
Actor a;
|
||||
if ( i < 6 )
|
||||
{
|
||||
|
|
@ -406,7 +408,7 @@ Class UTPlayerGibber : UTGibber
|
|||
}
|
||||
}
|
||||
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
|
||||
a.vel = rvel*0.6+dir*FRandom[Blod](8.0,12.0);
|
||||
a.vel = rvel*0.6+dir*FRandom[Blod](3.0,6.0);
|
||||
}
|
||||
}
|
||||
for ( int i=0; i<gibsize; i++ )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue