Implement limiter for blood effects. Will be extended later.

This commit is contained in:
Mari the Deer 2020-09-02 00:49:19 +02:00
commit e2e21d3731
6 changed files with 137 additions and 12 deletions

View file

@ -106,8 +106,9 @@ Class mkBloodSpray : Actor
// becomes a decal on crash
Class mkBloodDrop : Actor
{
int deadtimer;
bool killme;
bool dead;
mkBloodDrop prevblod, nextblod;
Default
{
@ -131,6 +132,7 @@ Class mkBloodDrop : Actor
{
prev = pos; // for interpolation
if ( isFrozen() ) return;
if ( killme ) A_FadeOut(.01);
if ( dead )
{
// do nothing but follow floor movement and eventually fade out
@ -140,8 +142,6 @@ Class mkBloodDrop : Actor
UpdateWaterLevel(false);
}
if ( waterlevel > 0 ) A_FadeOut();
deadtimer++;
if ( deadtimer > 350 ) A_FadeOut(.01);
return; // we don't need to update states when we're dead
}
else
@ -232,11 +232,16 @@ Class mkBloodDrop : Actor
override void PostBeginPlay()
{
Super.PostBeginPlay();
deadtimer = Random[Blood](-20,20);
SWWMGoreHandler.QueueBlod(self);
int jumps = Random[Blood](0,3);
state dest = ResolveState("Spawn");
SetState(dest+jumps);
}
override void OnDestroy()
{
SWWMGoreHandler.DeQueueBlod(self);
Super.OnDestroy();
}
States
{
Spawn:
@ -301,11 +306,12 @@ Class mkBloodSmoke2 : mkBloodSmoke
// inspired by Lud's Universal Gibs
Class mkFlyingGib : Actor
{
int deadtimer;
bool killme;
int lastbleed;
color shadecol;
bool bleeding;
double rollvel;
mkFlyingGib prevmeat, nextmeat;
override void PostBeginPlay()
{
@ -320,13 +326,19 @@ Class mkFlyingGib : Actor
vel += master.vel*1.5;
CopyBloodColor(master);
}
deadtimer = Random[Gibs](-20,20);
rollvel = FRandom[Gibs](10,50)*RandomPick[Gibs](-1,1);
scale *= FRandom[Gibs](.5,1.5);
if ( master && master.bloodcolor ) shadecol = Color(master.bloodcolor.r/2,master.bloodcolor.g/2,master.bloodcolor.b/2);
else shadecol = Color(80,0,0);
bleeding = true;
if ( Random[Blood](0,1) ) bXFlip = true;
SWWMGoreHandler.QueueMeat(self);
}
override void OnDestroy()
{
SWWMGoreHandler.DeQueueMeat(self);
Super.OnDestroy();
}
override void Tick()
@ -338,14 +350,20 @@ Class mkFlyingGib : Actor
let s = Spawn("mkBloodSmoke",pos);
s.SetShade(shadecol);
}
if ( killme ) A_FadeOut(.01);
if ( CurState == ResolveState("Death2") )
{
if ( vel.length() < .1 ) bleeding = false;
deadtimer++;
if ( deadtimer > 300 ) A_FadeOut(.01);
if ( vel.length() < .1 )
bleeding = false;
return;
}
roll += rollvel;
if ( waterlevel > 0 )
{
rollvel *= .98;
vel *= .98;
if ( vel.length() < 10. ) A_FadeOut(.01);
}
}
override bool CanCollideWith(Actor other, bool passive)
@ -359,8 +377,8 @@ Class mkFlyingGib : Actor
double ang;
double pt;
Vector3 dir;
if ( level.maptime <= invoker.lastbleed ) return;
invoker.lastbleed = level.maptime;
if ( invoker.lastbleed > level.maptime ) return;
invoker.lastbleed = level.maptime+5;
for ( int i=0; i<8; i++ )
{
let b = Spawn("mkBloodDrop",pos);
@ -566,6 +584,89 @@ Class CorpseFallTracker : Thinker
Class SWWMGoreHandler : EventHandler
{
mkBloodDrop blods, blods_end;
int blods_cnt;
mkFlyingGib meats, meats_end;
int meats_cnt;
override void WorldLoaded( WorldEvent e )
{
// recheck queues in case limits changed
while ( blods && (blods_cnt > swwm_maxblood) )
DeQueueBlod(blods);
while ( meats && (meats_cnt > swwm_maxgibs) )
DeQueueMeat(meats);
}
static void QueueBlod( mkBloodDrop b )
{
let hnd = SWWMGoreHandler(EventHandler.Find("SWWMGoreHandler"));
if ( !hnd ) return;
hnd.blods_cnt++;
if ( !hnd.blods )
{
// this is the initial one
hnd.blods = b;
hnd.blods_end = b;
}
else
{
hnd.blods_end.nextblod = b;
b.prevblod = hnd.blods_end;
hnd.blods_end = b;
}
while ( hnd.blods && (hnd.blods_cnt > swwm_maxblood) )
DeQueueBlod(hnd.blods);
}
static void DeQueueBlod( mkBloodDrop b )
{
let hnd = SWWMGoreHandler(EventHandler.Find("SWWMGoreHandler"));
if ( !hnd || !hnd.blods ) return;
if ( (hnd.blods != b) && !b.prevblod && !b.nextblod ) return;
hnd.blods_cnt--;
if ( !b.prevblod ) hnd.blods = b.nextblod;
else b.prevblod.nextblod = b.nextblod;
if ( b == hnd.blods_end ) hnd.blods_end = b.prevblod;
if ( b.nextblod ) b.nextblod.prevblod = b.prevblod;
b.killme = true;
b.prevblod = null;
b.nextblod = null;
}
static void QueueMeat( mkFlyingGib m )
{
let hnd = SWWMGoreHandler(EventHandler.Find("SWWMGoreHandler"));
if ( !hnd ) return;
hnd.meats_cnt++;
if ( !hnd.meats )
{
// this is the initial one
hnd.meats = m;
hnd.meats_end = m;
}
else
{
hnd.meats_end.nextmeat = m;
m.prevmeat = hnd.meats_end;
hnd.meats_end = m;
}
while ( hnd.meats && (hnd.meats_cnt > swwm_maxgibs) )
DeQueueMeat(hnd.meats);
}
static void DeQueueMeat( mkFlyingGib m )
{
let hnd = SWWMGoreHandler(EventHandler.Find("SWWMGoreHandler"));
if ( !hnd || !hnd.meats ) return;
if ( (hnd.meats != m) && !m.prevmeat && !m.nextmeat ) return;
hnd.meats_cnt--;
if ( !m.prevmeat ) hnd.meats = m.nextmeat;
else m.prevmeat.nextmeat = m.nextmeat;
if ( m == hnd.meats_end ) hnd.meats_end = m.prevmeat;
if ( m.nextmeat ) m.nextmeat.prevmeat = m.prevmeat;
m.killme = true;
m.prevmeat = null;
m.nextmeat = null;
}
override void CheckReplacement( ReplaceEvent e )
{
// only replace vanilla blood if no other gore mod is doing it