1
0
KF2-Dev-Scripts/Engine/Classes/FractureManager.uc
2020-12-13 18:01:13 +03:00

173 lines
4.9 KiB
Ucode

/**
* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
*/
class FractureManager extends Actor
native(Mesh)
config(Game);
/* Number of FSM parts in the pool */
var int FSMPartPoolSize;
/** If TRUE, look for vibrating FSM parts and kill them */
var() bool bEnableAntiVibration;
/** How much vibration (defined as changes in angular velocity direction) must occur before part is killed. */
var() float DestroyVibrationLevel;
/** Min angular velocity of part to be killed by vibration detection code. */
var() float DestroyMinAngVel;
/** If TRUE, spawn effect for chunks falling off when doing radial damage (ie removing many chunks at once)*/
var() bool bEnableSpawnChunkEffectForRadialDamage;
/** */
var() float ExplosionVelScale;
/*
* Time after spawning a part during which the part is guaranteed to not be recycled again.
* Used to avoid redundant work when spawning a lot of parts relative to the pool size.
*/
const FSM_DEFAULTRECYCLETIME = 0.2;
var array<FracturedStaticMeshPart> PartPool;
var array<int> FreeParts;
/** List of actors that have fracture parts that have been deferred to spawn on upcoming frames */
var transient array< FracturedStaticMeshActor > ActorsWithDeferredPartsToSpawn;
/** Function use to spawn particle effect when a chunk is destroyed. */
`if(`__TW_LIGHTING_MODIFICATIONS_)
simulated event SpawnChunkDestroyEffect(ParticleSystem Effect, box ChunkBox, vector ChunkDir, float Scale, const FracturedStaticMeshComponent MeshComp)
`else
simulated event SpawnChunkDestroyEffect(ParticleSystem Effect, box ChunkBox, vector ChunkDir, float Scale)
`endif
{
local vector ChunkMiddle;
local ParticleSystemComponent EffectComp;
`if(`__TW_PERFORMANCE_)
if( WorldInfo.bDropDetail )
{
return;
}
`endif
ChunkMiddle = 0.5 * (ChunkBox.Min + ChunkBox.Max);
EffectComp = WorldInfo.MyEmitterPool.SpawnEmitter(Effect, ChunkMiddle, rotator(ChunkDir));
EffectComp.SetScale(Scale);
`if(`__TW_LIGHTING_MODIFICATIONS_)
if ( MeshComp != None )
{
EffectComp.SetLightingChannels(MeshComp.LightingChannels);
}
`endif
}
native function float GetNumFSMPartsScale();
/** Returns a scalar to the percentage chance of a fractured static mesh spawning a rigid body after
taking direct damage */
native function float GetFSMDirectSpawnChanceScale();
/** Returns a scalar to the percentage chance of a fractured static mesh spawning a rigid body after
taking radial damage, such as from an explosion */
native function float GetFSMRadialSpawnChanceScale();
/** Returns a distance scale for whether a fractured static mesh should actually fracture when damaged */
native function float GetFSMFractureCullDistanceScale();
cpptext
{
virtual void TickSpecial( FLOAT DeltaSeconds );
};
simulated event PreBeginPlay()
{
Super.PreBeginPlay();
CreateFSMParts();
}
simulated event Destroyed()
{
Super.Destroyed();
CleanUpFSMParts();
}
simulated final function CleanUpFSMParts()
{
local int Idx;
for( Idx=0; Idx<PartPool.length; Idx++ )
{
PartPool[Idx].Destroy();
PartPool[Idx] = None;
}
}
/** */
native function CreateFSMParts();
/** Recycles any active parts */
simulated native function ResetPoolVisibility();
/** Grab a FSMP from the free pool, or forcibly recycle a suitable one from the world. */
native function FracturedStaticMeshPart GetFSMPart(FracturedStaticMeshActor Parent, Vector SpawnLocation, Rotator SpawnRotation);
/** Function to actually spawn a FSMP. Allows game-specific pooling/capping of actors. */
simulated event FracturedStaticMeshPart SpawnPartActor(FracturedStaticMeshActor Parent, vector SpawnLocation, rotator SpawnRotation)
{
local FracturedStaticMeshPart NewPart;
//get a new part from the pool
NewPart = GetFSMPart(Parent, SpawnLocation, SpawnRotation);
if (NewPart != None)
{
NewPart.SetTimer( 10.f, FALSE, nameof(NewPart.TryToCleanUp) );
}
return NewPart;
}
/** Return a part to the pool. */
simulated event ReturnPartActor(FracturedStaticMeshPart Part)
{
FreeParts.AddItem(Part.PartPoolIndex);
}
/** Called every frame to update the object */
simulated function Tick( float DeltaTime )
{
local int CurActorIndex;
// Call parent implementation skipped because no implementation in Actor
//super.Tick( DeltaTime );
// Give any actors with deferred chunks a chance to spawn now
if( ActorsWithDeferredPartsToSpawn.length > 0 )
{
for( CurActorIndex = 0; CurActorIndex < ActorsWithDeferredPartsToSpawn.length; ++CurActorIndex )
{
if( ActorsWithDeferredPartsToSpawn[ CurActorIndex ].SpawnDeferredParts() )
{
// No chunks left to spawn, so we can remove it from our list
ActorsWithDeferredPartsToSpawn.remove( CurActorIndex, 1 );
--CurActorIndex;
}
}
}
}
defaultproperties
{
FSMPartPoolSize=50
bEnableAntiVibration=FALSE
DestroyVibrationLevel=3.0
DestroyMinAngVel=2.5
ExplosionVelScale=1.0
}