This commit is contained in:
6arelyFuture 2024-12-11 11:28:08 +01:00
commit 12ac62a956
Signed by: Future
GPG Key ID: F2000F181A4F7C85
444 changed files with 303964 additions and 0 deletions

270
codescripts/character.gsc Normal file
View 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
View File

@ -0,0 +1,7 @@
main()
{
assert(isdefined(self));
wait 0;
if (isdefined(self))
self delete();
}

11
codescripts/struct.gsc Normal file
View File

@ -0,0 +1,11 @@
InitStructs()
{
level.struct = [];
}
CreateStruct()
{
struct = spawnstruct();
level.struct[level.struct.size] = struct;
return struct;
}

View 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");
}
}
#/

File diff suppressed because it is too large Load Diff

2578
common_scripts/_createfx.gsc Normal file

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1286
common_scripts/_elevator.gsc Normal file

File diff suppressed because it is too large Load Diff

View 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
View 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

File diff suppressed because it is too large Load Diff

395
common_scripts/_pipes.gsc Normal file
View 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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
#include common_scripts\_destructible;
#include destructible_scripts\toy_chicken_common;
#using_animtree( "destructibles" );
main()
{
toy_chicken_common( "" );
}

View File

@ -0,0 +1,8 @@
#include common_scripts\_destructible;
#include destructible_scripts\toy_chicken_common;
#using_animtree( "destructibles" );
main()
{
toy_chicken_common( "_black_white" );
}

View 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" );
}

View 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 );
}

View 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" );
}

View 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" );
}

View 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 );
}

View 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();
}
}
}
}

View 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 );
}

View 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" );
}

View 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();
}

View 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();
}

View File

@ -0,0 +1,8 @@
#include destructible_scripts\vehicle_small_hatch;
#include common_scripts\_destructible;
#using_animtree( "destructibles" );
main()
{
vehicle_small_hatch( "blue" );
}

View File

@ -0,0 +1,8 @@
#include destructible_scripts\vehicle_small_hatch;
#include common_scripts\_destructible;
#using_animtree( "destructibles" );
main()
{
vehicle_small_hatch( "white" );
}

View 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";
}

View 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";
}

View 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";
}

View 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";
}

View 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";
}

View 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";
}

View 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";
}

View 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";
}

View 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";
}

View 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";
}

View 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";
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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);
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

View 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 );
}

File diff suppressed because it is too large Load Diff

View 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] );
}
}

View 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" );
}
}

View 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);
}

View 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);
}

View 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);
}
}
}
#/

View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

335
maps/mp/_barrels_leak.gsc Normal file
View 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
View 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
View 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
View 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
View 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
View 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 );
}
}
}

View 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
View File

@ -0,0 +1,294 @@
#include common_scripts\utility;