This commit is contained in:
6arelyFuture 2025-05-21 16:23:17 +02:00
commit 222e802504
Signed by: Future
GPG Key ID: F2000F181A4F7C85
359 changed files with 242229 additions and 0 deletions

121
LICENSE Normal file
View File

@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

View File

@ -0,0 +1,17 @@
// THIS FILE IS AUTOGENERATED, DO NOT MODIFY
main()
{
self setModel("mp_body_cloak_test");
self attach("mp_head_cloak_test", "", true);
self.headModel = "mp_head_cloak_test";
self setViewmodel("mp_viewhands_cloak_test");
self.voice = "american";
self SetClothType("vestlight");
}
precache()
{
precacheModel("mp_body_cloak_test");
precacheModel("mp_head_cloak_test");
precacheModel("mp_viewhands_cloak_test");
}

View File

@ -0,0 +1,16 @@
// THIS FILE IS AUTOGENERATED, DO NOT MODIFY
main()
{
self setModel("mp_sentinel_body_nojet_b");
codescripts\character::attachHead( "alias_mp_sentinel_heads", xmodelalias\alias_mp_sentinel_heads::main() );
self setViewmodel("viewhands_s1_pmc");
self.voice = "american";
self SetClothType("vestlight");
}
precache()
{
precacheModel("mp_sentinel_body_nojet_b");
codescripts\character::precacheModelArray(xmodelalias\alias_mp_sentinel_heads::main());
precacheModel("viewhands_s1_pmc");
}

View File

@ -0,0 +1,281 @@
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 setHeadModel( headArray[ index ] );
}
setHeadModel( headmodel )
{
if (isdefined(self.headmodel))
self detach(self.headmodel);
self attach( headmodel, "", true );
self.headModel = headmodel;
}
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 )
{
if (IsDefined( self.classname ))
self_info = strtok( self.classname, "_" );
else
self_info = [];
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 ) ];
}

View File

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

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,547 @@
#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", GetDvar( "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", GetDvar( "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 ) );
SetDevDvar( "scr_heightFogEnabled", GetDvar( "g_heightFogEnabledReadOnly", 0 ) );
SetDevDvar( "scr_heightFogBaseHeight", GetDvar( "g_heightFogBaseHeightReadOnly", 0 ) );
SetDevDvar( "scr_heightFogHalfPlaneDistance", GetDvar( "g_heightFogHalfPlaneDistanceReadOnly", 1000 ) );
// 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 ) );
SetDevDvar( "scr_atmosFogEnabled", GetDvar( "g_atmosFogEnabledReadOnly", 0 ) );
SetDevDvar( "scr_atmosFogSunFogColor", GetDvar( "g_atmosFogSunFogColorReadOnly", (.5, .5, .5 ) ) );
SetDevDvar( "scr_atmosFogHazeColor", GetDvar( "g_atmosFogHazeColorReadOnly", (.5, .5, .5 ) ) );
SetDevDvar( "scr_atmosFogHazeStrength", GetDvar( "g_atmosFogHazeStrengthReadOnly", .5 ) );
SetDevDvar( "scr_atmosFogHazeSpread", GetDvar( "g_atmosFogHazeSpreadReadOnly", .75 ) );
SetDevDvar( "scr_atmosFogExtinctionStrength", GetDvar( "g_atmosFogExtinctionStrengthReadOnly", 1 ) );
SetDevDvar( "scr_atmosFogInScatterStrength", GetDvar( "g_atmosFogInScatterStrengthReadOnly", 0 ) );
SetDevDvar( "scr_atmosFogHalfPlaneDistance", GetDvar( "g_atmosFogHalfPlaneDistanceReadOnly", 5000 ) );
SetDevDvar( "scr_atmosFogStartDistance", GetDvar( "g_atmosFogStartDistanceReadOnly", 0 ) );
SetDevDvar( "scr_atmosFogDistanceScale", GetDvar( "g_atmosFogDistanceScaleReadOnly", 1 ) );
SetDevDvar( "scr_atmosFogSkyDistance", int( GetDvar( "g_atmosFogSkyDistanceReadOnly", 100000 ) ) );
SetDevDvar( "scr_atmosFogSkyAngularFalloffEnabled", GetDvar( "g_atmosFogSkyAngularFalloffEnabledReadOnly", 0 ) );
SetDevDvar( "scr_atmosFogSkyFalloffStartAngle", GetDvar( "g_atmosFogSkyFalloffStartAngleReadOnly", 0 ) );
SetDevDvar( "scr_atmosFogSkyFalloffAngleRange", GetDvar( "g_atmosFogSkyFalloffAngleRangeReadOnly", 90 ) );
SetDevDvar( "scr_atmosFogSunDirection", GetDvarVector( "g_atmosFogSunDirectionReadOnly", (0, 0, 1) ) );
SetDevDvar( "scr_atmosFogHeightFogEnabled", GetDvar( "g_atmosFogHeightFogEnabledReadOnly", 0 ) );
SetDevDvar( "scr_atmosFogHeightFogBaseHeight", GetDvar( "g_atmosFogHeightFogBaseHeightReadOnly", 0 ) );
SetDevDvar( "scr_atmosFogHeightFogHalfPlaneDistance", GetDvar( "g_atmosFogHeightFogHalfPlaneDistanceReadOnly", 1000 ) );
$/
}
/$
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" ) );
level.heightFogEnabled = GetDvarInt( "scr_heightFogEnabled" );
level.heightFogBaseHeight = limit( GetDvarFloat( "scr_heightFogBaseHeight" ) );
level.heightFogHalfPlaneDistance = limit( GetDvarFloat( "scr_heightFogHalfPlaneDistance" ) );
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);
level.atmosFogEnabled = GetDvarInt( "scr_atmosFogEnabled" );
vec3 = GetDvarVector( "scr_atmosFogSunFogColor" );
x = limit( vec3[0] );
y = limit( vec3[1] );
z = limit( vec3[2] );
level.atmosFogSunFogColor = ( x, y, z );
vec3 = GetDvarVector( "scr_atmosFogHazeColor" );
x = limit( vec3[0] );
y = limit( vec3[1] );
z = limit( vec3[2] );
level.atmosFogHazeColor = ( x, y, z );
level.atmosFogHazeStrength = limit( GetDvarFloat( "scr_atmosFogHazeStrength" ) );
level.atmosFogHazeSpread = limit( GetDvarFloat( "scr_atmosFogHazeSpread" ) );
level.atmosFogExtinctionStrength = limit( GetDvarFloat( "scr_atmosFogExtinctionStrength" ) );
level.atmosFogInScatterStrength = limit( GetDvarFloat( "scr_atmosFogInScatterStrength" ) );
level.atmosFogHalfPlaneDistance = limit( GetDvarFloat( "scr_atmosFogHalfPlaneDistance" ) );
level.atmosFogStartDistance = limit( GetDvarFloat( "scr_atmosFogStartDistance" ) );
level.atmosFogDistanceScale = limit( GetDvarFloat( "scr_atmosFogDistanceScale" ) );
level.atmosFogSkyDistance = GetDvarInt( "scr_atmosFogSkyDistance" );
level.atmosFogSkyAngularFalloffEnabled = GetDvarInt( "scr_atmosFogSkyAngularFalloffEnabled" );
level.atmosFogSkyFalloffStartAngle = limit( GetDvarFloat( "scr_atmosFogSkyFalloffStartAngle" ) );
level.atmosFogSkyFalloffAngleRange = limit( GetDvarFloat( "scr_atmosFogSkyFalloffAngleRange" ) );
vec3 = GetDvarVector( "scr_atmosFogSunDirection" );
x = limit( vec3[0] );
y = limit( vec3[1] );
z = limit( vec3[2] );
level.atmosFogSunDirection = ( x, y, z );
level.atmosFogHeightFogEnabled = GetDvarInt( "scr_atmosFogHeightFogEnabled" );
level.atmosFogHeightFogBaseHeight = limit( GetDvarFloat( "scr_atmosFogHeightFogBaseHeight" ) );
level.atmosFogHeightFogHalfPlaneDistance = limit( GetDvarFloat( "scr_atmosFogHeightFogHalfPlaneDistance" ) );
}
limit( i)
{
limit = 0.001;
if ( ( i < limit ) && ( i > ( limit * -1 ) ) )
i = 0;
return i;
}
updateFogEntFromScript()
{
if ( GetDvarInt( "scr_cmd_plr_sun" ) )
{
SetDevDvar( "scr_sunFogDir", AnglesToForward( level.player GetPlayerAngles() ) );
SetDevDvar( "scr_cmd_plr_sun", 0 );
}
if ( GetDvarInt( "scr_cmd_plr_sun_atmos_fog" ) )
{
SetDevDvar( "scr_atmosFogSunDirection", AnglesToForward( level.player GetPlayerAngles() ) );
SetDevDvar( "scr_cmd_plr_sun_atmos_fog", 0 );
}
vision_set_name = ToLower(level.vision_set_transition_ent.vision_set);
if ( level.currentgen )
{
vision_set_name_cg = vision_set_name + "_cg";
if ( IsDefined( level.vision_set_fog[ vision_set_name_cg ] ) )
vision_set_name = vision_set_name_cg;
}
ent = level.vision_set_fog[ vision_set_name ];
if ( isdefined( ent ) && isdefined( ent.HDROverride ) && isdefined( level.vision_set_fog[ ToLower(ent.HDROverride) ] ) )
{
ent = level.vision_set_fog[ ToLower(ent.HDROverride) ];
}
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 ( IsDefined( level.heightFogEnabled ) && IsDefined( level.heightFogBaseHeight ) && IsDefined( level.heightFogHalfPlaneDistance ) )
{
ent.heightFogEnabled = level.heightFogEnabled;
ent.heightFogBaseHeight = level.heightFogBaseHeight;
ent.heightFogHalfPlaneDistance = level.heightFogHalfPlaneDistance;
}
else
{
ent.heightFogEnabled = 0;
ent.heightFogBaseHeight = 0;
ent.heightFogHalfPlaneDistance = 1000;
}
if ( IsDefined( level.atmosFogEnabled ) )
{
Assert( IsDefined( level.atmosFogSunFogColor ) );
Assert( IsDefined( level.atmosFogHazeColor ) );
Assert( IsDefined( level.atmosFogHazeStrength ) );
Assert( IsDefined( level.atmosFogHazeSpread ) );
Assert( IsDefined( level.atmosFogExtinctionStrength ) );
Assert( IsDefined( level.atmosFogInScatterStrength ) );
Assert( IsDefined( level.atmosFogHalfPlaneDistance ) );
Assert( IsDefined( level.atmosFogStartDistance ) );
Assert( IsDefined( level.atmosFogDistanceScale ) );
Assert( IsDefined( level.atmosFogSkyDistance ) );
Assert( IsDefined( level.atmosFogSkyAngularFalloffEnabled ) );
Assert( IsDefined( level.atmosFogSkyFalloffStartAngle ) );
Assert( IsDefined( level.atmosFogSkyFalloffAngleRange ) );
Assert( IsDefined( level.atmosFogSunDirection ) );
Assert( IsDefined( level.atmosFogHeightFogEnabled ) );
Assert( IsDefined( level.atmosFogHeightFogBaseHeight ) );
Assert( IsDefined( level.atmosFogHeightFogHalfPlaneDistance ) );
ent.atmosFogEnabled = level.atmosFogEnabled;
ent.atmosFogSunFogColor = level.atmosFogSunFogColor;
ent.atmosFogHazeColor = level.atmosFogHazeColor;
ent.atmosFogHazeStrength = level.atmosFogHazeStrength;
ent.atmosFogHazeSpread = level.atmosFogHazeSpread;
ent.atmosFogExtinctionStrength = level.atmosFogExtinctionStrength;
ent.atmosFogInScatterStrength = level.atmosFogInScatterStrength;
ent.atmosFogHalfPlaneDistance = level.atmosFogHalfPlaneDistance;
ent.atmosFogStartDistance = level.atmosFogStartDistance;
ent.atmosFogDistanceScale = level.atmosFogDistanceScale;
ent.atmosFogSkyDistance = level.atmosFogSkyDistance;
ent.atmosFogSkyAngularFalloffEnabled = level.atmosFogSkyAngularFalloffEnabled;
ent.atmosFogSkyFalloffStartAngle = level.atmosFogSkyFalloffStartAngle;
ent.atmosFogSkyFalloffAngleRange = level.atmosFogSkyFalloffAngleRange;
ent.atmosFogSunDirection = level.atmosFogSunDirection;
ent.atmosFogHeightFogEnabled = level.atmosFogHeightFogEnabled;
ent.atmosFogHeightFogBaseHeight = level.atmosFogHeightFogBaseHeight;
ent.atmosFogHeightFogHalfPlaneDistance = level.atmosFogHeightFogHalfPlaneDistance;
}
else
{
if ( IsDefined( ent.atmosFogEnabled ) )
{
ent.atmosFogEnabled = 0;
}
}
if ( GetDvarInt( "scr_fog_disable" ) )
{
ent.startDist = 2000000000;
ent.halfwayDist = 2000000001;
ent.red = 0;
ent.green = 0;
ent.blue = 0;
ent.HDRColorIntensity = 1;
ent.HDRSunColorIntensity = 1;
ent.maxOpacity = 0;
ent.skyFogIntensity = 0;
ent.heightFogEnabled = 0;
ent.heightFogBaseHeight = 0;
ent.heightFogHalfPlaneDistance = 1000;
if ( IsDefined( ent.atmosFogEnabled ) )
{
ent.atmosFogEnabled = 0;
}
}
set_fog_to_ent_values( ent, 0 );
}
}
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" ) + "\"" );
if( level.currentgen )
fileprint_launcher( "r_filmIntensity \"" + GetDvar( "r_filmTweakIntensity" ) + "\"" );
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( " " );
// 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( " " );
// 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( "r_volumeLightScatterEv \"" + GetDvar( "r_volumeLightScatterEv" ) + "\"" );
fileprint_launcher( " " );
// Rim Light (keep in sync with #define RIM_LIGHTING in platform_defines.h)
fileprint_launcher( "r_rimLightUseTweaks \"" + GetDvar( "r_rimLightUseTweaks" ) + "\"" );
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_rimLightFalloffMaxDistance \"" + GetDvar( "r_rimLightFalloffMaxDistance" ) + "\"" );
fileprint_launcher( "r_rimLightFalloffMinDistance \"" + GetDvar( "r_rimLightFalloffMinDistance" ) + "\"" );
fileprint_launcher( "r_rimLightFalloffMinIntensity \"" + GetDvar( "r_rimLightFalloffMinIntensity" ) + "\"" );
fileprint_launcher( " " );
// Unlit Surface
fileprint_launcher( "r_unlitSurfaceHDRScalar \"" + GetDvar( "r_unlitSurfaceHDRScalar" ) + "\"" );
fileprint_launcher( "" );
// Chromatic Aberration
fileprint_launcher( "r_chromaticAberrationMode \"" + GetDvar( "r_chromaticAberration" ) + "\"" );
fileprint_launcher( "r_chromaticSeparation \"" + GetDvar( "r_chromaticSeparationR" ) + " " + GetDvar( "r_chromaticSeparationG" ) + " " + GetDvar( "r_chromaticSeparationB" ) + "\"" );
fileprint_launcher( "r_chromaticAberrationAlpha \"" + GetDvar( "r_chromaticAberrationAlpha" ) + "\"" );
visionFileName = "\\share\\raw\\vision\\" + vision_set + ".vision";
return fileprint_launcher_end_file( visionFileName, true );
}
get_lightset_filename()
{
if ( level.nextgen )
{
// [nextgen-begin]
return "\\share\\raw\\maps\\createart\\" + get_template_level() + "_lightsets_hdr.csv";
// [nextgen-end]
}
else
{
return "\\share\\raw\\maps\\createart\\" + get_template_level() + "_lightsets.csv";
}
}
print_lightset( lightset_filename )
{
fileprint_launcher_start_file();
PrintLightSetSettings();
return fileprint_launcher_end_file( lightset_filename, true );
}
print_fog_ents( forMP )
{
foreach( ent in level.vision_set_fog )
{
if( !isdefined( ent.name ) )
continue;
ConvertLegacyFog( ent );
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 + "\" );");
if( isdefined( ent.startDist ) )
fileprint_launcher( "\tent.startDist = "+ent.startDist + ";" );
if( isdefined( ent.halfwayDist ) )
fileprint_launcher( "\tent.halfwayDist = "+ent.halfwayDist + ";" );
if( isdefined( ent.red ) )
fileprint_launcher( "\tent.red = "+ent.red + ";" );
if( isdefined( ent.green ) )
fileprint_launcher( "\tent.green = "+ent.green + ";" );
if( isdefined( ent.blue ) )
fileprint_launcher( "\tent.blue = "+ent.blue + ";" );
if( isdefined( ent.HDRColorIntensity ) )
fileprint_launcher( "\tent.HDRColorIntensity = "+ent.HDRColorIntensity + ";" );
if( isdefined( ent.maxOpacity ) )
fileprint_launcher( "\tent.maxOpacity = "+ent.maxOpacity + ";" );
if( isdefined( ent.transitionTime ) )
fileprint_launcher( "\tent.transitionTime = "+ent.transitionTime + ";" );
if( isdefined( ent.sunFogEnabled ) )
fileprint_launcher( "\tent.sunFogEnabled = "+ent.sunFogEnabled + ";" );
if( isdefined( ent.sunRed ) )
fileprint_launcher( "\tent.sunRed = "+ent.sunRed + ";" );
if( isdefined( ent.sunGreen ) )
fileprint_launcher( "\tent.sunGreen = "+ent.sunGreen + ";" );
if( isdefined( ent.sunBlue ) )
fileprint_launcher( "\tent.sunBlue = "+ent.sunBlue + ";" );
if( isdefined( ent.HDRSunColorIntensity ) )
fileprint_launcher( "\tent.HDRSunColorIntensity = "+ent.HDRSunColorIntensity + ";" );
if( isdefined( ent.sunDir ) )
fileprint_launcher( "\tent.sunDir = "+ent.sunDir + ";" );
if( isdefined( ent.sunBeginFadeAngle ) )
fileprint_launcher( "\tent.sunBeginFadeAngle = "+ent.sunBeginFadeAngle + ";" );
if( isdefined( ent.sunEndFadeAngle ) )
fileprint_launcher( "\tent.sunEndFadeAngle = "+ent.sunEndFadeAngle + ";" );
if( isdefined( ent.normalFogScale ) )
fileprint_launcher( "\tent.normalFogScale = "+ent.normalFogScale + ";" );
if( isdefined( ent.skyFogIntensity ) )
fileprint_launcher( "\tent.skyFogIntensity = "+ent.skyFogIntensity + ";" );
if( isdefined( ent.skyFogMinAngle ) )
fileprint_launcher( "\tent.skyFogMinAngle = "+ent.skyFogMinAngle + ";" );
if( isdefined( ent.skyFogMaxAngle ) )
fileprint_launcher( "\tent.skyFogMaxAngle = "+ent.skyFogMaxAngle + ";" );
if ( IsDefined( ent.HDROverride ) )
fileprint_launcher( "\tent.HDROverride = \"" + ent.HDROverride + "\";" );
if ( IsDefined( ent.heightFogEnabled ) )
fileprint_launcher( "\tent.heightFogEnabled = " + ent.heightFogEnabled + ";" );
if ( IsDefined( ent.heightFogBaseHeight ) )
fileprint_launcher( "\tent.heightFogBaseHeight = " + ent.heightFogBaseHeight + ";" );
if ( IsDefined( ent.heightFogHalfPlaneDistance ) )
fileprint_launcher( "\tent.heightFogHalfPlaneDistance = " + ent.heightFogHalfPlaneDistance + ";" );
if ( IsDefined( ent.atmosFogEnabled ) )
fileprint_launcher( "\tent.atmosFogEnabled = " + ent.atmosFogEnabled + ";" );
if ( IsDefined( ent.atmosFogSunFogColor ) )
fileprint_launcher( "\tent.atmosFogSunFogColor = " + ent.atmosFogSunFogColor + ";" );
if ( IsDefined( ent.atmosFogHazeColor ) )
fileprint_launcher( "\tent.atmosFogHazeColor = " + ent.atmosFogHazeColor + ";" );
if ( IsDefined( ent.atmosFogHazeStrength ) )
fileprint_launcher( "\tent.atmosFogHazeStrength = " + ent.atmosFogHazeStrength + ";" );
if ( IsDefined( ent.atmosFogHazeSpread ) )
fileprint_launcher( "\tent.atmosFogHazeSpread = " + ent.atmosFogHazeSpread + ";" );
if ( IsDefined( ent.atmosFogExtinctionStrength ) )
fileprint_launcher( "\tent.atmosFogExtinctionStrength = " + ent.atmosFogExtinctionStrength + ";" );
if ( IsDefined( ent.atmosFogInScatterStrength ) )
fileprint_launcher( "\tent.atmosFogInScatterStrength = " + ent.atmosFogInScatterStrength + ";" );
if ( IsDefined( ent.atmosFogHalfPlaneDistance ) )
fileprint_launcher( "\tent.atmosFogHalfPlaneDistance = " + ent.atmosFogHalfPlaneDistance + ";" );
if ( IsDefined( ent.atmosFogStartDistance ) )
fileprint_launcher( "\tent.atmosFogStartDistance = " + ent.atmosFogStartDistance + ";" );
if ( IsDefined( ent.atmosFogDistanceScale ) )
fileprint_launcher( "\tent.atmosFogDistanceScale = " + ent.atmosFogDistanceScale + ";" );
if ( IsDefined( ent.atmosFogSkyDistance ) )
fileprint_launcher( "\tent.atmosFogSkyDistance = " + int( ent.atmosFogSkyDistance ) + ";" );
if ( IsDefined( ent.atmosFogSkyAngularFalloffEnabled ) )
fileprint_launcher( "\tent.atmosFogSkyAngularFalloffEnabled = " + ent.atmosFogSkyAngularFalloffEnabled + ";" );
if ( IsDefined( ent.atmosFogSkyFalloffStartAngle ) )
fileprint_launcher( "\tent.atmosFogSkyFalloffStartAngle = " + ent.atmosFogSkyFalloffStartAngle + ";" );
if ( IsDefined( ent.atmosFogSkyFalloffAngleRange ) )
fileprint_launcher( "\tent.atmosFogSkyFalloffAngleRange = " + ent.atmosFogSkyFalloffAngleRange + ";" );
if ( IsDefined( ent.atmosFogSunDirection ) )
fileprint_launcher( "\tent.atmosFogSunDirection = " + ent.atmosFogSunDirection + ";" );
if ( IsDefined( ent.atmosFogHeightFogEnabled ) )
fileprint_launcher( "\tent.atmosFogHeightFogEnabled = " + ent.atmosFogHeightFogEnabled + ";" );
if ( IsDefined( ent.atmosFogHeightFogBaseHeight ) )
fileprint_launcher( "\tent.atmosFogHeightFogBaseHeight = " + ent.atmosFogHeightFogBaseHeight + ";" );
if ( IsDefined( ent.atmosFogHeightFogHalfPlaneDistance ) )
fileprint_launcher( "\tent.atmosFogHeightFogHalfPlaneDistance = " + ent.atmosFogHeightFogHalfPlaneDistance + ";" );
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 ( " " );
}
if ( !forMP )
{ // MP holds this script in the setup_fog() function.
// put out our dev only call to our fog file (normally code will parse it and apply it clientside)
fileprint_launcher( "\t/$" );
if ( IsUsingHDR() )
fileprint_launcher( "\tlevel._art_fog_setup = maps\\createart\\" + level.script + "_fog_hdr::main;" );
else
fileprint_launcher( "\tlevel._art_fog_setup = maps\\createart\\" + level.script + "_fog::main;" );
fileprint_launcher( "\t$/" );
}
}
print_fog_ents_csv()
{
foreach( ent in level.vision_set_fog )
{
if( !isdefined( ent.name ) )
continue;
targettedByHDROverride = false;
foreach( ent2 in level.vision_set_fog )
{
if ( isdefined(ent2.HDROverride) && ent2.HDROverride == ent.name )
{
targettedByHDROverride = true;
break;
}
}
if ( !targettedByHDROverride )
fileprint_launcher( "rawfile,vision/"+ent.name+".vision");
}
}
$/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,968 @@
#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( "vector", "origin", "Origin", (0,0,0), "fx", 1 );
addOption( "vector", "angles", "Angles", (0,0,0), "fx", 1 );
addOption( "string", "fxid", "FX id", "nil", "fx" );
addOption( "float", "delay", "Repeat rate/start delay", 0.5, "fx" );
addOption( "string", "flag", "Flag", "nil", "exploder" );
addOption( "string", "platform", "Platform", "all", "all" );
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" );
setup_help_keys();
addOption( "string", "soundalias", "Soundalias", "nil", "all" );
addOption( "string", "loopsound", "Loopsound", "nil", "exploder" );
addOption( "int", "reactive_radius", "Reactive Radius", 100, "reactive_fx", undefined, ::input_reactive_radius );
addOption( "string", "ambiencename", "Ambience Name", "nil", "soundfx_dynamic" );
addOption( "int", "dynamic_distance", "Dynamic Max Distance", 1000, "soundfx_dynamic" );
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;
level.effect_list_current_size = 0;
level.help_list_offset = 0;
level.help_list_offset_max = 20;
level.createfx_help_active = false;
level.createfx_menu_list_active = false;
// 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[ "all" ][ "soundfx_dynamic" ] = 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;
level.createfxMasks[ "soundfx_dynamic" ] = [];
level.createfxMasks[ "soundfx_dynamic" ][ "soundfx_dynamic" ] = 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_loopfx" );
draw_effects_list();
return;
}
else if ( button_is_clicked( "3" ) )
{
setmenu( "create_loopsound" );
ent = createLoopSound();
finish_creating_entity( ent );
return;
}
else if ( button_is_clicked( "4" ) )
{
setmenu( "create_exploder" );
ent = createNewExploder();
finish_creating_entity( ent );
return;
}
else if ( button_is_clicked( "5" ) )
{
setmenu( "create_interval_sound" );
ent = createIntervalSound();
finish_creating_entity( ent );
return;
}
else if ( button_is_clicked( "6" ) )
{
ent = createReactiveEnt();
finish_creating_entity( ent );
return;
}
else if ( button_is_clicked( "7" ) )
{
ent = createDynamicAmbience();
finish_creating_entity( ent );
return;
}
}
menu_create()
{
level.createfx_menu_list_active = true;
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 || level._createfx.justConvertedOneshot == 1 )
{
display_fx_info( last_selected_ent );
level.last_displayed_ent = last_selected_ent;
level._createfx.justConvertedOneshot = 0;
}
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" );
level.createfx_menu_list_active = false;
level.createfx_last_movement_timer = 0;
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" );
level.createfx_menu_list_active = false;
}
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 + 1 ][ 0 ].color = ( 1, 1, 0 );
if ( IsDefined( option[ "input_func" ] ) )
{
thread [[ option[ "input_func" ] ]]( drawnCount + 1 );
}
else
{
createfx_centerprint( "To set " + option[ "description" ] + ", type /fx newvalue. To remove "+ option[ "description" ] +", type /fx del" );
}
set_option_index( option[ "name" ] );
setdvar( "fx", "nil" );
}
menu_fx_option_set()
{
if ( getdvar( "fx" ) == "nil" )
return;
if ( getdvar( "fx" ) == "del" )
{
remove_selected_option();
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" );
if ( option[ "type" ] == "vector" )
setting = getdvarvector( "fx" );
if(isDefined(setting))
apply_option_to_selected_fx( option, setting );
else
setdvar( "fx" , "nil");
}
apply_option_to_selected_fx( option, setting )
{
save_undo_buffer();
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();
//if we moved it, restart and focus camera on new position
if( option[ "name" ] == "origin")
{
level.createfx_last_movement_timer = 0;
frame_selected();
}
//if we changed angles, restart fx
if( option[ "name" ] == "angles")
{
level.createfx_last_movement_timer = 0;
}
save_redo_buffer();
}
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, nowrite, input_func )
{
option = [];
option[ "type" ] = type;
option[ "name" ] = name;
option[ "description" ] = description;
option[ "default" ] = defaultSetting;
option[ "mask" ] = mask;
if ( isdefined(nowrite) && nowrite )
option[ "nowrite" ] = 1;
else
option[ "nowrite" ] = 0;
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() );
level.createfx_menu_list_active = true;
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 )
{
level.effect_list_current_size = count;
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;
if ( level.createfx_help_active )
return;
clear_fx_hudElements();
set_fx_hudElement( "Name: " + ent.v[ "fxid" ] );
set_fx_hudElement( "Type: " + ent.v[ "type" ] );
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 )
{
level.effect_list_current_size = count;
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;
}
}
}
display_current_translation()
{
ent = get_last_selected_ent();
if(isdefined(ent))
display_fx_info(ent);
}
//---------------------------------------------------------
// Draw Effects Section
//---------------------------------------------------------
draw_effects_list( title )
{
clear_fx_hudElements();
count = 0;
more = false;
keys = func_get_level_fx();
level.effect_list_current_size = keys.size;
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()
{
if ( level.effect_list_offset >= level.effect_list_current_size - level.effect_list_offset_max )
{
level.effect_list_offset = 0;
}
else
{
level.effect_list_offset += level.effect_list_offset_max;
}
}
decrement_list_offset()
{
if ( level.effect_list_current_size < level.effect_list_offset_max )
{
level.effect_list_offset = 0;
}
else
{
level.effect_list_offset -= level.effect_list_offset_max;
if ( level.effect_list_offset < 0 )
{
//keys = func_get_level_fx();
level.effect_list_offset = level.effect_list_current_size - level.effect_list_offset_max;
}
}
}
//---------------------------------------------------------
// Draw Help
//---------------------------------------------------------
draw_help_list( title )
{
clear_fx_hudElements();
count = 0;
keys = level.createfx_help_keys;
if( !IsDefined( title ) )
{
title = "Help";
}
set_fx_hudElement( "[" + title + "]");// + " [" + level.help_list_offset + " - " + keys.size + "]:" );
// if ( level.effect_list_offset >= keys.size )
// level.effect_list_offset = 0;
for ( i = level.help_list_offset; i < keys.size; i++ )
{
count = count + 1;
set_fx_hudElement( keys[ i ] );
if ( count >= level.help_list_offset_max )
{
more = true;
break;
}
}
if ( keys.size > level.help_list_offset_max )
{
level.effect_list_current_size = keys.size;
set_fx_hudElement( "(->) More >" );
set_fx_hudElement( "(<-) Previous >" );
}
}
increment_help_list_offset()
{
keys = level.createfx_help_keys;
if ( level.help_list_offset >= keys.size - level.help_list_offset_max )
{
level.help_list_offset = 0;
}
else
{
level.help_list_offset += level.help_list_offset_max;
}
}
decrement_help_list_offset()
{
level.help_list_offset -= level.help_list_offset_max;
if ( level.help_list_offset < 0 )
{
keys = level.createfx_help_keys;
level.help_list_offset = keys.size - level.help_list_offset_max;
}
}
help_navigation_buttons()
{
while(level.createfx_help_active == true)
{
if ( next_button() )
{
increment_help_list_offset();
draw_help_list();
wait 0.1;
}
else if ( previous_button() )
{
decrement_help_list_offset();
draw_help_list();
wait 0.1;
}
waitframe();
}
}
setup_help_keys()
{
level.createfx_help_keys = [
"Insert Insert entity",
"F2 Toggle createfx dot and text drawing",
"F5 SAVES your work",
"Z Undo",
"Shift-Z Redo",
"F Frames currently selected entities in camera view",
"END Drop selected entities to the ground",
"A Add option to the selected entities",
"P Reset the rotation of the selected entities",
"V Copy the angles from the most recently selected fx onto all selected fx.",
"O Orient all selected fx to point at most recently selected fx.",
"S Toggle Snap2Normal mode.",
"L Toggle 90deg Snap mode.",
"G Select all effects in level of same exploder or flag as selected.",
"U Select by name list.",
"C Convert One-Shot to Exploder.",
"Delete Kill the selected entities",
"ESCAPE Cancel out of option-modify-mode, must have console open",
"SPACE or -> Turn on exploders",
"<- Turn off exploders",
"Dpad Move selected entities on X/Y or rotate pitch/yaw",
"A button Toggle the selection of the current entity",
"X button Toggle entity rotation mode",
"Y button Move selected entites up or rotate roll",
"B button Move selected entites down or rotate roll",
"R Shoulder Move selected entities to the cursor",
"L Shoulder Hold to select multiple entites",
"L JoyClick Copy",
"R JoyClick Paste",
"Ctrl-C Copy",
"Ctrl-V Paste",
"N UFO",
"T Toggle Timescale FAST",
"Y Toggle Timescale SLOW",
"[ Toggle FX Visibility",
"] Toggle ShowTris",
"F11 Toggle FX Profile"];
}
//---------------------------------------------------------
// Select by Name Section
//---------------------------------------------------------
select_by_name()
{
count = 0;
picked_fx = undefined;
keys = func_get_level_fx();
for ( i = level.effect_list_offset; i < keys.size; i++ )
{
count = count + 1;
button_to_check = count;
if ( button_to_check == 10 )
button_to_check = 0;
if ( button_is_clicked( button_to_check + "" ) )
{
picked_fx = keys[ i ];
break;
}
if ( count > level.effect_list_offset_max )
break;
}
if ( !IsDefined( picked_fx ) )
return;
index_array = [];
foreach ( i, ent in level.createFXent )
{
if ( IsSubStr( ent.v[ "fxid" ], picked_fx ) )
{
index_array[ index_array.size ] = i;
}
}
deselect_all_ents();
select_index_array( index_array );
level._createfx.select_by_name = true;
}
//---------------------------------------------------------
// Utility Section
//---------------------------------------------------------
get_last_selected_ent()
{
return level._createfx.selected_fx_ents[ level._createfx.selected_fx_ents.size - 1 ];
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

970
raw/common_scripts/_fx.gsc Normal file
View File

@ -0,0 +1,970 @@
#include common_scripts\utility;
#include common_scripts\_createfx;
//#include soundscripts\_audio;
//#include soundscripts\_audio_dynamic_ambi;
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;
case "soundfx_dynamic":
ent thread create_dynamicambience();
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( "}" );
}
}
PlatformMatches()
{
if ( IsDefined( self.v[ "platform" ] ) && IsDefined( level.currentgen ) )
{
platform = self.v[ "platform" ];
if (( platform == "cg" && !level.currentgen ) ||
( platform == "ng" && !level.nextgen ) ||
( platform == "xenon" && !level.xenon ) ||
( platform == "ps3" && !level.ps3 ) ||
( platform == "pc" && !level.pc ) ||
( platform == "xb3" && !level.xb3 ) ||
( platform == "ps4" && !level.ps4 ) ||
( platform == "pccg" && !level.pccg ) ||
( platform == "!cg" && level.currentgen ) ||
( platform == "!ng" && level.nextgen ) ||
( platform == "!xenon" && level.xenon ) ||
( platform == "!ps3" && level.ps3 ) ||
( platform == "!pc" && level.pc ) ||
( platform == "!xb3" && level.xb3 ) ||
( platform == "!ps4" && level.ps4 ) ||
( platform == "!pccg" && level.pccg ) )
{
return false;
}
}
return true;
}
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()
{
if ( !PlatformMatches() )
{
return;
}
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()
{
if ( !PlatformMatches() )
{
return;
}
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" ] );
}
create_dynamicambience()
{
if ( !PlatformMatches() )
{
return;
}
if ( !IsDefined( self.v[ "ambiencename" ] ) )
return;
if ( self.v[ "ambiencename" ] == "nil" )
return;
if ( isSP() )
{
// TODO - Make this work in SP
/*
if ( IsDefined( self.dambInfoStruct ) )
{
DAMB_stop_preset_at_point( self.v[ "ambiencename" ], self.dambInfoStruct.unique_id );
}
DAMB_start_preset_at_point( self.v[ "ambiencename" ], self.v[ "origin" ], undefined, self.v[ "dynamic_distance" ], self.dambInfoStruct.unique_id );
*/
}
else
{
if ( GetDvar( "createfx" ) == "on" )
{
// wait till the player spawns and createfxlogic starts before continuing.
flag_wait( "createfx_started" );
}
if ( IsDefined( self.dambInfoStruct ) )
{
level.player StopDynamicAmbience( self.dambInfoStruct.unique_id );
}
self.dambInfoStruct = SpawnStruct();
self.dambInfoStruct assign_unique_id();
level.player PlayDynamicAmbience( self.v[ "ambiencename" ], self.v[ "origin" ], self.v[ "dynamic_distance" ], self.dambInfoStruct.unique_id );
}
}
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 ( !PlatformMatches() )
{
return;
}
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()
{
if ( !PlatformMatches() )
{
return;
}
// MP should not start this thread in release
if ( !isSP() && GetDVar( "createfx" ) == "" )
{
return;
}
if ( !IsDefined( level._fx.reactive_thread ) )
{
level._fx.reactive_thread = true;
level thread reactive_fx_thread();
}
if ( !IsDefined( level._fx.reactive_fx_ents ) )
{
level._fx.reactive_fx_ents = [];
}
level._fx.reactive_fx_ents[ level._fx.reactive_fx_ents.size ] = self;
self.next_reactive_time = 3000;
}
reactive_fx_thread()
{
if ( !isSp() )
{
if ( GetDvar( "createfx" ) == "on" )
{
// wait till the player spawns and createfxlogic starts before continuing.
flag_wait( "createfx_started" );
}
}
// TODO: Switch to using level notify instead
// HOWEVER!!! we will need the trigger_radius for when we are in CREATEFX mode for MP only!!!
// use level.mp_createfx condition
// trigger = Spawn( "trigger_radius", level.player.origin, 0, 5000, 5000 );
// trigger SetCanDamage( true );
// trigger EnableLinkTo();
// trigger LinkTo( level.player );
level._fx.reactive_sound_ents = [];
explosion_radius = 256;
while ( 1 )
{
// trigger waittill( "damage", dmg, attacker, dir_vec, point, type );
level waittill( "code_damageradius", attacker, explosion_radius, point, weapon_name );
ents = sort_reactive_ents( point, explosion_radius );
foreach ( i, ent in ents )
ent thread play_reactive_fx( i );
}
}
vector2d( vec )
{
return ( vec[ 0 ], vec[ 1 ], 0 );
}
sort_reactive_ents( point, explosion_radius )
{
closest = [];
time = GetTime();
foreach ( ent in level._fx.reactive_fx_ents )
{
if ( ent.next_reactive_time > time )
continue;
radius_squared = ent.v[ "reactive_radius" ] + explosion_radius;
radius_squared *= radius_squared;
if ( DistanceSquared( point, ent.v[ "origin" ] ) < radius_squared )
{
closest[ closest.size ] = ent;
}
}
foreach ( ent in closest )
{
playerToEnt = vector2d( ent.v[ "origin" ] - level.player.origin );
playerToPoint = vector2d( point - level.player.origin );
vec1 = VectorNormalize( playerToEnt );
vec2 = VectorNormalize( playerToPoint );
ent.dot = VectorDot( vec1, vec2 );
}
// Sort from lowest dot to greatest
for ( i = 0; i < closest.size - 1; i++ )
{
for ( j = i + 1; j < closest.size; j++ )
{
if ( closest[ i ].dot > closest[ j ].dot )
{
temp = closest[ i ];
closest[ i ] = closest[ j ];
closest[ j ] = temp;
}
}
}
// remove the .origin and .dot since we're done with sortbydistance()
foreach ( ent in closest )
{
ent.origin = undefined;
ent.dot = undefined;
}
// Make sure we only have 4
for ( i = CONST_MAX_REACTIVE_SOUND_ENTS; i < closest.size; i++ )
{
closest[ i ] = undefined;
}
return closest;
}
play_reactive_fx( num )
{
sound_ent = get_reactive_sound_ent();
if ( !IsDefined( sound_ent ) )
return;
/#
self.is_playing = true;
#/
self.next_reactive_time = GeTTime() + CONST_NEXT_PLAY_TIME;
sound_ent.origin = self.v[ "origin" ];
sound_ent.is_playing = true;
wait( num * RandomFloatRange( 0.05, 0.1 ) );
if ( isSP() )
{
sound_ent PlaySound( self.v[ "soundalias" ], "sounddone" );
sound_ent waittill( "sounddone" );
}
else
{
sound_ent PlaySound( self.v[ "soundalias" ] );
wait( 2 );
}
// wait for sounddone to be removed compeletely
// bug in prague port to iw6 where in the same frame this got called again after the sounddone notify
// odd thing, even 0.05 doesn't work. Code should fix this!
wait( 0.1 );
sound_ent.is_playing = false;
/#
self.is_playing = undefined;
#/
}
get_reactive_sound_ent()
{
foreach ( ent in level._fx.reactive_sound_ents )
{
if ( !ent.is_playing )
return ent;
}
if ( level._fx.reactive_sound_ents.size < CONST_MAX_REACTIVE_SOUND_ENTS )
{
ent = Spawn( "script_origin", ( 0, 0, 0 ) );
ent.is_playing = false;
level._fx.reactive_sound_ents[ level._fx.reactive_sound_ents.size ] = ent;
return ent;
}
return undefined;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
#include common_scripts\_destructible;
#using_animtree( "destructibles" );
main()
{
dest_onestate("berlin_hotel_lights_wall2","berlin_hotel_lights_wall2_destroyed","fx/misc/light_blowout_wall_runner");
}
dest_onestate(destructibleType,dest,fx,sound)
{
destructible_create(destructibleType,"tag_origin",150,undefined,32);
destructible_fx( "tag_fx", fx);
destructible_state( "tag_origin", dest, undefined, undefined, "no_meele" );
if (isdefined( sound))
destructible_sound( sound );
}

View File

@ -0,0 +1,24 @@
#include common_scripts\_destructible;
#using_animtree( "destructibles" );
main()
{
//---------------------------------------------------------------------
// container_plastic_72x56x48_01
//---------------------------------------------------------------------
destructible_create( "container_plastic_72x56x48_01_destp", "tag_origin", 500, undefined, 32, "no_melee" );
destructible_fx( "tag_origin", "vfx/destructible/container_plastic_72x56x48_01", true );
destructible_explode( 1500, 3000, 100, 100, 10, 20, undefined, undefined, undefined, undefined, undefined, undefined, 2000, 3000 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage, continueDamage, originOffset, earthQuakeScale, earthQuakeRadius, originOffset3d, delaytime, angularImpulse_min, angularImpulse_max
destructible_state( "tag_origin", "container_plastic_72x56x48_01_dstry_destp", undefined, undefined, undefined, undefined, undefined, false );
destructible_part( "tag_part_01", "container_plastic_72x56x48_01_part_01_destp", undefined, undefined, undefined, undefined, 1.0, 1.0 );
destructible_part( "tag_part_02", "container_plastic_72x56x48_01_part_02_destp", undefined, undefined, undefined, undefined, 1.0, 1.0 );
destructible_part( "tag_part_03", "container_plastic_72x56x48_01_part_03_destp", undefined, undefined, undefined, undefined, 1.0, 1.0 );
destructible_part( "tag_part_04", "container_plastic_72x56x48_01_part_04_destp", undefined, undefined, undefined, undefined, 1.0, 1.0 );
destructible_part( "tag_part_05", "container_plastic_72x56x48_01_part_05_destp", undefined, undefined, undefined, undefined, 1.0, 1.0 );
destructible_part( "tag_part_06", "container_plastic_72x56x48_01_part_06_destp", undefined, undefined, undefined, undefined, 1.0, 1.0 );
destructible_part( "tag_part_07", "container_plastic_72x56x48_01_part_07_destp", undefined, undefined, undefined, undefined, 1.0, 1.0 );
destructible_part( "tag_part_08", "container_plastic_72x56x48_01_part_08_destp", undefined, undefined, undefined, undefined, 1.0, 1.0 );
}

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,17 @@
#include common_scripts\_destructible;
#using_animtree( "destructibles" );
main()
{
//---------------------------------------------------------------------
// electric box medium toy
//---------------------------------------------------------------------
destructible_create( "toy_electricbox4", "tag_origin", 150, undefined, 32, "no_melee" );
destructible_splash_damage_scaler( 15 );
destructible_fx( "tag_fx", "fx/props/electricbox4_explode", undefined, undefined, undefined, 1 );
destructible_sound( "exp_fusebox_sparks" );
destructible_explode( 20, 2000, 32, 32, 32, 48, undefined, 0 ); // force_min, force_max, rangeSP, rangeMP, mindamage, maxdamage, continue damage, originoffset
destructible_state( undefined, "me_electricbox4_dest", undefined, undefined, "no_melee" );
// door
destructible_part( "tag_fx", "me_electricbox4_door", undefined, undefined, undefined, undefined, 1.0, 1.0 );
}

View File

@ -0,0 +1,44 @@
#include common_scripts\_destructible;
#using_animtree( "destructibles" );
main()
{
//---------------------------------------------------------------------
// Locker Double
//---------------------------------------------------------------------
destructible_create( "toy_locker_double", "tag_origin", 150, undefined, 32, "no_melee" );
destructible_anim( %locker_broken_both_doors_1, #animtree, "setanimknob", undefined, 0, "locker_broken_both_doors_1" );
destructible_fx( "tag_fx", "fx/props/locker_double_des_02_right", undefined, undefined, 0 );
destructible_sound( "lockers_fast", undefined, 0 );
destructible_anim( %locker_broken_both_doors_2, #animtree, "setanimknob", undefined, 1, "locker_broken_both_doors_2" );
destructible_fx( "tag_fx", "fx/props/locker_double_des_01_left", undefined, undefined, 1 );
destructible_sound( "lockers_fast", undefined, 1 );
destructible_anim( %locker_broken_both_doors_4, #animtree, "setanimknob", undefined, 2, "locker_broken_both_doors_4" );
destructible_fx( "tag_fx", "fx/props/locker_double_des_03_both", undefined, undefined, 2 );
destructible_sound( "lockers_double", undefined, 2 );
destructible_anim( %locker_broken_door1_fast, #animtree, "setanimknob", undefined, 3, "locker_broken_door1_fast" );
destructible_fx( "tag_fx", "fx/props/locker_double_des_01_left", undefined, undefined, 3 );
destructible_sound( "lockers_fast", undefined, 3 );
destructible_anim( %locker_broken_door2_fast, #animtree, "setanimknob", undefined, 4, "locker_broken_door2_fast" );
destructible_fx( "tag_fx", "fx/props/locker_double_des_02_right", undefined, undefined, 4 );
destructible_sound( "lockers_fast", undefined, 4 );
destructible_anim( %locker_broken_both_doors_3, #animtree, "setanimknob", undefined, 5, "locker_broken_both_doors_3" );
destructible_fx( "tag_fx", "fx/misc/no_effect", undefined, undefined, 5 );
destructible_sound( "lockers_minor", undefined, 5 );
destructible_anim( %locker_broken_door1_slow, #animtree, "setanimknob", undefined, 6, "locker_broken_door1_slow" );
destructible_fx( "tag_fx", "fx/misc/no_effect", undefined, undefined, 6 );
destructible_sound( "lockers_minor", undefined, 6 );
destructible_anim( %locker_broken_door2_slow, #animtree, "setanimknob", undefined, 7, "locker_broken_door2_slow" );
destructible_fx( "tag_fx", "fx/misc/no_effect", undefined, undefined, 7 );
destructible_sound( "lockers_minor", undefined, 7 );
destructible_state( undefined, "com_locker_double_destroyed", undefined, undefined, "no_melee" );
}

0
raw/dev_code_post_gfx_mp Normal file
View File

0
raw/dev_code_pre_gfx_mp Normal file
View File

0
raw/dev_common_bots_mp Normal file
View File

0
raw/dev_common_core_mp Normal file
View File

3
raw/dev_common_mp Normal file
View File

@ -0,0 +1,3 @@
^1ERROR: alias 'exo_shield_activate_npc' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_activate_npc_lyr' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_activate_npc_lyr_02' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_activate_plr' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_activate_plr_lyr' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_activate_plr_lyr_02' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_close' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_deactivate_lyr_plr' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_deactivate_npc' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_deactivate_npc_lyr' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_deactivate_plr' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_open' already added but differs - undefined behavior will result.^1ERROR: alias 'stim_activate' already added but differs - undefined behavior will result.^1ERROR: alias 'stim_activate_lyr' already added but differs - undefined behavior will result.^1ERROR: alias 'stim_activate_lyr_02' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_activate_npc' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_activate_npc_lyr' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_activate_npc_lyr_02' already added but differs - undefined behavior will result.^1ERROR: alias 'exo_shield_activate_plr' already added but differs - undefined behavior will result.ERROR: *** Truncating Too Many Errors ***
ERROR: *** Truncating Too Many Errors ***
ERROR: *** Truncating Too Many Errors ***

0
raw/dev_development_mp Normal file
View File

1
raw/dev_mp_comeback Normal file
View File

@ -0,0 +1 @@
^1ERROR: Too many collision tris for 'cb_power_core_lod0101' (36704 > 32768)

1
raw/dev_mp_dam Normal file
View File

@ -0,0 +1 @@
^1ERROR: Could not open 'mp/constbaselines/bl_ps4_mp_dam_ball.bin'^1ERROR: failed loading 'mp/constbaselines/bl_ps4_mp_dam_ball.bin' of type 'rawfile'^1ERROR: Could not open 'mp/constbaselines/bl_ps4_mp_dam_sr.bin'^1ERROR: failed loading 'mp/constbaselines/bl_ps4_mp_dam_sr.bin' of type 'rawfile'^1ERROR: Could not open 'mp/constbaselines/bl_ps4_mp_dam_twar.bin'^1ERROR: failed loading 'mp/constbaselines/bl_ps4_mp_dam_twar.bin' of type 'rawfile'

0
raw/dev_mp_detroit Normal file
View File

0
raw/dev_mp_greenband Normal file
View File

0
raw/dev_mp_instinct Normal file
View File

0
raw/dev_mp_lab2 Normal file
View File

0
raw/dev_mp_laser2 Normal file
View File

0
raw/dev_mp_levity Normal file
View File

0
raw/dev_mp_prison Normal file
View File

0
raw/dev_mp_prison_z Normal file
View File

0
raw/dev_mp_recovery Normal file
View File

0
raw/dev_mp_refraction Normal file
View File

0
raw/dev_mp_solar Normal file
View File

0
raw/dev_mp_terrace Normal file
View File

0
raw/dev_mp_venus Normal file
View File

View File

View File

View File

View File

0
raw/dev_patch_common_mp Normal file
View File

View File

0
raw/dev_patch_mp_dam Normal file
View File

0
raw/dev_patch_mp_detroit Normal file
View File

View File

View File

0
raw/dev_patch_mp_lab2 Normal file
View File

0
raw/dev_patch_mp_laser2 Normal file
View File

0
raw/dev_patch_mp_levity Normal file
View File

0
raw/dev_patch_mp_prison Normal file
View File

View File

View File

0
raw/dev_patch_mp_solar Normal file
View File

0
raw/dev_patch_mp_terrace Normal file
View File

0
raw/dev_patch_mp_venus Normal file
View File

View File

@ -0,0 +1 @@
^1ERROR: Could not open '../dedicated/ps4/zone_source/assetlist/mp_vlobby_room.csv'^1ERROR: Could not open '../dedicated/ps4/zone_source/assetinfo/mp_vlobby_room.csv'

22030
raw/maps/_utility.gsc Normal file

File diff suppressed because it is too large Load Diff

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 = "fence_tarp_108x76";
if ( isSp() )
{
level.anim_prop_models[ model ][ "wind" ] = %fence_tarp_108x76_med_01;
}
else
level.anim_prop_models[ model ][ "wind" ] = "fence_tarp_108x76_med_01";
}

View File

@ -0,0 +1,7 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
set_basic_animated_model( "foliage_tree_grey_oak_lg_a_animated", %foliage_tree_grey_oak_lg_a_sway, "foliage_tree_grey_oak_lg_a_sway" );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_comeback_fog_hdr::SetupFog( );
else
maps\createart\mp_comeback_fog::SetupFog( );
VisionSetNaked( "mp_comeback", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_dam_fog_hdr::SetupFog( );
else
maps\createart\mp_dam_fog::SetupFog( );
VisionSetNaked( "mp_dam", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_detroit_fog_hdr::SetupFog( );
else
maps\createart\mp_detroit_fog::SetupFog( );
VisionSetNaked( "mp_detroit", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_greenband_fog_hdr::SetupFog( );
else
maps\createart\mp_greenband_fog::SetupFog( );
VisionSetNaked( "mp_greenband", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_instinct_fog_hdr::SetupFog( );
else
maps\createart\mp_instinct_fog::SetupFog( );
VisionSetNaked( "mp_instinct", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_lab2_fog_hdr::SetupFog( );
else
maps\createart\mp_lab2_fog::SetupFog( );
VisionSetNaked( "mp_lab2", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_laser2_fog_hdr::SetupFog( );
else
maps\createart\mp_laser2_fog::SetupFog( );
VisionSetNaked( "mp_laser2", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_levity_fog_hdr::SetupFog( );
else
maps\createart\mp_levity_fog::SetupFog( );
VisionSetNaked( "mp_levity", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_prison_fog_hdr::SetupFog( );
else
maps\createart\mp_prison_fog::SetupFog( );
VisionSetNaked( "mp_prison", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_prison_z_fog_hdr::SetupFog( );
else
maps\createart\mp_prison_z_fog::SetupFog( );
VisionSetNaked( "mp_prison_z", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_recovery_fog_hdr::SetupFog( );
else
maps\createart\mp_recovery_fog::SetupFog( );
VisionSetNaked( "mp_recovery", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_refraction_fog_hdr::SetupFog( );
else
maps\createart\mp_refraction_fog::SetupFog( );
VisionSetNaked( "mp_refraction", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_solar_fog_hdr::SetupFog( );
else
maps\createart\mp_solar_fog::SetupFog( );
VisionSetNaked( "mp_solar", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_terrace_fog_hdr::SetupFog( );
else
maps\createart\mp_terrace_fog::SetupFog( );
VisionSetNaked( "mp_terrace", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_venus_fog_hdr::SetupFog( );
else
maps\createart\mp_venus_fog::SetupFog( );
VisionSetNaked( "mp_venus", 0 );
}

View File

@ -0,0 +1,13 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
if (IsUsingHDR())
maps\createart\mp_vlobby_room_fog_hdr::SetupFog( );
else
maps\createart\mp_vlobby_room_fog::SetupFog( );
VisionSetNaked( "mp_vlobby_room", 0 );
}

291
raw/maps/mp/_adrenaline.gsc Normal file
View File

@ -0,0 +1,291 @@
/*
Exo Overclock
Author: Keith Evans
Description: A piece of equipment used to give you temporarily increased speed
*/
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
#include maps\mp\gametypes\_hostmigration;
#include maps\mp\perks\_perkfunctions;
#include maps\mp\_snd_common_mp;
CONST_Adrenaline_SpeedScale = 1.12;
CONST_Adrenaline_Timeout = 10;
watchAdrenalineUsage() // self = player
{
self notify( "exo_overclock_taken" ); // Cleans up existing Exo Overclock threads.
level endon( "game_ended" );
self endon( "death" );
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "faux_spawn" );
self endon( "exo_overclock_taken" );
if ( !self HasWeapon( "adrenaline_mp" ) )
return;
self AdrenalineInit();
self thread MonitorPlayerDeath();
self thread wait_for_game_end();
while ( 1 )
{
self waittill( "exo_adrenaline_fire" );
if( !IsAlive( self ) )
return;
self thread tryUseAdrenaline();
}
}
AdrenalineInit()
{
self.overclock_on = false;
self BatterySetDischargeScale( "adrenaline_mp", 1.0 );
full_energy = self BatteryGetSize( "adrenaline_mp" );
if ( self GetTacticalWeapon() == "adrenaline_mp" )
{
self SetClientOmnvar( "exo_ability_nrg_req0", 0 );
self SetClientOmnvar( "exo_ability_nrg_total0", full_energy );
self SetClientOmnvar( "ui_exo_battery_level0", full_energy );
}
else if ( self GetLethalWeapon() == "adrenaline_mp" )
{
self SetClientOmnvar( "exo_ability_nrg_req1", 0 );
self SetClientOmnvar( "exo_ability_nrg_total1", full_energy );
self SetClientOmnvar( "ui_exo_battery_level1", full_energy );
}
if ( !IsDefined( level.exo_overclock_vfx_le_active ) )
level.exo_overclock_vfx_le_active = LoadFX( "vfx/lights/exo_overclock_hip_le_start" );
if ( !IsDefined( level.exo_overclock_vfx_ri_active ) )
level.exo_overclock_vfx_ri_active = LoadFX( "vfx/lights/exo_overclock_hip_ri_start" );
if ( !IsDefined( level.exo_overclock_vfx_le_inactive ) )
level.exo_overclock_vfx_le_inactive = LoadFX( "vfx/lights/exo_overclock_hip_le_inactive" );
if ( !IsDefined( level.exo_overclock_vfx_ri_inactive ) )
level.exo_overclock_vfx_ri_inactive = LoadFX( "vfx/lights/exo_overclock_hip_ri_inactive" );
wait( 0.05 );
if ( !inVirtualLobby() )
{
//turn on fx for inactive exo overclock
PlayFXOnTag( level.exo_overclock_vfx_le_inactive, self, "J_Hip_LE" );
PlayFXOnTag( level.exo_overclock_vfx_ri_inactive, self, "J_Hip_RI" );
}
}
tryUseAdrenaline( ) // self == player
{
self endon( "exo_overclock_taken" );
if ( self.overclock_on == true )
{
self thread StopAdrenaline( true );
}
else
{
self thread StartAdrenaline();
}
}
killOverclockFx() // self == player
{
if ( IsDefined( self.overclock_fx_l ) )
{
self.overclock_fx_l delete();
self.overclock_fx_l = undefined;
}
if ( IsDefined( self.overclock_fx_r ) )
{
self.overclock_fx_r delete();
self.overclock_fx_r = undefined;
}
}
StartAdrenaline() //self == player
{
self endon( "death" );
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "faux_spawn" );
self endon( "exo_overclock_taken" );
self endon( "EndAdrenaline" );
self.overclock_on = true;
// Need to handle this here because Exo Overclock is not processed like a grenade as other Exo Abilities are.
maps\mp\gametypes\_gamelogic::setHasDoneCombat( self, true );
self.adrenaline_speed_scalar = CONST_Adrenaline_SpeedScale;
if ( self _hasPerk( "specialty_lightweight" ) )
{
// lightWeightScalar() does not return the percent speed boost from lightweight but the full scalar, hence the -1.
self.moveSpeedScaler = self.adrenaline_speed_scalar + ( lightWeightScalar() - 1 );
}
else
{
self.moveSpeedScaler = self.adrenaline_speed_scalar;
}
//for coop - set movespeed to be based of the class setting
if ( isdefined ( level.isHorde ) && level.isHorde )
{
class = self GetClientOmnvar ( "ui_horde_player_class" );
self.moveSpeedScaler = min ( ( level.classSettings[class]["speed"] + 0.25 ), CONST_Adrenaline_SpeedScale );
}
self maps\mp\gametypes\_weapons::updateMoveSpeedScale();
self BatteryDischargeBegin( "adrenaline_mp" );
self maps\mp\_exo_battery::set_exo_ability_hud_omnvar( "adrenaline_mp", "ui_exo_battery_toggle", 1 );
self thread maps\mp\_exo_battery::update_exo_battery_hud( "adrenaline_mp" );
self thread monitor_overclock_battery_charge();
// activation sound
self snd_message( "mp_exo_overclock_activate" );
// vfx
self killOverclockFx();
wait( 0.05 );
if ( !self.overclock_on ) //turned off during wait?
return;
if ( !IsDefined( self.exo_cloak_on ) || self.exo_cloak_on == false )
{
self.overclock_fx_l = SpawnLinkedFx( level.exo_overclock_vfx_le_active, self, "J_Hip_LE" );
self.overclock_fx_r = SpawnLinkedFx( level.exo_overclock_vfx_ri_active, self, "J_Hip_RI" );
TriggerFX( self.overclock_fx_l );
TriggerFX( self.overclock_fx_r );
}
//jwells - overlay VFX handled in code so killcam will work
}
StopAdrenaline( should_play_fx ) // self = player
{
if ( !isDefined( self.overclock_on ) || !self.overclock_on )
return;
if ( !IsDefined( should_play_fx ) )
{
should_play_fx = true;
}
self notify( "EndAdrenaline" );
self.overclock_on = false;
if ( self _hasPerk( "specialty_lightweight" ) )
{
self.moveSpeedScaler = lightWeightScalar();
}
else
{
self.moveSpeedScaler = level.basePlayerMoveScale;
}
//for coop - set movespeed back to the class setting
if ( isdefined ( level.isHorde ) && level.isHorde )
{
class = self GetClientOmnvar ( "ui_horde_player_class" );
self.moveSpeedScaler = level.classSettings[class]["speed"];
}
self maps\mp\gametypes\_weapons::updateMoveSpeedScale();
self.adrenaline_speed_scalar = undefined;
self BatteryDischargeEnd( "adrenaline_mp" );
self maps\mp\_exo_battery::set_exo_ability_hud_omnvar( "adrenaline_mp", "ui_exo_battery_toggle", 0 );
self killOverclockFx();
if ( should_play_fx == true )
{
// deactivation sound
self snd_message( "mp_exo_overclock_deactivate" );
wait( 0.05 );
if ( !IsDefined( self.exo_cloak_on ) || self.exo_cloak_on == false )
{
self.overclock_fx_l = SpawnLinkedFx( level.exo_overclock_vfx_le_inactive, self, "J_Hip_LE" );
self.overclock_fx_r = SpawnLinkedFx( level.exo_overclock_vfx_ri_inactive, self, "J_Hip_RI" );
TriggerFX( self.overclock_fx_l );
TriggerFX( self.overclock_fx_r );
}
}
//jwells - overlay VFX handled in code so killcam will work
}
MonitorPlayerDeath()
{
self endon( "disconnect" );
self waittill_any( "death", "joined_team", "faux_spawn", "exo_overclock_taken" );
self thread StopAdrenaline( false );
}
monitor_overclock_battery_charge() // self = player
{
self endon( "death" );
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "faux_spawn" );
self endon( "exo_overclock_taken" );
self endon( "EndAdrenaline" );
while ( self.overclock_on == true )
{
if ( self BatteryGetCharge( "adrenaline_mp" ) <= 0 )
{
thread StopAdrenaline( true );
}
wait( 0.05 );
}
}
take_exo_overclock() //self = player
{
self notify( "kill_battery" );
self notify( "exo_overclock_taken" );
self takeWeapon( "adrenaline_mp" );
}
give_exo_overclock() //self = player
{
self giveWeapon( "adrenaline_mp" );
self thread watchAdrenalineUsage();
}
wait_for_game_end() // self = player
{
self endon( "death" );
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "faux_spawn" );
self endon( "exo_overclock_taken" );
level waittill( "game_ended" );
self thread StopAdrenaline( false );
}

View File

@ -0,0 +1,596 @@
#include common_scripts\utility;
#include maps\mp\_utility;
SCR_CONST_AERIAL_PATHNODE_OFFSET_DEFAULT = 500;
SCR_CONST_AERIAL_PATHNODE_GROUP_CONNECT_DIST_DEFAULT = 250;
SCR_CONST_AERIAL_PATHNODE_MAX_GROUP_CONNECTIONS = 3;
SCR_CONST_DEBUG_DONT_CONNECT_GROUPS = false;
SCR_CONST_DEBUG_SHOW_NODE_GROUPS = false;
SCR_CONST_DEBUG_SHOW_ADDED_LINKS = false;
waittill_aerial_pathnodes_calculated()
{
while(!IsDefined(level.calculated_aerial_nodes_done) || !level.calculated_aerial_nodes_done)
wait(0.5);
}
get_aerial_offset()
{
if ( IsDefined(level.aerial_pathnode_offset) )
return (0,0,level.aerial_pathnode_offset);
else
return (0,0,SCR_CONST_AERIAL_PATHNODE_OFFSET_DEFAULT);
}
get_group_connect_dist()
{
if ( IsDefined(level.aerial_pathnode_group_connect_dist) )
{
if ( level.nextgen )
Assert(level.aerial_pathnode_group_connect_dist <= 650);
else
Assert(level.aerial_pathnode_group_connect_dist <= 500);
return level.aerial_pathnode_group_connect_dist;
}
else
{
return SCR_CONST_AERIAL_PATHNODE_GROUP_CONNECT_DIST_DEFAULT;
}
}
node_is_valid__to_convert_to_aerial_pathnode( node )
{
return (node.type == "Path" && NodeExposedToSky( node, true ) && !node NodeIsDisconnected() );
}
calculate_aerial_pathnodes()
{
if ( IsDefined(level.calculated_aerial_nodes_in_progress) || IsDefined(level.calculated_aerial_nodes_done) )
return;
mapname = GetDvar( "mapname" );
if ( mapname == getdvar( "virtualLobbyMap") || mapname == "mp_character_room" || GetDvarInt( "virtualLobbyActive" ) == 1 )
return;
level.calculated_aerial_nodes_in_progress = true;
level.calculated_aerial_nodes_done = false;
wait(0.5);
/#
SetDevDvarIfUninitialized("ai_showNodesAerial", 0);
#/
// First make a list of all aerial nodes and their aerial neighbors
level.aerial_pathnodes = [];
all_nodes = GetAllNodes();
foreach( node in all_nodes )
{
if ( node_is_valid__to_convert_to_aerial_pathnode(node) )
{
level.aerial_pathnodes[level.aerial_pathnodes.size] = node;
if ( !IsDefined(node.aerial_neighbors) )
node.aerial_neighbors = [];
neighbors = GetLinkedNodes(node);
foreach( neighbor_node in neighbors )
{
if ( node_is_valid__to_convert_to_aerial_pathnode(neighbor_node) && !array_contains(node.aerial_neighbors, neighbor_node) )
{
node.aerial_neighbors[node.aerial_neighbors.size] = neighbor_node;
// To handle the case of one-way links, we make sure to add the link to the neighbor back to this node (in case that node doesn't have it)
if ( !IsDefined(neighbor_node.aerial_neighbors) )
neighbor_node.aerial_neighbors = [];
if ( !array_contains(neighbor_node.aerial_neighbors, node) )
neighbor_node.aerial_neighbors[neighbor_node.aerial_neighbors.size] = node;
}
}
}
}
all_nodes = undefined;
wait(0.05);
// Next divide the nodes into disjoint sets
node_groups = divide_nodes_into_groups( level.aerial_pathnodes, 1 );
max_group_connections = SCR_CONST_AERIAL_PATHNODE_MAX_GROUP_CONNECTIONS;
if ( !SCR_CONST_DEBUG_DONT_CONNECT_GROUPS )
{
// See if we can connect some of these disjoint sets
close_dist = get_group_connect_dist();
potential_aerial_neighbor_nodes = [];
aerial_nodes_processed = 0;
for( i=0; i<node_groups.size; i++ )
{
if ( !IsDefined( potential_aerial_neighbor_nodes[i] ) )
potential_aerial_neighbor_nodes[i] = [];
foreach( node in node_groups[i] )
{
for( j=i+1; j<node_groups.size; j++ )
{
if ( !IsDefined( potential_aerial_neighbor_nodes[i][j] ) )
potential_aerial_neighbor_nodes[i][j] = [];
potential_neighbors_node_in_i_to_group_j = [];
foreach( other_node in node_groups[j] )
{
dist = Distance(node.origin,other_node.origin);
within_close_dist = dist < close_dist;
force_connection = false;
if ( !within_close_dist )
{
if ( IsDefined(level.aerial_pathnodes_force_connect) )
{
foreach( override in level.aerial_pathnodes_force_connect)
{
radius_sq = squared(override.radius);
if ( Distance2DSquared(override.origin,node.origin) < radius_sq && Distance2DSquared(override.origin,other_node.origin) < radius_sq )
{
force_connection = true;
break;
}
}
}
}
room_in_array = potential_neighbors_node_in_i_to_group_j.size < max_group_connections || dist < potential_neighbors_node_in_i_to_group_j[max_group_connections-1][2];
if ( within_close_dist && room_in_array )
{
if ( potential_neighbors_node_in_i_to_group_j.size == max_group_connections )
potential_neighbors_node_in_i_to_group_j[max_group_connections-1] = undefined;
potential_neighbors_node_in_i_to_group_j[potential_neighbors_node_in_i_to_group_j.size] = [node,other_node,dist];
potential_neighbors_node_in_i_to_group_j = array_sort_with_func( potential_neighbors_node_in_i_to_group_j, ::is_pair_a_closer_than_pair_b );
}
else if ( force_connection )
{
potential_aerial_neighbor_nodes[i][j][potential_aerial_neighbor_nodes[i][j].size] = [node,other_node,-1];
}
}
foreach( node_pair in potential_neighbors_node_in_i_to_group_j )
potential_aerial_neighbor_nodes[i][j][potential_aerial_neighbor_nodes[i][j].size] = node_pair;
}
aerial_nodes_processed++;
if ( aerial_nodes_processed >= 50 )
{
aerial_nodes_processed = 0;
wait(0.05);
}
}
}
// Now sort the array of potential aerial neighbors, so we can check the closest pairs first
wait(0.05);
num_sorted = 0;
for( i=0; i<node_groups.size; i++ )
{
for( j=i+1; j<node_groups.size; j++ )
{
num_sorted += potential_aerial_neighbor_nodes[i][j].size;
potential_aerial_neighbor_nodes[i][j] = array_sort_with_func( potential_aerial_neighbor_nodes[i][j], ::is_pair_a_closer_than_pair_b, 150 );
if ( num_sorted > 500 )
{
wait(0.05);
num_sorted = 0;
}
}
}
wait(0.05);
// Now iterate through potential_aerial_neighbor_nodes doing traces. If they succeed, the nodes are added to each others' neighbor lists
aerial_offset = get_aerial_offset();
increment = 10;
num_traces = 0;
if ( SCR_CONST_DEBUG_SHOW_ADDED_LINKS )
level.added_aerial_links = [];
for( i=0; i<node_groups.size; i++ )
{
for( j=i+1; j<node_groups.size; j++ )
{
foreach ( pair in potential_aerial_neighbor_nodes[i][j] )
{
node0 = pair[0];
node1 = pair[1];
if ( !node0_has_neighbor_connected_to_node1(node0, node1) )
{
connections_0_to_group_1 = num_node_connections_to_group(node0,node1.aerial_group);
connections_1_to_group_0 = num_node_connections_to_group(node1,node0.aerial_group);
if ( connections_0_to_group_1 < max_group_connections && connections_1_to_group_0 < max_group_connections )
{
hitPos = PlayerPhysicsTrace( node0.origin + aerial_offset, node1.origin + aerial_offset );
num_traces++;
trace_succeeded = DistanceSquared( hitPos, node1.origin + aerial_offset ) < 1;
if ( !trace_succeeded && pair[2] == -1 )
{
// This is a force pair, so try another trace
trace_succeeded = BulletTracePassed( node0.origin + aerial_offset, node1.origin + aerial_offset, false, undefined );
}
if ( trace_succeeded )
{
Assert(!array_contains(node0.aerial_neighbors,node1));
node0.aerial_neighbors[node0.aerial_neighbors.size] = node1;
Assert(!array_contains(node1.aerial_neighbors,node0));
node1.aerial_neighbors[node1.aerial_neighbors.size] = node0;
if ( SCR_CONST_DEBUG_SHOW_ADDED_LINKS )
level.added_aerial_links[level.added_aerial_links.size] = [node0,node1];
}
if ( (num_traces % increment) == 0 )
wait(0.05);
}
}
}
}
}
potential_aerial_neighbor_nodes = undefined;
// Finally try to divide the nodes again, and then discard any remaining orphaned groups (small collections of nodes that have no links to anything else)
node_groups = divide_nodes_into_groups( level.aerial_pathnodes );
if ( SCR_CONST_DEBUG_SHOW_NODE_GROUPS )
{
// Sort the groups into largest to smallest, for consistent group coloring
node_groups = array_sort_with_func( node_groups, ::is_group_a_larger_than_group_b );
for( i=0; i<node_groups.size; i++ )
{
foreach( node in node_groups[i] )
node.aerial_group = i;
}
}
else
{
// Don't need to keep aerial_group stored on each pathnode anymore
foreach( node in level.aerial_pathnodes )
node.aerial_group = undefined;
}
largest_group_size = 0;
for ( i=0; i<node_groups.size; i++ )
{
largest_group_size = max(node_groups[i].size, largest_group_size);
}
Assert( level.aerial_pathnodes.size < 40 || largest_group_size > 20 ); // Assert that either we have a small number of aerial nodes, or there's at least one large group of them
for ( i=0; i<node_groups.size; i++ )
{
if ( node_groups[i].size < 0.1 * largest_group_size )
{
foreach( node in node_groups[i] )
{
// Remove the node from the aerial pathnode list
level.aerial_pathnodes = array_remove( level.aerial_pathnodes, node );
// For each neighbor, find the link back to this node and sever it
foreach( neighbor_node in node.aerial_neighbors )
{
for( j=0; j<neighbor_node.aerial_neighbors.size; j++ )
{
neighbor_node_neighbor = neighbor_node.aerial_neighbors[j];
if ( neighbor_node_neighbor == node )
{
neighbor_node.aerial_neighbors[j] = neighbor_node.aerial_neighbors[neighbor_node.aerial_neighbors.size-1];
neighbor_node.aerial_neighbors[neighbor_node.aerial_neighbors.size-1] = undefined;
j--;
}
}
}
// Now clear out all of this node's neighbors
node.aerial_neighbors = undefined;
}
}
}
}
level.calculated_aerial_nodes_done = true;
level.calculated_aerial_nodes_in_progress = false;
/#
thread draw_debug_aerial_nodes();
#/
}
is_group_a_larger_than_group_b( a, b )
{
return ( a.size > b.size );
}
is_pair_a_closer_than_pair_b( a, b )
{
return ( a[2] < b[2] );
}
num_node_connections_to_group( node0, group_index )
{
connections = 0;
foreach( neighbor in node0.aerial_neighbors )
{
if ( neighbor.aerial_group == group_index )
connections++;
}
return connections;
}
node0_has_neighbor_connected_to_node1( node0, node1 )
{
foreach( neighbor in node0.aerial_neighbors )
{
foreach( neighbor_neighbor in neighbor.aerial_neighbors )
{
if ( neighbor_neighbor == node1 )
return true;
}
}
return false;
}
divide_nodes_into_groups( nodes, ignore_size )
{
if ( !IsDefined(ignore_size) )
ignore_size = 0; // Ignore any groups with this size or less
foreach( node in nodes )
node.aerial_group = undefined;
temp_aerial_nodes = nodes;
node_groups = [];
while( temp_aerial_nodes.size > 0 ) // While there's still nodes to process
{
current_index = node_groups.size;
node_groups[current_index] = [];
temp_aerial_nodes[0].aerial_group = -1; // -1 for group means the node is waiting to be processed by the search
open_nodes = [temp_aerial_nodes[0]];
open_nodes_processed_for_this_group = 0;
while( open_nodes.size > 0 )
{
// Add the current open node to the list, and mark its group
current_open_node = open_nodes[0];
node_groups[current_index][node_groups[current_index].size] = current_open_node;
Assert(!IsDefined(current_open_node.aerial_group) || current_open_node.aerial_group == -1);
current_open_node.aerial_group = current_index;
// Then remove it and add its undiscovered neighbors (since they are part of the same group)
open_nodes[0] = open_nodes[open_nodes.size-1];
open_nodes[open_nodes.size-1] = undefined;
foreach( neighbor_node in current_open_node.aerial_neighbors )
{
if ( !IsDefined(neighbor_node.aerial_group) )
{
neighbor_node.aerial_group = -1;
open_nodes[open_nodes.size] = neighbor_node;
}
}
// Finally remove it from the temp array since it has been processed
for( i = 0; i < temp_aerial_nodes.size; i++ )
{
if ( temp_aerial_nodes[i] == current_open_node )
{
temp_aerial_nodes[i] = temp_aerial_nodes[temp_aerial_nodes.size-1];
temp_aerial_nodes[temp_aerial_nodes.size-1] = undefined;
break;
}
}
open_nodes_processed_for_this_group++;
if ( open_nodes_processed_for_this_group > 100 )
{
wait(0.05); // Wait a frame if we've processed a ton of open nodes in a single group
open_nodes_processed_for_this_group = 0;
}
}
if ( node_groups[current_index].size <= ignore_size )
{
node_groups[current_index] = undefined;
}
else
{
wait(0.05);
}
}
wait(0.05);
return node_groups;
}
/#
should_draw_for_node( node, max_dist_sq, player_origin, player_angles, player_fov )
{
if ( Distance2DSquared(player_origin,node.origin) > max_dist_sq )
return false;
if ( !within_fov(player_origin, player_angles, (node.origin+get_aerial_offset()), player_fov) )
return false;
return true;
}
draw_debug_aerial_nodes()
{
self notify("bot_draw_debug_aerial_nodes");
self endon("bot_draw_debug_aerial_nodes");
level endon("teleport_to_zone");
node_colors = [ (0,1,1), (0,1,0), (0,0,1), (1,0,1), (1,1,0), (1,0,0), (1,0.6,0.6), (0.6,1,0.6), (0.6,0.6,1), (0.1,0.1,0.1) ];
draw_time = 0.5;
while(1)
{
ai_showNodesAerial = GetDvar( "ai_showNodesAerial" );
if ( ai_showNodesAerial == "1" || ai_showNodesAerial == "2" )
{
max_dist_sq = squared(GetDvarFloat("ai_ShowNodesDist"));
player = maps\mp\gametypes\_dev::getNotBot();
aerial_offset = get_aerial_offset();
if ( IsDefined(player) && max_dist_sq > 0 )
{
if ( IsDefined(level.aerial_pathnodes_force_connect) )
{
foreach( override in level.aerial_pathnodes_force_connect )
maps\mp\bots\_bots_util::bot_draw_cylinder( override.origin - (0,0,500), override.radius, 1000, draw_time, undefined, (1,0,0), true, 20 );
}
player_origin = player GetViewOrigin();
player_angles = player GetPlayerAngles();
fov = cos( 85 * 0.5 );
current_nodes = level.aerial_pathnodes;
for ( i = 0; i < current_nodes.size; i++ )
{
if ( should_draw_for_node(current_nodes[i], max_dist_sq, player_origin, player_angles, fov) )
{
if ( SCR_CONST_DEBUG_SHOW_NODE_GROUPS )
{
color_index = current_nodes[i].aerial_group % 10;
color = node_colors[color_index];
}
else
{
color = (0,1,1);
}
if ( ai_showNodesAerial == "2" )
{
maps\mp\bots\_bots_util::bot_draw_cylinder(current_nodes[i].origin - (0,0,5) + aerial_offset, 10, 12, draw_time, undefined, color, true, 4);
}
else
{
foreach( neighbor_node in current_nodes[i].aerial_neighbors )
{
// Neighbor node is valid and has not been visited yet, so draw a line to it
if ( array_contains(current_nodes,neighbor_node) )
{
if ( SCR_CONST_DEBUG_SHOW_ADDED_LINKS && !SCR_CONST_DEBUG_DONT_CONNECT_GROUPS )
{
foreach( node_pair in level.added_aerial_links )
{
if ( node_pair[0] == current_nodes[i] && node_pair[1] == neighbor_node || node_pair[0] == neighbor_node && node_pair[1] == current_nodes[i] )
{
color = (1,0,0);
break;
}
}
}
line( current_nodes[i].origin + aerial_offset, neighbor_node.origin + aerial_offset, color, 1.0, true, INT(draw_time * 20) );
}
}
}
// Once we've gone through all the neighbor nodes, remove this node from the list (so we don't get double lines)
current_nodes[i] = current_nodes[current_nodes.size-1];
current_nodes[current_nodes.size-1] = undefined;
i--;
}
}
}
}
wait(draw_time);
}
}
#/
/*
=============
///ScriptDocBegin
"Name: node_is_aerial(<node>)"
"Summary: Returns true if this node is an aerial node"
"MandatoryArg: <node> : The node to check"
"Example: if ( node_is_aerial(node1) )"
///ScriptDocEnd
============
*/
node_is_aerial( node )
{
return IsDefined(node.aerial_neighbors);
}
/*
=============
///ScriptDocBegin
"Name: get_ent_closest_aerial_node(<max_radius>, <min_radius>)"
"Summary: Finds the closest aerial node to the given entity"
"CallOn: An entity"
"OptionalArg: <max_radius> : Maximum distance to search"
"OptionalArg: <min_radius> : Minimum distance to search"
"Example: closest_node = self get_closest_aerial_node();"
///ScriptDocEnd
============
*/
get_ent_closest_aerial_node( max_radius, min_radius )
{
if ( !IsDefined(max_radius) )
max_radius = 1500;
if ( !IsDefined(min_radius) )
min_radius = 0;
nodes = GetNodesInRadiusSorted( self.origin, max_radius, min_radius, get_aerial_offset()[2] * 2, "path" );
for( i=0; i<nodes.size; i++ )
{
if ( node_is_aerial(nodes[i]) )
return nodes[i];
}
}
/*
=============
///ScriptDocBegin
"Name: find_path_between_aerial_nodes(<node_start>, <node_end>)"
"Summary: Finds a (potentially non-optimal) path between the aerial start and end nodes"
"MandatoryArg: <node_start> : The start node"
"MandatoryArg: <node_end> : The end node"
"Example: path = find_path_between_aerial_nodes(node1, node2);"
///ScriptDocEnd
============
*/
find_path_between_aerial_nodes( node_start, node_end )
{
Assert( node_is_aerial(node_start) );
Assert( node_is_aerial(node_end) );
node_start.path_to_this_node = [];
node_queue = [node_start];
all_nodes_explored = [node_start];
while(!IsDefined(node_end.path_to_this_node))
{
current_node = node_queue[0];
node_queue = array_remove(node_queue,current_node);
foreach( neighbor_node in current_node.aerial_neighbors )
{
if ( !IsDefined(neighbor_node.path_to_this_node) )
{
neighbor_node.path_to_this_node = array_add(current_node.path_to_this_node,current_node);
node_queue[node_queue.size] = neighbor_node;
all_nodes_explored[all_nodes_explored.size] = neighbor_node;
}
}
}
path = array_add(node_end.path_to_this_node,node_end);
foreach( node in all_nodes_explored )
node.path_to_this_node = undefined;
return path;
}

View File

@ -0,0 +1,64 @@
#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( animated_models, ::animateModel );
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 ];
}
//wait( RandomFloatRange( 0, 5 ) ); // TODO: get a way to play animations at random starting points
self ScriptModelPlayAnim( animation );
self willNeverChange();
}

98
raw/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 );
}
}

829
raw/maps/mp/_art.gsc Normal file
View File

@ -0,0 +1,829 @@
// 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;
main()
{
if ( !isDefined( level.dofDefault ) )
{
//These values match what the code is setting ClientSpawn
level.dofDefault[ "nearStart" ] = 0;
level.dofDefault[ "nearEnd" ] = 0;
level.dofDefault[ "farStart" ] = 0;
level.dofDefault[ "farEnd" ] = 0;
level.dofDefault[ "nearBlur" ] = 6;
level.dofDefault[ "farBlur" ] = 1.8;
}
/$
if ( !isdefined( level.script ) )
level.script = ToLower( GetDvar( "mapname" ) );
setDevDvarIfUninitialized( "scr_art_tweak", 0 );
setDevDvarIfUninitialized( "scr_dof_enable", "1" );
setDevDvarIfUninitialized( "scr_cmd_plr_sun", "0" );
setDevDvarIfUninitialized( "scr_cmd_plr_sun_atmos_fog", "0" );
setDevDvarIfUninitialized( "scr_cinematic_autofocus", "1" );
setDevDvarIfUninitialized( "scr_art_visionfile", level.script );
level.curDoF = ( level.dofDefault[ "farStart" ] - level.dofDefault[ "nearEnd" ] ) / 2;
level._clearalltextafterhudelem = false;
level.buttons = [];
if( !isdefined( level.vision_set_vision ) )
{
level.vision_set_vision = [];
}
if ( !isdefined( level.vision_set_transition_ent ) )
{
level.vision_set_transition_ent = SpawnStruct();
level.vision_set_transition_ent.vision_set = level.script;
level.vision_set_transition_ent.time = 0;
}
thread tweaklightset();
thread tweakart();
$/
}
setup_fog_tweak()
{
/$
if( !isdefined( level.vision_set_fog ) )
{
level.vision_set_fog = [];
if (isdefined(level._art_fog_setup))
[[level._art_fog_setup]]();
construct_vision_set( "" ); // so we always have an entry for the default case
construct_vision_set( level.script );
set_fog( level.script );
common_scripts\_artCommon::setfogsliders();
}
$/
}
initTweaks()
{
/$
setup_fog_tweak();
// create new vision sets for those triggers that aren't yet hooked up
construct_vision_ents();
if ( !IsDefined( level.vision_set_names ) )
level.vision_set_names = [];
// Add existing vision sets for any fog that's been created thus far
foreach( key, value in level.vision_set_fog )
{
common_scripts\_artCommon::add_vision_set_to_list( key );
}
add_vision_sets_from_triggers();
hud_init();
playerInit();
level.players[0] VisionSetNakedForPlayer( level.script, 0 ); // to disable clientside visionsets, so the script based fog is active
$/
}
tweaklightset()
{
/$
SetDevDvar( "scr_lightset_dump", "0" );
for ( ;; )
{
if ( GetDvarInt( "scr_lightset_dump" ) != 0 )
{
SetDevDvar( "scr_lightset_dump", "0" );
common_scripts\_artCommon::print_lightset( get_lightset_filename() );
}
wait .05;
}
$/
}
tweakart()
{
/$
if ( !isdefined( level.tweakfile ) )
level.tweakfile = false;
// not in DEVGUI
SetDevDvar( "scr_fog_fraction", "1.0" );
SetDevDvar( "scr_art_dump", "0" );
// update the devgui variables to current settings
SetDevDvar( "scr_dof_nearStart", level.dofDefault[ "nearStart" ] );
SetDevDvar( "scr_dof_nearEnd", level.dofDefault[ "nearEnd" ] );
SetDevDvar( "scr_dof_farStart", level.dofDefault[ "farStart" ] );
SetDevDvar( "scr_dof_farEnd", level.dofDefault[ "farEnd" ] );
SetDevDvar( "scr_dof_nearBlur", level.dofDefault[ "nearBlur" ] );
SetDevDvar( "scr_dof_farBlur", level.dofDefault[ "farBlur" ] );
// not in DEVGUI
level.fogfraction = 1.0;
file = undefined;
filename = undefined;
last_vision_set = "";
inited = false;
for ( ;; )
{
while ( GetDvarInt( "scr_art_tweak", 0 ) == 0 )
{
AssertEx( GetDvarInt( "scr_art_dump", 0 ) == 0, "Must Enable Art Tweaks to export _art file." );
wait .05;
if ( ! GetDvarInt( "scr_art_tweak", 0 ) == 0 )
common_scripts\_artCommon::setfogsliders();// sets the sliders to whatever the current fog value is
}
if ( GetDvarInt( "scr_art_tweak_message" ) )
{
SetDevDvar( "scr_art_tweak_message", "0" );
IPrintLnBold( "ART TWEAK ENABLED" );
}
if ( !inited )
{
inited = true;
initTweaks();
}
//translate the slider values to script variables
common_scripts\_artCommon::translateFogSlidersToScript();
// dofvarupdate();
// catch all those cases where a slider can be pushed to a place of conflict
fovslidercheck();
common_scripts\_artCommon::fogslidercheck();
dump = dumpsettings();// dumps and returns true if the dump dvar is set
updateFogEntFromScript();
if ( getdvarint( "scr_select_art_next" ) || button_down( "dpad_up", "kp_uparrow" ) )
setgroup_down();
else if ( getdvarint( "scr_select_art_prev" ) || button_down( "dpad_down", "kp_downarrow" ) )
setgroup_up();
else if( level.vision_set_transition_ent.vision_set != last_vision_set )
{
last_vision_set = level.vision_set_transition_ent.vision_set;
setcurrentgroup( last_vision_set );
}
// level.player setDefaultDepthOfField();
if ( dump )
{
IPrintLnBold( "Art settings dumped success!" );
SetdevDvar( "scr_art_dump", "0" );
}
wait .1;
}
$/
}
fovslidercheck()
{
/$
// catch all those cases where a slider can be pushed to a place of conflict
if ( level.dofDefault[ "nearStart" ] >= level.dofDefault[ "nearEnd" ] )
{
level.dofDefault[ "nearStart" ] = level.dofDefault[ "nearEnd" ] - 1;
SetDevDvar( "scr_dof_nearStart", level.dofDefault[ "nearStart" ] );
}
if ( level.dofDefault[ "nearEnd" ] <= level.dofDefault[ "nearStart" ] )
{
level.dofDefault[ "nearEnd" ] = level.dofDefault[ "nearStart" ] + 1;
SetDevDvar( "scr_dof_nearEnd", level.dofDefault[ "nearEnd" ] );
}
if ( level.dofDefault[ "farStart" ] >= level.dofDefault[ "farEnd" ] )
{
level.dofDefault[ "farStart" ] = level.dofDefault[ "farEnd" ] - 1;
SetDevDvar( "scr_dof_farStart", level.dofDefault[ "farStart" ] );
}
if ( level.dofDefault[ "farEnd" ] <= level.dofDefault[ "farStart" ] )
{
level.dofDefault[ "farEnd" ] = level.dofDefault[ "farStart" ] + 1;
SetDevDvar( "scr_dof_farEnd", level.dofDefault[ "farEnd" ] );
}
if ( level.dofDefault[ "farBlur" ] >= level.dofDefault[ "nearBlur" ] )
{
level.dofDefault[ "farBlur" ] = level.dofDefault[ "nearBlur" ] - .1;
SetDevDvar( "scr_dof_farBlur", level.dofDefault[ "farBlur" ] );
}
if ( level.dofDefault[ "farStart" ] <= level.dofDefault[ "nearEnd" ] )
{
level.dofDefault[ "farStart" ] = level.dofDefault[ "nearEnd" ] + 1;
SetDevDvar( "scr_dof_farStart", level.dofDefault[ "farStart" ] );
}
$/
}
// updateFogEntFromScript()
// NOTE: This has moved to _artCommon.gsc
construct_vision_ents()
{
if( !isdefined( level.vision_set_fog ))
level.vision_set_fog = [];
trigger_multiple_visionsets = GetEntArray( "trigger_multiple_visionset" , "classname" );
foreach( trigger in trigger_multiple_visionsets )
{
if( IsDefined( trigger.script_visionset ) )
{
construct_vision_set( trigger.script_visionset );
}
if ( IsDefined( trigger.script_visionset_start ) )
{
construct_vision_set( trigger.script_visionset_start );
}
if ( IsDefined( trigger.script_visionset_end ) )
{
construct_vision_set( trigger.script_visionset_end );
}
}
}
construct_vision_set( vision_set )
{
if ( IsDefined( level.vision_set_fog[ vision_set ] ) )
{
return;
}
create_default_vision_set_fog( vision_set );
create_vision_set_vision( vision_set );
IPrintLnBold( "new vision: " + vision_set );
}
create_vision_set_vision( vision )
{
if ( !isdefined( level.vision_set_vision ) )
level.vision_set_vision = [];
ent = SpawnStruct();
ent.name = vision;
level.vision_set_vision[ vision ] = ent;
return ent;
}
add_vision_sets_from_triggers()
{
/$
assert( IsDefined( level.vision_set_fog ) );
triggers = GetEntArray( "trigger_multiple_visionset" , "classname" );
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 );
$/
}
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;
ent.heightFogEnabled = 0;
ent.heightFogBaseHeight = 0;
ent.heightFogHalfPlaneDistance = 1000;
}
create_vision_set_fog( fogset )
{
if ( !isdefined( level.vision_set_fog ) )
level.vision_set_fog = [];
ent = SpawnStruct();
ent.name = fogset;
/* // Use HDRColorIntensity/HDRSunColorIntensity existence to determine the space of the color values.
// 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;
ent.heightFogEnabled = 0;
ent.heightFogBaseHeight = 0;
ent.heightFogHalfPlaneDistance = 1000;
level.vision_set_fog[ ToLower(fogset) ] = ent;
return ent;
}
set_fog( fogname, transition_time )
{
level.vision_set_transition_ent.vision_set = fogname;
level.vision_set_transition_ent.time = transition_time;
ent = get_fog(fogname);
if( GetDvarInt( "scr_art_tweak") != 0 )
{
translateEntTosliders(ent );
//pending some mechanism to handle transition while your editting, just set to zero for now since it leaves less room for ugly.
transition_time = 0;
}
set_fog_to_ent_values( ent, transition_time );
}
translateEntTosliders(ent)
{
/$
ConvertLegacyFog( 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 );
SetDevDvar( "scr_heightFogEnabled", ent.heightFogEnabled );
SetDevDvar( "scr_heightFogBaseHeight", ent.heightFogBaseHeight );
SetDevDvar( "scr_heightFogHalfPlaneDistance", ent.heightFogHalfPlaneDistance );
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 );
}
if ( IsDefined( ent.atmosFogEnabled ) )
{
AssertEx( IsDefined( ent.atmosFogSunFogColor ) );
AssertEx( IsDefined( ent.atmosFogHazeColor ) );
AssertEx( IsDefined( ent.atmosFogHazeStrength ) );
AssertEx( IsDefined( ent.atmosFogHazeSpread ) );
AssertEx( IsDefined( ent.atmosFogExtinctionStrength ) );
AssertEx( IsDefined( ent.atmosFogInScatterStrength ) );
AssertEx( IsDefined( ent.atmosFogHalfPlaneDistance ) );
AssertEx( IsDefined( ent.atmosFogStartDistance ) );
AssertEx( IsDefined( ent.atmosFogDistanceScale ) );
AssertEx( IsDefined( ent.atmosFogSkyDistance ) );
AssertEx( IsDefined( ent.atmosFogSkyAngularFalloffEnabled ) );
AssertEx( IsDefined( ent.atmosFogSkyFalloffStartAngle ) );
AssertEx( IsDefined( ent.atmosFogSkyFalloffAngleRange ) );
AssertEx( IsDefined( ent.atmosFogSunDirection ) );
AssertEx( IsDefined( ent.atmosFogHeightFogEnabled ) );
AssertEx( IsDefined( ent.atmosFogHeightFogBaseHeight ) );
AssertEx( IsDefined( ent.atmosFogHeightFogHalfPlaneDistance ) );
SetDevDvar( "scr_atmosFogEnabled", ent.atmosFogEnabled );
SetDevDvar( "scr_atmosFogSunFogColor", ent.atmosFogSunFogColor );
SetDevDvar( "scr_atmosFogHazeColor", ent.atmosFogHazeColor );
SetDevDvar( "scr_atmosFogHazeStrength", ent.atmosFogHazeStrength );
SetDevDvar( "scr_atmosFogHazeSpread", ent.atmosFogHazeSpread );
SetDevDvar( "scr_atmosFogExtinctionStrength", ent.atmosFogExtinctionStrength );
SetDevDvar( "scr_atmosFogInScatterStrength", ent.atmosFogInScatterStrength );
SetDevDvar( "scr_atmosFogHalfPlaneDistance", ent.atmosFogHalfPlaneDistance );
SetDevDvar( "scr_atmosFogStartDistance", ent.atmosFogStartDistance );
SetDevDvar( "scr_atmosFogDistanceScale", ent.atmosFogDistanceScale );
SetDevDvar( "scr_atmosFogSkyDistance", int( ent.atmosFogSkyDistance ) );
SetDevDvar( "scr_atmosFogSkyAngularFalloffEnabled", ent.atmosFogSkyAngularFalloffEnabled );
SetDevDvar( "scr_atmosFogSkyFalloffStartAngle", ent.atmosFogSkyFalloffStartAngle );
SetDevDvar( "scr_atmosFogSkyFalloffAngleRange", ent.atmosFogSkyFalloffAngleRange );
SetDevDvar( "scr_atmosFogSunDirection", ent.atmosFogSunDirection );
SetDevDvar( "scr_atmosFogHeightFogEnabled", ent.atmosFogHeightFogEnabled );
SetDevDvar( "scr_atmosFogHeightFogBaseHeight", ent.atmosFogHeightFogBaseHeight );
SetDevDvar( "scr_atmosFogHeightFogHalfPlaneDistance", ent.atmosFogHeightFogHalfPlaneDistance );
}
else
{
SetDevDvar( "scr_atmosFogEnabled", false );
}
$/
}
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();
level.scripted_elems[ level.scripted_elems.size ] = elem;
return elem;
}
_settext( text )
{
self.realtext = text;
self settext( "_" );
self thread _clearalltextafterhudelem();
sizeofelems = 0;
foreach ( elem in level.scripted_elems )
{
if ( isdefined( elem.realtext ) )
{
sizeofelems += elem.realtext.size;
elem settext( elem.realtext );
}
}
println( "Size of elems: " + sizeofelems );
}
_clearalltextafterhudelem()
{
if (GetDvar("netconststrings_enabled") != "0")
return;
if ( level._clearalltextafterhudelem )
return;
level._clearalltextafterhudelem = true;
self clearalltextafterhudelem();
wait .05;
level._clearalltextafterhudelem = false;
}
setgroup_up()
{
reset_cmds();
index = undefined;
keys = getarraykeys( level.vision_set_fog );
for ( i = 0;i < keys.size;i++ )
if ( keys[ i ] == level.vision_set_transition_ent.vision_set )
{
index = i + 1;
break;
}
if ( index == keys.size )
return;
setcurrentgroup( keys[index] );
}
setgroup_down()
{
reset_cmds();
index = undefined;
keys = getarraykeys( level.vision_set_fog );
for ( i = 0;i < keys.size;i++ )
if ( keys[ i ] == level.vision_set_transition_ent.vision_set )
{
index = i - 1;
break;
}
if ( index < 0 )
return;
setcurrentgroup( keys[index] );
}
reset_cmds()
{
SetDevDvar( "scr_select_art_next", 0 );
SetDevDvar( "scr_select_art_prev", 0 );
}
setcurrentgroup( group )
{
keys = getarraykeys( level.vision_set_fog );
if ( level.currentgen )
{
group_cg = group + "_cg";
index_cg = array_find( keys, group_cg );
if ( IsDefined( index_cg ) )
group = group_cg;
}
level.spam_model_current_group = group;
index = 0;
div = int( level.spam_group_hudelems.size / 2 );
for ( i = 0;i < keys.size;i++ )
if ( keys[ i ] == group )
{
index = i;
break;
}
level.spam_group_hudelems[ div ] _settext( keys[ index ] );
for ( i = 1;i < level.spam_group_hudelems.size - div;i++ )
{
if ( index - i < 0 )
{
level.spam_group_hudelems[ div + i ] _settext( "." );
continue;
}
level.spam_group_hudelems[ div + i ] _settext( keys[ index - i ] );
}
for ( i = 1;i < level.spam_group_hudelems.size - div;i++ )
{
if ( index + i > keys.size - 1 )
{
// -- --
level.spam_group_hudelems[ div - i ] _settext( "." );
continue;
}
level.spam_group_hudelems[ div - i ] _settext( keys[ index + i ] );
}
set_fog( keys[ index ], 0 ) ;
}
get_fog( fogset )
{
if ( !isdefined( level.vision_set_fog ) )
level.vision_set_fog = [];
ent = level.vision_set_fog[ fogset ];
//assertex( IsDefined( ent ), "fog set: " + fogset + "does not exist, use create_fog( " + fogset + " ) in your level_fog.gsc." );
return ent;
}
init_fog_transition()
{
if ( !IsDefined( level.fog_transition_ent ) )
{
level.fog_transition_ent = SpawnStruct();
level.fog_transition_ent.fogset = "";
level.fog_transition_ent.time = 0;
}
}
playerInit()
{
last_vision_set = level.vision_set_transition_ent.vision_set;
//clear these so the vision set will happen.
level.vision_set_transition_ent.vision_set = "";
level.vision_set_transition_ent.time = "";
init_fog_transition();
level.fog_transition_ent.fogset = "";
level.fog_transition_ent.time = "";
setcurrentgroup( last_vision_set );
}
button_down( btn, btn2 )
{
pressed = level.player ButtonPressed( btn );
if ( !pressed )
{
pressed = level.player 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;
}
dumpsettings()
{
/$
if ( ( GetDvarInt( "scr_art_dump" ) == 0 ) )
return false;
dump_art = GetDvarInt( "scr_art_dump" );
SetDevDvar( "scr_art_dump", "0" );
////////////////// _art.gsc
artStartFogFileExport();
fileprint_launcher( "// _createart generated. modify at your own risk. Changing values should be fine." );
fileprint_launcher( "main()" );
fileprint_launcher( "{" );
fileprint_launcher( "" );
fileprint_launcher( "\tlevel.tweakfile = true;" );
fileprint_launcher( " " );
fogpath = "maps\\createart\\" + GetDvar( "scr_art_visionfile" ) + "_fog";
fileprint_launcher( "\tif (IsUsingHDR())" );
fileprint_launcher( "\t\t" + fogpath + "_hdr::SetupFog( );" );
fileprint_launcher( "\telse" );
fileprint_launcher( "\t\t" + fogpath + "::SetupFog( );" );
fileprint_launcher( "\tVisionSetNaked( \"" + level.script + "\", 0 );" );
fileprint_launcher( "" );
fileprint_launcher( "}" );
artEndFogFileExport(); // This actually writes out the _art file
//////////////////////////////
// MP doesn't write [level]_art.csv?
////////////////// _fog.gsc
art_print_fog(); // This is what really writes out the _fog file
//////////////////////////////
////////////////// .vision
// only print the currently selected vision file
if ( dump_art )
{
if ( !common_scripts\_artCommon::print_vision( level.vision_set_transition_ent.vision_set ) )
return false;
}
//////////////////////////////
IPrintLnBold( "ART DUMPED SUCCESSFULLY" );
return true;
$/
}
//****** Pulled from _artcommon before integration
artStartVisionFileExport()
{
fileprint_launcher_start_file();
}
artEndVisionFileExport()
{
return fileprint_launcher_end_file( "\\share\\raw\\vision\\"+level.script+ ".vision", true );
}
artStartFogFileExport()
{
fileprint_launcher_start_file();
}
artEndFogFileExport()
{
return fileprint_launcher_end_file( "\\share\\raw\\maps\\createart\\"+level.script+ "_art.gsc", true );
}
artfxprintlnFog()
{
fileprint_launcher( "" );
fileprint_launcher( "\t//* Fog section * " );
fileprint_launcher( "" );
fileprint_launcher( "\tsetDevDvar( \"scr_fog_disable\"" + ", " + "\"" + GetDvarInt( "scr_fog_disable" ) + "\"" + " );" );
fileprint_launcher( "" );
fileprint_launcher( "\t/$" );
if ( IsUsingHDR() )
fileprint_launcher( "\tlevel._art_fog_setup = maps\\createart\\" + level.script + "_fog_hdr::main;" );
else
fileprint_launcher( "\tlevel._art_fog_setup = maps\\createart\\" + level.script + "_fog::main;" );
fileprint_launcher( "\t$/" );
}
//****** End Pulled from _artcommon before integration
art_print_fog()
{
/$
default_name = get_template_level();
fileprint_launcher_start_file();
fileprint_launcher( "// _createart generated. modify at your own risk. " );
fileprint_launcher( "main()" );
fileprint_launcher( "{" );
common_scripts\_artCommon::print_fog_ents( true );
fileprint_launcher( "}" );
fileprint_launcher( " " );
fileprint_launcher( "setupfog()" );
fileprint_launcher( "{" );
artfxprintlnFog();
fileprint_launcher( "}" );
if ( IsUsingHDR() )
fileprint_launcher_end_file( "\\share\\raw\\maps\\createart\\" + default_name + "_fog_hdr.gsc", true );
else
fileprint_launcher_end_file( "\\share\\raw\\maps\\createart\\" + default_name + "_fog.gsc", true );
$/
}
create_light_set( name )
{
if ( !isdefined( level.light_set ) )
level.light_set = [];
ent = SpawnStruct();
ent.name = name;
level.light_set[ name ] = ent;
return ent;
}

871
raw/maps/mp/_audio.gsc Normal file
View File

@ -0,0 +1,871 @@
#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 )
{
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 ] );
}
/*
=============
///ScriptDocBegin
"Name: snd_play_team_splash( ally_sfx, enemy_sfx )"
"Summary: Plays a 2d splash sound on all players based on what team they are on."
"CallOn: A Player"
"OptionalArg: < ally_sfx, enemy_sfx > : soundaliases you want to play on players that are ally or enemies."
"Example: warbird snd_play_team_splash( "my_team_captured_the_flag", "the_enemy_team_captured_the_flag" ) ;"
"SPMP: MP"
///ScriptDocEnd
=============
*/
snd_play_team_splash( ally_sfx, enemy_sfx )
{
if(!isdefined( ally_sfx ))
{
ally_sfx = "null";
}
if(!isdefined( enemy_sfx ))
{
enemy_sfx = "null";
}
if( level.teambased )
{
foreach( player in level.players )
{
if( IsDefined( player ) && IsSentient( player ) && IsSentient( self ) && player.team != self.team )
{
// Play This Sound on all enemy players in a match.
if( SoundExists( enemy_sfx ) )
{
player playlocalsound( enemy_sfx );
}
}
else if( IsDefined( player ) && IsSentient( player ) && IsSentient( self ) && player.team == self.team )
{
// Play This Sound on all friendly players in a match.
if( SoundExists( ally_sfx ) )
{
player playlocalsound( ally_sfx );
}
}
}
}
}
/*
=============
///ScriptDocBegin
"Name: snd_play_on_notetrack_timer( alias, notetrack_frame, start_frame, _cleanup_time )"
"Summary: Plays a sound after."
"CallOn: An Entity"
"Manditory Arg: <alias> : soundaliases you want to play."
"Manditory Arg: <notetrack_frame> : The frame you want your sound to play on."
"Manditory Arg: <start_frame> : The starting frame number of the animation you are watching."
"OptionalArg: <_Cleanup_Time> : Time before the sound ent will be deleted (default is 8)."
"Example: level.elevator snd_play_on_notetrack_timer( "elevator_crash", 414, 225, 15 );;"
"SPMP: MP"
///ScriptDocEnd
=============
*/
snd_play_on_notetrack_timer( alias, notetrack_frame, start_frame, _cleanup_time )
{
//cleanup_time = 8;
//if( IsDefined( _cleanup_time ) )
// cleanup_time = _cleanup_time;
//frame_dif = notetrack_frame - start_frame / 30;
//wait( frame_dif );
//snd_play_linked( alias, self, cleanup_time );
}
/*
=============
///ScriptDocBegin
"Name: snd_play_on_notetrack( guy, animstring )"
"Summary: Listens for and Plays a sound on a notetrack event."
"CallOn: An Entity that is being animated on."
"Manditory Arg: <aliases> : array of soundaliases you want to play."
"Manditory Arg: <notetrack> : One vaild reference notetrack that exists in the animation, this must match the second arg of ScriptModelPlayAnimDeltaMotion used to call this anim.."
"Example:
***Anim - Just add valid notetrack in this case "laser_xform_up_sec1_start" ) self.lifter ScriptModelPlayAnimDeltaMotion( self.lifter.animUp, "laser_xform_up_sec1_start" );
self.lifter thread snd_play_on_notetrack( notetracktoaliasarray, "laser_xform_up_sec1_start" );
"SPMP: MP"
///ScriptDocEnd
=============
*/
snd_play_on_notetrack( aliases, notetrack, _customfunction )
{
self endon( "stop_sequencing_notetracks" );
self endon( "death" );
self sndx_play_on_notetrack_internal( aliases, notetrack, _customfunction );
}
sndx_play_on_notetrack_internal( aliases, notetrack, _customfunction )// _customfunction isn't even used. we should get rid of it.
{
for (;;)
{
self waittill( notetrack, note );
if ( isDefined( note ) && note != "end" )
{
if( isarray( aliases ))
{
alias = aliases[note];
if ( IsDefined( alias ) )
{
self playsound( alias );
}
}
else
{
if ( notetrack == note )
{
self playsound( aliases );
}
}
}
}
}
/*
=============
///ScriptDocBegin
"Name: ScriptModelPlayAnimWithNotify( <guy>, <notifyName>, <alias> )"
"Summary: Plays an animation and hooks into the notetrack, playing the alias when the notify is triggered."
"CallOn: Ignored"
"Example: ScriptModelPlayAnimWithNotify( level.thing, "sp_foo", "foo" );"
"SPMP: MP"
///ScriptDocEnd
=============
*/
ScriptModelPlayAnimWithNotify( guy, animName, notifyName, alias, customlevelend, customguyend1, customguyend2 )
{
if ( IsDefined( customlevelend ) )
{
level endon( customlevelend );
}
guy ScriptModelPlayAnimDeltaMotion( animName, notifyName );
thread ScriptModelPlayAnimWithNotify_Notetracks( guy, notifyName, alias, customlevelend, customguyend1, customguyend2 );
}
ScriptModelPlayAnimWithNotify_Notetracks( guy, notifyName, alias, customlevelend, customguyend1, customguyend2 )
{
if ( IsDefined( customlevelend ) )
{
level endon( customlevelend );
}
if ( IsDefined( customguyend1 ) )
{
guy endon( customguyend1 );
}
if ( IsDefined( customguyend2 ) )
{
guy endon( customguyend2 );
}
guy endon( "death" );
for ( ;; )
{
guy waittill( notifyName, note );
if ( isDefined( note ) && ( note == notifyName ) )
{
guy playSound( alias );
}
}
}
/*
=============
///ScriptDocBegin
"Name: snd_veh_play_loops( <array> , <ent> )"
"Summary: Plays up to 3 Loops on a vehicle by creating new sound ents and linking them to the functions self."
"CallOn: An Entity"
"OptionalArg: <loop_01, loop_02, loop_03, loop_04 > : soundaliases you want to link to this ent."
"Example: warbird snd_veh_play_loops;"
"SPMP: MP"
///ScriptDocEnd
=============
*/
snd_veh_play_loops( loop_01, loop_02, loop_03 )
{
vehicle = self;
loop_array = [ loop_01, loop_02, loop_03 ];
ent_array[0] = spawn( "script_origin", vehicle.origin );
ent_array[0] LinkToSynchronizedParent( vehicle );
ent_array[0] playloopsound( loop_01 );
ent_array[1] = spawn( "script_origin", vehicle.origin );
ent_array[1] LinkToSynchronizedParent( vehicle );
ent_array[1] playloopsound( loop_02 );
ent_array[2] = spawn( "script_origin", vehicle.origin );
ent_array[2] LinkToSynchronizedParent( vehicle );
ent_array[2] playloopsound( loop_03 );
vehicle waittill( "death" );
foreach( ent in ent_array )
{
if( isDefined( ent ) )
{
//vehicle_loop_ent setvolume(0, 0.05);
wait(0.06);
ent delete();
}
}
}
DEPRECATED_aud_map(input, env_points)
{
// input is zero to one
assert(IsDefined(input));
assert(input >= 0.0 && input <= 1.0);
assert(IsDefined(env_points));
/#
// this ensures that the given envelope is in order, otherwise we'd have to perform a sorting function.
//audx_validate_env_array(env_points);
#/
output = 0.0;
num_points = env_points.size;
// find the x-values which are relevant for the input
prev_point = env_points[0]; // grab the first point
for (i = 1; i < env_points.size; i++)
{
next_point = env_points[i];
if (input >= prev_point[0] && input <= next_point[0])
{
prev_x = prev_point[0];
next_x = next_point[0];
prev_y = prev_point[1];
next_y = next_point[1];
x_fract = (input - prev_x) / (next_x - prev_x);
output = prev_y + x_fract * (next_y - prev_y);
break;
}
else
{
prev_point = next_point;
}
}
assert(output >= 0.0 && output <= 1.0);
return output;
}
/*
=============
///ScriptDocBegin
"Name: snd_play_loop_in_space( <alias_name> , <org>, <stop_loop_notify>, <fadeout_time_> )"
"Summary: Plays a loopsound in space with a stop loop notify string. "
"Module: Sound"
"CallOn: A Thread"
"MandatoryArg: <alias_name>: name of the alias"
"MandatoryArg: <org>: Vector"
"MandatoryArg: <stop_loop_notify>: Notify string used to stop the sound."
"OptionalArg: <fadeout_time_>: Changes the fadeout time of the sound once the stop loop notify is called."
"Example: "snd_play_loop_in_space( "best_fire_loop_ever" , ( 100, 1203, 10 ), "stop_best_fire_loop_ever", 0.5 )"
"SPMP: Multiplayer"
///ScriptDocEnd
=============
*/
snd_play_loop_in_space( alias_name, org, stop_loop_notify, fadeout_time_ )
{
// Default Fadeout Time.
fadeout_time = 0.2;
if(isDefined( fadeout_time_ ) )
fadeout_time = fadeout_time_;
snd_ent = spawn( "script_origin", org );
snd_ent playloopsound( alias_name );
thread sndx_play_loop_in_space_internal( snd_ent, stop_loop_notify, fadeout_time );
return snd_ent;
}
sndx_play_loop_in_space_internal( snd_ent, stop_loop_notify, fadeout_time )
{
level waittill( stop_loop_notify );
if(IsDefined( snd_ent ) )
{
snd_ent scalevolume( 0, fadeout_time );
wait( fadeout_time + 0.05 );
snd_ent delete();
}
}
/*
=============
///ScriptDocBegin
"Name: snd_script_timer( <update_rate> )"
"Summary: prints timestamps to easily time events in script. "
"Module: Sound"
"MandatoryArg: <update_rate>: how fast the prints happen.
"Example: "snd_script_timer( 0.1 )"
"SPMP: Multiplayer"
///ScriptDocEnd
=============
*/
snd_script_timer( speed )
{
level.timer_number = 0;
if(!IsDefined( speed ))
{
// Default Speed set to 0.1
speed = 0.1;
}
while(1)
{
iprintln( level.timer_number );
wait( speed );
level.timer_number = level.timer_number + speed;
}
}
/*
=============
///ScriptDocBegin
"Name: snd_play_in_space( <alias_name> , <org>, <_cleanuptime> )"
"Summary: Plays a sound in space, returns an ent and cleans it up when done. "
"Module: Sound"
"CallOn: A Thread"
"MandatoryArg: <alias_name>: name of the alias"
"MandatoryArg: <org>: Vector"
"MandatoryArg: <_cleanuptime>: Time before ents are cleaned up."
"Example: "snd_play_in_space( "playasoundhereomg" , ( 100, 1203, 10 ) )"
"SPMP: Multiplayer"
///ScriptDocEnd
=============
*/
snd_play_in_space( alias_name, org, _cleanup_time, _fadeout_time )
{
cleanup_time = 9;
fadeout_time = 0.75;
snd_ent = spawn( "script_origin", org );
snd_ent playsound( alias_name );
snd_ent thread sndx_play_in_space_internal( cleanup_time, fadeout_time );
return snd_ent;
}
sndx_play_in_space_internal( _cleanup_time, _fadeout_time )
{
cleanup_time = 9;
fadeout_time = 0.05;
snd_ent = self;
if( IsDefined( _cleanup_time ) )
cleanup_time = _cleanup_time;
if( IsDefined( _fadeout_time ) )
fadeout_time = _fadeout_time;
wait( cleanup_time );
if(IsDefined( snd_ent ) )
{
snd_ent scalevolume( 0, fadeout_time );
wait( fadeout_time + 0.05 );
if(IsDefined( snd_ent ))
snd_ent delete();
}
}
/*
=============
///ScriptDocBegin
"Name: snd_play_in_space_delayed( <alias_name> , <org>, <delay_time>, <_cleanuptime> )"
"Summary: Plays a sound in space, returns an ent and cleans it up when done. "
"Module: Sound"
"CallOn: A Thread"
"MandatoryArg: <alias_name>: name of the alias"
"MandatoryArg: <org>: Vector"
"MandatoryArg: <_cleanuptime>: Time before ents are cleaned up."
"MandatoryArg: <delay_time>: Time before sound starts."
"Example: "snd_play_in_space( "playasoundhereomg" , ( 100, 1203, 10 ) )"
"SPMP: Multiplayer"
///ScriptDocEnd
=============
*/
snd_play_in_space_delayed( alias_name, org, delay_time, _cleanup_time, _fadeout_time )
{
cleanup_time = 9;
fadeout_time = 0.75;
snd_ent = spawn( "script_origin", org );
snd_ent thread sndx_play_in_space_delayed_internal( alias_name, delay_time, _cleanup_time, _fadeout_time );
return snd_ent;
}
sndx_play_in_space_delayed_internal( alias_name, delay_time, _cleanup_time, _fadeout_time )
{
wait( delay_time );
cleanup_time = 9;
fadeout_time = 0.05;
snd_ent = self;
snd_ent playsound( alias_name );
if( IsDefined( _cleanup_time ) )
cleanup_time = _cleanup_time;
if( IsDefined( _fadeout_time ) )
fadeout_time = _fadeout_time;
wait( cleanup_time );
if(IsDefined( snd_ent ) )
{
snd_ent scalevolume( 0, fadeout_time );
wait( fadeout_time + 0.05 );
if(IsDefined( snd_ent ))
snd_ent delete();
}
}
/*
=============
///ScriptDocBegin
"Name: snd_play_linked( <alias_name> , <ent>, <_cleanuptime>, <_fadeouttime> )"
"Summary: Plays a sound attached on an ent, returns ent and cleans it up when done. "
"Module: Sound"
"CallOn: A Thread"
"MandatoryArg: <alias_name>: name of the alias"
"MandatoryArg: <ent>: Ent you wish to attach sound to"
"OptionalArg: <_cleanuptime>: Time before ents are cleaned up."
"OptionalArg: <_fadeouttime>: Fade time before the ent is deleted (after cleanuptime is complete."
"Example: "snd_play_in_space( "play_a_sound_on_a_thing" , ent )"
"SPMP: Multiplayer"
///ScriptDocEnd
=============
*/
snd_play_linked( alias_name, ent, _cleanup_time, _fadeout_time )
{
snd_ent = spawn( "script_origin", ent.origin );
snd_ent linkto( ent );
snd_ent thread sndx_play_linked_internal( alias_name, ent, _cleanup_time, _fadeout_time );
return snd_ent;
}
sndx_play_linked_internal( alias_name, ent, _cleanup_time, _fadeout_time )
{
cleanup_time = 9;
fadeout_time = 0.05;
snd_ent = self;
snd_ent playsound( alias_name );
if( IsDefined( _cleanup_time ) )
cleanup_time = _cleanup_time;
if( IsDefined( _fadeout_time ) )
fadeout_time = _fadeout_time;
wait( cleanup_time );
if(IsDefined( snd_ent ) )
{
snd_ent scalevolume( 0, fadeout_time );
wait( fadeout_time + 0.05 );
snd_ent delete();
}
}
/*
=============
///ScriptDocBegin
"Name: snd_play_linked_loop( <alias_name> , <ent>, <_cleanuptime>, <_fadeouttime> )"
"Summary: Plays a sound attached on an ent, returns ent and cleans it up when done. "
"Module: Sound"
"CallOn: A Thread"
"MandatoryArg: <alias_name>: name of the alias"
"MandatoryArg: <ent>: Ent you wish to attach sound to"
"OptionalArg: <_fadeouttime>: Fade time before the ent is deleted."
"Example: snd_play_in_space( "play_a_sound_on_a_thing" , ent )
"SPMP: Multiplayer"
///ScriptDocEnd
=============
*/
snd_play_linked_loop( alias_name, ent, _fadeout_time )
{
snd_ent = spawn( "script_origin", ent.origin );
snd_ent linkto( ent );
snd_ent thread sndx_play_linked_loop_internal( alias_name, ent, _fadeout_time );
return snd_ent;
}
sndx_play_linked_loop_internal( alias_name, ent, _fadeout_time )
{
fadeout_time = 0.05;
snd_ent = self;
snd_ent playloopsound( alias_name );
if( IsDefined( _fadeout_time ) )
fadeout_time = _fadeout_time;
ent waittill( "death" );
if(IsDefined( snd_ent ) )
{
snd_ent scalevolume( 0, fadeout_time );
wait( fadeout_time + 0.05 );
snd_ent delete();
}
}
/*
///ScriptDocBegin
"Name: aud_print_3d_on_ent(<msg> , <_size>, <_text_color> )"
"Summary: Create a print msg in 3d space that follows the entity this function is called on."
"Module: Audio"
"CallOn: The entity you wish to tag your print msg to."
"MandatoryArg: <msg> : Your print msg."
"OptionalArg": <_size> : Text size.
"OptionalArg": <_text_color> : Text color.
"OptionalArg": <_msg_callback> : Function pointer that returns a string which will be concatenated to <msg>. _msg_callback is called on self.
"OptionalArg": <_msg_callback> : Duration in seconds that the 3D message should be printed on self.
"SPMP: multiplayer"
///ScriptDocEnd
*/
aud_print_3d_on_ent(msg, _size, _text_color, _msg_callback, durration_)
{
if(IsDefined(self))
{
white = (1, 1, 1); //Default color if no arg is given.
red = (1, 0, 0);
green = (0, 1, 0);
blue = (0, 1, 1);
size = 5;
text_color = white;
if(IsDefined(_size))
{
size = _size;
}
if(IsDefined( _text_color))
{
text_color = _text_color;
switch( text_color )
{
case "red":
{
text_color = red;
}
break;
case "white":
{
text_color = white;
}
break;
case "blue":
{
text_color = blue;
}
break;
case "green":
{
text_color = green;
}
break;
default:
{
text_color = white;
}
}
}
if(IsDefined(durration_))
{
self thread audx_print_3d_timer(durration_);
}
self endon("death");
self endon("aud_stop_3D_print");
while(IsDefined(self))
{
full_msg = msg;
if (IsDefined(_msg_callback))
{
full_msg = full_msg + self [[_msg_callback]]();
}
Print3d(self.origin, full_msg, text_color, 1, size, 1);
wait(0.05);
}
}
}
audx_print_3d_timer( durration_ )
{
self endon("death");
assert(IsDefined(durration_));
wait(durration_);
if (IsDefined(self))
{
self notify("aud_stop_3D_print");
}
}
// NOTES
// Checks to see if game mode is team based.
//level.teamBased
//self endon( "disconnect" );
//level endon( "game_ended" );
snd_vehicle_mp()
{
// vehicle = self;
//
// //Setup Default Envelopes.
// hover_env = [ [0,1],[1,0.25] ];
// move_env = [ [0,0.3],[1,1] ];
//
// if( isdefined( _hover_env ) )
// hover_env = _hover_env;
//
// if( isdefined( _move_env ) )
// move_env = _move_env;
//
// // Create Ents and link them to the vehicle.
// ent_array[ "hover_lp" ] = spawn( "script_origin", vehicle.origin );
// ent_array[ "hover_lp" ] LinkToSynchronizedParent( vehicle );
// ent_array[ "hover_lp" ] playloopsound( close_lp );
//
// ent_array[ "move_lp" ] = spawn( "script_origin", vehicle.origin );
// ent_array[ "move_lp" ] LinkToSynchronizedParent( vehicle );
// ent_array[ "move_lp" ] playloopsound( move_lp );
//
// ent_array[ "dist_lp" ] = spawn( "script_origin", vehicle.origin );
// ent_array[ "dist_lp" ] LinkToSynchronizedParent( vehicle );
// ent_array[ "dist_lp" ] playloopsound( dist_lp );
//
// velocity = 0.0;
//
// //Scale Volumes Based on Inputs
// while( Isdefined( vehicle ))
// {
//
// //if is player controlled....
// new_velocity = vehicle Vehicle_GetSpeed();
// if( new_velocity <= 0 )
// {
// player_velocity = vehicle GetEntityVelocity();
// if (isdefined(player_velocity))
// {
// new_velocity = Length2D(player_velocity);
// }
// }
// new_velocity = clamp(new_velocity, 0.0, 10.0) / 10.0;
// if ( new_velocity > velocity)
// {
// //velocity = (new_velocity + velocity) / 2.0;
// }
// else
// {
// velocity = new_velocity;
// }
//
// hover_vol = DEPRECATED_aud_map( velocity, hover_env );
// ent_array[ "hover_lp" ] scalevolume( hover_vol, 0.05 );
//
// move_vol = DEPRECATED_aud_map( velocity, move_env );
// ent_array[ "move_lp" ] scalevolume( move_vol, 0.05 );
// wait(0.05);
//
// }
//
// //vehicle waittill( "death" );
//
// foreach( ent in ent_array )
// {
// if( isDefined( ent ) )
// {
// ent setvolume(0, 1);
// wait( 1 );
// ent delete();
// }
// }
}

470
raw/maps/mp/_awards.gsc Normal file
View File

@ -0,0 +1,470 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
/#
CONST_PRINT_AWARDS = false;
#/
init()
{
initAwards();
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
if ( !isDefined( player.pers["stats"] ) )
player.pers["stats"] = [];
player.stats = player.pers["stats"];
// initialize player stats
if( !player.stats.size )
{
foreach ( ref, award in level.awards )
{
player initPlayerStat( ref, level.awards[ ref ].defaultvalue );
}
}
}
}
initAwards()
{
// medals
initStatAward( "headshots", 0, ::highestWins );
initStatAward( "multikill", 0, ::highestWins );
initStatAward( "avengekills", 0, ::highestWins );
initStatAward( "comebacks", 0, ::highestWins );
initStatAward( "rescues", 0, ::highestWins );
initStatAward( "longshots", 0, ::highestWins );
initStatAward( "revengekills", 0, ::highestWins );
initStatAward( "bulletpenkills", 0, ::highestWins );
initStatAward( "throwback_kill", 0, ::highestWins );
initStatAward( "firstblood", 0, ::highestWins );
initStatAward( "posthumous", 0, ::highestWins );
initStatAward( "assistedsuicide", 0, ::highestWins );
initStatAward( "buzzkill", 0, ::highestWins );
initStatAward( "oneshotkill", 0, ::highestWins );
initStatAward( "air_to_air_kill", 0, ::highestWins );
initStatAward( "air_to_ground_kill", 0, ::highestWins );
initStatAward( "ground_to_air_kill", 0, ::highestWins );
initStatAward( "doublekill", 0, ::highestWins );
initStatAward( "triplekill", 0, ::highestWins );
initStatAward( "fourkill", 0, ::highestWins );
initStatAward( "fivekill", 0, ::highestWins );
initStatAward( "sixkill", 0, ::highestWins );
initStatAward( "sevenkill", 0, ::highestWins );
initStatAward( "eightkill", 0, ::highestWins );
initStatAward( "hijacker", 0, ::highestWins );
initStatAward( "backstab", 0, ::highestWins );
initStatAward( "5killstreak", 0, ::highestWins );
initStatAward( "10killstreak", 0, ::highestWins );
initStatAward( "15killstreak", 0, ::highestWins );
initStatAward( "20killstreak", 0, ::highestWins );
initStatAward( "25killstreak", 0, ::highestWins );
initStatAward( "30killstreak", 0, ::highestWins );
initStatAward( "30pluskillstreak", 0, ::highestWins );
initStatAward( "pointblank", 0, ::highestWins );
initStatAward( "firstplacekill", 0, ::highestWins );
initStatAward( "boostslamkill", 0, ::highestWins );
initStatAward( "assault", 0, ::highestWins );
initStatAward( "defends", 0, ::highestWins );
initStatAward( "exo_knife_kill", 0, ::highestWins );
initStatAward( "exo_knife_recall_kill", 0, ::highestWins );
initStatAward( "near_death_kill", 0, ::highestWins );
initStatAward( "slide_kill", 0, ::highestWins );
initStatAward( "flash_kill", 0, ::highestWins );
initStatAward( "riot_kill", 0, ::highestWins );
initStatAward( "melee_air_to_air", 0, ::highestWins );
initStatAward( "assist_riot_shield", 0, ::highestWins );
initStatAward( "semtex_stick", 0, ::highestWins );
initStatAward( "stuck_with_explosive", 0, ::highestWins );
initStatAward( "crossbow_stick", 0, ::highestWins );
initStatAward( "multiKillOneBullet", 0, ::highestWins );
initStatAward( "think_fast", 0, ::highestWins );
initStatAward( "take_and_kill", 0, ::highestWins );
initStatAward( "four_play", 0, ::highestWins );
initStatAward( "sharepackage", 0, ::highestWins );
initStatAward( "map_killstreak", 0, ::highestWins );
initStatAward( "killstreak_tag", 0, ::highestWins );
initStatAward( "killstreak_join", 0, ::highestWins );
// not medals but need for comabt record data
initStatAward( "kills", 0, ::highestWins );
initStatAward( "longestkillstreak", 0, ::highestWins );
initStatAward( "knifekills", 0, ::highestWins );
initStatAward( "kdratio", 0, ::highestWins );
initStatAward( "deaths", 0, ::lowestWithHalfPlayedTime );
initStatAward( "assists", 0, ::highestWins );
initStatAward( "totalGameScore", 0, ::highestWins );
initStatAward( "scorePerMinute", 0, ::highestWins );
initStatAward( "mostScorePerLife", 0, ::highestWins );
initStatAward( "killStreaksUsed", 0, ::highestWins );
// gun game medals
initStatAward( "humiliation", 0, ::highestWins );
initStatAward( "regicide", 0, ::highestWins );
initStatAward( "gunslinger", 0, ::highestWins );
initStatAward( "dejavu", 0, ::highestWins );
initStatAward( "levelup", 0, ::highestWins );
// infected medals
initStatAward( "omegaman", 0, ::highestWins );
initStatAward( "plague", 0, ::highestWins );
initStatAward( "patientzero", 0, ::highestWins );
initStatAward( "careless", 0, ::highestWins );
initStatAward( "survivor", 0, ::highestWins );
initStatAward( "contagious", 0, ::highestWins );
// capture the flag medals
initStatAward( "flagscaptured", 0, ::highestWins );
initStatAward( "flagsreturned", 0, ::highestWins);
initStatAward( "flagcarrierkills", 0, ::highestWins );
initStatAward( "flagscarried", 0, ::highestWins );
initStatAward( "killsasflagcarrier", 0, ::highestWins );
// domination medals
initStatAward( "pointscaptured", 0, ::highestWins );
initStatAward( "kill_while_capture", 0, ::highestWins );
initStatAward( "opening_move", 0, ::highestWins );
// hard point medals
initStatAward( "hp_secure", 0, ::highestWins );
// SD/SR medals
initStatAward( "targetsdestroyed", 0, ::highestWins );
initStatAward( "bombsplanted", 0, ::highestWins );
initStatAward( "bombsdefused", 0, ::highestWins );
initStatAward( "ninja_defuse", 0, ::highestWins );
initStatAward( "last_man_defuse", 0, ::highestWins );
initStatAward( "elimination", 0, ::highestWins );
initStatAward( "last_man_standing", 0, ::highestWins );
initStatAward( "sr_tag_elimination", 0, ::highestWins );
initStatAward( "sr_tag_revive", 0, ::highestWins );
// kill confirmed medals
initStatAward( "killsconfirmed", 0, ::highestWins );
initStatAward( "killsdenied", 0, ::highestWins );
initStatAward( "kill_denied_retrieved", 0, ::highestWins );
initStatAward( "tag_collector", 0, ::highestWins );
// ball medals
initStatAward( "touchdown", 0, ::highestWins );
initStatAward( "fieldgoal", 0, ::highestWins );
initStatAward( "interception", 0, ::highestWins );
initStatAward( "kill_with_ball", 0, ::highestWins );
initStatAward( "ball_score_assist", 0, ::highestWins );
initStatAward( "pass_kill_pickup", 0, ::highestWins );
initStatAward( "killedBallCarrier", 0, ::highestWins );
// killstreak destroyed medals
initStatAward( "uav_destroyed", 0, ::highestWins );
initStatAward( "warbird_destroyed", 0, ::highestWins );
initStatAward( "paladin_destroyed", 0, ::highestWins );
initStatAward( "vulcan_destroyed", 0, ::highestWins );
initStatAward( "goliath_destroyed", 0, ::highestWins );
initStatAward( "missile_strike_destroyed", 0, ::highestWins );
initStatAward( "sentry_gun_destroyed", 0, ::highestWins );
initStatAward( "strafing_run_destroyed", 0, ::highestWins );
initStatAward( "assault_drone_destroyed", 0, ::highestWins );
initStatAward( "recon_drone_destroyed", 0, ::highestWins );
initStatAward( "map_killstreak_destroyed", 0, ::highestWins );
initStatAward( "assist_killstreak_destroyed", 0, ::highestWins );
// killstreak kill medals
initStatAward( "warbird_kill", 0, ::highestWins );
initStatAward( "paladin_kill", 0, ::highestWins );
initStatAward( "vulcan_kill", 0, ::highestWins );
initStatAward( "goliath_kill", 0, ::highestWins );
initStatAward( "airdrop_kill", 0, ::highestWins );
initStatAward( "airdrop_trap_kill", 0, ::highestWins );
initStatAward( "missile_strike_kill", 0, ::highestWins );
initStatAward( "sentry_gun_kill", 0, ::highestWins );
initStatAward( "strafing_run_kill", 0, ::highestWins );
initStatAward( "assault_drone_kill", 0, ::highestWins );
initStatAward( "map_killstreak_kill", 0, ::highestWins );
initStatAward( "coop_killstreak_kill", 0, ::highestWins );
// killstreak earned medals
initStatAward( "uav_earned", 0, ::highestWins );
initStatAward( "warbird_earned", 0, ::highestWins );
initStatAward( "orbitalsupport_earned", 0, ::highestWins );
initStatAward( "orbital_strike_laser_earned", 0, ::highestWins );
initStatAward( "orbital_carepackage_earned", 0, ::highestWins );
initStatAward( "heavy_exosuit_earned", 0, ::highestWins );
initStatAward( "missile_strike_earned", 0, ::highestWins );
initStatAward( "remote_mg_sentry_turret_earned",0, ::highestWins );
initStatAward( "strafing_run_airstrike_earned", 0, ::highestWins );
initStatAward( "assault_ugv_earned", 0, ::highestWins );
initStatAward( "recon_ugv_earned", 0, ::highestWins );
initStatAward( "emp_earned", 0, ::highestWins );
// this needs to be the last stat in the list
initStatAward( "numMatchesRecorded", 0, ::highestWins );
}
initStatAward( ref, defaultvalue, process, var1, var2 )
{
assert( isDefined( ref ) );
level.awards[ ref ] = spawnStruct();
level.awards[ ref ].defaultvalue = defaultvalue;
if( isDefined( process ) )
level.awards[ ref ].process = process;
if( isDefined( var1 ) )
level.awards[ ref ].var1 = var1;
if( isDefined( var2 ) )
level.awards[ ref ].var2 = var2;
}
setPersonalBestIfGreater( ref )
{
recordValue = self getCommonPlayerData( "bests", ref );
playerValue = self getPlayerStat( ref );
playerValue = getFormattedValue( ref, playerValue );
if ( recordValue == 0 || ( playervalue > recordValue ) )
{
self setCommonPlayerData( "bests", ref, playerValue );
}
}
setPersonalBestIfLower( ref )
{
recordvalue = self getCommonPlayerData( "bests", ref );
playervalue = self getPlayerStat( ref );
playerValue = getFormattedValue( ref, playerValue );
if ( recordValue == 0 || ( playervalue < recordvalue ) )
{
self setCommonPlayerData( "bests", ref, playerValue );
}
}
calculateKD( player )
{
kills = player getPlayerStat( "kills" );
deaths = player getPlayerStat( "deaths" );
if ( deaths == 0 )
deaths = 1;
player setPlayerStat( "kdratio", ( kills / deaths ) );
}
getTotalScore( player )
{
totalScore = player.score;
if( !level.teamBased )
totalScore = player.extrascore0;
return totalScore;
}
calculateSPM( player )
{
if( player.timePlayed["total"] < 1 )
return;
totalScore = getTotalScore( player );
secondsPlayed = player.timePlayed["total"];
scorePerMinute = totalScore / (secondsPlayed / 60 );
player setPlayerStat( "totalGameScore", totalScore );
player setPlayerStat( "scorePerMinute", scorePerMinute );
}
assignAwards()
{
// Special case handling of awards which get stat values updated at the end of a game
foreach ( player in level.players )
{
// dont assign awards if not ranked match
if ( !player rankingEnabled() )
return;
player incPlayerStat( "numMatchesRecorded", 1 );
calculateKD( player );
calculateSPM( player );
}
// process end of match stats
foreach ( ref, award in level.awards )
{
if ( !isDefined( level.awards[ ref ].process ) )
continue;
process = level.awards[ ref ].process;
var1 = level.awards[ ref ].var1;
var2 = level.awards[ ref ].var2;
if ( isDefined( var1 ) && isDefined( var2 ) )
[[ process ]]( ref, var1, var2 );
else if ( isDefined( var1 ) )
[[ process ]]( ref, var1 );
else
[[ process ]]( ref );
}
/#
if( CONST_PRINT_AWARDS )
{
printAwards();
}
#/
}
/#
printAwards()
{
foreach ( player in level.players )
{
if( IsAI(player) )
continue;
awardNames = GetArrayKeys( level.awards );
for ( i = 0; i < awardNames.size; i++ )
{
value = player getCommonPlayerData( "round", "awards", awardNames[i] );
println( "Awards: [", player.name, "][", awardNames[i], "] = ", value );
}
}
}
#/
giveAward( ref )
{
value = self getPlayerStat( ref );
value = getFormattedValue( ref, value );
// set awards values for the round
self setCommonPlayerData( "round", "awards", ref, value );
if ( practiceRoundGame() )
return;
// set the award values for lifetime total
if( shouldAverageTotal( ref ) )
{
numMatches = self getCommonPlayerData( "awards", "numMatchesRecorded" );
oldAverage = self getCommonPlayerData( "awards", ref );
oldTotal = oldAverage * numMatches;
newAverage = int( (oldTotal + value) / (numMatches + 1) );
self setCommonPlayerData( "awards", ref, newAverage);
}
else
{
recordValue = self getCommonPlayerData( "awards", ref );
self setCommonPlayerData( "awards", ref, recordValue + value );
}
}
shouldAverageTotal( ref )
{
switch( ref )
{
case "scorePerMinute":
case "kdratio":
return true;
}
return false;
}
getFormattedValue( ref, value )
{
awardFormat = tableLookup( "mp/awardTable.csv", 1, ref, 5 );
switch ( awardFormat )
{
case "float":
value = limitDecimalPlaces( value, 2 );
value = value * 100;
break;
case "ratio":
case "multi":
case "count":
case "time":
case "distance":
case "none":
default:
break;
}
value = int( value );
return ( value );
}
highestWins( ref, minAwardable )
{
foreach ( player in level.players )
{
if ( player rankingEnabled() && player statValueChanged( ref ) && ( !isDefined( minAwardable ) || player getPlayerStat( ref ) >= minAwardable ) )
{
player giveAward( ref );
player setPersonalBestIfGreater( ref );
}
}
}
lowestWins( ref, maxAwardable)
{
foreach ( player in level.players )
{
if ( player rankingEnabled() && player statValueChanged( ref ) && ( !isDefined( maxAwardable ) || player getPlayerStat( ref ) <= maxAwardable ) )
{
player giveAward( ref );
player setPersonalBestIfLower( ref );
}
}
}
lowestWithHalfPlayedTime( ref )
{
gameLength = getTimePassed() / 1000;
halfGameLength = gameLength * 0.5;
foreach ( player in level.players )
{
// hasSpawned check is required or players who pick a team and never spawn can win awards
if ( player.hasSpawned && player.timePlayed["total"] >= halfGameLength )
{
player giveAward( ref );
player setPersonalBestIfLower( ref );
}
}
}
statValueChanged( ref )
{
playervalue = self getPlayerStat( ref );
defaultvalue = level.awards[ ref ].defaultvalue;
if ( playervalue == defaultvalue )
return false;
else
return true;
}

View File

@ -0,0 +1,96 @@
#include maps\mp\_utility;
resolveBraggingRights()
{
num_bragging_rights = GetNumBraggingRights();
brarray = [];
//clear the array
for( i = 0; i < num_bragging_rights; i++ )
brarray[i] = [];
foreach( p in level.players )
{
if( IsAlive( p ) )
{
br = p GetBraggingRight();
if( br < num_bragging_rights ) //which means is valid
{
//stat_name = TableLookupByRow( "mp/braggingrights.csv", br, 0 );
//stat_accessor = TableLookupByRow( "mp/braggingrights.csv", br, 2 );
//Print( p.name + " BR:" + br + " stat_name: " + stat_name + " stat_accessor: " + stat_accessor );
curr_size = brarray[br].size;
brarray[br][ curr_size ] = p;
}
}
}
foreach( i, br in brarray )
{
if( br.size > 1 )
{
Print( "Resolving BR conflict at : " + i );
stat_accessor = TableLookupByRow( "mp/braggingrights.csv", i, 2 );
highScore = undefined;
winner = undefined;
foreach( player in br )
{
playerValue = player getPlayerStat( stat_accessor );
if( !IsDefined( highScore ) || playerValue > highScore )
{
winner = player;
highScore = playerValue;
}
}
foreach( player in br )
{
if( player == winner )
{
if( !isdefined( player.matchBonus ) )
player.matchBonus = 0;
total_bonus = 0;
foreach( p in br )
{
if( IsDefined( p.matchBonus ) )
total_bonus += p.matchBonus;
}
player.matchBonus += total_bonus;
Print( "Bragging Rights Bonus: " + total_bonus + " For " + player.name + " \n");
}
else
{
Print( "Bragging Rights LOST by " + player.name + " \n");
player.braggingRightsLoser = true;
}
}
}
}
foreach( p in level.players )
{
if( isdefined( p.braggingRightsLoser ) && p.braggingRightsLoser )
p.matchBonus = 0;
}
}
GetNumBraggingRights()
{
line_num = -1;
line_val = "temp";
while( line_val != "" )
{
line_num++;
line_val = TableLookupByRow( "mp/braggingrights.csv", line_num, 0 );
}
return line_num;
}

79
raw/maps/mp/_compass.gsc Normal file
View File

@ -0,0 +1,79 @@
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;
}
}
// 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);
}

72
raw/maps/mp/_createfx.gsc Normal file
View File

@ -0,0 +1,72 @@
#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.callbackEntityOutOfWorld = ::void;
level.callbackCodeEndGame = ::void;
level.callbackPlayerLastStand = ::void;
level.callbackPlayerConnect = ::Callback_PlayerConnect;
level.callbackPlayerMigrated = ::void;
maps\mp\gametypes\_gameobjects::main( [] ); // clear out extra entities since we're tight on some levels
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" );
spawnangles = ( spawnpoints[0].angles[0], spawnpoints[0].angles[1], 0.0 );
self spawn( spawnpoints[0].origin, spawnangles );
self updateSessionState( "playing" );
self.maxhealth = 10000000;
self.health = 10000000;
level.player = self;
thread createFxLogic();
}
else
kick( self GetEntityNumber() );
}
func_player_speed()
{
scale = level._createfx.player_speed / 190;
level.player SetMoveSpeedScale( scale );
}

727
raw/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;
}
}

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)
{
}

View File

@ -0,0 +1,337 @@
#include common_scripts\utility;
#include maps\mp\gametypes\_hud_util;
#include maps\mp\_utility;
DEFAULT_START_PERCENTAGE = .5;
SD_WAIT_TIME = 10;
/*
=============
///ScriptDocBegin
"Name: DynamicEvent( dynamicEventStartFunc, dynamicEventResetFunc )"
"Summary: A wrapper for handling global Dynamic event functions. The function handles the timing and notifies the level: "dynamic_event_starting" when it's time. Optionally you can pass in a function that is called at the appropriate time as well.
"Module: Dynamic Event
"CallOn: level
"OptionalArg: dynamicEventStartFunc: The function that will play at the start of the dynamic event
"OptionalArg: dynamicEventResetFunc: The function that will be called to reset the event. Dev Only.
"Example: level thread DynamicEvent( ::dynamicEventStartFunc )
"SPMP: multiplayer"
///ScriptDocEnd
=============
*/
DynamicEvent( dynamicEventStartFunc, dynamicEventResetFunc, dynamicEventEndFunc )
{
if ( getdvarint( "r_reflectionProbeGenerate" ) )//in case maps need to call the dynamic event before load for createfx
return;
if ( IsDefined( level.dynamicEventsType ) )
{
if ( level.dynamicEventsType == 1 ) // Disabled (Before)
return;
if ( level.dynamicEventsType == 2 ) // Disabled (After)
{
if( isDefined( dynamicEventEndFunc ) )
level [[dynamicEventEndFunc]]();
return;
}
}
SetDvarIfUninitialized( "scr_dynamic_event_state", "on"); //options are: on, off, and endstate
if( getdvar( "scr_dynamic_event_state", "on" ) == "off" )
return;
else if( getdvar( "scr_dynamic_event_state", "on" ) == "endstate" )
{
if( isDefined( dynamicEventEndFunc ) )
level [[dynamicEventEndFunc]]();
return;
}
/#
SetDvarIfUninitialized( "scr_dynamic_event_start_perc", DEFAULT_START_PERCENTAGE);
SetDvarIfUninitialized( "scr_dynamic_event_start_now", 0);
#/
if( !isDefined( level.DynamicEvent ) )
level.DynamicEvent = [];
//round based gamemodes
if( level.gametype == "sd" || level.gametype == "sr" )
{
level thread handle_sd_dynamicEvent( dynamicEventStartFunc, dynamicEventEndFunc );
}
/* Removing score check. Dynamic events need to be time based only.
//do score check
else if( level.gametype == "war" || level.gametype == "conf" || level.gametype == "hp" || level.gametype == "dm" )
{
level thread handle_dynamicEvent( dynamicEventStartFunc, dynamicEventResetFunc );
}
*/
//don't do score check
else //ctf, dom, infect, twar
{
level thread handle_dynamicEvent( dynamicEventStartFunc, dynamicEventResetFunc, false );
}
level thread logDynamicEventStartTime();
}
logDynamicEventStartTime()
{
level endon( "game_ended" );
level waittill( "dynamic_event_starting" );
currentDeciSeconds = getTimePassedDeciSecondsIncludingRounds();
setMatchData( "dynamicEventTimeDeciSecondsFromMatchStart", clampToShort( currentDeciSeconds) );
}
handle_sd_dynamicEvent( dynamicEventStartFunc, dynamicEventEndFunc )
{
if( !isDefined( game["dynamicEvent_isInOvertime"] ) )
game["dynamicEvent_isInOvertime"] = false;
if( !isDefined( game["dynamicEvent_hasSwitchedSides"] ) )
game["dynamicEvent_hasSwitchedSides"] = false;
if( !isDefined( game["dynamicEvent_Overtime"] ) )
game["dynamicEvent_Overtime"] = false;
if( !isDefined( game["dynamicEvent_sd_round_counter"] ) )
game["dynamicEvent_sd_round_counter"] = 0;
else
game["dynamicEvent_sd_round_counter"]++;
/# level thread debug_watch_dynamicEvent_start_now( dynamicEventStartFunc );#/
//overtime reset
if( !game["dynamicEvent_isInOvertime"] && game["dynamicEvent_Overtime"] )
{
game["dynamicEvent_sd_round_counter"] = 0;
game["dynamicEvent_isInOvertime"] = true;
game["dynamicEvent_hasSwitchedSides"] = false;
}
//halftime switch sides reset
if( isDefined( game["switchedsides"] ) && game["switchedsides"] && !game["dynamicEvent_hasSwitchedSides"] && !game["dynamicEvent_isInOvertime"] )
{
game["dynamicEvent_sd_round_counter"] = 0;
game["dynamicEvent_hasSwitchedSides"] = true;
}
//do event
else if( game["dynamicEvent_sd_round_counter"] == 1 )
{
wait( SD_WAIT_TIME );
level notify( "dynamic_event_starting" );
if( isDefined( dynamicEventStartFunc ) && isDefined( dynamicEventEndFunc ) )
level [[dynamicEventStartFunc]]();
}
//do end
else if( game["dynamicEvent_sd_round_counter"] > 1 )
{
if( isDefined( dynamicEventStartFunc ) && isDefined( dynamicEventEndFunc ) )
level [[dynamicEventEndFunc]]();
}
}
debug_watch_dynamicEvent_start_now( dynamicEventStartFunc )
{
level endon( "game_ended" );
level notify( "waching_dynamicevent_dvar" );
level endon( "waching_dynamicevent_dvar" );
if( GetDvarInt( "scr_dynamic_event_start_now" ) == 1 )
{
setDvar( "scr_dynamic_event_start_now", 0 );
}
while( true )
{
if( GetDvarInt( "scr_dynamic_event_start_now" ) == 1 && game["dynamicEvent_sd_round_counter"] == 0 )
{
level notify( "dynamic_event_starting" );
if( isDefined( dynamicEventStartFunc ) )
level [[dynamicEventStartFunc]]();
game["dynamicEvent_sd_round_counter"] = 1;
while( GetDvarInt( "scr_dynamic_event_start_now", 1 ) == 1 )
{
wait( 1 );
}
}
wait( 1 );
}
}
handle_dynamicEvent( dynamicEventStartFunc, dynamicEventResetFunc, doScoreCheck )
{
time_limit = getDynamicEventTimeLimit();
start_time = getDynamicEventStartTime();
score = undefined;
score_limit = getScoreLimit();
if( !isDefined( doScoreCheck ) )
doScoreCheck = true;
while( time_limit > start_time && ( !doScoreCheck || ( !isDefined( score ) || score <= score_limit*level.DynamicEvent["start_percent"] ) ) )
{
/#
start_percent = GetDvarfloat( "scr_dynamic_event_start_perc", level.DynamicEvent["start_percent"] );
if( start_percent != level.DynamicEvent["start_percent"] )
{
setDynamicEventStartPercent( start_percent );
start_time = getDynamicEventStartTime();
}
if( GetDvarInt( "scr_dynamic_event_start_now" ) == 1 )
time_limit = start_time;
#/
wait( 1 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
time_limit = time_limit - 1;
score = GetDynamicEventHighestScore();
}
level notify( "dynamic_event_starting" );
if( isDefined( dynamicEventStartFunc ) )
level [[dynamicEventStartFunc]]();
/#
while ( IsDefined(dynamicEventResetFunc) )
{
SetDvar("scr_dynamic_event_start_now", 0);
while( !GetDvarInt("scr_dynamic_event_start_now", 0) )
waitframe();
level notify( "dynamic_event_reset" );
level [[dynamicEventResetFunc]]();
SetDvar("scr_dynamic_event_start_now", 0);
while( !GetDvarInt("scr_dynamic_event_start_now", 0) )
waitframe();
level notify( "dynamic_event_starting" );
if( isDefined( dynamicEventStartFunc ) )
level [[dynamicEventStartFunc]]();
}
#/
}
/*
=============
///ScriptDocBegin
"Name: setDynamicEventStartPercent( percent )"
"Summary: Sets when the dynamic event should start."
"Module: Dynamic Event"
"CallOn: level"
"OptionalArg: percent: The percentage of the total match time to start the event. expecting it to be between 0 and 1. default is .5 (50 percent)."
"Example: level setDynamicEventStartPercent( .5 )"
"SPMP: multiplayer"
///ScriptDocEnd
=============
*/
setDynamicEventStartPercent( percent )
{
if( !isDefined( percent ) )
percent = DEFAULT_START_PERCENTAGE;
if( percent < 0 || percent > 1 )
AssertMsg( "expecting a percent between 0 and 1" );
level.DynamicEvent["start_percent"] = percent;
}
/*
=============
///ScriptDocBegin
"Name: getDynamicEventStartTime()"
"Summary: gets the dynamic event start time. if it isn't set, it will set it."
"Module: Dynamic Event"
"CallOn: level"
"Example: start_time = getDynamicEventStartTime()"
"SPMP: multiplayer"
///ScriptDocEnd
=============
*/
getDynamicEventStartTime()
{
if( !isDefined( level.DynamicEvent["start_percent"] ) )
setDynamicEventStartPercent();
time_limit = getDynamicEventTimeLimit();
start_time = time_limit - ( time_limit * level.DynamicEvent["start_percent"] ); // set the move time to a percentage of the timelimit.
return start_time;
}
/*
=============
///ScriptDocBegin
"Name: GetDynamicEventHighestScore()"
"Summary: gets the highest score of one of the teams if teambased. If not teambased it uses player scores. "
"Module: Dynamic Event"
"CallOn: level"
"Example: start_time = GetDynamicEventHighestScore()"
"SPMP: multiplayer"
///ScriptDocEnd
=============
*/
GetDynamicEventHighestScore()
{
score = undefined;
if( level.teamBased )
{
team = maps\mp\gametypes\_gamescore::getWinningTeam();
if( isDefined( team ) && team == "none" && isDefined( level.teamNameList ) )
score = maps\mp\gametypes\_gamescore::_getTeamScore( level.teamNameList[0] );
else if( isDefined( team ) )
score = maps\mp\gametypes\_gamescore::_getTeamScore( team );
}
else
{
player = maps\mp\gametypes\_gamescore::getHighestScoringPlayer();
if( !isDefined( player ) && isDefined( level.players ) && level.players.size > 0 )
score = maps\mp\gametypes\_gamescore::_getPlayerScore( level.players[0] );
else if( isDefined( player ) )
score = maps\mp\gametypes\_gamescore::_getPlayerScore( player );
}
return score;
}
/*
=============
///ScriptDocBegin
"Name: getDynamicEventTimeLimit()"
"Summary: gets the time limit in seconds for the match, used for the dynamic event timing. If there is infinite time, the time limit for the dynamic event will use 600 secs (10 mins)"
"Module: Dynamic Event"
"CallOn: level"
"Example: time_limit = getDynamicEventTimeLimit()"
"SPMP: multiplayer"
///ScriptDocEnd
=============
*/
getDynamicEventTimeLimit()
{
time_limit = getTimeLimit();
if ( time_limit == 0 )//in case the time is infinite time (private match)
time_limit = 10 * 60; // get the game type timelimit in seconds
else
time_limit = time_limit * 60; // get the game type timelimit in seconds
has_half_time = getHalfTime();
if( isDefined( has_half_time ) && has_half_time )
time_limit = time_limit/2;
return time_limit;
}

File diff suppressed because it is too large Load Diff

232
raw/maps/mp/_empgrenade.gsc Normal file
View File

@ -0,0 +1,232 @@
#include maps\mp\_utility;
#include common_scripts\utility;
#include maps\mp\gametypes\_hud_util;
init()
{
//precacheShellshock("flashbang_mp");
PrecacheDigitalDistortCodeAssets();
thread onPlayerConnect();
PreCacheString( &"MP_EMP_REBOOTING" );
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill( "spawned_player" );
self thread monitorEMPGrenade();
}
}
monitorEMPGrenade()
{
self endon("death");
self endon("disconnect");
self endon("faux_spawn");
self.empEndTime = 0;
while(1)
{
self waittill( "emp_grenaded", attacker );
if ( !isalive( self ) )
continue;
if ( isDefined( self.usingRemote ) )
continue;
//MW3 emp resistance perk
if ( self _hasPerk( "specialty_empimmune" ) )
continue;
hurtVictim = true;
hurtAttacker = false;
assert(isdefined(self.pers["team"]));
if (level.teamBased && isdefined(attacker) && isdefined(attacker.pers["team"]) && attacker.pers["team"] == self.pers["team"] && attacker != self)
{
if(level.friendlyfire == 0) // no FF
{
continue;
}
else if(level.friendlyfire == 1) // FF
{
hurtattacker = false;
hurtvictim = true;
}
else if(level.friendlyfire == 2) // reflect
{
hurtvictim = false;
hurtattacker = true;
}
else if(level.friendlyfire == 3) // share
{
hurtattacker = true;
hurtvictim = true;
}
}
else if( isDefined(attacker) )
{
attacker notify( "emp_hit" );
if( attacker != self )
attacker maps\mp\gametypes\_missions::processChallenge( "ch_onthepulse" );
}
if ( hurtvictim && isDefined(self) )
self thread applyEMP();
if ( hurtattacker && isDefined(attacker) )
attacker thread applyEMP();
}
}
emp_hide_HUD( id )
{
maps\mp\gametypes\_scrambler::playerSetHUDEmpScrambledOff( id );
}
applyEMP()
{
self notify( "applyEmp" );
self endon( "applyEmp" );
self endon( "death" );
self endon( "disconnect" );
wait .05;
self.empDuration = 3;
HUDtext = 2;
// disable exo when emp'd, if gamemode appropriate
if( isAugmentedGameMode() )
{
HUDtext = 1;
self playerAllowHighJump(false, "empgrenade");
self playerAllowHighJumpDrop(false, "empgrenade");
self playerAllowBoostJump(false, "empgrenade");
self playerAllowPowerSlide(false, "empgrenade");
self playerAllowDodge(false, "empgrenade");
}
self.empGrenaded = true;
//self shellshock( "flashbang_mp", 1 );
self.empEndTime = getTime() + (self.empDuration * 1000);
id = maps\mp\gametypes\_scrambler::playerSetHUDEmpScrambled( self.empEndTime, HUDtext, "emp" );
self thread digitalDistort(self.empDuration, id);
self thread empRumbleLoop( .75 );
self setEMPJammed( true );
self thread empGrenadeDeathWaiter( id );
wait ( self.empDuration );
self notify( "empGrenadeTimedOut" );
self checkToTurnOffEmp( id );
}
digitalDistort( empDuration, id )
{
self endon("death");
self endon("disconnect");
self endon("faux_spawn");
self endon("joined_team");
self DigitalDistortSetMaterial("digital_distort_mp");
self DigitalDistortSetParams(1.0, 1.0);
self thread watchDistortDisconnectDeath( id );
wait( 0.1 );
//self DigitalDistortSetMaterial("digital_distort_persistent_mp");
fadeTime = empDuration;
maxIntensity = 0.95;
minIntensity = 0.2;
intensityRange = maxIntensity - minIntensity;
increment = 0.1;
currentIntensity = maxIntensity;
while ( fadeTime > 0 )
{
currentIntensity = intensityRange * ( fadeTime / empDuration ) + minIntensity;
self DigitalDistortSetParams( currentIntensity, 1.0 );
fadeTime -= increment;
wait( increment );
}
self DigitalDistortSetParams( 0.0, 0.0 );
}
watchDistortDisconnectDeath( id )
{
self waittill_any( "death", "disconnect", "faux_spawn", "joined_team" );
if ( IsDefined( self ) )
{
self DigitalDistortSetParams(0.0, 0.0);
emp_hide_HUD( id );
}
}
empGrenadeDeathWaiter( id )
{
self notify( "empGrenadeDeathWaiter" );
self endon( "empGrenadeDeathWaiter" );
self endon( "empGrenadeTimedOut" );
self waittill( "death" );
self checkToTurnOffEmp( id );
}
checkToTurnOffEmp( id )
{
self.empGrenaded = false;
self setEMPJammed( false );
// enable exo, if gamemode appropriate
if( isAugmentedGameMode() )
{
self playerAllowHighJump(true, "empgrenade");
self playerAllowHighJumpDrop(true, "empgrenade");
self playerAllowBoostJump(true, "empgrenade");
self playerAllowPowerSlide(true, "empgrenade");
self playerAllowDodge(true, "empgrenade");
}
self DigitalDistortSetParams(0.0, 0.0);
self emp_hide_HUD( id );
}
empRumbleLoop( duration )
{
self endon("emp_rumble_loop");
self notify("emp_rumble_loop");
goalTime = getTime() + duration * 1000;
while ( getTime() < goalTime )
{
self PlayRumbleOnEntity( "damage_heavy" );
wait( 0.05 );
}
}
isEMPGrenaded()
{
return isDefined( self.empEndTime ) && gettime() < self.empEndTime;
}

View File

@ -0,0 +1,414 @@
#include maps\mp\_utility;
#include common_scripts\utility;
#include maps\mp\gametypes\_hud_util;
init()
{
if (isdefined(level.initedEntityHeadIcons))
return;
level.initedEntityHeadIcons = true;
if( level.multiTeamBased )
{
foreach ( teamName in level.teamNameList )
{
str_team_headicon = "entity_headicon_" + teamName;
game[ str_team_headicon ] = maps\mp\gametypes\_teams::MT_getTeamHeadIcon( teamName );
precacheShader( game[ str_team_headicon ] );
}
}
else
{
game["entity_headicon_allies"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "allies" );
game["entity_headicon_axis"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "axis" );
precacheShader( game["entity_headicon_allies"] );
precacheShader( game["entity_headicon_axis"] );
}
}
// This can show to single players or to teams. Showing to a single player destroys instances of
// the icon that are shown to their team. Showing to a team destroys instances of the icon that
// are shown to players on that team
setHeadIcon( showTo, icon, offset, width, height, archived, delay, constantSize, pinToScreenEdge, fadeOutPinnedIcon, is3D, targetTag )
{
if ( IsGameParticipant( showTo ) && !IsPlayer( showTo ) )
return; // Doesn't work for Agents, etc.
if ( !isDefined( self.entityHeadIcons ) )
self.entityHeadIcons = [];
if( !IsDefined( archived ) )
archived = true;
if( !IsDefined( delay ) )
delay = 0.05;
if( !IsDefined( constantSize ) )
constantSize = true;
if( !IsDefined( pinToScreenEdge ) )
pinToScreenEdge = true;
if( !IsDefined( fadeOutPinnedIcon ) )
fadeOutPinnedIcon = false;
if( !IsDefined( is3D ) )
is3D = true;
if( !IsDefined( targetTag ) )
targetTag = "";
if ( !isPlayer( showTo ) && showTo == "none" )
{
foreach ( key, headIcon in self.entityHeadIcons )
{
// TODO: remove and fix properly after ship
if ( isDefined( headIcon ) )
headIcon destroy();
self.entityHeadIcons[ key ] = undefined;
}
return;
}
if ( isPlayer( showTo ) )
{
if ( isDefined( self.entityHeadIcons[ showTo.guid ] ) )
{
self.entityHeadIcons[ showTo.guid ] destroy();
self.entityHeadIcons[ showTo.guid ] = undefined;
}
if ( icon == "" )
return;
// remove from team or we'd have two icons
if ( isDefined( self.entityHeadIcons[ showTo.team ] ) )
{
self.entityHeadIcons[ showTo.team ] destroy();
self.entityHeadIcons[ showTo.team ] = undefined;
}
headIcon = newClientHudElem( showTo );
self.entityHeadIcons[ showTo.guid ] = headIcon;
}
else
{
assert( showTo == "axis" || showTo == "allies" || isSubStr( showTo, "team_" ) );
assert( level.teamBased );
if ( isDefined( self.entityHeadIcons[ showTo ] ) )
{
self.entityHeadIcons[ showTo ] destroy();
self.entityHeadIcons[ showTo ] = undefined;
}
if ( icon == "" )
return;
foreach ( key, hudIcon in self.entityHeadIcons )
{
if ( key == "axis" || key == "allies" )
continue;
player = getPlayerForGuid( key );
if ( player.team == showTo )
{
self.entityHeadIcons[ key ] destroy();
self.entityHeadIcons[ key ] = undefined;
}
}
headIcon = newTeamHudElem( showTo );
self.entityHeadIcons[ showTo ] = headIcon;
}
if ( !isDefined( width ) || !isDefined( height ) )
{
width = 10;
height = 10;
}
headIcon.archived = archived;
headIcon.alpha = 0.85;
headIcon setShader( icon, width, height );
headIcon setWaypoint( constantSize, pinToScreenEdge, fadeOutPinnedIcon, is3D );
if( targetTag == "" )
{
headIcon.x = self.origin[0] + offset[0];
headIcon.y = self.origin[1] + offset[1];
headIcon.z = self.origin[2] + offset[2];
headIcon thread keepPositioned( self, offset, delay );
}
else
{
headIcon.x = offset[0];
headIcon.y = offset[1];
headIcon.z = offset[2];
headIcon SetTargetEnt( self, targetTag );
}
self thread destroyIconsOnDeath();
if ( isPlayer( showTo ) )
headIcon thread destroyOnOwnerDisconnect( showTo );
if ( isPlayer( self ) )
headIcon thread destroyOnOwnerDisconnect( self );
return headIcon;
}
destroyOnOwnerDisconnect( owner )
{
self endon ( "death" );
owner waittill ( "disconnect" );
self destroy();
}
destroyIconsOnDeath()
{
self notify ( "destroyIconsOnDeath" );
self endon ( "destroyIconsOnDeath" );
self waittill ( "death" );
foreach ( key, headIcon in self.entityHeadIcons )
{
// TODO: remove and fix properly after ship
if( !isDefined(headIcon) ) //needed for FFA host migration (when host has active head icons)
continue;
headIcon destroy();
}
}
keepPositioned( owner, offset, delay )
{
self endon ( "death" );
owner endon ( "death" );
owner endon ( "disconnect" );
pos = owner.origin;
for ( ;; )
{
if( !IsDefined( owner ) )
return;
if ( pos != owner.origin )
{
pos = owner.origin;
self.x = pos[0] + offset[0];
self.y = pos[1] + offset[1];
self.z = pos[2] + offset[2];
}
if ( delay > 0.05 )
{
self.alpha = 0.85;
self FadeOverTime( delay );
self.alpha = 0;
}
wait delay;
}
}
//facing will always place the marker offset from the top of the actor.
//this is useful if your entity can attach to walls or ceilings
setTeamHeadIcon( team, offset, targetTag, mountedObject ) // "allies", "axis", "all", "none"
{
if ( !level.teamBased )
return;
if( !IsDefined( targetTag ) )
targetTag = "";
if ( !isDefined( self.entityHeadIconTeam ) )
{
self.entityHeadIconTeam = "none";
self.entityHeadIcon = undefined;
}
if(IsDefined(mountedObject)&&mountedObject == false)
facing = undefined;
shader = game["entity_headicon_" + team];
self.entityHeadIconTeam = team;
if ( isDefined( offset ) )
self.entityHeadIconOffset = offset;
else
self.entityHeadIconOffset = (0,0,0);
self notify( "kill_entity_headicon_thread" );
if ( team == "none" )
{
if ( isDefined( self.entityHeadIcon ) )
self.entityHeadIcon destroy();
return;
}
headIcon = newTeamHudElem( team );
headIcon.archived = true;
headIcon.alpha = .8;
headIcon setShader( shader, 10, 10 );
headIcon setWaypoint( false, false, false, true );
self.entityHeadIcon = headIcon;
if(!IsDefined(mountedObject))
{
if( targetTag == "" )
{
headIcon.x = self.origin[0] + self.entityHeadIconOffset[0];
headIcon.y = self.origin[1] + self.entityHeadIconOffset[1];
headIcon.z = self.origin[2] + self.entityHeadIconOffset[2];
self thread keepIconPositioned();
}
else
{
headIcon.x = self.entityHeadIconOffset[0];
headIcon.y = self.entityHeadIconOffset[1];
headIcon.z = self.entityHeadIconOffset[2];
headIcon SetTargetEnt( self, targetTag );
}
}
else
{
up = AnglesToUp( self.angles );
markerPosOverride = self.origin + ( up * 28 );
if( targetTag == "" )
{
headIcon.x = markerPosOverride[0];
headIcon.y = markerPosOverride[1];
headIcon.z = markerPosOverride[2];
self thread keepIconPositioned( mountedObject );
}
else
{ headIcon.x = markerPosOverride[0];
headIcon.y = markerPosOverride[1];
headIcon.z = markerPosOverride[2];
headIcon SetTargetEnt( self, targetTag );
}
}
self thread destroyHeadIconsOnDeath();
}
setPlayerHeadIcon( player, offset, targetTag ) // "allies", "axis", "all", "none"
{
if ( level.teamBased )
return;
if( !IsDefined( targetTag ) )
targetTag = "";
if ( !isDefined( self.entityHeadIconTeam ) )
{
self.entityHeadIconTeam = "none";
self.entityHeadIcon = undefined;
}
self notify( "kill_entity_headicon_thread" );
if ( !isDefined( player ) )
{
if ( isDefined( self.entityHeadIcon ) )
self.entityHeadIcon destroy();
return;
}
team = player.team;
self.entityHeadIconTeam = team;
if ( isDefined( offset ) )
self.entityHeadIconOffset = offset;
else
self.entityHeadIconOffset = (0,0,0);
shader = game["entity_headicon_" + team];
headIcon = newClientHudElem( player );
headIcon.archived = true;
headIcon.alpha = .8;
headIcon setShader( shader, 10, 10 );
headIcon setWaypoint( false, false, false, true );
self.entityHeadIcon = headIcon;
if( targetTag == "" )
{
headIcon.x = self.origin[0] + self.entityHeadIconOffset[0];
headIcon.y = self.origin[1] + self.entityHeadIconOffset[1];
headIcon.z = self.origin[2] + self.entityHeadIconOffset[2];
self thread keepIconPositioned();
}
else
{
headIcon.x = self.entityHeadIconOffset[0];
headIcon.y = self.entityHeadIconOffset[1];
headIcon.z = self.entityHeadIconOffset[2];
headIcon SetTargetEnt( self, targetTag );
}
self thread destroyHeadIconsOnDeath();
}
keepIconPositioned( mountedObject )
{
self endon( "kill_entity_headicon_thread" );
self endon( "death" );
pos = self.origin;
while(1)
{
if ( pos != self.origin )
{
self updateHeadIconOrigin( mountedObject );
pos = self.origin;
}
wait .05;
}
}
destroyHeadIconsOnDeath()
{
self endon( "kill_entity_headicon_thread" );
self waittill ( "death" );
// TODO: remove and fix properly after ship
if( !isDefined(self.entityHeadIcon) )
return;
self.entityHeadIcon destroy();
}
updateHeadIconOrigin( mountedObject )
{
if(!IsDefined(mountedObject))
{
self.entityHeadIcon.x = self.origin[0] + self.entityHeadIconOffset[0];
self.entityHeadIcon.y = self.origin[1] + self.entityHeadIconOffset[1];
self.entityHeadIcon.z = self.origin[2] + self.entityHeadIconOffset[2];
}
else
{
up = AnglesToUp( self.angles );
markerPosOverride = self.origin + ( up * 28 );
self.entityHeadIcon.x = markerPosOverride[0];
self.entityHeadIcon.y = markerPosOverride[1];
self.entityHeadIcon.z = markerPosOverride[2];
}
}

1849
raw/maps/mp/_events.gsc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,239 @@
#include maps\mp\_utility;
#include common_scripts\utility;
/*
=============
///ScriptDocBegin
"Name: update_exo_battery_hud( <weapon_name> , <additional_endon_string> )"
"Summary: updates the LUI battery HUD."
"Module: Entity"
"CallOn: a player"
"MandatoryArg: <weapon_name>: string - the name of the weapon for which the player is using battery energy."
"MandatoryArg: <weapon_active_flag>: bool - tracks the active state of the weapon. Ends updating "
"Example: player thread update_exo_battery_hud( "exoshield_equipment_mp" );"
"SPMP: MP"
///ScriptDocEnd
=============
*/
update_exo_battery_hud( weapon_name )
{
level endon( "game_ended" );
self endon( "death" );
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "faux_spawn" );
self endon( "kill_battery" );
if ( !IsPlayer(self) )
return;
while ( self get_exo_ability_hud_omnvar_value( weapon_name, "ui_exo_battery_toggle" ) == 1 )
{
battery_energy = self BatteryGetCharge( weapon_name );
// Setting ui_exo_battery_level to the current energy level.
self maps\mp\_exo_battery::set_exo_ability_hud_omnvar( weapon_name, "ui_exo_battery_level", battery_energy );
wait( 0.05 );
}
}
/*
low_exo_battery_energy_sfx( weapon_active_flag ) // self = player
{
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "faux_spawn" );
self endon( "kill_battery" );
self.is_playing_low_battery_sfx = false;
while ( isReallyAlive( self ) && weapon_active_flag == true )
{
battery_energy = self BatteryGetCharge( weapon_name );
battery_capacity = self BatteryGetSize( weapon_name );
if ( !self.is_playing_low_battery_sfx && battery_energy < battery_capacity / 4 )
{
self.is_playing_low_battery_sfx = true;
self thread play_low_energy_sfx();
}
wait( 0.05 );
}
// Turning off the low battery SFX.
self notify( "stop_low_battery_sfx" );
self.is_playing_low_battery_sfx = false;
}
play_low_energy_sfx() // self = player
{
self endon( "death" );
self endon( "disconnect" );
self endon( "faux_spawn" );
self endon( "joined_team" );
self endon( "stop_low_battery_sfx" );
while ( true )
{
self PlayLocalSound( "mp_exo_bat_low" );
wait( 0.6 );
}
}
*/
/*
=============
///ScriptDocBegin
"Name: set_exo_hud_omnvar( <weapon_name> , <omnvar_name> , <omnvar_value> )"
"Summary: checks whether the player has the given weapon in their tactical or lethal slot and changes the appropriate omnvar."
"Module: Entity"
"CallOn: a player"
"MandatoryArg: <weapon_name>: string - name of the weapon you want to check for."
"MandatoryArg: <omnvar_name>: string - omnvar that you want to set."
"MandatoryArg: <omnvar_value>: value to which you want to set the omnvar."
"Example: player set_exo_hud_omnvar( "exoshield_equipment_mp", "ui_exo_battery_level", 0 );"
"SPMP: MP"
///ScriptDocEnd
=============
*/
set_exo_ability_hud_omnvar( weapon_name, omnvar_name, omnvar_value )
{
if ( self GetTacticalWeapon() == weapon_name )
{
self SetClientOmnvar( omnvar_name + "0", omnvar_value );
if ( omnvar_name == "ui_exo_battery_toggle" )
{
if ( omnvar_value == 1 )
{
self SetClientOmnvar( "ui_exo_battery_iconA", weapon_name );
}
}
}
else if ( self GetLethalWeapon() == weapon_name )
{
self SetClientOmnvar( omnvar_name + "1", omnvar_value );
if ( omnvar_name == "ui_exo_battery_toggle" )
{
if ( omnvar_value == 1 )
{
self SetClientOmnvar( "ui_exo_battery_iconB", weapon_name );
}
}
}
else
{
// The player doesn't have an Exo Ability - toggle all battery HUD off.
self SetClientOmnvar( "ui_exo_battery_iconA", "reset" );
self SetClientOmnvar( "ui_exo_battery_iconB", "reset" );
self SetClientOmnvar( "ui_exo_battery_toggle0", 0 );
self SetClientOmnvar( "ui_exo_battery_toggle1", 0 );
}
}
/*
=============
///ScriptDocBegin
"Name: get_exo_ability_hud_omnvar_value( <weapon_name> , <omnvar_name//self=player> , <returnsstring> )"
"Summary: returns the appropriate omnvar value for the Exo Ability corresponding to weapon_name. Returns -1 if the user doesn't have an Exo Ability."
"Module: Entity"
"CallOn: a player"
"MandatoryArg: <weapon_name>: must be a valid Exo Ability (see _utility::is_exo_ability_weapon())"
"MandatoryArg: <omnvar_name>: must be a valid omnvar in omnvars.csv (e.g. ui_exo_battery_toggle, ui_exo_battery_level, exo_ability_nrg_req, or exo_ability_nrg_total)."
"Example: omnvar = player get_exo_ability_hud_omnvar_value( weapon_name, "ui_exo_battery_toggle" );"
"SPMP: MP"
///ScriptDocEnd
=============
*/
get_exo_ability_hud_omnvar_value( weapon_name, omnvar_name )
{
Assert( is_exo_ability_weapon( weapon_name ) );
if ( self GetTacticalWeapon() == weapon_name )
{
return self GetClientOmnvar( omnvar_name + "0" );
}
else if ( self GetLethalWeapon() == weapon_name )
{
return self GetClientOmnvar( omnvar_name + "1" );
}
return -1;
}
play_insufficient_tactical_energy_sfx() // self = player
{
level endon( "game_ended" );
self endon( "disconnect" );
self endon( "death" );
self endon( "faux_spawn" );
self endon( "joined_team" );
self endon( "kill_battery" );
// Removing old notifies if they already exist.
self NotifyOnPlayerCommandRemove( "tried_left_exo_ability", "+smoke" );
// Need to wait, otherwise the below notification won't be added properly.
wait( 0.05 );
self NotifyOnPlayerCommand( "tried_left_exo_ability", "+smoke" );
while ( true )
{
self waittill( "tried_left_exo_ability" );
weapon_name = self GetTacticalWeapon();
if ( is_exo_ability_weapon( weapon_name ) )
{
if ( self BatteryGetCharge( weapon_name ) < BatteryReqToUse( weapon_name ) )
{
// The player doesn't have enough energy to use the Exo Ability.
self PlayLocalSound( "mp_exo_bat_empty" );
}
}
}
}
play_insufficient_lethal_energy_sfx() // self = player
{
level endon( "game_ended" );
self endon( "disconnect" );
self endon( "death" );
self endon( "faux_spawn" );
self endon( "joined_team" );
self endon( "kill_battery" );
// Removing old notify if it already exist.
self NotifyOnPlayerCommandRemove( "tried_right_exo_ability", "+frag" );
// Need to wait, otherwise the below notification won't be added properly.
wait( 0.05 );
self NotifyOnPlayerCommand( "tried_right_exo_ability", "+frag" );
while ( true )
{
self waittill( "tried_right_exo_ability" );
weapon_name = self GetLethalWeapon();
if ( is_exo_ability_weapon( weapon_name ) )
{
if ( self BatteryGetCharge( weapon_name ) < BatteryReqToUse( weapon_name ) )
{
// The player doesn't have enough energy to use the Exo Ability.
self PlayLocalSound( "mp_exo_bat_empty" );
}
}
}
}

376
raw/maps/mp/_exo_cloak.gsc Normal file
View File

@ -0,0 +1,376 @@
#include maps\mp\_utility;
#include common_scripts\utility;
#include maps\mp\_snd_common_mp;
//==============================================================================
give_exo_cloak() // self = player, should not be threaded
//==============================================================================
{
cloakWeapon = get_exo_cloak_weapon();
if ( self HasWeapon( cloakWeapon ) )
return;
self giveWeapon( cloakWeapon );
self BatterySetDischargeScale( cloakWeapon, 1.0 );
self.exo_cloak_on = false;
self.exo_cloak_off_time = undefined;
if ( self GetTacticalWeapon() == cloakWeapon )
{
self SetClientOmnvar( "ui_exo_battery_level0", self BatteryGetCharge( cloakWeapon ) );
self SetClientOmnvar( "exo_ability_nrg_req0", BatteryReqToUse( cloakWeapon ) );
self SetClientOmnvar( "exo_ability_nrg_total0", self BatteryGetSize( cloakWeapon ) );
}
else if ( self GetLethalWeapon() == cloakWeapon )
{
self SetClientOmnvar( "ui_exo_battery_level1", self BatteryGetCharge( cloakWeapon ) );
self SetClientOmnvar( "exo_ability_nrg_req1", BatteryReqToUse( cloakWeapon ) );
self SetClientOmnvar( "exo_ability_nrg_total1", self BatteryGetSize( cloakWeapon ) );
}
if ( !IsDefined( self.exocloak ) )
{
self.exocloak = SpawnStruct();
}
self.exocloak.costume = [];
self.exocloak.costume["viewmodel"] = self GetViewModel();
self.exocloak.costume["body"] = self GetModelFromEntity();
assert( IsDefined( self.exocloak.costume["viewmodel"] ) );
assert( IsDefined( self.exocloak.costume["body"] ) );
self notify( "exo_cloak_reset" ); // clear any old threads that were spawned from a previous iteration of this function... this is required for timing reasons
self thread wait_for_exocloak_cancel();
self thread wait_for_exocloak_pressed();
self thread wait_for_player_death();
self thread wait_for_game_end();
}
//==============================================================================
wait_for_exocloak_pressed() // should be threaded
//==============================================================================
{
level endon( "game_ended" );
self endon( "death" );
self endon( "disconnect" );
self endon( "faux_spawn" );
self endon( "joined_team" );
self endon( "exo_cloak_reset" );
while ( true )
{
self waittill( "exo_ability_activate", weaponName );
if ( weaponName == level.cloakWeapon )
{
if ( !self IsCloaked() )
self thread handle_exocloak();
else
self active_cloaking_disable( true );
}
else if ( !is_exo_ability_weapon( weaponname ) )
{
// Non-Exo-Abilities should deactivate cloak.
self active_cloaking_disable( true );
}
}
}
//==============================================================================
wait_for_exocloak_cancel() // should be threaded
//==============================================================================
{
level endon( "game_ended" );
self endon( "death" );
self endon( "disconnect" );
self endon( "faux_spawn" );
self endon( "joined_team" );
self endon( "exo_cloak_reset" );
while ( true )
{
self waittill_any( "using_remote", "weapon_fired", "melee_fired", "ground_slam", "grenade_fire" );
self active_cloaking_disable( true );
}
}
//==============================================================================
wait_for_player_death() // should be threaded
//==============================================================================
{
level endon( "game_ended" );
self endon( "disconnect" );
self endon( "exo_cloak_reset" );
self waittill_any( "death", "faux_spawn", "joined_team" );
self active_cloaking_disable( true );
}
//==============================================================================
handle_exocloak() // should be threaded
//==============================================================================
{
level endon( "game_ended" );
self endon( "disconnect" );
self endon( "death" );
self endon( "faux_spawn" );
self endon( "joined_team" );
self endon( "exo_cloak_disabled" );
self endon( "exo_cloak_reset" );
if ( self BatteryGetCharge( level.cloakWeapon ) > 0 )
{
self active_cloaking_enable();
while ( self BatteryGetCharge( level.cloakWeapon ) > 0 )
{
wait 0.05;
}
self active_cloaking_disable( true );
}
}
//==============================================================================
active_cloaking_enable() // self == player, should not be threaded
//==============================================================================
{
println( "active_cloaking_enable() called." );
self.exo_cloak_on = true;
self.exo_cloak_off_time = undefined;
self CloakingEnable();
self hideAttachmentsWhileCloaked();
self BatteryDischargeBegin( level.cloakWeapon );
self maps\mp\_exo_battery::set_exo_ability_hud_omnvar( level.cloakWeapon, "ui_exo_battery_toggle", 1 );
self thread maps\mp\_exo_battery::update_exo_battery_hud( level.cloakWeapon );
self snd_message( "mp_exo_cloak_activate" );
self.pers["numberOfTimesCloakingUsed"]++;
if ( isdefined ( level.isHorde ) )
{
wait 2;
self.ignoreme = true;
}
}
//==============================================================================
active_cloaking_disable( should_play_fx ) // self == player, should not be threaded
//==============================================================================
{
if ( !IsDefined( should_play_fx ) )
{
should_play_fx = true;
}
if ( !self IsCloaked() )
return;
println( "active_cloaking_disable() called." );
self.exo_cloak_on = false;
self.exo_cloak_off_time = GetTime();
self CloakingDisable();
self showAttachmentsAfterCloak();
if ( isdefined ( level.isHorde ) )
self.ignoreme = false;
self BatteryDischargeEnd( level.cloakWeapon );
self maps\mp\_exo_battery::set_exo_ability_hud_omnvar( level.cloakWeapon, "ui_exo_battery_toggle", 0 );
if ( should_play_fx )
self snd_message( "mp_exo_cloak_deactivate" );
self notify( "exo_cloak_disabled" );
}
//==============================================================================
// Deactivates Exo Cloak and takes it away without the deactivation sound.
take_exo_cloak() // self = player, should not be threaded
//==============================================================================
{
cloakWeapon = get_exo_cloak_weapon();
self notify( "kill_battery" );
self active_cloaking_disable( false );
self takeWeapon( cloakWeapon );
self notify( "exo_cloak_reset" );
}
//==============================================================================
wait_for_game_end() // self = player, should be threaded
//==============================================================================
{
self endon( "death" );
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "faux_spawn" );
self endon( "exo_cloak_reset" );
level waittill( "game_ended" );
self active_cloaking_disable( true );
}
//==============================================================================
hideAttachmentsWhileCloaked() // self = player, should not be threaded
//==============================================================================
{
// Exo Overclock
if ( self HasWeapon( "adrenaline_mp" ) )
{
if ( IsDefined( self.overclock_on ) && self.overclock_on == true )
{
KillFXOnTag( level.exo_overclock_vfx_le_active, self, "J_Hip_LE" );
KillFXOnTag( level.exo_overclock_vfx_ri_active, self, "J_Hip_RI" );
}
else
{
KillFXOnTag( level.exo_overclock_vfx_le_inactive, self, "J_Hip_LE" );
KillFXOnTag( level.exo_overclock_vfx_ri_inactive, self, "J_Hip_RI" );
}
}
// Exo Trophy
if ( self HasWeapon( "exorepulsor_equipment_mp" ) )
{
if ( IsDefined( self.repulsorActive ) && self.repulsorActive == true )
{
KillFXOnTag( level.exo_repulsor_player_vfx_active, self, "TAG_JETPACK" );
}
else
{
KillFXOnTag( level.exo_repulsor_player_vfx_inactive, self, "TAG_JETPACK" );
}
}
// Exo Ping
if ( self HasWeapon( "exoping_equipment_mp" ) )
{
if ( IsDefined( self.exo_ping_on ) && self.exo_ping_on == true )
{
KillFXOnTag( level.exo_ping_vfx_active, self, "J_SpineUpper" );
}
else
{
KillFXOnTag( level.exo_ping_vfx_inactive, self, "J_SpineUpper" );
}
}
// Exo Stim
if ( self HasWeapon( "extra_health_mp" ) )
{
if ( IsDefined( self.exo_health_on ) && self.exo_health_on == true )
{
KillFXOnTag( level.exo_health_le_active_vfx, self, "J_Shoulder_LE" );
KillFXOnTag( level.exo_health_rt_active_vfx, self, "J_Shoulder_RI" );
}
else
{
KillFXOnTag( level.exo_health_le_inactive_vfx, self, "J_Shoulder_LE" );
KillFXOnTag( level.exo_health_rt_inactive_vfx, self, "J_Shoulder_RI" );
}
}
}
//==============================================================================
showAttachmentsAfterCloak() // self = player, should not be threaded
//==============================================================================
{
// Exo Overclock
if ( self HasWeapon( "adrenaline_mp" ) )
{
if ( IsDefined( self.overclock_on ) && self.overclock_on == true )
{
PlayFXOnTag( level.exo_overclock_vfx_le_active, self, "J_Hip_LE" );
PlayFXOnTag( level.exo_overclock_vfx_ri_active, self, "J_Hip_RI" );
}
else
{
PlayFXOnTag( level.exo_overclock_vfx_le_inactive, self, "J_Hip_LE" );
PlayFXOnTag( level.exo_overclock_vfx_ri_inactive, self, "J_Hip_RI" );
}
}
// Exo Trophy
if ( self HasWeapon( "exorepulsor_equipment_mp" ) )
{
if ( IsDefined( self.repulsorActive ) && self.repulsorActive == true )
{
PlayFXOnTag( level.exo_repulsor_player_vfx_active, self, "TAG_JETPACK" );
}
else
{
PlayFXOnTag( level.exo_repulsor_player_vfx_inactive, self, "TAG_JETPACK" );
}
}
// Exo Ping
if ( self HasWeapon( "exoping_equipment_mp" ) )
{
if ( IsDefined( self.exo_ping_on ) && self.exo_ping_on == true )
{
PlayFXOnTag( level.exo_ping_vfx_active, self, "J_SpineUpper" );
}
else
{
PlayFXOnTag( level.exo_ping_vfx_inactive, self, "J_SpineUpper" );
}
}
// Exo Stim
if ( self HasWeapon( "extra_health_mp" ) )
{
if ( IsDefined( self.exo_health_on ) && self.exo_health_on == true )
{
PlayFXOnTag( level.exo_health_le_active_vfx, self, "J_Shoulder_LE" );
PlayFXOnTag( level.exo_health_rt_active_vfx, self, "J_Shoulder_RI" );
}
else
{
PlayFXOnTag( level.exo_health_le_inactive_vfx, self, "J_Shoulder_LE" );
PlayFXOnTag( level.exo_health_rt_inactive_vfx, self, "J_Shoulder_RI" );
}
}
}
get_exo_cloak_weapon()
{
if ( IsDefined( level.cloakWeapon ) )
return level.cloakWeapon;
level.cloakWeapon = "exocloak_equipment_mp";
if ( isdefined ( level.isHorde ) )
level.cloakWeapon = "exocloakhorde_equipment_mp";
return level.cloakWeapon;
}

Some files were not shown because too many files have changed in this diff Show More