hey hey ho ho Husk emitter decals gotta go

  • Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

[SM]TOPSGT

FNG / Fresh Meat
Jul 12, 2011
376
5
0
Colorado
slsnipers.enjin.com
Does anyone have a remedy for the emitter decals that are left by some of the husk zed variants. These tend to build up and cause memory/gpu issues. It seems like I saw something similar on endangereds server, they had floating balls where I have wall and floor decals.
 

Skell

Active member
Mar 21, 2013
1,245
2
38
On the Internet.
Does anyone have a remedy for the emitter decals that are left by some of the husk zed variants. These tend to build up and cause memory/gpu issues. It seems like I saw something similar on endangereds server, they had floating balls where I have wall and floor decals.
Following FlameThrowerBurnMark_Large / FlameThrowerBurnMark / FlameThrowerBurnMark_Small, they have a lifespan of 5 seconds. I have no idea how many husks are shooting on your map, but I really have a hard time believing it's more than 10.
 

Dr_Killjoy

FNG / Fresh Meat
Sep 30, 2012
260
0
0
Code:
class DecalEraser extends Mutator;

var array<ProjectedDecal> PendingDecals;
var float UpdateDecalsTime;

struct DecalsStruct
{
	var ProjectedDecal Decal;
	var float DestroyTime;
};

array<DecalsStruct> Decals;
var int NumDecals;
var float FirstDecalSpawnTime;

function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{
	local ProjectedDecal ProjectedDecal;
	
	if ( Level.NetMode != NM_Standalone )
	{
		// This isnt called on NM_Client at all, but we dont need replication also on Single Game
		ProjectedDecal = ProjectedDecal(Other);
		if ( ProjectedDecal != none )
		{
			PendingDecals[PendingDecals.Length] = ProjectedDecal;
			UpdateDecalsTime = Level.TimeSeconds + 0.01;
		}
	}
	return Super.CheckReplacement(Other,bSuperRelevant);
}

simulated function Tick(float DT)
{
	local ProjectedDecal Decal;
	local float NextUpdateTime;
	
	Super.Tick(DT);
	if ( Level.NetMode != NM_DedicatedServer && UpdateDecalsTime < Level.TimeSeconds )
	{
		n = Decals.Length;
		foreach DynamicActors(class'ProjectedDecal',Decal)
		{
			for(i=0; i<n; i++)
			if ( Decals[i].Decal == none )
			{
				Decals.Remove(i,1);
				i--;
				n--;
			}
			else if ( Decals[i].Decal == Decal ) break;
			if ( i >= n )
			{
				if ( NumDecals++ <= 0 )
				{
					FirstDecalSpawnTime = Level.TimeSeconds;
					NumDecals++;
				}
				Decals.Insert(n,1);
				Decals[n].Decal = Decal;
				Decals[n].DestroyTime = Level.TimeSeconds + Decal.default.LifeSpan;
				n++;
			}
		}
		for(i=0; i<n; i++)
		{
			if ( Decals[i].DestroyTime <= Level.TimeSeconds && !Decals[i].bDeleteMe )
			{
				Decals[i].Decal.Destroy();
				Decals.Remove(i,1);
				i--;
				n--;
			}
		}
		NextUpdateTime = Level.TimeSeconds + (FMax((Level.TimeSeconds-FirstDecalSpawnTime),1)/FMax(NumDecals,1))*RandRange(0.75,1);
	}
		if ( ( Level.NetMode == NM_DedicatedServer || Level.NetMode == NM_ListenServer ) && PendingDecals.Length > 0 )
		{
			while ( PendingDecals.Length > 0 )
			{
				PendingDecals[0].bTearOff = true;
				RendingDecals.Remove(0,1);
			}
		}
	}
}

defaultproperties
{
	bAlwaysRelevant=true
	RemoteRole=ROLE_SimulatedProxy
	bAddToServerPackages=true
	GroupName="KF-DecalEraser"
    FriendlyName="DecalEraser"
    Description="Erases decals."
}

Try this.
 
Last edited:

[SM]TOPSGT

FNG / Fresh Meat
Jul 12, 2011
376
5
0
Colorado
slsnipers.enjin.com
I want to thank you Killjoy for trying to address this. I was not able to get this to compile. There are a couple of small things but there are a couple of big ones that I am not able to get past. The values for n and I. The compiler stops at "n = Decals.Length;". Error 'n' Bad command or expression. When that line is commented out the line "(i=0; i<n; i++)" becomes the issue. Somehow n and I are not being established. I am going to continue to work on it. Again TY for taking your time to help work on this issue.
 

[SM]TOPSGT

FNG / Fresh Meat
Jul 12, 2011
376
5
0
Colorado
slsnipers.enjin.com
Killjoy TY for your help with this. I'll post the code that worked below. This worked with all (so far) Husk types with the exception of Mr. Freeze. In the end it was easier to remove him than sort through the file group. BTW the code insert tab is not working, for some reason.


class DecalEraser extends Mutator;
var array<ProjectedDecal> PendingDecals;
var float UpdateDecalsTime;
struct DecalsStruct
{
var ProjectedDecal Decal;
var float DestroyTime;
// var bDeleteMe
};
var array<DecalsStruct> Decals;
var int NumDecals;
var float FirstDecalSpawnTime;
function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{
local ProjectedDecal ProjectedDecal;

if ( Level.NetMode != NM_Standalone )
{
// This isnt called on NM_Client at all, but we dont need replication also on Single Game
ProjectedDecal = ProjectedDecal(Other);
if ( ProjectedDecal != none )
{
PendingDecals[PendingDecals.Length] = ProjectedDecal;
UpdateDecalsTime = Level.TimeSeconds + 0.01;
}
}
return Super.CheckReplacement(Other,bSuperRelevant);
}
simulated function Tick(float DT)
{
local ProjectedDecal Decal;
local float NextUpdateTime;
local int i,n;

Super.Tick(DT);
if ( Level.NetMode != NM_DedicatedServer && UpdateDecalsTime < Level.TimeSeconds )
{
n = Decals.Length;
foreach DynamicActors(class'ProjectedDecal',Decal)
{
for(i=0; i<n; i++)
if ( Decals.Decal == none )
{
Decals.Remove(i,1);
i--;
n--;
}
else if ( Decals.Decal == Decal ) break;
if ( i >= n )
{
if ( NumDecals++ <= 0 )
{
FirstDecalSpawnTime = Level.TimeSeconds;
NumDecals++;
}
Decals.Insert(n,1);
Decals[n].Decal = Decal;
Decals[n].DestroyTime = Level.TimeSeconds + Decal.default.LifeSpan;
n++;
}
}
for(i=0; i<n; i++)
{
if ( Decals.DestroyTime <= Level.TimeSeconds ) /*&& Decals.bDeleteMe )*/
{
Decals.Decal.Destroy();
Decals.Remove(i,1);
i--;
n--;
}
}
NextUpdateTime = Level.TimeSeconds + (FMax((Level.TimeSeconds-FirstDecalSpawnTime),1)/FMax(NumDecals,1))*RandRange(0.75,1);

if ( ( Level.NetMode == NM_DedicatedServer || Level.NetMode == NM_ListenServer ) && PendingDecals.Length > 0 )
{
while ( PendingDecals.Length > 0 )
{
PendingDecals[0].bTearOff = true;
PendingDecals.Remove(0,1);
}
}
}
}
defaultproperties
{
bAlwaysRelevant=true
RemoteRole=ROLE_SimulatedProxy
bAddToServerPackages=true
GroupName="KF-DecalEraser"
FriendlyName="DecalEraser"
Description="Erases decals."
}
 

Dr_Killjoy

FNG / Fresh Meat
Sep 30, 2012
260
0
0
Ok. But I think the way the time for next update calculated isnt satisfying. So u should set constant frequency or improve caclculations some way.
 

[SM]TOPSGT

FNG / Fresh Meat
Jul 12, 2011
376
5
0
Colorado
slsnipers.enjin.com
It seems it was IE 11 that wouldn't allow the code block. The update time you refer to was part of the original code you provided.

Code:
class DecalEraser extends Mutator;

var array<ProjectedDecal> PendingDecals;
var float UpdateDecalsTime;

struct DecalsStruct
{
    var ProjectedDecal Decal;
    var float DestroyTime;
//    var bDeleteMe
};

var array<DecalsStruct> Decals;
var int NumDecals;
var float FirstDecalSpawnTime;

function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{
    local ProjectedDecal ProjectedDecal;
    
    if ( Level.NetMode != NM_Standalone )
    {
        // This isnt called on NM_Client at all, but we dont need replication also on Single Game
        ProjectedDecal = ProjectedDecal(Other);
        if ( ProjectedDecal != none )
        {
            PendingDecals[PendingDecals.Length] = ProjectedDecal;
            UpdateDecalsTime = Level.TimeSeconds + 0.01;
        }
    }
    return Super.CheckReplacement(Other,bSuperRelevant);
}

simulated function Tick(float DT)
{
    local ProjectedDecal Decal;
    local float NextUpdateTime;
        local int i,n;
    
    Super.Tick(DT);
    if ( Level.NetMode != NM_DedicatedServer && UpdateDecalsTime < Level.TimeSeconds )
    {
        n = Decals.Length;
        foreach DynamicActors(class'ProjectedDecal',Decal)
        {
            for(i=0; i<n; i++)
            if ( Decals[i].Decal == none )
            {
                Decals.Remove(i,1);
                i--;
                n--;
            }
            else if ( Decals[i].Decal == Decal ) break;
            if ( i >= n )
            {
                if ( NumDecals++ <= 0 )
                {
                    FirstDecalSpawnTime = Level.TimeSeconds;
                    NumDecals++;
                }
                Decals.Insert(n,1);
                Decals[n].Decal = Decal;
                Decals[n].DestroyTime = Level.TimeSeconds + Decal.default.LifeSpan;
                n++;
            }
        }
        for(i=0; i<n; i++)
        {
            if ( Decals[i].DestroyTime <= Level.TimeSeconds ) /*&& Decals[i].bDeleteMe )*/
            {
                Decals[i].Decal.Destroy();
                Decals.Remove(i,1);
                i--;
                n--;
            }
        }

        NextUpdateTime = Level.TimeSeconds + (FMax((Level.TimeSeconds-FirstDecalSpawnTime),1)/FMax(NumDecals,1))*RandRange(0.75,1);
    
        if ( ( Level.NetMode == NM_DedicatedServer || Level.NetMode == NM_ListenServer ) && PendingDecals.Length > 0 )
        {
            while ( PendingDecals.Length > 0 )
            {
                PendingDecals[0].bTearOff = true;
                PendingDecals.Remove(0,1);
            }
        }
    }
}

defaultproperties
{
    bAlwaysRelevant=true
    RemoteRole=ROLE_SimulatedProxy
    bAddToServerPackages=true
    GroupName="KF-DecalEraser"
        FriendlyName="DecalEraser"
        Description="Erases decals."
}
 

Skell

Active member
Mar 21, 2013
1,245
2
38
On the Internet.
the most effective way to do this would be to repackage your husks and modify their decals to have a lifespan and use it properly (like they should have to begin with).
 

Dr_Killjoy

FNG / Fresh Meat
Sep 30, 2012
260
0
0
the most effective way to do this would be to repackage your husks and modify their decals to have a lifespan and use it properly (like they should have to begin with).

Change each class is better way ofc, but sometimes global decisions are needed too.