init
This commit is contained in:
commit
12ac62a956
270
codescripts/character.gsc
Normal file
270
codescripts/character.gsc
Normal file
@ -0,0 +1,270 @@
|
||||
setModelFromArray( a )
|
||||
{
|
||||
self setModel( a[ randomint( a.size ) ] );
|
||||
}
|
||||
|
||||
precacheModelArray( a )
|
||||
{
|
||||
for ( i = 0; i < a.size; i++ )
|
||||
precacheModel( a[ i ] );
|
||||
}
|
||||
|
||||
attachHead( headAlias, headArray )
|
||||
{
|
||||
/#
|
||||
// For test map purposes only!! - IW5_Characters uses this.
|
||||
if ( IsDefined( level.store_characterinfo ) )
|
||||
{
|
||||
if ( !IsDefined( self.characterinfo ) )
|
||||
{
|
||||
self.characterinfo = SpawnStruct();
|
||||
self.characterinfo.headalias = headAlias;
|
||||
self.characterinfo.headarray = headarray;
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
if ( !isdefined( level.character_head_index ) )
|
||||
level.character_head_index = [];
|
||||
|
||||
if ( !isdefined( level.character_head_index[ headAlias ] ) )
|
||||
level.character_head_index[ headAlias ] = randomint( headArray.size );
|
||||
|
||||
assert( level.character_head_index[ headAlias ] < headArray.size );
|
||||
|
||||
index = ( level.character_head_index[ headAlias ] + 1 ) % headArray.size;
|
||||
|
||||
// the designer can overwrite the character
|
||||
if ( isdefined( self.script_char_index ) )
|
||||
{
|
||||
index = self.script_char_index % headArray.size;
|
||||
}
|
||||
|
||||
level.character_head_index[ headAlias ] = index;
|
||||
|
||||
self attach( headArray[ index ], "", true );
|
||||
self.headModel = headArray[ index ];
|
||||
}
|
||||
|
||||
attachHat( hatAlias, hatArray )
|
||||
{
|
||||
if ( !isdefined( level.character_hat_index ) )
|
||||
level.character_hat_index = [];
|
||||
|
||||
if ( !isdefined( level.character_hat_index[ hatAlias ] ) )
|
||||
level.character_hat_index[ hatAlias ] = randomint( hatArray.size );
|
||||
|
||||
assert( level.character_hat_index[ hatAlias ] < hatArray.size );
|
||||
|
||||
index = ( level.character_hat_index[ hatAlias ] + 1 ) % hatArray.size;
|
||||
|
||||
level.character_hat_index[ hatAlias ] = index;
|
||||
|
||||
self attach( hatArray[ index ] );
|
||||
self.hatModel = hatArray[ index ];
|
||||
}
|
||||
|
||||
new()
|
||||
{
|
||||
self detachAll();
|
||||
oldGunHand = self.anim_gunHand;
|
||||
if ( !isdefined( oldGunHand ) )
|
||||
return;
|
||||
self.anim_gunHand = "none";
|
||||
self [[ anim.PutGunInHand ]]( oldGunHand );
|
||||
}
|
||||
|
||||
save()
|
||||
{
|
||||
info[ "gunHand" ] = self.anim_gunHand;
|
||||
info[ "gunInHand" ] = self.anim_gunInHand;
|
||||
info[ "model" ] = self.model;
|
||||
info[ "hatModel" ] = self.hatModel;
|
||||
if ( isdefined( self.name ) )
|
||||
{
|
||||
info[ "name" ] = self.name;
|
||||
println( "Save: Guy has name ", self.name );
|
||||
}
|
||||
else
|
||||
println( "save: Guy had no name!" );
|
||||
|
||||
attachSize = self getAttachSize();
|
||||
for ( i = 0; i < attachSize; i++ )
|
||||
{
|
||||
info[ "attach" ][ i ][ "model" ] = self getAttachModelName( i );
|
||||
info[ "attach" ][ i ][ "tag" ] = self getAttachTagName( i );
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
load( info )
|
||||
{
|
||||
self detachAll();
|
||||
self.anim_gunHand = info[ "gunHand" ];
|
||||
self.anim_gunInHand = info[ "gunInHand" ];
|
||||
self setModel( info[ "model" ] );
|
||||
self.hatModel = info[ "hatModel" ];
|
||||
if ( isdefined( info[ "name" ] ) )
|
||||
{
|
||||
self.name = info[ "name" ];
|
||||
println( "Load: Guy has name ", self.name );
|
||||
}
|
||||
else
|
||||
println( "Load: Guy had no name!" );
|
||||
|
||||
attachInfo = info[ "attach" ];
|
||||
attachSize = attachInfo.size;
|
||||
for ( i = 0; i < attachSize; i++ )
|
||||
self attach( attachInfo[ i ][ "model" ], attachInfo[ i ][ "tag" ] );
|
||||
}
|
||||
|
||||
precache( info )
|
||||
{
|
||||
if ( isdefined( info[ "name" ] ) )
|
||||
println( "Precache: Guy has name ", info[ "name" ] );
|
||||
else
|
||||
println( "Precache: Guy had no name!" );
|
||||
|
||||
precacheModel( info[ "model" ] );
|
||||
|
||||
attachInfo = info[ "attach" ];
|
||||
attachSize = attachInfo.size;
|
||||
for ( i = 0; i < attachSize; i++ )
|
||||
precacheModel( attachInfo[ i ][ "model" ] );
|
||||
}
|
||||
|
||||
/*
|
||||
sample save / precache / load usage( precache is only required if there are any waits in the level script before load ):
|
||||
|
||||
save:
|
||||
info = foley codescripts\character::save();
|
||||
game[ "foley" ] = info;
|
||||
changelevel( "burnville", 0, true );
|
||||
|
||||
precache:
|
||||
codescripts\character::precache( game[ "foley" ] );
|
||||
|
||||
load:
|
||||
foley codescripts\character::load( game[ "foley" ] );
|
||||
|
||||
*/
|
||||
|
||||
get_random_character( amount )
|
||||
{
|
||||
self_info = strtok( self.classname, "_" );
|
||||
if ( !common_scripts\utility::isSP() )
|
||||
{
|
||||
if ( isDefined( self.pers["modelIndex"] ) && self.pers["modelIndex"] < amount )
|
||||
return self.pers["modelIndex"];
|
||||
|
||||
index = randomInt( amount );
|
||||
self.pers["modelIndex"] = index;
|
||||
|
||||
return index;
|
||||
}
|
||||
else if ( self_info.size <= 2 )
|
||||
{
|
||||
// some custom guy that doesn't use standard naming convention
|
||||
return randomint( amount );
|
||||
}
|
||||
|
||||
group = "auto"; // by default the type is an auto-selected character
|
||||
index = undefined;
|
||||
prefix = self_info[ 2 ]; // merc, marine, etc
|
||||
|
||||
// the designer can overwrite the character
|
||||
if ( isdefined( self.script_char_index ) )
|
||||
{
|
||||
index = self.script_char_index;
|
||||
}
|
||||
|
||||
// the designer can hint that this guy is a member of a group of like - spawned guys, so he should use a different index
|
||||
if ( isdefined( self.script_char_group ) )
|
||||
{
|
||||
type = "grouped";
|
||||
group = "group_" + self.script_char_group;
|
||||
}
|
||||
|
||||
if ( !isdefined( level.character_index_cache ) )
|
||||
{
|
||||
// separately store script grouped guys and auto guys so that they dont influence each other
|
||||
level.character_index_cache = [];
|
||||
}
|
||||
|
||||
if ( !isdefined( level.character_index_cache[ prefix ] ) )
|
||||
{
|
||||
// separately store script grouped guys and auto guys so that they dont influence each other
|
||||
level.character_index_cache[ prefix ] = [];
|
||||
}
|
||||
|
||||
if ( !isdefined( level.character_index_cache[ prefix ][ group ] ) )
|
||||
{
|
||||
initialize_character_group( prefix, group, amount );
|
||||
}
|
||||
|
||||
if ( !isdefined( index ) )
|
||||
{
|
||||
index = get_least_used_index( prefix, group );
|
||||
|
||||
if ( !isdefined( index ) )
|
||||
{
|
||||
// fail safe
|
||||
index = randomint( 5000 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while ( index >= amount )
|
||||
{
|
||||
index -= amount;
|
||||
}
|
||||
|
||||
level.character_index_cache[ prefix ][ group ][ index ]++;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
get_least_used_index( prefix, group )
|
||||
{
|
||||
lowest_indices = [];
|
||||
lowest_use = level.character_index_cache[ prefix ][ group ][ 0 ];
|
||||
lowest_indices[ 0 ] = 0;
|
||||
|
||||
for ( i = 1; i < level.character_index_cache[ prefix ][ group ].size; i++ )
|
||||
{
|
||||
if ( level.character_index_cache[ prefix ][ group ][ i ] > lowest_use )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( level.character_index_cache[ prefix ][ group ][ i ] < lowest_use )
|
||||
{
|
||||
// if its the new lowest, start over on the array
|
||||
lowest_indices = [];
|
||||
lowest_use = level.character_index_cache[ prefix ][ group ][ i ];
|
||||
}
|
||||
|
||||
// the equal amounts end up in the array
|
||||
lowest_indices[ lowest_indices.size ] = i;
|
||||
}
|
||||
assertex( lowest_indices.size, "Tried to spawn a character but the lowest indices didn't exist" );
|
||||
return random( lowest_indices );
|
||||
}
|
||||
|
||||
initialize_character_group( prefix, group, amount )
|
||||
{
|
||||
for ( i = 0; i < amount; i++ )
|
||||
{
|
||||
level.character_index_cache[ prefix ][ group ][ i ] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
get_random_weapon( amount )
|
||||
{
|
||||
return randomint( amount );
|
||||
}
|
||||
|
||||
random( array )
|
||||
{
|
||||
return array [ randomint( array.size ) ];
|
||||
}
|
7
codescripts/delete.gsc
Normal file
7
codescripts/delete.gsc
Normal file
@ -0,0 +1,7 @@
|
||||
main()
|
||||
{
|
||||
assert(isdefined(self));
|
||||
wait 0;
|
||||
if (isdefined(self))
|
||||
self delete();
|
||||
}
|
11
codescripts/struct.gsc
Normal file
11
codescripts/struct.gsc
Normal file
@ -0,0 +1,11 @@
|
||||
InitStructs()
|
||||
{
|
||||
level.struct = [];
|
||||
}
|
||||
|
||||
CreateStruct()
|
||||
{
|
||||
struct = spawnstruct();
|
||||
level.struct[level.struct.size] = struct;
|
||||
return struct;
|
||||
}
|
286
common_scripts/_artcommon.gsc
Normal file
286
common_scripts/_artcommon.gsc
Normal file
@ -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");
|
||||
}
|
||||
}
|
||||
#/
|
3799
common_scripts/_bcs_location_trigs.gsc
Normal file
3799
common_scripts/_bcs_location_trigs.gsc
Normal file
File diff suppressed because it is too large
Load Diff
2578
common_scripts/_createfx.gsc
Normal file
2578
common_scripts/_createfx.gsc
Normal file
File diff suppressed because it is too large
Load Diff
755
common_scripts/_createfxmenu.gsc
Normal file
755
common_scripts/_createfxmenu.gsc
Normal file
@ -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 ];
|
||||
}
|
1226
common_scripts/_csplines.gsc
Normal file
1226
common_scripts/_csplines.gsc
Normal file
File diff suppressed because it is too large
Load Diff
5063
common_scripts/_destructible.gsc
Normal file
5063
common_scripts/_destructible.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1636
common_scripts/_dynamic_world.gsc
Normal file
1636
common_scripts/_dynamic_world.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1286
common_scripts/_elevator.gsc
Normal file
1286
common_scripts/_elevator.gsc
Normal file
File diff suppressed because it is too large
Load Diff
987
common_scripts/_exploder.gsc
Normal file
987
common_scripts/_exploder.gsc
Normal file
@ -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 );
|
||||
}
|
871
common_scripts/_fx.gsc
Normal file
871
common_scripts/_fx.gsc
Normal file
@ -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;
|
||||
}
|
1104
common_scripts/_painter.gsc
Normal file
1104
common_scripts/_painter.gsc
Normal file
File diff suppressed because it is too large
Load Diff
395
common_scripts/_pipes.gsc
Normal file
395
common_scripts/_pipes.gsc
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
4981
common_scripts/utility.gsc
Normal file
4981
common_scripts/utility.gsc
Normal file
File diff suppressed because it is too large
Load Diff
8
destructible_scripts/toy_chicken.gsc
Normal file
8
destructible_scripts/toy_chicken.gsc
Normal file
@ -0,0 +1,8 @@
|
||||
#include common_scripts\_destructible;
|
||||
#include destructible_scripts\toy_chicken_common;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
toy_chicken_common( "" );
|
||||
}
|
8
destructible_scripts/toy_chicken_black_white.gsc
Normal file
8
destructible_scripts/toy_chicken_black_white.gsc
Normal file
@ -0,0 +1,8 @@
|
||||
#include common_scripts\_destructible;
|
||||
#include destructible_scripts\toy_chicken_common;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
toy_chicken_common( "_black_white" );
|
||||
}
|
19
destructible_scripts/toy_chicken_common.gsc
Normal file
19
destructible_scripts/toy_chicken_common.gsc
Normal file
@ -0,0 +1,19 @@
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
toy_chicken_common( version )
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// Chicken
|
||||
//---------------------------------------------------------------------
|
||||
destructible_create( "toy_chicken" + version, "tag_origin", 0, undefined, 32 );
|
||||
destructible_anim( %chicken_cage_loop_01, #animtree, "setanimknob", undefined, 0, "chicken_cage_loop_01", 1.6 );
|
||||
destructible_anim( %chicken_cage_loop_02, #animtree, "setanimknob", undefined, 1, "chicken_cage_loop_02", 1.6 );
|
||||
destructible_loopsound( "animal_chicken_idle_loop" );
|
||||
destructible_state( "tag_origin", "chicken" + version, 25 );
|
||||
destructible_fx( "tag_origin", "fx/props/chicken_exp" + version );
|
||||
destructible_anim( %chicken_cage_death, #animtree, "setanimknob", undefined, 0, "chicken_cage_death" );
|
||||
destructible_anim( %chicken_cage_death_02, #animtree, "setanimknob", undefined, 1, "chicken_cage_death_02" );
|
||||
destructible_sound( "animal_chicken_death" );
|
||||
destructible_state( undefined, "chicken" + version, undefined, undefined, "no_melee" );
|
||||
}
|
21
destructible_scripts/toy_filecabinet.gsc
Normal file
21
destructible_scripts/toy_filecabinet.gsc
Normal file
@ -0,0 +1,21 @@
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// filecabinet toy
|
||||
//---------------------------------------------------------------------
|
||||
destructible_create( "toy_filecabinet", "tag_origin", 120 );
|
||||
destructible_fx( "tag_drawer_lower", "fx/props/filecabinet_dam", true, damage_not( "splash" ) ); // coin drop
|
||||
destructible_sound( "exp_filecabinet" );
|
||||
destructible_state( undefined, "com_filecabinetblackclosed_dam", 20, undefined, undefined, "splash" );
|
||||
destructible_fx( "tag_drawer_upper", "fx/props/filecabinet_des", true, "splash" ); // coin drop
|
||||
destructible_sound( "exp_filecabinet" ); // coin drop sounds
|
||||
destructible_physics( "tag_drawer_upper", ( 50, -10, 5 ) ); // coin drop sounds
|
||||
destructible_state( undefined, "com_filecabinetblackclosed_des", undefined, undefined, undefined, undefined, undefined, false );
|
||||
|
||||
// front door
|
||||
destructible_part( "tag_drawer_upper", "com_filecabinetblackclosed_drawer", undefined, undefined, undefined, undefined, 1.0, 1.0 );
|
||||
|
||||
}
|
25
destructible_scripts/toy_light_ceiling_fluorescent.gsc
Normal file
25
destructible_scripts/toy_light_ceiling_fluorescent.gsc
Normal file
@ -0,0 +1,25 @@
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// Ceiling fluorescent light
|
||||
//---------------------------------------------------------------------
|
||||
destructible_create( "toy_light_ceiling_fluorescent", "tag_origin", 150, undefined, 32, "no_melee" );
|
||||
destructible_splash_damage_scaler( 15 );
|
||||
destructible_fx( "tag_fx", "fx/misc/light_fluorescent_blowout_runner" );
|
||||
destructible_fx( "tag_swing_fx", "fx/misc/light_blowout_swinging_runner" );
|
||||
destructible_lights_out( 16 );
|
||||
destructible_explode( 20, 2000, 64, 64, 40, 80 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage
|
||||
destructible_anim( %light_fluorescent_swing, #animtree, "setanimknob", undefined, 0, "light_fluorescent_swing" );
|
||||
destructible_sound( "fluorescent_light_fall", undefined, 0 );
|
||||
destructible_sound( "fluorescent_light_bulb", undefined, 0 );
|
||||
//destructible_sound( "fluorescent_light_spark", undefined, 0 );
|
||||
destructible_anim( %light_fluorescent_swing_02, #animtree, "setanimknob", undefined, 1, "light_fluorescent_swing_02" );
|
||||
destructible_sound( "fluorescent_light_fall", undefined, 1 );
|
||||
destructible_sound( "fluorescent_light_bulb", undefined, 1 );
|
||||
//destructible_sound( "fluorescent_light_spark", undefined, 1 );
|
||||
destructible_anim( %light_fluorescent_null, #animtree, "setanimknob", undefined, 2, "light_fluorescent_null" );
|
||||
destructible_state( undefined, "me_lightfluohang_double_destroyed", undefined, undefined, "no_melee" );
|
||||
}
|
30
destructible_scripts/toy_transformer_small01.gsc
Normal file
30
destructible_scripts/toy_transformer_small01.gsc
Normal file
@ -0,0 +1,30 @@
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// Small hanging Transformer box for Favela
|
||||
//---------------------------------------------------------------------
|
||||
destructible_create( "toy_transformer_small01", "tag_origin", 75, undefined, 32, "no_melee" );
|
||||
destructible_splash_damage_scaler( 15 );
|
||||
destructible_loopfx( "tag_fx", "fx/smoke/car_damage_whitesmoke", 0.4 );
|
||||
destructible_state( undefined, undefined, 75, undefined, 32, "no_melee" );
|
||||
destructible_loopfx( "tag_fx", "fx/smoke/car_damage_blacksmoke", 0.4 );
|
||||
destructible_state( undefined, undefined, 150, undefined, 32, "no_melee" );
|
||||
destructible_loopfx( "tag_fx", "fx/explosions/transformer_spark_runner", .5 );
|
||||
destructible_loopsound( "transformer_spark_loop" );
|
||||
destructible_healthdrain( 24, 0.2 );
|
||||
destructible_state( undefined, undefined, 250, undefined, 32, "no_melee" );
|
||||
destructible_loopfx( "tag_fx", "fx/explosions/transformer_spark_runner", .5 );
|
||||
destructible_loopfx( "tag_fx", "fx/fire/transformer_small_blacksmoke_fire", .4 );
|
||||
destructible_sound( "transformer01_flareup_med" );
|
||||
destructible_loopsound( "transformer_spark_loop" );
|
||||
destructible_healthdrain( 24, 0.2, 150, "allies" );
|
||||
destructible_state( undefined, undefined, 400, undefined, 5, "no_melee" );
|
||||
destructible_fx( "tag_fx", "fx/explosions/transformer_explosion", false );
|
||||
destructible_fx( "tag_fx", "fx/fire/firelp_small_pm" );
|
||||
destructible_sound( "transformer01_explode" );
|
||||
destructible_explode( 7000, 8000, 150, 256, 16, 100, undefined, 0 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage
|
||||
destructible_state( undefined, "utility_transformer_small01_dest", undefined, undefined, "no_melee" );
|
||||
}
|
17
destructible_scripts/toy_trashcan_metal_closed.gsc
Normal file
17
destructible_scripts/toy_trashcan_metal_closed.gsc
Normal file
@ -0,0 +1,17 @@
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// trashcan_metal_closed
|
||||
//---------------------------------------------------------------------
|
||||
destructible_create( "toy_trashcan_metal_closed", "tag_origin", 120, undefined, 32, "no_melee" );
|
||||
destructible_fx( "tag_fx", "fx/props/garbage_spew_des", true, "splash" );
|
||||
destructible_fx( "tag_fx", "fx/props/garbage_spew", true, damage_not( "splash" ) );
|
||||
destructible_sound( "exp_trashcan_sweet" );
|
||||
destructible_explode( 600, 651, 1, 1, 10, 20 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage
|
||||
destructible_state( undefined, "com_trashcan_metal_with_trash", undefined, undefined, undefined, undefined, undefined, false );
|
||||
|
||||
destructible_part( "tag_fx", "com_trashcan_metalLID", undefined, undefined, undefined, undefined, 1.0, 1.0 );
|
||||
}
|
97
destructible_scripts/toy_tv_flatscreen.gsc
Normal file
97
destructible_scripts/toy_tv_flatscreen.gsc
Normal file
@ -0,0 +1,97 @@
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
toy_tvs_flatscreen( version, mounting, destroyFn )
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// Flatscreen TVs
|
||||
//---------------------------------------------------------------------
|
||||
if(IsDefined( self.script_noteworthy ) && self.script_noteworthy == "blackice_tv")
|
||||
{
|
||||
destructible_create( "toy_tv_flatscreen_" + mounting + version, "tag_origin", 1, undefined, 32 );
|
||||
destructible_splash_damage_scaler( 1 );
|
||||
destructible_fx( "tag_fx", "fx/explosions/tv_flatscreen_explosion_quick" );
|
||||
destructible_sound( "tv_shot_burst" );
|
||||
destructible_explode( 20, 2000, 10, 10, 3, 3, undefined, 15 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage
|
||||
destructible_state( undefined, "ma_flatscreen_tv_" + mounting + "broken_" + version, 200, undefined, "no_melee" );
|
||||
}
|
||||
else
|
||||
{
|
||||
destructible_create( "toy_tv_flatscreen_" + mounting + version, "tag_origin", 1, undefined, 32 );
|
||||
destructible_splash_damage_scaler( 1 );
|
||||
destructible_fx( "tag_fx", "fx/explosions/tv_flatscreen_explosion" );
|
||||
destructible_sound( "tv_shot_burst" );
|
||||
destructible_explode( 20, 2000, 10, 10, 3, 3, undefined, 15 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage
|
||||
destructible_state( undefined, "ma_flatscreen_tv_" + mounting + "broken_" + version, 200, undefined, "no_melee" );
|
||||
}
|
||||
}
|
||||
|
||||
toy_tvs_flatscreen_sturdy( version, mounting, destroyFn )
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// Flatscreen TVs that can take more damage
|
||||
//---------------------------------------------------------------------
|
||||
if ( IsDefined( self.script_noteworthy ) && self.script_noteworthy == "blackice_tv" )
|
||||
{
|
||||
destructible_create( "toy_tv_flatscreen_" + mounting + version + "_sturdy", "tag_origin", 1, undefined, 1280 );
|
||||
destructible_splash_damage_scaler( 0.5 );
|
||||
destructible_fx( "tag_fx", "fx/explosions/tv_flatscreen_explosion_quick" );
|
||||
destructible_sound( "tv_shot_burst" );
|
||||
destructible_explode( 20, 2000, 10, 10, 3, 3, undefined, 15 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage
|
||||
destructible_state( undefined, "ma_flatscreen_tv_" + mounting + "broken_" + version, 200, undefined, "no_melee" );
|
||||
}
|
||||
else
|
||||
{
|
||||
destructible_create( "toy_tv_flatscreen_" + mounting + version + "_sturdy", "tag_origin", 1, undefined, 1280 );
|
||||
destructible_splash_damage_scaler( 0.5 );
|
||||
destructible_fx( "tag_fx", "fx/explosions/tv_flatscreen_explosion_cheap" );
|
||||
destructible_sound( "tv_shot_burst" );
|
||||
destructible_explode( 20, 2000, 10, 10, 3, 3, undefined, 15 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage
|
||||
destructible_state( undefined, "ma_flatscreen_tv_" + mounting + "broken_" + version, 200, undefined, "no_melee" );
|
||||
}
|
||||
}
|
||||
|
||||
toy_tvs_flatscreen_cinematic( modelName, destroyFn )
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// Flatscreen TV that has a (optional) separate model that shows a cinematic on the screen
|
||||
//---------------------------------------------------------------------
|
||||
if ( IsDefined( self.script_noteworthy ) && self.script_noteworthy == "blackice_tv" )
|
||||
{
|
||||
destructible_create( "toy_" + modelName, "tag_origin", 1, undefined, 32 );
|
||||
destructible_splash_damage_scaler( 1 );
|
||||
destructible_fx( "tag_fx", "fx/explosions/tv_flatscreen_explosion_quick" );
|
||||
destructible_sound( "tv_shot_burst" );
|
||||
destructible_explode( 20, 2000, 10, 10, 3, 3, undefined, 15 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage
|
||||
destructible_function( destroyFn );
|
||||
destructible_state( undefined, modelName + "_d", 200, undefined, "no_melee" );
|
||||
}
|
||||
else
|
||||
{
|
||||
destructible_create( "toy_" + modelName, "tag_origin", 1, undefined, 32 );
|
||||
destructible_splash_damage_scaler( 1 );
|
||||
destructible_fx( "tag_fx", "fx/explosions/tv_flatscreen_explosion" );
|
||||
destructible_sound( "tv_shot_burst" );
|
||||
destructible_explode( 20, 2000, 10, 10, 3, 3, undefined, 15 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage
|
||||
destructible_function( destroyFn );
|
||||
destructible_state( undefined, modelName + "_d", 200, undefined, "no_melee" );
|
||||
}
|
||||
}
|
||||
|
||||
// Finds and removes a targetted model. Commonly used to remove the cinematic-playing screen and/or a light when a TV is destroyed.
|
||||
RemoveTargetted()
|
||||
{
|
||||
if ( IsDefined( self.target ) ) {
|
||||
tgtModels = GetEntArray( self.target, "targetname" );
|
||||
if ( isDefined( tgtModels ) )
|
||||
{
|
||||
foreach ( tgtModel in tgtModels )
|
||||
{
|
||||
if ( tgtModel.classname == "light_omni" || tgtModel.classname == "light_spot" )
|
||||
tgtModel SetLightIntensity( 0 );
|
||||
else
|
||||
tgtModel Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
destructible_scripts/toy_tv_video_monitor.gsc
Normal file
8
destructible_scripts/toy_tv_video_monitor.gsc
Normal file
@ -0,0 +1,8 @@
|
||||
#include common_scripts\_destructible;
|
||||
#include destructible_scripts\toy_tv_flatscreen;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
toy_tvs_flatscreen_cinematic( "tv_video_monitor", ::RemoveTargetted );
|
||||
}
|
20
destructible_scripts/toy_wall_fan.gsc
Normal file
20
destructible_scripts/toy_wall_fan.gsc
Normal file
@ -0,0 +1,20 @@
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// wall fan
|
||||
//---------------------------------------------------------------------
|
||||
destructible_create( "toy_wall_fan", "tag_swivel", 0, undefined, 32 );
|
||||
destructible_anim( %wall_fan_rotate, #animtree, "setanimknob", undefined, undefined, "wall_fan_rotate" );
|
||||
destructible_loopsound( "wall_fan_fanning" );
|
||||
destructible_state( "tag_wobble", "cs_wallfan1", 150 );
|
||||
destructible_anim( %wall_fan_stop, #animtree, "setanimknob", undefined, undefined, "wall_fan_wobble" );
|
||||
destructible_fx( "tag_fx", "fx/explosions/wallfan_explosion_dmg" );
|
||||
destructible_sound( "wall_fan_sparks" );
|
||||
destructible_state( "tag_wobble", "cs_wallfan1", 150, undefined, "no_melee" );
|
||||
destructible_fx( "tag_fx", "fx/explosions/wallfan_explosion_des" );
|
||||
destructible_sound( "wall_fan_break" );
|
||||
destructible_state( undefined, "cs_wallfan1_dmg", undefined, undefined, "no_melee" );
|
||||
}
|
120
destructible_scripts/vehicle_pickup.gsc
Normal file
120
destructible_scripts/vehicle_pickup.gsc
Normal file
@ -0,0 +1,120 @@
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// White Pickup Truck
|
||||
//---------------------------------------------------------------------
|
||||
destructible_create( "vehicle_pickup", "tag_body", 300, undefined, 32, "no_melee" );
|
||||
//destructible_splash_damage_scaler( 18 );
|
||||
destructible_loopfx( "tag_hood_fx", "fx/smoke/car_damage_whitesmoke", 0.4 );
|
||||
destructible_state( undefined, undefined, 200, undefined, 32, "no_melee" );
|
||||
destructible_loopfx( "tag_hood_fx", "fx/smoke/car_damage_blacksmoke", 0.4 );
|
||||
destructible_state( undefined, undefined, 100, undefined, 32, "no_melee" );
|
||||
destructible_loopfx( "tag_hood_fx", "fx/smoke/car_damage_blacksmoke_fire", 0.4 );
|
||||
destructible_sound( "fire_vehicle_flareup_med" );
|
||||
destructible_loopsound( "fire_vehicle_med" );
|
||||
destructible_healthdrain( 15, 0.25, 210, "allies" );
|
||||
destructible_state( undefined, undefined, 300, "player_only", 32, "no_melee" );
|
||||
destructible_loopsound( "fire_vehicle_med" );
|
||||
destructible_state( undefined, undefined, 400, undefined, 32, "no_melee" );
|
||||
destructible_fx( "tag_death_fx", "fx/explosions/small_vehicle_explosion", false );
|
||||
destructible_sound( "car_explode" );
|
||||
destructible_explode( 4000, 5000, 210, 250, 50, 300, undefined, undefined, 0.3, 500 );
|
||||
destructible_anim( %vehicle_80s_sedan1_destroy, #animtree, "setanimknob", undefined, undefined, "vehicle_80s_sedan1_destroy" );
|
||||
destructible_state( undefined, "vehicle_pickup_destroyed", undefined, 32, "no_melee" );
|
||||
// Hood
|
||||
tag = "tag_hood";
|
||||
destructible_part( tag, "vehicle_pickup_hood", 800, undefined, undefined, undefined, 1.0, 2.5 );
|
||||
// Tires
|
||||
destructible_part( "left_wheel_01_jnt", undefined, 20, undefined, undefined, "no_melee" );
|
||||
destructible_anim( %vehicle_80s_sedan1_flattire_LF, #animtree, "setanim" );
|
||||
destructible_sound( "veh_tire_deflate", "bullet" );
|
||||
destructible_part( "left_wheel_02_jnt", undefined, 20, undefined, undefined, "no_melee" );
|
||||
destructible_anim( %vehicle_80s_sedan1_flattire_LB, #animtree, "setanim" );
|
||||
destructible_sound( "veh_tire_deflate", "bullet" );
|
||||
destructible_part( "right_wheel_01_jnt", undefined, 20, undefined, undefined, "no_melee" );
|
||||
destructible_anim( %vehicle_80s_sedan1_flattire_RF, #animtree, "setanim" );
|
||||
destructible_sound( "veh_tire_deflate", "bullet" );
|
||||
destructible_part( "right_wheel_02_jnt", undefined, 20, undefined, undefined, "no_melee" );
|
||||
destructible_anim( %vehicle_80s_sedan1_flattire_RB, #animtree, "setanim" );
|
||||
destructible_sound( "veh_tire_deflate", "bullet" );
|
||||
// Doors
|
||||
destructible_part( "tag_door_left_front", "vehicle_pickup_door_LF", undefined, undefined, undefined, undefined, 1.0, 1.0 );
|
||||
destructible_part( "tag_door_right_front", "vehicle_pickup_door_RF", undefined, undefined, undefined, undefined, 1.0, 1.0 );
|
||||
// Glass ( Front )
|
||||
tag = "tag_glass_front";
|
||||
destructible_part( tag, undefined, 40, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_front_fx", "fx/props/car_glass_large" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Glass ( Back )
|
||||
tag = "tag_glass_back";
|
||||
destructible_part( tag, undefined, 40, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_back_fx", "fx/props/car_glass_large" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Glass ( Left Front )
|
||||
tag = "tag_glass_left_front";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_left_front_fx", "fx/props/car_glass_med" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Glass ( Right Front )
|
||||
tag = "tag_glass_right_front";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_right_front_fx", "fx/props/car_glass_med" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Glass ( Left Back )
|
||||
tag = "tag_glass_left_back";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_left_back_fx", "fx/props/car_glass_med" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Glass ( Right Back )
|
||||
tag = "tag_glass_right_back";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_right_back_fx", "fx/props/car_glass_med" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Head Light ( Left )
|
||||
tag = "tag_light_left_front";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, 0.5 );
|
||||
destructible_fx( tag, "fx/props/car_glass_headlight" );
|
||||
destructible_sound( "veh_glass_break_small" );
|
||||
destructible_state( tag + "_d" );
|
||||
// Head Light ( Right )
|
||||
tag = "tag_light_right_front";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, 0.5 );
|
||||
destructible_fx( tag, "fx/props/car_glass_headlight" );
|
||||
destructible_sound( "veh_glass_break_small" );
|
||||
destructible_state( tag + "_d" );
|
||||
// Tail Light ( Left )
|
||||
tag = "tag_light_left_back";
|
||||
destructible_part( tag, undefined, 20 );
|
||||
destructible_fx( tag, "fx/props/car_glass_brakelight" );
|
||||
destructible_sound( "veh_glass_break_small" );
|
||||
destructible_state( tag + "_d" );
|
||||
// Tail Light ( Right )
|
||||
tag = "tag_light_right_back";
|
||||
destructible_part( tag, undefined, 20 );
|
||||
destructible_fx( tag, "fx/props/car_glass_brakelight" );
|
||||
destructible_sound( "veh_glass_break_small" );
|
||||
destructible_state( tag + "_d" );
|
||||
// Bumpers
|
||||
destructible_part( "tag_bumper_front", undefined, undefined, undefined, undefined, undefined, 1.0, 1.0 );
|
||||
destructible_part( "tag_bumper_back", undefined, undefined, undefined, undefined, undefined, undefined, 1.0 );
|
||||
// Side Mirrors
|
||||
destructible_part( "tag_mirror_left", "vehicle_pickup_mirror_L", 40, undefined, undefined, undefined, undefined, 1.0 );
|
||||
destructible_physics();
|
||||
destructible_part( "tag_mirror_right", "vehicle_pickup_mirror_R", 40, undefined, undefined, undefined, undefined, 1.0 );
|
||||
destructible_physics();
|
||||
}
|
120
destructible_scripts/vehicle_small_hatch.gsc
Normal file
120
destructible_scripts/vehicle_small_hatch.gsc
Normal file
@ -0,0 +1,120 @@
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
vehicle_small_hatch( color )
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// small hatch
|
||||
//---------------------------------------------------------------------
|
||||
destructible_create( "vehicle_small_hatch_" + color, "tag_body", 250, undefined, 32, "no_melee" );
|
||||
//destructible_splash_damage_scaler( 18 );
|
||||
destructible_loopfx( "tag_hood_fx", "fx/smoke/car_damage_whitesmoke", 0.4 );
|
||||
destructible_state( undefined, undefined, 200, undefined, 32, "no_melee" );
|
||||
destructible_loopfx( "tag_hood_fx", "fx/smoke/car_damage_blacksmoke", 0.4 );
|
||||
destructible_state( undefined, undefined, 100, undefined, 32, "no_melee" );
|
||||
destructible_loopfx( "tag_hood_fx", "fx/smoke/car_damage_blacksmoke_fire", 0.4 );
|
||||
destructible_sound( "fire_vehicle_flareup_med" );
|
||||
destructible_loopsound( "fire_vehicle_med" );
|
||||
destructible_healthdrain( 15, 0.25, 150, "allies" );
|
||||
destructible_state( undefined, undefined, 300, "player_only", 32, "no_melee" );
|
||||
destructible_loopsound( "fire_vehicle_med" );
|
||||
destructible_state( undefined, undefined, 400, undefined, 32, "no_melee" );
|
||||
destructible_fx( "tag_death_fx", "fx/explosions/small_vehicle_explosion", false );
|
||||
destructible_sound( "car_explode" );
|
||||
destructible_explode( 4000, 5000, 150, 250, 50, 300, undefined, undefined, 0.3, 500 );
|
||||
destructible_anim( %vehicle_80s_sedan1_destroy, #animtree, "setanimknob", undefined, undefined, "vehicle_80s_sedan1_destroy" );
|
||||
destructible_state( undefined, "vehicle_small_hatch_" + color + "_destroyed", undefined, 32, "no_melee" );
|
||||
// Hood
|
||||
tag = "tag_hood";
|
||||
destructible_part( tag, "vehicle_small_hatch_" + color + "_hood", 800, undefined, undefined, undefined, 1.0, 1.5 );
|
||||
// Tires
|
||||
destructible_part( "left_wheel_01_jnt", undefined, 20, undefined, undefined, "no_melee" );
|
||||
destructible_anim( %vehicle_80s_sedan1_flattire_LF, #animtree, "setanim" );
|
||||
destructible_sound( "veh_tire_deflate", "bullet" );
|
||||
destructible_part( "left_wheel_02_jnt", undefined, 20, undefined, undefined, "no_melee" );
|
||||
destructible_anim( %vehicle_80s_sedan1_flattire_LB, #animtree, "setanim" );
|
||||
destructible_sound( "veh_tire_deflate", "bullet" );
|
||||
destructible_part( "right_wheel_01_jnt", undefined, 20, undefined, undefined, "no_melee" );
|
||||
destructible_anim( %vehicle_80s_sedan1_flattire_RF, #animtree, "setanim" );
|
||||
destructible_sound( "veh_tire_deflate", "bullet" );
|
||||
destructible_part( "right_wheel_02_jnt", undefined, 20, undefined, undefined, "no_melee" );
|
||||
destructible_anim( %vehicle_80s_sedan1_flattire_RB, #animtree, "setanim" );
|
||||
destructible_sound( "veh_tire_deflate", "bullet" );
|
||||
// Doors
|
||||
destructible_part( "tag_door_left_front", "vehicle_small_hatch_" + color + "_door_LF", undefined, undefined, undefined, undefined, 1.0, 1.0 );
|
||||
destructible_part( "tag_door_right_front", "vehicle_small_hatch_" + color + "_door_RF", undefined, undefined, undefined, undefined, 1.0, 1.0 );
|
||||
// Glass ( Front )
|
||||
tag = "tag_glass_front";
|
||||
destructible_part( tag, undefined, 40, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_front_fx", "fx/props/car_glass_large" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Glass ( Back )
|
||||
tag = "tag_glass_back";
|
||||
destructible_part( tag, undefined, 40, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_back_fx", "fx/props/car_glass_large" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Glass ( Left Front )
|
||||
tag = "tag_glass_left_front";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_left_front_fx", "fx/props/car_glass_med" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Glass ( Right Front )
|
||||
tag = "tag_glass_right_front";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_right_front_fx", "fx/props/car_glass_med" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Glass ( Left Back )
|
||||
tag = "tag_glass_left_back";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_left_back_fx", "fx/props/car_glass_med" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Glass ( Right Back )
|
||||
tag = "tag_glass_right_back";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, undefined, undefined, true );
|
||||
destructible_state( tag + "_d", undefined, 60, undefined, undefined, undefined, true );
|
||||
destructible_fx( "tag_glass_right_back_fx", "fx/props/car_glass_med" );
|
||||
destructible_sound( "veh_glass_break_large" );
|
||||
destructible_state( undefined );
|
||||
// Head Light ( Left )
|
||||
tag = "tag_light_left_front";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, 0.5 );
|
||||
destructible_fx( tag, "fx/props/car_glass_headlight" );
|
||||
destructible_sound( "veh_glass_break_small" );
|
||||
destructible_state( tag + "_d" );
|
||||
// Head Light ( Right )
|
||||
tag = "tag_light_right_front";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, 0.5 );
|
||||
destructible_fx( tag, "fx/props/car_glass_headlight" );
|
||||
destructible_sound( "veh_glass_break_small" );
|
||||
destructible_state( tag + "_d" );
|
||||
// Tail Light ( Left )
|
||||
tag = "tag_light_left_back";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, 0.5 );
|
||||
destructible_fx( tag, "fx/props/car_glass_brakelight" );
|
||||
destructible_sound( "veh_glass_break_small" );
|
||||
destructible_state( tag + "_d" );
|
||||
// Tail Light ( Right )
|
||||
tag = "tag_light_right_back";
|
||||
destructible_part( tag, undefined, 20, undefined, undefined, undefined, 0.5 );
|
||||
destructible_fx( tag, "fx/props/car_glass_brakelight" );
|
||||
destructible_sound( "veh_glass_break_small" );
|
||||
destructible_state( tag + "_d" );
|
||||
// Bumpers
|
||||
destructible_part( "tag_bumper_front", undefined, undefined, undefined, undefined, undefined, 1.0 );
|
||||
destructible_part( "tag_bumper_back", undefined, undefined, undefined, undefined, undefined, 0.5 );
|
||||
// Side Mirrors
|
||||
destructible_part( "tag_mirror_left", "vehicle_small_hatch_" + color + "_mirror_L", 40, undefined, undefined, undefined, undefined, 1.0 );
|
||||
destructible_physics();
|
||||
destructible_part( "tag_mirror_right", "vehicle_small_hatch_" + color + "_mirror_R", 40, undefined, undefined, undefined, undefined, 1.0 );
|
||||
destructible_physics();
|
||||
}
|
8
destructible_scripts/vehicle_small_hatch_blue.gsc
Normal file
8
destructible_scripts/vehicle_small_hatch_blue.gsc
Normal file
@ -0,0 +1,8 @@
|
||||
#include destructible_scripts\vehicle_small_hatch;
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
vehicle_small_hatch( "blue" );
|
||||
}
|
8
destructible_scripts/vehicle_small_hatch_white.gsc
Normal file
8
destructible_scripts/vehicle_small_hatch_white.gsc
Normal file
@ -0,0 +1,8 @@
|
||||
#include destructible_scripts\vehicle_small_hatch;
|
||||
#include common_scripts\_destructible;
|
||||
#using_animtree( "destructibles" );
|
||||
|
||||
main()
|
||||
{
|
||||
vehicle_small_hatch( "white" );
|
||||
}
|
22
maps/animated_models/com_roofvent2.gsc
Normal file
22
maps/animated_models/com_roofvent2.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "com_roofvent2_animated";
|
||||
if ( SP )
|
||||
{
|
||||
level.anim_prop_models[ model ][ "rotate" ] = %roofvent_rotate;
|
||||
}
|
||||
else
|
||||
level.anim_prop_models[ model ][ "rotate" ] = "roofvent_rotate";
|
||||
}
|
16
maps/animated_models/foliage_pacific_bushtree01.gsc
Normal file
16
maps/animated_models/foliage_pacific_bushtree01.gsc
Normal file
@ -0,0 +1,16 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
model = "foliage_pacific_bushtree01_animated";
|
||||
if ( isSp() )
|
||||
{
|
||||
level.anim_prop_models[ model ][ "sway" ] = %foliage_pacific_bushtree01_sway;
|
||||
}
|
||||
else
|
||||
level.anim_prop_models[ model ][ "sway" ] = "foliage_pacific_bushtree01_sway";
|
||||
}
|
14
maps/animated_models/hanging_apron_wind_medium.gsc
Normal file
14
maps/animated_models/hanging_apron_wind_medium.gsc
Normal file
@ -0,0 +1,14 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
model = "clothes_line_tank_iw6";
|
||||
if ( isSP() )
|
||||
level.anim_prop_models[ model ][ "wind_medium" ] = %hanging_clothes_apron_wind_medium;
|
||||
else
|
||||
level.anim_prop_models[ model ][ "wind_medium" ] = "hanging_clothes_apron_wind_medium";
|
||||
}
|
14
maps/animated_models/hanging_longsleeve_wind_medium.gsc
Normal file
14
maps/animated_models/hanging_longsleeve_wind_medium.gsc
Normal file
@ -0,0 +1,14 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
model = "clothes_line_sweater_iw6";
|
||||
if ( isSP() )
|
||||
level.anim_prop_models[ model ][ "wind_medium" ] = %hanging_clothes_long_sleeve_wind_medium;
|
||||
else
|
||||
level.anim_prop_models[ model ][ "wind_medium" ] = "hanging_clothes_long_sleeve_wind_medium";
|
||||
}
|
14
maps/animated_models/hanging_sheet_wind_medium.gsc
Normal file
14
maps/animated_models/hanging_sheet_wind_medium.gsc
Normal file
@ -0,0 +1,14 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
model = "clothes_line_sheet_iw6";
|
||||
if ( isSP() )
|
||||
level.anim_prop_models[ model ][ "wind_medium" ] = %hanging_clothes_sheet_wind_medium;
|
||||
else
|
||||
level.anim_prop_models[ model ][ "wind_medium" ] = "hanging_clothes_sheet_wind_medium";
|
||||
}
|
14
maps/animated_models/hanging_shortsleeve_wind_medium.gsc
Normal file
14
maps/animated_models/hanging_shortsleeve_wind_medium.gsc
Normal file
@ -0,0 +1,14 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
model = "clothes_line_tshirt_iw6";
|
||||
if ( isSP() )
|
||||
level.anim_prop_models[ model ][ "wind_medium" ] = %hanging_clothes_short_sleeve_wind_medium;
|
||||
else
|
||||
level.anim_prop_models[ model ][ "wind_medium" ] = "hanging_clothes_short_sleeve_wind_medium";
|
||||
}
|
22
maps/animated_models/mp_flooded_water_debris_bob.gsc
Normal file
22
maps/animated_models/mp_flooded_water_debris_bob.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "debris_water_trash";
|
||||
if ( SP )
|
||||
{
|
||||
level.anim_prop_models[ model ][ "debris_water_trash" ] = %debris_water_trash_bob_anim;
|
||||
}
|
||||
else
|
||||
level.anim_prop_models[ model ][ "debris_water_trash" ] = "debris_water_trash_bob_anim";
|
||||
}
|
23
maps/animated_models/mp_flooded_water_debris_spiral.gsc
Normal file
23
maps/animated_models/mp_flooded_water_debris_spiral.gsc
Normal file
@ -0,0 +1,23 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "debris_water_trash";
|
||||
if ( SP )
|
||||
{
|
||||
level.anim_prop_models[ model ][ "debris_water_trash" ] = %debris_water_trash_spiral_anim;
|
||||
}
|
||||
else
|
||||
level.anim_prop_models[ model ][ "debris_water_trash" ] = "debris_water_trash_spiral_anim";
|
||||
}
|
||||
|
23
maps/animated_models/mp_flooded_water_street.gsc
Normal file
23
maps/animated_models/mp_flooded_water_street.gsc
Normal file
@ -0,0 +1,23 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "mp_flooded_street_water";
|
||||
if ( SP )
|
||||
{
|
||||
level.anim_prop_models[ model ][ "mp_flooded_street_water" ] = %mp_flooded_street_water_anim;
|
||||
}
|
||||
else
|
||||
level.anim_prop_models[ model ][ "mp_flooded_street_water" ] = "mp_flooded_street_water_anim";
|
||||
}
|
||||
|
16
maps/animated_models/mp_frag_crane.gsc
Normal file
16
maps/animated_models/mp_frag_crane.gsc
Normal file
@ -0,0 +1,16 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
model = "mp_frag_crane_anim";
|
||||
if ( isSP() )
|
||||
{
|
||||
level.anim_prop_models[ model ][ "idle" ] = %mp_frag_crane_sway;
|
||||
}
|
||||
else
|
||||
level.anim_prop_models[ model ][ "idle" ] = "mp_frag_crane_sway";
|
||||
}
|
23
maps/animated_models/wire_hanging_192long.gsc
Normal file
23
maps/animated_models/wire_hanging_192long.gsc
Normal file
@ -0,0 +1,23 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level.anim_prop_models ) )
|
||||
level.anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "prop_wire_hanging_192long";
|
||||
if ( SP )
|
||||
{
|
||||
level.anim_prop_models[ model ][ "self.wind" ] = %prop_wire_hanging_192long_wind1;
|
||||
}
|
||||
else
|
||||
level.anim_prop_models[ model ][ "self.wind" ] = "prop_wire_hanging_192long_wind1";
|
||||
}
|
||||
|
11
maps/createart/mp_alien_town_art.gsc
Normal file
11
maps/createart/mp_alien_town_art.gsc
Normal file
@ -0,0 +1,11 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_alien_town_fog::main;
|
||||
//* Fog section *
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
//setExpFog( 0, 5211.68, 0.627451, 0.717647, 0.745098, 0.38927, 0, 0.838639, 0.691254, 0.567937, (0.00390755, 0.00323934, -1), 83.5416, 92.7872, 2.25266 );
|
||||
//VisionSetNaked( "mp_alien_town", 0 );
|
||||
|
||||
}
|
10
maps/createart/mp_battery3_art.gsc
Normal file
10
maps/createart/mp_battery3_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_battery3_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 7346.26, 10487.6, 0.583682, 0.52939, 0.302793, 1, 1, 0, 0, 0, 0 );
|
||||
VisionSetNaked( "mp_battery3", 0 );
|
||||
}
|
10
maps/createart/mp_boneyard_ns_art.gsc
Normal file
10
maps/createart/mp_boneyard_ns_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_boneyard_ns_fog::main;
|
||||
//* Fog section *
|
||||
|
||||
VisionSetNaked( "mp_boneyard_ns", 0 );
|
||||
|
||||
}
|
10
maps/createart/mp_ca_behemoth_art.gsc
Normal file
10
maps/createart/mp_ca_behemoth_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_ca_behemoth_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 0, 34658, 0.423529, 0.490196, 0.666667, 0.88, 0.776167, 0, 0.482353, 0.458824, 0.4, 2.3, (0, 0, -1), 0, 135, 10, 0.901, 180, 113 );
|
||||
VisionSetNaked( "mp_ca_behemoth", 0 );
|
||||
}
|
10
maps/createart/mp_ca_impact_art.gsc
Normal file
10
maps/createart/mp_ca_impact_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_ca_impact_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 3026.57, 1163.94, 0.711328, 0.78437, 0.798145, 0.793067, 0.811095, 0, 1, -0.538688, 90 );
|
||||
VisionSetNaked( "mp_ca_impact", 0 );
|
||||
}
|
10
maps/createart/mp_ca_red_river_art.gsc
Normal file
10
maps/createart/mp_ca_red_river_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_ca_red_river_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 7220, 1084, 0.901961, 0.917647, 0.843137, 1, 0.2094, 0, 0, 0, 90 );
|
||||
VisionSetNaked( "mp_ca_red_river", 0 );
|
||||
}
|
10
maps/createart/mp_ca_rumble_art.gsc
Normal file
10
maps/createart/mp_ca_rumble_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_ca_rumble_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 562.278, 5000, 0.685692, 0.564965, 0.436857, 1, 0.60214, 0, 0, 0, 90 );
|
||||
VisionSetNaked( "mp_ca_rumble", 0 );
|
||||
}
|
14
maps/createart/mp_chasm_art.gsc
Normal file
14
maps/createart/mp_chasm_art.gsc
Normal file
@ -0,0 +1,14 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_chasm_fog::main;
|
||||
|
||||
//* Fog section *
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
|
||||
// setExpFog( 0, 5211.68, 0.480657, 0.755661, 0.785471, 2.01908, 0, 0, 0, 0, 0 );
|
||||
VisionSetNaked( "mp_chasm", 0 );
|
||||
|
||||
}
|
10
maps/createart/mp_conflict_art.gsc
Normal file
10
maps/createart/mp_conflict_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_conflict_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 0, 1958.84, 0.656882, 0.680657, 0.696267, 2, 0.90625, 0, 0.396688, 0.396688, 0.396619, 0.5, (0, 0, -1), 80, 105, 0.0625, 0.960938, 0, 54 );
|
||||
VisionSetNaked( "mp_conflict", 0 );
|
||||
}
|
10
maps/createart/mp_dart_art.gsc
Normal file
10
maps/createart/mp_dart_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_dart_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 200, 3500, 0.54, 0.54, 0.54, 1, 0.75, 0, 0.92, 0.69, 0.44, 1, (-0.27, -0.86, 0.4), 15, 60, 2.25, 1, 61, 85 );
|
||||
VisionSetNaked( "mp_dart", 0 );
|
||||
}
|
13
maps/createart/mp_descent_new_art.gsc
Normal file
13
maps/createart/mp_descent_new_art.gsc
Normal file
@ -0,0 +1,13 @@
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_descent_new_fog::main;
|
||||
|
||||
//* Fog section *
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
|
||||
// setExpFog( 0, 5211.68, 0.480657, 0.755661, 0.785471, 2.01908, 0, 0, 0, 0, 0 );
|
||||
VisionSetNaked( "mp_descent_new", 0 );
|
||||
|
||||
}
|
11
maps/createart/mp_dig_art.gsc
Normal file
11
maps/createart/mp_dig_art.gsc
Normal file
@ -0,0 +1,11 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_dig_fog::main;
|
||||
//* Fog section *
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 0, 5211.68, 0.627451, 0.717647, 0.745098, 0.38927, 0, 0.838639, 0.691254, 0.567937, (0.00390755, 0.00323934, -1), 83.5416, 92.7872, 2.25266 );
|
||||
VisionSetNaked( "mp_dig", 0 );
|
||||
|
||||
}
|
16
maps/createart/mp_dome_ns_art.gsc
Normal file
16
maps/createart/mp_dome_ns_art.gsc
Normal file
@ -0,0 +1,16 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_dome_ns_fog::main;
|
||||
//* Fog section *
|
||||
//setDevDvar( "scr_fog_disable", "0" );
|
||||
//setExpFog( 0, 5211.68, 0.627451, 0.717647, 0.745098, 0.38927, 0, 0.838639, 0.691254, 0.567937, (0.00390755, 0.00323934, -1), 83.5416, 92.7872, 2.25266 );
|
||||
VisionSetNaked( "mp_dome_ns", 0 );
|
||||
|
||||
|
||||
|
||||
//setdvar_cg_ng("r_specularColorScale", 3, 8.5);
|
||||
|
||||
|
||||
}
|
10
maps/createart/mp_fahrenheit_art.gsc
Normal file
10
maps/createart/mp_fahrenheit_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_fahrenheit_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 624.344, 2914.77, 0.53, 0.52, 0.57, 1, 1, 0, 0.84, 0.77, 0.67, 1, (-0.79, 0.17, 0.57), 0, 80.7, 0.9, 1, 23.32, 89.58 );
|
||||
VisionSetNaked( "mp_fahrenheit", 0 );
|
||||
}
|
11
maps/createart/mp_favela_iw6_art.gsc
Normal file
11
maps/createart/mp_favela_iw6_art.gsc
Normal file
@ -0,0 +1,11 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_favela_iw6_fog::main;
|
||||
//* Fog section *
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 0, 5211.68, 0.627451, 0.717647, 0.745098, 0.38927, 0, 0.838639, 0.691254, 0.567937, (0.00390755, 0.00323934, -1), 83.5416, 92.7872, 2.25266 );
|
||||
VisionSetNaked( "mp_favela_iw6", 0 );
|
||||
|
||||
}
|
10
maps/createart/mp_flooded_art.gsc
Normal file
10
maps/createart/mp_flooded_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_flooded_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 600, 1600, 0.721569, 0.823529, 0.929412, 1, 0.314067, 0, 0, 0, 90 );
|
||||
VisionSetNaked( "mp_flooded", 0 );
|
||||
}
|
10
maps/createart/mp_frag_art.gsc
Normal file
10
maps/createart/mp_frag_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_frag_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 1500, 6145, 0.8, 0.88, 1, 1, 0.25, 0, 1, 1, 0.94, 1.06, (0.76, 0.38, 0.51), 0, 100, 1, 1, 60, 85 );
|
||||
VisionSetNaked( "mp_frag", 0 );
|
||||
}
|
10
maps/createart/mp_hashima_art.gsc
Normal file
10
maps/createart/mp_hashima_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_hashima_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 1536, 10241, 0, 0.705811, 0.921875, 1, 0.5, 0, 0.757813, 0.607019, 0.363672, 1, (0.097, -0.031, -0.375), 55, 180, 2.5, 1, 60, 80 );
|
||||
VisionSetNaked( "mp_hashima", 0 );
|
||||
}
|
10
maps/createart/mp_lonestar_art.gsc
Normal file
10
maps/createart/mp_lonestar_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_lonestar_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 512, 7760.62, 0.5, 0.5, 0.5, 0.75, 0.859375, 0, 0.328125, 0.328125, 0.328125, 1, (0, 0, 1), 64, 91, 0.5, 1, 54, 82 );
|
||||
VisionSetNaked( "mp_lonestar", 0 );
|
||||
}
|
10
maps/createart/mp_mine_art.gsc
Normal file
10
maps/createart/mp_mine_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_mine_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 122.24, 25282, 0.846864, 0.748939, 0.5479, 1, 1, 0, 0, 0, 0 );
|
||||
VisionSetNaked( "mp_mine", 0 );
|
||||
}
|
10
maps/createart/mp_pirate_art.gsc
Normal file
10
maps/createart/mp_pirate_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_pirate_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 0, 1, 0.109, 0.113, 0.124, 0.807, 1, 0, 1, 30, 90 );
|
||||
VisionSetNaked( "mp_pirate", 0 );
|
||||
}
|
11
maps/createart/mp_prisonbreak_art.gsc
Normal file
11
maps/createart/mp_prisonbreak_art.gsc
Normal file
@ -0,0 +1,11 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_prisonbreak_fog::main;
|
||||
//* Fog section *
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
//setExpFog( 1400, 40500, 0.92, 0.99, 1.0, 0.22, 1, 0.64, 0.50, 0.50, (0.98, 0.09, 0.1), 0, 80.0, 5.0 );
|
||||
VisionSetNaked( "mp_prisonbreak", 0 );
|
||||
|
||||
}
|
9
maps/createart/mp_shipment_ns_art.gsc
Normal file
9
maps/createart/mp_shipment_ns_art.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_shipment_ns_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", 0 );
|
||||
VisionSetNaked( "mp_shipment_ns", 0 );
|
||||
}
|
10
maps/createart/mp_skeleton_art.gsc
Normal file
10
maps/createart/mp_skeleton_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_skeleton_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 575.658, 5181.9, 0.899167, 0.930833, 1, 3.42928, 0.619243, 0, 1, 78.972, 92.2944 );
|
||||
VisionSetNaked( "mp_skeleton", 0 );
|
||||
}
|
10
maps/createart/mp_snow_art.gsc
Normal file
10
maps/createart/mp_snow_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_snow_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 714.363, 7073.18, 0.345189, 0.457268, 0.453545, 1, 0.55, 0, 0.608505, 0.999996, 0.828083, 1, (0.12, -0.03, 0.99), 0, 55, 0.38, 1, 67.2161, 92.6819 );
|
||||
VisionSetNaked( "mp_snow", 0 );
|
||||
}
|
15
maps/createart/mp_sovereign_art.gsc
Normal file
15
maps/createart/mp_sovereign_art.gsc
Normal file
@ -0,0 +1,15 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_sovereign_fog::main;
|
||||
|
||||
//* Fog section *
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
|
||||
//setExpFog( 650, 2049, 0.352941, 0.411765, 0.478431, 1, 0.5, 0, 1, 0.854902, 0.74902, 1, (0.00390755, 0.00323934, -1), 61, 93.7872, 0.25 );
|
||||
VisionSetNaked( "mp_sovereign", 0 );
|
||||
|
||||
}
|
10
maps/createart/mp_strikezone_art.gsc
Normal file
10
maps/createart/mp_strikezone_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_strikezone_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 525.762, 18137.9, 0.62, 0.81, 0.81, 1.4, 1, 0, 0.99, 0.97, 0.83, 1.2, (-0.05, -0.89, 0.44), 0, 100, 0.9, 1, 13.7392, 117.129 );
|
||||
VisionSetNaked( "mp_strikezone", 0 );
|
||||
}
|
10
maps/createart/mp_swamp_art.gsc
Normal file
10
maps/createart/mp_swamp_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_swamp_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 0, 2985.05, 0.339273, 0.302975, 0.400243, 1, 0.485193, 0, 0, 0, 0 );
|
||||
VisionSetNaked( "mp_swamp", 0 );
|
||||
}
|
10
maps/createart/mp_warhawk_art.gsc
Normal file
10
maps/createart/mp_warhawk_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_warhawk_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 1307.29, 8178.08, 0.888789, 0.851156, 0.664851, 1.07658, 0.468766, 0, 0.639683, 0.464798, 0.346012, 0.573353, (0.89, 0.06, 0.44), 0, 137, 2.40463, 0.730742, 26.9803, 63.638 );
|
||||
VisionSetNaked( "mp_warhawk", 0 );
|
||||
}
|
10
maps/createart/mp_zebra_art.gsc
Normal file
10
maps/createart/mp_zebra_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_zebra_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 371.287, 7055.43, 0.395946, 0.358963, 0.352442, 0.742574, 0.919554, 0, 0, 0, 0 );
|
||||
VisionSetNaked( "mp_zebra", 0 );
|
||||
}
|
12
maps/createart/mp_zerosub_art.gsc
Normal file
12
maps/createart/mp_zerosub_art.gsc
Normal file
@ -0,0 +1,12 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_zerosub_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 0, 2985.05, 0.339273, 0.302975, 0.400243, 1, 0.485193, 0, 0, 0, 0 );
|
||||
VisionSetNaked( "mp_zerosub", 0 );
|
||||
}
|
||||
|
||||
|
10
maps/createart/mp_zulu_art.gsc
Normal file
10
maps/createart/mp_zulu_art.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
// _createart generated. modify at your own risk. Changing values should be fine.
|
||||
main()
|
||||
{
|
||||
level.tweakfile = true;
|
||||
level.parse_fog_func = maps\createart\mp_zulu_fog::main;
|
||||
|
||||
setDevDvar( "scr_fog_disable", "0" );
|
||||
// setExpFog( 7346.26, 10487.6, 0.583682, 0.52939, 0.302793, 1, 1, 0, 0, 0, 0 );
|
||||
VisionSetNaked( "mp_zulu", 0 );
|
||||
}
|
1230
maps/interactive_models/_birds_dlc.gsc
Normal file
1230
maps/interactive_models/_birds_dlc.gsc
Normal file
File diff suppressed because it is too large
Load Diff
664
maps/interactive_models/_interactive_utility.gsc
Normal file
664
maps/interactive_models/_interactive_utility.gsc
Normal file
@ -0,0 +1,664 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: delete_on_notify( <ent>, <notify1>, <notify2>, <notify3> )"
|
||||
"Summary: Just like delete_on_death, but takes up to 3 strings. Notifying any of the strings will result in ent being deleted."
|
||||
"Module: Entity"
|
||||
"CallOn: An entity"
|
||||
"MandatoryArg: <ent>: The entity to be deleted"
|
||||
"OptionalArg: <notify1>: Strings on the called-on-entity that you want to listen for."
|
||||
"Example: self thread delete_on_notify( trigger, "death", "damage" );"
|
||||
"SPMP: both"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
delete_on_notify( ent, notify1, notify2, notify3 )
|
||||
{
|
||||
//self ==> the entity you want to wait for a notify on before deleting the ent
|
||||
ent endon( "death" );
|
||||
self waittill_any( notify1, notify2, notify3 );
|
||||
if ( IsDefined( ent ) )
|
||||
ent Delete();
|
||||
}
|
||||
|
||||
// array_sortByArray - given an array, and another array of equal size containing a value to sort on, returns a copy of the first array, sorted.
|
||||
// Not optimized. O(n^2), I think.
|
||||
array_sortByArray( array, sorters )
|
||||
{
|
||||
newArray = [];
|
||||
newArray[0] = array[0];
|
||||
newSorters = [];
|
||||
newSorters[0] = sorters[0];
|
||||
for ( i=1; i<array.size; i++ )
|
||||
{
|
||||
sorted = false;
|
||||
for ( j=0; j<newArray.size; j++ )
|
||||
{
|
||||
if ( sorters[i] < newSorters[j] )
|
||||
{
|
||||
for ( k=newArray.size-1; k>=j; k-- )
|
||||
{
|
||||
newArray[ k+1 ] = newArray[ k ];
|
||||
newSorters[ k+1 ] = newSorters[ k ];
|
||||
}
|
||||
newArray[ j ] = array[ i ];
|
||||
newSorters[ j ] = sorters[ i ];
|
||||
sorted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !sorted )
|
||||
{
|
||||
newArray[ i ] = array[ i ];
|
||||
newSorters[ i ] = sorters[ i ];
|
||||
}
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
|
||||
// array_sortBySorter - given an array of structs, each of which contains a field named "sorter", returns a copy of the array, sorted.
|
||||
// Notes:
|
||||
// Not optimized. O(n^2), I think.
|
||||
// Does not copy the structs. Copies the array but references the original structs.
|
||||
array_sortBySorter( array )
|
||||
{
|
||||
newArray = [];
|
||||
newArray[0] = array[0];
|
||||
for ( i=1; i<array.size; i++ )
|
||||
{
|
||||
sorted = false;
|
||||
for ( j=0; j<newArray.size; j++ )
|
||||
{
|
||||
if ( array[i].sorter < newArray[j].sorter )
|
||||
{
|
||||
for ( k=newArray.size-1; k>=j; k-- )
|
||||
{
|
||||
newArray[ k+1 ] = newArray[ k ];
|
||||
}
|
||||
newArray[ j ] = array[ i ];
|
||||
sorted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !sorted )
|
||||
{
|
||||
newArray[ i ] = array[ i ];
|
||||
}
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: wait_then_fn( <notifyStr>, <fn>, <arg1>, <arg2>, <arg3> )"
|
||||
"Summary: Waits for a notify or a time, then calls the specified function with specified args."
|
||||
"Module: "
|
||||
"CallOn: Entity"
|
||||
"MandatoryArg: <notifyStr> : String to notify or time to wait"
|
||||
"MandatoryArg: <enders>: String (or array of strings) to kill the thread. Can be undefined."
|
||||
"MandatoryArg: <fn> : pointer to a script function"
|
||||
"OptionalArg: <arg1> : parameter 1 to pass to the process"
|
||||
"OptionalArg: <arg2> : parameter 2 to pass to the process"
|
||||
"OptionalArg: <arg3> : parameter 3 to pass to the process"
|
||||
"OptionalArg: <arg4> : parameter 4 to pass to the process"
|
||||
"Example: fish1 thread wait_then_fn( "path_complete", ::arriveAtLocation, false );"
|
||||
"SPMP: both"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
wait_then_fn( notifyStr, enders, fn, arg1, arg2, arg3, arg4 )
|
||||
{
|
||||
self endon( "death" );
|
||||
if ( IsDefined( enders ) ) {
|
||||
if ( IsArray( enders ) ) {
|
||||
foreach ( ender in enders )
|
||||
{
|
||||
self endon( ender );
|
||||
}
|
||||
} else {
|
||||
self endon( enders );
|
||||
}
|
||||
}
|
||||
if ( isString( notifyStr ) )
|
||||
self waittill( notifyStr );
|
||||
else // Assume it's a time
|
||||
wait ( notifyStr );
|
||||
if ( IsDefined( arg4 ) )
|
||||
self [[ fn ]]( arg1, arg2, arg3, arg4 );
|
||||
else if ( IsDefined( arg3 ) )
|
||||
self [[ fn ]]( arg1, arg2, arg3 );
|
||||
else if ( IsDefined( arg2 ) )
|
||||
self [[ fn ]]( arg1, arg2 );
|
||||
else if ( IsDefined( arg1 ) )
|
||||
self [[ fn ]]( arg1 );
|
||||
else
|
||||
self [[ fn ]]();
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: waittill_notify ( <waitStr> , <notifyEnt> , <notifyStr> , <ender> )"
|
||||
"Summary: Wait for a notify on one ent and then notify another ent."
|
||||
"Module: Entity"
|
||||
"CallOn: An entity"
|
||||
"MandatoryArg: <waitStr>: String to wait for."
|
||||
"MandatoryArg: <notifyEnt>: Entity to notify."
|
||||
"MandatoryArg: <notifyStr>: String to notify."
|
||||
"OptionalArg: <ender>: String that will end this thread."
|
||||
"OptionalArg: <multiple>: Continue waiting for more notifies after the first one. Defaults to false."
|
||||
"Example: waittill_notify ( "trigger", self, trigger.script_triggername );"
|
||||
"SPMP: singleplayer"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
|
||||
waittill_notify ( waitStr, notifyEnt, notifyStr, ender, multiple )
|
||||
{
|
||||
if ( !isDefined( multiple ) ) multiple = false;
|
||||
doItAgain = true;
|
||||
while ( doItAgain )
|
||||
{
|
||||
self endon( "death" );
|
||||
if ( IsDefined( ender ) ) self endon( ender );
|
||||
self waittill( waitStr );
|
||||
notifyEnt notify( notifyStr );
|
||||
doItAgain = multiple;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: loop_anim( <animArray> , <animName> , <ender> )"
|
||||
"Summary: Plays an animation or a group of animations over and over until notified. A very simple alternative to anim_loop_solo. Takes the animations as a parameter, so you don't need to set the model up in level.scr_anim."
|
||||
"Module: Anim"
|
||||
"CallOn: An entity"
|
||||
"MandatoryArg: <animArray>: An array. Can contain animations, arrays of animations and animweights (just like those found in level.scr_anim[animname])."
|
||||
"MandatoryArg: <animName>: The animation index in the array, just like anime in anim_loop_solo."
|
||||
"OptionalArg: <ender>: Notify string"
|
||||
"OptionalArg: <animRate>: Playback speed for the animation. Defaults to 1."
|
||||
"Example: "
|
||||
"SPMP: singleplayer"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
loop_anim( animArray, animName, ender, animRate )
|
||||
{
|
||||
self endon( "death" );
|
||||
if ( IsDefined( ender ) ) self endon( ender );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
a = self single_anim( animArray, animName, "loop_anim", false, animRate );
|
||||
if ( isSP() ) {
|
||||
self waittillmatch( "loop_anim", "end" );
|
||||
} else {
|
||||
wait GetAnimLength( a );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: single_anim( <animArray> , <animName> , <notifyStr> , <restartAnim> )"
|
||||
"Summary: Plays an animation or a group of animations. Similar to (but much simpler than) anim_single_solo. Takes the animations as a parameter, so you don't need to set the model up in level.scr_anim. Returns the animation chosen, so you can check the length or whatever."
|
||||
"Module: Anim"
|
||||
"CallOn: An entity"
|
||||
"MandatoryArg: <animArray>: An array. Can contain animations, arrays of animations and weights (just like those found in level.scr_anim[animname]). Can also contain mp animations (strings) using the suffix "mp"."
|
||||
"MandatoryArg: <animName>: The animation index in the array, just like anime in anim_loop_solo."
|
||||
"OptionalArg: <notifyStr>: String that the animation will notify for notetracks and when finished. Defaults to single_anim. SP only."
|
||||
"OptionalArg: <restartAnim>: Set to true to force the animation to start from the beginning, otherwise it will simply continue if it is already playing. Defaults to false. SP only."
|
||||
"OptionalArg: <animRate>: Playback speed for the animation. Defaults to 1. SP only."
|
||||
"Example: "
|
||||
"SPMP: both"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
|
||||
single_anim( animArray, animName, notifyStr, restartAnim, animRate )
|
||||
{
|
||||
if ( !IsDefined( notifyStr ) ) notifyStr = "single_anim";
|
||||
if ( !IsDefined( animRate ) ) animRate = 1;
|
||||
|
||||
if ( IsArray( animArray[ animName ] ) )
|
||||
{
|
||||
//AssertEx( IsDefined( animArray[ ( animName + "weight" ) ] ) , "Array of anims labeled \""+animName+"\" does not have associated \""+animName+"weight\" array." );
|
||||
if ( !IsDefined( animArray[ ( animName + "weight" ) ] ) )
|
||||
{
|
||||
animArray[ ( animName + "weight" ) ] = [];
|
||||
keys = GetArrayKeys( animArray[ animName ] );
|
||||
foreach ( key in keys )
|
||||
{
|
||||
animArray[ ( animName + "weight" ) ][ key ] = 1;
|
||||
}
|
||||
}
|
||||
AssertEx( IsArray( animArray[ ( animName + "weight" ) ] ) , "Array of anim weights labeled \""+animName+"weight\" is not an array." );
|
||||
AssertEx( animArray[ ( animName + "weight" ) ].size == animArray[ animName ].size, "Array of anims labeled \""+animName+"\" does not have a matching array of weights." );
|
||||
numAnims = animArray[ animName ].size;
|
||||
totalWeight = 0;
|
||||
for ( i = 0; i < numAnims; i++ )
|
||||
{
|
||||
totalWeight += animArray[ ( animName + "weight" ) ][ i ];
|
||||
}
|
||||
rand = RandomFloat( totalWeight );
|
||||
runningWeight = 0;
|
||||
sel = -1;
|
||||
while ( runningWeight <= rand )
|
||||
{
|
||||
sel++;
|
||||
runningWeight += animArray[ ( animName + "weight" ) ][ sel ];
|
||||
}
|
||||
animation = animArray[ animName ][ sel ];
|
||||
if ( IsDefined( animArray[ animName + "mp" ] ) ) {
|
||||
animation_mp = animArray[ animName + "mp" ][ sel ];
|
||||
} else {
|
||||
animation_mp = undefined;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
animation = animArray[ animName ];
|
||||
animation_mp = animArray[ animName + "mp" ];
|
||||
}
|
||||
if ( isSP() ) {
|
||||
if ( IsDefined( restartAnim) && restartAnim )
|
||||
self call [[ level.func[ "setflaggedanimknobrestart" ] ]]( notifyStr, animation, 1, 0.1, animRate );
|
||||
else
|
||||
self call [[ level.func[ "setflaggedanimknob" ] ]]( notifyStr, animation, 1, 0.1, animRate );
|
||||
} else {
|
||||
self call [[ level.func[ "scriptModelPlayAnim" ] ]]( animation_mp );
|
||||
}
|
||||
return animation;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: blendAnimsBySpeed( <speed> , <anims> , <animSpeeds>, <animLengths> )"
|
||||
"Summary: Only blends in SPBlends between animations in an array according to the speed parameter. Keeps all animations playing in sync (without using loopsync in the animtree). Note: uses SetAnimLimited, so be sure to set the parent node in the animtree separately."
|
||||
"Module: Anim"
|
||||
"CallOn: An entity"
|
||||
"MandatoryArg: <speed>: The number to be compared to the values in animSpeeds."
|
||||
"MandatoryArg: <anims>: Array of animations."
|
||||
"MandatoryArg: <anims>: Array of speeds that correspond to the animations."
|
||||
"MandatoryArg: <animLengths>: Array of lengths of the animations, to save it having to be calculated every time the function is called."
|
||||
"OptionalArg: <blendTime>: Blend time used as a parameter to SetAnim."
|
||||
"Example: "
|
||||
"SPMP: both"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
blendAnimsBySpeed( speed, anims, animSpeeds, animLengths, blendTime )
|
||||
{
|
||||
/#
|
||||
Assert( anims.size == animSpeeds.size && anims.size == animLengths.size );
|
||||
for ( i=1; i<animSpeeds.size; i++)
|
||||
Assert( animSpeeds[ i-1 ] < animSpeeds[ i ] );
|
||||
#/
|
||||
if ( !IsDefined( blendTime ) ) blendTime = 0.1;
|
||||
|
||||
speed = clamp( speed, animSpeeds[ 0 ], animSpeeds[ animSpeeds.size-1 ] );
|
||||
i = 0;
|
||||
while ( speed > animSpeeds[ i+1 ] )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
fastWeight = speed - animSpeeds[ i ];
|
||||
fastWeight /=animSpeeds[ i+1 ] - animSpeeds[ i ];
|
||||
if ( isSP() ) // We only blend in SP
|
||||
{
|
||||
fastWeight = clamp( fastWeight, 0.01, 0.99 ); // Don't allow anims to blend out so they don't lose their time.
|
||||
// Scale playback rates according to blend weights.
|
||||
// I'd love to use loopsync to achieve this but it appears to prevent SetAnimTime from working.
|
||||
speedRatio = animLengths[ i+1 ] / animLengths[ i ];
|
||||
fastRate = fastWeight + ( ( 1 - fastWeight ) * speedRatio );
|
||||
self call [[ level.func[ "setanimlimited" ] ]]( anims[ i ], 1 - fastWeight, blendTime, fastRate / speedRatio );
|
||||
self call [[ level.func[ "setanimlimited" ] ]]( anims[ i+1 ], fastWeight, blendTime, fastRate );
|
||||
for ( j=0; j<i; j++ )
|
||||
{
|
||||
speedRatio = animLengths[ i+1 ] / animLengths[ j ];
|
||||
self call [[ level.func[ "setanimlimited" ] ]]( anims[ j ], 0.01, blendTime, fastRate / speedRatio );
|
||||
}
|
||||
for ( j=i+2; j<animSpeeds.size; j++ )
|
||||
{
|
||||
speedRatio = animLengths[ i+1 ] / animLengths[ j ];
|
||||
self call [[ level.func[ "setanimlimited" ] ]]( anims[ j ], 0.01, blendTime, fastRate / speedRatio );
|
||||
}
|
||||
}
|
||||
else // MP. Just play the one that matches the speed best.
|
||||
{
|
||||
if ( fastWeight > 0.5 )
|
||||
{
|
||||
self call [[ level.func[ "scriptModelPlayAnim" ] ]]( anims[ i+1 ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
self call [[ level.func[ "scriptModelPlayAnim" ] ]]( anims[ i ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: detect_events()"
|
||||
"Summary: Makes an entity sentient and sets it up to detect nearby firefights. self.interrupted will be set to true for the frame in which an interruption occurs, so you can check it in situations where you can't wait for a notification."
|
||||
"Module: Entity"
|
||||
"CallOn: An entity"
|
||||
"MandatoryArg: <notifyString>: String that will be notified when violence is detected."
|
||||
"Example: self thread detect_events( "interrupted" );"
|
||||
"SPMP: singleplayer"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
|
||||
detect_events( notifyString )
|
||||
{
|
||||
if ( isSP() ) {
|
||||
self endon( "death" );
|
||||
self endon( "damage" );
|
||||
self call [[ level.makeEntitySentient_func ]]( "neutral" );
|
||||
self call [[ level.addAIEventListener_func ]]( "projectile_impact" );
|
||||
self call [[ level.addAIEventListener_func ]]( "bulletwhizby" );
|
||||
self call [[ level.addAIEventListener_func ]]( "gunshot" );
|
||||
self call [[ level.addAIEventListener_func ]]( "explode" );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
self waittill( "ai_event", eventtype );
|
||||
self notify( notifyString );
|
||||
self.interrupted = true;
|
||||
waittillframeend;
|
||||
self.interrupted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: detect_people( <radius> , <notifyStr> )"
|
||||
"Summary: Creates a trigger that detects people and vehicles. self.interrupted will be set to true for the frame in which an interruption occurs, so you can check it in situations where you can't wait for a notification."
|
||||
"Module: Entity"
|
||||
"CallOn: An entity"
|
||||
"MandatoryArg: <radius>: Radious and height of the trigger volume."
|
||||
"MandatoryArg: <notifyStr>: String to notify when someone enters the trigger."
|
||||
"MandatoryArg: <endonStr>: String(s) that will end this thread and delete the trigger when notified."
|
||||
"Example: self thread detect_people( info.react_distance, "interrupted", [ "death", "damage" ] );"
|
||||
"SPMP: singleplayer"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
|
||||
detect_people( radius, notifyStr, endonStr )
|
||||
{
|
||||
if ( !IsArray( endonStr ) )
|
||||
{
|
||||
tempStr = endonStr;
|
||||
endonStr = [];
|
||||
endonStr[0] = tempStr;
|
||||
}
|
||||
foreach (str in endonStr )
|
||||
self endon( str );
|
||||
|
||||
// I think the trigger_radius flags are as follows: AI_AXIS = 1, AI_ALLIES = 2, AI_NEUTRAL = 4, NOTPLAYER = 8 VEHICLE = 16 TRIGGER_SPAWN = 32 TOUCH_ONCE = 64
|
||||
// AI_AXIS + AI_ALLIES + AI_NEUTRAL + VEHICLE = 23
|
||||
self.detect_people_trigger[ notifyStr ] = Spawn( "trigger_radius", self.origin, 23, radius, radius );
|
||||
|
||||
for ( i = endonStr.size; i < 3; i++ ) // Pad the array to make it easier to use for function parameters.
|
||||
endonStr[i] = undefined;
|
||||
self thread delete_on_notify( self.detect_people_trigger[ notifyStr ], endonStr[0], endonStr[1], endonStr[2] );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
self.detect_people_trigger[ notifyStr ] waittill( "trigger", interruptedEnt );
|
||||
self.interruptedEnt = interruptedEnt; // (self.interruptedEnt can't be modified directly as a parameter to waittill.)
|
||||
self notify( notifyStr );
|
||||
self.interrupted = true;
|
||||
waittillframeend;
|
||||
self.interrupted = false;
|
||||
}
|
||||
}
|
||||
|
||||
detect_player_event( radius, notifyStr, endonStr, eventStr )
|
||||
{
|
||||
if ( !IsArray( endonStr ) )
|
||||
{
|
||||
tempStr = endonStr;
|
||||
endonStr = [];
|
||||
endonStr[0] = tempStr;
|
||||
}
|
||||
foreach (str in endonStr )
|
||||
self endon( str );
|
||||
|
||||
while( 1 ) {
|
||||
level.player waittill( eventStr );
|
||||
if ( DistanceSquared( level.player.origin, self.origin ) < radius*radius ) {
|
||||
self notify( notifyStr );
|
||||
self.interruptedEnt = level.player;
|
||||
self notify( notifyStr );
|
||||
self.interrupted = true;
|
||||
waittillframeend;
|
||||
self.interrupted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wraps <number> into 0 to <range>, just like AngleClamp does for the range of 0-360. Result will be >=0 and < abs(range). AKA modulo, %, remainder.
|
||||
wrap( number, range )
|
||||
{
|
||||
quotient = Int( number / range );
|
||||
remainder = number - ( range * quotient );
|
||||
if ( number < 0 ) remainder += range;
|
||||
if ( remainder == range ) remainder = 0;
|
||||
return remainder;
|
||||
}
|
||||
|
||||
interactives_DrawDebugLineForTime( org1, org2, r, g, b, timer )
|
||||
{
|
||||
/#
|
||||
if ( GetDvarInt( "interactives_debug" ) )
|
||||
{
|
||||
thread draw_line_for_time( org1, org2, r, g, b, timer );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
// Draws a cross in 3D space
|
||||
drawCross( origin, size, color, timeSeconds )
|
||||
{
|
||||
thread draw_line_for_time ( origin -( size, 0, 0 ), origin +( size, 0, 0 ), color[0], color[1], color[2], timeSeconds );
|
||||
thread draw_line_for_time ( origin -( 0, size, 0 ), origin +( 0, size, 0 ), color[0], color[1], color[2], timeSeconds );
|
||||
thread draw_line_for_time ( origin -( 0, 0, size ), origin +( 0, 0, size ), color[0], color[1], color[2], timeSeconds );
|
||||
}
|
||||
|
||||
// Draws a circle in 3D space
|
||||
drawCircle( origin, radius, color, timeSeconds )
|
||||
{
|
||||
numSegments = 16;
|
||||
for ( i=0; i<360; i+=(360/numSegments) )
|
||||
{
|
||||
j = i + (360/numSegments);
|
||||
thread draw_line_for_time ( origin + ( radius*Cos(i), radius*Sin(i), 0 ), origin + ( radius*Cos(j), radius*Sin(j), 0 ), color[0], color[1], color[2], timeSeconds );
|
||||
}
|
||||
}
|
||||
|
||||
// Draw an arc with an arrowhead on the end, in 3D space. Positive degrees means counterclockwise.
|
||||
drawCircularArrow( origin, radius, color, timeseconds, degrees )
|
||||
{
|
||||
if ( degrees == 0 ) return;
|
||||
numSegmentsFullCircle = 16;
|
||||
numSegments = int( 1 + (numSegmentsFullCircle * abs(degrees) / 360 ) );
|
||||
for ( seg=0; seg<numSegments; seg++ )
|
||||
{
|
||||
i = seg * degrees / numSegments;
|
||||
j = i + (degrees / numSegments);
|
||||
thread draw_line_for_time ( origin + ( radius*Cos(i), radius*Sin(i), 0 ), origin + ( radius*Cos(j), radius*Sin(j), 0 ), color[0], color[1], color[2], timeSeconds );
|
||||
}
|
||||
i = degrees;
|
||||
j = degrees - ( sign( degrees ) * 20 );
|
||||
thread draw_line_for_time ( origin + ( radius*Cos(i), radius*Sin(i), 0 ), origin + ( radius*0.8*Cos(j), radius*0.8*Sin(j), 0 ), color[0], color[1], color[2], timeSeconds );
|
||||
thread draw_line_for_time ( origin + ( radius*Cos(i), radius*Sin(i), 0 ), origin + ( radius*1.2*Cos(j), radius*1.2*Sin(j), 0 ), color[0], color[1], color[2], timeSeconds );
|
||||
}
|
||||
|
||||
IsInArray( e, array )
|
||||
{
|
||||
foreach ( a in array )
|
||||
{
|
||||
if ( e == a ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Newton's Method (Newton-Raphson method) to find a root of the polynomial y = p3*x^3 + p2*x^2 + p1*x + p0 in the interval x0 to x1.
|
||||
newtonsMethod( x0, x1, p3, p2, p1, p0, tolerance )
|
||||
{
|
||||
iterations = 5;
|
||||
x = ( x0 + x1 ) / 2;
|
||||
offset = tolerance + 1;
|
||||
while ( abs( offset ) > tolerance && iterations > 0)
|
||||
{
|
||||
value = (p3*x*x*x) + (p2*x*x) + (p1*x) + p0;
|
||||
slope = (3*p3*x*x) + (2*p2*x) + p1;
|
||||
AssertEx( slope != 0, "newtonsMethod found zero slope. Can't work with that." );
|
||||
offset = -1 * value / slope;
|
||||
oldx = x;
|
||||
x += offset;
|
||||
// Hack to keep the value within the bounds
|
||||
if ( x > x1 )
|
||||
x = ( oldX + (3*x1) ) / 4;
|
||||
else if ( x < x0 )
|
||||
x = ( oldX + (3*x0) ) / 4;
|
||||
iterations--;
|
||||
/# if ( iterations == 0 )
|
||||
Print( "_interactive_utility::newtonsMethod failed to converge. x0:"+x0+", x1:"+x1+", p3:"+p3+", p2:"+p2+", p1:"+p1+", p0:"+p0+", x:"+x );
|
||||
#/
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// rootsOfCubic. Doesn't work.
|
||||
rootsOfCubic(a,b,c,d)
|
||||
{
|
||||
if ( a == 0 ) {
|
||||
return rootsOfQuadratic(b,c,d);
|
||||
}
|
||||
// I can't do this mathematically without having a cube root function.
|
||||
q = (2*b*b*b) - (9*a*b*c) + (27*a*a*d);
|
||||
//Q = sqrt( q*q*q );
|
||||
bSquared3ac = (b*b) - (3*a*c);
|
||||
if ( ( bSquared3ac == 0 ) )
|
||||
{
|
||||
// If ( bSquared3ac == 0 ) there's only one real root regardless of what q is, but I can't find it without a cube root function.
|
||||
// root = cubeRoot( d/a );
|
||||
}
|
||||
if ( q == 0 && bSquared3ac==0 )
|
||||
{
|
||||
x[0] = -1 * b / (3*a);
|
||||
}
|
||||
else if ( q == 0 && bSquared3ac!=0 )
|
||||
{
|
||||
// There's a double root that I don't care about since it isn't a change from acceleration to deceleration
|
||||
// The other root is
|
||||
x[0] = ( (9*a*a*d) - (4*a*b*c) + (b*b*b) ) / ( a * ( (3*a*c) - (b*b) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Typical case...can't do it mathematically so do it numerically.
|
||||
// Need to break the curve into intervals and use Newton's Method above.
|
||||
}
|
||||
}
|
||||
|
||||
rootsOfQuadratic(a,b,c)
|
||||
{
|
||||
// The spline code generates some big numbers which cause errors due to overflow
|
||||
while ( abs(a)>65536 || abs(b)>65536 || abs(c)>65536 ) {
|
||||
a /= 10;
|
||||
b /= 10;
|
||||
c /= 10;
|
||||
}
|
||||
x = [];
|
||||
if ( a == 0 ) {
|
||||
if ( b != 0 ) {
|
||||
x[0] = -1 * c / b;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bSquared4ac = (b*b) - (4*a*c);
|
||||
if ( bSquared4ac > 0 ) {
|
||||
x[0] = ( (-1*b) - sqrt( bSquared4ac ) ) / (2*a);
|
||||
x[1] = ( (-1*b) + sqrt( bSquared4ac ) ) / (2*a);
|
||||
}
|
||||
else if ( bSquared4ac == 0 ) {
|
||||
x[0] = -1 * b / (2*a);
|
||||
}
|
||||
}
|
||||
// Note: If there are no roots, x will be empty.
|
||||
return x;
|
||||
}
|
||||
|
||||
// NonVectorLength
|
||||
// Just like Length, but gets the length of a vector represented as an array.
|
||||
// Optional second array will be sutracted (per-component) from the first. That is, NonVectorLength(origin1,origtin2) is the same as Length(origin1-origin2).
|
||||
NonVectorLength( array, array2 )
|
||||
{
|
||||
AssertEx( ( !IsDefined(array2) ) || ( array.size==array2.size ), "NonVectorLength: second array must have same number of components as first array." );
|
||||
sum = 0;
|
||||
for ( i=0; i<array.size; i++ )
|
||||
{
|
||||
value = array[i];
|
||||
if ( IsDefined(array2) ) value -= array2[i];
|
||||
sum += value*value;
|
||||
}
|
||||
return sqrt( sum );
|
||||
}
|
||||
|
||||
// clampAndNormalize
|
||||
// Clamps x to the range min-max and then divides it by that range, to give a result between 0 and 1.
|
||||
// Works for min<max and max<min.
|
||||
clampAndNormalize( x, min, max )
|
||||
{
|
||||
AssertEx( min != max, "clampAndNormalize: min must not equal max" );
|
||||
if ( min < max )
|
||||
x = clamp( x, min, max );
|
||||
else x = clamp( x, max, min );
|
||||
return ( x - min ) / (max - min );
|
||||
}
|
||||
|
||||
PointOnCircle( center, radius, deg )
|
||||
{
|
||||
x = Cos( deg );
|
||||
x *= radius;
|
||||
x += center[0];
|
||||
y = Sin( deg );
|
||||
y *= radius;
|
||||
y += center[1];
|
||||
z = center[2];
|
||||
return (x,y,z);
|
||||
}
|
||||
|
||||
zeroComponent( vector, comp )
|
||||
{
|
||||
return ( vector[0] * (comp != 0 ), vector[1] * (comp != 1 ), vector[2] * (comp != 2 ) );
|
||||
}
|
||||
|
||||
rotate90AroundAxis( vector, comp )
|
||||
{
|
||||
if ( comp == 0 )
|
||||
{
|
||||
return ( vector[0], vector[2], -1 * vector[1] );
|
||||
}
|
||||
else if ( comp == 1 )
|
||||
{
|
||||
return ( -1 * vector[2], vector[1], vector[0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( vector[1], -1 * vector[0], vector[2] );
|
||||
}
|
||||
}
|
136
maps/interactive_models/batcave.gsc
Normal file
136
maps/interactive_models/batcave.gsc
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* How to use this script:
|
||||
* You need an exploder which creates the FX of the bats flying,
|
||||
* and an animation which moves "tag_attach" along the flight path (for the sound).
|
||||
* You need a trigger with a targetname, to detect if players are close to the bats spawn location.
|
||||
* Then, just call vfxBatCaveWaitInit() with all those things.
|
||||
*/
|
||||
#include common_scripts\utility;
|
||||
|
||||
VFX_BAT_COOLDOWN = 60;
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: vfxBatCaveWaitInit( <triggername> , <exploderID> , <audioAnim> , <pos> , <emptyRoomCooldown> )"
|
||||
"Summary: Sets up a bat colony to detect players and play a bat exploder when a player fires his/her weapon nearby."
|
||||
"Module: "
|
||||
"CallOn: "
|
||||
"MandatoryArg: <triggername>: Targetname of a trigger that will detect players."
|
||||
"MandatoryArg: <exploderID>: ID of the exploder to be triggered."
|
||||
"OptionalArg: <audioAnim>: Animation with 'tag_attach' moving along the path of the EFX, for a sound to be attached to."
|
||||
"OptionalArg: <pos>: Position of the exploder, for the animation to be placed at."
|
||||
"OptionalArg: <emptyRoomCooldown>: Time the trigger must be undisturbed before the exploder can fire again. If undefined or 0, the exploder can fire periodically even the trigger has never been empty."
|
||||
"Example: thread vfxBatCaveWaitInit( "bats_1", 1, "bats_flyaway_1", (-2028, 464, 413) );"
|
||||
"SPMP: both"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
|
||||
vfxBatCaveWaitInit( triggername, exploderID, audioAnim, pos, emptyRoomCooldown )
|
||||
{
|
||||
if ( !IsDefined( emptyRoomCooldown ) )
|
||||
emptyRoomCooldown = 0;
|
||||
|
||||
level endon( "game_ended" );
|
||||
|
||||
// get the trigger
|
||||
trigger = GetEnt( triggername, "targetname" );
|
||||
if ( IsDefined( trigger ) )
|
||||
{
|
||||
trigger childthread vfxBatCaveTrigger( exploderID, audioAnim, pos );
|
||||
trigger childthread vfxBatCaveWatchForEmpty( emptyRoomCoolDown );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
trigger waittill( "trigger", player );
|
||||
|
||||
trigger thread vfxBatCaveWatchPlayerState( player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vfxBatCaveWatchPlayerState( player ) // self == bat trigger
|
||||
{
|
||||
// if any other player starts the bats, stop checking
|
||||
self endon( "batCaveTrigger" );
|
||||
|
||||
player endon( "death" );
|
||||
player endon( "disconnect" );
|
||||
|
||||
// make sure we aren't already runnning one
|
||||
player notify( "batCaveExit" );
|
||||
player endon( "batCaveExit" );
|
||||
|
||||
self childthread vfxBatCaveWatchPlayerWeapons( player );
|
||||
|
||||
// this detects if the player has exited the trigger
|
||||
while ( player IsTouching( self ) )
|
||||
{
|
||||
waitframe();
|
||||
self.lastTouchedTime = GetTime();
|
||||
}
|
||||
|
||||
player notify( "batCaveExit" );
|
||||
}
|
||||
|
||||
vfxBatCaveWatchPlayerWeapons( player )
|
||||
{
|
||||
player waittill( "weapon_fired" );
|
||||
self notify ( "batCaveTrigger" );
|
||||
}
|
||||
|
||||
vfxBatCaveWatchForEmpty( emptyRoomCoolDown )
|
||||
{
|
||||
self.lastTouchedTime = GetTime();
|
||||
self.batCaveReset = true;
|
||||
while ( true )
|
||||
{
|
||||
waitframe();
|
||||
if ( self.lastTouchedTime + emptyRoomCoolDown <= GetTime() ) {
|
||||
self.batCaveReset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vfxBatCaveTrigger( exploderID, audioAnim, pos )
|
||||
{
|
||||
/#
|
||||
SetDvarIfUninitialized( "scr_dbg_batcave_cooldown", VFX_BAT_COOLDOWN );
|
||||
#/
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "batCaveTrigger" );
|
||||
|
||||
if ( self.batCaveReset ) {
|
||||
vfxBatsFly( exploderID, audioAnim, pos );
|
||||
self.batCaveReset = false;
|
||||
|
||||
waitTime = VFX_BAT_COOLDOWN;
|
||||
/#
|
||||
waitTime = GetDvarInt( "scr_dbg_batcave_cooldown" );
|
||||
#/
|
||||
|
||||
wait ( waitTime );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Plays the bats effect and moving sound
|
||||
vfxBatsFly(exploderID, audioAnim, pos)
|
||||
{
|
||||
exploder(exploderID); // It's become pretty pointless to do these as exploders, but it works, so I'm leaving it for now.
|
||||
|
||||
// Play a sound that moves with the bats as they fly.
|
||||
if ( IsDefined(audioAnim) && IsDefined(pos) ) {
|
||||
soundrig = Spawn( "script_model", pos );
|
||||
soundrig SetModel( "vulture_circle_rig" );
|
||||
soundrig ScriptModelPlayAnim( audioAnim );
|
||||
dummy = Spawn( "script_model", soundrig GetTagOrigin( "tag_attach" ) );
|
||||
dummy LinkTo( soundrig, "tag_attach" );
|
||||
wait(0.1); // Without this the sound won't play. Because the tag is inside the wall?
|
||||
dummy PlaySoundOnMovingEnt( "scn_mp_swamp_bat_cave_big" );
|
||||
}
|
||||
}
|
||||
|
78
maps/interactive_models/crows_dlc.gsc
Normal file
78
maps/interactive_models/crows_dlc.gsc
Normal file
@ -0,0 +1,78 @@
|
||||
// Interactive_models\crows_dlc.gsc
|
||||
|
||||
// At Nate's suggestion I'm trying not to entangle this with other systems. There are some things I can't avoid though.
|
||||
// I introduced a level array called "_interactive" that I'll use for all this stuff that isn't a traditional destructible.
|
||||
// However, my intention is that any given type of interactive object can have its own struct in this array.
|
||||
// Crows are interactive_birds. They have a rig that all the birds attach to and different bird models for flying vs sitting.
|
||||
|
||||
// The 'dlc' version uses modified mp animations, which are hacky but still, it should be copied over the original version if
|
||||
// we plan to continue using it for the next game. (NB: It hasn't been tested in SP yet.)
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animals_dlc" );
|
||||
main()
|
||||
{
|
||||
info = SpawnStruct();
|
||||
info.interactive_type = "crows_dlc";
|
||||
info.rig_model = "use_radiant_model";
|
||||
info.rig_animtree = #animtree;
|
||||
info.rig_numtags = 2;//backup, really handled in Radiant
|
||||
info.bird_model["idle"] = "crow_fly";
|
||||
info.bird_model["fly"] = "crow_fly";
|
||||
info.bird_animtree = #animtree;
|
||||
info.topSpeed = 300; // Inches per second.
|
||||
info.accn = 75; // Use this for both acceleration and deceleration.
|
||||
info.scareRadius = 600; // Default distance at which pigeons will leave perch to avoid player or AI.
|
||||
info.death_effect = LoadFX( "fx/props/bird_feather_exp_black" );
|
||||
info.birdmodel_anims = [];
|
||||
info.rigmodel_anims = [];
|
||||
info.birdmodel_anims[ "idle" ][ 0 ] = %crow_idle_1;
|
||||
info.birdmodel_anims[ "idleweight" ][ 0 ] = 1;
|
||||
info.birdmodel_anims[ "idle" ][ 1 ] = %crow_idle_2;
|
||||
info.birdmodel_anims[ "idleweight" ][ 1 ] = 0.3;
|
||||
info.birdmodel_anims[ "flying" ] = %crow_fly;
|
||||
info.rigmodel_anims[ "flying" ] = %pigeon_flock_fly_loop;
|
||||
info.rigmodel_anims[ "takeoff_wire" ] = %pigeon_flock_takeoff_wire; // These match the Radiant keypairs "interactive_takeoffAnim" and "interactive_landAnim"
|
||||
info.rigmodel_anims[ "land_wire" ] = %pigeon_flock_land_wire;
|
||||
info.rigmodel_anims[ "takeoff_ground" ] = %pigeon_flock_takeoff_ground;
|
||||
info.rigmodel_anims[ "land_ground" ] = %pigeon_flock_land_ground;
|
||||
info.rigmodel_anims[ "takeoff_inpipe" ] = %pigeon_flock_takeoff_inpipe;
|
||||
info.rigmodel_anims[ "land_inpipe" ] = %pigeon_flock_land_inpipe;
|
||||
if ( !isSP() ) {
|
||||
info.birdmodel_anims[ "idlemp" ][ 0 ] = "crow_idle_1";
|
||||
info.birdmodel_anims[ "idlemp" ][ 1 ] = "crow_idle_2";
|
||||
info.birdmodel_anims[ "flyingmp" ] = "crow_fly";
|
||||
// These _mp animations for the rig are a hack. They are identical to the SP animations in length and
|
||||
// motion, but keep the tags all facing forward, since the MP animations can't be rotated the same way
|
||||
// the SP ones can.
|
||||
info.rigmodel_anims[ "flyingmp" ] = "pigeon_flock_fly_loop_mp";
|
||||
info.rigmodel_anims[ "takeoff_wiremp" ] = "pigeon_flock_takeoff_wire_mp";
|
||||
info.rigmodel_anims[ "land_wiremp" ] = "pigeon_flock_land_wire_mp";
|
||||
info.rigmodel_anims[ "takeoff_groundmp" ] = "pigeon_flock_takeoff_ground_mp";
|
||||
info.rigmodel_anims[ "land_groundmp" ] = "pigeon_flock_land_ground_mp";
|
||||
info.rigmodel_anims[ "takeoff_inpipemp" ] = "pigeon_flock_takeoff_inpipe_mp";
|
||||
info.rigmodel_anims[ "land_inpipemp" ] = "pigeon_flock_land_inpipe_mp";
|
||||
/*info.rigmodel_anims[ "flyingmp" ] = "pigeon_flock_fly_loop";
|
||||
info.rigmodel_anims[ "takeoff_wiremp" ] = "pigeon_flock_takeoff_wire";
|
||||
info.rigmodel_anims[ "land_wiremp" ] = "pigeon_flock_land_wire";
|
||||
info.rigmodel_anims[ "takeoff_groundmp" ] = "pigeon_flock_takeoff_ground";
|
||||
info.rigmodel_anims[ "land_groundmp" ] = "pigeon_flock_land_ground";
|
||||
info.rigmodel_anims[ "takeoff_inpipemp" ] = "pigeon_flock_takeoff_inpipe";
|
||||
info.rigmodel_anims[ "land_inpipemp" ] = "pigeon_flock_land_inpipe";*/
|
||||
|
||||
}
|
||||
info.sounds = [];
|
||||
info.sounds[ "takeoff" ] = "anml_crow_startle_flyaway";
|
||||
info.sounds[ "idle" ] = "anml_crow_idle";
|
||||
//TODO JL will also need to change KVPs in 'prefabs/mp_shipment_ns/shns_interactive_crows.map' from 'sound_csv_include:animal_bird' to the new csv
|
||||
|
||||
PreCacheModel( info.rig_model );
|
||||
foreach ( model in info.bird_model ) {
|
||||
PreCacheModel( model );
|
||||
}
|
||||
|
||||
if( !isdefined ( level._interactive ) )
|
||||
level._interactive = [];
|
||||
level._interactive[ info.interactive_type ] = info;
|
||||
thread maps\interactive_models\_birds_dlc::birds(info);
|
||||
}
|
76
maps/interactive_models/parakeets_dlc.gsc
Normal file
76
maps/interactive_models/parakeets_dlc.gsc
Normal file
@ -0,0 +1,76 @@
|
||||
// Interactive_models\Parakeets.gsc
|
||||
|
||||
// At Nate's suggestion I'm trying not to entangle this with other systems. There are some things I can't avoid though.
|
||||
// I introduced a level array called "_interactive" that I'll use for all this stuff that isn't a traditional destructible.
|
||||
// However, my intention is that any given type of interactive object can have its own struct in this array.
|
||||
// Parakeets are interactive_birds. They have a rig that all the birds attach to and different bird models for flying vs sitting.
|
||||
|
||||
// The 'dlc' version uses modified mp animations, which are hacky but still, it should be copied over the original version if
|
||||
// we plan to continue using it for the next game. (NB: It hasn't been tested in SP yet.)
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animals_dlc" );
|
||||
main()
|
||||
{
|
||||
info = SpawnStruct();
|
||||
info.interactive_type = "parakeets_dlc";
|
||||
info.rig_model = "pigeon_flock_rig";
|
||||
info.rig_animtree = #animtree;
|
||||
info.rig_numtags = 12;
|
||||
info.bird_model["idle"] = "parakeet";
|
||||
info.bird_model["fly"] = "parakeet_fly";
|
||||
info.bird_animtree = #animtree;
|
||||
info.topSpeed = 600; // Inches per second.
|
||||
info.accn = 150; // Use this for both acceleration and deceleration.
|
||||
info.scareRadius = 300; // Default distance at which pigeons will leave perch to avoid player or AI.
|
||||
info.death_effect = LoadFX( "fx/props/chicken_exp_white" );
|
||||
info.birdmodel_anims = [];
|
||||
info.rigmodel_anims = [];
|
||||
info.birdmodel_anims[ "idle" ][ 0 ] = %pigeon_idle;
|
||||
info.birdmodel_anims[ "idleweight" ][ 0 ] = 1;
|
||||
info.birdmodel_anims[ "idle" ][ 1 ] = %pigeon_idle_twitch_1;
|
||||
info.birdmodel_anims[ "idleweight" ][ 1 ] = 0.3;
|
||||
info.birdmodel_anims[ "flying" ] = %pigeon_flying_cycle;
|
||||
info.rigmodel_anims[ "flying" ] = %pigeon_flock_fly_loop;
|
||||
info.rigmodel_anims[ "takeoff_wire" ] = %pigeon_flock_takeoff_wire; // These match the Radiant keypairs "interactive_takeoffAnim" and "interactive_landAnim"
|
||||
info.rigmodel_anims[ "land_wire" ] = %pigeon_flock_land_wire;
|
||||
info.rigmodel_anims[ "takeoff_ground" ] = %pigeon_flock_takeoff_ground;
|
||||
info.rigmodel_anims[ "land_ground" ] = %pigeon_flock_land_ground;
|
||||
info.rigmodel_anims[ "takeoff_inpipe" ] = %pigeon_flock_takeoff_inpipe;
|
||||
info.rigmodel_anims[ "land_inpipe" ] = %pigeon_flock_land_inpipe;
|
||||
if ( !isSP() ) {
|
||||
info.birdmodel_anims[ "idlemp" ][ 0 ] = "pigeon_idle";
|
||||
info.birdmodel_anims[ "idlemp" ][ 1 ] = "pigeon_idle_twitch_1";
|
||||
info.birdmodel_anims[ "flyingmp" ] = "pigeon_flying_cycle";
|
||||
// These _mp animations for the rig are a hack. They are identical to the SP animations in length and
|
||||
// motion, but keep the tags all facing forward, since the MP animations can't be rotated the same way
|
||||
// the SP ones can.
|
||||
info.rigmodel_anims[ "flyingmp" ] = "pigeon_flock_fly_loop_mp";
|
||||
info.rigmodel_anims[ "takeoff_wiremp" ] = "pigeon_flock_takeoff_wire_mp";
|
||||
info.rigmodel_anims[ "land_wiremp" ] = "pigeon_flock_land_wire_mp";
|
||||
info.rigmodel_anims[ "takeoff_groundmp" ] = "pigeon_flock_takeoff_ground_mp";
|
||||
info.rigmodel_anims[ "land_groundmp" ] = "pigeon_flock_land_ground_mp";
|
||||
info.rigmodel_anims[ "takeoff_inpipemp" ] = "pigeon_flock_takeoff_inpipe_mp";
|
||||
info.rigmodel_anims[ "land_inpipemp" ] = "pigeon_flock_land_inpipe_mp";
|
||||
/*info.rigmodel_anims[ "flyingmp" ] = "pigeon_flock_fly_loop";
|
||||
info.rigmodel_anims[ "takeoff_wiremp" ] = "pigeon_flock_takeoff_wire";
|
||||
info.rigmodel_anims[ "land_wiremp" ] = "pigeon_flock_land_wire";
|
||||
info.rigmodel_anims[ "takeoff_groundmp" ] = "pigeon_flock_takeoff_ground";
|
||||
info.rigmodel_anims[ "land_groundmp" ] = "pigeon_flock_land_ground";
|
||||
info.rigmodel_anims[ "takeoff_inpipemp" ] = "pigeon_flock_takeoff_inpipe";
|
||||
info.rigmodel_anims[ "land_inpipemp" ] = "pigeon_flock_land_inpipe";*/
|
||||
|
||||
}
|
||||
info.sounds = [];
|
||||
info.sounds[ "takeoff" ] = "anml_bird_startle_flyaway";
|
||||
|
||||
PreCacheModel( info.rig_model );
|
||||
foreach ( model in info.bird_model ) {
|
||||
PreCacheModel( model );
|
||||
}
|
||||
|
||||
if( !isdefined ( level._interactive ) )
|
||||
level._interactive = [];
|
||||
level._interactive[ info.interactive_type ] = info;
|
||||
thread maps\interactive_models\_birds_dlc::birds(info);
|
||||
}
|
96
maps/interactive_models/vulture_mp.gsc
Normal file
96
maps/interactive_models/vulture_mp.gsc
Normal file
@ -0,0 +1,96 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: vulture_circling( <origin> )"
|
||||
"Summary: Creates a vulture circling around the specified origin. Don't forget to include interactive_vulture_circling.csv in your zone file."
|
||||
"Module: "
|
||||
"CallOn: Nothing"
|
||||
"MandatoryArg: <origin>: A vector specifying a point in space."
|
||||
"Example: vulture_circling((105, -1320, 1600));"
|
||||
"SPMP: Both"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
|
||||
vulture_circling(origin, number)
|
||||
{
|
||||
if ( !IsDefined(number) )
|
||||
number = 1;
|
||||
if ( !IsDefined(level._interactive) ) {
|
||||
level._interactive = [];
|
||||
}
|
||||
if ( !IsDefined(level._interactive["vultures"]) ) {
|
||||
level._interactive["vultures"]["count"] = 0;
|
||||
level._interactive["vultures"]["anims"][0] = "vulture_rig_circle";
|
||||
level._interactive["vultures"]["anims"][1] = "vulture_rig_circle2";
|
||||
level._interactive["vultures"]["anims"][2] = "vulture_rig_circle3";
|
||||
level._interactive["vultures"]["rigs"] = [];
|
||||
level._interactive["vultures"]["vultures"] = [];
|
||||
}
|
||||
for ( i=0; i<number; i++ ) {
|
||||
newOrigin = origin + ( (0,0,50) * i );
|
||||
if ( i > 0 )
|
||||
newOrigin += (0,0,RandomIntRange(-20,20));
|
||||
thread vulture_circling_internal(newOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
vulture_circling_internal(origin)
|
||||
{
|
||||
count = level._interactive["vultures"]["rigs"].size;
|
||||
|
||||
yaw = RandomInt(360);
|
||||
|
||||
rig = Spawn( "script_model", origin );
|
||||
rig.angles = (0, yaw, 0);
|
||||
rig SetModel( "vulture_circle_rig" );
|
||||
|
||||
vulture = Spawn( "script_model", rig.origin );
|
||||
vulture.angles = (0, yaw, 0);
|
||||
vulture SetModel( "ng_vulture" );
|
||||
|
||||
vulture LinkTo( rig, "tag_attach" );
|
||||
riganim = level._interactive["vultures"]["anims"][mod(count, 3)];
|
||||
rig ScriptModelPlayAnim( riganim );
|
||||
level._interactive["vultures"]["vultures"][count] = vulture;
|
||||
level._interactive["vultures"]["rigs"][count] = rig;
|
||||
|
||||
vulture endon("death");
|
||||
wait( RandomFloat(5) );
|
||||
vulture ScriptModelPlayAnim( "vulture_fly_loop_all" );
|
||||
}
|
||||
|
||||
/#
|
||||
vultures_toggle_thread()
|
||||
{
|
||||
SetDevDvar("vultures_enable", "1");
|
||||
while ( true ) {
|
||||
while( GetDvarInt("vultures_enable") >= 1 )
|
||||
{
|
||||
wait .5;
|
||||
}
|
||||
IPrintLn("Deleting vultures");
|
||||
positions = [];
|
||||
foreach (vulture in level._interactive["vultures"]["vultures"] ) {
|
||||
vulture Delete();
|
||||
}
|
||||
foreach ( rig in level._interactive["vultures"]["rigs"] ) {
|
||||
positions[positions.size] = rig.origin;
|
||||
rig Delete();
|
||||
}
|
||||
level._interactive["vultures"]["rigs"] = [];
|
||||
level._interactive["vultures"]["vultures"] = [];
|
||||
|
||||
while( GetDvarInt("vultures_enable") < 1 )
|
||||
{
|
||||
wait .5;
|
||||
}
|
||||
IPrintLn("Adding vultures");
|
||||
foreach ( position in positions ) {
|
||||
thread vulture_circling(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
#/
|
63
maps/mp/_animatedmodels.gsc
Normal file
63
maps/mp/_animatedmodels.gsc
Normal file
@ -0,0 +1,63 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
//level.init_animatedmodels_dump = false;
|
||||
|
||||
if ( !isdefined( level.anim_prop_models ) )
|
||||
level.anim_prop_models = []; // this is what the LD puts in their map
|
||||
|
||||
// Do special MP anim precaching
|
||||
model_keys = GetArrayKeys( level.anim_prop_models );
|
||||
foreach ( model_key in model_keys )
|
||||
{
|
||||
anim_keys = GetArrayKeys( level.anim_prop_models[model_key] );
|
||||
foreach ( anim_key in anim_keys )
|
||||
PrecacheMpAnim( level.anim_prop_models[model_key][anim_key] );
|
||||
//PrecacheMpAnim( level.anim_prop_models[ "foliage_tree_palm_bushy_1" ][ "strong" ] );
|
||||
}
|
||||
|
||||
// wait until the end of the frame so that maps can init their trees
|
||||
// in their _anim instead of only above _load
|
||||
waittillframeend;
|
||||
|
||||
level.init_animatedmodels = [];
|
||||
|
||||
animated_models = getentarray( "animated_model", "targetname" );
|
||||
//array_thread( animated_models, ::model_init );
|
||||
|
||||
// one or more of the models initialized by model_init() was not setup by the map
|
||||
// so print this helpful note so the designer can see how to add it ot their level
|
||||
//if ( level.init_animatedmodels_dump )
|
||||
//assertmsg( "anims not cached for animated prop model, Repackage Zones and Rebuild Precache Script in Launcher:" );
|
||||
|
||||
array_thread_amortized( animated_models, ::animateModel, 0.05 );
|
||||
|
||||
level.init_animatedmodels = undefined;
|
||||
}
|
||||
|
||||
// Disabled for now since we are precaching .animation prefabs in a non-standard way
|
||||
/*model_init()
|
||||
{
|
||||
if ( !isdefined( level.anim_prop_models[ self.model ] ) )
|
||||
level.init_animatedmodels_dump = true;
|
||||
}*/
|
||||
|
||||
// TODO: When we have multiple animations, instead of choosing randomly, do round-robin to get an even spread
|
||||
animateModel()
|
||||
{
|
||||
if ( IsDefined( self.animation ) )
|
||||
{
|
||||
animation = self.animation;
|
||||
}
|
||||
else
|
||||
{
|
||||
keys = GetArrayKeys( level.anim_prop_models[ self.model ] );
|
||||
animkey = keys[ RandomInt( keys.size ) ];
|
||||
animation = level.anim_prop_models[ self.model ][ animkey ];
|
||||
}
|
||||
|
||||
self ScriptModelPlayAnim( animation );
|
||||
self willNeverChange();
|
||||
}
|
98
maps/mp/_areas.gsc
Normal file
98
maps/mp/_areas.gsc
Normal file
@ -0,0 +1,98 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
/*QUAKED trigger_multiple_area (0.12 0.23 1.0)
|
||||
defaulttexture="trigger"
|
||||
"script_area" - A localized string that names the area. e.g. "MP_FLOWER_SHOP"
|
||||
Defines an area that the player is in.*/
|
||||
|
||||
/*QUAKED trigger_multiple_softlanding (0.12 0.23 1.0)
|
||||
defaulttexture="trigger"
|
||||
"script_type" - "car", "boxes", "trash"
|
||||
Defines a soft landing area.*/
|
||||
|
||||
|
||||
init()
|
||||
{
|
||||
level.softLandingTriggers = getEntArray( "trigger_multiple_softlanding", "classname" );
|
||||
|
||||
destructibles = getEntArray( "destructible_vehicle", "targetname" );
|
||||
|
||||
foreach ( trigger in level.softLandingTriggers )
|
||||
{
|
||||
if ( trigger.script_type != "car" )
|
||||
continue;
|
||||
|
||||
foreach ( destructible in destructibles )
|
||||
{
|
||||
/*
|
||||
if ( !trigger isTouching( destructible ) )
|
||||
{
|
||||
println( distance( trigger.origin, destructible.origin ) );
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
if ( distance( trigger.origin, destructible.origin ) > 64.0 )
|
||||
continue;
|
||||
|
||||
assert( !isDefined( trigger.destructible ) );
|
||||
|
||||
trigger.destructible = destructible;
|
||||
}
|
||||
}
|
||||
|
||||
//foreach ( trigger in level.softLandingTriggers )
|
||||
// trigger thread common_scripts\_dynamic_world::triggerTouchThink( ::playerEnterSoftLanding, ::playerLeaveSoftLanding );
|
||||
|
||||
thread onPlayerConnect();
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill ( "connected", player );
|
||||
|
||||
player.softLanding = undefined;
|
||||
|
||||
player thread softLandingWaiter();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
playerEnterSoftLanding( trigger )
|
||||
{
|
||||
self.softLanding = trigger;
|
||||
}
|
||||
|
||||
|
||||
playerLeaveSoftLanding( trigger )
|
||||
{
|
||||
self.softLanding = undefined;
|
||||
}
|
||||
|
||||
|
||||
softLandingWaiter()
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill ( "soft_landing", trigger, damage );
|
||||
|
||||
//if ( damage < 10 )
|
||||
// continue;
|
||||
|
||||
if ( !isDefined( trigger.destructible ) )
|
||||
continue;
|
||||
|
||||
//magicBullet( "mp5_mp", self.origin, self.origin + (0,0,-100), self );
|
||||
|
||||
//self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, dflags );
|
||||
|
||||
//traceData = bulletTrace( self.origin, self.origin + (0,0,-100), true, self );
|
||||
|
||||
}
|
||||
}
|
714
maps/mp/_art.gsc
Normal file
714
maps/mp/_art.gsc
Normal file
@ -0,0 +1,714 @@
|
||||
// This function should take care of grain and glow settings for each map, plus anything else that artists
|
||||
// need to be able to tweak without bothering level designers.
|
||||
#include common_scripts\utility;
|
||||
#include common_scripts\_artCommon;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
main()
|
||||
{
|
||||
/#
|
||||
PrecacheMenu( "dev_vision_noloc" );
|
||||
PrecacheMenu( "dev_vision_exec" );
|
||||
|
||||
setDevDvarIfUninitialized( "scr_art_tweak", 0 );
|
||||
setDevDvarIfUninitialized( "scr_cmd_plr_sun", "0" );
|
||||
SetDevDvarIfUninitialized( "scr_cmd_plr_sunflare", "0" );
|
||||
setDevDvarIfUninitialized( "scr_art_visionfile", level.script );
|
||||
SetDevDvar( "r_artUseTweaks", false );
|
||||
|
||||
thread tweakart();
|
||||
|
||||
tess_init();
|
||||
|
||||
if ( !isdefined( level.script ) )
|
||||
level.script = ToLower( GetDvar( "mapname" ) );
|
||||
#/
|
||||
}
|
||||
|
||||
/#
|
||||
initTweaks()
|
||||
{
|
||||
SetDevDvar( "r_artUseTweaks", true );
|
||||
|
||||
if ( IsDefined( level.parse_fog_func ) )
|
||||
[[level.parse_fog_func]]();
|
||||
|
||||
if ( !IsDefined( level.buttons ) )
|
||||
level.buttons = [];
|
||||
|
||||
level._clearalltextafterhudelem = false;
|
||||
|
||||
if ( !IsDefined( level.vision_set_names ) )
|
||||
level.vision_set_names = [];
|
||||
|
||||
if( !IsDefined( level.vision_set_fog ) )
|
||||
{
|
||||
level.vision_set_fog = [];
|
||||
create_default_vision_set_fog( level.script );
|
||||
common_scripts\_artCommon::setfogsliders();
|
||||
}
|
||||
|
||||
foreach( key, value in level.vision_set_fog )
|
||||
{
|
||||
common_scripts\_artCommon::add_vision_set_to_list( key );
|
||||
}
|
||||
|
||||
add_vision_sets_from_triggers();
|
||||
|
||||
update_current_vision_set_dvars();
|
||||
|
||||
if ( !IsDefined( level.current_vision_set ) )
|
||||
level.current_vision_set = GetDvar( "r_artTweaksLastVisionSet", "" );
|
||||
|
||||
IPrintLnBold( "ART TWEAK ENABLED" );
|
||||
hud_init();
|
||||
|
||||
last_vision_set = level.current_vision_set;
|
||||
if ( !IsDefined( last_vision_set ) || last_vision_set == "" )
|
||||
last_vision_set = level.script;
|
||||
|
||||
setcurrentgroup( last_vision_set );
|
||||
}
|
||||
|
||||
tweakart()
|
||||
{
|
||||
if ( !isdefined( level.tweakfile ) )
|
||||
level.tweakfile = false;
|
||||
|
||||
// not in DEVGUI
|
||||
SetDevDvar( "scr_fog_fraction", "1.0" );
|
||||
SetDevDvar( "scr_art_dump", "0" );
|
||||
|
||||
printed = false;
|
||||
|
||||
last_vision_set = "";
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
while ( GetDvarInt( "scr_art_tweak", 0 ) == 0 )
|
||||
wait .05;
|
||||
|
||||
if ( !printed )
|
||||
{
|
||||
printed = true;
|
||||
initTweaks();
|
||||
}
|
||||
|
||||
//translate the slider values to script variables
|
||||
common_scripts\_artCommon::translateFogSlidersToScript();
|
||||
|
||||
common_scripts\_artCommon::fogslidercheck();
|
||||
|
||||
updateSunFlarePosition();
|
||||
|
||||
dumpsettings();
|
||||
|
||||
updateFogFromScript();
|
||||
|
||||
if ( getdvarint( "scr_select_art_next" ) || button_down( "dpad_down", "kp_downarrow" ) )
|
||||
setgroup_down();
|
||||
else if ( getdvarint( "scr_select_art_prev" ) || button_down( "dpad_up", "kp_uparrow" ) )
|
||||
setgroup_up();
|
||||
else if( level.current_vision_set != last_vision_set )
|
||||
{
|
||||
last_vision_set = level.current_vision_set;
|
||||
setcurrentgroup( last_vision_set );
|
||||
}
|
||||
|
||||
wait .05;
|
||||
}
|
||||
}
|
||||
|
||||
tess_init()
|
||||
{
|
||||
using_tessellation = GetDvar( "r_tessellation" );
|
||||
if( using_tessellation == "" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
level.tess = SpawnStruct();
|
||||
|
||||
// Default Tessellation Values - push base settings to game values
|
||||
level.tess.cutoff_distance_current = GetDvarFloat( "r_tessellationCutoffDistanceBase", 960.0 );
|
||||
level.tess.cutoff_distance_goal = level.tess.cutoff_distance_current;
|
||||
level.tess.cutoff_falloff_current = GetDvarFloat( "r_tessellationCutoffFalloffBase", 320.0 );
|
||||
level.tess.cutoff_falloff_goal = level.tess.cutoff_falloff_current;
|
||||
level.tess.time_remaining = 0.0;
|
||||
SetDvar( "r_tessellationCutoffDistance", level.tess.cutoff_distance_current );
|
||||
SetDvar( "r_tessellationCutoffFalloff" , level.tess.cutoff_falloff_current );
|
||||
|
||||
thread tess_update();
|
||||
}
|
||||
|
||||
tess_set_goal( cutoff_distance, cutoff_falloff, blend_time )
|
||||
{
|
||||
level.tess.cutoff_distance_goal = cutoff_distance;
|
||||
level.tess.cutoff_falloff_goal = cutoff_falloff;
|
||||
level.tess.time_remaining = blend_time;
|
||||
}
|
||||
|
||||
tess_update()
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
cutoff_distance_old = level.tess.cutoff_distance_current;
|
||||
cutoff_falloff_old = level.tess.cutoff_falloff_current;
|
||||
|
||||
waitframe();
|
||||
if ( level.tess.time_remaining > 0.0 )
|
||||
{
|
||||
frames = level.tess.time_remaining * 20;
|
||||
distance_increment = ( level.tess.cutoff_distance_goal - level.tess.cutoff_distance_current ) / frames;
|
||||
falloff_increment = ( level.tess.cutoff_falloff_goal - level.tess.cutoff_falloff_current ) / frames;
|
||||
level.tess.cutoff_distance_current += distance_increment;
|
||||
level.tess.cutoff_falloff_current += falloff_increment;
|
||||
level.tess.time_remaining -= 0.05;
|
||||
}
|
||||
else
|
||||
{
|
||||
level.tess.cutoff_distance_current = level.tess.cutoff_distance_goal;
|
||||
level.tess.cutoff_falloff_current = level.tess.cutoff_falloff_goal;
|
||||
}
|
||||
|
||||
if( cutoff_distance_old != level.tess.cutoff_distance_current )
|
||||
{
|
||||
SetDvar( "r_tessellationCutoffDistance", level.tess.cutoff_distance_current );
|
||||
}
|
||||
if( cutoff_falloff_old != level.tess.cutoff_falloff_current )
|
||||
{
|
||||
SetDvar( "r_tessellationCutoffFalloff" , level.tess.cutoff_falloff_current );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateSunFlarePosition()
|
||||
{
|
||||
if ( GetDvarInt( "scr_cmd_plr_sunflare" ) )
|
||||
{
|
||||
SetDevDvar( "scr_cmd_plr_sunflare", 0 );
|
||||
|
||||
pos = level.players[0] GetPlayerAngles();
|
||||
|
||||
// Output the pos to the window
|
||||
pos_string = "Sun Flare = ( " + pos[0] + ", " + pos[1] + ", " + pos[2] + " )";
|
||||
IPrintLnBold( pos_string );
|
||||
Print( pos_string );
|
||||
}
|
||||
}
|
||||
|
||||
dumpsettings()
|
||||
{
|
||||
if ( GetDvarInt( "scr_art_dump" ) == 0 )
|
||||
return false;
|
||||
|
||||
SetdevDvar( "scr_art_dump", "0" );
|
||||
|
||||
////////////////// [level]_art.gsc
|
||||
fileprint_launcher_start_file();
|
||||
fileprint_launcher( "// _createart generated. modify at your own risk. Changing values should be fine." );
|
||||
fileprint_launcher( "main()" );
|
||||
fileprint_launcher( "{" );
|
||||
fileprint_launcher( "\tlevel.tweakfile = true;" );
|
||||
if ( IsDefined( level.parse_fog_func ) ) // Don't print this unless it already exists (otherwise [levelname]_fog.gsc will likely fail to compile)
|
||||
fileprint_launcher( "\tlevel.parse_fog_func = maps\\createart\\" + level.script + "_fog::main;" );
|
||||
fileprint_launcher( "" );
|
||||
fileprint_launcher( "\tsetDevDvar( \"scr_fog_disable\"" + ", " + "\"" + GetDvarInt( "scr_fog_disable" ) + "\"" + " );" );
|
||||
// Writing this out in case someone needs it
|
||||
if ( ! GetDvarInt( "scr_fog_disable" ) )
|
||||
{
|
||||
if ( level.sunFogEnabled )
|
||||
fileprint_launcher( "//\tsetExpFog( " + level.fognearplane + ", " + level.fogexphalfplane + ", " + level.fogcolor[0] + ", " + level.fogcolor[1] + ", " + level.fogcolor[2] + ", " + level.fogHDRColorIntensity + ", " + level.fogmaxopacity + ", 0, " + level.sunFogColor[0] + ", " + level.sunFogColor[1] + ", " + level.sunFogColor[2] + ", " + level.sunFogHDRColorIntensity + ", (" + level.sunFogDir[0] + ", " + level.sunFogDir[1] + ", " + level.sunFogDir[2] + "), " + level.sunFogBeginFadeAngle + ", " + level.sunFogEndFadeAngle + ", " + level.sunFogScale + ", " + level.skyFogIntensity + ", " + level.skyFogMinAngle + ", " + level.skyFogMaxAngle + " );" );
|
||||
else
|
||||
fileprint_launcher( "//\tsetExpFog( " + level.fognearplane + ", " + level.fogexphalfplane + ", " + level.fogcolor[0] + ", " + level.fogcolor[1] + ", " + level.fogcolor[2] + ", " + level.fogHDRColorIntensity + ", " + level.fogmaxopacity + ", 0, " + level.skyFogIntensity + ", " + level.skyFogMinAngle + ", " + level.skyFogMaxAngle + " );" );
|
||||
}
|
||||
fileprint_launcher( "\tVisionSetNaked( \"" + level.script + "\", 0 );" );
|
||||
fileprint_launcher( "}" );
|
||||
if ( !fileprint_launcher_end_file( "\\share\\raw\\maps\\createart\\" + level.script + "_art.gsc", true ) )
|
||||
return;
|
||||
//////////////////////////////
|
||||
|
||||
|
||||
// MP doesn't write [level]_art.csv?
|
||||
|
||||
|
||||
////////////////// [level]_fog.gsc
|
||||
if ( IsDefined( level.parse_fog_func ) )
|
||||
{
|
||||
fileprint_launcher_start_file();
|
||||
fileprint_launcher( "// _createart generated. modify at your own risk. Do not use block comments." );
|
||||
fileprint_launcher( "main()" );
|
||||
fileprint_launcher( "{" );
|
||||
common_scripts\_artCommon::print_fog_ents( true );
|
||||
fileprint_launcher( "}" );
|
||||
if ( !fileprint_launcher_end_file( "\\share\\raw\\maps\\createart\\" + level.script + "_fog.gsc", true ) )
|
||||
return;
|
||||
}
|
||||
//////////////////////////////
|
||||
|
||||
|
||||
////////////////// [level].vision
|
||||
if ( !common_scripts\_artCommon::print_vision( level.current_vision_set ) )
|
||||
return;
|
||||
|
||||
iprintlnbold( "Save successful!" );
|
||||
|
||||
PrintLn( "Art settings dumped success!" );
|
||||
}
|
||||
|
||||
add_vision_sets_from_triggers()
|
||||
{
|
||||
assert( IsDefined( level.vision_set_fog ) );
|
||||
|
||||
triggers = GetEntArray( "trigger_multiple_visionset" , "classname" );
|
||||
|
||||
// mkornkven: probably won't get anything -- need a way to get at the client trigger data?
|
||||
foreach( trigger in triggers )
|
||||
{
|
||||
name = undefined;
|
||||
|
||||
if( IsDefined( trigger.script_visionset ) )
|
||||
name = ToLower( trigger.script_visionset );
|
||||
else if ( IsDefined( trigger.script_visionset_start ) )
|
||||
name = ToLower( trigger.script_visionset_start );
|
||||
else if ( IsDefined( trigger.script_visionset_end ) )
|
||||
name = ToLower( trigger.script_visionset_end );
|
||||
|
||||
if ( IsDefined( name ) )
|
||||
add_vision_set( name );
|
||||
}
|
||||
}
|
||||
|
||||
add_vision_set( vision_set_name )
|
||||
{
|
||||
assert( vision_set_name == ToLower( vision_set_name ) );
|
||||
|
||||
if ( IsDefined( level.vision_set_fog[ vision_set_name ] ) )
|
||||
return;
|
||||
|
||||
create_default_vision_set_fog( vision_set_name );
|
||||
common_scripts\_artCommon::add_vision_set_to_list( vision_set_name );
|
||||
|
||||
IPrintLnBold( "new vision: " + vision_set_name );
|
||||
}
|
||||
|
||||
button_down( btn, btn2 )
|
||||
{
|
||||
pressed = level.players[0] ButtonPressed( btn );
|
||||
|
||||
if ( !pressed )
|
||||
{
|
||||
pressed = level.players[0] ButtonPressed( btn2 );
|
||||
}
|
||||
|
||||
if ( !IsDefined( level.buttons[ btn ] ) )
|
||||
{
|
||||
level.buttons[ btn ] = 0;
|
||||
}
|
||||
|
||||
// To Prevent Spam
|
||||
if ( GetTime() < level.buttons[ btn ] )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
level.buttons[ btn ] = GetTime() + 400;
|
||||
return pressed;
|
||||
}
|
||||
|
||||
updateFogFromScript()
|
||||
{
|
||||
if ( GetDvarInt( "scr_cmd_plr_sun" ) )
|
||||
{
|
||||
SetDevDvar( "scr_sunFogDir", AnglesToForward( level.players[0] GetPlayerAngles() ) );
|
||||
SetDevDvar( "scr_cmd_plr_sun", 0 );
|
||||
}
|
||||
|
||||
ent = get_fog_ent_for_vision_set( level.current_vision_set );
|
||||
|
||||
if( IsDefined( ent ) && isdefined( ent.name ) )
|
||||
{
|
||||
ent.startDist = level.fognearplane;
|
||||
ent.halfwayDist = level.fogexphalfplane;
|
||||
ent.red = level.fogcolor[ 0 ];
|
||||
ent.green = level.fogcolor[ 1 ];
|
||||
ent.blue = level.fogcolor[ 2 ];
|
||||
ent.HDRColorIntensity = level.fogHDRColorIntensity;
|
||||
ent.maxOpacity = level.fogmaxopacity;
|
||||
|
||||
ent.sunFogEnabled = level.sunFogEnabled;
|
||||
ent.sunRed = level.sunFogColor[ 0 ];
|
||||
ent.sunGreen = level.sunFogColor[ 1 ];
|
||||
ent.sunBlue = level.sunFogColor[ 2 ];
|
||||
ent.HDRSunColorIntensity = level.sunFogHDRColorIntensity;
|
||||
ent.sunDir = level.sunFogDir;
|
||||
ent.sunBeginFadeAngle = level.sunFogBeginFadeAngle;
|
||||
ent.sunEndFadeAngle = level.sunFogEndFadeAngle;
|
||||
ent.normalFogScale = level.sunFogScale;
|
||||
|
||||
ent.skyFogIntensity = level.skyFogIntensity;
|
||||
ent.skyFogMinAngle = level.skyFogMinAngle;
|
||||
ent.skyFogMaxAngle = level.skyFogMaxAngle;
|
||||
|
||||
if ( GetDvarInt( "scr_fog_disable" ) )
|
||||
{
|
||||
ent.startDist = 2000000000;
|
||||
ent.halfwayDist = 2000000001;
|
||||
ent.red = 0;
|
||||
ent.green = 0;
|
||||
ent.blue = 0;
|
||||
ent.HDRSunColorIntensity = 1;
|
||||
ent.maxOpacity = 0;
|
||||
ent.skyFogIntensity = 0;
|
||||
}
|
||||
|
||||
if ( IsDefined( level.parse_fog_func ) ) // Otherwise, this is the default set, which we don't want to set
|
||||
set_fog_to_ent_values( ent, 0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update_current_vision_set_dvars()
|
||||
{
|
||||
level.players[0] openpopupmenu("dev_vision_exec");
|
||||
wait( 0.05 );
|
||||
level.players[0] closepopupmenu();
|
||||
}
|
||||
|
||||
vision_set_changes( vision_set )
|
||||
{
|
||||
// Set the vision set and push the values to tweak dvars in code
|
||||
VisionSetNaked( vision_set, 0 );
|
||||
update_current_vision_set_dvars();
|
||||
level.current_vision_set = vision_set;
|
||||
}
|
||||
|
||||
vision_set_fog_changes( vision_set, transition_time )
|
||||
{
|
||||
vision_set_changes( vision_set );
|
||||
fog_ent = get_fog_ent_for_vision_set( vision_set );
|
||||
if ( IsDefined( fog_ent ) )
|
||||
{
|
||||
translateFogEntTosliders( fog_ent );
|
||||
if ( IsDefined( level.parse_fog_func ) ) // Otherwise, this is the default set, which we don't want to set
|
||||
set_fog_to_ent_values( fog_ent, transition_time);
|
||||
}
|
||||
}
|
||||
|
||||
get_fog_ent_for_vision_set( vision_set )
|
||||
{
|
||||
fog_ent = level.vision_set_fog[ ToLower( vision_set ) ];
|
||||
if ( using_hdr_fog() && IsDefined( fog_ent ) && IsDefined( fog_ent.HDROverride ) )
|
||||
fog_ent = level.vision_set_fog[ ToLower( fog_ent.HDROverride ) ];
|
||||
|
||||
return fog_ent;
|
||||
}
|
||||
|
||||
using_hdr_fog()
|
||||
{
|
||||
if ( !IsDefined( level.console ) )
|
||||
set_console_status();
|
||||
AssertEx( IsDefined( level.console ) && IsDefined( level.xb3 ) && IsDefined( level.ps4 ), "Expected platform defines to be complete." );
|
||||
|
||||
return is_gen4();
|
||||
}
|
||||
|
||||
translateFogEntTosliders( ent )
|
||||
{
|
||||
SetDevDvar( "scr_fog_exp_halfplane", ent.halfwayDist );
|
||||
SetDevDvar( "scr_fog_nearplane", ent.startDist );
|
||||
SetDevDvar( "scr_fog_color", ( ent.red, ent.green, ent.blue ) );
|
||||
SetDevDvar( "scr_fog_color_intensity", ent.HDRColorIntensity );
|
||||
SetDevDvar( "scr_fog_max_opacity", ent.maxOpacity );
|
||||
|
||||
SetDevDvar( "scr_skyFogIntensity", ent.skyFogIntensity );
|
||||
SetDevDvar( "scr_skyFogMinAngle", ent.skyFogMinAngle );
|
||||
SetDevDvar( "scr_skyFogMaxAngle", ent.skyFogMaxAngle );
|
||||
|
||||
if ( IsDefined( ent.sunFogEnabled ) && ent.sunFogEnabled )
|
||||
{
|
||||
SetDevDvar( "scr_sunFogEnabled", 1 );
|
||||
SetDevDvar( "scr_sunFogColor", ( ent.sunRed, ent.sunGreen,ent.sunBlue ) );
|
||||
SetDevDvar( "scr_sunFogColorIntensity", ent.HDRSunColorIntensity );
|
||||
SetDevDvar( "scr_sunFogDir", ent.sunDir );
|
||||
SetDevDvar( "scr_sunFogBeginFadeAngle", ent.sunBeginFadeAngle );
|
||||
SetDevDvar( "scr_sunFogEndFadeAngle", ent.sunEndFadeAngle );
|
||||
SetDevDvar( "scr_sunFogScale", ent.normalFogScale );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDevDvar( "scr_sunFogEnabled", 0 );
|
||||
}
|
||||
}
|
||||
|
||||
set_fog_to_ent_values( ent, transition_time )
|
||||
{
|
||||
if ( IsDefined( ent.sunFogEnabled) && ent.sunFogEnabled )
|
||||
{
|
||||
if ( !isPlayer( self ) )
|
||||
{
|
||||
SetExpFog(
|
||||
ent.startDist,
|
||||
ent.halfwayDist,
|
||||
ent.red,
|
||||
ent.green,
|
||||
ent.blue,
|
||||
ent.HDRColorIntensity,
|
||||
ent.maxOpacity,
|
||||
transition_time,
|
||||
ent.sunRed,
|
||||
ent.sunGreen,
|
||||
ent.sunBlue,
|
||||
ent.HDRSunColorIntensity,
|
||||
ent.sunDir,
|
||||
ent.sunBeginFadeAngle,
|
||||
ent.sunEndFadeAngle,
|
||||
ent.normalFogScale,
|
||||
ent.skyFogIntensity,
|
||||
ent.skyFogMinAngle,
|
||||
ent.skyFogMaxAngle );
|
||||
}
|
||||
else
|
||||
{
|
||||
self PlayerSetExpFog(
|
||||
ent.startDist,
|
||||
ent.halfwayDist,
|
||||
ent.red,
|
||||
ent.green,
|
||||
ent.blue,
|
||||
ent.HDRColorIntensity,
|
||||
ent.maxOpacity,
|
||||
transition_time,
|
||||
ent.sunRed,
|
||||
ent.sunGreen,
|
||||
ent.sunBlue,
|
||||
ent.HDRSunColorIntensity,
|
||||
ent.sunDir,
|
||||
ent.sunBeginFadeAngle,
|
||||
ent.sunEndFadeAngle,
|
||||
ent.normalFogScale,
|
||||
ent.skyFogIntensity,
|
||||
ent.skyFogMinAngle,
|
||||
ent.skyFogMaxAngle );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isPlayer( self ) )
|
||||
{
|
||||
SetExpFog(
|
||||
ent.startDist,
|
||||
ent.halfwayDist,
|
||||
ent.red,
|
||||
ent.green,
|
||||
ent.blue,
|
||||
ent.HDRColorIntensity,
|
||||
ent.maxOpacity,
|
||||
transition_time,
|
||||
ent.skyFogIntensity,
|
||||
ent.skyFogMinAngle,
|
||||
ent.skyFogMaxAngle );
|
||||
}
|
||||
else
|
||||
{
|
||||
self PlayerSetExpFog(
|
||||
ent.startDist,
|
||||
ent.halfwayDist,
|
||||
ent.red,
|
||||
ent.green,
|
||||
ent.blue,
|
||||
ent.HDRColorIntensity,
|
||||
ent.maxOpacity,
|
||||
transition_time,
|
||||
ent.skyFogIntensity,
|
||||
ent.skyFogMinAngle,
|
||||
ent.skyFogMaxAngle );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create_default_vision_set_fog( name )
|
||||
{
|
||||
ent = create_vision_set_fog( name );
|
||||
ent.startDist = 3764.17;
|
||||
ent.halfwayDist = 19391;
|
||||
ent.red = 0.661137;
|
||||
ent.green = 0.554261;
|
||||
ent.blue = 0.454014;
|
||||
ent.maxOpacity = 0.7;
|
||||
ent.transitionTime = 0;
|
||||
ent.skyFogIntensity = 0;
|
||||
ent.skyFogMinAngle = 0;
|
||||
ent.skyFogMaxAngle = 0;
|
||||
}
|
||||
|
||||
hud_init()
|
||||
{
|
||||
listsize = 7;
|
||||
|
||||
hudelems = [];
|
||||
spacer = 15;
|
||||
div = int( listsize / 2 );
|
||||
org = 240 - div * spacer;
|
||||
alphainc = .5 / div;
|
||||
alpha = alphainc;
|
||||
|
||||
for ( i = 0;i < listsize;i++ )
|
||||
{
|
||||
hudelems[ i ] = _newhudelem();
|
||||
hudelems[ i ].location = 0;
|
||||
hudelems[ i ].alignX = "left";
|
||||
hudelems[ i ].alignY = "middle";
|
||||
hudelems[ i ].foreground = 1;
|
||||
hudelems[ i ].fontScale = 2;
|
||||
hudelems[ i ].sort = 20;
|
||||
if ( i == div )
|
||||
hudelems[ i ].alpha = 1;
|
||||
else
|
||||
hudelems[ i ].alpha = alpha;
|
||||
|
||||
hudelems[ i ].x = 20;
|
||||
hudelems[ i ].y = org;
|
||||
hudelems[ i ] _settext( "." );
|
||||
|
||||
if ( i == div )
|
||||
alphainc *= -1;
|
||||
|
||||
alpha += alphainc;
|
||||
|
||||
org += spacer;
|
||||
}
|
||||
|
||||
level.spam_group_hudelems = hudelems;
|
||||
}
|
||||
|
||||
_newhudelem()
|
||||
{
|
||||
if ( !isdefined( level.scripted_elems ) )
|
||||
level.scripted_elems = [];
|
||||
elem = newhudelem(); // client?
|
||||
level.scripted_elems[ level.scripted_elems.size ] = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
_settext( text )
|
||||
{
|
||||
self.realtext = text;
|
||||
self setDevText( "_" );
|
||||
self thread _clearalltextafterhudelem();
|
||||
sizeofelems = 0;
|
||||
foreach ( elem in level.scripted_elems )
|
||||
{
|
||||
if ( isdefined( elem.realtext ) )
|
||||
{
|
||||
sizeofelems += elem.realtext.size;
|
||||
elem setDevText( elem.realtext );
|
||||
}
|
||||
}
|
||||
println( "Size of elems: " + sizeofelems );
|
||||
}
|
||||
|
||||
_clearalltextafterhudelem()
|
||||
{
|
||||
if ( level._clearalltextafterhudelem )
|
||||
return;
|
||||
level._clearalltextafterhudelem = true;
|
||||
self clearalltextafterhudelem();
|
||||
wait .05;
|
||||
level._clearalltextafterhudelem = false;
|
||||
}
|
||||
|
||||
setgroup_up()
|
||||
{
|
||||
reset_cmds();
|
||||
|
||||
current_vision_set_name = level.current_vision_set;
|
||||
|
||||
index = array_find( level.vision_set_names, current_vision_set_name );
|
||||
if ( !IsDefined( index ) )
|
||||
return;
|
||||
|
||||
index -= 1;
|
||||
|
||||
if ( index < 0 )
|
||||
return;
|
||||
|
||||
setcurrentgroup( level.vision_set_names[index] );
|
||||
}
|
||||
|
||||
setgroup_down()
|
||||
{
|
||||
reset_cmds();
|
||||
|
||||
current_vision_set_name = level.current_vision_set;
|
||||
|
||||
index = array_find( level.vision_set_names, current_vision_set_name );
|
||||
if ( !IsDefined( index ) )
|
||||
return;
|
||||
|
||||
index += 1;
|
||||
|
||||
if ( index >= level.vision_set_names.size )
|
||||
return;
|
||||
|
||||
setcurrentgroup( level.vision_set_names[index] );
|
||||
}
|
||||
|
||||
reset_cmds()
|
||||
{
|
||||
SetDevDvar( "scr_select_art_next", 0 );
|
||||
SetDevDvar( "scr_select_art_prev", 0 );
|
||||
}
|
||||
|
||||
setcurrentgroup( group )
|
||||
{
|
||||
level.spam_model_current_group = group;
|
||||
|
||||
index = array_find( level.vision_set_names, group );
|
||||
if ( !IsDefined( index ) )
|
||||
index = -1;
|
||||
|
||||
hud_list_size = level.spam_group_hudelems.size;
|
||||
hud_start_index = index - int( hud_list_size / 2 );
|
||||
|
||||
for ( i = 0; i < hud_list_size; i++ )
|
||||
{
|
||||
hud_index = hud_start_index + i;
|
||||
if ( hud_index < 0 || hud_index >= level.vision_set_names.size )
|
||||
{
|
||||
level.spam_group_hudelems[i] _settext( "." );
|
||||
continue;
|
||||
}
|
||||
|
||||
level.spam_group_hudelems[i] _settext( level.vision_set_names[hud_index] );
|
||||
}
|
||||
|
||||
group_name = "";
|
||||
if ( index >= 0 )
|
||||
group_name = level.vision_set_names[ index ];
|
||||
|
||||
vision_set_fog_changes( group_name, 0 );
|
||||
}
|
||||
#/
|
||||
|
||||
create_vision_set_fog( fogsetName )
|
||||
{
|
||||
/#
|
||||
if ( !isdefined( level.vision_set_fog ) )
|
||||
level.vision_set_fog = [];
|
||||
|
||||
ent = SpawnStruct();
|
||||
ent.name = fogsetName;
|
||||
|
||||
// Special init for variables that may not exist on every set of fog yet -- add variable defaults here to avoid IsDefined checks everywhere later on
|
||||
ent.HDRColorIntensity = 1;
|
||||
ent.HDRSunColorIntensity = 1;
|
||||
ent.skyFogIntensity = 0;
|
||||
ent.skyFogMinAngle = 0;
|
||||
ent.skyFogMaxAngle = 0;
|
||||
|
||||
level.vision_set_fog[ ToLower(fogsetName) ] = ent;
|
||||
return ent;
|
||||
#/
|
||||
}
|
||||
|
139
maps/mp/_audio.gsc
Normal file
139
maps/mp/_audio.gsc
Normal file
@ -0,0 +1,139 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init_audio()
|
||||
{
|
||||
if ( !IsDefined( level.audio ) )
|
||||
{
|
||||
level.audio = SpawnStruct();
|
||||
}
|
||||
|
||||
init_reverb();
|
||||
init_whizby();
|
||||
|
||||
level.onPlayerConnectAudioInit = ::OnPlayerConnectAudioInit;
|
||||
}
|
||||
|
||||
OnPlayerConnectAudioInit()
|
||||
{
|
||||
self apply_reverb( "default" );
|
||||
// self apply_whizby(); <-- Does not work yet... Looks like it overflows the server.
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Reverb Section
|
||||
//---------------------------------------------------------
|
||||
init_reverb()
|
||||
{
|
||||
add_reverb( "default", "generic", 0.15, 0.9, 2 );
|
||||
}
|
||||
|
||||
add_reverb( name, type, wetlevel, drylevel, fadetime )
|
||||
{
|
||||
Assert( IsDefined( type ) );
|
||||
Assert( IsDefined( wetlevel ) );
|
||||
Assert( IsDefined( drylevel ) );
|
||||
|
||||
reverb = [];
|
||||
|
||||
is_roomtype_valid( type );
|
||||
|
||||
reverb[ "roomtype" ] = type;
|
||||
reverb[ "wetlevel" ] = wetlevel;
|
||||
reverb[ "drylevel" ] = drylevel;
|
||||
reverb[ "fadetime" ] = fadetime;
|
||||
|
||||
level.audio.reverb_settings[ name ] = reverb;
|
||||
}
|
||||
|
||||
is_roomtype_valid( type )
|
||||
{
|
||||
/#
|
||||
switch ( type )
|
||||
{
|
||||
case "generic":
|
||||
case "paddedcell":
|
||||
case "room":
|
||||
case "bathroom":
|
||||
case "livingroom":
|
||||
case "stoneroom":
|
||||
case "auditorium":
|
||||
case "concerthall":
|
||||
case "cave":
|
||||
case "arena":
|
||||
case "hangar":
|
||||
case "carpetedhallway":
|
||||
case "hallway":
|
||||
case "stonecorridor":
|
||||
case "alley":
|
||||
case "forest":
|
||||
case "city":
|
||||
case "mountains":
|
||||
case "quarry":
|
||||
case "plain":
|
||||
case "parkinglot":
|
||||
case "sewerpipe":
|
||||
case "underwater":
|
||||
case "drugged":
|
||||
case "dizzy":
|
||||
case "psychotic":
|
||||
return;
|
||||
default:
|
||||
AssertMsg( type + " is an Invalid Roomtype" );
|
||||
break;
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
apply_reverb( name )
|
||||
{
|
||||
if ( !IsDefined( level.audio.reverb_settings[ name ] ) )
|
||||
{
|
||||
reverb = level.audio.reverb_settings[ "default" ];
|
||||
}
|
||||
else
|
||||
{
|
||||
reverb = level.audio.reverb_settings[ name ];
|
||||
}
|
||||
|
||||
self SetReverb( "snd_enveffectsprio_level", reverb[ "roomtype" ], reverb[ "drylevel" ], reverb[ "wetlevel" ], reverb[ "fadetime" ] );
|
||||
// self SetClientDvar( "cg_levelReverbRoomType", reverb[ "roomtype" ] );
|
||||
// self SetClientDvar( "cg_levelReverbDryLevel", reverb[ "drylevel" ] );
|
||||
// self SetClientDvar( "cg_levelReverbWetLevel", reverb[ "wetlevel" ] );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// whizBy Section
|
||||
//---------------------------------------------------------
|
||||
|
||||
init_whizby()
|
||||
{
|
||||
SetDevDvar( "snd_newwhizby", 1 );
|
||||
|
||||
// Default settings -- Call wrappers in your level to overwrite.
|
||||
level.audio.whizby_settings = [];
|
||||
set_whizby_radius( 15.0, 30.0, 50.0 );
|
||||
set_whizby_spread( 150.0, 250.0, 350.0 );
|
||||
}
|
||||
|
||||
set_whizby_radius( near, medium, far )
|
||||
{
|
||||
assertex( near != 0, "whizby near radius cannot be zero" );
|
||||
level.audio.whizby_settings[ "radius" ] = [ near, medium, far ];
|
||||
}
|
||||
|
||||
set_whizby_spread( near, medium, far )
|
||||
{
|
||||
level.audio.whizby_settings[ "spread" ] = [ near, medium, far ];
|
||||
}
|
||||
|
||||
apply_whizby()
|
||||
{
|
||||
settings = level.audio.whizby_settings;
|
||||
|
||||
spread = settings[ "spread" ];
|
||||
rad = settings[ "radius" ];
|
||||
|
||||
self SetWhizbySpreads( spread[ 0 ], spread[ 1 ], spread[ 2 ] );
|
||||
self SetWhizbyRadii( rad[ 0 ], rad[ 1 ], rad[ 2 ] );
|
||||
}
|
1084
maps/mp/_awards.gsc
Normal file
1084
maps/mp/_awards.gsc
Normal file
File diff suppressed because it is too large
Load Diff
335
maps/mp/_barrels_leak.gsc
Normal file
335
maps/mp/_barrels_leak.gsc
Normal file
@ -0,0 +1,335 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CONSTANTS //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
level_limit_barrel_fx = 8;
|
||||
max_fires_from_entity = 4;
|
||||
level_barrel_fx_chance = 33;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// LOGIC //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
main()
|
||||
{
|
||||
if ( IsDefined( level.barrels_init ) )
|
||||
return;
|
||||
|
||||
|
||||
level.barrels_init = true;
|
||||
//level._barrel_fx_time = 25; //handle this individually for different barrel types
|
||||
barrels = GetEntArray( "barrel_shootable", "targetname" );
|
||||
if ( !barrels.size )
|
||||
return;
|
||||
level._barrels = SpawnStruct();
|
||||
level._barrels.num_barrel_fx = 0;
|
||||
|
||||
barrels thread precacheFX();
|
||||
barrels thread methodsInit();
|
||||
|
||||
thread post_load( barrels );
|
||||
}
|
||||
|
||||
post_load( barrels )
|
||||
{
|
||||
waittillframeend;// insure that structs are initialized
|
||||
if( level.createFX_enabled )
|
||||
return;
|
||||
array_thread( barrels, ::barrelsetup );
|
||||
}
|
||||
|
||||
barrelsetup()
|
||||
{
|
||||
self SetCanDamage( true );
|
||||
self SetCanRadiusDamage( false ); // optimization
|
||||
self.barrel_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 barrel_wait_loop();
|
||||
}
|
||||
|
||||
barrel_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_barrel_fx_chance )
|
||||
continue;
|
||||
}
|
||||
hasTakenDamage = true;
|
||||
|
||||
result = self barrel_logic( direction_vec, P, type, attacker );
|
||||
if ( result )
|
||||
remaining--;
|
||||
|
||||
if ( remaining <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
self SetCanDamage( false );
|
||||
}
|
||||
|
||||
barrel_logic( direction_vec, P, type, damageOwner )
|
||||
{
|
||||
if ( level._barrels.num_barrel_fx > level_limit_barrel_fx )
|
||||
return false;
|
||||
|
||||
if ( !isDefined( level._barrels._barrel_methods[ type ] ) )
|
||||
P = self barrel_calc_nofx( P, type );
|
||||
else
|
||||
P = self [[ level._barrels._barrel_methods[ type ] ]]( P, type );
|
||||
|
||||
if ( !isdefined( P ) )
|
||||
return false;
|
||||
|
||||
if ( IsDefined( damageOwner.classname ) && damageOwner.classname == "worldspawn" )
|
||||
return false;
|
||||
|
||||
foreach ( value in self.barrel_fx_array )
|
||||
{
|
||||
if ( DistanceSquared( P, value.origin ) < 25 )
|
||||
return false;
|
||||
}
|
||||
|
||||
//calculate the vector derived from the center line of our barrel 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 barrelfx( P, vec, damageOwner );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//DC_NOTE commented out all sound related stuff because it was giving me grief in mp_zulu
|
||||
barrelfx( P, vec, damageOwner )
|
||||
{
|
||||
time = level._barrels.fx_time[ self.script_noteworthy ] ;
|
||||
fx_time = level._barrels._barrel_fx_time[ self.script_noteworthy ] ;
|
||||
intervals = Int( fx_time / time );// loops for 25 seconds
|
||||
intervals_end = 30;
|
||||
hitsnd = level._barrels._sound[ self.script_noteworthy + "_hit" ];
|
||||
loopsnd = level._barrels._sound[ self.script_noteworthy + "_loop" ];
|
||||
endsnd = level._barrels._sound[ self.script_noteworthy + "_end" ];
|
||||
|
||||
snd = Spawn( "script_origin", P );
|
||||
// snd Hide();
|
||||
snd PlaySound( hitsnd );
|
||||
snd PlayLoopSound( loopsnd );
|
||||
self.barrel_fx_array[ self.barrel_fx_array.size ] = snd;
|
||||
|
||||
// if ( isSP() || self.script_noteworthy != "steam" )
|
||||
if ( isSP() )
|
||||
self thread barrel_damage( P, vec, damageOwner, snd );
|
||||
|
||||
//rotate the emitter angle over time
|
||||
efx_rot = Spawn( "script_model", P );
|
||||
efx_rot SetModel( "tag_origin" );
|
||||
efx_rot.angles = VectorToAngles( vec );
|
||||
wait .05;//cant play fx on same frame it's spawned in mp appearantly
|
||||
PlayFXOnTag( level._barrels._effect[ self.script_noteworthy ] , efx_rot, "tag_origin" );
|
||||
level._barrels.num_barrel_fx++;
|
||||
efx_rot RotatePitch( 90, time, 1, 1 );
|
||||
wait time;
|
||||
StopFXOnTag( level._barrels._effect[ self.script_noteworthy ] , efx_rot, "tag_origin" );
|
||||
intervals--;
|
||||
//now check for other fx and rest of intervals
|
||||
while ( level._barrels.num_barrel_fx <= level_limit_barrel_fx && intervals > 0 )
|
||||
{
|
||||
efx_rot = Spawn( "script_model", P );
|
||||
efx_rot SetModel( "tag_origin" );
|
||||
efx_rot.angles = VectorToAngles( vec );
|
||||
wait .05;//cant play fx on same frame it's spawned in mp appearantly
|
||||
PlayFXOnTag( level._barrels._effect[ self.script_noteworthy ] , efx_rot, "tag_origin" );
|
||||
level._barrels.num_barrel_fx++;
|
||||
efx_rot RotatePitch( 90, time, 1, 1 );
|
||||
wait time;
|
||||
StopFXOnTag( level._barrels._effect[ self.script_noteworthy ] , efx_rot, "tag_origin" );
|
||||
}
|
||||
|
||||
// snd PlaySound( endsnd );
|
||||
wait( .5 );
|
||||
// snd StopLoopSound( loopsnd );
|
||||
snd Delete();
|
||||
self.barrel_fx_array = array_removeUndefined( self.barrel_fx_array );
|
||||
|
||||
level._barrels.num_barrel_fx--;
|
||||
}
|
||||
|
||||
barrel_damage( P, vec, damageOwner, fx )
|
||||
{
|
||||
if ( !allow_barrel_damage() )
|
||||
return;
|
||||
|
||||
fx endon( "death" );
|
||||
|
||||
origin = fx.origin + ( VectorNormalize( vec ) * 40 );
|
||||
dmg = level._barrels._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_barrel_damage()
|
||||
{
|
||||
if( !isSP() )
|
||||
return false;
|
||||
|
||||
if ( !isDefined( level.barrelsDamage ) )
|
||||
return false;
|
||||
|
||||
return ( level.barrelsDamage );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CALCULATIONS / SETUP //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
methodsInit()
|
||||
{
|
||||
level._barrels._barrel_methods = [];
|
||||
level._barrels._barrel_methods[ "MOD_UNKNOWN" ] = ::barrel_calc_splash;
|
||||
level._barrels._barrel_methods[ "MOD_PISTOL_BULLET" ] = ::barrel_calc_ballistic;
|
||||
level._barrels._barrel_methods[ "MOD_RIFLE_BULLET" ] = ::barrel_calc_ballistic;
|
||||
level._barrels._barrel_methods[ "MOD_GRENADE" ] = ::barrel_calc_splash;
|
||||
level._barrels._barrel_methods[ "MOD_GRENADE_SPLASH" ] = ::barrel_calc_splash;
|
||||
level._barrels._barrel_methods[ "MOD_PROJECTILE" ] = ::barrel_calc_splash;
|
||||
level._barrels._barrel_methods[ "MOD_PROJECTILE_SPLASH" ] = ::barrel_calc_splash;
|
||||
level._barrels._barrel_methods[ "MOD_TRIGGER_HURT" ] = ::barrel_calc_splash;
|
||||
level._barrels._barrel_methods[ "MOD_EXPLOSIVE" ] = ::barrel_calc_splash;
|
||||
level._barrels._barrel_methods[ "MOD_EXPLOSIVE_BULLET" ] = ::barrel_calc_splash;
|
||||
}
|
||||
|
||||
barrel_calc_ballistic( P, type )
|
||||
{
|
||||
return P;
|
||||
}
|
||||
|
||||
barrel_calc_splash( P, type )
|
||||
{
|
||||
vec = VectorNormalize( VectorFromLineToPoint( self.A, self.B, P ) );
|
||||
P = PointOnSegmentNearestToPoint( self.A, self.B, P );
|
||||
return( P + ( vec * 4 ) );
|
||||
}
|
||||
|
||||
barrel_calc_nofx( P, type )
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
|
||||
precacheFX()
|
||||
{
|
||||
oil_leak = false;
|
||||
oil_cap = false;
|
||||
beer_leak = false;
|
||||
foreach ( value in self )
|
||||
{
|
||||
if ( value.script_noteworthy == "oil_leak" )
|
||||
{
|
||||
value willNeverChange();
|
||||
oil_leak = true;
|
||||
}
|
||||
else if ( value.script_noteworthy == "oil_cap" )
|
||||
{
|
||||
value willNeverChange();
|
||||
oil_cap = true;
|
||||
}
|
||||
else if ( value.script_noteworthy == "beer_leak" )
|
||||
{
|
||||
value willNeverChange();
|
||||
beer_leak = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
println( "Unknown 'barrel_shootable' script_noteworthy type '%s'\n", value.script_noteworthy );
|
||||
}
|
||||
}
|
||||
|
||||
//DC_NOTE commented out all sound related stuff because it was giving me grief in mp_zulu
|
||||
if ( oil_leak )
|
||||
{
|
||||
level._barrels._effect[ "oil_leak" ] = loadfx( "fx/impacts/pipe_oil_barrel_spill" );
|
||||
//level._barrels._sound[ "oil_leak_hit" ] = "mtl_oil_barrel_hit";
|
||||
//level._barrels._sound[ "oil_leak_loop" ] = "mtl_oil_barrel_hiss_loop";
|
||||
//level._barrels._sound[ "oil_leak_end" ] = "mtl_oil_barrel_hiss_loop_end";
|
||||
level._barrels.fx_time[ "oil_leak" ] = 6;
|
||||
level._barrels._barrel_fx_time["oil_leak"] = 6;
|
||||
level._barrels._dmg[ "oil_leak" ] = 5;
|
||||
}
|
||||
if ( oil_cap )
|
||||
{
|
||||
level._barrels._effect[ "oil_cap" ] = loadfx( "fx/impacts/pipe_oil_barrel_squirt" );
|
||||
//level._barrels._sound[ "oil_cap_hit" ] = "mtl_oil_barrel_hit";
|
||||
//level._barrels._sound[ "oil_cap_loop" ] = "mtl_oil_barrel_hiss_loop";
|
||||
//level._barrels._sound[ "oil_cap_end" ] = "mtl_oil_barrel_hiss_loop_end";
|
||||
level._barrels.fx_time[ "oil_cap" ] = 3;
|
||||
level._barrels._dmg[ "oil_cap" ] = 5;
|
||||
level._barrels._barrel_fx_time["oil_cap"] = 5;
|
||||
}
|
||||
if ( beer_leak )//DC_TODO create beer fx
|
||||
{
|
||||
level._barrels._effect[ "beer_leak" ] = loadfx( "fx/impacts/beer_barrel_spill" );
|
||||
level._barrels._sound[ "beer_leak_hit" ] = "mtl_beer_keg_hit";
|
||||
level._barrels._sound[ "beer_leak_loop" ] = "mtl_beer_keg_hiss_loop";
|
||||
level._barrels._sound[ "beer_leak_end" ] = "mtl_beer_keg_hiss_loop_end";
|
||||
level._barrels.fx_time[ "beer_leak" ] = 6;
|
||||
level._barrels._barrel_fx_time["beer_leak"] = 6;
|
||||
level._barrels._dmg[ "beer_leak" ] = 5;
|
||||
}
|
||||
}
|
753
maps/mp/_breach.gsc
Normal file
753
maps/mp/_breach.gsc
Normal file
@ -0,0 +1,753 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
main()
|
||||
{
|
||||
thread main_thread();
|
||||
}
|
||||
|
||||
main_thread()
|
||||
{
|
||||
breach_precache();
|
||||
waitframe();
|
||||
|
||||
breach = getstructarray("breach", "targetname");
|
||||
array_thread(breach, ::breach_init);
|
||||
}
|
||||
|
||||
breach_precache()
|
||||
{
|
||||
level.breach_icon_count = -1;
|
||||
|
||||
level._effect["default"] = loadfx("fx/explosions/breach_room_cheap");
|
||||
}
|
||||
|
||||
breach_init()
|
||||
{
|
||||
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
|
||||
return;
|
||||
|
||||
if(!IsDefined(self.target))
|
||||
return;
|
||||
self.breach_targets = [];
|
||||
self.auto_breach_gametypes = [];
|
||||
|
||||
if(IsDefined(self.script_noteworthy))
|
||||
{
|
||||
toks = StrTok(self.script_noteworthy, ",");
|
||||
foreach(tok in toks)
|
||||
{
|
||||
if(GetSubStr(tok,0,7) == "not_in_")
|
||||
{
|
||||
self.auto_breach_gametypes[self.auto_breach_gametypes.size] = GetSubStr(tok,7,tok.size);
|
||||
}
|
||||
|
||||
if(tok == "only_if_allowClassChoice")
|
||||
{
|
||||
if(!allowClassChoice())
|
||||
{
|
||||
self.auto_breach_gametypes[self.auto_breach_gametypes.size] = level.gameType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ents = GetEntArray(self.target, "targetname");
|
||||
structs = getstructarray(self.target, "targetname");
|
||||
targets = array_combine(ents, structs);
|
||||
nodes = self getLinknameNodes();
|
||||
foreach (node in nodes)
|
||||
{
|
||||
node.isPathNode = true;
|
||||
}
|
||||
targets = array_combine(targets, nodes);
|
||||
|
||||
foreach(target in targets)
|
||||
{
|
||||
if(!IsDefined(target.script_noteworthy))
|
||||
{
|
||||
target.script_noteworthy = target.classname;
|
||||
}
|
||||
|
||||
if(target.script_noteworthy == "trigger_use_touch")
|
||||
{
|
||||
target UseTriggerRequireLookAt();
|
||||
target.script_noteworthy = "trigger_use";
|
||||
}
|
||||
if(!IsDefined(target.isPathNode) || target.isPathNode == false)
|
||||
target.script_noteworthy = ToLower(target.script_noteworthy);
|
||||
types = StrTok(target.script_noteworthy, ", ");
|
||||
|
||||
foreach(type in types)
|
||||
{
|
||||
event_name = undefined;
|
||||
toks = StrTok(type, "_");
|
||||
if(toks.size>=3 && toks[toks.size-2] == "on")
|
||||
{
|
||||
event_name = toks[toks.size-1];
|
||||
type = toks[0];
|
||||
for(i=1;i<toks.size-2;i++)
|
||||
type = type + "_" + toks[i];
|
||||
}
|
||||
|
||||
useSide = false;
|
||||
toks = StrTok(type, "_");
|
||||
if(toks.size>=2 && toks[toks.size-1] == "useside")
|
||||
{
|
||||
useSide = true;
|
||||
type = toks[0];
|
||||
for(i=1;i<toks.size-2;i++)
|
||||
type = type + "_" + toks[i];
|
||||
}
|
||||
|
||||
|
||||
add_breach_target(target, type, event_name, useSide);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case "show":
|
||||
case "animated":
|
||||
target Hide();
|
||||
break;
|
||||
case "solid":
|
||||
if( IsDefined( target.spawnflags ) && ( target.spawnflags & 2 ) ) // AI_SIGHT_LINE
|
||||
{
|
||||
target SetAISightLineVisible( 0 );
|
||||
}
|
||||
target NotSolid();
|
||||
break;
|
||||
case "teleport_show":
|
||||
target trigger_off();
|
||||
break;
|
||||
case "use_icon":
|
||||
// self thread breach_icon("use", target.origin, target.angles, ["breach_used","breach_activated"] );
|
||||
break;
|
||||
case "trigger_damage":
|
||||
self thread breach_damage_watch(target);
|
||||
break;
|
||||
case "fx":
|
||||
if(!IsDefined(target.angles))
|
||||
target.angles = (0,0,0);
|
||||
break;
|
||||
case "connect_node":
|
||||
target DisconnectNode();
|
||||
break;
|
||||
case "disconnect_node":
|
||||
target ConnectNode();
|
||||
break;
|
||||
case "delete":
|
||||
if( IsDefined( target.spawnflags ) && ( target.spawnflags & 2 ) ) // AI_SIGHT_LINE
|
||||
{
|
||||
target SetAISightLineVisible( 1 );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(level.createFX_enabled)
|
||||
return;
|
||||
|
||||
use_trigger = get_breach_target("trigger_use");
|
||||
if(IsDefined(use_trigger))
|
||||
{
|
||||
|
||||
if(!IsDefined(get_breach_target("sound")))
|
||||
{
|
||||
script_origin = spawn("script_origin", use_trigger.origin);
|
||||
add_breach_target(script_origin, "sound");
|
||||
}
|
||||
if(!IsDefined(get_breach_target("damage")))
|
||||
{
|
||||
damage = SpawnStruct();
|
||||
damage.origin = use_trigger.origin;
|
||||
add_breach_target(damage, "damage");
|
||||
}
|
||||
|
||||
//init default damage info,
|
||||
damages = get_breach_targets("damage");
|
||||
foreach(damage in damages)
|
||||
{
|
||||
if(!IsDefined(damage.radius))
|
||||
damage.radius = 128;
|
||||
if(!IsDefined(damage.max_damage))
|
||||
damage.max_damage = 100;
|
||||
if(!IsDefined(damage.min_damage))
|
||||
damage.min_damage = 1;
|
||||
}
|
||||
self thread breach_use_watch();
|
||||
}
|
||||
|
||||
self thread breach_on_activate();
|
||||
|
||||
self breach_on_event("init");
|
||||
|
||||
foreach(type in self.auto_breach_gametypes)
|
||||
{
|
||||
if(level.gametype == type)
|
||||
{
|
||||
self notify("breach_activated", undefined, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
add_breach_target(target, action, event_name, useSide)
|
||||
{
|
||||
if(!IsDefined(event_name))
|
||||
event_name = "activate";
|
||||
if(!IsDefined(useSide))
|
||||
useSide = false;
|
||||
|
||||
if(!IsDefined(self.breach_targets[event_name]))
|
||||
self.breach_targets[event_name] = [];
|
||||
|
||||
if(!IsDefined(self.breach_targets[event_name][action]))
|
||||
self.breach_targets[event_name][action] = [];
|
||||
|
||||
s = spawnStruct();
|
||||
s.target = target;
|
||||
|
||||
//Check if object has a facing
|
||||
if(useSide)
|
||||
{
|
||||
s.facing_dot = 0;
|
||||
s.facing_angles3d = false;
|
||||
s.facing_dir = AnglesToForward(target.angles);
|
||||
|
||||
if(IsDefined(target.target))
|
||||
{
|
||||
target_targets = getstructarray(target.target, "targetname");
|
||||
foreach(target_target in target_targets)
|
||||
{
|
||||
if(!IsDefined(target_target.script_noteworthy))
|
||||
continue;
|
||||
|
||||
switch(target_target.script_noteworthy)
|
||||
{
|
||||
case "angles":
|
||||
case "angles_3d":
|
||||
s.facing_angles3d = true;
|
||||
//fall through
|
||||
case "angles_2d":
|
||||
if(!IsDefined(s.angles3d))
|
||||
s.facing_angles3d = false;
|
||||
s.facing_dir = AnglesToForward(target_target.angles);
|
||||
if(IsDefined(target_target.script_dot))
|
||||
s.facing_dot = target_target.script_dot;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size = self.breach_targets[event_name][action].size;
|
||||
self.breach_targets[event_name][action][size] = s;
|
||||
}
|
||||
|
||||
get_breach_target(action, event_name, player)
|
||||
{
|
||||
targets = get_breach_targets(action, event_name, player);
|
||||
if(targets.size>0)
|
||||
{
|
||||
return targets[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
get_breach_targets(action, event_name, player)
|
||||
{
|
||||
targets = [];
|
||||
|
||||
if(!IsDefined(event_name))
|
||||
event_name = "activate";
|
||||
|
||||
if(!IsDefined(self.breach_targets[event_name]))
|
||||
return targets;
|
||||
if(!IsDefined(self.breach_targets[event_name][action]))
|
||||
return targets;
|
||||
|
||||
foreach(s in self.breach_targets[event_name][action])
|
||||
{
|
||||
if(IsDefined(s.facing_dir) && IsDefined(player))
|
||||
{
|
||||
player_dir = player.origin - s.target.origin;
|
||||
if(!s.facing_angles3d)
|
||||
player_dir = (player_dir[0], player_dir[1], 0);
|
||||
player_dir = VectorNormalize(player_dir);
|
||||
|
||||
dot = VectorDot(player_dir, s.facing_dir);
|
||||
if(dot<s.facing_dot)
|
||||
continue;
|
||||
}
|
||||
|
||||
targets[targets.size] = s.target;
|
||||
}
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
breach_damage_watch( trigger )
|
||||
{
|
||||
self endon( "breach_activated" );
|
||||
|
||||
trigger waittill( "trigger", player );
|
||||
|
||||
self notify( "breach_activated", player, false );
|
||||
}
|
||||
|
||||
breach_on_activate()
|
||||
{
|
||||
self waittill("breach_activated", player, no_fx);
|
||||
if(!isDefined(no_fx))
|
||||
no_fx = false;
|
||||
|
||||
if( IsDefined(self.useObject) && !no_fx )
|
||||
{
|
||||
self.useObject breach_set_2dIcon("hud_grenadeicon_back_red");
|
||||
self.useObject delayThread(3, ::breach_set_2dIcon, undefined);
|
||||
}
|
||||
|
||||
breach_on_event("activate", player, no_fx);
|
||||
|
||||
if(IsDefined(self.useObject))
|
||||
self.useObject.visuals = [];
|
||||
|
||||
breach_set_can_use(false);
|
||||
}
|
||||
|
||||
breach_on_event( event_name, player, no_fx )
|
||||
{
|
||||
if ( !IsDefined( no_fx ) )
|
||||
no_fx = false;
|
||||
|
||||
if ( event_name == "use" ) // breach is being manually planted
|
||||
{
|
||||
targets = get_breach_targets( "damage", "activate", player );
|
||||
foreach ( target in targets )
|
||||
{
|
||||
target.planted = true;
|
||||
}
|
||||
}
|
||||
|
||||
array_call( get_breach_targets( "solid", event_name, player ), ::Solid );
|
||||
array_call( get_breach_targets( "notsolid", event_name, player ), ::NotSolid );
|
||||
array_thread( get_breach_targets( "hide", event_name, player ), ::breach_hide );
|
||||
array_thread( get_breach_targets( "show", event_name, player ), ::breach_show );
|
||||
array_thread( get_breach_targets( "teleport_show", event_name, player ), ::trigger_on );
|
||||
array_thread( get_breach_targets( "delete", event_name, player ), ::breach_delete );
|
||||
array_thread( get_breach_targets( "teleport_hide", event_name, player ), ::trigger_off );
|
||||
array_call( get_breach_targets( "connect_node", event_name, player ), ::ConnectNode );
|
||||
array_call( get_breach_targets( "disconnect_node", event_name, player ), ::DisconnectNode );
|
||||
array_thread( get_breach_targets( "break_glass", event_name, player ), ::breach_break_glass );
|
||||
array_thread( get_breach_targets( "animated", event_name, player ), ::breach_animate_model );
|
||||
|
||||
if ( !no_fx )
|
||||
{
|
||||
array_thread( get_breach_targets( "fx", event_name, player ), ::breach_play_fx, self );
|
||||
array_thread( get_breach_targets( "damage", event_name, player ), ::breach_damage_radius, player );
|
||||
}
|
||||
}
|
||||
|
||||
breach_delete()
|
||||
{
|
||||
if(IsDefined(self.script_index))
|
||||
{
|
||||
exploder(self.script_index);
|
||||
}
|
||||
|
||||
self SetAISightLineVisible( 0 );
|
||||
self delete();
|
||||
}
|
||||
|
||||
breach_hide()
|
||||
{
|
||||
self SetAISightLineVisible( 0 );
|
||||
self Hide();
|
||||
}
|
||||
|
||||
breach_show()
|
||||
{
|
||||
self SetAISightLineVisible( 1 );
|
||||
self Show();
|
||||
}
|
||||
|
||||
breach_play_fx(root)
|
||||
{
|
||||
fx_name = undefined;
|
||||
if(isdefined(self.script_fxid))
|
||||
{
|
||||
fx_name = self.script_fxid;
|
||||
}
|
||||
else if(IsDefined(root.script_fxid))
|
||||
{
|
||||
fx_name = root.script_fxid;
|
||||
}
|
||||
|
||||
if(!IsDefined(fx_name) || !IsDefined(level._effect[fx_name]))
|
||||
{
|
||||
fx_name = "default";
|
||||
}
|
||||
|
||||
PlayFX(level._effect[fx_name], self.origin, AnglesToForward(self.angles), AnglesToUp(self.angles));
|
||||
}
|
||||
|
||||
breach_damage_radius(attacker)
|
||||
{
|
||||
stuntime = 2.0; // 2 seconds is the minimum a concussion grenade will do
|
||||
|
||||
if( IsDefined( self.planted ) && ( self.planted == true ) )
|
||||
{
|
||||
// RadiusDamage(self.origin, self.radius, self.max_damage, self.min_damage, attacker);
|
||||
foreach( participant in level.participants )
|
||||
{
|
||||
participant_to_breach_dist_sq = DistanceSquared( self.origin, participant.origin );
|
||||
if( participant_to_breach_dist_sq < ( self.radius * self.radius ) )
|
||||
{
|
||||
participant ShellShock( "mp_radiation_high", stuntime );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlayRumbleOnPosition( "artillery_rumble", self.origin );
|
||||
}
|
||||
|
||||
breach_break_glass()
|
||||
{
|
||||
GlassRadiusDamage( self.origin, 128, 500, 500 );
|
||||
}
|
||||
|
||||
breach_animate_model()
|
||||
{
|
||||
self SetAISightLineVisible( 1 );
|
||||
self Show();
|
||||
|
||||
if ( IsDefined( self.animation ) )
|
||||
{
|
||||
self ScriptModelPlayAnim( self.animation );
|
||||
}
|
||||
}
|
||||
|
||||
breach_use_watch()
|
||||
{
|
||||
self endon("breach_activated");
|
||||
wait .05;
|
||||
|
||||
self.useObject = maps\mp\gametypes\_gameobjects::createUseObject( "neutral", get_breach_target("trigger_use"), get_breach_targets("use_model"), (0,0,0) );
|
||||
self.useObject.parent = self;
|
||||
self.useObject.useWeapon = "breach_plant_mp";
|
||||
self.useObject.id = "breach";
|
||||
|
||||
self breach_set_can_use(true);
|
||||
self.useObject maps\mp\gametypes\_gameobjects::setUseTime( 0.5 );
|
||||
self.useObject maps\mp\gametypes\_gameobjects::setUseText( &"MP_BREACHING" );
|
||||
self.useObject maps\mp\gametypes\_gameobjects::setUseHintText( &"MP_BREACH" );
|
||||
self.useObject maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
self.useObject.onUse = ::breach_onUse;
|
||||
self.useObject.onEndUse = ::breach_onEndUse;
|
||||
}
|
||||
|
||||
breach_set_can_use(canUse)
|
||||
{
|
||||
if(!IsDefined(self.useObject))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(canUse)
|
||||
{
|
||||
foreach(vis in self.useObject.visuals)
|
||||
{
|
||||
if( vis.model == "mil_semtex_belt" )
|
||||
{
|
||||
vis SetModel("mil_semtex_belt_obj");
|
||||
}
|
||||
}
|
||||
self.useObject maps\mp\gametypes\_gameobjects::allowUse( "any" );
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach(vis in self.useObject.visuals)
|
||||
{
|
||||
if( vis.model == "mil_semtex_belt" )
|
||||
{
|
||||
vis SetModel("mil_semtex_belt");
|
||||
}
|
||||
}
|
||||
self.useObject notify( "disabled" );
|
||||
self.useObject maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
}
|
||||
}
|
||||
|
||||
breach_onUse(player)
|
||||
{
|
||||
self.parent endon("breach_activated");
|
||||
|
||||
self.parent notify("breach_used");
|
||||
self.parent breach_set_can_use(false);
|
||||
|
||||
self.parent breach_on_event("use", player);
|
||||
|
||||
self.parent thread breach_warning_icon(self);
|
||||
|
||||
sound_ent = undefined;
|
||||
sound_targets = self.parent get_breach_targets( "sound" );
|
||||
if ( sound_targets.size > 1 )
|
||||
{
|
||||
sound_targets = SortByDistance( sound_targets, player.origin );
|
||||
sound_ent = sound_targets[0];
|
||||
}
|
||||
else if ( sound_targets.size > 0 )
|
||||
{
|
||||
sound_ent = sound_targets[0];
|
||||
}
|
||||
|
||||
breaching_team = player.team; // need to store this in case the player switches teams between starting and finishing the breach
|
||||
|
||||
if(IsDefined(sound_ent))
|
||||
{
|
||||
for(i=0;i<3; i++)
|
||||
{
|
||||
sound_ent PlaySound("breach_beep");
|
||||
wait .75;
|
||||
}
|
||||
|
||||
if( IsDefined( sound_ent.script_parameters ) )
|
||||
{
|
||||
params = StrTok( sound_ent.script_parameters, ";" );
|
||||
foreach ( param in params )
|
||||
{
|
||||
toks = StrTok( param, "=" );
|
||||
if ( toks.size < 2 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch( toks[ 0 ] )
|
||||
{
|
||||
case "play_sound":
|
||||
switch( toks[ 1 ] )
|
||||
{
|
||||
case "concrete":
|
||||
sound_ent PlaySound( "detpack_explo_concrete" );
|
||||
break;
|
||||
case "wood":
|
||||
sound_ent PlaySound( "detpack_explo_wood" );
|
||||
break;
|
||||
case "custom":
|
||||
if ( toks.size == 3 )
|
||||
{
|
||||
sound_ent PlaySound( toks[2] );
|
||||
}
|
||||
break;
|
||||
case "metal":
|
||||
case "undefined":
|
||||
default:
|
||||
sound_ent PlaySound( "detpack_explo_metal" );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sound_ent PlaySound( "detpack_explo_metal" );
|
||||
}
|
||||
}
|
||||
|
||||
self.parent notify( "breach_activated", player, undefined, breaching_team );
|
||||
}
|
||||
|
||||
breach_onEndUse( team, player, success )
|
||||
{
|
||||
if( IsPlayer( player ) )
|
||||
{
|
||||
player maps\mp\gametypes\_gameobjects::updateUIProgress( self, false );
|
||||
}
|
||||
}
|
||||
|
||||
breach_set_2dIcon( icon )
|
||||
{
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy" , icon );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", icon );
|
||||
}
|
||||
|
||||
breach_warning_icon( useObject )
|
||||
{
|
||||
icon_origin = useObject.curOrigin + ( 0, 0, 5 );
|
||||
if ( useobject.parent get_breach_targets( "use_icon" ).size )
|
||||
icon_origin = useobject.parent get_breach_targets( "use_icon" )[ 0 ].origin;
|
||||
|
||||
useObject.parent thread breach_icon( "warning", icon_origin, undefined, "breach_activated" );
|
||||
}
|
||||
|
||||
breach_icon( type, origin, angles, end_ons )
|
||||
{
|
||||
if ( level.createFX_enabled )
|
||||
return;
|
||||
|
||||
level.breach_icon_count++;
|
||||
|
||||
icon_id = "breach_icon_" + level.breach_icon_count;
|
||||
|
||||
breach_icon_update( type, origin, angles, icon_id, end_ons );
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( IsDefined( player.breach_icons ) && IsDefined( player.breach_icons[ icon_id ] ) )
|
||||
{
|
||||
player.breach_icons[ icon_id ] thread breach_icon_fade_out();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
breach_icon_update( type, origin, angles, icon_id, end_ons )
|
||||
{
|
||||
if ( IsDefined( end_ons ) )
|
||||
{
|
||||
if ( IsString( end_ons ) )
|
||||
end_ons = [ end_ons ];
|
||||
|
||||
foreach ( end_on in end_ons )
|
||||
self endon( end_on );
|
||||
}
|
||||
|
||||
|
||||
show_dist = 100;
|
||||
show_z = 70;
|
||||
icon = "hud_grenadeicon";
|
||||
pin = true;
|
||||
switch( type )
|
||||
{
|
||||
case "use":
|
||||
show_dist = 300;
|
||||
icon = "breach_icon";
|
||||
pin = false;
|
||||
break;
|
||||
case "warning":
|
||||
show_dist = 400;
|
||||
damage_info = get_breach_target( "damage" );
|
||||
if ( IsDefined( damage_info ) )
|
||||
show_dist = damage_info.radius;
|
||||
icon = "hud_grenadeicon";
|
||||
pin = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
show_dir = undefined;
|
||||
if ( IsDefined( angles ) )
|
||||
{
|
||||
show_dir = AnglesToForward( angles );
|
||||
}
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( !IsDefined( player.breach_icons ) )
|
||||
player.breach_icons = [];
|
||||
|
||||
if ( breach_icon_update_is_player_in_range( player, origin, show_dist, show_dir, show_z ) )
|
||||
{
|
||||
if ( !IsDefined( player.breach_icons[ icon_id ] ) )
|
||||
{
|
||||
player.breach_icons[ icon_id ] = breach_icon_create( player, icon, origin, pin );
|
||||
player.breach_icons[ icon_id ].alpha = 0;
|
||||
}
|
||||
|
||||
player.breach_icons[ icon_id ] notify( "stop_fade" );
|
||||
player.breach_icons[ icon_id ] thread breach_icon_fade_in();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( IsDefined( player.breach_icons[ icon_id ] ) )
|
||||
{
|
||||
player.breach_icons[ icon_id ] thread breach_icon_fade_out();
|
||||
}
|
||||
}
|
||||
}
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
breach_icon_update_is_player_in_range( player, origin, show_dist, show_dir, show_z )
|
||||
{
|
||||
test_origin = player.origin+(0,0,30);
|
||||
|
||||
if(IsDefined(show_z) && abs(test_origin[2] - origin[2]) > show_z)
|
||||
return false;
|
||||
|
||||
if(IsDefined(show_dist))
|
||||
{
|
||||
show_dist_sqr = show_dist*show_dist;
|
||||
dist_sqr = DistanceSquared(test_origin, origin);
|
||||
if(dist_sqr>show_dist_sqr)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(IsDefined(show_dir))
|
||||
{
|
||||
dir_to_player = test_origin - origin;
|
||||
//Normalize dir_to_player if not checking against zero.
|
||||
if(VectorDot(show_dir, dir_to_player)<0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
breach_icon_create(player, icon, origin, pin)
|
||||
{
|
||||
icon = player createIcon( icon, 16, 16 );
|
||||
icon setWayPoint( true, pin );
|
||||
icon.x = origin[0];
|
||||
icon.y = origin[1];
|
||||
icon.z = origin[2];
|
||||
return icon;
|
||||
}
|
||||
|
||||
breach_icon_fade_in()
|
||||
{
|
||||
self endon("death");
|
||||
|
||||
if(self.alpha == 1)
|
||||
return;
|
||||
|
||||
self FadeOverTime(.5);
|
||||
self.alpha = 1;
|
||||
}
|
||||
|
||||
breach_icon_fade_out()
|
||||
{
|
||||
self endon("death");
|
||||
self endon("stop_fade");
|
||||
|
||||
if(self.alpha == 0)
|
||||
return;
|
||||
|
||||
time = .5;
|
||||
self FadeOverTime(time);
|
||||
self.alpha = 0;
|
||||
wait time;
|
||||
|
||||
self Destroy();
|
||||
}
|
85
maps/mp/_compass.gsc
Normal file
85
maps/mp/_compass.gsc
Normal file
@ -0,0 +1,85 @@
|
||||
setupMiniMap(material)
|
||||
{
|
||||
// use 0 for no required map aspect ratio.
|
||||
requiredMapAspectRatio = level.requiredMapAspectRatio;
|
||||
|
||||
corners = getentarray("minimap_corner", "targetname");
|
||||
if (corners.size != 2)
|
||||
{
|
||||
println("^1Error: There are not exactly two \"minimap_corner\" entities in the map. Could not set up minimap.");
|
||||
return;
|
||||
}
|
||||
|
||||
corner0 = (corners[0].origin[0], corners[0].origin[1], 0);
|
||||
corner1 = (corners[1].origin[0], corners[1].origin[1], 0);
|
||||
|
||||
cornerdiff = corner1 - corner0;
|
||||
|
||||
north = (cos(getnorthyaw()), sin(getnorthyaw()), 0);
|
||||
west = (0 - north[1], north[0], 0);
|
||||
|
||||
// we need the northwest and southeast corners. all we know is that corner0 is opposite of corner1.
|
||||
if (vectordot(cornerdiff, west) > 0) {
|
||||
// corner1 is further west than corner0
|
||||
if (vectordot(cornerdiff, north) > 0) {
|
||||
// corner1 is northwest, corner0 is southeast
|
||||
northwest = corner1;
|
||||
southeast = corner0;
|
||||
}
|
||||
else {
|
||||
// corner1 is southwest, corner0 is northeast
|
||||
side = vecscale(north, vectordot(cornerdiff, north));
|
||||
northwest = corner1 - side;
|
||||
southeast = corner0 + side;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// corner1 is further east than corner0
|
||||
if (vectordot(cornerdiff, north) > 0) {
|
||||
// corner1 is northeast, corner0 is southwest
|
||||
side = vecscale(north, vectordot(cornerdiff, north));
|
||||
northwest = corner0 + side;
|
||||
southeast = corner1 - side;
|
||||
}
|
||||
else {
|
||||
// corner1 is southeast, corner0 is northwest
|
||||
northwest = corner0;
|
||||
southeast = corner1;
|
||||
}
|
||||
}
|
||||
|
||||
if( GetDvar("mapname") == "mp_boneyard_ns")
|
||||
{
|
||||
southeast -= (220,220,0);
|
||||
northwest += (220,220,0);
|
||||
}
|
||||
|
||||
// expand map area to fit required aspect ratio
|
||||
if ( requiredMapAspectRatio > 0 )
|
||||
{
|
||||
northportion = vectordot(northwest - southeast, north);
|
||||
westportion = vectordot(northwest - southeast, west);
|
||||
mapAspectRatio = westportion / northportion;
|
||||
if ( mapAspectRatio < requiredMapAspectRatio )
|
||||
{
|
||||
incr = requiredMapAspectRatio / mapAspectRatio;
|
||||
addvec = vecscale( west, westportion * (incr - 1) * 0.5 );
|
||||
}
|
||||
else
|
||||
{
|
||||
incr = mapAspectRatio / requiredMapAspectRatio;
|
||||
addvec = vecscale( north, northportion * (incr - 1) * 0.5 );
|
||||
}
|
||||
northwest += addvec;
|
||||
southeast -= addvec;
|
||||
}
|
||||
|
||||
level.mapSize = vectordot(northwest - southeast, north);
|
||||
|
||||
setMiniMap(material, northwest[0], northwest[1], southeast[0], southeast[1]);
|
||||
}
|
||||
|
||||
vecscale(vec, scalar)
|
||||
{
|
||||
return (vec[0]*scalar, vec[1]*scalar, vec[2]*scalar);
|
||||
}
|
74
maps/mp/_createfx.gsc
Normal file
74
maps/mp/_createfx.gsc
Normal file
@ -0,0 +1,74 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\_createFxMenu;
|
||||
#include common_scripts\_createfx;
|
||||
#include common_scripts\_fx;
|
||||
|
||||
createfx()
|
||||
{
|
||||
level.func_position_player = ::void;
|
||||
level.func_position_player_get = ::func_position_player_get;
|
||||
level.func_loopfxthread = ::loopfxthread;
|
||||
level.func_oneshotfxthread = ::oneshotfxthread;
|
||||
level.func_create_loopsound = ::create_loopsound;
|
||||
// level.func_exploder_preload = ::exploder_before_load;;
|
||||
// level.func_exploder_postload = ::exploder_after_load;;
|
||||
level.func_updatefx = ::restart_fx_looper;
|
||||
level.func_process_fx_rotater = ::process_fx_rotater;
|
||||
level.func_player_speed = ::func_player_speed;
|
||||
|
||||
level.mp_createfx = true;
|
||||
|
||||
// MP only stuff
|
||||
level.callbackStartGameType = ::void;
|
||||
level.callbackPlayerConnect = ::void;
|
||||
level.callbackPlayerDisconnect = ::void;
|
||||
level.callbackPlayerDamage = ::void;
|
||||
level.callbackPlayerKilled = ::void;
|
||||
level.callbackCodeEndGame = ::void;
|
||||
level.callbackPlayerLastStand = ::void;
|
||||
level.callbackPlayerConnect = ::Callback_PlayerConnect;
|
||||
level.callbackPlayerMigrated = ::void;
|
||||
|
||||
thread func_get_level_fx(); // start gettin these on start
|
||||
createfx_common();
|
||||
|
||||
level waittill( "eternity" );
|
||||
}
|
||||
|
||||
func_position_player_get( lastPlayerOrigin )
|
||||
{
|
||||
return level.player.origin;
|
||||
}
|
||||
|
||||
Callback_PlayerConnect()
|
||||
{
|
||||
self waittill( "begin" );
|
||||
|
||||
if ( !isdefined( level.player ) )
|
||||
{
|
||||
spawnpoints = getentarray( "mp_global_intermission", "classname" );
|
||||
self spawn( spawnpoints[0].origin, spawnpoints[0].angles );
|
||||
self updateSessionState( "playing", "" );
|
||||
self.maxhealth = 10000000;
|
||||
self.health = 10000000;
|
||||
level.player = self;
|
||||
|
||||
thread createFxLogic();
|
||||
//thread ufo_mode();
|
||||
}
|
||||
else
|
||||
kick( self GetEntityNumber() );
|
||||
}
|
||||
|
||||
//ufo_mode()
|
||||
//{
|
||||
// level.player openpopupmenu( "painter_mp" );// painter.menu execs some console commands( ufo mode ).. sneaky hacks.
|
||||
// level.player closepopupmenu( "painter_mp" );
|
||||
//}
|
||||
|
||||
func_player_speed()
|
||||
{
|
||||
scale = level._createfx.player_speed / 190;
|
||||
level.player SetMoveSpeedScale( scale );
|
||||
}
|
727
maps/mp/_crib.gsc
Normal file
727
maps/mp/_crib.gsc
Normal file
@ -0,0 +1,727 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
CONST_default_radial_radius = 8; // default distance between radial button and center
|
||||
CONST_radial_center_extrude_dist = 40; // this is the distance between the floating radial center and the oberver's eye
|
||||
CONST_direct_travel = 1; // no path, directly zoom to position
|
||||
CONST_view_travel_unit_dist = 1200; // distance unit per travel interval
|
||||
CONST_view_travel_unit_time = 1; // in seconds per travel interval
|
||||
CONST_blur_strength = 3; // blur strength during view travel, sine curved over travel duration
|
||||
|
||||
init()
|
||||
{
|
||||
precacheShellShock( "frag_grenade_mp" );
|
||||
|
||||
radial_button_definitions(); // define radial button sets and buttons
|
||||
radial_init(); // setup radial button mechanism
|
||||
view_path_setup(); // setup view flight paths
|
||||
player_init();
|
||||
}
|
||||
|
||||
// ====================================================================================
|
||||
// == inits ==
|
||||
// ====================================================================================
|
||||
|
||||
radial_button_definitions()
|
||||
{
|
||||
newRadialButtonGroup( "main", "player_view1_start", "player_view1_end" );
|
||||
|
||||
// Main menu's buttons:
|
||||
bWeapons_a = newRadialButton( "main", "Primary Weapon", "radial_weapons_primary", ::action_weapons_primary );
|
||||
bWeapons_b = newRadialButton( "main", "Secondary Weapon", "radial_weapons_secondary", ::action_weapons_secondary );
|
||||
bGears = newRadialButton( "main", "Gears", "radial_gears", ::action_gears );
|
||||
bKillStreaks= newRadialButton( "main", "Kill Streaks", "radial_killstreaks", ::action_killstreak );
|
||||
bLeadboards = newRadialButton( "main", "Leaderboards", "radial_leaderboards", ::action_leaderboards );
|
||||
//
|
||||
|
||||
newRadialButtonGroup( "gears", "player_view2_start", "player_view2_end" );
|
||||
newRadialButtonGroup( "weapons_primary", "player_view3_start", "player_view3_end" );
|
||||
newRadialButtonGroup( "weapons_secondary", "player_view3_start", "player_view3_end" );
|
||||
newRadialButtonGroup( "killstreak", "player_view4_start", "player_view4_end" );
|
||||
newRadialButtonGroup( "leaderboards", "player_view5_start", "player_view5_end" );
|
||||
}
|
||||
|
||||
|
||||
radial_init()
|
||||
{
|
||||
// calculate start & end angles of all buttons for range selection
|
||||
foreach ( button_group in level.radial_button_group )
|
||||
{
|
||||
// sort buttons by angle so we can calculate mid angles in sequence
|
||||
sort_buttons_by_angle( button_group );
|
||||
|
||||
for ( i = 0; i < button_group.size; i ++ )
|
||||
{
|
||||
if ( isdefined( button_group[ i + 1 ] ) )
|
||||
{
|
||||
mid_angle = getMidAngle( button_group[ i ].pos_angle, button_group[ i + 1 ].pos_angle );
|
||||
button_group[ i ].end_angle = mid_angle;
|
||||
button_group[ i + 1 ].start_angle = mid_angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
mid_angle = getMidAngle( button_group[ i ].pos_angle, button_group[ 0 ].pos_angle ) + 180; // +180 to mirror angle
|
||||
if ( mid_angle > 360 )
|
||||
mid_angle -= 360;
|
||||
|
||||
button_group[ i ].end_angle = mid_angle;
|
||||
button_group[ 0 ].start_angle = mid_angle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// monitors
|
||||
thread updateSelectedButton();
|
||||
thread watchSelectButtonPress();
|
||||
thread watchBackButtonPress();
|
||||
thread debug_toggle();
|
||||
}
|
||||
|
||||
|
||||
debug_toggle()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
level.crib_debug = 1;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
if ( !isdefined( level.observer ) )
|
||||
{
|
||||
wait 0.05;
|
||||
continue;
|
||||
}
|
||||
|
||||
button_reset = true;
|
||||
while ( !( level.observer buttonPressed( "BUTTON_Y" ) ) )
|
||||
wait 0.05;
|
||||
|
||||
level.observer playsound("mouse_click");
|
||||
|
||||
if ( button_reset )
|
||||
{
|
||||
level.crib_debug *= -1;
|
||||
button_reset = false;
|
||||
}
|
||||
|
||||
while ( level.observer buttonPressed( "BUTTON_Y" ) )
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
player_init()
|
||||
{
|
||||
level thread onPlayerConnect();
|
||||
level thread return_hud();
|
||||
}
|
||||
|
||||
|
||||
return_hud()
|
||||
{
|
||||
level waittill( "game_ended" );
|
||||
setdvar( "cg_draw2d", 1 );
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player thread readyPlayer();
|
||||
player waittill( "spawned_player" );
|
||||
|
||||
wait 1;
|
||||
|
||||
player takeallweapons();
|
||||
setdvar( "cg_draw2d", 0 );
|
||||
|
||||
if ( !isdefined( player ) )
|
||||
return;
|
||||
else
|
||||
level.observer = player;
|
||||
|
||||
player thread get_right_stick_angle();
|
||||
|
||||
zoom_to_radial_menu( "main" ); // fly to the first radial menu
|
||||
}
|
||||
|
||||
|
||||
readyPlayer()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
team = "autoassign";
|
||||
|
||||
while(!isdefined(self.pers["team"]))
|
||||
wait .05;
|
||||
|
||||
self notify("menuresponse", game["menu_team"], team);
|
||||
wait 0.5;
|
||||
|
||||
classes = getArrayKeys( level.classMap );
|
||||
okclasses = [];
|
||||
for ( i = 0; i < classes.size; i++ )
|
||||
{
|
||||
if ( !isSubStr( classes[i], "custom" ) )
|
||||
okclasses[ okclasses.size ] = classes[i];
|
||||
}
|
||||
|
||||
assert( okclasses.size );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
class = okclasses[ 0 ];
|
||||
self notify("menuresponse", "changeclass", class);
|
||||
|
||||
self waittill( "spawned_player" );
|
||||
wait ( 0.10 );
|
||||
}
|
||||
}
|
||||
|
||||
// ====================================================================================
|
||||
// == Radial Mechanics ==
|
||||
// ====================================================================================
|
||||
|
||||
get_right_stick_angle()
|
||||
{
|
||||
// self is user
|
||||
level endon( "game_ended" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
rs_vec = self GetNormalizedMovement();
|
||||
rs_angles = vectortoangles( rs_vec );
|
||||
level.rs_angle = int( rs_angles[1] );
|
||||
|
||||
wait 0.05; // update rate
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
newRadialButtonGroup( group_name, view_start, view_end )
|
||||
{
|
||||
if ( isdefined( level.radial_button_group ) && level.radial_button_group.size )
|
||||
assertex( !isdefined( level.radial_button_group[ group_name ] ), "Radial button group: " + group_name + " is already defined." );
|
||||
|
||||
player_view_ent = getent( view_end, "targetname" );
|
||||
assertex( isdefined( player_view_ent ), "Missing player view entity, can not setup radial menu in space" );
|
||||
|
||||
extruded_vec = ( VectorNormalize( AnglesToForward( player_view_ent.angles ) ) * CONST_radial_center_extrude_dist );
|
||||
|
||||
level.radial_button_group[ group_name ] = [];
|
||||
level.radial_button_group_info[ group_name ][ "view_start" ] = view_start;
|
||||
level.radial_button_group_info[ group_name ][ "view_pos" ] = player_view_ent.origin + extruded_vec;
|
||||
level.radial_button_group_info[ group_name ][ "player_view_pos" ] = player_view_ent.origin;
|
||||
level.radial_button_group_info[ group_name ][ "view_angles" ] = player_view_ent.angles;
|
||||
}
|
||||
|
||||
|
||||
newRadialButton( button_group, button_label, button_ent_name, action_func )
|
||||
{
|
||||
assertex( isdefined( level.radial_button_group[ button_group ] ), "Radial button group: " + button_group + " does not exist." );
|
||||
|
||||
ent = getent( button_ent_name, "targetname" );
|
||||
new_button_angle = getRadialAngleFromEnt( button_group, ent );
|
||||
|
||||
button = spawnstruct();
|
||||
button.pos = ent.origin;
|
||||
button.label = button_label;
|
||||
button.font_size = 1;
|
||||
button.font_color = ( 0.5, 0.5, 1 );
|
||||
button.pos_angle = new_button_angle;
|
||||
button.action_func = action_func;
|
||||
button.radius_pos = CONST_default_radial_radius;
|
||||
|
||||
level.radial_button_group[ button_group ][ level.radial_button_group[ button_group ].size ] = button;
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
updateSelectedButton()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
if ( !isdefined( level.radial_button_current_group ) )
|
||||
{
|
||||
wait 0.05;
|
||||
continue;
|
||||
}
|
||||
|
||||
last_active_button = level.active_button;
|
||||
|
||||
foreach ( button in level.radial_button_group[ level.radial_button_current_group ] )
|
||||
{
|
||||
if ( isInRange( button.start_angle, button.end_angle ) )
|
||||
level.active_button = button;
|
||||
else
|
||||
button.font_color = ( 0.5, 0.5, 1 );
|
||||
}
|
||||
|
||||
if ( isdefined ( level.active_button ) )
|
||||
{
|
||||
level.active_button.font_color = ( 1, 1, 0.5 );
|
||||
|
||||
if ( isdefined( last_active_button ) && last_active_button != level.active_button )
|
||||
level.observer playsound("mouse_over");
|
||||
}
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
watchSelectButtonPress()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
if ( !isdefined( level.observer ) )
|
||||
{
|
||||
wait 0.05;
|
||||
continue;
|
||||
}
|
||||
|
||||
button_reset = true;
|
||||
while ( !( level.observer buttonPressed( "BUTTON_A" ) ) )
|
||||
wait 0.05;
|
||||
|
||||
level.observer playsound("mouse_click");
|
||||
|
||||
if ( isdefined( level.active_button ) && button_reset )
|
||||
{
|
||||
level.active_button notify( "select_button_pressed" );
|
||||
[[level.active_button.action_func]]();
|
||||
button_reset = false;
|
||||
}
|
||||
|
||||
while ( level.observer buttonPressed( "BUTTON_A" ) )
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
watchBackButtonPress()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
if ( !isdefined( level.observer ) )
|
||||
{
|
||||
wait 0.05;
|
||||
continue;
|
||||
}
|
||||
|
||||
button_reset = true;
|
||||
while ( !( level.observer buttonPressed( "BUTTON_X" ) ) )
|
||||
wait 0.05;
|
||||
|
||||
level.observer playsound("mouse_click");
|
||||
|
||||
if ( button_reset )
|
||||
{
|
||||
action_back();
|
||||
button_reset = false;
|
||||
}
|
||||
|
||||
while ( level.observer buttonPressed( "BUTTON_X" ) )
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sort_buttons_by_angle( button_group )
|
||||
{
|
||||
// button_group is actual array
|
||||
// bubble sort buttons
|
||||
for ( i = 0; i < button_group.size - 1; i++ )
|
||||
{
|
||||
for ( j = 0; j < button_group.size - 1 - i; j++ )
|
||||
{
|
||||
if ( button_group[ j + 1 ].pos_angle < button_group[ j ].pos_angle )
|
||||
button_switch( button_group[ j ], button_group[ j + 1 ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
button_switch( button1, button2 )
|
||||
{
|
||||
temp_pos = button1.pos;
|
||||
temp_label = button1.label;
|
||||
temp_pos_angle = button1.pos_angle;
|
||||
temp_action_func = button1.action_func;
|
||||
temp_radius_pos = button1.radius_pos;
|
||||
|
||||
button1.pos = button2.pos;
|
||||
button1.label = button2.label;
|
||||
button1.pos_angle = button2.pos_angle;
|
||||
button1.action_func = button2.action_func;
|
||||
button1.radius_pos = button2.radius_pos;
|
||||
|
||||
button2.pos = temp_pos;
|
||||
button2.label = temp_label;
|
||||
button2.pos_angle = temp_pos_angle;
|
||||
button2.action_func = temp_action_func;
|
||||
button2.radius_pos = temp_radius_pos;
|
||||
}
|
||||
|
||||
|
||||
draw_radial_buttons( button_group )
|
||||
{
|
||||
foreach ( button in level.radial_button_group[ button_group ] )
|
||||
button thread draw_radial_button( button_group );
|
||||
}
|
||||
|
||||
|
||||
//print3d(<origin>, <text>, <color>, <alpha>, <scale>, <duration> )
|
||||
draw_radial_button( button_group )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self endon( "remove_button" );
|
||||
|
||||
floating_origin = level.radial_button_group_info[ button_group ][ "view_pos" ];
|
||||
button_radial_pos = floating_origin + radial_angle_to_vector( self.pos_angle, 4 );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
//line( level.radial_button_group_info[ button_group ][ "view_pos" ], self.pos, ( 0, 1, 0 ), 0.05, false );
|
||||
|
||||
range_color = ( 1, 0, 0 );
|
||||
if ( isInRange( self.start_angle, self.end_angle ) )
|
||||
range_color = ( 1, 1, 0 );
|
||||
|
||||
print3d( self.pos, self.label, self.font_color, 0.75, self.font_size, 1 );
|
||||
|
||||
if ( isdefined( level.crib_debug ) && level.crib_debug > 0 )
|
||||
{
|
||||
print3d( button_radial_pos, ".("+int(self.pos_angle)+")", range_color, 0.75, 0.05, 1 );
|
||||
|
||||
line( floating_origin, floating_origin + radial_angle_to_vector( self.start_angle, 2 ), range_color, 0.05 );
|
||||
line( floating_origin + radial_angle_to_vector( self.start_angle, 2 ), floating_origin + radial_angle_to_vector( self.end_angle, 2 ), range_color, 0.05 );
|
||||
|
||||
// right stick debug ling
|
||||
r_radial_pos = floating_origin + radial_angle_to_vector( level.rs_angle, 2 );
|
||||
line( floating_origin, r_radial_pos, ( 1, 1, 1 ), 0.05 );
|
||||
|
||||
|
||||
}
|
||||
print3d( floating_origin - ( 0, 0, 4.5 ), "(A)=Select (X)=Back", (1, 1, 1), 0.5, 0.05, 1 );
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Zoom_To_Radial_Menu( button_group, reverse )
|
||||
{
|
||||
level.active_button = undefined;
|
||||
|
||||
assertex( isdefined( level.observer ), "Missing observer (connected player), can not attach player to view path" );
|
||||
|
||||
if ( isdefined( level.radial_button_current_group ) && level.radial_button_current_group != "" )
|
||||
{
|
||||
level.radial_button_previous_group = level.radial_button_current_group;
|
||||
}
|
||||
else
|
||||
{
|
||||
level.radial_button_previous_group = "main";
|
||||
level.radial_button_current_group = "main";
|
||||
}
|
||||
|
||||
foreach ( button in level.radial_button_group[ level.radial_button_previous_group ] )
|
||||
button notify( "remove_button" );
|
||||
|
||||
//iPrintLnBold( "flying to: " + button_group );
|
||||
|
||||
if ( isdefined( reverse ) && reverse )
|
||||
level.observer go_path_by_targetname_reverse( level.radial_button_group_info[ level.radial_button_previous_group ][ "view_start" ], button_group );
|
||||
else
|
||||
level.observer go_path_by_targetname( level.radial_button_group_info[ button_group ][ "view_start" ] );
|
||||
|
||||
level thread draw_radial_buttons( button_group );
|
||||
level.radial_button_current_group = button_group;
|
||||
}
|
||||
|
||||
|
||||
// ====================================================================================
|
||||
// == Radial menu - math ==
|
||||
// ====================================================================================
|
||||
|
||||
// edit function with care, returns orientation-sensistive angles
|
||||
getRadialAngleFromEnt( button_group, ent )
|
||||
{
|
||||
assertex( isdefined( level.radial_button_group[ button_group ] ), "getRadialAngleFromEnt: Radial button group does not exist." );
|
||||
assertex( isdefined( ent ), "getRadialAngleFromEnt: Missing entity to be measured." );
|
||||
|
||||
rAngle = level.radial_button_group_info[ button_group ][ "view_angles" ];
|
||||
rPos = level.radial_button_group_info[ button_group ][ "view_pos" ];
|
||||
rPos += ( VectorNormalize( AnglesToForward( rAngle ) ) * CONST_radial_center_extrude_dist );
|
||||
rForward = AnglesToForward( rAngle );
|
||||
rUpwardNorm = VectorNormalize( AnglesToUp( rAngle ) );
|
||||
|
||||
eAngle = ent.angles;
|
||||
ePos = ent.origin;
|
||||
|
||||
projNorm = VectorNormalize( VectorFromLineToPoint( rPos, ( rPos + rForward ), ePos ) );
|
||||
radial_angle = Acos( VectorDot( projNorm, rUpwardNorm ) );
|
||||
|
||||
// vector mirroring
|
||||
if ( VectorDot( AnglesToRight( rAngle ), projNorm ) < 0 )
|
||||
radial_angle = 360 - radial_angle;
|
||||
|
||||
return radial_angle;
|
||||
}
|
||||
|
||||
|
||||
// converts projected angle into player's view plane into a vector
|
||||
radial_angle_to_vector( angle, scaler )
|
||||
{
|
||||
b_angles = ( 270 - ( angle ), 0 , 0 ); // 270 degrees offset to face the player
|
||||
b_vec = AnglesToForward( b_angles );
|
||||
b_vec_norm = VectorNormalize( b_vec );
|
||||
b_vec_final = ( b_vec_norm * scaler );
|
||||
|
||||
return b_vec_final;
|
||||
}
|
||||
|
||||
|
||||
getMidAngle( a1, a2 )
|
||||
{
|
||||
// 0 -> 360 domain
|
||||
mid_angle = ( ( a1 + a2 + 720 ) / 2 ) - 360;
|
||||
return mid_angle;
|
||||
}
|
||||
|
||||
|
||||
isInRange( start_angle, end_angle )
|
||||
{
|
||||
inside_big_angle = ( level.rs_angle > start_angle && level.rs_angle < 360 );
|
||||
inside_small_angle = ( level.rs_angle > 0 && level.rs_angle < end_angle );
|
||||
|
||||
if ( start_angle > end_angle )
|
||||
in_range = ( inside_big_angle || inside_small_angle );
|
||||
else
|
||||
in_range = ( level.rs_angle > start_angle && level.rs_angle < end_angle );
|
||||
|
||||
return in_range;
|
||||
}
|
||||
|
||||
// ====================================================================================
|
||||
// == Button action functions ==
|
||||
// ====================================================================================
|
||||
|
||||
// close radial buttons
|
||||
action_back()
|
||||
{
|
||||
//if ( isdefined( level.radial_button_previous_group ) && level.radial_button_previous_group != "" )
|
||||
// zoom_to_radial_menu( level.radial_button_previous_group );
|
||||
/*else*/ if ( isdefined( level.radial_button_current_group ) && level.radial_button_current_group != "main" )
|
||||
zoom_to_radial_menu( "main", true );
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// ==== main ====
|
||||
action_weapons_primary()
|
||||
{
|
||||
iPrintLnBold( "action_weapons_primary" );
|
||||
zoom_to_radial_menu( "weapons_primary" );
|
||||
}
|
||||
|
||||
|
||||
action_weapons_secondary()
|
||||
{
|
||||
iPrintLnBold( "action_weapons_secondary" );
|
||||
zoom_to_radial_menu( "weapons_secondary" );
|
||||
}
|
||||
|
||||
action_gears()
|
||||
{
|
||||
iPrintLnBold( "action_gears" );
|
||||
zoom_to_radial_menu( "gears" );
|
||||
}
|
||||
|
||||
|
||||
action_killstreak()
|
||||
{
|
||||
iPrintLnBold( "action_killstreak" );
|
||||
zoom_to_radial_menu( "killstreak" );
|
||||
}
|
||||
|
||||
|
||||
action_leaderboards()
|
||||
{
|
||||
iPrintLnBold( "action_leaderboards" );
|
||||
zoom_to_radial_menu( "leaderboards" );
|
||||
}
|
||||
|
||||
// ====================================================================================
|
||||
// == Pathing functions ==
|
||||
// ====================================================================================
|
||||
|
||||
view_path_setup()
|
||||
{
|
||||
// setup all paths
|
||||
level.view_paths = [];
|
||||
|
||||
// build paths
|
||||
build_path_by_targetname( "player_view1_start" );
|
||||
build_path_by_targetname( "player_view2_start" );
|
||||
build_path_by_targetname( "player_view3_start" );
|
||||
build_path_by_targetname( "player_view4_start" );
|
||||
build_path_by_targetname( "player_view5_start" );
|
||||
}
|
||||
|
||||
|
||||
build_path_by_targetname( path_name )
|
||||
{
|
||||
level.view_paths[ path_name ] = [];
|
||||
|
||||
path_node = getent( path_name, "targetname" );
|
||||
level.view_paths[ path_name ][ level.view_paths[ path_name ].size ] = path_node;
|
||||
|
||||
while( isdefined( path_node ) && isdefined( path_node.target ) )
|
||||
{
|
||||
next_node = getent( path_node.target, "targetname" );
|
||||
level.view_paths[ path_name ][ level.view_paths[ path_name ].size ] = next_node;
|
||||
path_node = next_node;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
go_path_by_targetname( path_name )
|
||||
{
|
||||
// self is player
|
||||
if ( !isdefined( level.dummy_mover ) )
|
||||
{
|
||||
start_node = level.view_paths[ path_name ][ 0 ];
|
||||
level.dummy_mover = spawn( "script_model", start_node.origin );
|
||||
level.dummy_mover.angles = start_node.angles;
|
||||
//self AllowedStances( "stand" );
|
||||
self setOrigin( level.dummy_mover.origin - ( 0, 0, 65 ) );
|
||||
self linkTo( level.dummy_mover );
|
||||
wait 0.05;
|
||||
self setplayerangles ( level.dummy_mover.angles );
|
||||
|
||||
self thread force_player_angles();
|
||||
}
|
||||
|
||||
/*
|
||||
travel_time = 1;
|
||||
dist = 0;
|
||||
foreach ( idx, node in level.view_paths[ path_name ] )
|
||||
{
|
||||
if ( isdefined( level.view_paths[ path_name ][ idx + 1 ] ) )
|
||||
dist += abs( distance( level.view_paths[ path_name ][ idx ].origin, level.view_paths[ path_name ][ idx + 1 ].origin ) );
|
||||
}*/
|
||||
|
||||
travel_speed = CONST_view_travel_unit_time;
|
||||
total_distance = abs( distance( level.dummy_mover.origin, level.view_paths[ path_name ][ level.view_paths[ path_name ].size - 1 ].origin ) );
|
||||
travel_speed *= total_distance / CONST_view_travel_unit_dist;
|
||||
travel_speed = max( travel_speed, 0.1 ); // due to repeated button presses, the travel distance can be cut to 0 travel speed at times.
|
||||
|
||||
blur_time = travel_speed;
|
||||
if ( !CONST_direct_travel )
|
||||
blur_time *= travel_speed * ( level.view_paths[ path_name ].size + 1 );
|
||||
self thread blur_sine( CONST_blur_strength, blur_time );
|
||||
|
||||
foreach ( idx, node in level.view_paths[ path_name ] )
|
||||
{
|
||||
//travel_speed = travel_time * ( abs( distance( level.dummy_mover.origin, node.origin ) ) / dist );
|
||||
//travel_speed += 0.05;
|
||||
|
||||
if ( CONST_direct_travel )
|
||||
{
|
||||
if ( idx != level.view_paths[ path_name ].size - 1 )
|
||||
continue;
|
||||
}
|
||||
|
||||
//level.dummy_mover MoveTo( node.origin, travel_speed );
|
||||
level.dummy_mover MoveTo( node.origin, travel_speed, travel_speed * 0.5, 0 );
|
||||
level.dummy_mover RotateTo( node.angles, travel_speed, travel_speed * 0.5, 0);
|
||||
wait travel_speed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
go_path_by_targetname_reverse( path_name, back_to_button_group )
|
||||
{
|
||||
assertex( isdefined( level.dummy_mover ), "go_path_by_targetname_reverse called before go_path_by_targetname" );
|
||||
|
||||
travel_speed = CONST_view_travel_unit_time;
|
||||
total_distance = abs( distance( level.dummy_mover.origin, level.radial_button_group_info[ back_to_button_group ][ "player_view_pos" ] ) );
|
||||
travel_speed *= total_distance / CONST_view_travel_unit_dist;
|
||||
travel_speed = max( travel_speed, 0.1 ); // due to repeated button presses, the travel distance can be cut to 0 travel speed at times.
|
||||
|
||||
blur_time = travel_speed;
|
||||
if ( !CONST_direct_travel )
|
||||
blur_time *= travel_speed * ( level.view_paths[ path_name ].size + 1 );
|
||||
self thread blur_sine( CONST_blur_strength, blur_time );
|
||||
|
||||
if ( !CONST_direct_travel )
|
||||
{
|
||||
for ( idx = level.view_paths[ path_name ].size - 1; idx >= 0; idx-- )
|
||||
{
|
||||
node = level.view_paths[ path_name ][ idx ];
|
||||
level.dummy_mover MoveTo( node.origin, travel_speed );
|
||||
level.dummy_mover RotateTo( node.angles, travel_speed );
|
||||
|
||||
//self thread travel_view_fx( travel_speed );
|
||||
wait travel_speed;
|
||||
}
|
||||
}
|
||||
|
||||
self thread blur_sine( CONST_blur_strength, travel_speed );
|
||||
|
||||
pos = level.radial_button_group_info[ back_to_button_group ][ "player_view_pos" ];
|
||||
angle = level.radial_button_group_info[ back_to_button_group ][ "view_angles" ];
|
||||
|
||||
level.dummy_mover MoveTo( pos, travel_speed, travel_speed * 0.5, 0 );
|
||||
level.dummy_mover RotateTo( angle, travel_speed, travel_speed * 0.5, 0 );
|
||||
wait travel_speed;
|
||||
}
|
||||
|
||||
|
||||
travel_view_fx( time )
|
||||
{
|
||||
self setblurforplayer( 20, ( time + 0.2 )/2 );
|
||||
self setblurforplayer( 0, ( time + 0.2 )/2 );
|
||||
self shellshock( "frag_grenade_mp", time + 0.2 );
|
||||
}
|
||||
|
||||
|
||||
blur_sine( strength, time )
|
||||
{
|
||||
time_scaled = int( time/0.05 );
|
||||
|
||||
for( i = 0; i < time_scaled; i ++ )
|
||||
{
|
||||
fraction = ( i / ( time_scaled ) );
|
||||
cos_fraction= sin( 180 * fraction );
|
||||
blur_amount = strength * cos_fraction;
|
||||
|
||||
setdvar( "r_blur", blur_amount );
|
||||
wait 0.05;
|
||||
}
|
||||
setdvar( "r_blur", 0 );
|
||||
}
|
||||
|
||||
|
||||
force_player_angles()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self endon( "disconnect" );
|
||||
level.dummy_mover endon( "remove_dummy" );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
self setplayerangles ( level.dummy_mover.angles );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
137
maps/mp/_defcon.gsc
Normal file
137
maps/mp/_defcon.gsc
Normal file
@ -0,0 +1,137 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
// if ( game["state"] == "postgame" && game["teamScores"][attacker.team] > game["teamScores"][level.otherTeam[attacker.team]] )
|
||||
|
||||
ICONSIZE = 20;
|
||||
|
||||
init()
|
||||
{
|
||||
if ( !isDefined( level.defconMode ) || level.defconMode == false )
|
||||
return;
|
||||
|
||||
if ( !isDefined( game["defcon"] ) )
|
||||
game["defcon"] = 4;
|
||||
|
||||
SetDvar( "scr_defcon", game["defcon"] );
|
||||
|
||||
/# setDevDvarIfUninitialized( "scr_defconStreak", 10 ); #/
|
||||
|
||||
level.defconStreakAdd[5] = 0;
|
||||
level.defconStreakAdd[4] = 0;
|
||||
level.defconStreakAdd[3] = -1;
|
||||
level.defconStreakAdd[2] = -1;
|
||||
level.defconStreakAdd[1] = -1;
|
||||
|
||||
level.defconPointMod[5] = 1;
|
||||
level.defconPointMod[4] = 1;
|
||||
level.defconPointMod[3] = 1;
|
||||
level.defconPointMod[2] = 1;
|
||||
level.defconPointMod[1] = 2;
|
||||
|
||||
updateDefcon( game["defcon"] );
|
||||
thread defconKillstreakThread();
|
||||
}
|
||||
|
||||
defconKillstreakWait( streakCount )
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill ( "player_got_killstreak_" + streakCount, player );
|
||||
level notify ( "defcon_killstreak", streakCount, player );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
defconKillstreakThread()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
|
||||
requiredKillCount = 10;
|
||||
|
||||
/#
|
||||
requiredKillCount = getDvarInt( "scr_defconStreak" );
|
||||
#/
|
||||
|
||||
level thread defconKillstreakWait( requiredKillCount );
|
||||
level thread defconKillstreakWait( requiredKillCount - 1 );
|
||||
level thread defconKillstreakWait( requiredKillCount - 2 );
|
||||
|
||||
level thread defconKillstreakWait( (requiredKillCount * 2) );
|
||||
level thread defconKillstreakWait( (requiredKillCount * 2) - 1 );
|
||||
level thread defconKillstreakWait( (requiredKillCount * 2) - 2 );
|
||||
|
||||
level thread defconKillstreakWait( (requiredKillCount * 3) );
|
||||
level thread defconKillstreakWait( (requiredKillCount * 3) - 1 );
|
||||
level thread defconKillstreakWait( (requiredKillCount * 3) - 2 );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill ( "defcon_killstreak", streakCount, changingPlayer );
|
||||
|
||||
if ( game["defcon"] <= 1 )
|
||||
continue;
|
||||
|
||||
if ( (streakCount % requiredKillCount) == requiredKillCount - 2 )
|
||||
{
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( !isAlive( player ) )
|
||||
continue;
|
||||
|
||||
player thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "two_from_defcon", changingPlayer );
|
||||
}
|
||||
}
|
||||
else if ( (streakCount % requiredKillCount) == requiredKillCount - 1 )
|
||||
{
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( !isAlive( player ) )
|
||||
continue;
|
||||
|
||||
player thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "one_from_defcon", changingPlayer );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
updateDefcon( game["defcon"] - 1, changingPlayer, streakCount );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateDefcon( newDefcon, changingPlayer, streakCount )
|
||||
{
|
||||
newDefcon = int( newDefcon );
|
||||
oldDefcon = game["defcon"];
|
||||
game["defcon"] = newDefcon;
|
||||
|
||||
// level.killStreakMod = level.defconStreakAdd[newDefcon];
|
||||
level.objectivePointsMod = level.defconPointMod[newDefcon];
|
||||
|
||||
setDvar( "scr_defcon", game["defcon"] );
|
||||
|
||||
//isdefined used for variable init
|
||||
if( isDefined( changingPlayer ) )
|
||||
changingPlayer notify( "changed_defcon" );
|
||||
|
||||
if ( newDefcon == oldDefcon )
|
||||
return;
|
||||
|
||||
if ( game["defcon"] == 3 && isDefined( changingPlayer ) )
|
||||
{
|
||||
changingPlayer maps\mp\killstreaks\_killstreaks::giveKillstreak( "airdrop_mega" );
|
||||
changingPlayer thread maps\mp\gametypes\_hud_message::splashNotify( "caused_defcon" , streakCount );
|
||||
}
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( isAlive( player ) )
|
||||
{
|
||||
player thread maps\mp\gametypes\_hud_message::defconSplashNotify( game["defcon"], newDefcon < oldDefcon );
|
||||
if ( isDefined( changingPlayer ) )
|
||||
player thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "changed_defcon", changingPlayer );
|
||||
}
|
||||
}
|
||||
}
|
82
maps/mp/_destructables.gsc
Normal file
82
maps/mp/_destructables.gsc
Normal file
@ -0,0 +1,82 @@
|
||||
init()
|
||||
{
|
||||
// level.destructableFX = loadfx("fx/breakables/exp_wall_cinderblock_96");
|
||||
|
||||
ents = getentarray("destructable", "targetname");
|
||||
|
||||
if (getdvar("scr_destructables") == "0")
|
||||
{
|
||||
for (i = 0; i < ents.size; i++)
|
||||
ents[i] delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < ents.size; i++)
|
||||
{
|
||||
ents[i] thread destructable_think();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destructable_think()
|
||||
{
|
||||
accumulate = 40;
|
||||
threshold = 0;
|
||||
|
||||
if (isdefined(self.script_accumulate))
|
||||
accumulate = self.script_accumulate;
|
||||
if (isdefined(self.script_threshold))
|
||||
threshold = self.script_threshold;
|
||||
|
||||
if (isdefined(self.script_destructable_area)) {
|
||||
areas = strtok(self.script_destructable_area, " ");
|
||||
for (i = 0; i < areas.size; i++)
|
||||
self blockArea(areas[i]);
|
||||
}
|
||||
|
||||
if ( isdefined( self.script_fxid ) )
|
||||
self.fx = loadfx( self.script_fxid );
|
||||
|
||||
dmg = 0;
|
||||
|
||||
self setcandamage(true);
|
||||
while(1)
|
||||
{
|
||||
self waittill("damage", amount, other);
|
||||
if (amount >= threshold)
|
||||
{
|
||||
dmg += amount;
|
||||
if (dmg >= accumulate)
|
||||
{
|
||||
self thread destructable_destruct();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destructable_destruct()
|
||||
{
|
||||
ent = self;
|
||||
if (isdefined(self.script_destructable_area)) {
|
||||
areas = strtok(self.script_destructable_area, " ");
|
||||
for (i = 0; i < areas.size; i++)
|
||||
self unblockArea(areas[i]);
|
||||
}
|
||||
if ( isdefined( ent.fx ) )
|
||||
playfx( ent.fx, ent.origin + (0,0,6) );
|
||||
ent delete();
|
||||
}
|
||||
|
||||
blockArea(area)
|
||||
{
|
||||
}
|
||||
blockEntsInArea(ents, area)
|
||||
{
|
||||
}
|
||||
unblockArea(area)
|
||||
{
|
||||
}
|
||||
unblockEntsInArea(ents, area)
|
||||
{
|
||||
}
|
294
maps/mp/_dlcalienegg.gsc
Normal file
294
maps/mp/_dlcalienegg.gsc
Normal file
@ -0,0 +1,294 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
CONST_EGG_ID = "dlcEggStatus";
|
||||
CONST_ALL_EGG_CHALLENGE = "ch_weekly_1";
|
||||
|
||||
init()
|
||||
{
|
||||
// this is a terrible hack.
|
||||
// We are tracking all of the egg state in one 32-bit integer.
|
||||
// The lower 16 bits track whether the player has shot the egg for that level, 4-bits per map-pack.
|
||||
|
||||
|
||||
|
||||
// the number of bits shifted should correspond to the order in mapNames.csv
|
||||
// we'll use this to check completion of player data
|
||||
level.dlcAlienEggs = [];
|
||||
// pack 1
|
||||
level.dlcAlienEggs[ "mp_boneyard_ns" ] = 1 << 0;
|
||||
level.dlcAlienEggs[ "mp_swamp" ] = 1 << 1;
|
||||
level.dlcAlienEggs[ "mp_ca_red_river" ] = 1 << 2;
|
||||
level.dlcAlienEggs[ "mp_ca_rumble" ] = 1 << 3;
|
||||
|
||||
// pack 2
|
||||
level.dlcAlienEggs[ "mp_dome_ns" ] = 1 << 4;
|
||||
level.dlcAlienEggs[ "mp_battery3" ] = 1 << 5;
|
||||
level.dlcAlienEggs[ "mp_ca_impact" ] = 1 << 6;
|
||||
level.dlcAlienEggs[ "mp_ca_behemoth" ] = 1 << 7;
|
||||
|
||||
// pack 3. bits 8-11
|
||||
level.dlcAlienEggs[ "mp_dig" ] = 1 << 8;
|
||||
level.dlcAlienEggs[ "mp_favela_iw6" ] = 1 << 9;
|
||||
level.dlcAlienEggs[ "mp_pirate" ] = 1 << 10;
|
||||
level.dlcAlienEggs[ "mp_zulu" ] = 1 << 11;
|
||||
|
||||
// pack 4. bits 12-15
|
||||
level.dlcAlienEggs[ "mp_conflict" ] = 1 << 12;
|
||||
level.dlcAlienEggs[ "mp_mine" ] = 1 << 13;
|
||||
level.dlcAlienEggs[ "mp_zerosub" ] = 1 << 14;
|
||||
level.dlcAlienEggs[ "mp_shipment_ns" ] = 1 << 15;
|
||||
|
||||
// Translate each map name to its pack number (0-based)
|
||||
level.dlcAliengEggMapToPack[ "mp_boneyard_ns" ] = 0;
|
||||
level.dlcAliengEggMapToPack[ "mp_swamp" ] = 0;
|
||||
level.dlcAliengEggMapToPack[ "mp_ca_red_river" ] = 0;
|
||||
level.dlcAliengEggMapToPack[ "mp_ca_rumble" ] = 0;
|
||||
|
||||
level.dlcAliengEggMapToPack[ "mp_dome_ns" ] = 1;
|
||||
level.dlcAliengEggMapToPack[ "mp_battery3" ] = 1;
|
||||
level.dlcAliengEggMapToPack[ "mp_ca_impact" ] = 1;
|
||||
level.dlcAliengEggMapToPack[ "mp_ca_behemoth" ] = 1;
|
||||
|
||||
level.dlcAliengEggMapToPack[ "mp_dig" ] = 2;
|
||||
level.dlcAliengEggMapToPack[ "mp_favela_iw6" ] = 2;
|
||||
level.dlcAliengEggMapToPack[ "mp_pirate" ] = 2;
|
||||
level.dlcAliengEggMapToPack[ "mp_zulu" ] = 2;
|
||||
|
||||
// pack 4. bits 12-15
|
||||
level.dlcAliengEggMapToPack[ "mp_conflict" ] = 3;
|
||||
level.dlcAliengEggMapToPack[ "mp_mine" ] = 3;
|
||||
level.dlcAliengEggMapToPack[ "mp_zerosub" ] = 3;
|
||||
level.dlcAliengEggMapToPack[ "mp_shipment_ns" ] = 3;
|
||||
|
||||
// # of set bits in 0 - 15
|
||||
// use to look up how many eggs have been achieved
|
||||
level.bitCounts = [ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 ];
|
||||
|
||||
level._effect[ "vfx_alien_easter_egg_hit" ] = loadfx( "vfx/gameplay/alien/vfx_alien_easter_egg_hit" );
|
||||
}
|
||||
|
||||
setupEggForMap( eggName )
|
||||
{
|
||||
if ( level.rankedMatch )
|
||||
{
|
||||
init();
|
||||
|
||||
flags = level.dlcAlienEggs[ getMapName() ];
|
||||
|
||||
AssertEx( IsDefined( flags ), "dlcAlienEggs bit flag not set up for map: " + getMapName() );
|
||||
|
||||
egg = GetEnt( eggName, "targetname" );
|
||||
if ( IsDefined( egg ) )
|
||||
{
|
||||
// add flags
|
||||
// playlistType = GetDvarInt( "scr_playlist_type", 0 );
|
||||
|
||||
if ( egg.classname == "script_model" )
|
||||
{
|
||||
egg SetCanDamage( true );
|
||||
}
|
||||
|
||||
egg thread eggTrackHits();
|
||||
}
|
||||
|
||||
/#
|
||||
thread eggDebug();
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
eggTrackHits()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self.health = 99999;
|
||||
|
||||
level.eggHits = [];
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "damage", damage, attacker, direction, point, damageType );
|
||||
|
||||
// play a sound and effect?
|
||||
PlayFX( getfx( "vfx_alien_easter_egg_hit" ), point, AnglesToForward( direction ), AnglesToUp( direction ) );
|
||||
|
||||
if ( IsPlayer( attacker ) && !IsAI( attacker ) )
|
||||
{
|
||||
attackerNum = attacker getUniqueId();
|
||||
// we have not hit this egg before
|
||||
if ( !IsDefined( level.eggHits[ attackerNum ] ) )
|
||||
{
|
||||
level.eggHits[ attackerNum ] = 1;
|
||||
self eggRegisterHit( damage, attacker, direction, point, damageType );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eggRegisterHit( damage, attacker, direction, point, type )
|
||||
{
|
||||
self.health += damage; // don't let the health drop
|
||||
|
||||
if ( !( attacker eggHasCompletedForMap( getMapName() ) ) )
|
||||
{
|
||||
attacker eggSetCompletedForMap( getMapName() );
|
||||
}
|
||||
else if ( attacker eggAllFound()
|
||||
&& attacker ch_getState( CONST_ALL_EGG_CHALLENGE ) < 2
|
||||
)
|
||||
{
|
||||
attacker eggAwardPatch();
|
||||
}
|
||||
}
|
||||
|
||||
eggHasCompletedForMap( mapName ) // self == player
|
||||
{
|
||||
eggState = self GetRankedPlayerDataReservedInt( CONST_EGG_ID );
|
||||
|
||||
bitFlag = level.dlcAlienEggs[ mapName ];
|
||||
if ( IsDefined( bitFlag ) &&
|
||||
(eggState & bitFlag) != 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
eggSetCompletedForMap( mapName ) // self == player
|
||||
{
|
||||
bitFlag = level.dlcAlienEggs[ mapName ];
|
||||
|
||||
if ( IsDefined( bitFlag ) )
|
||||
{
|
||||
eggState = self GetRankedPlayerDataReservedInt( CONST_EGG_ID );
|
||||
|
||||
eggState |= bitFlag;
|
||||
self SetRankedPlayerDataReservedInt( CONST_EGG_ID, eggState );
|
||||
|
||||
packNum = level.dlcAliengEggMapToPack[ mapName ];
|
||||
AssertEx( IsDefined( packNum ), "MapPack ID not defined for " + mapName );
|
||||
|
||||
numCompleted = eggCountCompletedEggsForPack( packNum, eggState );
|
||||
packNum++; // the splashes are indexed 1-4, instead of 0-3
|
||||
if ( numCompleted < 4 )
|
||||
{
|
||||
self maps\mp\gametypes\_hud_message::playerCardSplashNotify( "dlc_eggFound_" + packNum, self, numCompleted );
|
||||
}
|
||||
else
|
||||
{
|
||||
// if all the eggs are found, give ultimate award
|
||||
if ( self eggAllFound()
|
||||
&& ch_getState( CONST_ALL_EGG_CHALLENGE ) < 2
|
||||
)
|
||||
{
|
||||
self eggAwardPatch();
|
||||
}
|
||||
// otherwise give award for this pack
|
||||
else
|
||||
{
|
||||
self maps\mp\gametypes\_hud_message::playerCardSplashNotify( "dlc_eggAllFound_" + packNum, self );
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "dlc_egg_hunt" );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
self PlayLocalSound( "ui_extinction_egg_splash" );
|
||||
}
|
||||
}
|
||||
|
||||
eggAwardPatch()
|
||||
{
|
||||
self maps\mp\gametypes\_hud_message::playerCardSplashNotify( "dlc_eggAllFound", self );
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "dlc_egg_hunt_all" );
|
||||
|
||||
ch_setState( CONST_ALL_EGG_CHALLENGE, 2 ); // patch. Weekly challenges are unlocked with state set to 2.
|
||||
}
|
||||
|
||||
eggCountCompletedEggsForPack( packNum, eggState )
|
||||
{
|
||||
flags = eggState >> (packnum * 4); // move the bits to the first set of 4
|
||||
flags &= 15; // mask out everything but the first four bits
|
||||
|
||||
return level.bitCounts[ flags ];
|
||||
}
|
||||
|
||||
// packNum is 0-indexed
|
||||
eggAllFoundForPack( packNum )
|
||||
{
|
||||
eggState = self GetRankedPlayerDataReservedInt( CONST_EGG_ID );
|
||||
packEggState = (eggState >> (packnum *4)) & 15;
|
||||
|
||||
return (packEggState != 0);
|
||||
}
|
||||
|
||||
// all 16 eggs found
|
||||
CONST_ALL_EGGS_MASK = (1 << 16) - 1;
|
||||
eggAllFound()
|
||||
{
|
||||
eggState = self GetRankedPlayerDataReservedInt( CONST_EGG_ID );
|
||||
|
||||
return ( eggState == CONST_ALL_EGGS_MASK );
|
||||
}
|
||||
|
||||
/#
|
||||
eggDebug()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
level waittill( "connected", player );
|
||||
|
||||
player thread eggDebugPlayer();
|
||||
}
|
||||
|
||||
eggDebugPlayer() // self == player
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
SetDvarIfUninitialized( "scr_egg_set", "" );
|
||||
SetDvarIfUninitialized( "scr_egg_pack_set", 0 );
|
||||
SetDvarIfUninitialized( "scr_egg_clear", 0 );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
mapName = GetDvar( "scr_egg_set" );
|
||||
if ( mapName != "" )
|
||||
{
|
||||
self eggSetCompletedForMap( mapName );
|
||||
SetDvar( "scr_egg_set", "" );
|
||||
}
|
||||
|
||||
if ( GetDvarInt( "scr_egg_clear" ) != 0 )
|
||||
{
|
||||
self SetRankedPlayerDataReservedInt( CONST_EGG_ID, 0 );
|
||||
SetDvar( "scr_egg_clear", 0 );
|
||||
level.eggHits = [];
|
||||
|
||||
ch_setState( CONST_ALL_EGG_CHALLENGE, 0 );
|
||||
}
|
||||
|
||||
// set all the flags for one pack
|
||||
targetPackNum = GetDvarInt( "scr_egg_pack_set" );
|
||||
if ( targetPackNum > 0 )
|
||||
{
|
||||
targetPackNum--;
|
||||
|
||||
foreach ( mapName, packNum in level.dlcAliengEggMapToPack )
|
||||
{
|
||||
if ( packNum == targetPackNum && !( self eggHasCompletedForMap( mapName ) ) )
|
||||
{
|
||||
self eggSetCompletedForMap( mapName );
|
||||
wait (3.6); // a little bit more than the duration of the splash
|
||||
}
|
||||
}
|
||||
|
||||
SetDvar( "scr_egg_pack_set", "" );
|
||||
}
|
||||
|
||||
wait ( 0.25 );
|
||||
}
|
||||
}
|
||||
#/
|
378
maps/mp/_elevator.gsc
Normal file
378
maps/mp/_elevator.gsc
Normal file
@ -0,0 +1,378 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
// ELEVATOR TEST
|
||||
ELEVATOR_DOOR_TIME = 2;
|
||||
ELEVATOR_FLOOR_MOVE_TIME = 5;
|
||||
ELEVATOR_AUTOCLOSE_TIMEOUT = 10;
|
||||
|
||||
ELEVATOR_DOOR_STATE_CLOSED = 0;
|
||||
ELEVATOR_DOOR_STATE_OPENING = 1;
|
||||
ELEVATOR_DOOR_STATE_OPEN = 2;
|
||||
ELEVATOR_DOOR_STATE_CLOSING = 3;
|
||||
|
||||
// should scale elevator door speed based on the actual distance moved
|
||||
// in case of interrupts
|
||||
|
||||
init_elevator( config )
|
||||
{
|
||||
elevator = GetEnt( config.name, "targetname" );
|
||||
AssertEx( IsDefined( elevator ), "Could not find an elevator entity named " + config.name );
|
||||
elevator.unresolved_collision_func = ::handleUnreslovedCollision;
|
||||
|
||||
elevator.doors = [];
|
||||
foreach ( floorname, doorset in config.doors )
|
||||
{
|
||||
list = [];
|
||||
foreach ( doorname in doorset )
|
||||
{
|
||||
list[ list.size ] = setupDoor( doorName + "left", false, config.doorMoveDist );
|
||||
list[ list.size ] = setupDoor( doorName + "right", true, config.doorMoveDist );
|
||||
}
|
||||
|
||||
elevator.doors[ floorname ] = list;
|
||||
}
|
||||
|
||||
elevator.trigBlock = GetEnt( config.trigBlockName, "targetname" );
|
||||
AssertEx( IsDefined( elevator.trigBlock ), "Could not find an elevator trigger named " + config.trigBlockName );
|
||||
|
||||
elevator.curFloor = "floor1";
|
||||
elevator.requestedFloor = elevator.curFloor;
|
||||
elevator.doorState = ELEVATOR_DOOR_STATE_CLOSED;
|
||||
|
||||
elevator.doorOpenTime = 2.0;
|
||||
elevator.doorSpeed = config.doorMoveDist / elevator.doorOpenTime;
|
||||
elevator.moveTime = 5.0;
|
||||
elevator.autoCloseTimeout = 10.0;
|
||||
|
||||
elevator.destinations = [];
|
||||
elevator.pathBlockers = [];
|
||||
elevator.buttons = GetEntArray( config.buttons, "targetname" );
|
||||
foreach ( button in elevator.buttons )
|
||||
{
|
||||
button setupButton( elevator );
|
||||
}
|
||||
|
||||
elevatorModels = GetEntArray( "elevator_models", "targetname" );
|
||||
foreach ( eleModel in elevatorModels )
|
||||
{
|
||||
eleModel LinkTo( elevator );
|
||||
}
|
||||
|
||||
elevator thread elevatorThink();
|
||||
|
||||
elevator thread openElevatorDoors( elevator.curFloor, false );
|
||||
}
|
||||
|
||||
setupDoor( doorName, isRightSide, moveDistance )
|
||||
{
|
||||
door = GetEnt( doorName, "targetname" );
|
||||
if (IsDefined(door))
|
||||
{
|
||||
door.closePos = door.origin;
|
||||
if (IsDefined(door.target))
|
||||
{
|
||||
targetStruct = getstruct( door.target, "targetname" );
|
||||
door.openPos = targetStruct.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = AnglesToForward( door.angles ) * moveDistance;
|
||||
/*
|
||||
if (isRightSide)
|
||||
{
|
||||
offset *= -1;
|
||||
}
|
||||
*/
|
||||
door.openPos = door.origin + offset;
|
||||
}
|
||||
|
||||
// door.unresolved_collision_func = ::handleUnreslovedCollision;
|
||||
|
||||
return door;
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertEx( IsDefined( door ), "Could not find an elevator door entity named " + doorName );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setupButton( elevator ) // self == button
|
||||
{
|
||||
self.owner = elevator;
|
||||
|
||||
if ( IsDefined( self.target ) )
|
||||
{
|
||||
destination = getstruct( self.target, "targetname" );
|
||||
if ( IsDefined( destination ) )
|
||||
{
|
||||
elevator.destinations[ self.script_label ] = destination.origin;
|
||||
if ( IsDefined( destination.target ) )
|
||||
{
|
||||
blocker = GetEnt( destination.target, "targetname" );
|
||||
if ( IsDefined( blocker ) )
|
||||
{
|
||||
elevator.pathBlockers[ self.script_label ] = blocker;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self enableButton();
|
||||
}
|
||||
|
||||
enableButton() // self == button
|
||||
{
|
||||
self SetHintString( &"MP_ELEVATOR_USE" );
|
||||
self MakeUsable();
|
||||
|
||||
self thread buttonThink();
|
||||
}
|
||||
|
||||
disableButton()
|
||||
{
|
||||
self MakeUnusable();
|
||||
}
|
||||
|
||||
buttonThink()
|
||||
{
|
||||
elevator = self.owner;
|
||||
elevator endon( "elevator_busy" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "trigger" );
|
||||
|
||||
if ( self.script_label == "elevator" )
|
||||
{
|
||||
// do some stuff
|
||||
if ( elevator.curFloor == "floor1" )
|
||||
{
|
||||
elevator.requestedFloor = "floor2";
|
||||
}
|
||||
else
|
||||
{
|
||||
elevator.requestedFloor = "floor1";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
elevator.requestedFloor = self.script_label;
|
||||
}
|
||||
|
||||
elevator notify( "elevator_called" );
|
||||
}
|
||||
}
|
||||
|
||||
elevatorThink()
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "elevator_called" );
|
||||
|
||||
foreach ( button in self.buttons )
|
||||
{
|
||||
button disableButton();
|
||||
}
|
||||
|
||||
if ( self.curFloor != self.requestedFloor )
|
||||
{
|
||||
if ( self.doorState != ELEVATOR_DOOR_STATE_CLOSED )
|
||||
{
|
||||
self notify ("elevator_stop_autoclose");
|
||||
self thread closeElevatorDoors( self.curFloor );
|
||||
self waittill( "elevator_doors_closed" );
|
||||
}
|
||||
|
||||
self elevatorMoveToFloor( self.requestedFloor );
|
||||
wait (0.25);
|
||||
}
|
||||
|
||||
self thread openElevatorDoors( self.curFloor, false );
|
||||
|
||||
self waittill ( "elevator_doors_open" );
|
||||
foreach ( button in self.buttons )
|
||||
{
|
||||
button enableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elevatorMoveToFloor( targetFloor )
|
||||
{
|
||||
self PlaySound( "scn_elevator_startup" );
|
||||
self PlayLoopSound( "scn_elevator_moving_lp" );
|
||||
|
||||
destinationPos = self.destinations[ targetFloor ];
|
||||
deltaZ = destinationPos[2] - self.origin[2];
|
||||
|
||||
// move doors
|
||||
foreach ( door in self.doors[ "elevator" ] )
|
||||
{
|
||||
door MoveZ( deltaZ, self.moveTime );
|
||||
}
|
||||
// move the floor
|
||||
self MoveZ( deltaZ, self.moveTime );
|
||||
|
||||
wait ( self.moveTime );
|
||||
|
||||
self StopLoopSound ( "scn_elevator_moving_lp" );
|
||||
self PlaySound ( "scn_elevator_stopping" );
|
||||
self PlaySound ( "scn_elevator_beep" );
|
||||
|
||||
self.curFloor = self.requestedFloor;
|
||||
}
|
||||
|
||||
openElevatorDoors( floorName, autoClose ) // elevator
|
||||
{
|
||||
doorset = self.doors[ floorName ];
|
||||
|
||||
self.doorState = ELEVATOR_DOOR_STATE_OPENING;
|
||||
|
||||
// figre out the time it takes to move 1 door, assume it's the same fo rall
|
||||
door = doorset[0];
|
||||
doorDest = (door.openPos[0], door.openPos[1], door.origin[2]);
|
||||
moveDelta = doorDest - door.origin;
|
||||
moveDist = Length( moveDelta );
|
||||
|
||||
// this might move 0 time / 0 dist
|
||||
// but we need it to counteract the closing elevator
|
||||
// wish I could just tell it to stop, instead
|
||||
movetime = moveDist / self.doorSpeed;
|
||||
accelTime = 0.25;
|
||||
if (moveTime == 0.0)
|
||||
{
|
||||
moveTime = 0.05;
|
||||
accelTime = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self PlaySound( "scn_elevator_doors_opening" );
|
||||
accelTime = min(accelTime, moveTime);
|
||||
}
|
||||
|
||||
foreach ( door in doorset )
|
||||
{
|
||||
door MoveTo( (door.openPos[0], door.openPos[1], door.origin[2]), movetime, 0.0, accelTime );
|
||||
}
|
||||
wait ( movetime );
|
||||
|
||||
self.doorState = ELEVATOR_DOOR_STATE_OPEN;
|
||||
|
||||
self notify ( "elevator_doors_open" );
|
||||
|
||||
self elevatorClearPath( floorName );
|
||||
|
||||
if ( autoClose )
|
||||
{
|
||||
self thread elevatorDoorsAutoClose();
|
||||
}
|
||||
}
|
||||
|
||||
closeElevatorDoors( floorName )
|
||||
{
|
||||
self endon( "elevator_close_interrupted" );
|
||||
|
||||
self thread watchCloseInterrupted( floorName );
|
||||
|
||||
doorset = self.doors[ floorName ];
|
||||
|
||||
self.doorState = ELEVATOR_DOOR_STATE_CLOSING;
|
||||
|
||||
// figre out the time it takes to move 1 door, assume it's the same fo rall
|
||||
door = doorset[0];
|
||||
doorDest = (door.closePos[0], door.closePos[1], door.origin[2]);
|
||||
moveDelta = doorDest - door.origin;
|
||||
moveDist = Length( moveDelta );
|
||||
|
||||
if ( moveDist != 0.0 )
|
||||
{
|
||||
movetime = moveDist / self.doorSpeed;
|
||||
foreach ( door in doorset )
|
||||
{
|
||||
// we assume the doors all begin closed,
|
||||
// so door.closePos should eventually be defined by the time we need it
|
||||
door MoveTo( (door.closePos[0], door.closePos[1], door.origin[2]), movetime, 0.0, 0.25 );
|
||||
}
|
||||
self PlaySound( "scn_elevator_doors_closing" );
|
||||
wait ( movetime );
|
||||
}
|
||||
|
||||
self.doorState = ELEVATOR_DOOR_STATE_CLOSED;
|
||||
|
||||
self elevatorBlockPath( floorName );
|
||||
|
||||
self notify( "elevator_doors_closed" );
|
||||
}
|
||||
|
||||
watchCloseInterrupted( floorName )
|
||||
{
|
||||
// if the doors have closed successfully, we don't care any more
|
||||
self endon( "elevator_doors_closed" );
|
||||
|
||||
// make sure there is nothing in the way now
|
||||
nothingBlocking = true;
|
||||
foreach ( character in level.characters )
|
||||
{
|
||||
if ( character isTouchingTrigger( self.trigBlock ) )
|
||||
{
|
||||
nothingBlocking = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( nothingBlocking )
|
||||
{
|
||||
self.trigBlock waittill( "trigger" );
|
||||
}
|
||||
|
||||
self notify( "elevator_close_interrupted" );
|
||||
|
||||
self openElevatorDoors( floorName, true );
|
||||
}
|
||||
|
||||
isTouchingTrigger( trigger ) // self == player
|
||||
{
|
||||
return ( IsAlive( self ) && self IsTouching( trigger ) );
|
||||
}
|
||||
|
||||
elevatorDoorsAutoClose() // self == elevator
|
||||
{
|
||||
self endon( "elevator_doors_closed" );
|
||||
self endon( "elevator_stop_autoclose" );
|
||||
|
||||
wait ( self.autoCloseTimeout );
|
||||
|
||||
self closeElevatorDoors( self.curFloor);
|
||||
}
|
||||
|
||||
handleUnreslovedCollision( hitEnt ) // self == mover, hitEnt == player (usually)
|
||||
{
|
||||
if ( !IsPlayer( hitEnt ) )
|
||||
{
|
||||
hitEnt DoDamage( 1000, hitEnt.origin, self, self, "MOD_CRUSH" );
|
||||
}
|
||||
}
|
||||
|
||||
elevatorClearPath( floorName ) // self == elevator
|
||||
{
|
||||
blocker = self.pathBlockers[ floorName ];
|
||||
if ( IsDefined( blocker ) )
|
||||
{
|
||||
blocker ConnectPaths();
|
||||
blocker Hide();
|
||||
blocker NotSolid();
|
||||
}
|
||||
}
|
||||
|
||||
elevatorBlockPath( floorName )
|
||||
{
|
||||
blocker = self.pathBlockers[ floorName ];
|
||||
if ( IsDefined( blocker ) )
|
||||
{
|
||||
blocker Show();
|
||||
blocker Solid();
|
||||
blocker DisconnectPaths();
|
||||
}
|
||||
}
|
468
maps/mp/_elevator_v2.gsc
Normal file
468
maps/mp/_elevator_v2.gsc
Normal file
@ -0,0 +1,468 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
// _elevator_v2: used in mp_mines.gsc (original was used in mp_fahrenheit).
|
||||
// Making adjustments to allow for multiple types of elevators
|
||||
|
||||
// ELEVATOR TEST
|
||||
ELEVATOR_DOOR_TIME = 2;
|
||||
ELEVATOR_FLOOR_MOVE_TIME = 5;
|
||||
ELEVATOR_AUTOCLOSE_TIMEOUT = 10;
|
||||
|
||||
ELEVATOR_DOOR_STATE_CLOSED = 0;
|
||||
ELEVATOR_DOOR_STATE_OPENING = 1;
|
||||
ELEVATOR_DOOR_STATE_OPEN = 2;
|
||||
ELEVATOR_DOOR_STATE_CLOSING = 3;
|
||||
|
||||
// should scale elevator door speed based on the actual distance moved
|
||||
// in case of interrupts
|
||||
|
||||
init_elevator( config )
|
||||
{
|
||||
elevator = GetEnt( config.name, "targetname" );
|
||||
AssertEx( IsDefined( elevator ), "Could not find an elevator entity named " + config.name );
|
||||
elevator.unresolved_collision_func = ::handleUnreslovedCollision;
|
||||
|
||||
elevator.doors = [];
|
||||
if ( IsDefined( config.doors ) )
|
||||
{
|
||||
foreach ( floorname, doorset in config.doors )
|
||||
{
|
||||
list = [];
|
||||
foreach ( doorname in doorset )
|
||||
{
|
||||
list[ list.size ] = setupDoor( doorName + "left", false, config.doorMoveDist );
|
||||
list[ list.size ] = setupDoor( doorName + "right", true, config.doorMoveDist );
|
||||
}
|
||||
|
||||
elevator.doors[ floorname ] = list;
|
||||
}
|
||||
|
||||
if ( IsDefined( config.doorOpenTime ) )
|
||||
elevator.doorOpenTime = config.doorOpenTime;
|
||||
else
|
||||
elevator.doorOpenTime = ELEVATOR_DOOR_TIME;
|
||||
|
||||
elevator.doorSpeed = config.doorMoveDist / elevator.doorOpenTime;
|
||||
|
||||
if ( IsDefined( config.autoCloseTimeout ) )
|
||||
elevator.autoCloseTimeout = config.autoCloseTimeout;
|
||||
else
|
||||
elevator.autoCloseTimeout = ELEVATOR_AUTOCLOSE_TIMEOUT;
|
||||
|
||||
elevator.trigBlock = GetEnt( config.trigBlockName, "targetname" );
|
||||
AssertEx( IsDefined( elevator.trigBlock ), "Could not find an elevator trigger named " + config.trigBlockName );
|
||||
|
||||
if ( IsDefined( config.autoCloseTimeout ) )
|
||||
elevator.autoCloseTimeout = config.autoCloseTimeout;
|
||||
else
|
||||
elevator.autoCloseTimeout = ELEVATOR_AUTOCLOSE_TIMEOUT;
|
||||
|
||||
elevator.doorOpenSfx = config.doorOpenSfx; // scn_elevator_doors_opening
|
||||
elevator.doorCloseSfx = config.doorCloseSfx; // scn_elevator_doors_closing
|
||||
}
|
||||
|
||||
if ( IsDefined( config.moveTime ) )
|
||||
elevator.moveTime = config.moveTime;
|
||||
else
|
||||
elevator.moveTime = ELEVATOR_FLOOR_MOVE_TIME;
|
||||
|
||||
elevator.destinations = [];
|
||||
elevator.pathBlockers = [];
|
||||
elevator.buttons = GetEntArray( config.buttons, "targetname" );
|
||||
foreach ( button in elevator.buttons )
|
||||
{
|
||||
button setupButton( elevator );
|
||||
}
|
||||
|
||||
// set up destinations
|
||||
destinationStructs = getstructarray( config.destinations, "targetname" );
|
||||
foreach ( destination in destinationStructs )
|
||||
{
|
||||
elevator setupDestination( destination );
|
||||
}
|
||||
elevator.destinationNames = config.destinationNames;
|
||||
|
||||
elevator.curFloor = config.destinationNames[0]; // "floor1"; should this be determined from destinations?
|
||||
elevator.requestedFloor = elevator.curFloor;
|
||||
elevator.doorState = ELEVATOR_DOOR_STATE_CLOSED;
|
||||
|
||||
if ( IsDefined( config.models ) )
|
||||
{
|
||||
elevatorModels = GetEntArray( config.models, "targetname" );
|
||||
if ( IsDefined( elevatorModels ) )
|
||||
{
|
||||
foreach ( eleModel in elevatorModels )
|
||||
{
|
||||
eleModel LinkTo( elevator );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elevator thread elevatorThink();
|
||||
|
||||
if (elevator.doors.size > 0)
|
||||
{
|
||||
elevator thread openElevatorDoors( elevator.curFloor, false );
|
||||
}
|
||||
|
||||
// sounds
|
||||
elevator.startSfx = config.startSfx; // "scn_elevator_startup"
|
||||
elevator.stopSfx = config.stopSfx; // "scn_elevator_stopping"
|
||||
elevator.loopSfx = config.loopSfx; // "scn_elevator_moving_lp"
|
||||
elevator.beepSfx = config.beepSfx; // "scn_elevator_beep"
|
||||
|
||||
|
||||
// callback on init
|
||||
elevator.onMoveCallback = config.onMoveCallback;
|
||||
elevator.onArrivedCallback = config.onArrivedCallback;
|
||||
|
||||
return elevator;
|
||||
}
|
||||
|
||||
setupDoor( doorName, isRightSide, moveDistance )
|
||||
{
|
||||
door = GetEnt( doorName, "targetname" );
|
||||
if (IsDefined(door))
|
||||
{
|
||||
door.closePos = door.origin;
|
||||
if (IsDefined(door.target))
|
||||
{
|
||||
targetStruct = getstruct( door.target, "targetname" );
|
||||
door.openPos = targetStruct.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = AnglesToForward( door.angles ) * moveDistance;
|
||||
/*
|
||||
if (isRightSide)
|
||||
{
|
||||
offset *= -1;
|
||||
}
|
||||
*/
|
||||
door.openPos = door.origin + offset;
|
||||
}
|
||||
|
||||
// door.unresolved_collision_func = ::handleUnreslovedCollision;
|
||||
|
||||
return door;
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertEx( IsDefined( door ), "Could not find an elevator door entity named " + doorName );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setupButton( elevator ) // self == button
|
||||
{
|
||||
self.owner = elevator;
|
||||
|
||||
if ( IsDefined( self.target ) )
|
||||
{
|
||||
destination = getstruct( self.target, "targetname" );
|
||||
self setupDestination( destination );
|
||||
}
|
||||
|
||||
self enableButton();
|
||||
}
|
||||
|
||||
setupDestination( destination ) // self == elevator
|
||||
{
|
||||
|
||||
if ( IsDefined( destination ) )
|
||||
{
|
||||
self.destinations[ destination.script_label ] = destination.origin;
|
||||
if ( IsDefined( destination.target ) )
|
||||
{
|
||||
blocker = GetEnt( destination.target, "targetname" );
|
||||
if ( IsDefined( blocker ) )
|
||||
{
|
||||
self.pathBlockers[ destination.script_label ] = blocker;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enableButton() // self == button
|
||||
{
|
||||
self SetHintString( &"MP_ELEVATOR_USE" );
|
||||
self MakeUsable();
|
||||
|
||||
self thread buttonThink();
|
||||
}
|
||||
|
||||
disableButton()
|
||||
{
|
||||
self MakeUnusable();
|
||||
}
|
||||
|
||||
buttonThink()
|
||||
{
|
||||
elevator = self.owner;
|
||||
elevator endon( "elevator_busy" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "trigger" );
|
||||
|
||||
if ( !IsDefined( self.script_label ) || self.script_label == "elevator" )
|
||||
{
|
||||
// do some stuff
|
||||
if ( elevator.curFloor == elevator.destinationNames[0] )
|
||||
{
|
||||
elevator.requestedFloor = elevator.destinationNames[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
elevator.requestedFloor = elevator.destinationNames[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
elevator.requestedFloor = self.script_label;
|
||||
}
|
||||
|
||||
elevator notify( "elevator_called" );
|
||||
}
|
||||
}
|
||||
|
||||
elevatorThink()
|
||||
{
|
||||
hasDoors = self.doors.size > 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "elevator_called" );
|
||||
|
||||
foreach ( button in self.buttons )
|
||||
{
|
||||
button disableButton();
|
||||
}
|
||||
|
||||
if ( self.curFloor != self.requestedFloor )
|
||||
{
|
||||
if ( self.doorState != ELEVATOR_DOOR_STATE_CLOSED )
|
||||
{
|
||||
self notify ("elevator_stop_autoclose");
|
||||
self thread closeElevatorDoors( self.curFloor );
|
||||
self waittill( "elevator_doors_closed" );
|
||||
}
|
||||
else if ( !hasDoors )
|
||||
{
|
||||
self elevatorBlockPath( self.curFloor );
|
||||
}
|
||||
|
||||
self elevatorMoveToFloor( self.requestedFloor );
|
||||
wait (0.25);
|
||||
}
|
||||
|
||||
if ( hasDoors )
|
||||
{
|
||||
self thread openElevatorDoors( self.curFloor, false );
|
||||
self waittill ( "elevator_doors_open" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self elevatorClearPath( self.curFloor );
|
||||
}
|
||||
|
||||
foreach ( button in self.buttons )
|
||||
{
|
||||
button enableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elevatorMoveToFloor( targetFloor )
|
||||
{
|
||||
//self PlaySound( self.startSfx );
|
||||
//self PlayLoopSound( self.loopSfx );
|
||||
|
||||
destinationPos = self.destinations[ targetFloor ];
|
||||
deltaZ = destinationPos[2] - self.origin[2]; // may need to change this to full vector later
|
||||
|
||||
if ( IsDefined( self.doors[ "elevator" ] ) )
|
||||
{
|
||||
// move doors
|
||||
foreach ( door in self.doors[ "elevator" ] )
|
||||
{
|
||||
door MoveZ( deltaZ, self.moveTime );
|
||||
}
|
||||
}
|
||||
|
||||
// move the floor
|
||||
self MoveZ( deltaZ, self.moveTime );
|
||||
|
||||
if ( IsDefined( self.onMoveCallback ) )
|
||||
{
|
||||
self thread [[ self.onMoveCallback ]]( targetFloor );
|
||||
}
|
||||
|
||||
wait ( self.moveTime );
|
||||
|
||||
//self StopLoopSound ( self.loopSfx );
|
||||
//self PlaySound ( self.stopSfx );
|
||||
if ( IsDefined( self.beepSfx ) )
|
||||
self PlaySound ( self.beepSfx );
|
||||
|
||||
self.curFloor = self.requestedFloor;
|
||||
|
||||
if ( IsDefined( self.onArrivedCallback ) )
|
||||
{
|
||||
self thread [[ self.onArrivedCallback ]]( self.curFloor );
|
||||
}
|
||||
}
|
||||
|
||||
openElevatorDoors( floorName, autoClose ) // elevator
|
||||
{
|
||||
doorset = self.doors[ floorName ];
|
||||
|
||||
self.doorState = ELEVATOR_DOOR_STATE_OPENING;
|
||||
|
||||
// figre out the time it takes to move 1 door, assume it's the same fo rall
|
||||
door = doorset[0];
|
||||
doorDest = (door.openPos[0], door.openPos[1], door.origin[2]);
|
||||
moveDelta = doorDest - door.origin;
|
||||
moveDist = Length( moveDelta );
|
||||
|
||||
// this might move 0 time / 0 dist
|
||||
// but we need it to counteract the closing elevator
|
||||
// wish I could just tell it to stop, instead
|
||||
movetime = moveDist / self.doorSpeed;
|
||||
accelTime = 0.25;
|
||||
if (moveTime == 0.0)
|
||||
{
|
||||
moveTime = 0.05;
|
||||
accelTime = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self PlaySound( self.doorOpenSfx );
|
||||
accelTime = min(accelTime, moveTime);
|
||||
}
|
||||
|
||||
foreach ( door in doorset )
|
||||
{
|
||||
door MoveTo( (door.openPos[0], door.openPos[1], door.origin[2]), movetime, 0.0, accelTime );
|
||||
}
|
||||
wait ( movetime );
|
||||
|
||||
self.doorState = ELEVATOR_DOOR_STATE_OPEN;
|
||||
|
||||
self notify ( "elevator_doors_open" );
|
||||
|
||||
self elevatorClearPath( floorName );
|
||||
|
||||
if ( autoClose )
|
||||
{
|
||||
self thread elevatorDoorsAutoClose();
|
||||
}
|
||||
}
|
||||
|
||||
closeElevatorDoors( floorName )
|
||||
{
|
||||
self endon( "elevator_close_interrupted" );
|
||||
|
||||
self thread watchCloseInterrupted( floorName );
|
||||
|
||||
doorset = self.doors[ floorName ];
|
||||
|
||||
self.doorState = ELEVATOR_DOOR_STATE_CLOSING;
|
||||
|
||||
// figre out the time it takes to move 1 door, assume it's the same fo rall
|
||||
door = doorset[0];
|
||||
doorDest = (door.closePos[0], door.closePos[1], door.origin[2]);
|
||||
moveDelta = doorDest - door.origin;
|
||||
moveDist = Length( moveDelta );
|
||||
|
||||
if ( moveDist != 0.0 )
|
||||
{
|
||||
movetime = moveDist / self.doorSpeed;
|
||||
foreach ( door in doorset )
|
||||
{
|
||||
// we assume the doors all begin closed,
|
||||
// so door.closePos should eventually be defined by the time we need it
|
||||
door MoveTo( (door.closePos[0], door.closePos[1], door.origin[2]), movetime, 0.0, 0.25 );
|
||||
}
|
||||
self PlaySound( self.doorCloseSfx );
|
||||
wait ( movetime );
|
||||
}
|
||||
|
||||
self.doorState = ELEVATOR_DOOR_STATE_CLOSED;
|
||||
|
||||
self elevatorBlockPath( floorName );
|
||||
|
||||
self notify( "elevator_doors_closed" );
|
||||
}
|
||||
|
||||
watchCloseInterrupted( floorName )
|
||||
{
|
||||
// if the doors have closed successfully, we don't care any more
|
||||
self endon( "elevator_doors_closed" );
|
||||
|
||||
// make sure there is nothing in the way now
|
||||
nothingBlocking = true;
|
||||
foreach ( character in level.characters )
|
||||
{
|
||||
if ( character isTouchingTrigger( self.trigBlock ) )
|
||||
{
|
||||
nothingBlocking = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( nothingBlocking )
|
||||
{
|
||||
self.trigBlock waittill( "trigger" );
|
||||
}
|
||||
|
||||
self notify( "elevator_close_interrupted" );
|
||||
|
||||
self openElevatorDoors( floorName, true );
|
||||
}
|
||||
|
||||
isTouchingTrigger( trigger ) // self == player
|
||||
{
|
||||
return ( IsAlive( self ) && self IsTouching( trigger ) );
|
||||
}
|
||||
|
||||
elevatorDoorsAutoClose() // self == elevator
|
||||
{
|
||||
self endon( "elevator_doors_closed" );
|
||||
self endon( "elevator_stop_autoclose" );
|
||||
|
||||
wait ( self.autoCloseTimeout );
|
||||
|
||||
self closeElevatorDoors( self.curFloor);
|
||||
}
|
||||
|
||||
handleUnreslovedCollision( hitEnt ) // self == mover, hitEnt == player (usually)
|
||||
{
|
||||
if ( !IsPlayer( hitEnt ) )
|
||||
{
|
||||
hitEnt DoDamage( 1000, hitEnt.origin, self, self, "MOD_CRUSH" );
|
||||
}
|
||||
}
|
||||
|
||||
elevatorClearPath( floorName ) // self == elevator
|
||||
{
|
||||
blocker = self.pathBlockers[ floorName ];
|
||||
if ( IsDefined( blocker ) )
|
||||
{
|
||||
blocker ConnectPaths();
|
||||
blocker Hide();
|
||||
blocker NotSolid();
|
||||
}
|
||||
}
|
||||
|
||||
elevatorBlockPath( floorName )
|
||||
{
|
||||
blocker = self.pathBlockers[ floorName ];
|
||||
if ( IsDefined( blocker ) )
|
||||
{
|
||||
blocker Show();
|
||||
blocker Solid();
|
||||
blocker DisconnectPaths();
|
||||
}
|
||||
}
|
171
maps/mp/_empgrenade.gsc
Normal file
171
maps/mp/_empgrenade.gsc
Normal file
@ -0,0 +1,171 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\killstreaks\_emp_common;
|
||||
|
||||
|
||||
init()
|
||||
{
|
||||
thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
player thread onPlayerSpawned();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self thread monitorEMPGrenade();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
monitorEMPGrenade()
|
||||
{
|
||||
self endon("death");
|
||||
self endon("disconnect");
|
||||
self endon("faux_spawn");
|
||||
self.empEndTime = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
// self waittill( "emp_grenaded", attacker );
|
||||
self waittill( "emp_damage", attacker, duration );
|
||||
|
||||
if ( !IsAlive( self )
|
||||
|| IsDefined( self.usingRemote )
|
||||
|| ( self _hasPerk( "specialty_empimmune" ) ) //MW3 emp resistance perk
|
||||
|| !IsDefined( attacker )
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hurtVictim = true;
|
||||
hurtAttacker = false;
|
||||
|
||||
assert( IsDefined(self.pers["team"]) );
|
||||
|
||||
if ( level.teamBased
|
||||
&& attacker != self
|
||||
&& IsDefined(attacker.pers["team"])
|
||||
&& attacker.pers["team"] == self.pers["team"]
|
||||
)
|
||||
{
|
||||
if(level.friendlyfire == 0) // no FF
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if(level.friendlyfire == 1) // FF
|
||||
{
|
||||
hurtattacker = false;
|
||||
hurtvictim = true;
|
||||
}
|
||||
else if(level.friendlyfire == 2) // reflect
|
||||
{
|
||||
hurtvictim = false;
|
||||
hurtattacker = true;
|
||||
}
|
||||
else if(level.friendlyfire == 3) // share
|
||||
{
|
||||
hurtattacker = true;
|
||||
hurtvictim = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attacker notify( "emp_hit" );
|
||||
|
||||
if( attacker != self )
|
||||
{
|
||||
attacker maps\mp\gametypes\_missions::processChallenge( "ch_onthepulse" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( hurtvictim && IsDefined(self) )
|
||||
{
|
||||
self thread applyEMP( duration );
|
||||
}
|
||||
if ( hurtattacker )
|
||||
{
|
||||
attacker thread applyEMP( duration );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
applyEMP( duration )
|
||||
{
|
||||
self notify( "applyEmp" );
|
||||
self endon( "applyEmp" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
self endon( "death" );
|
||||
|
||||
wait .05;
|
||||
|
||||
self.empGrenaded = true;
|
||||
self shellshock( "flashbang_mp", 1 );
|
||||
self.empEndTime = GetTime() + (duration * 1000);
|
||||
|
||||
self applyPerPlayerEMPEffects_OnDetonate();
|
||||
self applyPerPlayerEMPEffects();
|
||||
self thread empRumbleLoop( .75 );
|
||||
self thread empGrenadeDeathWaiter();
|
||||
|
||||
wait ( duration );
|
||||
|
||||
self notify( "empGrenadeTimedOut" );
|
||||
self checkToTurnOffEmp();
|
||||
}
|
||||
|
||||
empGrenadeDeathWaiter()
|
||||
{
|
||||
self notify( "empGrenadeDeathWaiter" );
|
||||
self endon( "empGrenadeDeathWaiter" );
|
||||
|
||||
self endon( "empGrenadeTimedOut" );
|
||||
|
||||
self waittill( "death" );
|
||||
self checkToTurnOffEmp();
|
||||
}
|
||||
|
||||
checkToTurnOffEmp()
|
||||
{
|
||||
self.empGrenaded = false;
|
||||
|
||||
if ( !(self shouldPlayerBeAffectedByEMP()) )
|
||||
{
|
||||
self removePerPlayerEMPEffects();
|
||||
}
|
||||
}
|
||||
|
||||
empRumbleLoop( duration )
|
||||
{
|
||||
self endon("emp_rumble_loop");
|
||||
self notify("emp_rumble_loop");
|
||||
|
||||
goalTime = GetTime() + duration * 1000;
|
||||
|
||||
while ( GetTime() < goalTime )
|
||||
{
|
||||
self PlayRumbleOnEntity( "damage_heavy" );
|
||||
wait( 0.05 );
|
||||
}
|
||||
}
|
||||
|
||||
// 2013-06-30 wallace: is isEMPGrenaded being used any more? Not sure if we even need the timestamp
|
||||
isEMPGrenaded()
|
||||
{
|
||||
return isDefined( self.empEndTime ) && gettime() < self.empEndTime;
|
||||
}
|
331
maps/mp/_entityheadicons.gsc
Normal file
331
maps/mp/_entityheadicons.gsc
Normal file
@ -0,0 +1,331 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
init()
|
||||
{
|
||||
if (isdefined(level.initedEntityHeadIcons))
|
||||
return;
|
||||
level.initedEntityHeadIcons = true;
|
||||
|
||||
if( level.multiTeamBased )
|
||||
{
|
||||
foreach ( teamName in level.teamNameList )
|
||||
{
|
||||
str_team_headicon = "entity_headicon_" + teamName;
|
||||
game[ str_team_headicon ] = maps\mp\gametypes\_teams::MT_getTeamHeadIcon( teamName );
|
||||
precacheShader( game[ str_team_headicon ] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
game["entity_headicon_allies"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "allies" );
|
||||
game["entity_headicon_axis"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "axis" );
|
||||
|
||||
precacheShader( game["entity_headicon_allies"] );
|
||||
precacheShader( game["entity_headicon_axis"] );
|
||||
}
|
||||
}
|
||||
|
||||
// This can show to single players or to teams. Showing to a single player destroys instances of
|
||||
// the icon that are shown to their team. Showing to a team destroys instances of the icon that
|
||||
// are shown to players on that team
|
||||
setHeadIcon( showTo, icon, offset, width, height, archived, delay, constantSize, pinToScreenEdge, fadeOutPinnedIcon, is3D )
|
||||
{
|
||||
if ( IsGameParticipant( showTo ) && !IsPlayer( showTo ) )
|
||||
return; // Doesn't work for Agents, etc.
|
||||
|
||||
if ( !isDefined( self.entityHeadIcons ) )
|
||||
self.entityHeadIcons = [];
|
||||
|
||||
if( !IsDefined( archived ) )
|
||||
archived = true;
|
||||
|
||||
if( !IsDefined( delay ) )
|
||||
delay = 0.05;
|
||||
|
||||
if( !IsDefined( constantSize ) )
|
||||
constantSize = true;
|
||||
|
||||
if( !IsDefined( pinToScreenEdge ) )
|
||||
pinToScreenEdge = true;
|
||||
|
||||
if( !IsDefined( fadeOutPinnedIcon ) )
|
||||
fadeOutPinnedIcon = false;
|
||||
|
||||
if( !IsDefined( is3D ) )
|
||||
is3D = true;
|
||||
|
||||
if ( !isPlayer( showTo ) && showTo == "none" )
|
||||
{
|
||||
foreach ( key, headIcon in self.entityHeadIcons )
|
||||
{
|
||||
// TODO: remove and fix properly after ship
|
||||
if ( isDefined( headIcon ) )
|
||||
headIcon destroy();
|
||||
|
||||
self.entityHeadIcons[ key ] = undefined;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isPlayer( showTo ) )
|
||||
{
|
||||
if ( isDefined( self.entityHeadIcons[ showTo.guid ] ) )
|
||||
{
|
||||
self.entityHeadIcons[ showTo.guid ] destroy();
|
||||
self.entityHeadIcons[ showTo.guid ] = undefined;
|
||||
}
|
||||
|
||||
if ( icon == "" )
|
||||
return;
|
||||
|
||||
if ( isDefined(showTo.team) )
|
||||
{
|
||||
// remove from team or we'd have two icons
|
||||
if ( isDefined( self.entityHeadIcons[ showTo.team ] ) )
|
||||
{
|
||||
self.entityHeadIcons[ showTo.team ] destroy();
|
||||
self.entityHeadIcons[ showTo.team ] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
headIcon = newClientHudElem( showTo );
|
||||
self.entityHeadIcons[ showTo.guid ] = headIcon;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( showTo == "axis" || showTo == "allies" || isSubStr( showTo, "team_" ));
|
||||
assert( level.teamBased );
|
||||
|
||||
if ( isDefined( self.entityHeadIcons[ showTo ] ) )
|
||||
{
|
||||
self.entityHeadIcons[ showTo ] destroy();
|
||||
self.entityHeadIcons[ showTo ] = undefined;
|
||||
}
|
||||
|
||||
if ( icon == "" )
|
||||
return;
|
||||
|
||||
foreach ( key, hudIcon in self.entityHeadIcons )
|
||||
{
|
||||
if ( key == "axis" || key == "allies" )
|
||||
continue;
|
||||
|
||||
player = getPlayerForGuid( key );
|
||||
if ( player.team == showTo )
|
||||
{
|
||||
self.entityHeadIcons[ key ] destroy();
|
||||
self.entityHeadIcons[ key ] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
headIcon = newTeamHudElem( showTo );
|
||||
self.entityHeadIcons[ showTo ] = headIcon;
|
||||
}
|
||||
|
||||
if ( !isDefined( width ) || !isDefined( height ) )
|
||||
{
|
||||
width = 10;
|
||||
height = 10;
|
||||
}
|
||||
|
||||
headIcon.archived = archived;
|
||||
headIcon.x = self.origin[0] + offset[0];
|
||||
headIcon.y = self.origin[1] + offset[1];
|
||||
headIcon.z = self.origin[2] + offset[2];
|
||||
headIcon.alpha = 0.85;
|
||||
headIcon setShader( icon, width, height );
|
||||
headIcon setWaypoint( constantSize, pinToScreenEdge, fadeOutPinnedIcon, is3D );
|
||||
|
||||
headIcon thread keepPositioned( self, offset, delay );
|
||||
self thread destroyIconsOnDeath();
|
||||
if ( isPlayer( showTo ) )
|
||||
headIcon thread destroyOnOwnerDisconnect( showTo );
|
||||
if ( isPlayer( self ) )
|
||||
headIcon thread destroyOnOwnerDisconnect( self );
|
||||
|
||||
return headIcon;
|
||||
}
|
||||
|
||||
|
||||
destroyOnOwnerDisconnect( owner )
|
||||
{
|
||||
self endon ( "death" );
|
||||
|
||||
owner waittill ( "disconnect" );
|
||||
|
||||
self destroy();
|
||||
}
|
||||
|
||||
|
||||
destroyIconsOnDeath()
|
||||
{
|
||||
self notify ( "destroyIconsOnDeath" );
|
||||
self endon ( "destroyIconsOnDeath" );
|
||||
|
||||
self waittill ( "death" );
|
||||
|
||||
if ( !isDefined( self.entityHeadIcons ) )
|
||||
return;
|
||||
|
||||
foreach ( key, headIcon in self.entityHeadIcons )
|
||||
{
|
||||
// TODO: remove and fix properly after ship
|
||||
if( !isDefined(headIcon) ) //needed for FFA host migration (when host has active head icons)
|
||||
continue;
|
||||
|
||||
headIcon destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
keepPositioned( owner, offset, delay )
|
||||
{
|
||||
self endon ( "death" );
|
||||
owner endon ( "death" );
|
||||
owner endon ( "disconnect" );
|
||||
|
||||
allowCodeLink = ( IsDefined(owner.classname) && !isOwnerCarePakage(owner) );
|
||||
|
||||
if( allowCodeLink )
|
||||
{
|
||||
self LinkWaypointToTargetWithOffset( owner, offset );
|
||||
}
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if( !IsDefined( owner ) )
|
||||
return;
|
||||
|
||||
if( !allowCodeLink )
|
||||
{
|
||||
pos = owner.origin;
|
||||
|
||||
self.x = pos[0] + offset[0];
|
||||
self.y = pos[1] + offset[1];
|
||||
self.z = pos[2] + offset[2];
|
||||
}
|
||||
|
||||
if ( delay > 0.05 )
|
||||
{
|
||||
self.alpha = 0.85;
|
||||
self FadeOverTime( delay );
|
||||
self.alpha = 0;
|
||||
}
|
||||
|
||||
wait delay;
|
||||
}
|
||||
}
|
||||
|
||||
isOwnerCarePakage( owner )
|
||||
{
|
||||
return ( IsDefined(owner.targetname) && ( owner.targetname == "care_package" ) );
|
||||
}
|
||||
|
||||
setTeamHeadIcon( team, offset ) // "allies", "axis", "all", "none"
|
||||
{
|
||||
if ( !level.teamBased )
|
||||
return;
|
||||
|
||||
if ( !isDefined( self.entityHeadIconTeam ) )
|
||||
{
|
||||
self.entityHeadIconTeam = "none";
|
||||
self.entityHeadIcon = undefined;
|
||||
}
|
||||
|
||||
shader = game["entity_headicon_" + team];
|
||||
|
||||
self.entityHeadIconTeam = team;
|
||||
|
||||
if ( isDefined( offset ) )
|
||||
self.entityHeadIconOffset = offset;
|
||||
else
|
||||
self.entityHeadIconOffset = (0,0,0);
|
||||
|
||||
self notify( "kill_entity_headicon_thread" );
|
||||
|
||||
if ( team == "none" )
|
||||
{
|
||||
if ( isDefined( self.entityHeadIcon ) )
|
||||
self.entityHeadIcon destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
headIcon = newTeamHudElem( team );
|
||||
headIcon.archived = true;
|
||||
headIcon.x = self.origin[0] + self.entityHeadIconOffset[0];
|
||||
headIcon.y = self.origin[1] + self.entityHeadIconOffset[1];
|
||||
headIcon.z = self.origin[2] + self.entityHeadIconOffset[2];
|
||||
headIcon.alpha = .8;
|
||||
headIcon setShader( shader, 10, 10 );
|
||||
headIcon setWaypoint( false, false, false, true );
|
||||
self.entityHeadIcon = headIcon;
|
||||
|
||||
self thread keepIconPositioned();
|
||||
self thread destroyHeadIconsOnDeath();
|
||||
}
|
||||
|
||||
setPlayerHeadIcon( player, offset ) // "allies", "axis", "all", "none"
|
||||
{
|
||||
if ( level.teamBased )
|
||||
return;
|
||||
|
||||
if ( !isDefined( self.entityHeadIconTeam ) )
|
||||
{
|
||||
self.entityHeadIconTeam = "none";
|
||||
self.entityHeadIcon = undefined;
|
||||
}
|
||||
|
||||
self notify( "kill_entity_headicon_thread" );
|
||||
|
||||
if ( !isDefined( player ) )
|
||||
{
|
||||
if ( isDefined( self.entityHeadIcon ) )
|
||||
self.entityHeadIcon destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
team = player.team;
|
||||
self.entityHeadIconTeam = team;
|
||||
|
||||
if ( isDefined( offset ) )
|
||||
self.entityHeadIconOffset = offset;
|
||||
else
|
||||
self.entityHeadIconOffset = (0,0,0);
|
||||
|
||||
shader = game["entity_headicon_" + team];
|
||||
|
||||
headIcon = newClientHudElem( player );
|
||||
headIcon.archived = true;
|
||||
headIcon.x = self.origin[0] + self.entityHeadIconOffset[0];
|
||||
headIcon.y = self.origin[1] + self.entityHeadIconOffset[1];
|
||||
headIcon.z = self.origin[2] + self.entityHeadIconOffset[2];
|
||||
headIcon.alpha = .8;
|
||||
headIcon setShader( shader, 10, 10 );
|
||||
headIcon setWaypoint( false, false, false, true );
|
||||
self.entityHeadIcon = headIcon;
|
||||
|
||||
self thread keepIconPositioned();
|
||||
self thread destroyHeadIconsOnDeath();
|
||||
}
|
||||
|
||||
keepIconPositioned()
|
||||
{
|
||||
self.entityHeadIcon LinkWaypointToTargetWithOffset( self, self.entityHeadIconOffset );
|
||||
}
|
||||
|
||||
destroyHeadIconsOnDeath()
|
||||
{
|
||||
self endon( "kill_entity_headicon_thread" );
|
||||
self waittill ( "death" );
|
||||
|
||||
// TODO: remove and fix properly after ship
|
||||
if( !isDefined(self.entityHeadIcon) )
|
||||
return;
|
||||
|
||||
self.entityHeadIcon destroy();
|
||||
}
|
||||
|
||||
|
984
maps/mp/_events.gsc
Normal file
984
maps/mp/_events.gsc
Normal file
@ -0,0 +1,984 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
// load all of the scoring data for the current game mode
|
||||
game_type_col = [];
|
||||
game_type_col[ "dm" ] = 3; // free for all
|
||||
game_type_col[ "war" ] = 4; // team deathmatch
|
||||
game_type_col[ "sd" ] = 5; // search and destroy
|
||||
game_type_col[ "dom" ] = 6; // domination
|
||||
game_type_col[ "conf" ] = 7; // kill confirmed
|
||||
game_type_col[ "sr" ] = 8; // search and rescue
|
||||
game_type_col[ "bnty" ] = 9; // bounty
|
||||
game_type_col[ "grind" ] = 10; // grind
|
||||
game_type_col[ "blitz" ] = 11; // blitz
|
||||
game_type_col[ "cranked" ] = 12; // cranked
|
||||
game_type_col[ "infect" ] = 13; // infected
|
||||
game_type_col[ "sotf" ] = 14; // survival of the fittest
|
||||
game_type_col[ "sotf_ffa" ] = 15; // survival of the fittest FFA
|
||||
game_type_col[ "horde" ] = 16; // horde
|
||||
game_type_col[ "mugger" ] = 17; // mugger
|
||||
game_type_col[ "aliens" ] = 18; // aliens
|
||||
game_type_col[ "gun" ] = 19; // gun game
|
||||
game_type_col[ "grnd" ] = 20; // drop zone
|
||||
game_type_col[ "siege" ] = 21; // reinforce
|
||||
|
||||
game_type = level.gameType;
|
||||
if( !IsDefined( game_type ) )
|
||||
game_type = GetDvar( "g_gametype" );
|
||||
|
||||
row = 0;
|
||||
while( true )
|
||||
{
|
||||
value = TableLookupByRow( "mp/xp_event_table.csv", row, game_type_col[ game_type ] );
|
||||
if( !IsDefined( value ) || value == "" )
|
||||
break;
|
||||
|
||||
ref = TableLookupByRow( "mp/xp_event_table.csv", row, 0 );
|
||||
|
||||
if( ref == "win" || ref == "loss" || ref == "tie" )
|
||||
value = float( value );
|
||||
else
|
||||
value = int( value );
|
||||
|
||||
if( value != -1 )
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( ref, value );
|
||||
|
||||
row++;
|
||||
}
|
||||
// end scoring data
|
||||
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "damage", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "heavy_damage", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "damaged", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "kill", 1 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "killed", 0 );
|
||||
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "healed", 0);
|
||||
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "headshot", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "melee", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "backstab", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "longshot", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "pointblank", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "assistedsuicide", 0);
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "defender", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "avenger", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "execution", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "comeback", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "revenge", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "buzzkill", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "double", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "triple", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "multi", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "assist", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "firstBlood", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "capture", 1 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "assistedCapture", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "plant", 1 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "defuse", 1 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "vehicleDestroyed", 1);
|
||||
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "3streak", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "4streak", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "5streak", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "6streak", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "7streak", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "8streak", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "9streak", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "10streak", 0 );
|
||||
maps\mp\killstreaks\_killstreaks::registerAdrenalineInfo( "regen", 0 );
|
||||
|
||||
precacheShader( "crosshair_red" );
|
||||
|
||||
level._effect["money"] = loadfx ("fx/props/cash_player_drop");
|
||||
|
||||
level.numKills = 0;
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player.killedPlayers = [];
|
||||
player.killedPlayersCurrent = [];
|
||||
player.ch_extremeCrueltyComplete = false; // setting a player var to throttle challenge completion rate
|
||||
player.ch_tangoDownComplete = false; // for iw7 we should handle this in the challenge table
|
||||
player.killedBy = [];
|
||||
player.lastKilledBy = undefined;
|
||||
player.greatestUniquePlayerKills = 0;
|
||||
|
||||
player.recentKillCount = 0;
|
||||
player.lastKillTime = 0;
|
||||
player.lastKillDogTime = 0;
|
||||
player.damagedPlayers = [];
|
||||
|
||||
player thread monitorCrateJacking();
|
||||
player thread monitorObjectives();
|
||||
player thread monitorHealed();
|
||||
}
|
||||
}
|
||||
|
||||
damagedPlayer( victim, damage, weapon )
|
||||
{
|
||||
if ( damage < 50 && damage > 10 )
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "damage" );
|
||||
else
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "heavy_damage" );
|
||||
}
|
||||
|
||||
//notifies killed player over necessary frames
|
||||
killedPlayerNotifySys( killId, victim, weapon, meansOfDeath )
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
self notify ( "killedPlayerNotify" );
|
||||
self endon ( "killedPlayerNotify" );
|
||||
|
||||
if( !isDefined( self.killsInAFrameCount ) )
|
||||
self.killsInAFrameCount = 0;
|
||||
|
||||
self.killsInAFrameCount++;
|
||||
|
||||
wait ( 0.05 );
|
||||
|
||||
if ( self.killsInAFrameCount > 1 )
|
||||
self thread notifyKilledPlayer( killId, victim, weapon, meansOfDeath, self.killsInAFrameCount );
|
||||
else
|
||||
self notify( "got_a_kill", victim, weapon, meansOfDeath );
|
||||
|
||||
self.killsInAFrameCount = 0;
|
||||
}
|
||||
|
||||
//possible loss of proper killID etc here. Using last killed properties
|
||||
notifyKilledPlayer( killId, victim, weapon, meansOfDeath, numKills )
|
||||
{
|
||||
for( i = 0; i < numKills; i++ )
|
||||
{
|
||||
//used by intel
|
||||
self notify( "got_a_kill", victim, weapon, meansOfDeath );
|
||||
wait ( 0.05 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
killedPlayer( killId, victim, weapon, meansOfDeath )
|
||||
{
|
||||
victimGuid = victim.guid;
|
||||
myGuid = self.guid;
|
||||
curTime = getTime();
|
||||
|
||||
self thread killedPlayerNotifySys( killId, victim, weapon, meansOfDeath );
|
||||
self thread updateRecentKills( killId );
|
||||
self.lastKillTime = getTime();
|
||||
self.lastKilledPlayer = victim;
|
||||
|
||||
self.modifiers = [];
|
||||
|
||||
level.numKills++;
|
||||
|
||||
// a player is either damaged, or killed; never both
|
||||
self.damagedPlayers[victimGuid] = undefined;
|
||||
|
||||
if ( !isKillstreakWeapon( weapon ) && !self isJuggernaut() && !self _hasPerk( "specialty_explosivebullets" ) )
|
||||
{
|
||||
if ( weapon == "none" )
|
||||
return false;
|
||||
|
||||
// added a failsafe here because this could be the victim killing themselves with something like the dead man's hand deathstreak
|
||||
if ( victim.attackers.size == 1 && !IsDefined( victim.attackers[victim.guid] ) )
|
||||
{
|
||||
/#
|
||||
if ( !isDefined( victim.attackers[self.guid] ) )
|
||||
{
|
||||
println("Weapon: " + weapon );
|
||||
println("meansOfDeath: " + meansOfDeath );
|
||||
println("Attacker GUID: " + self.guid + " (name: " + self.name + ")" );
|
||||
|
||||
i = 0;
|
||||
foreach ( key,value in victim.attackers )
|
||||
{
|
||||
println( "victim.attackers " + i + " GUID: " + key + " (name: " + value.name + ")" );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#/
|
||||
assertEx( isDefined( victim.attackers[self.guid] ), "See console log for details" );
|
||||
|
||||
weaponClass = getWeaponClass( weapon );
|
||||
|
||||
if( weaponClass == "weapon_sniper" &&
|
||||
meansOfDeath != "MOD_MELEE" &&
|
||||
getTime() == victim.attackerData[self.guid].firstTimeDamaged )
|
||||
{
|
||||
self.modifiers["oneshotkill"] = true;
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "one_shot_kill" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isDefined( victim.throwingGrenade ) && victim.throwingGrenade == "frag_grenade_mp" )
|
||||
self.modifiers["cooking"] = true;
|
||||
|
||||
if ( isDefined(self.assistedSuicide) && self.assistedSuicide )
|
||||
self assistedSuicide( killId, weapon, meansOfDeath );
|
||||
|
||||
if ( level.numKills == 1 )
|
||||
self firstBlood( killId, weapon, meansOfDeath );
|
||||
|
||||
if ( self.pers["cur_death_streak"] > 3 )
|
||||
self comeBack( killId, weapon, meansOfDeath );
|
||||
|
||||
if ( meansOfDeath == "MOD_HEAD_SHOT" )
|
||||
{
|
||||
if ( isDefined( victim.lastStand ) )
|
||||
execution( killId, weapon, meansOfDeath );
|
||||
else
|
||||
headShot( killId, weapon, meansOfDeath );
|
||||
}
|
||||
|
||||
if ( isDefined(self.wasti) && self.wasti && getTime() - self.spawnTime <= 5000 )
|
||||
self.modifiers["jackintheboxkill"] = true;
|
||||
|
||||
if ( !isAlive( self ) && self.deathtime + 800 < getTime() )
|
||||
postDeathKill( killId );
|
||||
|
||||
if ( level.teamBased && curTime - victim.lastKillTime < 500 )
|
||||
{
|
||||
if ( victim.lastkilledplayer != self )
|
||||
self avengedPlayer( killId, weapon, meansOfDeath );
|
||||
}
|
||||
|
||||
if ( IsDefined( victim.lastKillDogTime ) && curTime - victim.lastKillDogTime < 2000 )
|
||||
{
|
||||
self avengedDog( killId, weapon, meansOfDeath );
|
||||
}
|
||||
|
||||
foreach ( guid, damageTime in victim.damagedPlayers )
|
||||
{
|
||||
if ( guid == self.guid )
|
||||
continue;
|
||||
|
||||
if ( level.teamBased && curTime - damageTime < 500 )
|
||||
self defendedPlayer( killId, weapon, meansOfDeath );
|
||||
}
|
||||
|
||||
if ( isDefined( victim.attackerPosition ) )
|
||||
attackerPosition = victim.attackerPosition;
|
||||
else
|
||||
attackerPosition = self.origin;
|
||||
|
||||
if ( isPointBlank ( self, weapon, meansOfDeath, attackerPosition, victim ) )
|
||||
self thread pointblank( killId, weapon, meansOfDeath );
|
||||
else if( isLongShot( self, weapon, meansOfDeath, attackerPosition, victim ) )
|
||||
self thread longshot( killId, weapon, meansOfDeath );
|
||||
|
||||
victim_pers_cur_kill_streak = victim.pers[ "cur_kill_streak" ];
|
||||
if ( victim_pers_cur_kill_streak > 0 && isDefined( victim.killstreaks[ victim_pers_cur_kill_streak + 1 ] ) )
|
||||
{
|
||||
// playercard splash for the killstreak stopped
|
||||
self buzzKill( killId, victim, weapon, meansOfDeath );
|
||||
}
|
||||
|
||||
self thread checkMatchDataKills( killId, victim, weapon, meansOfDeath);
|
||||
|
||||
}
|
||||
else if( weapon == "guard_dog_mp" )
|
||||
{
|
||||
if( !isAlive( self ) && self.deathtime < GetTime() )
|
||||
postDeathDogKill();
|
||||
}
|
||||
|
||||
if ( !isDefined( self.killedPlayers[victimGuid] ) )
|
||||
self.killedPlayers[victimGuid] = 0;
|
||||
|
||||
if ( !isDefined( self.killedPlayersCurrent[victimGuid] ) )
|
||||
self.killedPlayersCurrent[victimGuid] = 0;
|
||||
|
||||
if ( !isDefined( victim.killedBy[myGuid] ) )
|
||||
victim.killedBy[myGuid] = 0;
|
||||
|
||||
self.killedPlayers[victimGuid]++;
|
||||
|
||||
//this sets player stat for routine customer award
|
||||
if ( self.killedPlayers[victimGuid] > self.greatestUniquePlayerKills )
|
||||
self setPlayerStat( "killedsameplayer", self.killedPlayers[victimGuid] );
|
||||
|
||||
self.killedPlayersCurrent[victimGuid]++;
|
||||
victim.killedBy[myGuid]++;
|
||||
|
||||
victim.lastKilledBy = self;
|
||||
}
|
||||
|
||||
isLongShot( attacker, weapon, meansOfDeath, attackerPosition, victim )
|
||||
{
|
||||
if( isAlive( attacker ) &&
|
||||
!attacker isUsingRemote() &&
|
||||
( meansOfDeath == "MOD_RIFLE_BULLET" || meansOfDeath == "MOD_PISTOL_BULLET" || meansOfDeath == "MOD_HEAD_SHOT" ) &&
|
||||
!isKillstreakWeapon( weapon ) && !isDefined( attacker.assistedSuicide ) )
|
||||
{
|
||||
// check depending on the weapon being used to kill
|
||||
thisWeaponClass = getWeaponClass( weapon );
|
||||
switch( thisWeaponClass )
|
||||
{
|
||||
case "weapon_pistol":
|
||||
weapDist = 800;
|
||||
break;
|
||||
case "weapon_smg":
|
||||
weapDist = 1200;
|
||||
break;
|
||||
case "weapon_dmr":
|
||||
case "weapon_assault":
|
||||
case "weapon_lmg":
|
||||
weapDist = 1500;
|
||||
break;
|
||||
case "weapon_sniper":
|
||||
weapDist = 2000;
|
||||
break;
|
||||
case "weapon_shotgun":
|
||||
weapDist = 500;
|
||||
break;
|
||||
case "weapon_projectile":
|
||||
default:
|
||||
weapDist = 1536; // the old number
|
||||
break;
|
||||
}
|
||||
|
||||
weapDistSq = weapDist * weapDist;
|
||||
if( DistanceSquared( attackerPosition, victim.origin ) > weapDistSq )
|
||||
{
|
||||
if( attacker IsItemUnlocked( "specialty_holdbreath" ) && attacker _hasPerk( "specialty_holdbreath" ) )
|
||||
attacker maps\mp\gametypes\_missions::processChallenge( "ch_longdistance" );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
isPointBlank( attacker, weapon, meansOfDeath, attackerPosition, victim )
|
||||
{
|
||||
if( isAlive( attacker ) &&
|
||||
!attacker isUsingRemote() &&
|
||||
( meansOfDeath == "MOD_RIFLE_BULLET" || meansOfDeath == "MOD_PISTOL_BULLET" || meansOfDeath == "MOD_HEAD_SHOT" ) &&
|
||||
!isKillstreakWeapon( weapon ) && !isDefined( attacker.assistedSuicide ) )
|
||||
{
|
||||
// point blank is the same for all classes of weapons, about 8'
|
||||
weapDistSq = 96 * 96;
|
||||
if( DistanceSquared( attackerPosition, victim.origin ) < weapDistSq )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
checkMatchDataKills( killId, victim, weapon, meansOfDeath )
|
||||
{
|
||||
weaponClass = getWeaponClass( weapon );
|
||||
alreadyUsed = false;
|
||||
|
||||
self thread camperCheck();
|
||||
|
||||
if ( isDefined( self.lastKilledBy ) && self.lastKilledBy == victim )
|
||||
{
|
||||
self.lastKilledBy = undefined;
|
||||
self revenge( killId );
|
||||
}
|
||||
|
||||
if ( victim.iDFlags & level.iDFLAGS_PENETRATION )
|
||||
self incPlayerStat( "bulletpenkills", 1 );
|
||||
|
||||
self_pers_rank = self.pers["rank"];
|
||||
victim_pers_rank = victim.pers["rank"];
|
||||
if ( self_pers_rank < victim_pers_rank )
|
||||
self incPlayerStat( "higherrankkills", 1 );
|
||||
|
||||
if ( self_pers_rank > victim_pers_rank )
|
||||
self incPlayerStat( "lowerrankkills", 1 );
|
||||
|
||||
if ( isDefined( self.inFinalStand ) && self.inFinalStand )
|
||||
self incPlayerStat( "laststandkills", 1 );
|
||||
|
||||
if ( isDefined( victim.inFinalStand ) && victim.inFinalStand )
|
||||
self incPlayerStat( "laststanderkills", 1 );
|
||||
|
||||
if ( self getCurrentWeapon() != self.primaryWeapon && self getCurrentWeapon() != self.secondaryWeapon )
|
||||
self incPlayerStat( "otherweaponkills", 1 );
|
||||
|
||||
timeAlive = getTime() - victim.spawnTime ;
|
||||
|
||||
if( !matchMakingGame() )
|
||||
victim setPlayerStatIfLower( "shortestlife", timeAlive );
|
||||
|
||||
victim setPlayerStatIfGreater( "longestlife", timeAlive );
|
||||
|
||||
if( meansOfDeath != "MOD_MELEE" )
|
||||
{
|
||||
switch( weaponClass )
|
||||
{
|
||||
case "weapon_pistol":
|
||||
case "weapon_smg":
|
||||
case "weapon_assault":
|
||||
case "weapon_projectile":
|
||||
case "weapon_dmr":
|
||||
case "weapon_sniper":
|
||||
case "weapon_shotgun":
|
||||
case "weapon_lmg":
|
||||
self checkMatchDataWeaponKills( victim, weapon, meansOfDeath, weaponClass );
|
||||
break;
|
||||
case "weapon_grenade":
|
||||
case "weapon_explosive":
|
||||
self checkMatchDataEquipmentKills( victim, weapon, meansOfDeath );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need to make sure these only apply to kills of an enemy, not friendlies or yourself
|
||||
checkMatchDataWeaponKills( victim, weapon, meansOfDeath, weaponType )
|
||||
{
|
||||
attacker = self;
|
||||
kill_ref = undefined;
|
||||
headshot_ref = undefined;
|
||||
death_ref = undefined;
|
||||
|
||||
switch( weaponType )
|
||||
{
|
||||
case "weapon_pistol":
|
||||
kill_ref = "pistolkills";
|
||||
headshot_ref = "pistolheadshots";
|
||||
break;
|
||||
case "weapon_smg":
|
||||
kill_ref = "smgkills";
|
||||
headshot_ref = "smgheadshots";
|
||||
break;
|
||||
case "weapon_assault":
|
||||
kill_ref = "arkills";
|
||||
headshot_ref = "arheadshots";
|
||||
break;
|
||||
case "weapon_projectile":
|
||||
if ( weaponClass( weapon ) == "rocketlauncher" )
|
||||
kill_ref = "rocketkills";
|
||||
break;
|
||||
case "weapon_dmr":
|
||||
kill_ref = "dmrkills";
|
||||
headshot_ref = "dmrheadshots";
|
||||
break;
|
||||
case "weapon_sniper":
|
||||
kill_ref = "sniperkills";
|
||||
headshot_ref = "sniperheadshots";
|
||||
break;
|
||||
case "weapon_shotgun":
|
||||
kill_ref = "shotgunkills";
|
||||
headshot_ref = "shotgunheadshots";
|
||||
death_ref = "shotgundeaths";
|
||||
break;
|
||||
case "weapon_lmg":
|
||||
kill_ref = "lmgkills";
|
||||
headshot_ref = "lmgheadshots";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isDefined ( kill_ref ) )
|
||||
attacker incPlayerStat( kill_ref, 1 );
|
||||
|
||||
if ( isDefined ( headshot_ref ) && meansOfDeath == "MOD_HEAD_SHOT" )
|
||||
attacker incPlayerStat( headshot_ref, 1 );
|
||||
|
||||
if ( isDefined ( death_ref ) && !matchMakingGame() )
|
||||
victim incPlayerStat( death_ref, 1 );
|
||||
|
||||
if ( attacker isPlayerAds() )
|
||||
{
|
||||
attacker incPlayerStat( "adskills", 1 );
|
||||
|
||||
isThermal = IsSubStr( weapon, "thermal" );
|
||||
|
||||
// If weapon sniper, or acog or scope. Scope covers weapon_dmr with default scope
|
||||
if ( isThermal || IsSubStr( weapon, "acog" ) || IsSubStr( weapon, "scope" ) )
|
||||
attacker incPlayerStat( "scopedkills", 1 );
|
||||
|
||||
if ( isThermal )
|
||||
attacker incPlayerStat( "thermalkills", 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
attacker incPlayerStat( "hipfirekills", 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// Need to make sure these only apply to kills of an enemy, not friendlies or yourself
|
||||
checkMatchDataEquipmentKills( victim, weapon, meansOfDeath )
|
||||
{
|
||||
attacker = self;
|
||||
|
||||
// equipment kills
|
||||
switch( weapon )
|
||||
{
|
||||
case "frag_grenade_mp":
|
||||
attacker incPlayerStat( "fragkills", 1 );
|
||||
attacker incPlayerStat( "grenadekills", 1 );
|
||||
isEquipment = true;
|
||||
break;
|
||||
case "c4_mp":
|
||||
attacker incPlayerStat( "c4kills", 1 );
|
||||
isEquipment = true;
|
||||
break;
|
||||
case "semtex_mp":
|
||||
attacker incPlayerStat( "semtexkills", 1 );
|
||||
attacker incPlayerStat( "grenadekills", 1 );
|
||||
isEquipment = true;
|
||||
break;
|
||||
case "claymore_mp":
|
||||
attacker incPlayerStat( "claymorekills", 1 );
|
||||
isEquipment = true;
|
||||
break;
|
||||
case "throwingknife_mp":
|
||||
attacker incPlayerStat( "throwingknifekills", 1 );
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "knifethrow" );
|
||||
isEquipment = true;
|
||||
break;
|
||||
default:
|
||||
isEquipment = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isEquipment )
|
||||
attacker incPlayerStat( "equipmentkills", 1 );
|
||||
}
|
||||
|
||||
camperCheck()
|
||||
{
|
||||
self.lastKillWasCamping = false;
|
||||
if ( !isDefined ( self.lastKillLocation ) )
|
||||
{
|
||||
self.lastKillLocation = self.origin;
|
||||
self.lastCampKillTime = getTime();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Distance( self.lastKillLocation, self.origin ) < 512 && getTime() - self.lastCampKillTime > 5000 )
|
||||
{
|
||||
self incPlayerStat( "mostcamperkills", 1 );
|
||||
self.lastKillWasCamping = true;
|
||||
}
|
||||
|
||||
self.lastKillLocation = self.origin;
|
||||
self.lastCampKillTime = getTime();
|
||||
}
|
||||
|
||||
consolation( killId )
|
||||
{
|
||||
/*
|
||||
value = int( maps\mp\gametypes\_rank::getScoreInfoValue( "kill" ) * 0.25 );
|
||||
|
||||
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "consolation", value );
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "consolation", value );
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
proximityAssist( killId )
|
||||
{
|
||||
self.modifiers["proximityAssist"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "proximityassist" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "proximityassist" );
|
||||
//self thread maps\mp\_matchdata::logKillEvent( killId, "proximityAssist" );
|
||||
}
|
||||
|
||||
|
||||
proximityKill( killId )
|
||||
{
|
||||
self.modifiers["proximityKill"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "proximitykill" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "proximitykill" );
|
||||
//self thread maps\mp\_matchdata::logKillEvent( killId, "proximityKill" );
|
||||
}
|
||||
|
||||
|
||||
longshot( killId, weapon, meansOfDeath )
|
||||
{
|
||||
self.modifiers["longshot"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "longshot" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "longshot", undefined, weapon, meansOfDeath );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "longshot" );
|
||||
self incPlayerStat( "longshots", 1 );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "longshot" );
|
||||
}
|
||||
|
||||
pointblank( killId, weapon, meansOfDeath )
|
||||
{
|
||||
self.modifiers["pointblank"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "pointblank" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "pointblank", undefined, weapon, meansOfDeath );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "pointblank" );
|
||||
// self incPlayerStat( "pointblank", 1 );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "pointblank" );
|
||||
}
|
||||
|
||||
|
||||
execution( killId, weapon, meansOfDeath )
|
||||
{
|
||||
self.modifiers["execution"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "execution" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "execution", undefined, weapon, meansOfDeath );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "execution" );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "execution" );
|
||||
}
|
||||
|
||||
|
||||
headShot( killId, weapon, meansOfDeath )
|
||||
{
|
||||
self.modifiers["headshot"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "headshot" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "headshot", undefined, weapon, meansOfDeath );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "headshot" );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "headshot" );
|
||||
}
|
||||
|
||||
|
||||
avengedPlayer( killId, weapon, meansOfDeath )
|
||||
{
|
||||
self.modifiers["avenger"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "avenger" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "avenger", undefined, weapon, meansOfDeath );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "avenger" );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "avenger" );
|
||||
|
||||
self incPlayerStat( "avengekills", 1 );
|
||||
}
|
||||
|
||||
avengedDog( killId, weapon, meansOfDeath )
|
||||
{
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "dog_avenger" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "dog_avenger", undefined, weapon, meansOfDeath );
|
||||
}
|
||||
|
||||
assistedSuicide( killId, weapon, meansOfDeath )
|
||||
{
|
||||
self.modifiers["assistedsuicide"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "assistedsuicide" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "assistedsuicide", undefined, weapon, meansOfDeath );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "assistedsuicide" );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "assistedsuicide" );
|
||||
}
|
||||
|
||||
defendedPlayer( killId, weapon, meansOfDeath )
|
||||
{
|
||||
self.modifiers["defender"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "defender" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "defender", undefined, weapon, meansOfDeath );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "defender" );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "defender" );
|
||||
|
||||
self incPlayerStat( "rescues", 1 );
|
||||
}
|
||||
|
||||
|
||||
postDeathKill( killId )
|
||||
{
|
||||
self.modifiers[ "posthumous" ] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "posthumous" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "posthumous" );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "posthumous" );
|
||||
}
|
||||
|
||||
postDeathDogKill()
|
||||
{
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "martyrdog" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "martyrdog" );
|
||||
}
|
||||
|
||||
backStab( killId )
|
||||
{
|
||||
self iPrintLnBold( "backstab" );
|
||||
}
|
||||
|
||||
|
||||
revenge( killId )
|
||||
{
|
||||
self.modifiers["revenge"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "revenge" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "revenge" );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "revenge" );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "revenge" );
|
||||
|
||||
self incPlayerStat( "revengekills", 1 );
|
||||
}
|
||||
|
||||
|
||||
multiKill( killId, killCount )
|
||||
{
|
||||
assert( killCount > 1 );
|
||||
|
||||
if ( killCount == 2 )
|
||||
{
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "double" );
|
||||
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "double" );
|
||||
}
|
||||
else if ( killCount == 3 )
|
||||
{
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "triple" );
|
||||
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "triple" );
|
||||
thread teamPlayerCardSplash( "callout_3xkill", self );
|
||||
}
|
||||
else
|
||||
{
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "multi" );
|
||||
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "multi" );
|
||||
thread teamPlayerCardSplash( "callout_3xpluskill", self );
|
||||
}
|
||||
|
||||
self thread maps\mp\_matchdata::logMultiKill( killId, killCount );
|
||||
|
||||
// update player multikill record
|
||||
self setPlayerStatIfGreater( "multikill", killCount );
|
||||
|
||||
// update player multikill count
|
||||
self incPlayerStat( "mostmultikills", 1 );
|
||||
}
|
||||
|
||||
|
||||
firstBlood( killId, weapon, meansOfDeath )
|
||||
{
|
||||
self.modifiers["firstblood"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "firstblood" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "firstblood", undefined, weapon, meansOfDeath );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "firstblood" );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "firstBlood" );
|
||||
|
||||
thread teamPlayerCardSplash( "callout_firstblood", self );
|
||||
|
||||
self maps\mp\gametypes\_missions::processChallenge( "ch_bornready" );
|
||||
}
|
||||
|
||||
|
||||
winningShot( killId )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
buzzKill( killId, victim, weapon, meansOfDeath )
|
||||
{
|
||||
self.modifiers["buzzkill"] = victim.pers["cur_kill_streak"];
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "buzzkill" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "buzzkill", undefined, weapon, meansOfDeath );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "buzzkill" );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "buzzkill" );
|
||||
}
|
||||
|
||||
|
||||
comeBack( killId, weapon, meansOfDeath )
|
||||
{
|
||||
self.modifiers["comeback"] = true;
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "comeback" );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "comeback", undefined, weapon, meansOfDeath );
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "comeback" );
|
||||
self thread maps\mp\_matchdata::logKillEvent( killId, "comeback" );
|
||||
|
||||
self incPlayerStat( "comebacks", 1 );
|
||||
}
|
||||
|
||||
|
||||
disconnected()
|
||||
{
|
||||
myGuid = self.guid;
|
||||
|
||||
for ( entry = 0; entry < level.players.size; entry++ )
|
||||
{
|
||||
if ( isDefined( level.players[entry].killedPlayers[myGuid] ) )
|
||||
level.players[entry].killedPlayers[myGuid] = undefined;
|
||||
|
||||
if ( isDefined( level.players[entry].killedPlayersCurrent[myGuid] ) )
|
||||
level.players[entry].killedPlayersCurrent[myGuid] = undefined;
|
||||
|
||||
if ( isDefined( level.players[entry].killedBy[myGuid] ) )
|
||||
level.players[entry].killedBy[myGuid] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
monitorHealed()
|
||||
{
|
||||
level endon( "end_game" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "healed");
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "healed" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateRecentKills( killId )
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
self notify ( "updateRecentKills" );
|
||||
self endon ( "updateRecentKills" );
|
||||
|
||||
self.recentKillCount++;
|
||||
|
||||
wait ( 1.0 );
|
||||
|
||||
if ( self.recentKillCount > 1 )
|
||||
self multiKill( killId, self.recentKillCount );
|
||||
|
||||
self.recentKillCount = 0;
|
||||
}
|
||||
|
||||
monitorCrateJacking()
|
||||
{
|
||||
level endon( "end_game" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
self waittill( "hijacker", crateType, owner );
|
||||
|
||||
self thread maps\mp\gametypes\_rank::xpEventPopup( "hijacker" );
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "hijacker" );
|
||||
|
||||
splashName = "hijacked_airdrop";
|
||||
challengeName = "ch_hijacker";
|
||||
|
||||
switch( crateType )
|
||||
{
|
||||
case "sentry":
|
||||
splashName = "hijacked_sentry";
|
||||
break;
|
||||
case "juggernaut":
|
||||
splashName = "hijacked_juggernaut";
|
||||
break;
|
||||
case "maniac":
|
||||
splashname = "hijacked_maniac";
|
||||
break;
|
||||
case "juggernaut_swamp_slasher":
|
||||
splashname = "hijacked_juggernaut_swamp_slasher";
|
||||
break;
|
||||
case "juggernaut_predator":
|
||||
splashname = "hijacked_juggernaut_predator";
|
||||
break;
|
||||
case "juggernaut_death_mariachi":
|
||||
splashname = "hijacked_juggernaut_death_mariachi";
|
||||
break;
|
||||
case "remote_tank":
|
||||
splashName = "hijacked_remote_tank";
|
||||
break;
|
||||
case "mega":
|
||||
case "emergency_airdrop":
|
||||
splashName = "hijacked_emergency_airdrop";
|
||||
challengeName = "ch_newjack";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( IsDefined( owner ) )
|
||||
owner maps\mp\gametypes\_hud_message::playerCardSplashNotify( splashName, self );
|
||||
self notify( "process", challengeName );
|
||||
}
|
||||
}
|
||||
|
||||
monitorObjectives()
|
||||
{
|
||||
level endon( "end_game" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "objective", objType );
|
||||
|
||||
switch( objType )
|
||||
{
|
||||
case "captured":
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "capture" );
|
||||
if ( isDefined( self.lastStand ) && self.lastStand )
|
||||
{
|
||||
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "heroic", maps\mp\gametypes\_rank::getScoreInfoValue( "reviver" ) );
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( "reviver" );
|
||||
}
|
||||
break;
|
||||
case "plant":
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "plant" );
|
||||
break;
|
||||
case "defuse":
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "defuse" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this gets called directly from the game mode gscs instead of leaning on the above notify system
|
||||
giveObjectivePointStreaks()
|
||||
{
|
||||
halfTick_activate = true; // turn this to true in ffotd / patch to activate the objective point system
|
||||
if ( halfTick_activate )
|
||||
{
|
||||
// DM - 5/2/14 - make sure this isn't getting applied to squadmates
|
||||
if( !IsAgent( self ) )
|
||||
{
|
||||
self.pers["objectivePointStreak"]++;
|
||||
// for every two objective points earned, give 1 killstreak tick
|
||||
should_give_point = ( self.pers["objectivePointStreak"] % 2 == 0 );
|
||||
|
||||
if ( should_give_point )
|
||||
{
|
||||
self maps\mp\killstreaks\_killstreaks::giveAdrenaline( "kill" );
|
||||
}
|
||||
// if this results false, set a half killstreak tick in lua
|
||||
// NOTE: this gets overridden in KillstreakHud.lua if the player is using specialist and is maxed to avoid showing the half tick
|
||||
self SetClientOmnvar( "ui_half_tick", !should_give_point );
|
||||
}
|
||||
}
|
||||
}
|
176
maps/mp/_flashgrenades.gsc
Normal file
176
maps/mp/_flashgrenades.gsc
Normal file
@ -0,0 +1,176 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
main()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
startMonitoringFlash()
|
||||
{
|
||||
self thread monitorFlash();
|
||||
}
|
||||
|
||||
|
||||
stopMonitoringFlash(disconnected)
|
||||
{
|
||||
self notify("stop_monitoring_flash");
|
||||
}
|
||||
|
||||
|
||||
flashRumbleLoop( duration )
|
||||
{
|
||||
self endon("stop_monitoring_flash");
|
||||
|
||||
self endon("flash_rumble_loop");
|
||||
self notify("flash_rumble_loop");
|
||||
|
||||
goalTime = getTime() + duration * 1000;
|
||||
|
||||
while ( getTime() < goalTime )
|
||||
{
|
||||
self PlayRumbleOnEntity( "damage_heavy" );
|
||||
wait( 0.05 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
monitorFlash()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
self notify("monitorFlash");
|
||||
self endon("monitorFlash");
|
||||
|
||||
self.flashEndTime = 0;
|
||||
|
||||
durationMultiplier = 1; // how long the flash lasts
|
||||
|
||||
while(1)
|
||||
{
|
||||
self waittill( "flashbang", origin, percent_distance, percent_angle, attacker, teamName, extraDuration );
|
||||
|
||||
if ( !IsAlive( self ) )
|
||||
break;
|
||||
|
||||
if ( IsDefined( self.usingRemote ) )
|
||||
continue;
|
||||
|
||||
// an agent killstreak should not be flashed by its owner
|
||||
if( IsDefined(self.owner) && IsDefined(attacker) && (attacker == self.owner) )
|
||||
continue;
|
||||
|
||||
if( !IsDefined( extraDuration ) )
|
||||
extraDuration = 0;
|
||||
|
||||
hurtattacker = false;
|
||||
hurtvictim = true;
|
||||
|
||||
// with this being the 9-bang we shouldn't consider angle as a variable because of the multiple blasts
|
||||
//if ( percent_angle < 0.25 )
|
||||
// percent_angle = 0.25;
|
||||
//else if ( percent_angle > 0.8 )
|
||||
percent_angle = 1;
|
||||
|
||||
duration = percent_distance * percent_angle * durationMultiplier;
|
||||
duration += extraDuration;
|
||||
|
||||
// MW3 stun resistance perk
|
||||
duration = maps\mp\perks\_perkfunctions::applyStunResistence( duration );
|
||||
|
||||
if ( duration < 0.25 )
|
||||
continue;
|
||||
|
||||
rumbleduration = undefined;
|
||||
if ( duration > 2 )
|
||||
rumbleduration = 0.75;
|
||||
else
|
||||
rumbleduration = 0.25;
|
||||
|
||||
assert(IsDefined(self.team));
|
||||
if (level.teamBased && IsDefined(attacker) && IsDefined(attacker.team) && attacker.team == self.team && attacker != self)
|
||||
{
|
||||
if(level.friendlyfire == 0) // no FF
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if(level.friendlyfire == 1) // FF
|
||||
{
|
||||
}
|
||||
else if(level.friendlyfire == 2) // reflect
|
||||
{
|
||||
duration = duration * .5;
|
||||
rumbleduration = rumbleduration * .5;
|
||||
hurtvictim = false;
|
||||
hurtattacker = true;
|
||||
}
|
||||
else if(level.friendlyfire == 3) // share
|
||||
{
|
||||
duration = duration * .5;
|
||||
rumbleduration = rumbleduration * .5;
|
||||
hurtattacker = true;
|
||||
}
|
||||
}
|
||||
else if( IsDefined(attacker) )
|
||||
{
|
||||
attacker notify( "flash_hit" );
|
||||
if( attacker != self )
|
||||
attacker maps\mp\gametypes\_missions::processChallenge( "ch_indecentexposure" );
|
||||
}
|
||||
|
||||
if ( hurtvictim && IsDefined(self) )
|
||||
{
|
||||
self thread applyFlash(duration, rumbleduration);
|
||||
|
||||
if ( IsDefined(attacker) && attacker != self )
|
||||
{
|
||||
attacker thread maps\mp\gametypes\_damagefeedback::updateDamageFeedback( "flash" );
|
||||
|
||||
// need this here because there are instances where you can not take damage from a flashbang but still get flashed
|
||||
// since you don't take damage the recon perk won't paint you when it should
|
||||
// show the victim on the minimap for N seconds
|
||||
victim = self;
|
||||
if( IsPlayer( attacker ) && attacker IsItemUnlocked( "specialty_paint" ) && attacker _hasPerk( "specialty_paint" ) )
|
||||
{
|
||||
if( !victim maps\mp\perks\_perkfunctions::isPainted() )
|
||||
attacker maps\mp\gametypes\_missions::processChallenge( "ch_paint_pro" );
|
||||
|
||||
victim thread maps\mp\perks\_perkfunctions::setPainted( attacker );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( hurtattacker && IsDefined(attacker) )
|
||||
{
|
||||
attacker thread applyFlash(duration, rumbleduration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
applyFlash(duration, rumbleduration)
|
||||
{
|
||||
// wait for the highest flash duration this frame,
|
||||
// and apply it in the following frame
|
||||
|
||||
if (!IsDefined(self.flashDuration) || duration > self.flashDuration)
|
||||
self.flashDuration = duration;
|
||||
if (!IsDefined(self.flashRumbleDuration) || rumbleduration > self.flashRumbleDuration)
|
||||
self.flashRumbleDuration = rumbleduration;
|
||||
|
||||
wait .05;
|
||||
|
||||
if (IsDefined(self.flashDuration)) {
|
||||
self shellshock( "flashbang_mp", self.flashDuration ); // TODO: avoid shellshock overlap
|
||||
self.flashEndTime = getTime() + (self.flashDuration * 1000);
|
||||
}
|
||||
if (IsDefined(self.flashRumbleDuration)) {
|
||||
self thread flashRumbleLoop( self.flashRumbleDuration ); //TODO: Non-hacky rumble.
|
||||
}
|
||||
|
||||
self.flashDuration = undefined;
|
||||
self.flashRumbleDuration = undefined;
|
||||
}
|
||||
|
||||
|
||||
isFlashbanged()
|
||||
{
|
||||
return IsDefined( self.flashEndTime ) && gettime() < self.flashEndTime;
|
||||
}
|
272
maps/mp/_fx.gsc
Normal file
272
maps/mp/_fx.gsc
Normal file
@ -0,0 +1,272 @@
|
||||
#include common_scripts\utility;
|
||||
#include common_scripts\_fx;
|
||||
#include common_scripts\_createfx;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\_createfx;
|
||||
|
||||
/*
|
||||
****************************************************************************************************************
|
||||
OneShotfx: Fires an effect once.
|
||||
maps\mp\_fx::OneShotfx( effectname, (x y z), predelay);
|
||||
|
||||
Example:
|
||||
maps\mp\_fx::OneShotfx(level.medFire, // Medium fire effect
|
||||
(-701, -18361, 148), // Origin
|
||||
5); // Wait 5 seconds before doing effect
|
||||
****************************************************************************************************************
|
||||
|
||||
|
||||
****************************************************************************************************************
|
||||
Loopfx: Loops an effect with a waittime.
|
||||
maps\mp\_fx::loopfx( effectname, (x y z), delay_between_shots);
|
||||
|
||||
Example:
|
||||
maps\mp\_fx::loopfx(level.medFire, // Medium fire effect
|
||||
(-701, -18361, 148), // Origin
|
||||
0.3); // Wait 0.3 seconds between shots
|
||||
****************************************************************************************************************
|
||||
|
||||
|
||||
****************************************************************************************************************
|
||||
GunFireLoopfx: Simulates bursts of fire.
|
||||
maps\mp\_fx::gunfireloopfx(fxId, fxPos, shotsMin, shotsMax, shotdelayMin, shotdelayMax, betweenSetsMin, betweenSetsMax)
|
||||
|
||||
Example:
|
||||
maps\mp\_fx::gunfireloopfx (level.medFire, // Medium fire effect
|
||||
(-701, -18361, 148), // Origin
|
||||
10, 15, // 10 to 15 shots
|
||||
0.1, 0.3, // 0.1 to 0.3 seconds between shots
|
||||
2.5, 9); // 2.5 to 9 seconds between sets of shots.
|
||||
****************************************************************************************************************
|
||||
|
||||
****************************************************************************************************************
|
||||
GrenadeExplosionfx: Creates a grenade explosion with view jitter.
|
||||
maps\mp\_fx::GrenadeExplosionfx((x y z));
|
||||
|
||||
Example:
|
||||
maps\mp\_fx::GrenadeExplosionfx( (-701, -18361, 148) ); // origin
|
||||
****************************************************************************************************************
|
||||
*/
|
||||
|
||||
script_print_fx()
|
||||
{
|
||||
if ( ( !isdefined( self.script_fxid ) ) || ( !isdefined( self.script_fxcommand ) ) || ( !isdefined( self.script_delay ) ) )
|
||||
{
|
||||
println( "Effect at origin ", self.origin, " doesn't have script_fxid/script_fxcommand/script_delay" );
|
||||
self delete();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( self.target ) )
|
||||
org = getent( self.target ).origin;
|
||||
else
|
||||
org = "undefined";
|
||||
|
||||
// println ("^a Command:", self.script_fxcommand, " Effect:", self.script_fxID, " Delay:", self.script_delay, " ", self.origin);
|
||||
if ( self.script_fxcommand == "OneShotfx" )
|
||||
println( "maps\mp\_fx::OneShotfx(\"" + self.script_fxid + "\", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
|
||||
|
||||
if ( self.script_fxcommand == "loopfx" )
|
||||
println( "maps\mp\_fx::LoopFx(\"" + self.script_fxid + "\", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
|
||||
|
||||
if ( self.script_fxcommand == "loopsound" )
|
||||
println( "maps\mp\_fx::LoopSound(\"" + self.script_fxid + "\", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
|
||||
}
|
||||
|
||||
|
||||
GrenadeExplosionfx( pos )
|
||||
{
|
||||
playfx( level._effect[ "mechanical explosion" ], pos );
|
||||
earthquake( 0.15, 0.5, pos, 250 );
|
||||
// TODO: Add explosion effect and view jitter
|
||||
// println("The script command grenadeExplosionEffect has been removed. maps\\mp\\_fx::GrenadeExplosionfx must be set up to make an effect and jitter the view.");
|
||||
}
|
||||
|
||||
|
||||
soundfx( fxId, fxPos, endonNotify )
|
||||
{
|
||||
org = spawn( "script_origin", ( 0, 0, 0 ) );
|
||||
org.origin = fxPos;
|
||||
org playloopsound( fxId );
|
||||
if ( isdefined( endonNotify ) )
|
||||
org thread soundfxDelete( endonNotify );
|
||||
|
||||
/*
|
||||
ent = level thread createfx_showOrigin ( fxId, fxPos, undefined, undefined, "soundfx" );
|
||||
ent.delay = 0;
|
||||
ent endon ("effect deleted");
|
||||
ent.soundfx = org;
|
||||
*/
|
||||
}
|
||||
|
||||
soundfxDelete( endonNotify )
|
||||
{
|
||||
level waittill( endonNotify );
|
||||
self delete();
|
||||
}
|
||||
|
||||
func_glass_handler()
|
||||
{
|
||||
// FuncGlassIndex [ Index ]
|
||||
// FuncGlassDecals [ Glass Index ] [ Attached SINGLE Decal ]
|
||||
// Funcglass.Targetname == Decal.Script_noteworthy
|
||||
funcglass_indexies = [];
|
||||
funcglass_decals = [];
|
||||
temp_decals = GetEntArray("vfx_custom_glass","targetname");
|
||||
foreach ( decal in temp_decals)
|
||||
{
|
||||
if (IsDefined(decal.script_noteworthy))
|
||||
{
|
||||
attached_glass = GetGlass(decal.script_noteworthy);
|
||||
if (IsDefined (attached_glass))
|
||||
{
|
||||
funcglass_decals[attached_glass] = decal;
|
||||
funcglass_indexies[funcglass_indexies.size] = attached_glass;
|
||||
}
|
||||
}
|
||||
}
|
||||
funcglass_alive_count = funcglass_indexies.size;
|
||||
funcglass_count = funcglass_indexies.size;
|
||||
|
||||
// Run up to 5 times on each frame, avoid too much going on
|
||||
max_iterations = 5;
|
||||
current_index = 0;
|
||||
while(funcglass_alive_count!=0)
|
||||
{
|
||||
max_index = current_index+max_iterations-1;
|
||||
if (max_index > funcglass_count)
|
||||
max_index = funcglass_count;
|
||||
if (current_index ==funcglass_count)
|
||||
current_index = 0;
|
||||
for (; current_index < max_index ; current_index++ )
|
||||
{
|
||||
glass_index = funcglass_indexies[current_index];
|
||||
decal = funcglass_decals[glass_index];
|
||||
|
||||
// Decal is defined, glass isn't destroyed yet (here)
|
||||
if (IsDefined(decal))
|
||||
{
|
||||
// Glass is destroyed in the world
|
||||
if (IsGlassDestroyed(glass_index))
|
||||
{
|
||||
decal delete();
|
||||
funcglass_alive_count--;
|
||||
funcglass_decals[glass_index] = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
wait(.05);
|
||||
}
|
||||
}
|
||||
|
||||
/*rainfx( fxId, fxId2, fxPos )
|
||||
{
|
||||
org = spawn( "script_origin", ( 0, 0, 0 ) );
|
||||
org.origin = fxPos;
|
||||
org thread rainLoop( fxId, fxId2 );
|
||||
|
||||
//ent = level thread createfx_showOrigin( fxId, fxPos, undefined, undefined, "rainfx", undefined, fxId2 );
|
||||
//ent.delay = 0;
|
||||
//ent endon ("effect deleted");
|
||||
//ent.soundfx = org;
|
||||
}
|
||||
|
||||
rainLoop( hardRain, lightRain )
|
||||
{
|
||||
// org playloopsound (fxId);
|
||||
self endon( "death" );
|
||||
blend = spawn( "sound_blend", ( 0.0, 0.0, 0.0 ) );
|
||||
blend.origin = self.origin;
|
||||
self thread blendDelete( blend );
|
||||
|
||||
blend2 = spawn( "sound_blend", ( 0.0, 0.0, 0.0 ) );
|
||||
blend2.origin = self.origin;
|
||||
self thread blendDelete( blend2 );
|
||||
|
||||
|
||||
// lerp of 0 will play _null only
|
||||
blend setSoundBlend( lightRain + "_null", lightRain, 0 );
|
||||
blend2 setSoundBlend( hardRain + "_null", hardRain, 1 );
|
||||
rain = "hard";
|
||||
blendTime = undefined;
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "rain_change", change, blendTime );
|
||||
blendTime *= 20;// internal framerate
|
||||
assert( change == "hard" || change == "light" || change == "none" );
|
||||
assert( blendtime > 0 );
|
||||
|
||||
if ( change == "hard" )
|
||||
{
|
||||
if ( rain == "none" )
|
||||
{
|
||||
blendTime *= 0.5;// gotta do 2 blends to go from none to hard
|
||||
for ( i = 0;i < blendtime;i++ )
|
||||
{
|
||||
blend setSoundBlend( lightRain + "_null", lightRain, i / blendtime );
|
||||
wait( 0.05 );
|
||||
}
|
||||
rain = "light";
|
||||
}
|
||||
if ( rain == "light" )
|
||||
{
|
||||
for ( i = 0;i < blendtime;i++ )
|
||||
{
|
||||
blend setSoundBlend( lightRain + "_null", lightRain, 1 - ( i / blendtime ) );
|
||||
blend2 setSoundBlend( hardRain + "_null", hardRain, i / blendtime );
|
||||
wait( 0.05 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( change == "none" )
|
||||
{
|
||||
if ( rain == "hard" )
|
||||
{
|
||||
blendTime *= 0.5;// gotta do 2 blends to go from hard to none
|
||||
for ( i = 0;i < blendtime;i++ )
|
||||
{
|
||||
blend setSoundBlend( lightRain + "_null", lightRain, ( i / blendtime ) );
|
||||
blend2 setSoundBlend( hardRain + "_null", hardRain, 1 - ( i / blendtime ) );
|
||||
wait( 0.05 );
|
||||
}
|
||||
rain = "light";
|
||||
}
|
||||
if ( rain == "light" )
|
||||
{
|
||||
for ( i = 0;i < blendtime;i++ )
|
||||
{
|
||||
blend setSoundBlend( lightRain + "_null", lightRain, 1 - ( i / blendtime ) );
|
||||
wait( 0.05 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( change == "light" )
|
||||
{
|
||||
if ( rain == "none" )
|
||||
{
|
||||
for ( i = 0;i < blendtime;i++ )
|
||||
{
|
||||
blend setSoundBlend( lightRain + "_null", lightRain, i / blendtime );
|
||||
wait( 0.05 );
|
||||
}
|
||||
}
|
||||
if ( rain == "hard" )
|
||||
{
|
||||
for ( i = 0;i < blendtime;i++ )
|
||||
{
|
||||
blend setSoundBlend( lightRain + "_null", lightRain, i / blendtime );
|
||||
blend2 setSoundBlend( hardRain + "_null", hardRain, 1 - ( i / blendtime ) );
|
||||
wait( 0.05 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rain = change;
|
||||
}
|
||||
}*/
|
||||
|
||||
blendDelete( blend )
|
||||
{
|
||||
self waittill( "death" );
|
||||
blend delete();
|
||||
}
|
50
maps/mp/_global_fx.gsc
Normal file
50
maps/mp/_global_fx.gsc
Normal file
@ -0,0 +1,50 @@
|
||||
#include maps\mp\_global_fx_code;
|
||||
|
||||
// This script automaticly plays a users specified oneshot effect on all prefabs that have the
|
||||
// specified "script_struct" and "targetname" It also excepts angles from the "script_struct"
|
||||
// but will set a default angle of ( 0, 0, 0 ) if none is defined.
|
||||
|
||||
main()
|
||||
{
|
||||
// targetname fxFile
|
||||
global_FX( "ch_streetlight_02_FX_origin" , "fx/misc/lighthaze" );
|
||||
global_FX( "me_streetlight_01_FX_origin" , "fx/misc/lighthaze_bog_a" );
|
||||
global_FX( "ch_street_light_01_on" , "fx/misc/light_glow_white" );
|
||||
global_FX( "lamp_post_globe_on" , "fx/misc/light_glow_white" );
|
||||
global_FX( "highway_lamp_post" , "fx/misc/lighthaze_villassault" );
|
||||
global_FX( "cs_cargoship_spotlight_on_FX_origin" , "fx/misc/lighthaze" );
|
||||
global_FX( "com_tires_burning01_FX_origin" , "fx/fire/tire_fire_med" );
|
||||
global_FX( "icbm_powerlinetower_FX_origin" , "fx/misc/power_tower_light_red_blink" );
|
||||
global_FX( "icbm_mainframe_FX_origin" , "fx/props/icbm_mainframe_lightblink" );
|
||||
global_FX( "lighthaze_oilrig_FX_origin" , "fx/misc/lighthaze_oilrig" );
|
||||
global_FX( "lighthaze_white_FX_origin" , "fx/misc/lighthaze_white" );
|
||||
global_FX( "light_glow_walllight_white_FX_origin", "fx/misc/light_glow_walllight_white" );
|
||||
global_FX( "fluorescent_glow_FX_origin" , "fx/misc/fluorescent_glow" );
|
||||
global_FX( "light_glow_industrial_FX_origin" , "fx/misc/light_glow_industrial" );
|
||||
global_FX( "highrise_blinky_tower" , "fx/misc/power_tower_light_red_blink_large" );
|
||||
global_FX( "light_glow_white_bulb_FX_origin" , "fx/misc/light_glow_white_bulb" );
|
||||
global_FX( "light_glow_white_lamp_FX_origin" , "fx/misc/light_glow_white_lamp" );
|
||||
global_FX( "mp_snow_light_on" , "vfx/ambient/lights/vfx_bulb_prismatic_mp_snow" );
|
||||
global_FX( "vfx_fog_water_mp" , "vfx/ambient/atmospheric/vfx_fog_water_mp" );
|
||||
global_FX( "vfx_mp_handflare" , "vfx/ambient/props/vfx_handflare_sov" );
|
||||
global_FX( "vfx_mp_sov_ceiling_light" , "vfx/ambient/lights/vfx_glow_ceil_light_sov" );
|
||||
|
||||
|
||||
|
||||
|
||||
// targetname fxFile delay
|
||||
global_FX( "light_red_steady_FX_origin" , "fx/misc/tower_light_red_steady" , -2 );
|
||||
global_FX( "light_blue_steady_FX_origin" , "fx/misc/tower_light_blue_steady" , -2 );
|
||||
global_FX( "light_orange_steady_FX_origin" , "fx/misc/tower_light_orange_steady" , -2 );
|
||||
global_FX( "glow_stick_pile_FX_origin" , "fx/misc/glow_stick_glow_pile" , -2 );
|
||||
global_FX( "glow_stick_orange_pile_FX_origin", "fx/misc/glow_stick_glow_pile_orange" , -2 );
|
||||
global_FX( "light_pulse_red_FX_origin" , "fx/misc/light_glow_red_generic_pulse" , -2 );
|
||||
global_FX( "light_pulse_red_FX_origin" , "fx/misc/light_glow_red_generic_pulse" , -2 );
|
||||
global_FX( "light_pulse_orange_FX_origin" , "fx/misc/light_glow_orange_generic_pulse", -2 );
|
||||
global_FX( "light_red_blink_FX_origin" , "fx/misc/power_tower_light_red_blink" , -2 );
|
||||
|
||||
// targetname fxFile delay fxName soundalias
|
||||
global_FX( "flare_ambient_FX_origin" , "fx/misc/flare_ambient" , undefined, undefined, "emt_road_flare_burn" );
|
||||
global_FX( "me_dumpster_fire_FX_origin", "fx/fire/firelp_med_pm" , undefined, undefined, "fire_dumpster_medium" );
|
||||
global_FX( "barrel_fireFX_origin" , "fx/fire/firelp_barrel_pm", undefined, undefined, "fire_barrel_temp" );
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user