Assorted changes, including some code cleanup and more accurate UT physics for various projectiles.

I also made the Kinsie's Test Map tweaks toggleable because someone didn't like them.
This commit is contained in:
Marisa the Magician 2019-01-21 22:57:56 +01:00
commit 4189150f17
11 changed files with 174 additions and 103 deletions

View file

@ -38,3 +38,4 @@ server float flak_swingerstrength = 0.5; // strength of visual recoil
server bool flak_radboots = true; // jump boots protect against damaging floors (this is to account for the lack of a radsuit) server bool flak_radboots = true; // jump boots protect against damaging floors (this is to account for the lack of a radsuit)
server bool flak_blood = true; // [WIP] use doom tournament blood (disable if using another gore mod) server bool flak_blood = true; // [WIP] use doom tournament blood (disable if using another gore mod)
server bool flak_gibs = false; // [WIP/UNSTABLE] use doom tournament gibbing (disable if using another gore mod) server bool flak_gibs = false; // [WIP/UNSTABLE] use doom tournament gibbing (disable if using another gore mod)
server bool flak_doomtest = false; // made toggleable due to loud complaints

View file

@ -66,6 +66,7 @@ OptionMenu "UTOptionMenu"
Option "UT Blood", "flak_blood", "YesNo" Option "UT Blood", "flak_blood", "YesNo"
Option "[WIP] UT Gibbing", "flak_gibs", "YesNo" Option "[WIP] UT Gibbing", "flak_gibs", "YesNo"
Option "[WIP] Corpses Take Damage", "flak_corpsedamage", "YesNo" Option "[WIP] Corpses Take Damage", "flak_corpsedamage", "YesNo"
Option "Edit Kinsie's Test Map", "flak_doomtest", "YesNo"
} }
AddOptionMenu "OptionsMenu" AddOptionMenu "OptionsMenu"

View file

@ -1,3 +1,10 @@
Texture "DefTex",128,128
{
XScale 4
YScale 4
WorldPanning
Patch "-noflat-", 0, 0
}
Sprite "HBOXA0",1,1{} Sprite "HBOXA0",1,1{}
Sprite "HBOXB0",1,1{} Sprite "HBOXB0",1,1{}
Sprite "HBOXC0",1,1{} Sprite "HBOXC0",1,1{}

View file

@ -198,8 +198,6 @@ Class BioGel : Actor
deadtimer = -1; deadtimer = -1;
l = Spawn("BioLight",pos); l = Spawn("BioLight",pos);
l.target = self; l.target = self;
b = Spawn("BioHitbox",pos);
b.target = self;
rollvel = FRandom[GES](10,30)*RandomPick[GES](-1,1); rollvel = FRandom[GES](10,30)*RandomPick[GES](-1,1);
pitchvel = FRandom[GES](10,30)*RandomPick[GES](-1,1); pitchvel = FRandom[GES](10,30)*RandomPick[GES](-1,1);
yawvel = FRandom[GES](10,30)*RandomPick[GES](-1,1); yawvel = FRandom[GES](10,30)*RandomPick[GES](-1,1);
@ -297,72 +295,8 @@ Class BioGel : Actor
SetStateLabel("XDeath"); SetStateLabel("XDeath");
return; return;
} }
FLineTraceData d;
A_SetSize(0.1,0); A_SetSize(0.1,0);
if ( BlockingLine ) if ( tracer && tracer.bACTLIKEBRIDGE )
{
atline = BlockingLine;
normal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
atside = 1;
if ( !BlockingLine.sidedef[1] || (CurSector == BlockingLine.frontsector) )
{
atside = 0;
normal *= -1;
}
Vector3 orig = (BlockingLine.v1.p.x,BlockingLine.v1.p.y,0);
Vector3 onwall = pos-(normal dot (pos-orig))*normal;
SetOrigin(onwall+normal*0.5,false);
// attempt to guess line part (upper/mid/lower)
if ( !atline.sidedef[1] ) atpart = 0; // mid
else if ( atline.sidedef[atside?0:1].sector.ceilingplane.ZAtPoint(pos.xy) < pos.z ) atpart = 1; // upper
else if ( atline.sidedef[atside?0:1].sector.floorplane.ZAtPoint(pos.xy) > pos.z ) atpart = -1; // lower
else atpart = 0;
if ( atpart == 1 )
{
if ( atline.flags&Line.ML_DONTPEGTOP ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(1);
else atz = pos.z-atline.sidedef[atside?0:1].sector.GetPlaneTexZ(1);
}
else if ( atpart == -1 )
{
if ( atline.flags&Line.ML_DONTPEGBOTTOM ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(0);
else atz = pos.z-atline.sidedef[atside?0:1].sector.GetPlaneTexZ(0);
}
else if ( atline.flags&Line.ML_DONTPEGBOTTOM ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(0);
else atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(1);
angle = atan2(normal.y,normal.x);
pitch = 0;
roll = 180; // otherwise it slides upwards (UT changes roll like this too)
if ( waterlevel > 0 ) hittype = HIT_FLOOR;
else hittype = HIT_WALL;
}
else if ( pos.z <= floorz+4 )
{
atsector = cursector;
atplane = 0;
normal = cursector.floorplane.Normal;
pitch = asin(-normal.z);
angle = atan2(normal.y,normal.x);
roll = FRandom[GES](0,360);
SetOrigin((pos.x,pos.y,floorz)+normal*0.5,false);
atz = pos.z-cursector.GetPlaneTexZ(0);
hittype = HIT_FLOOR;
}
else if ( pos.z >= ceilingz-8 )
{
atsector = cursector;
atplane = 1;
normal = cursector.ceilingplane.Normal;
pitch = asin(-normal.z);
angle = atan2(normal.y,normal.x);
roll = FRandom[GES](0,360);
SetOrigin((pos.x,pos.y,ceilingz)+normal*0.5,false);
atz = pos.z-cursector.GetPlaneTexZ(1);
if ( waterlevel > 0 ) hittype = HIT_FLOOR;
else if ( normal dot (0,0,-1) > 0.7 )
hittype = HIT_CEILING;
else hittype = HIT_FLOOR;
}
else if ( tracer && tracer.bACTLIKEBRIDGE )
{ {
atbridge = tracer; atbridge = tracer;
onbridge = true; onbridge = true;
@ -461,11 +395,77 @@ Class BioGel : Actor
} }
} }
} }
else if ( BlockingFloor )
{
atsector = BlockingFloor;
atplane = 0;
normal = BlockingFloor.floorplane.Normal;
pitch = asin(-normal.z);
angle = atan2(normal.y,normal.x);
roll = FRandom[GES](0,360);
SetOrigin((pos.x,pos.y,floorz)+normal*0.5,false);
atz = pos.z-BlockingFloor.GetPlaneTexZ(0);
hittype = HIT_FLOOR;
}
else if ( BlockingCeiling )
{
atsector = BlockingCeiling;
atplane = 1;
normal = BlockingCeiling.ceilingplane.Normal;
pitch = asin(-normal.z);
angle = atan2(normal.y,normal.x);
roll = FRandom[GES](0,360);
SetOrigin((pos.x,pos.y,ceilingz)+normal*0.5,false);
atz = pos.z-BlockingCeiling.GetPlaneTexZ(1);
if ( waterlevel > 0 ) hittype = HIT_FLOOR;
else if ( normal dot (0,0,-1) > 0.7 )
hittype = HIT_CEILING;
else hittype = HIT_FLOOR;
}
else
if ( BlockingLine )
{
atline = BlockingLine;
normal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
atside = 1;
if ( !BlockingLine.sidedef[1] || (CurSector == BlockingLine.frontsector) )
{
atside = 0;
normal *= -1;
}
Vector3 orig = (BlockingLine.v1.p.x,BlockingLine.v1.p.y,0);
Vector3 onwall = pos-(normal dot (pos-orig))*normal;
SetOrigin(onwall+normal*0.5,false);
// attempt to guess line part (upper/mid/lower)
if ( !atline.sidedef[1] ) atpart = 0; // mid
else if ( atline.sidedef[atside?0:1].sector.ceilingplane.ZAtPoint(pos.xy) < pos.z ) atpart = 1; // upper
else if ( atline.sidedef[atside?0:1].sector.floorplane.ZAtPoint(pos.xy) > pos.z ) atpart = -1; // lower
else atpart = 0;
if ( atpart == 1 )
{
if ( atline.flags&Line.ML_DONTPEGTOP ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(1);
else atz = pos.z-atline.sidedef[atside?0:1].sector.GetPlaneTexZ(1);
}
else if ( atpart == -1 )
{
if ( atline.flags&Line.ML_DONTPEGBOTTOM ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(0);
else atz = pos.z-atline.sidedef[atside?0:1].sector.GetPlaneTexZ(0);
}
else if ( atline.flags&Line.ML_DONTPEGBOTTOM ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(0);
else atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(1);
angle = atan2(normal.y,normal.x);
pitch = 0;
roll = 180; // otherwise it slides upwards (UT changes roll like this too)
if ( waterlevel > 0 ) hittype = HIT_FLOOR;
else hittype = HIT_WALL;
}
else else
{ {
SetStateLabel("XDeath"); SetStateLabel("XDeath");
return; return;
} }
b = Spawn("BioHitbox",pos);
b.target = self;
A_PlaySound("ges/hit"); A_PlaySound("ges/hit");
A_SprayDecal("BioSplat",-172); A_SprayDecal("BioSplat",-172);
int numpt = Min(100,int(Scale.x*10))+Random[GES](-5,5); int numpt = Min(100,int(Scale.x*10))+Random[GES](-5,5);

View file

@ -221,11 +221,11 @@ Class UTGrenade : UTRocket
DamageType 'GrenadeDeath'; DamageType 'GrenadeDeath';
-NOGRAVITY; -NOGRAVITY;
+USEBOUNCESTATE; +USEBOUNCESTATE;
-BOUNCEAUTOOFF;
+BOUNCEAUTOOFFFLOORONLY;
-EXPLODEONWATER; -EXPLODEONWATER;
+CANBOUNCEWATER; +CANBOUNCEWATER;
BounceType "Doom"; +NOEXPLODEFLOOR;
BounceType "Hexen";
WallBounceFactor 0.75;
BounceFactor 0.75; BounceFactor 0.75;
ReactionTime 85; ReactionTime 85;
Speed 20; Speed 20;
@ -243,20 +243,37 @@ Class UTGrenade : UTRocket
Spawn: Spawn:
RCKT A 1 RCKT A 1
{ {
angle += anglevel; if ( !bNOGRAVITY )
pitch += pitchvel; {
roll += rollvel; angle += anglevel;
pitch += pitchvel;
roll += rollvel;
}
let s = Spawn("UTSmoke",pos);
s.scale *= 2.0;
s.alpha *= 0.6;
s.vel = (FRandom[Eightball](-0.1,0.1),FRandom[Eightball](-0.1,0.1),FRandom[Eightball](-0.1,0.3));
s.vel += vel*0.05;
s.SetShade("000000");
A_Countdown(); A_Countdown();
} }
Wait; Wait;
Bounce: Bounce:
RCKT A 0 RCKT A 0
{ {
bHITOWNER = true;
A_PlaySound("utrl/bounce"); A_PlaySound("utrl/bounce");
rollvel = FRandom[Eightball](-16,16); rollvel = FRandom[Eightball](-16,16);
pitchvel = FRandom[Eightball](-16,16); pitchvel = FRandom[Eightball](-16,16);
anglevel = FRandom[Eightball](-16,16); anglevel = FRandom[Eightball](-16,16);
bHITOWNER = true; if ( vel.z > 10 ) vel.z = 0.5*(10+vel.z);
else if ( BlockingFloor && (vel.xy.length() < 0.5) )
{
vel *= 0;
bNOGRAVITY = true;
bMOVEWITHSECTOR = true;
ClearBounce();
}
} }
Goto Spawn; Goto Spawn;
Death: Death:

View file

@ -88,7 +88,7 @@ Class BulletImpact : Actor
Class UTCasing : Actor Class UTCasing : Actor
{ {
int deadtimer; int deadtimer, numbounces;
double pitchvel, anglevel; double pitchvel, anglevel;
double heat; double heat;
@ -102,7 +102,9 @@ Class UTCasing : Actor
+THRUACTORS; +THRUACTORS;
+USEBOUNCESTATE; +USEBOUNCESTATE;
+INTERPOLATEANGLES; +INTERPOLATEANGLES;
BounceType "Doom"; Mass 1;
BounceType "Hexen";
WallBounceFactor 0.65;
BounceFactor 0.65; BounceFactor 0.65;
BounceSound "bullet/casing"; BounceSound "bullet/casing";
} }
@ -144,6 +146,12 @@ Class UTCasing : Actor
pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1); pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1); anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
vel = (vel.unit()+(FRandom[Junk](-.2,.2),FRandom[Junk](-.2,.2),FRandom[Junk](-.2,.2))).unit()*vel.length(); vel = (vel.unit()+(FRandom[Junk](-.2,.2),FRandom[Junk](-.2,.2),FRandom[Junk](-.2,.2))).unit()*vel.length();
if ( numbounces && ((numbounces > 3) || (Random[Junk](1,20) < 17) || (vel.z > -1.4)) )
{
ClearBounce();
ExplodeMissile();
}
numbounces++;
} }
Goto Spawn; Goto Spawn;
Death: Death:

View file

@ -166,12 +166,11 @@ Class FlakChunk : Actor
Speed 50; Speed 50;
DamageFunction Random[Flak](15,20); DamageFunction Random[Flak](15,20);
DamageType 'Shredded'; DamageType 'Shredded';
BounceType "Doom"; BounceType "Hexen";
BounceFactor 0.8; BounceFactor 0.8;
WallBounceFactor 0.8; WallBounceFactor 0.8;
PROJECTILE; PROJECTILE;
+USEBOUNCESTATE; +USEBOUNCESTATE;
-BOUNCEAUTOOFF;
+CANBOUNCEWATER; +CANBOUNCEWATER;
+SKYEXPLODE; +SKYEXPLODE;
+INTERPOLATEANGLES; +INTERPOLATEANGLES;
@ -232,9 +231,8 @@ Class FlakChunk : Actor
action void A_HandleBounce() action void A_HandleBounce()
{ {
bHITOWNER = true; bHITOWNER = true;
A_SprayDecal("WallCrack",-8);
int numpt = Random[Flak](2,3); int numpt = Random[Flak](2,3);
if ( frame < 10 ) if ( (frame < 10) && Random[Flak](0,1) )
{ {
for ( int i=0; i<numpt; i++ ) for ( int i=0; i<numpt; i++ )
{ {
@ -243,6 +241,7 @@ Class FlakChunk : Actor
s.vel = pvel; s.vel = pvel;
} }
} }
else A_SprayDecal("WallCrack",-8);
A_Gravity(); A_Gravity();
invoker.rollvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed); invoker.rollvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed);
invoker.pitchvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed); invoker.pitchvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed);
@ -255,7 +254,7 @@ Class FlakChunk : Actor
} }
override int DoSpecialDamage( Actor target, int damage, Name damagetype ) override int DoSpecialDamage( Actor target, int damage, Name damagetype )
{ {
if ( vel.length() <= 5.0 ) return 0; if ( vel.length() <= 5.0 ) return -1;
FlakAccumulator.Accumulate(target,damage); FlakAccumulator.Accumulate(target,damage);
int gibhealth = (target.GibHealth==int.min)?-target.SpawnHealth():target.GibHealth; int gibhealth = (target.GibHealth==int.min)?-target.SpawnHealth():target.GibHealth;
int calcdmg = FlakAccumulator.GetAmount(target); int calcdmg = FlakAccumulator.GetAmount(target);

View file

@ -60,13 +60,12 @@ Class Razor2 : Actor
DamageFunction (Random[Ripper](20,25)*((DamageType=='Decapitated')?3:1.0)); DamageFunction (Random[Ripper](20,25)*((DamageType=='Decapitated')?3:1.0));
DamageType 'Shredded'; DamageType 'Shredded';
Obituary "%k ripped a chunk of meat out of %o with the Ripper."; Obituary "%k ripped a chunk of meat out of %o with the Ripper.";
BounceType "Doom"; BounceType "Hexen";
ReactionTime 7; ReactionTime 7;
BounceFactor 1.0; BounceFactor 1.0;
WallBounceFactor 1.0; WallBounceFactor 1.0;
PROJECTILE; PROJECTILE;
+USEBOUNCESTATE; +USEBOUNCESTATE;
-BOUNCEAUTOOFF;
+SKYEXPLODE; +SKYEXPLODE;
+CANBOUNCEWATER; +CANBOUNCEWATER;
+NODAMAGETHRUST; +NODAMAGETHRUST;

View file

@ -115,6 +115,7 @@ Class TranslocatorGlow : Actor
Class TranslocatorModule : Actor Class TranslocatorModule : Actor
{ {
Actor b; Actor b;
bool alreadyhit;
Default Default
{ {
@ -128,12 +129,10 @@ Class TranslocatorModule : Actor
+HITTRACER; +HITTRACER;
+MOVEWITHSECTOR; +MOVEWITHSECTOR;
+CANBOUNCEWATER; +CANBOUNCEWATER;
-BOUNCEAUTOOFF;
+BOUNCEAUTOOFFFLOORONLY;
+BLOCKASPLAYER; +BLOCKASPLAYER;
BounceType "Doom"; BounceType "Hexen";
BounceFactor 0.5; BounceFactor 0.3;
WallBounceFactor 0.5; WallBounceFactor 0.3;
} }
override void PostBeginPlay() override void PostBeginPlay()
@ -207,8 +206,17 @@ Class TranslocatorModule : Actor
Bounce: Bounce:
TMOD A 0 TMOD A 0
{ {
A_SetPitch(0); if ( alreadyhit )
A_PlaySound("transloc/bounce"); {
ClearBounce();
ExplodeMissile();
}
else
{
A_SetPitch(0);
A_PlaySound("transloc/bounce");
if ( BlockingFloor ) alreadyhit = true;
}
} }
Goto Spawn; Goto Spawn;
Death: Death:

View file

@ -601,6 +601,8 @@ Class UTWeapon : Weapon
virtual ui void PreRender( double lbottom ) {} virtual ui void PreRender( double lbottom ) {}
// Drawstuffs over HUD // Drawstuffs over HUD
virtual ui void PostRender( double lbottom ) {} virtual ui void PostRender( double lbottom ) {}
// Future preparations for scripted textures
virtual ui void RenderOverlay( RenderEvent e ) {}
override Inventory CreateTossable( int amt ) override Inventory CreateTossable( int amt )
{ {
@ -1284,7 +1286,7 @@ Class ShredCorpseHitbox : Actor
override void Tick() override void Tick()
{ {
Super.Tick(); Super.Tick();
if ( !target || (target.Health > 0) || target.InStateSequence(target.CurState,target.FindState("XDeath")) ) if ( !flak_corpsedamage || !target || (target.Health > 0) || target.InStateSequence(target.CurState,target.FindState("XDeath")) )
{ {
Destroy(); Destroy();
return; return;
@ -1300,6 +1302,7 @@ Class ShredCorpseHitbox : Actor
{ {
// force gib (cheap ATM) // force gib (cheap ATM)
State gib = target.FindState("XDeath"); State gib = target.FindState("XDeath");
if ( !gib ) gib = target.FindState("Death.Extreme");
if ( gib ) target.SetState(gib); if ( gib ) target.SetState(gib);
Destroy(); Destroy();
} }
@ -1562,8 +1565,15 @@ Class UTMainHandler : StaticEventHandler
override void WorldLoaded( WorldEvent e ) override void WorldLoaded( WorldEvent e )
{ {
if ( gamestate != GS_LEVEL || e.IsSaveGame ) return; if ( gamestate != GS_LEVEL || e.IsSaveGame ) return;
// prettify Kinsie's test map for a more Unreal feel
let level = currentSession.levelinfo[0]; let level = currentSession.levelinfo[0];
// just replace the -noflat- with a better scaled version
if ( !flak_doomtest )
{
if ( (level.GetChecksum() ~== "FBC3B6622A8B74AE06DE01E70007AC33") || (level.GetChecksum() ~== "D8206A3414DA967F2159473B5791139E") )
level.ReplaceTextures("-noflat-","DefTex",0);
return;
}
// prettify Kinsie's test map for a more Unreal feel
if ( level.GetChecksum() ~== "FBC3B6622A8B74AE06DE01E70007AC33" ) if ( level.GetChecksum() ~== "FBC3B6622A8B74AE06DE01E70007AC33" )
{ {
TextureID deftex = TexMan.CheckForTexture("-noflat-",TexMan.Type_Any); TextureID deftex = TexMan.CheckForTexture("-noflat-",TexMan.Type_Any);
@ -1838,6 +1848,9 @@ Class UTMainHandler : StaticEventHandler
override void RenderOverlay( RenderEvent e ) override void RenderOverlay( RenderEvent e )
{ {
// well this if sure is a long one
if ( players[consoleplayer].camera.player && players[consoleplayer].camera.player.ReadyWeapon && (players[consoleplayer].camera.player.ReadyWeapon is 'UTWeapon') )
UTWeapon(players[consoleplayer].camera.player.ReadyWeapon).RenderOverlay(e);
if ( !menuactive ) return; if ( !menuactive ) return;
if ( tex.IsNull() || !tex.IsValid() ) return; if ( tex.IsNull() || !tex.IsValid() ) return;
if ( !CVar.GetCVar('flak_showmenu',players[consoleplayer]).GetBool() ) return; if ( !CVar.GetCVar('flak_showmenu',players[consoleplayer]).GetBool() ) return;
@ -1849,11 +1862,12 @@ Class UTMainHandler : StaticEventHandler
{ {
if ( e.Thing.bDONTGIB ) return; if ( e.Thing.bDONTGIB ) return;
// gibbers // gibbers
if ( flak_gibs && !e.Thing.bNOBLOOD && ((e.Inflictor && e.Inflictor.bEXTREMEDEATH) || (e.Thing.Health < e.Thing.GetGibHealth())) && (!e.Inflictor || !e.Inflictor.bNOEXTREMEDEATH) ) if ( flak_gibs && !e.Thing.bNOBLOOD && (e.Thing.FindState("XDeath") || e.Thing.FindState("Death.Extreme")) && ((e.Inflictor && e.Inflictor.bEXTREMEDEATH) || (e.Thing.Health < e.Thing.GetGibHealth())) && (!e.Inflictor || !e.Inflictor.bNOEXTREMEDEATH) )
{ {
// players have special gibbing // players have special gibbing
if ( e.Thing.player ) if ( e.Thing.player )
{ {
// TODO
return; return;
} }
// generic gibbing // generic gibbing

View file

@ -8,6 +8,7 @@ Class UTBlood : Actor
+NOBLOCKMAP; +NOBLOCKMAP;
+NOGRAVITY; +NOGRAVITY;
+NOTELEPORT; +NOTELEPORT;
+DONTSPLASH;
+FORCEXYBILLBOARD; +FORCEXYBILLBOARD;
+PUFFGETSOWNER; +PUFFGETSOWNER;
} }
@ -61,6 +62,7 @@ Class UTBloodDrop : Actor
Default Default
{ {
Scale 0.24; Scale 0.24;
Mass 1;
Radius 2; Radius 2;
Height 2; Height 2;
RenderStyle "Translucent"; RenderStyle "Translucent";
@ -99,6 +101,7 @@ Class UTBloodSpurt : Actor
{ {
+NOBLOCKMAP; +NOBLOCKMAP;
+NOGRAVITY; +NOGRAVITY;
+DONTSPLASH;
+NOTELEPORT; +NOTELEPORT;
+THRUACTORS; +THRUACTORS;
} }
@ -134,6 +137,7 @@ Class UTBloodTrail : Actor
+NOBLOCKMAP; +NOBLOCKMAP;
+NOGRAVITY; +NOGRAVITY;
+NOTELEPORT; +NOTELEPORT;
+DONTSPLASH;
+THRUACTORS; +THRUACTORS;
} }
override void PostBeginPlay() override void PostBeginPlay()
@ -183,6 +187,7 @@ Class UTBloodPuff : Actor
+NOBLOCKMAP; +NOBLOCKMAP;
+NOGRAVITY; +NOGRAVITY;
+NOTELEPORT; +NOTELEPORT;
+DONTSPLASH;
+FORCEXYBILLBOARD; +FORCEXYBILLBOARD;
} }
States States
@ -284,12 +289,13 @@ Class UTGib : Actor
{ {
Radius 4; Radius 4;
Height 4; Height 4;
BounceType "Doom"; BounceType "Hexen";
BounceFactor 0.7; BounceFactor 0.8;
WallBounceFactor 0.7; WallBounceFactor 0.8;
+ROLLSPRITE; +ROLLSPRITE;
+ROLLCENTER; +ROLLCENTER;
+INTERPOLATEANGLES; +INTERPOLATEANGLES;
+CANBOUNCEWATER;
+MISSILE; +MISSILE;
+THRUACTORS; +THRUACTORS;
+USEBOUNCESTATE; +USEBOUNCESTATE;
@ -297,19 +303,30 @@ Class UTGib : Actor
override void PostBeginPlay() override void PostBeginPlay()
{ {
Super.PostBeginPlay(); Super.PostBeginPlay();
let t = Spawn("UTBloodTrail",pos); tracer = Spawn("UTBloodTrail",pos);
t.target = self; tracer.target = self;
if ( bloodcolor ) t.SetShade(bloodcolor); if ( bloodcolor ) tracer.SetShade(bloodcolor);
else t.SetShade(gameinfo.defaultbloodcolor); else tracer.SetShade(gameinfo.defaultbloodcolor);
t.translation = bloodtranslation; tracer.translation = bloodtranslation;
rollvel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1); rollvel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1);
anglevel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1); anglevel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1);
pitchvel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1); pitchvel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1);
} }
void A_HandleBounce() void A_HandleBounce()
{ {
if ( vel.length() > double.epsilon ) double spd = vel.length();
vel = (vel.unit()+(FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2))).unit()*vel.length(); if ( spd > double.epsilon )
vel = (vel.unit()+(FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2))).unit()*spd;
if ( BlockingFloor && (vel.xy.length() < 1) )
{
ClearBounce();
ExplodeMissile();
}
if ( spd < 10 )
{
if ( tracer ) tracer.Destroy();
}
else if ( spd > 20 ) vel *= 0.8;
A_PlaySound("misc/gibp"); A_PlaySound("misc/gibp");
double ang, pt; double ang, pt;
for ( int i=0; i<6; i++ ) for ( int i=0; i<6; i++ )