init
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
setfogsliders()
|
||||
{
|
||||
/#
|
||||
// The read-only vars are set each time a call to SetExpFog is made, so they should contain the 'fog dest' params
|
||||
SetDevDvar( "scr_fog_exp_halfplane", GetDvar( "g_fogHalfDistReadOnly", 0.0 ) );
|
||||
SetDevDvar( "scr_fog_nearplane", GetDvar( "g_fogStartDistReadOnly", 0.1 ) );
|
||||
SetDevDvar( "scr_fog_color", GetDvarVector( "g_fogColorReadOnly", ( 1, 0, 0 ) ) );
|
||||
SetDevDvar( "scr_fog_color_intensity", GetDvar( "g_fogColorIntensityReadOnly", 1.0 ) );
|
||||
SetDevDvar( "scr_fog_max_opacity", GetDvar( "g_fogMaxOpacityReadOnly", 1.0 ) );
|
||||
|
||||
SetDevDvar( "scr_sunFogEnabled", GetDvar( "g_sunFogEnabledReadOnly", 0 ) );
|
||||
SetDevDvar( "scr_sunFogColor", GetDvarVector( "g_sunFogColorReadOnly", ( 1, 0, 0 ) ) );
|
||||
SetDevDvar( "scr_sunfogColorIntensity", GetDvar( "g_sunFogColorIntensityReadOnly", 1.0 ) );
|
||||
SetDevDvar( "scr_sunFogDir", GetDvarVector( "g_sunFogDirReadOnly", ( 1, 0, 0 ) ) );
|
||||
SetDevDvar( "scr_sunFogBeginFadeAngle", GetDvar( "g_sunFogBeginFadeAngleReadOnly", 0.0 ) );
|
||||
SetDevDvar( "scr_sunFogEndFadeAngle", GetDvar( "g_sunFogEndFadeAngleReadOnly", 180.0 ) );
|
||||
SetDevDvar( "scr_sunFogScale", GetDvar( "g_sunFogScaleReadOnly", 1.0 ) );
|
||||
|
||||
// The r_sky_fog vars are only active if tweaks on them are enabled, which is a little strange...
|
||||
SetDevDvar( "scr_skyFogIntensity", GetDvar( "r_sky_fog_intensity" ), 0.0 );
|
||||
SetDevDvar( "scr_skyFogMinAngle", GetDvar( "r_sky_fog_min_angle" ), 0.0 );
|
||||
SetDevDvar( "scr_skyFogMaxAngle", GetDvar( "r_sky_fog_max_angle" ), 90.0 );
|
||||
#/
|
||||
}
|
||||
|
||||
/#
|
||||
translateFogSlidersToScript()
|
||||
{
|
||||
level.fogexphalfplane = limit( GetDvarFloat( "scr_fog_exp_halfplane" ) );
|
||||
level.fognearplane = limit( GetDvarFloat( "scr_fog_nearplane" ) );
|
||||
level.fogHDRColorIntensity = limit( GetDvarFloat( "scr_fog_color_intensity" ) );
|
||||
level.fogmaxopacity = limit( GetDvarFloat( "scr_fog_max_opacity" ) );
|
||||
|
||||
level.sunFogEnabled = GetDvarInt( "scr_sunFogEnabled" );
|
||||
level.sunFogHDRColorIntensity = limit( GetDvarFloat( "scr_sunFogColorIntensity" ) );
|
||||
level.sunFogBeginFadeAngle = limit( GetDvarFloat( "scr_sunFogBeginFadeAngle" ) );
|
||||
level.sunFogEndFadeAngle = limit( GetDvarFloat( "scr_sunFogEndFadeAngle" ) );
|
||||
level.sunFogScale = limit( GetDvarFloat( "scr_sunFogScale" ) );
|
||||
|
||||
level.skyFogIntensity = limit( GetDvarFloat( "scr_skyFogIntensity" ) );
|
||||
level.skyFogMinAngle = limit( GetDvarFloat( "scr_skyFogMinAngle" ) );
|
||||
level.skyFogMaxAngle = limit( GetDvarFloat( "scr_skyFogMaxAngle" ) );
|
||||
|
||||
fogColor = GetDvarVector( "scr_fog_color" );
|
||||
r = limit( fogColor[0] );
|
||||
g = limit( fogColor[1] );
|
||||
b = limit( fogColor[2] );
|
||||
level.fogcolor = ( r, g , b );
|
||||
|
||||
sunFogColor = GetDvarVector( "scr_sunFogColor" );
|
||||
r = limit( sunFogColor[0] );
|
||||
g = limit( sunFogColor[1] );
|
||||
b = limit( sunFogColor[2] );
|
||||
level.sunFogColor =( r, g , b );
|
||||
|
||||
sunFogDir = GetDvarVector( "scr_sunFogDir" );
|
||||
x = limit( sunFogDir[0]);
|
||||
y = limit( sunFogDir[1]);
|
||||
z = limit( sunFogDir[2]);
|
||||
level.sunFogDir = ( x, y, z );
|
||||
}
|
||||
|
||||
limit( i )
|
||||
{
|
||||
limit = 0.001;
|
||||
if ( ( i < limit ) && ( i > ( limit * -1 ) ) )
|
||||
i = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
fogslidercheck()
|
||||
{
|
||||
// catch all those cases where a slider can be pushed to a place of conflict
|
||||
if ( level.sunFogBeginFadeAngle >= level.sunFogEndFadeAngle )
|
||||
{
|
||||
level.sunFogBeginFadeAngle = level.sunFogEndFadeAngle - 1;
|
||||
SetDvar( "scr_sunFogBeginFadeAngle", level.sunFogBeginFadeAngle );
|
||||
}
|
||||
|
||||
if ( level.sunFogEndFadeAngle <= level.sunFogBeginFadeAngle )
|
||||
{
|
||||
level.sunFogEndFadeAngle = level.sunFogBeginFadeAngle + 1;
|
||||
SetDvar( "scr_sunFogEndFadeAngle", level.sunFogEndFadeAngle );
|
||||
}
|
||||
}
|
||||
|
||||
add_vision_set_to_list( vision_set_name )
|
||||
{
|
||||
assert( IsDefined( level.vision_set_names ) );
|
||||
|
||||
found = array_find( level.vision_set_names, vision_set_name );
|
||||
if ( IsDefined( found ) )
|
||||
return;
|
||||
|
||||
level.vision_set_names = array_add( level.vision_set_names, vision_set_name );
|
||||
}
|
||||
|
||||
print_vision( vision_set )
|
||||
{
|
||||
found = array_find( level.vision_set_names, vision_set );
|
||||
if ( !IsDefined( found ) )
|
||||
return;
|
||||
|
||||
fileprint_launcher_start_file();
|
||||
|
||||
// Glow
|
||||
fileprint_launcher( "r_glow \"" + GetDvar( "r_glowTweakEnable" ) + "\"" );
|
||||
fileprint_launcher( "r_glowRadius0 \"" + GetDvar( "r_glowTweakRadius0" ) + "\"" );
|
||||
fileprint_launcher( "r_glowBloomPinch \"" + GetDvar( "r_glowTweakBloomPinch" ) + "\"" );
|
||||
fileprint_launcher( "r_glowBloomCutoff \"" + GetDvar( "r_glowTweakBloomCutoff" ) + "\"" );
|
||||
fileprint_launcher( "r_glowBloomDesaturation \"" + GetDvar( "r_glowTweakBloomDesaturation" ) + "\"" );
|
||||
fileprint_launcher( "r_glowBloomIntensity0 \"" + GetDvar( "r_glowTweakBloomIntensity0" ) + "\"" );
|
||||
fileprint_launcher( "r_glowUseAltCutoff \"" + GetDvar( "r_glowTweakUseAltCutoff" ) + "\"" );
|
||||
fileprint_launcher( " " );
|
||||
|
||||
// Film
|
||||
fileprint_launcher( "r_filmEnable \"" + GetDvar( "r_filmTweakEnable" ) + "\"" );
|
||||
fileprint_launcher( "r_filmContrast \"" + GetDvar( "r_filmTweakContrast" ) + "\"" );
|
||||
fileprint_launcher( "r_filmBrightness \"" + GetDvar( "r_filmTweakBrightness" ) + "\"" );
|
||||
fileprint_launcher( "r_filmDesaturation \"" + GetDvar( "r_filmTweakDesaturation" ) + "\"" );
|
||||
fileprint_launcher( "r_filmDesaturationDark \"" + GetDvar( "r_filmTweakDesaturationDark" ) + "\"" );
|
||||
fileprint_launcher( "r_filmInvert \"" + GetDvar( "r_filmTweakInvert" ) + "\"" );
|
||||
fileprint_launcher( "r_filmLightTint \"" + GetDvar( "r_filmTweakLightTint" ) + "\"" );
|
||||
fileprint_launcher( "r_filmMediumTint \"" + GetDvar( "r_filmTweakMediumTint" ) + "\"" );
|
||||
fileprint_launcher( "r_filmDarkTint \"" + GetDvar( "r_filmTweakDarkTint" ) + "\"" );
|
||||
fileprint_launcher( " " );
|
||||
|
||||
// Character Light
|
||||
fileprint_launcher( "r_primaryLightUseTweaks \"" + GetDvar( "r_primaryLightUseTweaks" ) + "\"" );
|
||||
fileprint_launcher( "r_primaryLightTweakDiffuseStrength \"" + GetDvar( "r_primaryLightTweakDiffuseStrength" ) + "\"" );
|
||||
fileprint_launcher( "r_primaryLightTweakSpecularStrength \"" + GetDvar( "r_primaryLightTweakSpecularStrength" ) + "\"" );
|
||||
fileprint_launcher( "r_charLightAmbient \"" + GetDvar( "r_charLightAmbient" ) + "\"" );
|
||||
fileprint_launcher( "r_primaryLightUseTweaks_NG \"" + GetDvar( "r_primaryLightUseTweaks_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_primaryLightTweakDiffuseStrength_NG \"" + GetDvar( "r_primaryLightTweakDiffuseStrength_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_primaryLightTweakSpecularStrength_NG \"" + GetDvar( "r_primaryLightTweakSpecularStrength_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_charLightAmbient_NG \"" + GetDvar( "r_charLightAmbient_NG" ) + "\"" );
|
||||
fileprint_launcher( " " );
|
||||
|
||||
// Viewmodel Light
|
||||
fileprint_launcher( "r_viewModelPrimaryLightUseTweaks \"" + GetDvar( "r_viewModelPrimaryLightUseTweaks" ) + "\"" );
|
||||
fileprint_launcher( "r_viewModelPrimaryLightTweakDiffuseStrength \"" + GetDvar( "r_viewModelPrimaryLightTweakDiffuseStrength" ) + "\"" );
|
||||
fileprint_launcher( "r_viewModelPrimaryLightTweakSpecularStrength \"" + GetDvar( "r_viewModelPrimaryLightTweakSpecularStrength" ) + "\"" );
|
||||
fileprint_launcher( "r_viewModelLightAmbient \"" + GetDvar( "r_viewModelLightAmbient" ) + "\"" );
|
||||
fileprint_launcher( "r_viewModelPrimaryLightUseTweaks_NG \"" + GetDvar( "r_viewModelPrimaryLightUseTweaks_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_viewModelPrimaryLightTweakDiffuseStrength_NG \"" + GetDvar( "r_viewModelPrimaryLightTweakDiffuseStrength_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_viewModelPrimaryLightTweakSpecularStrength_NG \"" + GetDvar( "r_viewModelPrimaryLightTweakSpecularStrength_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_viewModelLightAmbient_NG \"" + GetDvar( "r_viewModelLightAmbient_NG" ) + "\"" );
|
||||
fileprint_launcher( " " );
|
||||
|
||||
// Material Bloom
|
||||
fileprint_launcher( "r_materialBloomRadius \"" + GetDvar( "r_materialBloomRadius" ) + "\"" );
|
||||
fileprint_launcher( "r_materialBloomPinch \"" + GetDvar( "r_materialBloomPinch" ) + "\"" );
|
||||
fileprint_launcher( "r_materialBloomIntensity \"" + GetDvar( "r_materialBloomIntensity" ) + "\"" );
|
||||
fileprint_launcher( "r_materialBloomLuminanceCutoff \"" + GetDvar( "r_materialBloomLuminanceCutoff" ) + "\"" );
|
||||
fileprint_launcher( "r_materialBloomDesaturation \"" + GetDvar( "r_materialBloomDesaturation" ) + "\"" );
|
||||
fileprint_launcher( " " );
|
||||
|
||||
// Volume Light Scatter
|
||||
fileprint_launcher( "r_volumeLightScatter \"" + GetDvar( "r_volumeLightScatterUseTweaks" ) + "\"" );
|
||||
fileprint_launcher( "r_volumeLightScatterLinearAtten \"" + GetDvar( "r_volumeLightScatterLinearAtten" ) + "\"" );
|
||||
fileprint_launcher( "r_volumeLightScatterQuadraticAtten \"" + GetDvar( "r_volumeLightScatterQuadraticAtten" ) + "\"" );
|
||||
fileprint_launcher( "r_volumeLightScatterAngularAtten \"" + GetDvar( "r_volumeLightScatterAngularAtten" ) + "\"" );
|
||||
fileprint_launcher( "r_volumeLightScatterDepthAttenNear \"" + GetDvar( "r_volumeLightScatterDepthAttenNear" ) + "\"" );
|
||||
fileprint_launcher( "r_volumeLightScatterDepthAttenFar \"" + GetDvar( "r_volumeLightScatterDepthAttenFar" ) + "\"" );
|
||||
fileprint_launcher( "r_volumeLightScatterBackgroundDistance \"" + GetDvar( "r_volumeLightScatterBackgroundDistance" ) + "\"" );
|
||||
fileprint_launcher( "r_volumeLightScatterColor \"" + GetDvar( "r_volumeLightScatterColor" ) + "\"" );
|
||||
fileprint_launcher( " " );
|
||||
|
||||
// SSAO
|
||||
fileprint_launcher( "r_ssaoStrength \"" + GetDvar( "r_ssaoStrength" ) + "\"" );
|
||||
fileprint_launcher( "r_ssaoPower \"" + GetDvar( "r_ssaoPower" ) + "\"" );
|
||||
fileprint_launcher( " " );
|
||||
|
||||
// Rim Light
|
||||
fileprint_launcher( "r_rimLight0Pitch \"" + GetDvar( "r_rimLight0Pitch" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLight0Heading \"" + GetDvar( "r_rimLight0Heading" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLightDiffuseIntensity \"" + GetDvar( "r_rimLightDiffuseIntensity" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLightSpecIntensity \"" + GetDvar( "r_rimLightSpecIntensity" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLightBias \"" + GetDvar( "r_rimLightBias" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLightPower \"" + GetDvar( "r_rimLightPower" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLight0Color \"" + GetDvar( "r_rimLight0Color" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLight0Pitch_NG \"" + GetDvar( "r_rimLight0Pitch_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLight0Heading_NG \"" + GetDvar( "r_rimLight0Heading_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLightDiffuseIntensity_NG \"" + GetDvar( "r_rimLightDiffuseIntensity_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLightSpecIntensity_NG \"" + GetDvar( "r_rimLightSpecIntensity_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLightBias_NG \"" + GetDvar( "r_rimLightBias_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLightPower_NG \"" + GetDvar( "r_rimLightPower_NG" ) + "\"" );
|
||||
fileprint_launcher( "r_rimLight0Color_NG \"" + GetDvar( "r_rimLight0Color_NG" ) + "\"" );
|
||||
fileprint_launcher( " " );
|
||||
|
||||
// Unlit Surface
|
||||
fileprint_launcher( "r_unlitSurfaceHDRScalar \"" + GetDvar( "r_unlitSurfaceHDRScalar" ) + "\"" );
|
||||
fileprint_launcher( " " );
|
||||
|
||||
// Colorization
|
||||
colorizationName = GetDvar( "r_colorizationTweakName" );
|
||||
toneMappingName = GetDvar( "r_toneMappingTweakName" );
|
||||
clutMaterialName = GetDvar( "r_clutMaterialTweakName" );
|
||||
if ( colorizationName != "" )
|
||||
fileprint_launcher( "colorizationSet \"" + colorizationName + "\"" );
|
||||
if ( toneMappingName != "" )
|
||||
fileprint_launcher( "toneMapping \"" + toneMappingName + "\"" );
|
||||
if ( clutMaterialName != "" )
|
||||
fileprint_launcher( "clutMaterial \"" + clutMaterialName + "\"" );
|
||||
|
||||
return fileprint_launcher_end_file( "\\share\\raw\\vision\\" + vision_set + ".vision", true );
|
||||
}
|
||||
|
||||
print_fog_ents( forMP )
|
||||
{
|
||||
foreach( ent in level.vision_set_fog )
|
||||
{
|
||||
if( !isdefined( ent.name ) )
|
||||
continue;
|
||||
|
||||
if ( forMP )
|
||||
fileprint_launcher( "\tent = maps\\mp\\_art::create_vision_set_fog( \"" + ent.name + "\" );");
|
||||
else
|
||||
fileprint_launcher( "\tent = maps\\_utility::create_vision_set_fog( \"" + ent.name + "\" );");
|
||||
|
||||
fileprint_launcher( "\tent.startDist = " + ent.startDist + ";" );
|
||||
fileprint_launcher( "\tent.halfwayDist = " + ent.halfwayDist + ";" );
|
||||
fileprint_launcher( "\tent.red = " + ent.red + ";" );
|
||||
fileprint_launcher( "\tent.green = " + ent.green + ";" );
|
||||
fileprint_launcher( "\tent.blue = " + ent.blue + ";" );
|
||||
fileprint_launcher( "\tent.HDRColorIntensity = " + ent.HDRColorIntensity + ";" );
|
||||
fileprint_launcher( "\tent.maxOpacity = " + ent.maxOpacity + ";" );
|
||||
fileprint_launcher( "\tent.transitionTime = " + ent.transitionTime + ";" );
|
||||
fileprint_launcher( "\tent.sunFogEnabled = " + ent.sunFogEnabled + ";" );
|
||||
fileprint_launcher( "\tent.sunRed = " + ent.sunRed + ";" );
|
||||
fileprint_launcher( "\tent.sunGreen = " + ent.sunGreen + ";" );
|
||||
fileprint_launcher( "\tent.sunBlue = " + ent.sunBlue + ";" );
|
||||
fileprint_launcher( "\tent.HDRSunColorIntensity = " + ent.HDRSunColorIntensity + ";" );
|
||||
fileprint_launcher( "\tent.sunDir = " + ent.sunDir + ";" );
|
||||
fileprint_launcher( "\tent.sunBeginFadeAngle = " + ent.sunBeginFadeAngle + ";" );
|
||||
fileprint_launcher( "\tent.sunEndFadeAngle = " + ent.sunEndFadeAngle + ";" );
|
||||
fileprint_launcher( "\tent.normalFogScale = " + ent.normalFogScale + ";" );
|
||||
fileprint_launcher( "\tent.skyFogIntensity = " + ent.skyFogIntensity + ";" );
|
||||
fileprint_launcher( "\tent.skyFogMinAngle = " + ent.skyFogMinAngle + ";" );
|
||||
fileprint_launcher( "\tent.skyFogMaxAngle = " + ent.skyFogMaxAngle + ";" );
|
||||
|
||||
if ( IsDefined( ent.HDROverride ) )
|
||||
fileprint_launcher( "\tent.HDROverride = \"" + ent.HDROverride + "\";" );
|
||||
|
||||
if( isDefined( ent.stagedVisionSets ) )
|
||||
{
|
||||
string = " ";
|
||||
for( i = 0; i < ent.stagedVisionSets.size; i++ )
|
||||
{
|
||||
string = string + "\""+ ent.stagedVisionSets[i] + "\"";
|
||||
if ( i < ent.stagedVisionSets.size - 1 )
|
||||
string = string + ",";
|
||||
string = string + " ";
|
||||
}
|
||||
|
||||
fileprint_launcher( "\tent.stagedVisionSets = [" + string + "];" );
|
||||
}
|
||||
|
||||
fileprint_launcher ( " " );
|
||||
}
|
||||
}
|
||||
|
||||
print_fog_ents_csv()
|
||||
{
|
||||
foreach( ent in level.vision_set_fog )
|
||||
{
|
||||
if( !isdefined( ent.name ) )
|
||||
continue;
|
||||
|
||||
targettedByHDROverride = false;
|
||||
foreach( ent2 in level.vision_set_fog )
|
||||
{
|
||||
if ( isdefined(ent2.HDROverride) && ent2.HDROverride == ent.name )
|
||||
{
|
||||
targettedByHDROverride = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !targettedByHDROverride )
|
||||
fileprint_launcher( "rawfile,vision/"+ent.name+".vision");
|
||||
}
|
||||
}
|
||||
#/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,755 @@
|
||||
#include common_scripts\utility;
|
||||
#include common_scripts\_createfx;
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Menu init/loop section
|
||||
//---------------------------------------------------------
|
||||
init_menu()
|
||||
{
|
||||
level._createfx.options = [];
|
||||
// each option has a type, a name its stored under, a description, a default, and a mask it uses to determine
|
||||
// which types of fx can have this option
|
||||
addOption( "string", "fxid", "FX id", "nil", "fx" );
|
||||
addOption( "float", "delay", "Repeat rate/start delay", 0.5, "fx" );
|
||||
addOption( "string", "flag", "Flag", "nil", "exploder" );
|
||||
|
||||
if( !level.mp_createfx )
|
||||
{
|
||||
addOption( "string", "firefx", "2nd FX id", "nil", "exploder" );
|
||||
addOption( "float", "firefxdelay", "2nd FX id repeat rate", 0.5, "exploder" );
|
||||
addOption( "float", "firefxtimeout", "2nd FX timeout", 5, "exploder" );
|
||||
addOption( "string", "firefxsound", "2nd FX soundalias", "nil", "exploder" );
|
||||
addOption( "float", "damage", "Radius damage", 150, "exploder" );
|
||||
addOption( "float", "damage_radius", "Radius of radius damage", 250, "exploder" );
|
||||
addOption( "string", "earthquake", "Earthquake", "nil", "exploder" );
|
||||
addOption( "string", "ender", "Level notify for ending 2nd FX", "nil", "exploder" );
|
||||
}
|
||||
|
||||
addOption( "float", "delay_min", "Minimimum time between repeats", 1, "soundfx_interval" );
|
||||
addOption( "float", "delay_max", "Maximum time between repeats", 2, "soundfx_interval" );
|
||||
addOption( "int", "repeat", "Number of times to repeat", 5, "exploder" );
|
||||
addOption( "string", "exploder", "Exploder", "1", "exploder" );
|
||||
|
||||
addOption( "string", "soundalias", "Soundalias", "nil", "all" );
|
||||
addOption( "string", "loopsound", "Loopsound", "nil", "exploder" );
|
||||
|
||||
addOption( "int", "reactive_radius", "Reactive Radius", 100, "reactive_fx", ::input_reactive_radius );
|
||||
|
||||
if( !level.mp_createfx )
|
||||
{
|
||||
addOption( "string", "rumble", "Rumble", "nil", "exploder" );
|
||||
addOption( "int", "stoppable", "Can be stopped from script", "1", "all" );
|
||||
}
|
||||
|
||||
level.effect_list_offset = 0;
|
||||
level.effect_list_offset_max = 10;
|
||||
|
||||
|
||||
// creates mask groups. For example if the above says its mask is "fx", then all the types under "fx" can use the option
|
||||
level.createfxMasks = [];
|
||||
level.createfxMasks[ "all" ] = [];
|
||||
level.createfxMasks[ "all" ][ "exploder" ] = true;
|
||||
level.createfxMasks[ "all" ][ "oneshotfx" ] = true;
|
||||
level.createfxMasks[ "all" ][ "loopfx" ] = true;
|
||||
level.createfxMasks[ "all" ][ "soundfx" ] = true;
|
||||
level.createfxMasks[ "all" ][ "soundfx_interval" ] = true;
|
||||
level.createfxMasks[ "all" ][ "reactive_fx" ] = true;
|
||||
|
||||
level.createfxMasks[ "fx" ] = [];
|
||||
level.createfxMasks[ "fx" ][ "exploder" ] = true;
|
||||
level.createfxMasks[ "fx" ][ "oneshotfx" ] = true;
|
||||
level.createfxMasks[ "fx" ][ "loopfx" ] = true;
|
||||
|
||||
level.createfxMasks[ "exploder" ] = [];
|
||||
level.createfxMasks[ "exploder" ][ "exploder" ] = true;
|
||||
|
||||
level.createfxMasks[ "loopfx" ] = [];
|
||||
level.createfxMasks[ "loopfx" ][ "loopfx" ] = true;
|
||||
|
||||
level.createfxMasks[ "oneshotfx" ] = [];
|
||||
level.createfxMasks[ "oneshotfx" ][ "oneshotfx" ] = true;
|
||||
|
||||
level.createfxMasks[ "soundfx" ] = [];
|
||||
level.createfxMasks[ "soundfx" ][ "soundalias" ] = true;
|
||||
|
||||
level.createfxMasks[ "soundfx_interval" ] = [];
|
||||
level.createfxMasks[ "soundfx_interval" ][ "soundfx_interval" ] = true;
|
||||
|
||||
level.createfxMasks[ "reactive_fx" ] = [];
|
||||
level.createfxMasks[ "reactive_fx" ][ "reactive_fx" ] = true;
|
||||
|
||||
// Mainly used for input of a menu
|
||||
menus = [];
|
||||
menus[ "creation" ] = ::menu_create_select;
|
||||
menus[ "create_oneshot" ] = ::menu_create;
|
||||
menus[ "create_loopfx" ] = ::menu_create;
|
||||
menus[ "change_fxid" ] = ::menu_create;
|
||||
menus[ "none" ] = ::menu_none;
|
||||
menus[ "add_options" ] = ::menu_add_options;
|
||||
menus[ "select_by_name" ] = ::menu_select_by_name;
|
||||
|
||||
level._createfx.menus = menus;
|
||||
}
|
||||
|
||||
menu( name )
|
||||
{
|
||||
return level.create_fx_menu == name;
|
||||
}
|
||||
|
||||
setmenu( name )
|
||||
{
|
||||
level.create_fx_menu = name;
|
||||
}
|
||||
|
||||
create_fx_menu()
|
||||
{
|
||||
if ( button_is_clicked( "escape", "x" ) )
|
||||
{
|
||||
_exit_menu();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( IsDefined( level._createfx.menus[ level.create_fx_menu ] ) )
|
||||
{
|
||||
[[ level._createfx.menus[ level.create_fx_menu ] ]]();
|
||||
}
|
||||
}
|
||||
|
||||
menu_create_select()
|
||||
{
|
||||
if ( button_is_clicked( "1" ) )
|
||||
{
|
||||
setmenu( "create_oneshot" );
|
||||
draw_effects_list();
|
||||
return;
|
||||
}
|
||||
else if ( button_is_clicked( "2" ) )
|
||||
{
|
||||
setmenu( "create_loopsound" );
|
||||
ent = createLoopSound();
|
||||
finish_creating_entity( ent );
|
||||
return;
|
||||
}
|
||||
else if ( button_is_clicked( "3" ) )
|
||||
{
|
||||
setmenu( "create_exploder" );
|
||||
ent = createNewExploder();
|
||||
finish_creating_entity( ent );
|
||||
return;
|
||||
}
|
||||
else if ( button_is_clicked( "4" ) )
|
||||
{
|
||||
setmenu( "create_interval_sound" );
|
||||
ent = createIntervalSound();
|
||||
finish_creating_entity( ent );
|
||||
return;
|
||||
}
|
||||
else if ( button_is_clicked( "5" ) )
|
||||
{
|
||||
ent = createReactiveEnt();
|
||||
finish_creating_entity( ent );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
menu_create()
|
||||
{
|
||||
if ( next_button() )
|
||||
{
|
||||
increment_list_offset();
|
||||
draw_effects_list();
|
||||
}
|
||||
else if ( previous_button() )
|
||||
{
|
||||
decrement_list_offset();
|
||||
draw_effects_list();
|
||||
}
|
||||
|
||||
menu_fx_creation();
|
||||
}
|
||||
|
||||
menu_none()
|
||||
{
|
||||
if ( button_is_clicked( "m" ) )
|
||||
increment_list_offset();
|
||||
|
||||
// change selected entities
|
||||
menu_change_selected_fx();
|
||||
|
||||
// if there's a selected ent then display the info on the last one to be selected
|
||||
if ( entities_are_selected() )
|
||||
{
|
||||
last_selected_ent = get_last_selected_ent();
|
||||
|
||||
// only update hudelems when we have new info
|
||||
if ( !IsDefined( level.last_displayed_ent ) || last_selected_ent != level.last_displayed_ent )
|
||||
{
|
||||
display_fx_info( last_selected_ent );
|
||||
level.last_displayed_ent = last_selected_ent;
|
||||
}
|
||||
|
||||
if ( button_is_clicked( "a" ) )
|
||||
{
|
||||
clear_settable_fx();
|
||||
setMenu( "add_options" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
level.last_displayed_ent = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
menu_add_options()
|
||||
{
|
||||
if ( !entities_are_selected() )
|
||||
{
|
||||
clear_fx_hudElements();
|
||||
setMenu( "none" );
|
||||
return;
|
||||
}
|
||||
|
||||
display_fx_add_options( get_last_selected_ent() );
|
||||
if ( next_button() )
|
||||
{
|
||||
increment_list_offset();
|
||||
// draw_effects_list();
|
||||
}
|
||||
}
|
||||
|
||||
menu_select_by_name()
|
||||
{
|
||||
if ( next_button() )
|
||||
{
|
||||
increment_list_offset();
|
||||
draw_effects_list( "Select by name" );
|
||||
}
|
||||
else if ( previous_button() )
|
||||
{
|
||||
decrement_list_offset();
|
||||
draw_effects_list( "Select by name" );
|
||||
}
|
||||
|
||||
select_by_name();
|
||||
}
|
||||
|
||||
next_button()
|
||||
{
|
||||
return button_is_clicked( "rightarrow" );
|
||||
}
|
||||
|
||||
previous_button()
|
||||
{
|
||||
return button_is_clicked( "leftarrow" );
|
||||
}
|
||||
|
||||
_exit_menu()
|
||||
{
|
||||
clear_fx_hudElements();
|
||||
clear_entity_selection();
|
||||
update_selected_entities();
|
||||
setmenu( "none" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Create FX Section (button presses)
|
||||
//---------------------------------------------------------
|
||||
menu_fx_creation()
|
||||
{
|
||||
count = 0;
|
||||
picked_fx = undefined;
|
||||
keys = func_get_level_fx();
|
||||
|
||||
for ( i = level.effect_list_offset; i < keys.size; i++ )
|
||||
{
|
||||
count = count + 1;
|
||||
button_to_check = count;
|
||||
if ( button_to_check == 10 )
|
||||
button_to_check = 0;
|
||||
if ( button_is_clicked( button_to_check + "" ) )
|
||||
{
|
||||
picked_fx = keys[ i ];
|
||||
break;
|
||||
}
|
||||
|
||||
if ( count > level.effect_list_offset_max )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !isdefined( picked_fx ) )
|
||||
return;
|
||||
|
||||
if ( menu( "change_fxid" ) )
|
||||
{
|
||||
apply_option_to_selected_fx( get_option( "fxid" ), picked_fx );
|
||||
level.effect_list_offset = 0;
|
||||
clear_fx_hudElements();
|
||||
setMenu( "none" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ent = undefined;
|
||||
if ( menu( "create_loopfx" ) )
|
||||
ent = createLoopEffect( picked_fx );
|
||||
if ( menu( "create_oneshot" ) )
|
||||
ent = createOneshotEffect( picked_fx );
|
||||
|
||||
finish_creating_entity( ent );
|
||||
}
|
||||
|
||||
finish_creating_entity( ent )
|
||||
{
|
||||
assert( isdefined( ent ) );
|
||||
ent.v[ "angles" ] = vectortoangles( ( ent.v[ "origin" ] + ( 0, 0, 100 ) ) - ent.v[ "origin" ] );
|
||||
ent post_entity_creation_function();// for createfx dev purposes
|
||||
clear_entity_selection();
|
||||
select_last_entity();
|
||||
move_selection_to_cursor();
|
||||
update_selected_entities();
|
||||
setMenu( "none" );
|
||||
}
|
||||
|
||||
entities_are_selected()
|
||||
{
|
||||
return level._createfx.selected_fx_ents.size > 0;
|
||||
}
|
||||
|
||||
menu_change_selected_fx()
|
||||
{
|
||||
if ( !level._createfx.selected_fx_ents.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
drawnCount = 0;
|
||||
ent = get_last_selected_ent();
|
||||
|
||||
for ( i = 0; i < level._createfx.options.size; i++ )
|
||||
{
|
||||
option = level._createfx.options[ i ];
|
||||
if ( !isdefined( ent.v[ option[ "name" ] ] ) )
|
||||
continue;
|
||||
count++ ;
|
||||
if ( count < level.effect_list_offset )
|
||||
continue;
|
||||
|
||||
drawnCount++ ;
|
||||
button_to_check = drawnCount;
|
||||
if ( button_to_check == 10 )
|
||||
button_to_check = 0;
|
||||
|
||||
if ( button_is_clicked( button_to_check + "" ) )
|
||||
{
|
||||
prepare_option_for_change( option, drawnCount );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( drawnCount > level.effect_list_offset_max )
|
||||
{
|
||||
more = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prepare_option_for_change( option, drawnCount )
|
||||
{
|
||||
if ( option[ "name" ] == "fxid" )
|
||||
{
|
||||
setMenu( "change_fxid" );
|
||||
draw_effects_list();
|
||||
return;
|
||||
}
|
||||
|
||||
level.createfx_inputlocked = true;
|
||||
level._createfx.hudelems[ drawnCount + 3 ][ 0 ].color = ( 1, 1, 0 );
|
||||
|
||||
if ( IsDefined( option[ "input_func" ] ) )
|
||||
{
|
||||
thread [[ option[ "input_func" ] ]]( drawnCount + 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
createfx_centerprint( "To change " + option[ "description" ] + " on selected entities, type /fx newvalue" );
|
||||
}
|
||||
|
||||
set_option_index( option[ "name" ] );
|
||||
setdvar( "fx", "nil" );
|
||||
}
|
||||
|
||||
menu_fx_option_set()
|
||||
{
|
||||
if ( getdvar( "fx" ) == "nil" )
|
||||
return;
|
||||
|
||||
option = get_selected_option();
|
||||
setting = undefined;
|
||||
if ( option[ "type" ] == "string" )
|
||||
setting = getdvar( "fx" );
|
||||
if ( option[ "type" ] == "int" )
|
||||
setting = getdvarint( "fx" );
|
||||
if ( option[ "type" ] == "float" )
|
||||
setting = getdvarfloat( "fx" );
|
||||
|
||||
apply_option_to_selected_fx( option, setting );
|
||||
}
|
||||
|
||||
apply_option_to_selected_fx( option, setting )
|
||||
{
|
||||
for ( i = 0; i < level._createfx.selected_fx_ents.size; i++ )
|
||||
{
|
||||
ent = level._createfx.selected_fx_ents[ i ];
|
||||
|
||||
if ( mask( option[ "mask" ], ent.v[ "type" ] ) )
|
||||
ent.v[ option[ "name" ] ] = setting;
|
||||
}
|
||||
|
||||
level.last_displayed_ent = undefined; // needed to force a redraw of the last display ent
|
||||
update_selected_entities();
|
||||
clear_settable_fx();
|
||||
}
|
||||
|
||||
set_option_index( name )
|
||||
{
|
||||
for ( i = 0; i < level._createfx.options.size; i++ )
|
||||
{
|
||||
if ( level._createfx.options[ i ][ "name" ] != name )
|
||||
continue;
|
||||
|
||||
level._createfx.selected_fx_option_index = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
get_selected_option()
|
||||
{
|
||||
return level._createfx.options[ level._createfx.selected_fx_option_index ];
|
||||
}
|
||||
|
||||
mask( type, name )
|
||||
{
|
||||
return isdefined( level.createfxMasks[ type ][ name ] );
|
||||
}
|
||||
|
||||
addOption( type, name, description, defaultSetting, mask, input_func )
|
||||
{
|
||||
option = [];
|
||||
option[ "type" ] = type;
|
||||
option[ "name" ] = name;
|
||||
option[ "description" ] = description;
|
||||
option[ "default" ] = defaultSetting;
|
||||
option[ "mask" ] = mask;
|
||||
|
||||
if ( IsDefined( input_func ) )
|
||||
{
|
||||
option[ "input_func" ] = input_func;
|
||||
}
|
||||
|
||||
level._createfx.options[ level._createfx.options.size ] = option;
|
||||
}
|
||||
|
||||
get_option( name )
|
||||
{
|
||||
for ( i = 0; i < level._createfx.options.size; i++ )
|
||||
{
|
||||
if ( level._createfx.options[ i ][ "name" ] == name )
|
||||
return level._createfx.options[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Reactive Radius
|
||||
//---------------------------------------------------------
|
||||
input_reactive_radius( menu_index )
|
||||
{
|
||||
level._createfx.hudelems[ menu_index ][ 0 ] SetDevText( "Reactive Radius, Press: + OR -" );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
wait( 0.05 );
|
||||
if ( level.player ButtonPressed( "escape" ) || level.player ButtonPressed( "x" ) )
|
||||
break;
|
||||
|
||||
val = 0;
|
||||
if ( level.player ButtonPressed( "-" ) )
|
||||
val = -10;
|
||||
else if ( level.player ButtonPressed( "=" ) )
|
||||
val = 10;
|
||||
|
||||
|
||||
if ( val != 0 )
|
||||
{
|
||||
foreach ( ent in level._createfx.selected_fx_ents )
|
||||
{
|
||||
if ( IsDefined( ent.v[ "reactive_radius" ] ) )
|
||||
{
|
||||
ent.v[ "reactive_radius" ] += val;
|
||||
ent.v[ "reactive_radius" ] = Clamp( ent.v[ "reactive_radius" ], 10, 1000 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
level.last_displayed_ent = undefined; // needed to force a redraw of the last display ent
|
||||
update_selected_entities();
|
||||
clear_settable_fx();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Display FX Add Options
|
||||
//---------------------------------------------------------
|
||||
display_fx_add_options( ent )
|
||||
{
|
||||
// are we doing the create fx menu right now?
|
||||
assert( menu( "add_options" ) );
|
||||
assert( entities_are_selected() );
|
||||
|
||||
clear_fx_hudElements();
|
||||
set_fx_hudElement( "Name: " + ent.v[ "fxid" ] );
|
||||
set_fx_hudElement( "Type: " + ent.v[ "type" ] );
|
||||
set_fx_hudElement( "Origin: " + ent.v[ "origin" ] );
|
||||
set_fx_hudElement( "Angles: " + ent.v[ "angles" ] );
|
||||
|
||||
// if entities are selected then we make the entity stats modifiable
|
||||
count = 0;
|
||||
drawnCount = 0;
|
||||
more = false;
|
||||
|
||||
if ( level.effect_list_offset >= level._createfx.options.size )
|
||||
level.effect_list_offset = 0;
|
||||
|
||||
for ( i = 0; i < level._createfx.options.size; i++ )
|
||||
{
|
||||
option = level._createfx.options[ i ];
|
||||
if ( isdefined( ent.v[ option[ "name" ] ] ) )
|
||||
continue;
|
||||
|
||||
// does this type of effect get this kind of option?
|
||||
if ( !mask( option[ "mask" ], ent.v[ "type" ] ) )
|
||||
continue;
|
||||
|
||||
count++ ;
|
||||
if ( count < level.effect_list_offset )
|
||||
continue;
|
||||
if ( drawnCount >= level.effect_list_offset_max )
|
||||
continue;
|
||||
|
||||
drawnCount++ ;
|
||||
button_to_check = drawnCount;
|
||||
if ( button_to_check == 10 )
|
||||
button_to_check = 0;
|
||||
if ( button_is_clicked( button_to_check + "" ) )
|
||||
{
|
||||
add_option_to_selected_entities( option );
|
||||
// prepare_option_for_change( option, drawnCount );
|
||||
menuNone();
|
||||
level.last_displayed_ent = undefined; // needed to force a redraw of the last display ent
|
||||
return;
|
||||
}
|
||||
|
||||
set_fx_hudElement( button_to_check + ". " + option[ "description" ] );
|
||||
}
|
||||
|
||||
if ( count > level.effect_list_offset_max )
|
||||
set_fx_hudElement( "(->) More >" );
|
||||
|
||||
set_fx_hudElement( "(x) Exit >" );
|
||||
}
|
||||
|
||||
add_option_to_selected_entities( option )
|
||||
{
|
||||
setting = undefined;
|
||||
for ( i = 0; i < level._createfx.selected_fx_ents.size; i++ )
|
||||
{
|
||||
ent = level._createfx.selected_fx_ents[ i ];
|
||||
|
||||
if ( mask( option[ "mask" ], ent.v[ "type" ] ) )
|
||||
ent.v[ option[ "name" ] ] = option[ "default" ];
|
||||
}
|
||||
}
|
||||
|
||||
menuNone()
|
||||
{
|
||||
level.effect_list_offset = 0;
|
||||
clear_fx_hudElements();
|
||||
setMenu( "none" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Display FX info
|
||||
//---------------------------------------------------------
|
||||
display_fx_info( ent )
|
||||
{
|
||||
// are we doing the create fx menu right now?
|
||||
if ( !menu( "none" ) )
|
||||
return;
|
||||
|
||||
clear_fx_hudElements();
|
||||
set_fx_hudElement( "Name: " + ent.v[ "fxid" ] );
|
||||
set_fx_hudElement( "Type: " + ent.v[ "type" ] );
|
||||
set_fx_hudElement( "Origin: " + ent.v[ "origin" ] );
|
||||
set_fx_hudElement( "Angles: " + ent.v[ "angles" ] );
|
||||
|
||||
if ( entities_are_selected() )
|
||||
{
|
||||
// if entities are selected then we make the entity stats modifiable
|
||||
count = 0;
|
||||
drawnCount = 0;
|
||||
more = false;
|
||||
for ( i = 0; i < level._createfx.options.size; i++ )
|
||||
{
|
||||
option = level._createfx.options[ i ];
|
||||
if ( !isdefined( ent.v[ option[ "name" ] ] ) )
|
||||
continue;
|
||||
count++ ;
|
||||
if ( count < level.effect_list_offset )
|
||||
continue;
|
||||
|
||||
drawnCount++ ;
|
||||
set_fx_hudElement( drawnCount + ". " + option[ "description" ] + ": " + ent.v[ option[ "name" ] ] );
|
||||
if ( drawnCount > level.effect_list_offset_max )
|
||||
{
|
||||
more = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( count > level.effect_list_offset_max )
|
||||
set_fx_hudElement( "(->) More >" );
|
||||
set_fx_hudElement( "(a) Add >" );
|
||||
set_fx_hudElement( "(x) Exit >" );
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 0;
|
||||
more = false;
|
||||
for ( i = 0; i < level._createfx.options.size; i++ )
|
||||
{
|
||||
option = level._createfx.options[ i ];
|
||||
if ( !isdefined( ent.v[ option[ "name" ] ] ) )
|
||||
continue;
|
||||
count++ ;
|
||||
set_fx_hudElement( option[ "description" ] + ": " + ent.v[ option[ "name" ] ] );
|
||||
if ( count > level._createfx.hudelem_count )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Draw Effects Section
|
||||
//---------------------------------------------------------
|
||||
draw_effects_list( title )
|
||||
{
|
||||
clear_fx_hudElements();
|
||||
|
||||
count = 0;
|
||||
more = false;
|
||||
|
||||
keys = func_get_level_fx();
|
||||
|
||||
if( !IsDefined( title ) )
|
||||
{
|
||||
title = "Pick an effect";
|
||||
}
|
||||
|
||||
set_fx_hudElement( title + " [" + level.effect_list_offset + " - " + keys.size + "]:" );
|
||||
|
||||
// if ( level.effect_list_offset >= keys.size )
|
||||
// level.effect_list_offset = 0;
|
||||
|
||||
for ( i = level.effect_list_offset; i < keys.size; i++ )
|
||||
{
|
||||
count = count + 1;
|
||||
set_fx_hudElement( count + ". " + keys[ i ] );
|
||||
if ( count >= level.effect_list_offset_max )
|
||||
{
|
||||
more = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( keys.size > level.effect_list_offset_max )
|
||||
{
|
||||
set_fx_hudElement( "(->) More >" );
|
||||
set_fx_hudElement( "(<-) Previous >" );
|
||||
}
|
||||
}
|
||||
|
||||
increment_list_offset()
|
||||
{
|
||||
keys = func_get_level_fx();
|
||||
|
||||
if ( level.effect_list_offset >= keys.size - level.effect_list_offset_max )
|
||||
{
|
||||
level.effect_list_offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
level.effect_list_offset += level.effect_list_offset_max;
|
||||
}
|
||||
}
|
||||
|
||||
decrement_list_offset()
|
||||
{
|
||||
level.effect_list_offset -= level.effect_list_offset_max;
|
||||
|
||||
if ( level.effect_list_offset < 0 )
|
||||
{
|
||||
keys = func_get_level_fx();
|
||||
level.effect_list_offset = keys.size - level.effect_list_offset_max;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Select by Name Section
|
||||
//---------------------------------------------------------
|
||||
select_by_name()
|
||||
{
|
||||
count = 0;
|
||||
picked_fx = undefined;
|
||||
keys = func_get_level_fx();
|
||||
|
||||
for ( i = level.effect_list_offset; i < keys.size; i++ )
|
||||
{
|
||||
count = count + 1;
|
||||
button_to_check = count;
|
||||
if ( button_to_check == 10 )
|
||||
button_to_check = 0;
|
||||
if ( button_is_clicked( button_to_check + "" ) )
|
||||
{
|
||||
picked_fx = keys[ i ];
|
||||
break;
|
||||
}
|
||||
|
||||
if ( count > level.effect_list_offset_max )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !IsDefined( picked_fx ) )
|
||||
return;
|
||||
|
||||
index_array = [];
|
||||
foreach ( i, ent in level.createFXent )
|
||||
{
|
||||
if ( IsSubStr( ent.v[ "fxid" ], picked_fx ) )
|
||||
{
|
||||
index_array[ index_array.size ] = i;
|
||||
}
|
||||
}
|
||||
|
||||
deselect_all_ents();
|
||||
select_index_array( index_array );
|
||||
|
||||
level._createfx.select_by_name = true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Utility Section
|
||||
//---------------------------------------------------------
|
||||
get_last_selected_ent()
|
||||
{
|
||||
return level._createfx.selected_fx_ents[ level._createfx.selected_fx_ents.size - 1 ];
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,987 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
/*
|
||||
|
||||
Handles Old-School exploders. This is coupled with _createfx and _fx since a Radiant Created "exploder" can trigger a createfx created effect.
|
||||
|
||||
This Script is legacy, tried and true, It eats up entites when using script_brushmodel swapping and a lot of script_models and the damage triggers.
|
||||
|
||||
We should in a future game consider some entiity optimization in code. A way to Join models and brushes as one entity would be key.
|
||||
|
||||
*/
|
||||
|
||||
setup_individual_exploder( ent )
|
||||
{
|
||||
exploder_num = ent.script_exploder;
|
||||
if ( !IsDefined( level.exploders[ exploder_num ] ) )
|
||||
{
|
||||
level.exploders[ exploder_num ] = [];
|
||||
}
|
||||
|
||||
targetname = ent.targetname;
|
||||
if ( !IsDefined( targetname ) )
|
||||
targetname = "";
|
||||
|
||||
level.exploders[ exploder_num ][ level.exploders[ exploder_num ].size ] = ent;
|
||||
if ( exploder_model_starts_hidden( ent ) )
|
||||
{
|
||||
ent Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( exploder_model_is_damaged_model( ent ) )
|
||||
{
|
||||
ent Hide();
|
||||
ent NotSolid();
|
||||
if ( IsDefined( ent.spawnflags ) && ( ent.spawnflags & 1 ) )
|
||||
{
|
||||
if ( IsDefined( ent.script_disconnectpaths ) )
|
||||
{
|
||||
ent ConnectPaths();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( exploder_model_is_chunk( ent ) )
|
||||
{
|
||||
ent Hide();
|
||||
ent NotSolid();
|
||||
if ( IsDefined( ent.spawnflags ) && ( ent.spawnflags & 1 ) )
|
||||
ent ConnectPaths();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setupExploders()
|
||||
{
|
||||
level.exploders = [];
|
||||
|
||||
// Hide exploder models.
|
||||
ents = GetEntArray( "script_brushmodel", "classname" );
|
||||
smodels = GetEntArray( "script_model", "classname" );
|
||||
for ( i = 0; i < smodels.size; i++ )
|
||||
ents[ ents.size ] = smodels[ i ];
|
||||
|
||||
foreach ( ent in ents )
|
||||
{
|
||||
if ( IsDefined( ent.script_prefab_exploder ) )
|
||||
ent.script_exploder = ent.script_prefab_exploder;
|
||||
|
||||
if ( IsDefined( ent.masked_exploder ) )
|
||||
continue;
|
||||
|
||||
if ( IsDefined( ent.script_exploder ) )
|
||||
{
|
||||
setup_individual_exploder( ent );
|
||||
}
|
||||
}
|
||||
|
||||
script_exploders = [];
|
||||
|
||||
potentialExploders = GetEntArray( "script_brushmodel", "classname" );
|
||||
for ( i = 0; i < potentialExploders.size; i++ )
|
||||
{
|
||||
if ( IsDefined( potentialExploders[ i ].script_prefab_exploder ) )
|
||||
potentialExploders[ i ].script_exploder = potentialExploders[ i ].script_prefab_exploder;
|
||||
|
||||
if ( IsDefined( potentialExploders[ i ].script_exploder ) )
|
||||
script_exploders[ script_exploders.size ] = potentialExploders[ i ];
|
||||
}
|
||||
|
||||
potentialExploders = GetEntArray( "script_model", "classname" );
|
||||
for ( i = 0; i < potentialExploders.size; i++ )
|
||||
{
|
||||
if ( IsDefined( potentialExploders[ i ].script_prefab_exploder ) )
|
||||
potentialExploders[ i ].script_exploder = potentialExploders[ i ].script_prefab_exploder;
|
||||
|
||||
if ( IsDefined( potentialExploders[ i ].script_exploder ) )
|
||||
script_exploders[ script_exploders.size ] = potentialExploders[ i ];
|
||||
}
|
||||
|
||||
potentialExploders = GetEntArray( "item_health", "classname" );
|
||||
for ( i = 0; i < potentialExploders.size; i++ )
|
||||
{
|
||||
if ( IsDefined( potentialExploders[ i ].script_prefab_exploder ) )
|
||||
potentialExploders[ i ].script_exploder = potentialExploders[ i ].script_prefab_exploder;
|
||||
|
||||
if ( IsDefined( potentialExploders[ i ].script_exploder ) )
|
||||
script_exploders[ script_exploders.size ] = potentialExploders[ i ];
|
||||
}
|
||||
|
||||
|
||||
potentialExploders = level.struct;
|
||||
for ( i = 0; i < potentialExploders.size; i++ )
|
||||
{
|
||||
if ( !IsDefined( potentialExploders[ i ] ) )
|
||||
continue; // these must be getting deleted somewhere else?
|
||||
if ( IsDefined( potentialExploders[ i ].script_prefab_exploder ) )
|
||||
potentialExploders[ i ].script_exploder = potentialExploders[ i ].script_prefab_exploder;
|
||||
|
||||
if ( IsDefined( potentialExploders[ i ].script_exploder ) )
|
||||
{
|
||||
if ( !IsDefined( potentialExploders[ i ].angles ) )
|
||||
potentialExploders[ i ].angles = ( 0, 0, 0 );
|
||||
script_exploders[ script_exploders.size ] = potentialExploders[ i ];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( !IsDefined( level.createFXent ) )
|
||||
level.createFXent = [];
|
||||
|
||||
acceptableTargetnames = [];
|
||||
acceptableTargetnames[ "exploderchunk visible" ] = true;
|
||||
acceptableTargetnames[ "exploderchunk" ] = true;
|
||||
acceptableTargetnames[ "exploder" ] = true;
|
||||
|
||||
thread setup_flag_exploders();
|
||||
|
||||
for ( i = 0; i < script_exploders.size; i++ )
|
||||
{
|
||||
exploder = script_exploders[ i ];
|
||||
|
||||
|
||||
ent = createExploder( exploder.script_fxid );
|
||||
ent.v = [];
|
||||
ent.v[ "origin" ] = exploder.origin;
|
||||
ent.v[ "angles" ] = exploder.angles;
|
||||
ent.v[ "delay" ] = exploder.script_delay;
|
||||
ent.v[ "delay_post" ] = exploder.script_delay_post;
|
||||
ent.v[ "firefx" ] = exploder.script_firefx;
|
||||
ent.v[ "firefxdelay" ] = exploder.script_firefxdelay;
|
||||
ent.v[ "firefxsound" ] = exploder.script_firefxsound;
|
||||
ent.v[ "earthquake" ] = exploder.script_earthquake;
|
||||
ent.v[ "rumble" ] = exploder.script_rumble;
|
||||
ent.v[ "damage" ] = exploder.script_damage;
|
||||
ent.v[ "damage_radius" ] = exploder.script_radius;
|
||||
ent.v[ "soundalias" ] = exploder.script_soundalias;
|
||||
ent.v[ "repeat" ] = exploder.script_repeat;
|
||||
ent.v[ "delay_min" ] = exploder.script_delay_min;
|
||||
ent.v[ "delay_max" ] = exploder.script_delay_max;
|
||||
ent.v[ "target" ] = exploder.target;
|
||||
ent.v[ "ender" ] = exploder.script_ender;
|
||||
ent.v[ "physics" ] = exploder.script_physics;
|
||||
ent.v[ "type" ] = "exploder";
|
||||
// ent.v[ "worldfx" ] = true;
|
||||
if ( !IsDefined( exploder.script_fxid ) )
|
||||
ent.v[ "fxid" ] = "No FX";
|
||||
else
|
||||
ent.v[ "fxid" ] = exploder.script_fxid;
|
||||
ent.v [ "exploder" ] = exploder.script_exploder;
|
||||
AssertEx( IsDefined( exploder.script_exploder ), "Exploder at origin " + exploder.origin + " has no script_exploder" );
|
||||
if ( IsDefined( level.createFXexploders ) )
|
||||
{ // if we're using the optimized lookup, add it in the proper place
|
||||
ary = level.createFXexploders[ ent.v[ "exploder" ] ];
|
||||
if ( !IsDefined( ary ) )
|
||||
ary = [];
|
||||
ary[ ary.size ] = ent;
|
||||
level.createFXexploders[ ent.v[ "exploder" ] ] = ary;
|
||||
}
|
||||
|
||||
if ( !IsDefined( ent.v[ "delay" ] ) )
|
||||
ent.v[ "delay" ] = 0;
|
||||
|
||||
if ( IsDefined( exploder.target ) )
|
||||
{
|
||||
get_ent = GetEntArray( ent.v[ "target" ], "targetname" )[ 0 ];
|
||||
if ( IsDefined( get_ent ) )
|
||||
{
|
||||
org = get_ent.origin;
|
||||
ent.v[ "angles" ] = VectorToAngles( org - ent.v[ "origin" ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
get_ent = get_target_ent( ent.v[ "target" ] );
|
||||
if ( IsDefined( get_ent ) )
|
||||
{
|
||||
org = get_ent.origin;
|
||||
ent.v[ "angles" ] = VectorToAngles( org - ent.v[ "origin" ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this basically determines if its a brush / model exploder or not
|
||||
if ( !IsDefined( exploder.code_classname ) )
|
||||
{
|
||||
//I assume everything that doesn't have a code_classname is a struct that needs a script_modelname to make its way into the game
|
||||
ent.model = exploder;
|
||||
if ( IsDefined( ent.model.script_modelname ) )
|
||||
{
|
||||
PreCacheModel( ent.model.script_modelname );
|
||||
}
|
||||
}
|
||||
else if ( exploder.code_classname == "script_brushmodel" || IsDefined( exploder.model ) )
|
||||
{
|
||||
ent.model = exploder;
|
||||
ent.model.disconnect_paths = exploder.script_disconnectpaths;
|
||||
}
|
||||
|
||||
if ( IsDefined( exploder.targetname ) && IsDefined( acceptableTargetnames[ exploder.targetname ] ) )
|
||||
ent.v[ "exploder_type" ] = exploder.targetname;
|
||||
else
|
||||
ent.v[ "exploder_type" ] = "normal";
|
||||
|
||||
if ( IsDefined( exploder.masked_exploder ) )
|
||||
{
|
||||
ent.v[ "masked_exploder" ] = exploder.model;
|
||||
ent.v[ "masked_exploder_spawnflags" ] = exploder.spawnflags;
|
||||
ent.v[ "masked_exploder_script_disconnectpaths" ] = exploder.script_disconnectpaths;
|
||||
exploder Delete();
|
||||
}
|
||||
ent common_scripts\_createfx::post_entity_creation_function();
|
||||
}
|
||||
}
|
||||
|
||||
setup_flag_exploders()
|
||||
{
|
||||
// createfx has to do 2 waittillframeends so we have to do 3 to make sure this comes after
|
||||
// createfx is all done setting up. Who will raise the gambit to 4?
|
||||
waittillframeend;
|
||||
waittillframeend;
|
||||
waittillframeend;
|
||||
exploder_flags = [];
|
||||
|
||||
foreach ( ent in level.createFXent )
|
||||
{
|
||||
if ( ent.v[ "type" ] != "exploder" )
|
||||
continue;
|
||||
theFlag = ent.v[ "flag" ];
|
||||
|
||||
if ( !IsDefined( theFlag ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( theFlag == "nil" )
|
||||
{
|
||||
ent.v[ "flag" ] = undefined;
|
||||
}
|
||||
|
||||
exploder_flags[ theFlag ] = true;
|
||||
}
|
||||
|
||||
foreach ( msg, _ in exploder_flags )
|
||||
{
|
||||
thread exploder_flag_wait( msg );
|
||||
}
|
||||
}
|
||||
|
||||
exploder_flag_wait( msg )
|
||||
{
|
||||
if ( !flag_exist( msg ) )
|
||||
flag_init( msg );
|
||||
flag_wait( msg );
|
||||
|
||||
foreach ( ent in level.createFXent )
|
||||
{
|
||||
if ( ent.v[ "type" ] != "exploder" )
|
||||
continue;
|
||||
theFlag = ent.v[ "flag" ];
|
||||
|
||||
if ( !IsDefined( theFlag ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( theFlag != msg )
|
||||
continue;
|
||||
ent activate_individual_exploder();
|
||||
}
|
||||
}
|
||||
|
||||
exploder_model_is_damaged_model( ent )
|
||||
{
|
||||
return( IsDefined( ent.targetname ) ) && ( ent.targetname == "exploder" );
|
||||
}
|
||||
|
||||
exploder_model_starts_hidden( ent )
|
||||
{
|
||||
return( ent.model == "fx" ) && ( ( !IsDefined( ent.targetname ) ) || ( ent.targetname != "exploderchunk" ) );
|
||||
}
|
||||
|
||||
exploder_model_is_chunk( ent )
|
||||
{
|
||||
return( IsDefined( ent.targetname ) ) && ( ent.targetname == "exploderchunk" );
|
||||
}
|
||||
|
||||
show_exploder_models_proc( num )
|
||||
{
|
||||
num += "";
|
||||
|
||||
//prof_begin( "hide_exploder" );
|
||||
if ( IsDefined( level.createFXexploders ) )
|
||||
{ // do optimized flavor if available
|
||||
exploders = level.createFXexploders[ num ];
|
||||
if ( IsDefined( exploders ) )
|
||||
{
|
||||
foreach ( ent in exploders )
|
||||
{
|
||||
//pre exploded geo. don't worry about deleted exploder geo..
|
||||
if ( ! exploder_model_starts_hidden( ent.model )
|
||||
&& ! exploder_model_is_damaged_model( ent.model )
|
||||
&& !exploder_model_is_chunk( ent.model ) )
|
||||
{
|
||||
ent.model Show();
|
||||
}
|
||||
|
||||
//exploded geo and should be shown
|
||||
if ( IsDefined( ent.brush_shown ) )
|
||||
ent.model Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < level.createFXent.size; i++ )
|
||||
{
|
||||
ent = level.createFXent[ i ];
|
||||
if ( !IsDefined( ent ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "type" ] != "exploder" )
|
||||
continue;
|
||||
|
||||
// make the exploder actually removed the array instead?
|
||||
if ( !IsDefined( ent.v[ "exploder" ] ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "exploder" ] + "" != num )
|
||||
continue;
|
||||
|
||||
if ( IsDefined( ent.model ) )
|
||||
{
|
||||
|
||||
//pre exploded geo. don't worry about deleted exploder geo..
|
||||
if ( ! exploder_model_starts_hidden( ent.model ) && ! exploder_model_is_damaged_model( ent.model ) && !exploder_model_is_chunk( ent.model ) )
|
||||
{
|
||||
ent.model Show();
|
||||
}
|
||||
|
||||
//exploded geo and should be shown
|
||||
if ( IsDefined( ent.brush_shown ) )
|
||||
ent.model Show();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//prof_end( "hide_exploder" );
|
||||
}
|
||||
|
||||
stop_exploder_proc( num )
|
||||
{
|
||||
num += "";
|
||||
|
||||
if ( IsDefined( level.createFXexploders ) )
|
||||
{ // do optimized flavor if available
|
||||
exploders = level.createFXexploders[ num ];
|
||||
if ( IsDefined( exploders ) )
|
||||
{
|
||||
foreach ( ent in exploders )
|
||||
{
|
||||
if ( !IsDefined( ent.looper ) )
|
||||
continue;
|
||||
|
||||
ent.looper Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < level.createFXent.size; i++ )
|
||||
{
|
||||
ent = level.createFXent[ i ];
|
||||
if ( !IsDefined( ent ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "type" ] != "exploder" )
|
||||
continue;
|
||||
|
||||
// make the exploder actually removed the array instead?
|
||||
if ( !IsDefined( ent.v[ "exploder" ] ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "exploder" ] + "" != num )
|
||||
continue;
|
||||
|
||||
if ( !IsDefined( ent.looper ) )
|
||||
continue;
|
||||
|
||||
ent.looper Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get_exploder_array_proc( msg )
|
||||
{
|
||||
msg += "";
|
||||
array = [];
|
||||
if ( IsDefined( level.createFXexploders ) )
|
||||
{ // do optimized flavor if available
|
||||
exploders = level.createFXexploders[ msg ];
|
||||
if ( IsDefined( exploders ) )
|
||||
{
|
||||
array = exploders;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( ent in level.createFXent )
|
||||
{
|
||||
if ( ent.v[ "type" ] != "exploder" )
|
||||
continue;
|
||||
|
||||
// make the exploder actually removed the array instead?
|
||||
if ( !IsDefined( ent.v[ "exploder" ] ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "exploder" ] + "" != msg )
|
||||
continue;
|
||||
|
||||
array[ array.size ] = ent;
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
hide_exploder_models_proc( num )
|
||||
{
|
||||
num += "";
|
||||
|
||||
//prof_begin( "hide_exploder" );
|
||||
|
||||
if ( IsDefined( level.createFXexploders ) )
|
||||
{ // do optimized flavor if available
|
||||
exploders = level.createFXexploders[ num ];
|
||||
if ( IsDefined( exploders ) )
|
||||
{
|
||||
foreach ( ent in exploders )
|
||||
{
|
||||
if ( IsDefined( ent.model ) )
|
||||
ent.model Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < level.createFXent.size; i++ )
|
||||
{
|
||||
ent = level.createFXent[ i ];
|
||||
if ( !IsDefined( ent ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "type" ] != "exploder" )
|
||||
continue;
|
||||
|
||||
// make the exploder actually removed the array instead?
|
||||
if ( !IsDefined( ent.v[ "exploder" ] ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "exploder" ] + "" != num )
|
||||
continue;
|
||||
|
||||
|
||||
if ( IsDefined( ent.model ) )
|
||||
ent.model Hide();
|
||||
|
||||
}
|
||||
}
|
||||
//prof_end( "hide_exploder" );
|
||||
}
|
||||
|
||||
delete_exploder_proc( num )
|
||||
{
|
||||
num += "";
|
||||
|
||||
//prof_begin( "delete_exploder" );
|
||||
if ( IsDefined( level.createFXexploders ) )
|
||||
{ // do optimized flavor if available
|
||||
exploders = level.createFXexploders[ num ];
|
||||
if ( IsDefined( exploders ) )
|
||||
{
|
||||
foreach ( ent in exploders )
|
||||
{
|
||||
if ( IsDefined( ent.model ) )
|
||||
ent.model Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < level.createFXent.size; i++ )
|
||||
{
|
||||
ent = level.createFXent[ i ];
|
||||
if ( !IsDefined( ent ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "type" ] != "exploder" )
|
||||
continue;
|
||||
|
||||
// make the exploder actually removed the array instead?
|
||||
if ( !IsDefined( ent.v[ "exploder" ] ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "exploder" ] + "" != num )
|
||||
continue;
|
||||
|
||||
if ( IsDefined( ent.model ) )
|
||||
ent.model Delete();
|
||||
}
|
||||
}
|
||||
//ends trigger threads.
|
||||
level notify( "killexplodertridgers" + num );
|
||||
|
||||
//prof_end( "delete_exploder" );
|
||||
}
|
||||
|
||||
exploder_damage()
|
||||
{
|
||||
if ( IsDefined( self.v[ "delay" ] ) )
|
||||
delay = self.v[ "delay" ];
|
||||
else
|
||||
delay = 0;
|
||||
|
||||
if ( IsDefined( self.v[ "damage_radius" ] ) )
|
||||
radius = self.v[ "damage_radius" ];
|
||||
else
|
||||
radius = 128;
|
||||
|
||||
damage = self.v[ "damage" ];
|
||||
origin = self.v[ "origin" ];
|
||||
|
||||
wait( delay );
|
||||
|
||||
if ( IsDefined( level.custom_radius_damage_for_exploders ) )
|
||||
[[ level.custom_radius_damage_for_exploders ]]( origin, radius, damage );
|
||||
else
|
||||
// Range, max damage, min damage
|
||||
RadiusDamage( origin, radius, damage, damage );
|
||||
}
|
||||
|
||||
activate_individual_exploder_proc()
|
||||
{
|
||||
if ( IsDefined( self.v[ "firefx" ] ) )
|
||||
self thread fire_effect();
|
||||
|
||||
if ( IsDefined( self.v[ "fxid" ] ) && self.v[ "fxid" ] != "No FX" )
|
||||
self thread cannon_effect();
|
||||
else
|
||||
if ( IsDefined( self.v[ "soundalias" ] ) && self.v[ "soundalias" ] != "nil" )
|
||||
self thread sound_effect();
|
||||
|
||||
if ( IsDefined( self.v[ "loopsound" ] ) && self.v[ "loopsound" ] != "nil" )
|
||||
self thread effect_loopsound();
|
||||
|
||||
if ( IsDefined( self.v[ "damage" ] ) )
|
||||
self thread exploder_damage();
|
||||
|
||||
if ( IsDefined( self.v[ "earthquake" ] ) )
|
||||
self thread exploder_earthquake();
|
||||
|
||||
if ( IsDefined( self.v[ "rumble" ] ) )
|
||||
self thread exploder_rumble();
|
||||
|
||||
if ( self.v[ "exploder_type" ] == "exploder" )
|
||||
self thread brush_show();
|
||||
else
|
||||
if ( ( self.v[ "exploder_type" ] == "exploderchunk" ) || ( self.v[ "exploder_type" ] == "exploderchunk visible" ) )
|
||||
self thread brush_throw();
|
||||
else
|
||||
self thread brush_delete();
|
||||
}
|
||||
|
||||
brush_delete()
|
||||
{
|
||||
// if( ent.v[ "exploder_type" ] != "normal" && !isdefined( ent.v[ "fxid" ] ) && !isdefined( ent.v[ "soundalias" ] ) )
|
||||
// if( !isdefined( ent.script_fxid ) )
|
||||
|
||||
num = self.v[ "exploder" ];
|
||||
if ( IsDefined( self.v[ "delay" ] ) )
|
||||
wait( self.v[ "delay" ] );
|
||||
else
|
||||
wait( 0.05 ); // so it disappears after the replacement appears
|
||||
|
||||
if ( !IsDefined( self.model ) )
|
||||
return;
|
||||
|
||||
|
||||
Assert( IsDefined( self.model ) );
|
||||
|
||||
if ( IsDefined( self.model.classname ) ) // script_struct support - Nate -- self is always a struct so it will never have a classname, using self.model instead -Carlos
|
||||
if ( isSP() && ( self.model.spawnflags & 1 ) )
|
||||
self.model call [[ level.connectPathsFunction ]]();
|
||||
|
||||
if ( level.createFX_enabled )
|
||||
{
|
||||
if ( IsDefined( self.exploded ) )
|
||||
return;
|
||||
|
||||
self.exploded = true;
|
||||
self.model Hide();
|
||||
self.model NotSolid();
|
||||
|
||||
wait( 3 );
|
||||
self.exploded = undefined;
|
||||
self.model Show();
|
||||
self.model Solid();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !IsDefined( self.v[ "fxid" ] ) || self.v[ "fxid" ] == "No FX" )
|
||||
self.v[ "exploder" ] = undefined;
|
||||
|
||||
waittillframeend;// so it hides stuff after it shows the new stuff
|
||||
|
||||
// if ( IsDefined( self.classname ) ) // script_struct support nate --- self is always a struct so it will never have a classname, using self.model instead -Carlos
|
||||
if ( IsDefined( self.model ) && IsDefined( self.model.classname ) )
|
||||
{
|
||||
self.model Delete();
|
||||
}
|
||||
}
|
||||
|
||||
brush_throw()
|
||||
{
|
||||
if ( IsDefined( self.v[ "delay" ] ) )
|
||||
wait( self.v[ "delay" ] );
|
||||
|
||||
ent = undefined;
|
||||
if ( IsDefined( self.v[ "target" ] ) )
|
||||
ent = get_target_ent( self.v[ "target" ] );
|
||||
|
||||
if ( !IsDefined( ent ) )
|
||||
{
|
||||
self.model Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
self.model Show();
|
||||
|
||||
if ( IsDefined( self.v[ "delay_post" ] ) )
|
||||
wait( self.v[ "delay_post" ] );
|
||||
|
||||
startorg = self.v[ "origin" ];
|
||||
startang = self.v[ "angles" ];
|
||||
org = ent.origin;
|
||||
|
||||
temp_vec = ( org - self.v[ "origin" ] );
|
||||
x = temp_vec[ 0 ];
|
||||
y = temp_vec[ 1 ];
|
||||
z = temp_vec[ 2 ];
|
||||
|
||||
physics = IsDefined( self.v[ "physics" ] );
|
||||
if ( physics )
|
||||
{
|
||||
target = undefined;
|
||||
if ( IsDefined( ent.target ) )
|
||||
target = ent get_target_ent();
|
||||
|
||||
if ( !IsDefined( target ) )
|
||||
{
|
||||
contact_point = startorg; // no spin just push it.
|
||||
throw_vec = ent.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
contact_point = ent.origin;
|
||||
throw_vec = ( ( target.origin - ent.origin ) * self.v[ "physics" ] );
|
||||
|
||||
}
|
||||
self.model PhysicsLaunchClient( contact_point, throw_vec );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.model RotateVelocity( ( x, y, z ), 12 );
|
||||
self.model MoveGravity( ( x, y, z ), 12 );
|
||||
}
|
||||
|
||||
if ( level.createFX_enabled )
|
||||
{
|
||||
if ( IsDefined( self.exploded ) )
|
||||
return;
|
||||
|
||||
self.exploded = true;
|
||||
wait( 3 );
|
||||
self.exploded = undefined;
|
||||
self.v[ "origin" ] = startorg;
|
||||
self.v[ "angles" ] = startang;
|
||||
self.model Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
self.v[ "exploder" ] = undefined;
|
||||
wait( 6 );
|
||||
self.model Delete();
|
||||
}
|
||||
|
||||
brush_show()
|
||||
{
|
||||
if ( IsDefined( self.v[ "delay" ] ) )
|
||||
wait( self.v[ "delay" ] );
|
||||
|
||||
Assert( IsDefined( self.model ) );
|
||||
|
||||
if ( !IsDefined( self.model.script_modelname ) )
|
||||
{
|
||||
self.model Show();
|
||||
self.model Solid();
|
||||
}
|
||||
else // script_structs don't pass in their .model value SO use script_modelname on them saves an entity.
|
||||
{
|
||||
model = self.model spawn_tag_origin();
|
||||
if ( IsDefined( self.model.script_linkname ) )
|
||||
model.script_linkname = self.model.script_linkname;
|
||||
model SetModel( self.model.script_modelname );
|
||||
model Show();
|
||||
}
|
||||
|
||||
self.brush_shown = true; // used for hiding an exploder.
|
||||
|
||||
if ( isSP() && !IsDefined( self.model.script_modelname ) && ( self.model.spawnflags & 1 ) )
|
||||
{
|
||||
if ( !IsDefined( self.model.disconnect_paths ) )
|
||||
self.model call [[ level.connectPathsFunction ]]();
|
||||
else
|
||||
self.model call [[ level.disconnectPathsFunction ]]();
|
||||
}
|
||||
|
||||
if ( level.createFX_enabled )
|
||||
{
|
||||
if ( IsDefined( self.exploded ) )
|
||||
return;
|
||||
|
||||
self.exploded = true;
|
||||
wait( 3 );
|
||||
self.exploded = undefined;
|
||||
|
||||
if ( !IsDefined( self.model.script_modelname ) )
|
||||
{
|
||||
self.model Hide();
|
||||
self.model NotSolid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exploder_rumble()
|
||||
{
|
||||
if ( !isSP() )
|
||||
return;
|
||||
|
||||
self exploder_delay();
|
||||
level.player PlayRumbleOnEntity( self.v[ "rumble" ] );
|
||||
}
|
||||
|
||||
exploder_delay()
|
||||
{
|
||||
if ( !IsDefined( self.v[ "delay" ] ) )
|
||||
self.v[ "delay" ] = 0;
|
||||
|
||||
min_delay = self.v[ "delay" ];
|
||||
max_delay = self.v[ "delay" ] + 0.001; // cant randomfloatrange on the same #
|
||||
if ( IsDefined( self.v[ "delay_min" ] ) )
|
||||
min_delay = self.v[ "delay_min" ];
|
||||
|
||||
if ( IsDefined( self.v[ "delay_max" ] ) )
|
||||
max_delay = self.v[ "delay_max" ];
|
||||
|
||||
if ( min_delay > 0 )
|
||||
wait( RandomFloatRange( min_delay, max_delay ) );
|
||||
}
|
||||
|
||||
effect_loopsound()
|
||||
{
|
||||
if ( IsDefined( self.loopsound_ent ) )
|
||||
{
|
||||
self.loopsound_ent Delete();
|
||||
}
|
||||
// save off this info in case we delete the effect
|
||||
origin = self.v[ "origin" ];
|
||||
alias = self.v[ "loopsound" ];
|
||||
self exploder_delay();
|
||||
|
||||
self.loopsound_ent = play_loopsound_in_space( alias, origin );
|
||||
}
|
||||
|
||||
sound_effect()
|
||||
{
|
||||
self effect_soundalias();
|
||||
}
|
||||
|
||||
effect_soundalias()
|
||||
{
|
||||
// save off this info in case we delete the effect
|
||||
origin = self.v[ "origin" ];
|
||||
alias = self.v[ "soundalias" ];
|
||||
self exploder_delay();
|
||||
play_sound_in_space( alias, origin );
|
||||
}
|
||||
|
||||
exploder_earthquake()
|
||||
{
|
||||
self exploder_delay();
|
||||
do_earthquake( self.v[ "earthquake" ], self.v[ "origin" ] );
|
||||
}
|
||||
|
||||
exploder_playSound()
|
||||
{
|
||||
if ( !IsDefined( self.v[ "soundalias" ] ) || self.v[ "soundalias" ] == "nil" )
|
||||
return;
|
||||
|
||||
play_sound_in_space( self.v[ "soundalias" ], self.v[ "origin" ] );
|
||||
}
|
||||
|
||||
fire_effect()
|
||||
{
|
||||
forward = self.v[ "forward" ];
|
||||
up = self.v[ "up" ];
|
||||
|
||||
org = undefined;
|
||||
|
||||
firefxSound = self.v[ "firefxsound" ];
|
||||
origin = self.v[ "origin" ];
|
||||
firefx = self.v[ "firefx" ];
|
||||
ender = self.v[ "ender" ];
|
||||
if ( !IsDefined( ender ) )
|
||||
ender = "createfx_effectStopper";
|
||||
|
||||
fireFxDelay = 0.5;
|
||||
if ( IsDefined( self.v[ "firefxdelay" ] ) )
|
||||
fireFxDelay = self.v[ "firefxdelay" ];
|
||||
|
||||
self exploder_delay();
|
||||
|
||||
if ( IsDefined( firefxSound ) )
|
||||
loop_fx_sound( firefxSound, origin, 1, ender );
|
||||
|
||||
PlayFX( level._effect[ firefx ], self.v[ "origin" ], forward, up );
|
||||
}
|
||||
|
||||
cannon_effect()
|
||||
{
|
||||
if ( IsDefined( self.v[ "repeat" ] ) )
|
||||
{
|
||||
thread exploder_playSound();
|
||||
for ( i = 0; i < self.v[ "repeat" ]; i++ )
|
||||
{
|
||||
PlayFX( level._effect[ self.v[ "fxid" ] ], self.v[ "origin" ], self.v[ "forward" ], self.v[ "up" ] );
|
||||
self exploder_delay();
|
||||
}
|
||||
return;
|
||||
}
|
||||
self exploder_delay();
|
||||
|
||||
if ( IsDefined( self.looper ) )
|
||||
self.looper Delete();
|
||||
|
||||
self.looper = SpawnFx( getfx( self.v[ "fxid" ] ), self.v[ "origin" ], self.v[ "forward" ], self.v[ "up" ] );
|
||||
TriggerFX( self.looper );
|
||||
exploder_playSound();
|
||||
}
|
||||
|
||||
activate_exploder( num, players, startTime )
|
||||
{
|
||||
num += "";
|
||||
//prof_begin( "activate_exploder" );
|
||||
|
||||
//here's a hook so you can know when a certain number of an exploder is going off
|
||||
level notify( "exploding_" + num );
|
||||
|
||||
found_server_exploder = false;
|
||||
|
||||
if ( IsDefined( level.createFXexploders ) && !level.createFX_enabled )
|
||||
{ // do optimized form if available
|
||||
exploders = level.createFXexploders[ num ];
|
||||
if ( IsDefined( exploders ) )
|
||||
{
|
||||
foreach ( ent in exploders )
|
||||
{
|
||||
ent activate_individual_exploder();
|
||||
found_server_exploder = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0;i < level.createFXent.size;i++ )
|
||||
{
|
||||
ent = level.createFXent[ i ];
|
||||
if ( !IsDefined( ent ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "type" ] != "exploder" )
|
||||
continue;
|
||||
|
||||
// make the exploder actually removed the array instead?
|
||||
if ( !IsDefined( ent.v[ "exploder" ] ) )
|
||||
continue;
|
||||
|
||||
if ( ent.v[ "exploder" ] + "" != num )
|
||||
continue;
|
||||
|
||||
ent activate_individual_exploder();
|
||||
found_server_exploder = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !shouldRunServerSideEffects() && !found_server_exploder )
|
||||
activate_clientside_exploder( num, players, startTime );
|
||||
|
||||
//prof_end( "activate_exploder" );
|
||||
}
|
||||
|
||||
activate_clientside_exploder( exploderName, players, startTime )
|
||||
{
|
||||
if ( !is_valid_clientside_exploder_name( exploderName ) )
|
||||
{
|
||||
PrintLn( "^1ERROR: Exploder Index '" + exploderName + "' is not a valid exploder index >= 0" );
|
||||
return;
|
||||
}
|
||||
|
||||
exploder_num = Int( exploderName );
|
||||
ActivateClientExploder( exploder_num, players, startTime );
|
||||
}
|
||||
|
||||
is_valid_clientside_exploder_name( exploderName )
|
||||
{
|
||||
if ( !IsDefined( exploderName ) )
|
||||
return false;
|
||||
|
||||
exploder_num = exploderName;
|
||||
if ( IsString( exploderName ) )
|
||||
{
|
||||
exploder_num = Int( exploderName );
|
||||
if ( exploder_num == 0 && exploderName != "0" )
|
||||
return false;
|
||||
}
|
||||
|
||||
return exploder_num >= 0;
|
||||
}
|
||||
|
||||
shouldRunServerSideEffects()
|
||||
{
|
||||
if ( isSP() )
|
||||
return true;
|
||||
|
||||
if ( !IsDefined( level.createFX_enabled ) )
|
||||
level.createFX_enabled = ( GetDvar( "createfx" ) != "" );
|
||||
|
||||
if ( level.createFX_enabled )
|
||||
return true;
|
||||
else
|
||||
return GetDvar( "clientSideEffects" ) != "1";
|
||||
}
|
||||
|
||||
exploder_before_load( num, players, startTime )
|
||||
{
|
||||
// gotta wait twice because the createfx_init function waits once then inits all exploders. This guarentees
|
||||
// that if an exploder is run on the first frame, it happens after the fx are init.
|
||||
waittillframeend;
|
||||
waittillframeend;
|
||||
activate_exploder( num, players, startTime );
|
||||
}
|
||||
|
||||
exploder_after_load( num, players, startTime )
|
||||
{
|
||||
activate_exploder( num, players, startTime );
|
||||
}
|
||||
@@ -0,0 +1,871 @@
|
||||
#include common_scripts\utility;
|
||||
#include common_scripts\_createfx;
|
||||
|
||||
CONST_MAX_SP_CREATEFX = 1500;
|
||||
CONST_MAX_SP_CREATESOUND = 384;
|
||||
initFX()
|
||||
{
|
||||
if ( !isdefined( level.func ) )
|
||||
level.func = [];
|
||||
|
||||
if ( !isdefined( level.func[ "create_triggerfx" ] ) )
|
||||
level.func[ "create_triggerfx" ] = ::create_triggerfx;
|
||||
|
||||
if ( !IsDefined( level._fx ) )
|
||||
level._fx = SpawnStruct();
|
||||
|
||||
create_lock( "createfx_looper", 20 );
|
||||
level.fxfireloopmod = 1;
|
||||
|
||||
// wrapper for the exploder function so we dont have to use flags and do ifs/waittills on every exploder call
|
||||
level._fx.exploderFunction = common_scripts\_exploder::exploder_before_load;
|
||||
waittillframeend;// Wait one frame so the effects get setup by the maps fx thread
|
||||
waittillframeend;// Wait another frame so effects can be loaded based on start functions. Without this FX are initialiazed before they are defined by start functions.
|
||||
level._fx.exploderFunction = common_scripts\_exploder::exploder_after_load;
|
||||
|
||||
level._fx.server_culled_sounds = false;
|
||||
if ( GetDvarInt( "serverCulledSounds" ) == 1 )
|
||||
level._fx.server_culled_sounds = true;
|
||||
|
||||
if ( level.createFX_enabled )
|
||||
level._fx.server_culled_sounds = false;
|
||||
|
||||
/#
|
||||
SetDevDvarIfUninitialized( "scr_map_exploder_dump", 0 );
|
||||
SetDevDvarIfUninitialized( "createfx_removedupes", 0 );
|
||||
|
||||
if ( GetDvarInt( "r_reflectionProbeGenerate" ) == 1 )
|
||||
level._fx.server_culled_sounds = true;
|
||||
#/
|
||||
|
||||
// Give createfx_common time to delete triggers to free up entity slots.
|
||||
if ( level.createFX_enabled )
|
||||
{
|
||||
level waittill( "createfx_common_done" );
|
||||
}
|
||||
|
||||
/#
|
||||
remove_dupes();
|
||||
#/
|
||||
|
||||
for ( i = 0; i < level.createFXent.size; i++ )
|
||||
{
|
||||
ent = level.createFXent[ i ];
|
||||
ent set_forward_and_up_vectors();
|
||||
|
||||
switch ( ent.v[ "type" ] )
|
||||
{
|
||||
case "loopfx":
|
||||
ent thread loopfxthread();
|
||||
break;
|
||||
case "oneshotfx":
|
||||
ent thread oneshotfxthread();
|
||||
break;
|
||||
case "soundfx":
|
||||
ent thread create_loopsound();
|
||||
break;
|
||||
case "soundfx_interval":
|
||||
ent thread create_interval_sound();
|
||||
break;
|
||||
case "reactive_fx":
|
||||
ent add_reactive_fx();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
check_createfx_limit();
|
||||
}
|
||||
|
||||
remove_dupes()
|
||||
{
|
||||
/#
|
||||
if ( GetDvarInt( "createfx_removedupes" ) == 0 )
|
||||
return;
|
||||
|
||||
new_ents = [];
|
||||
for ( i = 0; i < level.createFXent.size; i++ )
|
||||
{
|
||||
add_ent = true;
|
||||
i_ent = level.createFXent[ i ];
|
||||
for ( j = i + 1; j < level.createFXent.size; j++ )
|
||||
{
|
||||
j_ent = level.createFXent[ j ];
|
||||
|
||||
if ( j_ent.v[ "type" ] == i_ent.v[ "type" ] )
|
||||
{
|
||||
if ( j_ent.v[ "origin" ] == i_ent.v[ "origin" ] )
|
||||
{
|
||||
println( "^3--REMOVING DUPE'D " + j_ent.v[ "type" ] + " AT " + j_ent.v[ "origin" ] );
|
||||
add_ent = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( add_ent )
|
||||
new_ents[ new_ents.size ] = i_ent;
|
||||
}
|
||||
|
||||
level.createFXent = new_ents;
|
||||
#/
|
||||
}
|
||||
|
||||
check_createfx_limit()
|
||||
{
|
||||
/#
|
||||
if ( !isSP() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fx_count = 0;
|
||||
sound_count = 0;
|
||||
foreach ( ent in level.createFXent )
|
||||
{
|
||||
if ( is_createfx_type( ent, "fx" ) )
|
||||
fx_count++;
|
||||
else if ( is_createfx_type( ent, "sound" ) )
|
||||
sound_count++;
|
||||
}
|
||||
|
||||
println( "^5Total CreateFX FX Ents: " + fx_count );
|
||||
println( "^5Total CreateFX SOUND Ents: " + sound_count );
|
||||
|
||||
check_limit_type( "fx", fx_count );
|
||||
check_limit_type( "sound", sound_count );
|
||||
#/
|
||||
}
|
||||
|
||||
check_limit_type( type, count )
|
||||
{
|
||||
/#
|
||||
limit = undefined;
|
||||
if ( type == "fx" )
|
||||
{
|
||||
limit = CONST_MAX_SP_CREATEFX;
|
||||
}
|
||||
else if ( type == "sound" )
|
||||
{
|
||||
limit = CONST_MAX_SP_CREATESOUND;
|
||||
}
|
||||
|
||||
if ( count > limit )
|
||||
AssertMsg( "CREATEFX: You have too many " + type + " createFX ents. You need to reduce the amount.\nYou have " + count + " and the limit is " + limit );
|
||||
#/
|
||||
}
|
||||
|
||||
|
||||
print_org( fxcommand, fxId, fxPos, waittime )
|
||||
{
|
||||
if ( GetDvar( "debug" ) == "1" )
|
||||
{
|
||||
println( "{" );
|
||||
println( "\"origin\" \"" + fxPos[ 0 ] + " " + fxPos[ 1 ] + " " + fxPos[ 2 ] + "\"" );
|
||||
println( "\"classname\" \"script_model\"" );
|
||||
println( "\"model\" \"fx\"" );
|
||||
println( "\"script_fxcommand\" \"" + fxcommand + "\"" );
|
||||
println( "\"script_fxid\" \"" + fxId + "\"" );
|
||||
println( "\"script_delay\" \"" + waittime + "\"" );
|
||||
println( "}" );
|
||||
}
|
||||
}
|
||||
|
||||
OneShotfx( fxId, fxPos, waittime, fxPos2 )
|
||||
{
|
||||
// level thread print_org ("OneShotfx", fxId, fxPos, waittime);
|
||||
// level thread OneShotfxthread (fxId, fxPos, waittime, fxPos2);
|
||||
}
|
||||
|
||||
exploderfx( num, fxId, fxPos, waittime, fxPos2, fireFx, fireFxDelay, fireFxSound, fxSound, fxQuake, fxDamage, soundalias, repeat, delay_min, delay_max, damage_radius, fireFxTimeout, exploder_group )
|
||||
{
|
||||
if ( 1 )
|
||||
{
|
||||
ent = createExploder( fxId );
|
||||
ent.v[ "origin" ] = fxPos;
|
||||
ent.v[ "angles" ] = ( 0, 0, 0 );
|
||||
if ( isdefined( fxPos2 ) )
|
||||
ent.v[ "angles" ] = vectortoangles( fxPos2 - fxPos );
|
||||
ent.v[ "delay" ] = waittime;
|
||||
ent.v[ "exploder" ] = num;
|
||||
if (isdefined(level.createFXexploders))
|
||||
{ // if we're using the optimized lookup, add it in the proper place
|
||||
ary = level.createFXexploders[ ent.v[ "exploder" ] ];
|
||||
if (!isdefined(ary))
|
||||
ary = [];
|
||||
ary[ary.size] = ent;
|
||||
level.createFXexploders[ ent.v[ "exploder" ] ] = ary;
|
||||
}
|
||||
// deprecated
|
||||
return;
|
||||
}
|
||||
fx = spawn( "script_origin", ( 0, 0, 0 ) );
|
||||
// println ("total ", getentarray ("script_origin","classname").size);
|
||||
fx.origin = fxPos;
|
||||
fx.angles = vectortoangles( fxPos2 - fxPos );
|
||||
// fx.targetname = "exploder";
|
||||
fx.script_exploder = num;
|
||||
fx.script_fxid = fxId;
|
||||
fx.script_delay = waittime;
|
||||
|
||||
fx.script_firefx = fireFx;
|
||||
fx.script_firefxdelay = ( fireFxDelay );// for awhile the script exported strings for this value so we cast it to float
|
||||
fx.script_firefxsound = fireFxSound;
|
||||
|
||||
fx.script_sound = fxSound;
|
||||
fx.script_earthquake = fxQuake;
|
||||
fx.script_damage = ( fxDamage );
|
||||
fx.script_radius = ( damage_radius );
|
||||
fx.script_soundalias = soundalias;
|
||||
fx.script_firefxtimeout = ( fireFxTimeout );
|
||||
fx.script_repeat = ( repeat );
|
||||
fx.script_delay_min = ( delay_min );
|
||||
fx.script_delay_max = ( delay_max );
|
||||
fx.script_exploder_group = exploder_group;
|
||||
|
||||
forward = anglestoforward( fx.angles );
|
||||
forward *= ( 150 );
|
||||
fx.targetPos = fxPos + forward;
|
||||
|
||||
if ( !isdefined( level._script_exploders ) )
|
||||
level._script_exploders = [];
|
||||
level._script_exploders[ level._script_exploders.size ] = fx;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
loopfxRotate(fxId, fxPos, waittime, angle, fxStart, fxStop, timeout)
|
||||
{
|
||||
level thread print_org ("loopfx", fxId, fxPos, waittime);
|
||||
level thread loopfxthread (fxId, fxPos, waittime, fxPos2, fxStart, fxStop, timeout);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
loopfx( fxId, fxPos, waittime, fxPos2, fxStart, fxStop, timeout )
|
||||
{
|
||||
println( "Loopfx is deprecated!" );
|
||||
ent = createLoopEffect( fxId );
|
||||
ent.v[ "origin" ] = fxPos;
|
||||
ent.v[ "angles" ] = ( 0, 0, 0 );
|
||||
if ( isdefined( fxPos2 ) )
|
||||
ent.v[ "angles" ] = vectortoangles( fxPos2 - fxPos );
|
||||
ent.v[ "delay" ] = waittime;
|
||||
}
|
||||
|
||||
/*
|
||||
loopfx(fxId, fxPos, waittime, fxPos2, fxStart, fxStop, timeout)
|
||||
{
|
||||
level thread print_org ("loopfx", fxId, fxPos, waittime);
|
||||
level thread loopfxthread (fxId, fxPos, waittime, fxPos2, fxStart, fxStop, timeout);
|
||||
}
|
||||
*/
|
||||
|
||||
create_looper()
|
||||
{
|
||||
//assert (isdefined(self.looper));
|
||||
self.looper = playLoopedFx( level._effect[ self.v[ "fxid" ] ], self.v[ "delay" ], self.v[ "origin" ], 0, self.v[ "forward" ], self.v[ "up" ] );
|
||||
create_loopsound();
|
||||
}
|
||||
|
||||
create_loopsound()
|
||||
{
|
||||
self notify( "stop_loop" );
|
||||
|
||||
if ( !IsDefined( self.v[ "soundalias" ] ) )
|
||||
return;
|
||||
|
||||
if ( self.v[ "soundalias" ] == "nil" )
|
||||
return;
|
||||
|
||||
/#
|
||||
if ( GetDvar( "r_reflectionProbeGenerate" ) == "1" )
|
||||
return;
|
||||
#/
|
||||
|
||||
culled = false;
|
||||
end_on = undefined;
|
||||
if ( isdefined( self.v[ "stopable" ] ) && self.v[ "stopable" ] )
|
||||
{
|
||||
if ( IsDefined( self.looper ) )
|
||||
end_on = "death";
|
||||
else
|
||||
end_on = "stop_loop";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level._fx.server_culled_sounds && IsDefined( self.v[ "server_culled" ] ) )
|
||||
culled = self.v[ "server_culled" ];
|
||||
}
|
||||
|
||||
ent = self;
|
||||
if ( IsDefined( self.looper ) )
|
||||
ent = self.looper;
|
||||
|
||||
createfx_ent = undefined;
|
||||
if ( level.createFX_enabled )
|
||||
createfx_ent = self;
|
||||
|
||||
ent loop_fx_sound_with_angles( self.v[ "soundalias" ], self.v[ "origin" ], self.v[ "angles" ], culled, end_on, createfx_ent );
|
||||
}
|
||||
|
||||
create_interval_sound()
|
||||
{
|
||||
self notify( "stop_loop" );
|
||||
|
||||
if ( !IsDefined( self.v[ "soundalias" ] ) )
|
||||
return;
|
||||
if ( self.v[ "soundalias" ] == "nil" )
|
||||
return;
|
||||
|
||||
ender = undefined;
|
||||
runner = self;
|
||||
|
||||
/#
|
||||
if ( GetDvar( "r_reflectionProbeGenerate" ) == "1" )
|
||||
return;
|
||||
#/
|
||||
|
||||
|
||||
if( ( IsDefined( self.v[ "stopable" ] ) && self.v[ "stopable" ] ) || level.createFX_enabled )
|
||||
{
|
||||
if ( IsDefined( self.looper ) )
|
||||
{
|
||||
runner = self.looper;
|
||||
ender = "death";
|
||||
}
|
||||
else
|
||||
ender = "stop_loop";
|
||||
|
||||
}
|
||||
|
||||
runner thread loop_fx_sound_interval_with_angles( self.v[ "soundalias" ], self.v[ "origin" ], self.v[ "angles" ], ender, undefined, self.v[ "delay_min" ], self.v[ "delay_max" ] );
|
||||
}
|
||||
|
||||
loopfxthread()
|
||||
{
|
||||
waitframe();
|
||||
// println ( "fx testing running Id: ", fxId );
|
||||
// if ((isdefined (level.scr_sound)) && (isdefined (level.scr_sound[fxId])))
|
||||
// loopSound(level.scr_sound[fxId], fxPos);
|
||||
|
||||
if ( isdefined( self.fxStart ) )
|
||||
level waittill( "start fx" + self.fxStart );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
/*
|
||||
if (isdefined (ent.org2))
|
||||
{
|
||||
fxAngle = vectorNormalize (ent.org2 - ent.org);
|
||||
looper = playLoopedFx( level._effect[fxId], ent.delay, ent.org, 0, fxAngle );
|
||||
}
|
||||
else
|
||||
looper = playLoopedFx( level._effect[fxId], ent.delay, ent.org, 0 );
|
||||
*/
|
||||
create_looper();
|
||||
|
||||
if ( isdefined( self.timeout ) )
|
||||
thread loopfxStop( self.timeout );
|
||||
|
||||
if ( isdefined( self.fxStop ) )
|
||||
level waittill( "stop fx" + self.fxStop );
|
||||
else
|
||||
return;
|
||||
|
||||
if ( isdefined( self.looper ) )
|
||||
self.looper delete();
|
||||
|
||||
if ( isdefined( self.fxStart ) )
|
||||
level waittill( "start fx" + self.fxStart );
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
loopfxChangeID( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
ent waittill( "effect id changed", change );
|
||||
}
|
||||
|
||||
loopfxChangeOrg( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
for ( ;; )
|
||||
{
|
||||
ent waittill( "effect org changed", change );
|
||||
self.origin = change;
|
||||
}
|
||||
}
|
||||
|
||||
loopfxChangeDelay( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
ent waittill( "effect delay changed", change );
|
||||
}
|
||||
|
||||
loopfxDeletion( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
ent waittill( "effect deleted" );
|
||||
self delete();
|
||||
}
|
||||
|
||||
loopfxStop( timeout )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait( timeout );
|
||||
self.looper delete();
|
||||
}
|
||||
|
||||
loopSound( sound, Pos, waittime )
|
||||
{
|
||||
// level thread print_org ("loopSound", sound, Pos, waittime);
|
||||
level thread loopSoundthread( sound, Pos, waittime );
|
||||
}
|
||||
|
||||
loopSoundthread( sound, pos, waittime )
|
||||
{
|
||||
org = spawn( "script_origin", ( pos ) );
|
||||
|
||||
org.origin = pos;
|
||||
// println ("hello1 ", org.origin, sound);
|
||||
org playLoopSound( sound );
|
||||
}
|
||||
|
||||
gunfireloopfx( fxId, fxPos, shotsMin, shotsMax, shotdelayMin, shotdelayMax, betweenSetsMin, betweenSetsMax )
|
||||
{
|
||||
thread gunfireloopfxthread( fxId, fxPos, shotsMin, shotsMax, shotdelayMin, shotdelayMax, betweenSetsMin, betweenSetsMax );
|
||||
}
|
||||
|
||||
gunfireloopfxthread( fxId, fxPos, shotsMin, shotsMax, shotdelayMin, shotdelayMax, betweenSetsMin, betweenSetsMax )
|
||||
{
|
||||
level endon( "stop all gunfireloopfx" );
|
||||
waitframe();
|
||||
|
||||
if ( betweenSetsMax < betweenSetsMin )
|
||||
{
|
||||
temp = betweenSetsMax;
|
||||
betweenSetsMax = betweenSetsMin;
|
||||
betweenSetsMin = temp;
|
||||
}
|
||||
|
||||
betweenSetsBase = betweenSetsMin;
|
||||
betweenSetsRange = betweenSetsMax - betweenSetsMin;
|
||||
|
||||
if ( shotdelayMax < shotdelayMin )
|
||||
{
|
||||
temp = shotdelayMax;
|
||||
shotdelayMax = shotdelayMin;
|
||||
shotdelayMin = temp;
|
||||
}
|
||||
|
||||
shotdelayBase = shotdelayMin;
|
||||
shotdelayRange = shotdelayMax - shotdelayMin;
|
||||
|
||||
if ( shotsMax < shotsMin )
|
||||
{
|
||||
temp = shotsMax;
|
||||
shotsMax = shotsMin;
|
||||
shotsMin = temp;
|
||||
}
|
||||
|
||||
shotsBase = shotsMin;
|
||||
shotsRange = shotsMax - shotsMin;
|
||||
|
||||
fxEnt = spawnFx( level._effect[ fxId ], fxPos );
|
||||
|
||||
if ( !level.createFX_enabled )
|
||||
fxEnt willNeverChange();
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
shotnum = shotsBase + randomint( shotsRange );
|
||||
for ( i = 0;i < shotnum;i++ )
|
||||
{
|
||||
triggerFx( fxEnt );
|
||||
|
||||
wait( shotdelayBase + randomfloat( shotdelayRange ) );
|
||||
}
|
||||
wait( betweenSetsBase + randomfloat( betweenSetsRange ) );
|
||||
}
|
||||
}
|
||||
|
||||
gunfireloopfxVec( fxId, fxPos, fxPos2, shotsMin, shotsMax, shotdelayMin, shotdelayMax, betweenSetsMin, betweenSetsMax )
|
||||
{
|
||||
thread gunfireloopfxVecthread( fxId, fxPos, fxPos2, shotsMin, shotsMax, shotdelayMin, shotdelayMax, betweenSetsMin, betweenSetsMax );
|
||||
}
|
||||
|
||||
gunfireloopfxVecthread( fxId, fxPos, fxPos2, shotsMin, shotsMax, shotdelayMin, shotdelayMax, betweenSetsMin, betweenSetsMax )
|
||||
{
|
||||
level endon( "stop all gunfireloopfx" );
|
||||
waitframe();
|
||||
|
||||
if ( betweenSetsMax < betweenSetsMin )
|
||||
{
|
||||
temp = betweenSetsMax;
|
||||
betweenSetsMax = betweenSetsMin;
|
||||
betweenSetsMin = temp;
|
||||
}
|
||||
|
||||
betweenSetsBase = betweenSetsMin;
|
||||
betweenSetsRange = betweenSetsMax - betweenSetsMin;
|
||||
|
||||
if ( shotdelayMax < shotdelayMin )
|
||||
{
|
||||
temp = shotdelayMax;
|
||||
shotdelayMax = shotdelayMin;
|
||||
shotdelayMin = temp;
|
||||
}
|
||||
|
||||
shotdelayBase = shotdelayMin;
|
||||
shotdelayRange = shotdelayMax - shotdelayMin;
|
||||
|
||||
if ( shotsMax < shotsMin )
|
||||
{
|
||||
temp = shotsMax;
|
||||
shotsMax = shotsMin;
|
||||
shotsMin = temp;
|
||||
}
|
||||
|
||||
shotsBase = shotsMin;
|
||||
shotsRange = shotsMax - shotsMin;
|
||||
|
||||
fxPos2 = vectornormalize( fxPos2 - fxPos );
|
||||
|
||||
fxEnt = spawnFx( level._effect[ fxId ], fxPos, fxPos2 );
|
||||
|
||||
if ( !level.createFX_enabled )
|
||||
fxEnt willNeverChange();
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
shotnum = shotsBase + randomint( shotsRange );
|
||||
for ( i = 0;i < int( shotnum / level.fxfireloopmod );i++ )
|
||||
{
|
||||
triggerFx( fxEnt );
|
||||
delay = ( ( shotdelayBase + randomfloat( shotdelayRange ) ) * level.fxfireloopmod );
|
||||
if ( delay < .05 )
|
||||
delay = .05;
|
||||
wait delay;
|
||||
}
|
||||
wait( shotdelayBase + randomfloat( shotdelayRange ) );
|
||||
wait( betweenSetsBase + randomfloat( betweenSetsRange ) );
|
||||
}
|
||||
}
|
||||
|
||||
setfireloopmod( value )
|
||||
{
|
||||
level.fxfireloopmod = 1 / value;
|
||||
}
|
||||
|
||||
setup_fx()
|
||||
{
|
||||
if ( ( !isdefined( self.script_fxid ) ) || ( !isdefined( self.script_fxcommand ) ) || ( !isdefined( self.script_delay ) ) )
|
||||
{
|
||||
// println (self.script_fxid);
|
||||
// println (self.script_fxcommand);
|
||||
// println (self.script_delay);
|
||||
// println ("Effect at origin ", self.origin," doesn't have script_fxid/script_fxcommand/script_delay");
|
||||
// self delete();
|
||||
return;
|
||||
}
|
||||
|
||||
// println ("^a Command:", self.script_fxcommand, " Effect:", self.script_fxID, " Delay:", self.script_delay, " ", self.origin);
|
||||
if ( isdefined( self.model ) )
|
||||
if ( self.model == "toilet" )
|
||||
{
|
||||
self thread burnville_paratrooper_hack();
|
||||
return;
|
||||
}
|
||||
|
||||
org = undefined;
|
||||
if ( isdefined( self.target ) )
|
||||
{
|
||||
ent = getent( self.target, "targetname" );
|
||||
if ( isdefined( ent ) )
|
||||
org = ent.origin;
|
||||
}
|
||||
|
||||
fxStart = undefined;
|
||||
if ( isdefined( self.script_fxstart ) )
|
||||
fxStart = self.script_fxstart;
|
||||
|
||||
fxStop = undefined;
|
||||
if ( isdefined( self.script_fxstop ) )
|
||||
fxStop = self.script_fxstop;
|
||||
|
||||
if ( self.script_fxcommand == "OneShotfx" )
|
||||
OneShotfx( self.script_fxId, self.origin, self.script_delay, org );
|
||||
if ( self.script_fxcommand == "loopfx" )
|
||||
loopfx( self.script_fxId, self.origin, self.script_delay, org, fxStart, fxStop );
|
||||
if ( self.script_fxcommand == "loopsound" )
|
||||
loopsound( self.script_fxId, self.origin, self.script_delay );
|
||||
|
||||
self delete();
|
||||
}
|
||||
|
||||
burnville_paratrooper_hack()
|
||||
{
|
||||
normal = ( 0, 0, self.angles[ 1 ] );
|
||||
// println ("z: paratrooper fx hack: ", normal);
|
||||
id = level._effect[ self.script_fxId ];
|
||||
origin = self.origin;
|
||||
|
||||
// if (isdefined (self.script_delay))
|
||||
// wait (self.script_delay);
|
||||
|
||||
wait 1;
|
||||
level thread burnville_paratrooper_hack_loop( normal, origin, id );
|
||||
self delete();
|
||||
}
|
||||
|
||||
burnville_paratrooper_hack_loop( normal, origin, id )
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
// iprintln ("z: playing paratrooper fx", origin);
|
||||
|
||||
playfx( id, origin );
|
||||
wait( 30 + randomfloat( 40 ) );
|
||||
}
|
||||
}
|
||||
|
||||
create_triggerfx()
|
||||
{
|
||||
//assert (isdefined(self.looper));
|
||||
if( ! verify_effects_assignment( self.v[ "fxid" ] ) )
|
||||
return;
|
||||
|
||||
self.looper = spawnFx( level._effect[ self.v[ "fxid" ] ], self.v[ "origin" ], self.v[ "forward" ], self.v[ "up" ] );
|
||||
triggerFx( self.looper, self.v[ "delay" ] );
|
||||
|
||||
if ( !level.createFX_enabled )
|
||||
self.looper willNeverChange();
|
||||
|
||||
create_loopsound();
|
||||
}
|
||||
|
||||
verify_effects_assignment( effectID )
|
||||
{
|
||||
if( isdefined ( level._effect[ effectID ] ) )
|
||||
return true;
|
||||
if( ! isdefined( level._missing_FX ) )
|
||||
level._missing_FX = [];
|
||||
level._missing_FX[ self.v[ "fxid" ] ] = effectID;
|
||||
verify_effects_assignment_print( effectID );
|
||||
return false;
|
||||
}
|
||||
|
||||
verify_effects_assignment_print( effectID )
|
||||
{
|
||||
|
||||
level notify ( "verify_effects_assignment_print" );
|
||||
level endon ( "verify_effects_assignment_print" );
|
||||
wait .05; //allow errors on the same frame to que up before printing
|
||||
|
||||
println("Error:");
|
||||
println("Error:**********MISSING EFFECTS IDS**********");
|
||||
keys = getarraykeys( level._missing_FX );
|
||||
foreach( key in keys )
|
||||
{
|
||||
println( "Error: Missing Effects ID assignment for: "+ key );
|
||||
}
|
||||
println("Error:");
|
||||
|
||||
assertmsg( "Missing Effects ID assignments ( see console )" );
|
||||
}
|
||||
|
||||
OneShotfxthread()
|
||||
{
|
||||
wait(0.05);
|
||||
|
||||
if ( self.v[ "delay" ] > 0 )
|
||||
wait self.v[ "delay" ];
|
||||
|
||||
[[ level.func[ "create_triggerfx" ] ]]();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Reactive Section
|
||||
//---------------------------------------------------------
|
||||
CONST_MAX_REACTIVE_SOUND_ENTS = 4;
|
||||
CONST_NEXT_PLAY_TIME = 3000;
|
||||
add_reactive_fx()
|
||||
{
|
||||
// MP should not start this thread in release
|
||||
if ( !isSP() && GetDVar( "createfx" ) == "" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !IsDefined( level._fx.reactive_thread ) )
|
||||
{
|
||||
level._fx.reactive_thread = true;
|
||||
level thread reactive_fx_thread();
|
||||
}
|
||||
|
||||
if ( !IsDefined( level._fx.reactive_fx_ents ) )
|
||||
{
|
||||
level._fx.reactive_fx_ents = [];
|
||||
}
|
||||
|
||||
level._fx.reactive_fx_ents[ level._fx.reactive_fx_ents.size ] = self;
|
||||
self.next_reactive_time = 3000;
|
||||
}
|
||||
|
||||
reactive_fx_thread()
|
||||
{
|
||||
if ( !isSp() )
|
||||
{
|
||||
if ( GetDvar( "createfx" ) == "on" )
|
||||
{
|
||||
// wait till the player spawns and createfxlogic starts before continuing.
|
||||
flag_wait( "createfx_started" );
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Switch to using level notify instead
|
||||
// HOWEVER!!! we will need the trigger_radius for when we are in CREATEFX mode for MP only!!!
|
||||
// use level.mp_createfx condition
|
||||
// trigger = Spawn( "trigger_radius", level.player.origin, 0, 5000, 5000 );
|
||||
// trigger SetCanDamage( true );
|
||||
|
||||
// trigger EnableLinkTo();
|
||||
// trigger LinkTo( level.player );
|
||||
|
||||
level._fx.reactive_sound_ents = [];
|
||||
|
||||
explosion_radius = 256;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
// trigger waittill( "damage", dmg, attacker, dir_vec, point, type );
|
||||
level waittill( "code_damageradius", attacker, explosion_radius, point, weapon_name );
|
||||
|
||||
ents = sort_reactive_ents( point, explosion_radius );
|
||||
|
||||
foreach ( i, ent in ents )
|
||||
ent thread play_reactive_fx( i );
|
||||
}
|
||||
}
|
||||
|
||||
vector2d( vec )
|
||||
{
|
||||
return ( vec[ 0 ], vec[ 1 ], 0 );
|
||||
}
|
||||
|
||||
sort_reactive_ents( point, explosion_radius )
|
||||
{
|
||||
closest = [];
|
||||
time = GetTime();
|
||||
foreach ( ent in level._fx.reactive_fx_ents )
|
||||
{
|
||||
if ( ent.next_reactive_time > time )
|
||||
continue;
|
||||
|
||||
radius_squared = ent.v[ "reactive_radius" ] + explosion_radius;
|
||||
radius_squared *= radius_squared;
|
||||
if ( DistanceSquared( point, ent.v[ "origin" ] ) < radius_squared )
|
||||
{
|
||||
closest[ closest.size ] = ent;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( ent in closest )
|
||||
{
|
||||
playerToEnt = vector2d( ent.v[ "origin" ] - level.player.origin );
|
||||
playerToPoint = vector2d( point - level.player.origin );
|
||||
vec1 = VectorNormalize( playerToEnt );
|
||||
vec2 = VectorNormalize( playerToPoint );
|
||||
ent.dot = VectorDot( vec1, vec2 );
|
||||
}
|
||||
|
||||
// Sort from lowest dot to greatest
|
||||
for ( i = 0; i < closest.size - 1; i++ )
|
||||
{
|
||||
for ( j = i + 1; j < closest.size; j++ )
|
||||
{
|
||||
if ( closest[ i ].dot > closest[ j ].dot )
|
||||
{
|
||||
temp = closest[ i ];
|
||||
closest[ i ] = closest[ j ];
|
||||
closest[ j ] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove the .origin and .dot since we're done with sortbydistance()
|
||||
foreach ( ent in closest )
|
||||
{
|
||||
ent.origin = undefined;
|
||||
ent.dot = undefined;
|
||||
}
|
||||
|
||||
// Make sure we only have 4
|
||||
for ( i = CONST_MAX_REACTIVE_SOUND_ENTS; i < closest.size; i++ )
|
||||
{
|
||||
closest[ i ] = undefined;
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
play_reactive_fx( num )
|
||||
{
|
||||
sound_ent = get_reactive_sound_ent();
|
||||
|
||||
if ( !IsDefined( sound_ent ) )
|
||||
return;
|
||||
|
||||
/#
|
||||
self.is_playing = true;
|
||||
#/
|
||||
|
||||
self.next_reactive_time = GeTTime() + CONST_NEXT_PLAY_TIME;
|
||||
sound_ent.origin = self.v[ "origin" ];
|
||||
sound_ent.is_playing = true;
|
||||
|
||||
wait( num * RandomFloatRange( 0.05, 0.1 ) );
|
||||
|
||||
if ( isSP() )
|
||||
{
|
||||
sound_ent PlaySound( self.v[ "soundalias" ], "sounddone" );
|
||||
sound_ent waittill( "sounddone" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sound_ent PlaySound( self.v[ "soundalias" ] );
|
||||
wait( 2 );
|
||||
}
|
||||
|
||||
// wait for sounddone to be removed compeletely
|
||||
// bug in prague port to iw6 where in the same frame this got called again after the sounddone notify
|
||||
// odd thing, even 0.05 doesn't work. Code should fix this!
|
||||
wait( 0.1 );
|
||||
sound_ent.is_playing = false;
|
||||
|
||||
/#
|
||||
self.is_playing = undefined;
|
||||
#/
|
||||
}
|
||||
|
||||
get_reactive_sound_ent()
|
||||
{
|
||||
foreach ( ent in level._fx.reactive_sound_ents )
|
||||
{
|
||||
if ( !ent.is_playing )
|
||||
return ent;
|
||||
}
|
||||
|
||||
if ( level._fx.reactive_sound_ents.size < CONST_MAX_REACTIVE_SOUND_ENTS )
|
||||
{
|
||||
ent = Spawn( "script_origin", ( 0, 0, 0 ) );
|
||||
ent.is_playing = false;
|
||||
|
||||
level._fx.reactive_sound_ents[ level._fx.reactive_sound_ents.size ] = ent;
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,395 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CONSTANTS //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
level_limit_pipe_fx = 8;
|
||||
max_fires_from_entity = 4;
|
||||
level_pipe_fx_chance = 33;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// LOGIC //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
main()
|
||||
{
|
||||
if ( IsDefined( level.pipes_init ) )
|
||||
return;
|
||||
|
||||
|
||||
level.pipes_init = true;
|
||||
//level._pipe_fx_time = 25; //handle this individually for different pipe types
|
||||
pipes = GetEntArray( "pipe_shootable", "targetname" );
|
||||
if ( !pipes.size )
|
||||
return;
|
||||
level._pipes = SpawnStruct();
|
||||
level._pipes.num_pipe_fx = 0;
|
||||
|
||||
pipes thread precacheFX();
|
||||
pipes thread methodsInit();
|
||||
|
||||
thread post_load( pipes );
|
||||
}
|
||||
|
||||
post_load( pipes )
|
||||
{
|
||||
waittillframeend;// insure that structs are initialized
|
||||
if( level.createFX_enabled )
|
||||
return;
|
||||
array_thread( pipes, ::pipesetup );
|
||||
}
|
||||
|
||||
pipesetup()
|
||||
{
|
||||
self SetCanDamage( true );
|
||||
self SetCanRadiusDamage( false ); // optimization
|
||||
self.pipe_fx_array = [];
|
||||
|
||||
|
||||
node = undefined;
|
||||
|
||||
if ( IsDefined( self.target ) )
|
||||
{
|
||||
node = getstruct( self.target, "targetname" );
|
||||
self.A = node.origin;
|
||||
vec = AnglesToForward( node.angles );
|
||||
vec = ( vec * 128 );
|
||||
self.B = self.A + vec;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec = AnglesToForward( self.angles );
|
||||
vec1 = ( vec * 64 );
|
||||
self.A = self.origin + vec1;
|
||||
vec1 = ( vec * -64 );
|
||||
self.B = self.origin + vec1;
|
||||
}
|
||||
|
||||
self thread pipe_wait_loop();
|
||||
}
|
||||
|
||||
pipe_wait_loop()
|
||||
{
|
||||
P = ( 0, 0, 0 );// just to initialize P as a vector
|
||||
|
||||
hasTakenDamage = false;
|
||||
remaining = max_fires_from_entity;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "damage", damage, attacker, direction_vec, P, type );
|
||||
|
||||
// random so we don't get so many fx, but the very first time is guarenteed
|
||||
if ( hasTakenDamage )
|
||||
{
|
||||
if ( randomint( 100 ) <= level_pipe_fx_chance )
|
||||
continue;
|
||||
}
|
||||
hasTakenDamage = true;
|
||||
|
||||
result = self pipe_logic( direction_vec, P, type, attacker );
|
||||
if ( result )
|
||||
remaining--;
|
||||
|
||||
if ( remaining <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
self SetCanDamage( false );
|
||||
}
|
||||
|
||||
pipe_logic( direction_vec, P, type, damageOwner )
|
||||
{
|
||||
if ( level._pipes.num_pipe_fx > level_limit_pipe_fx )
|
||||
return false;
|
||||
|
||||
if ( !isDefined( level._pipes._pipe_methods[ type ] ) )
|
||||
P = self pipe_calc_nofx( P, type );
|
||||
else
|
||||
P = self [[ level._pipes._pipe_methods[ type ] ]]( P, type );
|
||||
|
||||
if ( !isdefined( P ) )
|
||||
return false;
|
||||
|
||||
if ( IsDefined( damageOwner.classname ) && damageOwner.classname == "worldspawn" )
|
||||
return false;
|
||||
|
||||
foreach ( value in self.pipe_fx_array )
|
||||
{
|
||||
if ( DistanceSquared( P, value.origin ) < 25 )
|
||||
return false;
|
||||
}
|
||||
|
||||
//calculate the vector derived from the center line of our pipe and the point of damage
|
||||
|
||||
// generate a vector from the attacker's eye to the impact point (AI) or origin to impact point (non-AI)
|
||||
E = undefined;
|
||||
if( IsAI( damageOwner ))
|
||||
E = damageOwner GetEye();
|
||||
else
|
||||
E = damageOwner.origin;
|
||||
|
||||
temp_vec = P - E;
|
||||
|
||||
// Extend the vector (this is to ensure it intersects the damaged entity, tracing to the point itself generated new points which were slightly off and bad normals) and return a trace
|
||||
trace = BulletTrace ( E, E + 1.5 * temp_vec, false, damageOwner, false );
|
||||
if ( isdefined ( trace [ "normal" ] ) && isdefined ( trace [ "entity" ] ) && trace ["entity"] == self )
|
||||
{
|
||||
vec = trace[ "normal" ];
|
||||
|
||||
// Use the surface normal of the impact point to generate the angles for the burst effect
|
||||
self thread pipefx( P, vec, damageOwner );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pipefx( P, vec, damageOwner )
|
||||
{
|
||||
time = level._pipes.fx_time[ self.script_noteworthy ] ;
|
||||
fx_time = level._pipes._pipe_fx_time[ self.script_noteworthy ] ;
|
||||
intervals = Int( fx_time / time );// loops for 25 seconds
|
||||
intervals_end = 30;
|
||||
hitsnd = level._pipes._sound[ self.script_noteworthy + "_hit" ];
|
||||
loopsnd = level._pipes._sound[ self.script_noteworthy + "_loop" ];
|
||||
endsnd = level._pipes._sound[ self.script_noteworthy + "_end" ];
|
||||
|
||||
snd = Spawn( "script_origin", P );
|
||||
// snd Hide();
|
||||
snd PlaySound( hitsnd );
|
||||
snd PlayLoopSound( loopsnd );
|
||||
self.pipe_fx_array[ self.pipe_fx_array.size ] = snd;
|
||||
|
||||
if ( isSP() || self.script_noteworthy != "steam" )
|
||||
self thread pipe_damage( P, vec, damageOwner, snd );
|
||||
|
||||
//if it is a barrel, rotate the emitter angle over time
|
||||
if( self.script_noteworthy == "oil_leak" )
|
||||
{
|
||||
efx_rot = Spawn( "script_model", P );
|
||||
efx_rot SetModel( "tag_origin" );
|
||||
efx_rot.angles = VectorToAngles( vec );
|
||||
PlayFXOnTag( level._pipes._effect[ self.script_noteworthy ] , efx_rot, "tag_origin" );
|
||||
level._pipes.num_pipe_fx++;
|
||||
efx_rot RotatePitch( 90, time, 1, 1 );
|
||||
wait time;
|
||||
StopFXOnTag( level._pipes._effect[ self.script_noteworthy ] , efx_rot, "tag_origin" );
|
||||
intervals--;
|
||||
}
|
||||
else
|
||||
{
|
||||
//do it once without checking for newer fx being played ( we're the newest )
|
||||
PlayFX( level._pipes._effect[ self.script_noteworthy ], P, vec );
|
||||
level._pipes.num_pipe_fx++;
|
||||
wait time;
|
||||
intervals--;
|
||||
}
|
||||
//now check for other fx and rest of intervals
|
||||
while ( level._pipes.num_pipe_fx <= level_limit_pipe_fx && intervals > 0 )
|
||||
{
|
||||
if( self.script_noteworthy == "oil_leak" )
|
||||
{
|
||||
efx_rot = Spawn( "script_model", P );
|
||||
efx_rot SetModel( "tag_origin" );
|
||||
efx_rot.angles = VectorToAngles( vec );
|
||||
PlayFXOnTag( level._pipes._effect[ self.script_noteworthy ] , efx_rot, "tag_origin" );
|
||||
level._pipes.num_pipe_fx++;
|
||||
efx_rot RotatePitch( 90, time, 1, 1 );
|
||||
wait time;
|
||||
StopFXOnTag( level._pipes._effect[ self.script_noteworthy ] , efx_rot, "tag_origin" );
|
||||
}
|
||||
else
|
||||
{
|
||||
//do it once without checking for newer fx being played ( we're the newest )
|
||||
PlayFX( level._pipes._effect[ self.script_noteworthy ], P, vec );
|
||||
wait time;
|
||||
intervals--;
|
||||
}
|
||||
}
|
||||
|
||||
snd PlaySound( endsnd );
|
||||
wait( .5 );
|
||||
snd StopLoopSound( loopsnd );
|
||||
snd Delete();
|
||||
self.pipe_fx_array = array_removeUndefined( self.pipe_fx_array );
|
||||
|
||||
level._pipes.num_pipe_fx--;
|
||||
}
|
||||
|
||||
pipe_damage( P, vec, damageOwner, fx )
|
||||
{
|
||||
if ( !allow_pipe_damage() )
|
||||
return;
|
||||
|
||||
fx endon( "death" );
|
||||
|
||||
origin = fx.origin + ( VectorNormalize( vec ) * 40 );
|
||||
dmg = level._pipes._dmg[ self.script_noteworthy ];
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
// do not pass damage owner if they have disconnected before the barrels explode.. the barrels?
|
||||
if ( !isdefined( self.damageOwner ) )
|
||||
{
|
||||
// MOD_TRIGGER_HURT so they dont do dirt on the player's screen
|
||||
self RadiusDamage( origin, 36, dmg, dmg * 0.75, undefined, "MOD_TRIGGER_HURT" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// MOD_TRIGGER_HURT so they dont do dirt on the player's screen
|
||||
self RadiusDamage( origin, 36, dmg, dmg * 0.75, damageOwner, "MOD_TRIGGER_HURT" );
|
||||
}
|
||||
|
||||
wait( 0.4 );
|
||||
}
|
||||
}
|
||||
|
||||
allow_pipe_damage()
|
||||
{
|
||||
if( !isSP() )
|
||||
return false;
|
||||
|
||||
if ( !isDefined( level.pipesDamage ) )
|
||||
return true;
|
||||
|
||||
return ( level.pipesDamage );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CALCULATIONS / SETUP //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
methodsInit()
|
||||
{
|
||||
level._pipes._pipe_methods = [];
|
||||
level._pipes._pipe_methods[ "MOD_UNKNOWN" ] = ::pipe_calc_splash;
|
||||
level._pipes._pipe_methods[ "MOD_PISTOL_BULLET" ] = ::pipe_calc_ballistic;
|
||||
level._pipes._pipe_methods[ "MOD_RIFLE_BULLET" ] = ::pipe_calc_ballistic;
|
||||
level._pipes._pipe_methods[ "MOD_GRENADE" ] = ::pipe_calc_splash;
|
||||
level._pipes._pipe_methods[ "MOD_GRENADE_SPLASH" ] = ::pipe_calc_splash;
|
||||
level._pipes._pipe_methods[ "MOD_PROJECTILE" ] = ::pipe_calc_splash;
|
||||
level._pipes._pipe_methods[ "MOD_PROJECTILE_SPLASH" ] = ::pipe_calc_splash;
|
||||
level._pipes._pipe_methods[ "MOD_TRIGGER_HURT" ] = ::pipe_calc_splash;
|
||||
level._pipes._pipe_methods[ "MOD_EXPLOSIVE" ] = ::pipe_calc_splash;
|
||||
level._pipes._pipe_methods[ "MOD_EXPLOSIVE_BULLET" ] = ::pipe_calc_splash;
|
||||
}
|
||||
|
||||
pipe_calc_ballistic( P, type )
|
||||
{
|
||||
return P;
|
||||
}
|
||||
|
||||
pipe_calc_splash( P, type )
|
||||
{
|
||||
vec = VectorNormalize( VectorFromLineToPoint( self.A, self.B, P ) );
|
||||
P = PointOnSegmentNearestToPoint( self.A, self.B, P );
|
||||
return( P + ( vec * 4 ) );
|
||||
}
|
||||
|
||||
pipe_calc_nofx( P, type )
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
|
||||
precacheFX()
|
||||
{
|
||||
steam = false;
|
||||
fire = false;
|
||||
steam_small = false;
|
||||
oil_leak = false;
|
||||
oil_cap = false;
|
||||
foreach ( value in self )
|
||||
{
|
||||
if ( value.script_noteworthy == "water" )
|
||||
value.script_noteworthy = "steam";
|
||||
|
||||
if ( value.script_noteworthy == "steam" )
|
||||
{
|
||||
value willNeverChange();
|
||||
steam = true;
|
||||
}
|
||||
else if ( value.script_noteworthy == "fire" )
|
||||
{
|
||||
value willNeverChange();
|
||||
fire = true;
|
||||
}
|
||||
else if ( value.script_noteworthy == "steam_small" )
|
||||
{
|
||||
value willNeverChange();
|
||||
steam_small = true;
|
||||
}
|
||||
else if ( value.script_noteworthy == "oil_leak" )
|
||||
{
|
||||
value willNeverChange();
|
||||
oil_leak = true;
|
||||
}
|
||||
else if ( value.script_noteworthy == "oil_cap" )
|
||||
{
|
||||
value willNeverChange();
|
||||
oil_cap = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
println( "Unknown 'pipe_shootable' script_noteworthy type '%s'\n", value.script_noteworthy );
|
||||
}
|
||||
}
|
||||
|
||||
if ( steam )
|
||||
{
|
||||
level._pipes._effect[ "steam" ] = LoadFX( "fx/impacts/pipe_steam" );
|
||||
level._pipes._sound[ "steam_hit" ] = "mtl_steam_pipe_hit";
|
||||
level._pipes._sound[ "steam_loop" ] = "mtl_steam_pipe_hiss_loop";
|
||||
level._pipes._sound[ "steam_end" ] = "mtl_steam_pipe_hiss_loop_end";
|
||||
level._pipes.fx_time[ "steam" ] = 3;
|
||||
level._pipes._dmg[ "steam" ] = 5;
|
||||
level._pipes._pipe_fx_time["steam"] = 25;
|
||||
}
|
||||
|
||||
if ( steam_small )
|
||||
{
|
||||
level._pipes._effect[ "steam_small" ] = LoadFX( "fx/impacts/pipe_steam_small" );
|
||||
level._pipes._sound[ "steam_small_hit" ] = "mtl_steam_pipe_hit";
|
||||
level._pipes._sound[ "steam_small_loop" ] = "mtl_steam_pipe_hiss_loop";
|
||||
level._pipes._sound[ "steam_small_end" ] = "mtl_steam_pipe_hiss_loop_end";
|
||||
level._pipes.fx_time[ "steam_small" ] = 3;
|
||||
level._pipes._dmg[ "steam_small" ] = 5;
|
||||
level._pipes._pipe_fx_time["steam_small"] = 25;
|
||||
}
|
||||
|
||||
if ( fire )
|
||||
{
|
||||
level._pipes._effect[ "fire" ] = LoadFX( "fx/impacts/pipe_fire" );
|
||||
level._pipes._sound[ "fire_hit" ] = "mtl_gas_pipe_hit";
|
||||
level._pipes._sound[ "fire_loop" ] = "mtl_gas_pipe_flame_loop";
|
||||
level._pipes._sound[ "fire_end" ] = "mtl_gas_pipe_flame_end";
|
||||
level._pipes.fx_time[ "fire" ] = 3;
|
||||
level._pipes._dmg[ "fire" ] = 5;
|
||||
level._pipes._pipe_fx_time["fire"] = 25;
|
||||
}
|
||||
|
||||
if ( oil_leak )
|
||||
{
|
||||
level._pipes._effect[ "oil_leak" ] = LoadFX( "fx/impacts/pipe_oil_barrel_spill" );
|
||||
// level._pipes._effect[ "oil_leak_end" ] = LoadFX( "fx/impacts/pipe_oil_barrel_spill_ending1" );
|
||||
level._pipes._sound[ "oil_leak_hit" ] = "mtl_oil_barrel_hit";
|
||||
level._pipes._sound[ "oil_leak_loop" ] = "mtl_oil_barrel_hiss_loop";
|
||||
level._pipes._sound[ "oil_leak_end" ] = "mtl_oil_barrel_hiss_loop_end";
|
||||
level._pipes.fx_time[ "oil_leak" ] = 6;
|
||||
level._pipes._pipe_fx_time["oil_leak"] = 6;
|
||||
level._pipes._dmg[ "oil_leak" ] = 5;
|
||||
}
|
||||
|
||||
if ( oil_cap )
|
||||
{
|
||||
level._pipes._effect[ "oil_cap" ] = LoadFX( "fx/impacts/pipe_oil_barrel_squirt" );
|
||||
level._pipes._sound[ "oil_cap_hit" ] = "mtl_steam_pipe_hit";
|
||||
level._pipes._sound[ "oil_cap_loop" ] = "mtl_steam_pipe_hiss_loop";
|
||||
level._pipes._sound[ "oil_cap_end" ] = "mtl_steam_pipe_hiss_loop_end";
|
||||
level._pipes.fx_time[ "oil_cap" ] = 3;
|
||||
level._pipes._dmg[ "oil_cap" ] = 5;
|
||||
level._pipes._pipe_fx_time["oil_cap"] = 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user