boiii-scripts/shared/ai/systems/fx_character.csc
2023-04-13 17:30:38 +02:00

256 lines
14 KiB
Plaintext

#using scripts\codescripts\struct;
#using scripts\shared\ai\systems\destructible_character;
#using scripts\shared\ai\systems\gib;
function autoexec main()
{
fxBundles = struct::get_script_bundles( "fxcharacterdef" );
processedFxBundles = [];
// Process all fx character script bundles into a direct lookup form for future access.
foreach ( fxBundleName, fxBundle in fxBundles )
{
processedFxBundle = SpawnStruct();
processedFxBundle.effectCount = fxBundle.effectCount;
processedFxBundle.fx = [];
processedFxBundle.name = fxBundleName;
for ( index = 1; index <= fxBundle.effectCount; index++ )
{
fx = GetStructField( fxBundle, "effect" + index + "_fx" );
if ( IsDefined( fx ) )
{
fxStruct = SpawnStruct();
fxStruct.attachTag = GetStructField( fxBundle, "effect" + index + "_attachtag" );
fxStruct.fx = GetStructField( fxBundle, "effect" + index + "_fx" );
fxStruct.stopOnGib = FxClientUtils::_GibPartNameToGibFlag(
GetStructField( fxBundle, "effect" + index + "_stopongib" ) );
fxStruct.stopOnPieceDestroyed = GetStructField( fxBundle, "effect" + index + "_stoponpiecedestroyed" );
processedFxBundle.fx[ processedFxBundle.fx.size ] = fxStruct;
}
}
processedFxBundles[ fxBundleName ] = processedFxBundle;
}
// Replaces all fx character script bundles with their processed form to free unncessary script variables.
level.scriptbundles[ "fxcharacterdef" ] = processedFxBundles;
}
#namespace FxClientUtils;
function private _ConfigEntity( localClientNum, entity )
{
if ( !IsDefined( entity._fxCharacter ) )
{
entity._fxCharacter = [];
handledGibs = array(
8,
16,
32,
128,
256 );
foreach ( gibFlag in handledGibs )
{
GibClientUtils::AddGibCallback( localClientNum, entity, gibFlag, &_GibHandler );
}
for ( index = 1; index <= 20; index++ )
{
DestructClientUtils::AddDestructPieceCallback( localClientNum, entity, index, &_DestructHandler );
}
}
}
function private _DestructHandler( localClientNum, entity, pieceNumber )
{
if ( !IsDefined( entity._fxCharacter ) )
{
return;
}
foreach ( fxBundleName, fxBundleInst in entity._fxCharacter )
{
fxBundle = struct::get_script_bundle( "fxcharacterdef", fxBundleName );
for ( index = 0; index < fxBundle.fx.size; index++ )
{
if ( IsDefined( fxBundleInst[ index ] ) &&
fxBundle.fx[index].stopOnPieceDestroyed === pieceNumber )
{
StopFx( localClientNum, fxBundleInst[ index ] );
fxBundleInst[ index ] = undefined;
}
}
}
}
function private _GibHandler( localClientNum, entity, gibFlag )
{
if ( !IsDefined( entity._fxCharacter ) )
{
return;
}
foreach ( fxBundleName, fxBundleInst in entity._fxCharacter )
{
fxBundle = struct::get_script_bundle( "fxcharacterdef", fxBundleName );
for ( index = 0; index < fxBundle.fx.size; index++ )
{
if ( IsDefined( fxBundleInst[ index ] ) && fxBundle.fx[index].stopOnGib === gibFlag )
{
StopFx( localClientNum, fxBundleInst[ index ] );
fxBundleInst[ index ] = undefined;
}
}
}
}
function private _GibPartNameToGibFlag( gibPartName )
{
if ( IsDefined( gibPartName ) )
{
switch ( gibPartName )
{
case "head":
return 8;
case "right arm":
return 16;
case "left arm":
return 32;
case "right leg":
return 128;
case "left leg":
return 256;
}
}
}
function private _IsGibbed( localClientNum, entity, stopOnGibFlag )
{
if ( !IsDefined( stopOnGibFlag ) )
{
return false;
}
return GibClientUtils::IsGibbed( localClientNum, entity, stopOnGibFlag );
}
function private _IsPieceDestructed( localClientNum, entity, stopOnPieceDestroyed )
{
if ( !IsDefined( stopOnPieceDestroyed ) )
{
return false;
}
return DestructClientUtils::IsPieceDestructed( localClientNum, entity, stopOnPieceDestroyed );
}
function private _ShouldPlayFx( localClientNum, entity, fxStruct )
{
if ( _IsGibbed( localClientNum, entity, fxStruct.stopOnGib ) )
{
return false;
}
if ( _IsPieceDestructed( localClientNum, entity, fxStruct.stopOnPieceDestroyed ) )
{
return false;
}
return true;
}
function PlayFxBundle( localClientNum, entity, fxScriptBundle )
{
if ( !IsDefined( fxScriptBundle ) )
{
return;
}
_ConfigEntity( localClientNum, entity );
fxBundle = struct::get_script_bundle( "fxcharacterdef", fxScriptBundle );
if ( IsDefined( entity._fxCharacter[ fxBundle.name ] ) )
{
// FxBundle is already playing, early out.
return;
}
if ( IsDefined( fxBundle ) )
{
playingFx = [];
for ( index = 0; index < fxBundle.fx.size; index++ )
{
fxStruct = fxBundle.fx[ index ];
if ( _ShouldPlayFx( localClientNum, entity, fxStruct ) )
{
playingFx[ index ] =
GibClientUtils::_PlayGibFX( localClientNum, entity, fxStruct.fx, fxStruct.attachTag );
}
}
if ( playingFx.size > 0 )
{
entity._fxCharacter[ fxBundle.name ] = playingFx;
}
}
}
function StopAllFXBundles( localClientNum, entity )
{
_ConfigEntity( localClientNum, entity );
fxBundleNames = [];
foreach ( fxBundleName, fxBundle in entity._fxCharacter )
{
fxBundleNames[ fxBundleNames.size ] = fxBundleName;
}
foreach ( fxBundleName in fxBundleNames )
{
StopFxBundle( localClientNum, entity, fxBundleName );
}
}
function StopFxBundle( localClientNum, entity, fxScriptBundle )
{
if ( !IsDefined( fxScriptBundle ) )
{
return;
}
_ConfigEntity( localClientNum, entity );
fxBundle = struct::get_script_bundle( "fxcharacterdef", fxScriptBundle );
if ( IsDefined( entity._fxCharacter[ fxBundle.name ] ) )
{
foreach ( fx in entity._fxCharacter[ fxBundle.name ] )
{
if ( IsDefined( fx ) )
{
StopFx( localClientNum, fx );
}
}
entity._fxCharacter[ fxBundle.name ] = undefined;
}
}