This commit is contained in:
reaaLx
2024-09-04 23:46:54 +10:00
parent 5f950a3356
commit 1ea2370337
471 changed files with 108331 additions and 0 deletions

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "accessories_windsock";
if ( SP )
{
level._anim_prop_models[ model ][ "wind_medium" ] = %windsock_wind_medium;
}
else
level._anim_prop_models[ model ][ "wind_medium" ] = "windsock_wind_medium";
}

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "com_roofvent2_animated";
if ( SP )
{
level._anim_prop_models[ model ][ "rotate" ] = %roofvent_rotate;
}
else
level._anim_prop_models[ model ][ "rotate" ] = "roofvent_rotate";
}

View File

@ -0,0 +1,13 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Uses .animation
model = "foliage_dead_pine_lg_animated_sway2";
level._anim_prop_models[ model ][ "sway2" ] = "foliage_dead_pine_lg_mp_sway2";
}
// SP not currently supported because this requires updating "animated_props" animtree

View File

@ -0,0 +1,13 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Uses .animation
model = "foliage_dead_pine_med_animated_sway2";
level._anim_prop_models[ model ][ "sway2" ] = "foliage_dead_pine_med_mp_sway2";
}
// SP not currently supported because this requires updating "animated_props" animtree

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_desertbrush_1_animated";
if ( SP )
{
level._anim_prop_models[ model ][ "sway" ] = %foliage_desertbrush_1_sway;
}
else
level._anim_prop_models[ model ][ "sway" ] = "foliage_desertbrush_1_sway";
}

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_pacific_fern01_animated";
if ( SP )
{
level._anim_prop_models[ model ][ "sway" ] = %foliage_pacific_fern01_sway;
}
else
level._anim_prop_models[ model ][ "sway" ] = "foliage_pacific_fern01_sway";
}

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_pacific_fern02_animated";
if ( SP )
{
level._anim_prop_models[ model ][ "sway" ] = %foliage_pacific_fern02_sway;
}
else
level._anim_prop_models[ model ][ "sway" ] = "foliage_pacific_fern02_sway";
}

View File

@ -0,0 +1,12 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
model = "foliage_pacific_palms06_animated";
level._anim_prop_models[ model ][ "sway" ] = "foliage_pacific_palms06_sway";
}
// SP not currently supported because this requires updating "animated_props" animtree

View File

@ -0,0 +1,21 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_pacific_palms08_animated";
if ( SP )
{
level._anim_prop_models[ model ][ "sway" ] = %foliage_pacific_palms08_sway;
}
else
level._anim_prop_models[ model ][ "sway" ] = "foliage_pacific_palms08_sway";
}

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_pacific_tropic_shrub01_animated";
if ( SP )
{
level._anim_prop_models[ model ][ "sway" ] = %foliage_pacific_tropic_shrub01_sway;
}
else
level._anim_prop_models[ model ][ "sway" ] = "foliage_pacific_tropic_shrub01_sway";
}

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_red_pine_lg_animated";
if ( SP )
{
level._anim_prop_models[ model ][ "sway" ] = %foliage_red_pine_lg_sway;
}
else
level._anim_prop_models[ model ][ "sway" ] = "foliage_red_pine_lg_sway";
}

View File

@ -0,0 +1,12 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
model = "foliage_tree_grey_oak_lg_a_animated";
level._anim_prop_models[ model ][ "sway" ] = "foliage_tree_grey_oak_lg_a_sway";
}
// SP not currently supported because this requires updating "animated_props" animtree

View File

@ -0,0 +1,12 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
model = "foliage_tree_grey_oak_xl_a_animated";
level._anim_prop_models[ model ][ "sway" ] = "foliage_tree_grey_oak_xl_a_sway";
}
// SP not currently supported because this requires updating "animated_props" animtree

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_tree_oak_1_animated2";
if ( SP )
{
level._anim_prop_models[ model ][ "sway" ] = %foliage_tree_oak_1_sway;
}
else
level._anim_prop_models[ model ][ "sway" ] = "foliage_tree_oak_1_sway";
}

View File

@ -0,0 +1,24 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_tree_palm_bushy_1";
if ( SP )
{
level._anim_prop_models[ model ][ "still" ] = %palmtree_bushy1_still;
level._anim_prop_models[ model ][ "strong" ] = %palmtree_bushy1_sway;
}
else
level._anim_prop_models[ model ][ "strong" ] = "palmtree_mp_bushy1_sway";
}
3

View File

@ -0,0 +1,23 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_tree_palm_bushy_2";
if ( SP )
{
level._anim_prop_models[ model ][ "still" ] = %palmtree_bushy2_still;
level._anim_prop_models[ model ][ "strong" ] = %palmtree_bushy2_sway;
}
else
level._anim_prop_models[ model ][ "strong" ] = "palmtree_mp_bushy2_sway";
}

View File

@ -0,0 +1,23 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_tree_palm_bushy_3";
if ( SP )
{
level._anim_prop_models[ model ][ "still" ] = %palmtree_bushy3_still;
level._anim_prop_models[ model ][ "strong" ] = %palmtree_bushy3_sway;
}
else
level._anim_prop_models[ model ][ "strong" ] = "palmtree_mp_bushy3_sway";
}

View File

@ -0,0 +1,23 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_tree_palm_tall_1";
if ( SP )
{
level._anim_prop_models[ model ][ "still" ] = %palmtree_tall1_still;
level._anim_prop_models[ model ][ "strong" ] = %palmtree_tall1_sway;
}
else
level._anim_prop_models[ model ][ "strong" ] = "palmtree_mp_tall1_sway";
}

View File

@ -0,0 +1,23 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_tree_palm_tall_2";
if ( SP )
{
level._anim_prop_models[ model ][ "still" ] = %palmtree_tall2_still;
level._anim_prop_models[ model ][ "strong" ] = %palmtree_tall2_sway;
}
else
level._anim_prop_models[ model ][ "strong" ] = "palmtree_mp_tall2_sway";
}

View File

@ -0,0 +1,23 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_tree_palm_tall_3";
if ( SP )
{
level._anim_prop_models[ model ][ "still" ] = %palmtree_tall3_still;
level._anim_prop_models[ model ][ "strong" ] = %palmtree_tall3_sway;
}
else
level._anim_prop_models[ model ][ "strong" ] = "palmtree_mp_tall3_sway";
}

View File

@ -0,0 +1,12 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
model = "foliage_tree_river_birch_lg_a_animated";
level._anim_prop_models[ model ][ "sway" ] = "foliage_tree_river_birch_lg_a_sway";
}
// SP not currently supported because this requires updating "animated_props" animtree

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "foliage_tree_river_birch_med_a_animated";
if ( SP )
{
level._anim_prop_models[ model ][ "sway" ] = %foliage_tree_river_birch_med_a_sway;
}
else
level._anim_prop_models[ model ][ "sway" ] = "foliage_tree_river_birch_med_a_sway";
}

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "highrise_fencetarp_01";
if ( SP )
{
level._anim_prop_models[ model ][ "wind" ] = %highrise_fencetarp_01_wind;
}
else
level._anim_prop_models[ model ][ "wind" ] = "highrise_fencetarp_01_wind";
}

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "highrise_fencetarp_09";
if ( SP )
{
level._anim_prop_models[ model ][ "wind" ] = %highrise_fencetarp_09_wind;
}
else
level._anim_prop_models[ model ][ "wind" ] = "highrise_fencetarp_09_wind";
}

View File

@ -0,0 +1,22 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level._anim_prop_models ) )
level._anim_prop_models = [];
// Would use isSP() but this runs before we can
mapname = tolower( getdvar( "mapname" ) );
SP = true;
if ( string_starts_with( mapname, "mp_" ) )
SP = false;
model = "color_tv_sign";
if ( SP )
{
level._anim_prop_models[ model ][ "sway" ] = %nx_pr_color_tv_sign_sway;
}
else
level._anim_prop_models[ model ][ "sway" ] = "nx_pr_color_tv_sign_sway";
}

View File

@ -0,0 +1,15 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
//* Fog section *
setDevDvar( "scr_fog_disable", "0" );
setExpFog( 1601.52, 28892.1, 0.627451, 0.717647, 0.745098, 0.38927, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0.839216, 0.690196, 0.568627, (0.00390755, 0.00323934, -1), 83.5416, 92.7872, 2.25266 );
VisionSetNaked( "mp_nx_fallout", 0 );
}

View File

@ -0,0 +1,16 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
//* Fog section *
setDevDvar( "scr_fog_disable", "0" );
setExpFog( 722, 50000, 0.7372549, 0.7372549, 0.7686275, 0.05416667, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0.8392157, 0.6862745, 0.5647059, ( 0.00390755, 0, 0 ), 0, 92, 2.25 );
//setExpFog( 2702.33, 9214.93, 0.870588, 0.45098, 0.341176, 0.407261, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0.839216, 0.690196, 0.568627, (0.00390755, 0.00323934, -1), 83.5416, 92.7872, 2.25266 );
VisionSetNaked( "mp_nx_galleria", 0 );
}

View File

@ -0,0 +1,15 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
//* Fog section *
setDevDvar( "scr_fog_disable", "0" );
setExpFog( 1711.38, 760.507, 0.254902, 0.392157, 0.282353, 0.33911, 0, 0, 0, 1, 1, 1, 1, 1, 1);
VisionSetNaked( "mp_nx_meteor", 0 );
}

View File

@ -0,0 +1,17 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
//* Fog section *
setDevDvar( "scr_fog_disable", "0" );
//setExpFog( 0, 80579, 0.627451, 0.717647, 0.745098, 0.38927, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0.839216, 0.690196, 0.568627, (0.00390755, 0.00323934, -1), 83.5416, 92.7872, 2.25266 );
//setExpFog (<Near Plane>, <Half Plane>, <Fog Color.R>, <Fog Color.G>, <Fog Color.B>,<Maximum Opacity>, <Transition Time>, <Mult Fog Blend Value>, <NearMultFogColor.R>, <NearMultFogColor.G>, <NearMultFogColor.B>, <FarMultFogColor.R>,<FarMultFogColor.G>, <FarMultFogColor.B>);
setExpFog( 1600, 50000, 0.6784314, 0.8156863, 0.9882353, 0.0505, 0, 0, 0, 1, 1, 1, 1, 1, 1 );
VisionSetNaked( "mp_nx_pitstop", 0 );
}

View File

@ -0,0 +1,15 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
//* Fog section *
setDevDvar( "scr_fog_disable", "0" );
setExpFog( 3133.49, 26045.9, 0.627451, 0.717647, 0.745098, 0.38927, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0.839216, 0.690196, 0.568627, (0.00390755, 0.00323934, -1), 83.5416, 92.7872, 2.25266 );
VisionSetNaked( "mp_nx_skylab", 0 );
}

View File

@ -0,0 +1,15 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
//* Fog section *
setDevDvar( "scr_fog_disable", "0" );
setExpFog( 4804.66, 23283.2, 0.627451, 0.717647, 0.745098, 0.38927, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0.839216, 0.690196, 0.568627, (0.00390755, 0.00323934, -1), 83.5416, 92.7872, 2.25266 );
VisionSetNaked( "mp_nx_stasis", 0 );
}

View File

@ -0,0 +1,15 @@
// _createart generated. modify at your own risk. Changing values should be fine.
main()
{
level.tweakfile = true;
//* Fog section *
setDevDvar( "scr_fog_disable", "0" );
setExpFog( 23185.5, 78310.7, 0.627451, 0.717647, 0.745098, 0.38927, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0.839216, 0.690196, 0.568627, (0.00390755, 0.00323934, -1), 83.5416, 92.7872, 2.25266 );
VisionSetNaked( "mp_nx_ugvhh", 0 );
}

View File

@ -0,0 +1,130 @@
//_createfx generated. Do not touch!!
#include common_scripts\utility;
#include common_scripts\_createfx;
main()
{
// CreateFX entities size: 19
ent = createOneshotEffect( "nx_mp_ash_aftermath_fallout" );
ent.v[ "origin" ] = ( 2017.18, -1199.75, 204.125 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_mp_ash_aftermath_fallout";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "battlefield_smokebank_S_warm_thick" );
ent.v[ "origin" ] = ( 2438.32, -1227.45, -71.929 );
ent.v[ "angles" ] = ( 270, 0, -90 );
ent.v[ "fxid" ] = "battlefield_smokebank_S_warm_thick";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "nx_mp_ash_aftermath_fallout" );
ent.v[ "origin" ] = ( 3470.61, -1185.94, 333.584 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_mp_ash_aftermath_fallout";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "nx_mp_ash_aftermath_fallout" );
ent.v[ "origin" ] = ( 3951.19, 420.776, 158.521 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_mp_ash_aftermath_fallout";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "nx_mp_ash_aftermath_fallout" );
ent.v[ "origin" ] = ( 4120.57, 1965.89, 284.069 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_mp_ash_aftermath_fallout";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "nx_mp_ash_aftermath_fallout" );
ent.v[ "origin" ] = ( 3221.7, 2587.15, 278.106 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_mp_ash_aftermath_fallout";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "nx_mp_ash_aftermath_fallout" );
ent.v[ "origin" ] = ( 1348.14, 939.963, 250.806 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_mp_ash_aftermath_fallout";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "battlefield_smokebank_S_warm_thick" );
ent.v[ "origin" ] = ( 2669.5, 670.057, -54.8789 );
ent.v[ "angles" ] = ( 270, 359.464, -89.4642 );
ent.v[ "fxid" ] = "battlefield_smokebank_S_warm_thick";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "tank_fire_hatch" );
ent.v[ "origin" ] = ( 2499.02, 1250.83, -0.891108 );
ent.v[ "angles" ] = ( 311.769, 179.925, -175.979 );
ent.v[ "fxid" ] = "tank_fire_hatch";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "battlefield_smokebank_S_warm_thick" );
ent.v[ "origin" ] = ( 1678.6, -467.411, 4.4418 );
ent.v[ "angles" ] = ( 272, 0, -90 );
ent.v[ "fxid" ] = "battlefield_smokebank_S_warm_thick";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "battlefield_smokebank_S_warm_thick" );
ent.v[ "origin" ] = ( 1847.72, -1496.66, 37.6898 );
ent.v[ "angles" ] = ( 272, 0, -90 );
ent.v[ "fxid" ] = "battlefield_smokebank_S_warm_thick";
ent.v[ "delay" ] = -15;
ent = createExploder( "No FX" );
ent.v[ "origin" ] = ( 2312, 760, 72.1 );
ent.v[ "angles" ] = ( 0, 90, 0 );
ent.v[ "fxid" ] = "No FX";
ent.v[ "delay" ] = 0;
ent.v[ "exploder" ] = "pf220_1";
ent = createExploder( "No FX" );
ent.v[ "origin" ] = ( 2312, 762, 70.1 );
ent.v[ "angles" ] = ( 281.421, 270, 0 );
ent.v[ "fxid" ] = "No FX";
ent.v[ "delay" ] = 0;
ent.v[ "exploder" ] = "pf220_1";
ent = createExploder( "No FX" );
ent.v[ "origin" ] = ( 1810.12, -1525.88, 78.1 );
ent.v[ "angles" ] = ( 286.848, 225, 0 );
ent.v[ "fxid" ] = "No FX";
ent.v[ "delay" ] = 0;
ent.v[ "exploder" ] = "pf221_2";
ent = createExploder( "No FX" );
ent.v[ "origin" ] = ( 1808, -1528, 80.1 );
ent.v[ "angles" ] = ( 0, 45, 0 );
ent.v[ "fxid" ] = "No FX";
ent.v[ "delay" ] = 0;
ent.v[ "exploder" ] = "pf221_2";
ent = createExploder( "No FX" );
ent.v[ "origin" ] = ( 1818.12, -1525.88, 78 );
ent.v[ "angles" ] = ( 0, 225, 0 );
ent.v[ "fxid" ] = "No FX";
ent.v[ "delay" ] = 0;
ent.v[ "exploder" ] = "pf228_1";
ent = createExploder( "No FX" );
ent.v[ "origin" ] = ( 1816, -1528, 80 );
ent.v[ "angles" ] = ( 0, 45, 0 );
ent.v[ "fxid" ] = "No FX";
ent.v[ "delay" ] = 0;
ent.v[ "exploder" ] = "pf228_1";
ent = createExploder( "No FX" );
ent.v[ "origin" ] = ( 1530.12, 2346.12, 86 );
ent.v[ "angles" ] = ( 0, 225, 0 );
ent.v[ "fxid" ] = "No FX";
ent.v[ "delay" ] = 0;
ent.v[ "exploder" ] = "pf229_2";
ent = createExploder( "No FX" );
ent.v[ "origin" ] = ( 1528, 2344, 88 );
ent.v[ "angles" ] = ( 0, 45, 0 );
ent.v[ "fxid" ] = "No FX";
ent.v[ "delay" ] = 0;
ent.v[ "exploder" ] = "pf229_2";
// CreateFX entities placed: 19
}

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,6 @@
//_createfx generated. Do not touch!!
#include common_scripts\utility;
#include common_scripts\_createfx;
main()
{
}

View File

@ -0,0 +1,62 @@
//_createfx generated. Do not touch!!
#include common_scripts\utility;
#include common_scripts\_createfx;
main()
{
// CreateFX entities size: 17
ent = createOneshotEffect( "snow_light" );
ent.v[ "origin" ] = ( 2607.87, 7429.89, 100 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "snow_light";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "snow_light" );
ent.v[ "origin" ] = ( 732.965, 8613.04, 100 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "snow_light";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "snow_light" );
ent.v[ "origin" ] = ( 3675.38, 8377.6, 100 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "snow_light";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "snow_light" );
ent.v[ "origin" ] = ( 4016.22, 7012.39, 100 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "snow_light";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "snow_light" );
ent.v[ "origin" ] = ( 1654.56, 5970.16, 100 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "snow_light";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "snow_light" );
ent.v[ "origin" ] = ( 1162.62, 6763.8, 100 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "snow_light";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "snow_light" );
ent.v[ "origin" ] = ( 3730.14, 5152.77, 100 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "snow_light";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "snow_light" );
ent.v[ "origin" ] = ( 2911.27, 5955.64, 100 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "snow_light";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "snow_light" );
ent.v[ "origin" ] = ( 2105.03, 8611.94, 100 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "snow_light";
ent.v[ "delay" ] = -15;
// CreateFX entities placed: 9
}

View File

@ -0,0 +1,124 @@
//_createfx generated. Do not touch!!
#include common_scripts\utility;
#include common_scripts\_createfx;
main()
{
// CreateFX entities size: 24
ent = createOneshotEffect( "ash_aftermath_ugv_mp" );
ent.v[ "origin" ] = ( 539.157, 1279.55, 596.643 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "ash_aftermath_ugv_mp";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "ash_aftermath_ugv_mp" );
ent.v[ "origin" ] = ( 1565.22, 3073.81, 699.572 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "ash_aftermath_ugv_mp";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "ash_aftermath_ugv_mp" );
ent.v[ "origin" ] = ( 5983.87, 4730.37, 825.99 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "ash_aftermath_ugv_mp";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "firelp_large_pm_bh1" );
ent.v[ "origin" ] = ( 1170.73, 1200.51, 226 );
ent.v[ "angles" ] = ( 296, 180, 180 );
ent.v[ "fxid" ] = "firelp_large_pm_bh1";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "firelp_med_pm_bh1" );
ent.v[ "origin" ] = ( 815.138, 1434.87, 250.526 );
ent.v[ "angles" ] = ( 282, 180, 180 );
ent.v[ "fxid" ] = "firelp_med_pm_bh1";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "firelp_med_pm_bh1" );
ent.v[ "origin" ] = ( 1087.65, 832.262, 442 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "firelp_med_pm_bh1";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "large_fire" );
ent.v[ "origin" ] = ( -1530.24, 2073.87, 489.872 );
ent.v[ "angles" ] = ( 4, 4, 0 );
ent.v[ "fxid" ] = "large_fire";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "nx_smoke_plume_periph_large_black" );
ent.v[ "origin" ] = ( -1346.8, 894.056, 301.98 );
ent.v[ "angles" ] = ( 270, 320.936, 39.0635 );
ent.v[ "fxid" ] = "nx_smoke_plume_periph_large_black";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "nx_smoke_plume_periph_large_black" );
ent.v[ "origin" ] = ( 555.964, -1769.39, 563.125 );
ent.v[ "angles" ] = ( 304.108, 164.878, 93.3438 );
ent.v[ "fxid" ] = "nx_smoke_plume_periph_large_black";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "nx_smoke_plume_periph_large_black" );
ent.v[ "origin" ] = ( 4200.01, 1853.93, 199.766 );
ent.v[ "angles" ] = ( 337.767, 305.881, 62.5061 );
ent.v[ "fxid" ] = "nx_smoke_plume_periph_large_black";
ent.v[ "delay" ] = -15;
ent = createOneshotEffect( "nx_smoke_plume_periph_large_black" );
ent.v[ "origin" ] = ( 7216.51, 5639.86, 479.075 );
ent.v[ "angles" ] = ( 284, 90, 96 );
ent.v[ "fxid" ] = "nx_smoke_plume_periph_large_black";
ent.v[ "delay" ] = -15;
ent = createExploder( "nx_orbital_laser_01" );
ent.v[ "origin" ] = ( -2045.08, 3938.13, 712.706 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_orbital_laser_01";
ent.v[ "delay" ] = 0;
ent.v[ "flag" ] = "nil";
ent.v[ "exploder" ] = "fx_orbital_laser_02";
ent.v[ "soundalias" ] = "nil";
ent.v[ "loopsound" ] = "nil";
ent = createExploder( "nx_orbital_laser_01" );
ent.v[ "origin" ] = ( -2005.55, 4289.13, 725.282 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_orbital_laser_01";
ent.v[ "delay" ] = 0;
ent.v[ "flag" ] = "nil";
ent.v[ "exploder" ] = "fx_orbital_laser_04";
ent.v[ "soundalias" ] = "nil";
ent.v[ "loopsound" ] = "nil";
ent = createExploder( "nx_orbital_laser_01" );
ent.v[ "origin" ] = ( -1867.38, 5205.8, 694.934 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_orbital_laser_01";
ent.v[ "delay" ] = 0;
ent.v[ "flag" ] = "nil";
ent.v[ "exploder" ] = "fx_orbital_laser_05";
ent.v[ "soundalias" ] = "nil";
ent.v[ "loopsound" ] = "nil";
ent = createExploder( "nx_orbital_laser_01" );
ent.v[ "origin" ] = ( -1493.62, 5253.13, 704.413 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_orbital_laser_01";
ent.v[ "delay" ] = 0;
ent.v[ "flag" ] = "nil";
ent.v[ "exploder" ] = "fx_orbital_laser_03";
ent.v[ "soundalias" ] = "nil";
ent.v[ "loopsound" ] = "nil";
ent = createExploder( "nx_orbital_laser_02" );
ent.v[ "origin" ] = ( -2019.07, 4678.03, 685.431 );
ent.v[ "angles" ] = ( 270, 0, 0 );
ent.v[ "fxid" ] = "nx_orbital_laser_02";
ent.v[ "delay" ] = 0;
ent.v[ "flag" ] = "nil";
ent.v[ "exploder" ] = "fx_orbital_laser_01";
ent.v[ "soundalias" ] = "nil";
ent.v[ "loopsound" ] = "nil";
// CreateFX entities placed: 16
}

471
maps/mp/_adrenaline.gsc Normal file
View File

@ -0,0 +1,471 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
ADRENALINE_UPDATE_TIME_SEC = 0.3;
ADRENALINE_MIN_HUD_ALPHA = 0.5;
ADRENALINE_FLASH_REMAINING_TIME_SEC = 5;
ADRENALINE_MIN_ALPHA_VALUE = 0.5;
ADRENALINE_FLASH_TIME_LEFT_SEC = 5.0;
ADRENALINE_ICON_PULSE_SCALE = 1.1;
//*******************************************************************
// *
// *
//*******************************************************************
init()
{
if( getDvarInt( "prototype_adrenaline_enabled" ) == 1 )
{
println( "Adrenaline enabled" );
initAdrenaline();
level thread onPlayerConnect();
}
else
{
println( "Adrenaline disabled" );
}
}
adrenalineDebugging()
{
return getDvarInt( "set adrenaline_debugging" );
}
//*******************************************************************
// *
// *
//*******************************************************************
initAdrenaline()
{
// setup the models and stuff we need for intel
precacheShader("combathigh_overlay");
level._adrenalineIconAsset = "hud_adrenaline";
precacheShader( level._adrenalineIconAsset );
}
//*******************************************************************
// *
// *
//*******************************************************************
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread onPlayerSpawned();
}
}
//*******************************************************************
// *
// *
//*******************************************************************
onPlayerSpawned()
{
for(;;)
{
if( adrenalineDebugging())
println( "Adrenaline: onPlayerSpawned" );
self waittill( "spawned_player" );
self setupAdrenaline();
// update adrenaline value
self thread adrenalineThink();
// clean up the hud at death
self thread adrenalineWaitTillDeath();
// update the hud
self thread adrenalineUpdate();
// cleanup when ready
self thread adrenalineWaitCleanup();
}
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineThink()
{
self endon( "disconnect" );
self endon( "death" );
oldSPM = 0;
for(;;)
{
// cull out old scores
self adrenalineCleanScores();
newSPM = self adrenalineScorePerMin();
oldTime = self._adrenalineTimeSec;
if( adrenalineDebugging() && newSPM > 0 )
{
println( "old spm " + oldSPM + " new spm " + newSPM + " thres " + addrenalineGetSPMThreshold() + " adren time " + self._adrenalineTimeSec + " dvar " + getDvarInt( "adrenaline_winddown_time_sec" ) );
}
// calculate if we are in adrenaline mode
if( oldSPM < newSPM && addrenalineGetSPMThreshold() <= newSPM )
{
self._adrenalineTimeSec = getDvarInt( "adrenaline_winddown_time_sec" );
self notify( "adrenaline_update" );
}
oldSPM = newSPM;
// wait for another update run
wait ADRENALINE_UPDATE_TIME_SEC;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineGetAlphaValue()
{
alpha = ( self._adrenalineTimeSec - ADRENALINE_FLASH_TIME_LEFT_SEC )/( getDvarFloat( "adrenaline_winddown_time_sec" ) - ADRENALINE_FLASH_TIME_LEFT_SEC ) * (1 - ADRENALINE_MIN_ALPHA_VALUE);
alpha += ADRENALINE_MIN_ALPHA_VALUE;
if( alpha > 1.0 )
{
alpha = 1.0;
}
//println( "alpha value calc ", alpha );
return alpha;
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineCleanScores()
{
for ( i = 0; i < self._adrenScoreTimes.size; i++ )
{
if( gettime() - self._adrenScoreTimes[i] > getDvarFloat( "adrenaline_history_mins" ) * 60 * 1000 )
{
self._adrenScoreTimes[i] = undefined;
self._adrenScores[i] = undefined;
}
}
self._adrenScoreTimes = array_removeUndefined( self._adrenScoreTimes );
self._adrenScores = array_removeUndefined( self._adrenScores );
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineScorePerMin()
{
totalScore = 0;
foreach( score in self._adrenScores )
{
totalScore += score;
}
return totalScore / ( getDvarFloat( "adrenaline_history_mins" ) * 1.0 );
}
//*******************************************************************
// *
// *
//*******************************************************************
addrenalineGetSPMThreshold()
{
deaths = self GetPlayerData( "deaths" );
kills = self GetPlayerData( "kills" );
ratio = 1;
if( deaths > 0 )
{
ratio = kills / ( deaths * 1.0 );
}
if( ratio < 1 )
{
ratio = 1;
}
if( adrenalineDebugging())
{
println( "Adrenaline: " + self.name + "kdratio " + ratio );
}
return getDvarInt( "adrenaline_spm_threshold" ) * ratio;
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineAddScore( score )
{
if( adrenalineDebugging())
{
println( "Adrenaline: " + self.name + " added score " + score );
}
if( isDefined( self._adrenalineOverlayOn ))
{
self._adrenScoreTimes[self._adrenScoreTimes.size] = gettime();
self._adrenScores[self._adrenScores.size] = score;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineGetXPMultiplier()
{
mult = 1;
if( isDefined( self._adrenalineOverlayOn ) && self._adrenalineOverlayOn )
{
mult = getDvarInt( "adrenaline_xp_multiplier" );
}
return mult;
}
//*******************************************************************
// *
// *
//*******************************************************************
setupAdrenaline()
{
self._adrenalineTimeSec = 0;
self._adrenScoreTimes = [];
self._adrenScores = [];
self._adrenalineOverlayOn = false;
self._adrenalineXPEarned = false;
self.adrenalineOverlay = undefined;
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineSetXPEarned()
{
self._adrenalineXPEarned = true;
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineDidEarnXP()
{
ret = false;
if( getDvarInt( "prototype_adrenaline_enabled" ) == 1 )
{
ret = self._adrenalineXPEarned;
}
return ret;
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineInAdrenalineMode()
{
ret = false;
if( getDvarInt( "prototype_adrenaline_enabled" ) == 1 && isDefined( self._adrenalineOverlayOn ))
{
ret = self._adrenalineOverlayOn;
}
return ret;
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineTrySplash( killedPlayer )
{
if( killedPlayer adrenalineInAdrenalineMode())
{
if( killedPlayer adrenalineDidEarnXP())
{
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "adrenaline_mood_killer", 0 );
}
else
{
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "adrenaline_iced", 0 );
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
enterAdrenaline()
{
if( !self._adrenalineOverlayOn )
{
self.adrenalineOverlay = newClientHudElem( self );
self.adrenalineOverlay.x = 0;
self.adrenalineOverlay.y = 0;
self.adrenalineOverlay.alignX = "left";
self.adrenalineOverlay.alignY = "top";
self.adrenalineOverlay.horzAlign = "fullscreen";
self.adrenalineOverlay.vertAlign = "fullscreen";
self.adrenalineOverlay setshader ( "combathigh_overlay", 640, 480 );
self.adrenalineOverlay.sort = -10;
self.adrenalineOverlay.archived = true;
self.adrenalineOverlay.alpha = 0;
self._adrenalineOverlayOn = true;
self.adrenalineIcon = createIcon( level._adrenalineIconAsset, 40, 40 );
self.adrenalineIcon.horzAlign = "left";
self.adrenalineIcon.alignX = "left";
self.adrenalineIcon.y = 0;
self.adrenalineIcon.x = 110;
self.adrenalineIcon.sort = -10;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineUpdate()
{
self endon( "death" );
self endon( "disconnect" );
for(;;)
{
self waittill( "adrenaline_update" );
if( !self._adrenalineOverlayOn )
{
wait 0.05;
if( adrenalineDebugging())
{
println( "Adrenaline: " + self.name + " enterAdrenaline" );
}
self enterAdrenaline();
self thread maps\mp\gametypes\_hud_message::SplashNotify( "adrenaline_enter", 0 );
}
self.adrenalineOverlay fadeOverTime( 0.3 );
self.adrenalineOverlay.alpha = 1;
wait 0.3;
self thread adrenalineThreadWinddown();
}
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineThreadWinddown()
{
self endon( "adrenaline_update" );
self endon( "death" );
self endon( "disconnect" );
// the normal fade down
while( self._adrenalineTimeSec > ADRENALINE_FLASH_TIME_LEFT_SEC )
{
alpha = self adrenalineGetAlphaValue();
if( adrenalineDebugging())
{
println( "Adrenaline: " + self.name + " update alpha " + alpha );
}
self.adrenalineOverlay fadeOverTime( ADRENALINE_UPDATE_TIME_SEC );
self.adrenalineOverlay.alpha = alpha;
wait ADRENALINE_UPDATE_TIME_SEC;
self._adrenalineTimeSec -= ADRENALINE_UPDATE_TIME_SEC;
}
origWidth = 40;
origHeight = 40;
while( self._adrenalineTimeSec > 0 )
{
if( adrenalineDebugging())
{
println( "Adrenaline: " + self.name + " update alpha " + ADRENALINE_MIN_ALPHA_VALUE );
}
self.AdrenalineOverlay fadeOverTime( 0.1 );
self.adrenalineOverlay.alpha = ADRENALINE_MIN_ALPHA_VALUE * 1.3;
self.adrenalineIcon scaleOverTime( 0.05, int( origWidth * ADRENALINE_ICON_PULSE_SCALE ), int( origHeight * ADRENALINE_ICON_PULSE_SCALE ) );
wait 0.05;
self.adrenalineIcon scaleOverTime( 0.3, origWidth, origHeight );
self.AdrenalineOverlay fadeOverTime( 0.1 );
self.adrenalineOverlay.alpha = ADRENALINE_MIN_ALPHA_VALUE;
wait 0.9;
self._adrenalineTimeSec -= 1;
}
self.AdrenalineOverlay fadeOverTime( 0.3 );
self.adrenalineOverlay.alpha = 0;
wait 0.3;
self notify( "adrenaline_cleanup" );
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineWaitCleanup()
{
for(;;)
{
self waittill_any_return( "adrenaline_cleanup", "death", "disconnect" );
if( adrenalineDebugging())
{
println( "Adrenaline: " + self.name + "adrenalineWaitCleanup()" );
}
if( self._adrenalineOverlayOn )
{
self._adrenalineOverlayOn = false;
self.adrenalineOverlay destroy();
self.adrenalineOverlay = undefined;
self.adrenalineIcon destroy();
self.adrenalineIcon = undefined;
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
adrenalineWaitTillDeath()
{
self waittill( "death" );
self notify( "adrenaline_cleanup" );
}

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

111
maps/mp/_areas.gsc Normal file
View File

@ -0,0 +1,111 @@
#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.*/
/*QUAKED script_vehicle_snowmobile_player_mp (1 0 0) (-16 -16 -24) (16 16 32) USABLE SPAWNER
maps\_snowmobile_player::main( "vehicle_snowmobile" );
include,vehicle_snowmobile_snowmobile_player
sound,vehicle_snowmobile,vehicle_standard,all_sp
defaultmdl="vehicle_snowmobile"
default:"vehicletype" "snowmobile_player_mp"
*/
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 );
}
}

189
maps/mp/_art.gsc Normal file
View File

@ -0,0 +1,189 @@
// 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()
{
/#
setDevDvarIfUninitialized( "scr_art_tweak", 0 );
setDevDvarIfUninitialized( "scr_dof_enable", "1" );
setDevDvarIfUninitialized( "scr_cmd_plr_sun", "0" );
setDevDvarIfUninitialized( "scr_cinematic_autofocus", "1" );
setDevDvarIfUninitialized( "scr_art_visionfile", level._script );
if ( !isDefined( level._dofDefault ) )
{
level._dofDefault[ "nearStart" ] = 0;
level._dofDefault[ "nearEnd" ] = 1;
level._dofDefault[ "farStart" ] = 8000;
level._dofDefault[ "farEnd" ] = 10000;
level._dofDefault[ "nearBlur" ] = 6;
level._dofDefault[ "farBlur" ] = 0;
}
level._curDoF = ( level._dofDefault[ "farStart" ] - level._dofDefault[ "nearEnd" ] ) / 2;
thread tweakart();
if ( !isdefined( level._script ) )
level._script = ToLower( GetDvar( "mapname" ) );
#/
}
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;
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" );
}
//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();
dump = dumpsettings();// dumps and returns true if the dump dvar is set
common_scripts\_artCommon::updateFogFromScript();
// 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" ] );
}
#/
}
dumpsettings()
{
/#
if ( GetDvarInt( "scr_art_dump" ) == 0 )
return false;
filename = "createart/" + GetDvar( "scr_art_visionfile" ) + "_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( " " );
artfxprintlnFog();
fileprint_launcher( "\tVisionSetNaked( \"" + level._script + "\", 0 );" );
fileprint_launcher( "" );
fileprint_launcher( "}" );
artEndFogFileExport();
visionFilename = "vision/" + GetDvar( "scr_art_visionfile" ) + ".vision";
artStartVisionFileExport();
fileprint_launcher( "r_glow \"" + GetDvar( "r_glowTweakEnable" ) + "\"" );
fileprint_launcher( "r_glowRadius0 \"" + GetDvar( "r_glowTweakRadius0" ) + "\"" );
fileprint_launcher( "r_glowBloomCutoff \"" + GetDvar( "r_glowTweakBloomCutoff" ) + "\"" );
fileprint_launcher( "r_glowBloomDesaturation \"" + GetDvar( "r_glowTweakBloomDesaturation" ) + "\"" );
fileprint_launcher( "r_glowBloomIntensity0 \"" + GetDvar( "r_glowTweakBloomIntensity0" ) + "\"" );
fileprint_launcher( " " );
fileprint_launcher( "r_filmEnable \"" + GetDvar( "r_filmTweakEnable" ) + "\"" );
fileprint_launcher( "r_filmContrast \"" + GetDvar( "r_filmTweakContrast" ) + "\"" );
fileprint_launcher( "r_filmBrightness \"" + GetDvar( "r_filmTweakBrightness" ) + "\"" );
fileprint_launcher( "r_filmDesaturation \"" + GetDvar( "r_filmTweakDesaturation" ) + "\"" );
fileprint_launcher( "r_filmDesaturationDark \"" + GetDvar( "r_filmTweakDesaturationDark" ) + "\"" );
fileprint_launcher( "r_filmInvert \"" + GetDvar( "r_filmTweakInvert" ) + "\"" );
fileprint_launcher( "r_filmLightTint \"" + GetDvar( "r_filmTweakLightTint" ) + "\"" );
fileprint_launcher( "r_filmMediumTint \"" + GetDvar( "r_filmTweakMediumTint" ) + "\"" );
fileprint_launcher( "r_filmDarkTint \"" + GetDvar( "r_filmTweakDarkTint" ) + "\"" );
fileprint_launcher( " " );
fileprint_launcher( "r_primaryLightUseTweaks \"" + GetDvar( "r_primaryLightUseTweaks" ) + "\"" );
fileprint_launcher( "r_primaryLightTweakDiffuseStrength \"" + GetDvar( "r_primaryLightTweakDiffuseStrength" ) + "\"" );
fileprint_launcher( "r_primaryLightTweakSpecularStrength \"" + GetDvar( "r_primaryLightTweakSpecularStrength" ) + "\"" );
if ( ! artEndVisionFileExport() )
return false;
IPrintLnBold( "ART DUMPED SUCCESSFULLY" );
return true;
#/
}

1142
maps/mp/_awards.gsc Normal file

File diff suppressed because it is too large Load Diff

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

82
maps/mp/_createfx.gsc Normal file
View File

@ -0,0 +1,82 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include common_scripts\_createFxMenu;
#include common_scripts\_createfx;
#include common_scripts\_fx;
createfx()
{
// tagPP<NOTE> by the time createfx is called, player position is already updated so those 2 functions don't work anymore.
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_updatefx = ::restart_fx_looper;
level._func_process_fx_rotater = ::process_fx_rotater;
level._mp_createfx = true;
// tagPP<NOTE> what do they do?
// level.func_exploder_preload = ::exploder_before_load;
// level.func_exploder_postload = ::exploder_after_load;
// MP only stuff
// level._callbackStartGameType = ::void; // Take it out because it broke server/client message.
level._callbackPlayerConnect = ::void;
level._callbackPlayerDisconnect = ::void;
level._callbackPlayerDamage = ::void;
level._callbackPlayerKilled = ::void;
level._callbackCodeEndGame = ::void;
level._callbackPlayerLastStand = ::void;
level._callbackPlayerConnect = ::Callback_PlayerConnect;
level._callbackPlayerMigrated = ::void;
// build _effect_keys array
func_get_level_fx();
// remove triggers, turn on painter.
createfx_common();
level waittill( "eternity" );
}
func_position_player_get( lastPlayerOrigin )
{
return level._player.origin;
}
Callback_PlayerConnect()
{
self waittill( "begin" );
if ( !isdefined( level._player ) )
{
spawnpoints = getentarray( "mp_global_intermission", "classname" );
self spawn( spawnpoints[0].origin, spawnpoints[0].angles );
self maps\mp\gametypes\_playerlogic::updateSessionState( "playing", "" );
self.maxhealth = 10000000;
self.health = 10000000;
level._player = self;
// createFX thread
thread createFxLogic();
// hack
thread ufo_mode();
}
else
{
kick( self GetEntityNumber() );
}
}
ufo_mode()
{
// painter.menu execs some console commands( ufo mode ).. sneaky hacks.
level._player openpopupmenu( "painter_mp" );
level._player closepopupmenu( "painter_mp" );
}

137
maps/mp/_defcon.gsc Normal file
View File

@ -0,0 +1,137 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
// if ( game["state"] == "postgame" && game["teamScores"][attacker.team] > game["teamScores"][level.otherTeam[attacker.team]] )
ICONSIZE = 20;
init()
{
if ( !isDefined( level._defconMode ) || level._defconMode == false )
return;
if ( !isDefined( game["defcon"] ) )
game["defcon"] = 4;
makeDvarServerInfo( "scr_defcon", game["defcon"] );
/# setDevDvarIfUninitialized( "scr_defconStreak", 10 ); #/
level._defconStreakAdd[5] = 0;
level._defconStreakAdd[4] = 0;
level._defconStreakAdd[3] = -1;
level._defconStreakAdd[2] = -1;
level._defconStreakAdd[1] = -1;
level._defconPointMod[5] = 1;
level._defconPointMod[4] = 1;
level._defconPointMod[3] = 1;
level._defconPointMod[2] = 1;
level._defconPointMod[1] = 2;
updateDefcon( game["defcon"] );
thread defconKillstreakThread();
}
defconKillstreakWait( streakCount )
{
for ( ;; )
{
level waittill ( "player_got_killstreak_" + streakCount, player );
level notify ( "defcon_killstreak", streakCount, player );
}
}
defconKillstreakThread()
{
level endon ( "game_ended" );
requiredKillCount = 10;
/#
requiredKillCount = getDvarInt( "scr_defconStreak" );
#/
level thread defconKillstreakWait( requiredKillCount );
level thread defconKillstreakWait( requiredKillCount - 1 );
level thread defconKillstreakWait( requiredKillCount - 2 );
level thread defconKillstreakWait( (requiredKillCount * 2) );
level thread defconKillstreakWait( (requiredKillCount * 2) - 1 );
level thread defconKillstreakWait( (requiredKillCount * 2) - 2 );
level thread defconKillstreakWait( (requiredKillCount * 3) );
level thread defconKillstreakWait( (requiredKillCount * 3) - 1 );
level thread defconKillstreakWait( (requiredKillCount * 3) - 2 );
for ( ;; )
{
level waittill ( "defcon_killstreak", streakCount, changingPlayer );
if ( game["defcon"] <= 1 )
continue;
if ( (streakCount % requiredKillCount) == requiredKillCount - 2 )
{
foreach ( player in level._players )
{
if ( !isAlive( player ) )
continue;
player thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "two_from_defcon", changingPlayer );
}
}
else if ( (streakCount % requiredKillCount) == requiredKillCount - 1 )
{
foreach ( player in level._players )
{
if ( !isAlive( player ) )
continue;
player thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "one_from_defcon", changingPlayer );
}
}
else
{
updateDefcon( game["defcon"] - 1, changingPlayer, streakCount );
}
}
}
updateDefcon( newDefcon, changingPlayer, streakCount )
{
newDefcon = int( newDefcon );
oldDefcon = game["defcon"];
game["defcon"] = newDefcon;
// level.killStreakMod = level.defconStreakAdd[newDefcon];
level._objectivePointsMod = level._defconPointMod[newDefcon];
setDvar( "scr_defcon", game["defcon"] );
//isdefined used for variable init
if( isDefined( changingPlayer ) )
changingPlayer notify( "changed_defcon" );
if ( newDefcon == oldDefcon )
return;
if ( game["defcon"] == 3 && isDefined( changingPlayer ) )
{
changingPlayer maps\mp\killstreaks\_killstreaks::giveKillstreak( "airdrop_mega" );
changingPlayer thread maps\mp\gametypes\_hud_message::splashNotify( "caused_defcon" , streakCount );
}
foreach ( player in level._players )
{
if ( isAlive( player ) )
{
player thread maps\mp\gametypes\_hud_message::defconSplashNotify( game["defcon"], newDefcon < oldDefcon );
if ( isDefined( changingPlayer ) )
player thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "changed_defcon", changingPlayer );
}
}
}

100
maps/mp/_destructables.gsc Normal file
View File

@ -0,0 +1,100 @@
init()
{
// level.destructableFX = loadfx("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)
{
spawns = getentarray("mp_tdm_spawn", "classname");
blockEntsInArea(spawns, area);
spawns = getentarray("mp_dm_spawn", "classname");
blockEntsInArea(spawns, area);
}
blockEntsInArea(ents, area)
{
for (i = 0; i < ents.size; i++) {
if (!isdefined(ents[i].script_destructable_area) || ents[i].script_destructable_area != area)
continue;
ents[i].blockedoff = true;
}
}
unblockArea(area)
{
spawns = getentarray("mp_tdm_spawn", "classname");
unblockEntsInArea(spawns, area);
spawns = getentarray("mp_dm_spawn", "classname");
unblockEntsInArea(spawns, area);
}
unblockEntsInArea(ents, area)
{
for (i = 0; i < ents.size; i++) {
if (!isdefined(ents[i].script_destructable_area) || ents[i].script_destructable_area != area)
continue;
ents[i].blockedoff = false;
}
}

1602
maps/mp/_doorbreach.gsc Normal file

File diff suppressed because it is too large Load Diff

490
maps/mp/_doorswitch.gsc Normal file
View File

@ -0,0 +1,490 @@
//****************************************************************************
// **
// Confidential - (C) Activision Publishing, Inc. 2010 **
// **
//****************************************************************************
// **
// Module: Phase 1 Check-In: The script is able to control multiple **
// sets of door-switch pairs. It will work with the following **
// required setups in Radiant: **
// 2 models: **
// script_model: "targetname" "door_switch" **
// script_model: "targetname" "door_for_door_switch" **
// 1 clips: **
// script_brushmodel: "targetname" "clip_on_door" **
// 5 triggers: **
// trigger_use: "targetname" "door_trigger" **
// trigger_multiple: "targetname" "trigger_on_door" **
// trigger_multiple: "targetname" "trigger_under_door" **
// trigger_multiple: "targetname" "trigger_on_floor" **
// trigger_multiple: "targetname" "trigger_on_top" **
// **
// Created: June 9th, 2011 - James Chen **
// **
//***************************************************************************/
TARGETNAME_DOOR_SWITCH_MODEL = "door_switch"; //model for the door switch
TARGETNAME_DOOR_SWITCH_TRIGGER = "door_trigger"; //trigger_use placed with the door switch
TARGETNAME_DOOR_CLIP = "clip_on_door"; //clip around the door
TARGETNAME_DOOR = "door_for_door_switch"; //model for the door
TARGETNAME_TRIGGER_ON_DOOR = "trigger_on_door"; //trigger_multiple placed at the bottom of the door
TARGETNAME_TRIGGER_UNDER_DOOR = "trigger_under_door"; //trigger_multiple placed under the door to detect players passing by
TARGETNAME_TRIGGER_ON_FLOOR = "trigger_on_floor"; //trigger_multiple to represent the lowest point the door can go
TARGETNAME_TRIGGER_ON_TOP = "trigger_on_top"; //trigger_multiple to represent the highest point the door can go
TIME_OPEN_DOOR = 15; //Based on the UGV design doc
NOTIFY_MESSAGE_DOOR_OPENING = "door_opening"; //the notify message when the door is opening
NOTIFY_MESSAGE_DOOR_CLOSING = "door_closing"; //the notify message when the door is closing
NOTIFY_MESSAGE_DOOR_AT_TOP = "door_at_top"; //the notify message when the door is at the top
NOTIFY_MESSAGE_DOOR_AT_BOTTOM = "door_at_bottom"; //the notify message when the door is at the bottom
NOTIFY_MESSAGE_DISABLE_DOOR_SWITCH = "disable_door_switch"; //the notify message to disable the door switch
HINT_STRING_FOR_TRIGGER = &"MP_HINT_STRING_DOOR_SWITCH"; //the default hint string that will appear when players are close to the trigger
DOOR_STATE_COMPLETELY_CLOSED = "completely_closed"; //the flag message when the door is completely closed
DOOR_STATE_COMPLETELY_OPENED = "completely_opened"; //the flag message when the door is completely opened
DOOR_STATE_OPENING = "door_opening"; //the flag message when the door is opening
DOOR_STATE_CLOSING = "door_closing"; //the flag message when the door is closeing
//tagJC<NOTE>: For demonstration, run mp_nx_switch
//*******************************************************************
// *
// *
//*******************************************************************
main()
{
//tagJC<NOTE>: These two lines are to test the desired functionality for the UGV escort mode. Disable the following lines will
// result in the default behavior for the door switch, unless the new controlling logic and (or) the is defined
// in the game mode.
//level._canPlayerUseDoor = ::gameModeLogic;
//level._shouldTheObjectiveEnd = ::objectiveTerminationLogic;
//level._HintStringForDoorSwitch = "Testing string - Press ^3[{+activate}]^7 to use the door switch";
//tagJC<NOTE>: Getting all the entities into corresponding arrays
level._DoorSwitch = getentArray_and_assert( TARGETNAME_DOOR_SWITCH_MODEL );
level._DoorSwitchTrigger = getentArray_and_assert( TARGETNAME_DOOR_SWITCH_TRIGGER );
level._ClipOnDoor = getentArray_and_assert( TARGETNAME_DOOR_CLIP );
level._DoorForDoorSwitch = getentArray_and_assert( TARGETNAME_DOOR );
level._TriggerOnDoor = getentArray_and_assert( TARGETNAME_TRIGGER_ON_DOOR );
level._TriggerUnderDoor = getentArray_and_assert( TARGETNAME_TRIGGER_UNDER_DOOR );
level._TriggerOnFloor = getentArray_and_assert( TARGETNAME_TRIGGER_ON_FLOOR );
level._TriggerOnTop = getentArray_and_assert( TARGETNAME_TRIGGER_ON_TOP );
//tagJC<NOTE>: Checking for the correct numbers of models, clips and triggers in order to make sure that the script will function
// correctly.
checking_setup();
//tagJC<NOTE>: Linking the door model and the trigger at the bottom of the door to the clip
linking( level._ClipOnDoor , level._DoorForDoorSwitch );
linking( level._ClipOnDoor , level._TriggerOnDoor );
//tagJC<NOTE>: Based on proximity, pair up the trigger on the switch, the clip on the door and the 4 triggers around the door
pairing( level._DoorSwitchTrigger, level._ClipOnDoor, level._TriggerOnDoor, level._TriggerUnderDoor, level._TriggerOnFloor, level._TriggerOnTop );
println ( "In the main of DoorSwitch" );
////tagJC<NOTE>: Activate all the switch triggers around the level
for ( i = 0; i < level._DoorSwitchTrigger.size; i++)
{
level._DoorSwitchTrigger[i] thread ActivateDoorTrigger();
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: self is the trigger on top of the switch
ActivateDoorTrigger()
{
//tagJC<NOTE>: If the door reaches the highest point it can reach, disable the switch. Move the following logic to game logic side
self endon ( NOTIFY_MESSAGE_DISABLE_DOOR_SWITCH );
self usetriggerrequirelookat();
//tagJC<NOTE>: Use level defined hint string (possibly defined for the game mode) if it is defined
if ( isDefined( level._HintStringForDoorSwitch ))
{
hint_string = level._HintStringForDoorSwitch;
}
else
{
//tagJC<NOTE>: Else, use the default hint string
hint_string = HINT_STRING_FOR_TRIGGER;
}
self SetHintString ( hint_string );
//tagJC<NOTE>: The door is at the initial completely closed state
self.state = DOOR_STATE_COMPLETELY_CLOSED;
self.isOpening = 0;
//tagJC<NOTE>: Based on the distance that the door is able to move, calculate its speed
door_opening = distance (self.pairedTriggerTop.origin, self.pairedTriggerFloor.origin );
door_speed = door_opening / TIME_OPEN_DOOR;
while (1)
{
self waittill( "trigger", player );
if ( isDefined( level._canPlayerUseDoor ))
{
result = [[level._canPlayerUseDoor]]( player, self, self.state );
}
else
{
result = defaultCanPlayerUseDoor( player, self, self.state );
}
if( result && isDefined( level._doorActivationSound ))
{
self [[level._doorActivationSound]]( player );
}
//println( "result is " + result);
//tagJC<NOTE>: If the door is currently not opening, open the door
if ( result && self.isOpening == 0)
{
//tagJC<NOTE>: Play the opening sound on the door if the desired sound is defined in the level
if ( isDefined ( level._doorOpeningSound ))
{
self [[level._doorOpeningSound]]();
}
self.state = DOOR_STATE_OPENING;
self.isOpening = 1;
self notify( NOTIFY_MESSAGE_DOOR_OPENING );
level notify( NOTIFY_MESSAGE_DOOR_OPENING );
//tagJC<NOTE>: Stop the script to kill players who are stuck since the door is opening
self notify( "stop_killing_player" );
//tagJC<NOTE>: Test whether the door is at the highest point that it can reach
if ( isDefined( level._shouldTheObjectiveEnd ))
{
self thread [[level._shouldTheObjectiveEnd]]();
}
else
{
self thread IsDoorAtTop();
}
//tagJC<NOTE>: Move the door upward
distance_to_open = distance (self.pairedTriggerTop.origin, self.pairedTriggerOn.origin );
time_to_open = distance_to_open / door_speed;
self.pairedClip notify( "movedone" );
self.pairedClip MoveZ( distance_to_open, time_to_open, time_to_open * 0.5, time_to_open * 0.4);
}
else if ( result && self.isOpening == 1)
{
//tagJC<NOTE>: Play the closing sound on the door if the desired sound is defined in the level
if ( isDefined ( level._doorClosingSound ))
{
self [[level._doorClosingSound]]();
}
self.state = DOOR_STATE_CLOSING;
self.isOpening = 0;
self notify( NOTIFY_MESSAGE_DOOR_CLOSING );
//tagJC<NOTE>: Test whether the door is at the lowest point that it can reach
self thread IsDoorAtBottom();
//tagJC<NOTE>: Kill any players who are stuck underneath the door
self thread KillPlayersUnder();
//tagJC<NOTE>: Move the door downward
distance_to_close = distance( self.pairedTriggerFloor.origin, self.pairedTriggerOn.origin );
time_to_close = distance_to_close / door_speed;
self.pairedClip notify( "movedone" );
self.pairedClip MoveZ( distance_to_close * -1, time_to_close, time_to_close * 0.5, time_to_close * 0.4);
}
wait ( 1 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: The default door behavior is that everyone (regardless of the team) can use the door
defaultCanPlayerUseDoor( player, trigger, door_state )
{
return true;
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: self is the door switch
IsDoorAtBottom()
{
self endon ( NOTIFY_MESSAGE_DOOR_OPENING );
self endon ( NOTIFY_MESSAGE_DISABLE_DOOR_SWITCH );
while ( 1 )
{
if ( self.pairedTriggerOn.origin[2] == self.pairedTriggerFloor.origin[2] )
{
if ( isDefined( level._doorCompletelyCloseSound ) && ( self.state != DOOR_STATE_COMPLETELY_CLOSED ))
{
self [[level._doorCompletelyCloseSound]]();
}
self notify ( NOTIFY_MESSAGE_DOOR_AT_BOTTOM );
self.state = DOOR_STATE_COMPLETELY_CLOSED;
}
wait 0.5;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: self is the door switch
IsDoorAtTop()
{
self endon ( NOTIFY_MESSAGE_DOOR_CLOSING );
self endon ( NOTIFY_MESSAGE_DISABLE_DOOR_SWITCH );
while ( 1 )
{
if ( self.pairedTriggerOn.origin[2] == self.pairedTriggerTop.origin[2] )
{
if ( isDefined( level._doorCompletelyOpenSound ) && ( self.state != DOOR_STATE_COMPLETELY_OPENED ))
{
self [[level._doorCompletelyOpenSound]]();
}
//tagJC<NOTE>: Once the door reaches the top, make the proper notify and change the state
self notify ( NOTIFY_MESSAGE_DOOR_AT_TOP );
self.state = DOOR_STATE_COMPLETELY_OPENED;
}
wait 0.5;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: self is the trigger on top of the door switch
KillPlayersUnder()
{
self endon ( "stop_killing_player" );
while ( 1 )
{
self.pairedTriggerUnder waittill( "trigger", player);
if (( player IsTouching( self.pairedTriggerOn ))) // && ( player IsTouching( Trigger2 )))
{
player thread [[level._callbackPlayerDamage]](
player, // eInflictor The entity that causes the damage.(e.g. a turret)
player, // eAttacker The entity that is attacking.
500, // iDamage Integer specifying the amount of damage done
0, // iDFlags Integer specifying flags that are to be applied to the damage
"MOD_SUICIDE", // sMeansOfDeath Integer specifying the method of death MOD_RIFLE_BULLET
player.primaryweapon, // sWeapon The weapon number of the weapon used to inflict the damage
player.origin, // vPoint The point the damage is from?
(0, 0, 0), // vDir The direction of the damage
"none", // sHitLoc The location of the hit
0 // psOffsetTime The time offset for the damage
);
}
wait .05;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Linking entities in object_list_2 to that in object_list_1 based on proximity
linking( object_list_1 , object_list_2 )
{
for ( i = 0; i < object_list_1.size; i++ )
{
//tagJC<NOTE>: Use an arbitrary distance as the base for comparision
paired_object2 = find_closest( object_list_1[i], object_list_2 );
//tagJC<NOTE>: Link the paired objects to that in object_list_1
paired_object2 LinkTo( object_list_1[i] );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: This function pairs up the clips with each other as well as the corresponding triggers
pairing( trigger_list, clip_list, trigger_on_list, trigger_under_list, trigger_floor_list, trigger_top_list )
{
for ( i = 0; i < trigger_list.size; i++ )
{
//tagJC<NOTE>: Determine the door clip, and the four triggers around the door that are the closest to the current
// switch trigger under examination
paired_clip = find_closest( trigger_list[i], clip_list );
paired_trigger_on = find_closest( trigger_list[i], trigger_on_list );
paired_trigger_under = find_closest( trigger_list[i], trigger_under_list );
paired_trigger_floor = find_closest( trigger_list[i], trigger_floor_list );
paired_trigger_top = find_closest( trigger_list[i], trigger_top_list );
//tagJC<NOTE>: Putting those closest entities as the member data for the switch trigger
trigger_list[i].pairedClip = paired_clip;
trigger_list[i].pairedTriggerOn = paired_trigger_on;
trigger_list[i].pairedTriggerUnder = paired_trigger_under;
trigger_list[i].pairedTriggerFloor = paired_trigger_floor;
trigger_list[i].pairedTriggerTop = paired_trigger_top;
//tagJC<NOTE>: Useful debugging message
//IPrintLnBold( "clip at " + paired_clip.origin + " is paired with switch trigger at " + trigger_list[i].origin);
//IPrintLnBold( "Trigger_on at " + paired_trigger_on.origin + " is paired with switch trigger at " + trigger_list[i].origin);
//IPrintLnBold( "Trigger_under at " + paired_trigger_under.origin + " is paired with switch trigger at " + trigger_list[i].origin);
//IPrintLnBold( "Trigger_floor at " + paired_trigger_floor.origin + " is paired with switch trigger at " + trigger_list[i].origin);
//IPrintLnBold( "Trigger_top at " + paired_trigger_top.origin + " is paired with switch trigger at " + trigger_list[i].origin);
}
}
//*******************************************************************
// *
// *
//*******************************************************************
find_closest( entity, entity_list )
{
//tagJC<NOTE>: Use an arbitrary distance as the base for comparision
closest_distance = distance( entity.origin , entity_list[0].origin );
closest_entity = entity_list[0];
for ( i = 1; i < entity_list.size; i++ )
{
//tagJC<NOTE>: If another entity on the list results in a shorter distance, update the results accordingly
if ( distance( entity.origin , entity_list[i].origin ) < closest_distance )
{
closest_distance = distance( entity.origin , entity_list[i].origin );
closest_entity = entity_list[i];
}
}
return closest_entity;
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Check for matching numbers of entities for door models, clips and triggers
checking_setup ()
{
set_count = level._DoorSwitch.size;
if ( level._DoorSwitchTrigger.size != set_count )
{
AssertEX( false , "The number of switch trigger needs to equal to the number of switch. There are " + set_count + " switch in the level. However, there are " + level._DoorSwitchTrigger.size + " switch trigger in the level." );
}
if ( level._ClipOnDoor.size != set_count )
{
AssertEX( false , "The number of door clip needs to equal to the number of switch. There are " + set_count + " switch in the level. However, there are " + level._ClipOnDoor.size + " door clips in the level." );
}
if ( level._DoorForDoorSwitch.size != set_count )
{
AssertEX( false , "The number of door models needs to equal to the number of switch. There are " + set_count + " switch in the level. However, there are " + level._DoorForDoorSwitch.size + " door models in the level." );
}
if ( level._TriggerOnDoor.size != set_count )
{
AssertEX( false , "The number of triggers on door needs to equal to the number of switch. There are " + set_count + " switch in the level. However, there are " + level._TriggerOnDoor.size + " triggers on door." );
}
if ( level._TriggerUnderDoor.size != set_count )
{
AssertEX( false , "The number of triggers under door needs to equal to the number of switch. There are " + set_count + " switch in the level. However, there are " + level._TriggerUnderDoor.size + " triggers under door." );
}
if ( level._TriggerOnFloor.size != set_count )
{
AssertEX( false , "The number of triggers on floor needs to equal to the number of switch. There are " + set_count + " switch in the level. However, there are " + level._TriggerOnFloor.size + " triggers on floor." );
}
if ( level._TriggerOnTop.size != set_count )
{
AssertEX( false , "The number of triggers on top of the door needs to equal to the number of switch. There are " + set_count + " switch in the level. However, there are " + level._TriggerOnTop.size + " triggers on top of the door." );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Useful helper function to get the requested entity and check for any errors
getentArray_and_assert( ent_name )
{
object = getEntArray( ent_name, "targetname" );
AssertEX( object.size > 0 , "There is no entity for " + ent_name );
return object;
}
maps/mp/_compass.gsc 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);
}

View File

@ -0,0 +1,342 @@
#include maps\mp\_utility;
#include common_scripts\utility;
#include maps\mp\gametypes\_hud_util;
init()
{
if (isdefined(level._initedEntityHeadIcons))
return;
level._initedEntityHeadIcons = true;
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"] );
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
str_team_headicon = "entity_headicon_" + level._teamNameList[i];
game[ str_team_headicon ] = maps\mp\gametypes\_teams::MTDM_getTeamHeadIcon( level._teamNameList[i] );
precacheShader( game[ str_team_headicon ] );
}
}
if (!level._teamBased)
return;
}
// This can show to single players or to teams. Showing to a single player destroys instances of
// the icon that are shown to their team. Showing to a team destroys instances of the icon that
// are shown to players on that team
setHeadIcon( showTo, icon, offset, width, height, archived, delay, constantSize, pinToScreenEdge, fadeOutPinnedIcon, is3D )
{
if ( !isDefined( self.entityHeadIcons ) )
self.entityHeadIcons = [];
if( !IsDefined( archived ) )
archived = true;
if( !IsDefined( delay ) )
delay = 0.05;
if( !IsDefined( constantSize ) )
constantSize = true;
if( !IsDefined( pinToScreenEdge ) )
pinToScreenEdge = true;
if( !IsDefined( fadeOutPinnedIcon ) )
fadeOutPinnedIcon = false;
if( !IsDefined( is3D ) )
is3D = true;
if ( !isPlayer( showTo ) && showTo == "none" )
{
foreach ( key, headIcon in self.entityHeadIcons )
{
// TODO: remove and fix properly after ship
if ( isDefined( headIcon ) )
headIcon destroy();
self.entityHeadIcons[ key ] = undefined;
}
return;
}
if ( isPlayer( showTo ) )
{
if ( isDefined( self.entityHeadIcons[ showTo.guid ] ) )
{
self.entityHeadIcons[ showTo.guid ] destroy();
self.entityHeadIcons[ showTo.guid ] = undefined;
}
if ( icon == "" )
return;
// 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
{
if( !level._multiteambased )
{
assert( showTo == "axis" || showTo == "allies" );
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;
if( level._multiTeamBased )
{
if( isSubStr( key, "team_" ))
{
continue;
}
}
player = getPlayerForGuid( key );
if ( isDefined( player ) && player.team == showTo )
{
if ( isDefined( self.entityHeadIcons[ key ] ) )
{
self.entityHeadIcons[ key ] destroy();
self.entityHeadIcons[ key ] = undefined;
}
}
}
headIcon = newTeamHudElem( showTo );
self.entityHeadIcons[ showTo ] = headIcon;
}
if ( !isDefined( width ) || !isDefined( height ) )
{
width = 10;
height = 10;
}
headIcon.archived = archived;
headIcon.x = self.origin[0] + offset[0];
headIcon.y = self.origin[1] + offset[1];
headIcon.z = self.origin[2] + offset[2];
headIcon.alpha = 0.85;
headIcon setShader( icon, width, height );
headIcon setWaypoint( constantSize, pinToScreenEdge, fadeOutPinnedIcon, is3D );
headIcon thread keepPositioned( self, offset, delay );
self thread destroyIconsOnDeath();
if ( isPlayer( showTo ) )
headIcon thread destroyOnOwnerDisconnect( showTo );
if ( isPlayer( self ) )
headIcon thread destroyOnOwnerDisconnect( self );
return headIcon;
}
destroyOnOwnerDisconnect( owner )
{
self endon ( "death" );
owner waittill ( "disconnect" );
self destroy();
}
destroyIconsOnDeath()
{
self notify ( "destroyIconsOnDeath" );
self endon ( "destroyIconsOnDeath" );
self waittill ( "death" );
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];
}
self.alpha = 1;
self FadeOverTime( delay );
self.alpha = 0;
wait delay;
}
}
setTeamHeadIcon( team, offset ) // "allies", "axis", "all", "none"
{
if ( !level._teamBased )
return;
if ( !isDefined( self.entityHeadIconTeam ) )
{
self.entityHeadIconTeam = "none";
self.entityHeadIcon = undefined;
}
shader = game["entity_headicon_" + team];
self.entityHeadIconTeam = team;
if ( isDefined( offset ) )
self.entityHeadIconOffset = offset;
else
self.entityHeadIconOffset = (0,0,0);
self notify( "kill_entity_headicon_thread" );
if ( team == "none" )
{
if ( isDefined( self.entityHeadIcon ) )
self.entityHeadIcon destroy();
return;
}
headIcon = newTeamHudElem( team );
headIcon.archived = true;
headIcon.x = self.origin[0] + self.entityHeadIconOffset[0];
headIcon.y = self.origin[1] + self.entityHeadIconOffset[1];
headIcon.z = self.origin[2] + self.entityHeadIconOffset[2];
headIcon.alpha = .8;
headIcon setShader( shader, 10, 10 );
headIcon setWaypoint( false, false, false, true );
self.entityHeadIcon = headIcon;
self thread keepIconPositioned();
self thread destroyHeadIconsOnDeath();
}
setPlayerHeadIcon( player, offset ) // "allies", "axis", "all", "none"
{
if ( level._teamBased )
return;
if ( !isDefined( self.entityHeadIconTeam ) )
{
self.entityHeadIconTeam = "none";
self.entityHeadIcon = undefined;
}
self notify( "kill_entity_headicon_thread" );
if ( !isDefined( player ) )
{
if ( isDefined( self.entityHeadIcon ) )
self.entityHeadIcon destroy();
return;
}
team = player.team;
self.entityHeadIconTeam = team;
if ( isDefined( offset ) )
self.entityHeadIconOffset = offset;
else
self.entityHeadIconOffset = (0,0,0);
shader = game["entity_headicon_" + team];
headIcon = newClientHudElem( player );
headIcon.archived = true;
headIcon.x = self.origin[0] + self.entityHeadIconOffset[0];
headIcon.y = self.origin[1] + self.entityHeadIconOffset[1];
headIcon.z = self.origin[2] + self.entityHeadIconOffset[2];
headIcon.alpha = .8;
headIcon setShader( shader, 10, 10 );
headIcon setWaypoint( false, false, false, true );
self.entityHeadIcon = headIcon;
self thread keepIconPositioned();
self thread destroyHeadIconsOnDeath();
}
keepIconPositioned()
{
self endon( "kill_entity_headicon_thread" );
self endon( "death" );
pos = self.origin;
while(1)
{
if ( pos != self.origin )
{
self updateHeadIconOrigin();
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()
{
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];
}

730
maps/mp/_events.gsc Normal file
View File

@ -0,0 +1,730 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "execution", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "avenger", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "defender", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "posthumous", 25 );
maps\mp\gametypes\_rank::registerScoreInfo( "revenge", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "double", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "triple", 75 );
maps\mp\gametypes\_rank::registerScoreInfo( "multi", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "buzzkill", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "firstblood", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "comeback", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "longshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assistedsuicide", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "knifethrow", 100 );
registerAdrenalineInfo( "damage", 10 );
registerAdrenalineInfo( "damaged", 20 );
registerAdrenalineInfo( "kill", 50 );
registerAdrenalineInfo( "killed", 20 );
registerAdrenalineInfo( "headshot", 20 );
registerAdrenalineInfo( "melee", 10 );
registerAdrenalineInfo( "backstab", 20 );
registerAdrenalineInfo( "longshot", 10 );
registerAdrenalineInfo( "assistedsuicide", 10);
registerAdrenalineInfo( "defender", 10 );
registerAdrenalineInfo( "avenger", 10 );
registerAdrenalineInfo( "execution", 10 );
registerAdrenalineInfo( "comeback", 50 );
registerAdrenalineInfo( "revenge", 20 );
registerAdrenalineInfo( "buzzkill", 20 );
registerAdrenalineInfo( "double", 10 );
registerAdrenalineInfo( "triple", 20 );
registerAdrenalineInfo( "multi", 30 );
registerAdrenalineInfo( "assist", 20 );
registerAdrenalineInfo( "3streak", 30 );
registerAdrenalineInfo( "5streak", 30 );
registerAdrenalineInfo( "7streak", 30 );
registerAdrenalineInfo( "10streak", 30 );
registerAdrenalineInfo( "regen", 30 );
precacheShader( "crosshair_red" );
level._effect["money"] = loadfx ("props/cash_player_drop");
level._numKills = 0;
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player.killedPlayers = [];
player.killedPlayersCurrent = [];
player.killedBy = [];
player.lastKilledBy = undefined;
player.greatestUniquePlayerKills = 0;
player.recentKillCount = 0;
player.lastKillTime = 0;
player.damagedPlayers = [];
player.adrenaline = 0;
player setAdrenaline( 0 );
player thread monitorCrateJacking();
player thread monitorObjectives();
}
}
damagedPlayer( victim, damage, weapon )
{
// self giveAdrenaline( "damage" );
// victim giveAdrenaline( "damaged" );
}
killedPlayer( killId, victim, weapon, meansOfDeath )
{
victimGuid = victim.guid;
myGuid = self.guid;
curTime = getTime();
self thread updateRecentKills( killId );
self.lastKillTime = getTime();
self.lastKilledPlayer = victim;
self.modifiers = [];
level._numKills++;
// a player is either damaged, or killed; never both
self.damagedPlayers[victimGuid] = undefined;
self giveAdrenaline( "kill" );
victim giveAdrenaline( "killed" );
if ( !isKillstreakWeapon( weapon ) )
{
if ( weapon == "none" )
return false;
//if ( isSubStr( weapon, "ranger" ) && isDefined( self.bothBarrels ) ) This wont work because this is called before weapons self.bothbarrels would be set
// self.modifiers["bothbarrels"] = true;
if ( isDefined( self.pers["copyCatLoadout"] ) && isDefined( self.pers["copyCatLoadout"]["owner"] ) )
{
if ( victim == self.pers["copyCatLoadout"]["owner"] )
self.modifiers["clonekill"] = true;
}
if ( victim.attackers.size == 1 )
{
/#
if ( !isDefined( victim.attackers[self.guid] ) )
{
println("Weapon: "+ weapon );
println("Attacker GUID:" + self.guid );
foreach ( key,value in victim.attackers )
println( "Victim Attacker list GUID: " + key );
}
#/
assertEx( isDefined( victim.attackers[self.guid] ), "See console log for details" );
weaponClass = getWeaponClass( weapon );
if ( getTime() == victim.attackerData[self.guid].firstTimeDamaged && meansOfDeath != "MOD_MELEE" && ( /*weaponClass == "weapon_shotgun" ||*/ weaponClass == "weapon_sniper" ) )
{
self.modifiers["oneshotkill"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "one_shot_kill" );
}
}
if ( isDefined( victim.throwingGrenade ) && victim.throwingGrenade == "frag_grenade_mp" )
self.modifiers["cooking"] = true;
if ( isDefined(self.assistedSuicide) && self.assistedSuicide )
self assistedSuicide( killId );
if ( level._numKills == 1 )
self firstBlood( killId );
if ( self.pers["cur_death_streak"] > 3 )
self comeBack( killId );
if ( meansOfDeath == "MOD_HEAD_SHOT" )
{
if ( isDefined( victim.lastStand ) )
execution( killId );
else
headShot( killId );
}
if ( isDefined(self.wasti) && self.wasti && getTime() - self.spawnTime <= 5000 )
self.modifiers["jackintheboxkill"] = true;
if ( !isAlive( self ) && self.deathtime + 800 < getTime() )
postDeathKill( killId );
fakeAvenge = false;
if ( level._teamBased && curTime - victim.lastKillTime < 500 )
{
if ( victim.lastkilledplayer != self )
self avengedPlayer( killId );
}
foreach ( guid, damageTime in victim.damagedPlayers )
{
if ( guid == self.guid )
continue;
if ( level._teamBased && curTime - damageTime < 500 )
{
p = getPlayerForGuid(guid);
if( p.team == self.team )
{
self defendedPlayer( killId );
}
}
}
if ( isDefined( victim.attackerPosition ) )
attackerPosition = victim.attackerPosition;
else
attackerPosition = self.origin;
if ( isAlive( self ) && !self isUsingRemote() && (meansOfDeath == "MOD_RIFLE_BULLET" || meansOfDeath == "MOD_PISTOL_BULLET" || meansOfDeath == "MOD_HEAD_SHOT") && distance( attackerPosition, victim.origin ) > 1536 && !isKillstreakWeapon( weapon ) && !isDefined( self.assistedSuicide ) )
self thread longshot( killId );
//if ( isAlive( self ) && self.health < 20 && isDefined( self.attackers ) && self.attackers.size == 1 && self.attackers[0] == victim )
// victim thread consolation( killId );
if ( isDefined( victim.killstreaks[ victim.pers["cur_kill_streak"] + 1 ] ) )
{
// playercard splash for the killstreak stopped
self buzzKill( killId, victim );
}
self maps\mp\_adrenaline::adrenalineTrySplash( victim );
self thread checkMatchDataKills( killId, victim, weapon, meansOfDeath);
}
if ( !isDefined( self.killedPlayers[victimGuid] ) )
self.killedPlayers[victimGuid] = 0;
if ( !isDefined( self.killedPlayersCurrent[victimGuid] ) )
self.killedPlayersCurrent[victimGuid] = 0;
if ( !isDefined( victim.killedBy[myGuid] ) )
victim.killedBy[myGuid] = 0;
self.killedPlayers[victimGuid]++;
//this sets player stat for routine customer award
if ( self.killedPlayers[victimGuid] > self.greatestUniquePlayerKills )
self setPlayerStat( "killedsameplayer", self.killedPlayers[victimGuid] );
self.killedPlayersCurrent[victimGuid]++;
victim.killedBy[myGuid]++;
victim.lastKilledBy = self;
}
checkMatchDataKills( killId, victim, weapon, meansOfDeath )
{
weaponClass = getWeaponClass( weapon );
alreadyUsed = false;
self thread camperCheck();
if ( isDefined( self.lastKilledBy ) && self.lastKilledBy == victim )
{
self.lastKilledBy = undefined;
self revenge( killId );
playFx( level._effect["money"], victim getTagOrigin( "j_spine4" ) );
}
if ( victim.iDFlags & level._iDFLAGS_PENETRATION )
self incPlayerStat( "bulletpenkills", 1 );
if ( self.pers["rank"] < victim.pers["rank"] )
self incPlayerStat( "higherrankkills", 1 );
if ( self.pers["rank"] > victim.pers["rank"] )
self incPlayerStat( "lowerrankkills", 1 );
if ( isDefined( self.laststand ) && self.laststand )
self incPlayerStat( "laststandkills", 1 );
if ( isDefined( victim.laststand ) && victim.laststand )
self incPlayerStat( "laststanderkills", 1 );
if ( self getCurrentWeapon() != self.loadoutPrimary + "_mp" && self getCurrentWeapon() != self.loadoutSecondary + "_mp" )
self incPlayerStat( "otherweaponkills", 1 );
if ( getBaseWeaponName( weapon ) == "m79" )
self incPlayerStat( "thumperkills", 1 );
timeAlive = getTime() - victim.spawnTime ;
if( !matchMakingGame() )
victim setPlayerStatIfLower( "shortestlife", timeAlive );
victim setPlayerStatIfGreater( "longestlife", timeAlive );
switch( weaponClass )
{
case "weapon_pistol":
case "weapon_machine_pistol":
case "weapon_smg":
case "weapon_assault":
case "weapon_projectile":
case "weapon_sniper":
case "weapon_shotgun":
case "weapon_lmg":
if ( self GetStance() == "crouch" )
{
self incPlayerStat( "crouchkills", 1 );
}
if ( self GetStance() == "prone" )
{
self incPlayerStat( "pronekills", 1 );
}
self checkMatchDataWeaponKills( victim, weapon, meansOfDeath, weaponClass );
break;
case "weapon_grenade":
case "weapon_explosive":
self checkMatchDataEquipmentKills( victim, weapon, meansOfDeath );
break;
default:
break;
}
}
// Need to make sure these only apply to kills of an enemy, not friendlies or yourself
checkMatchDataWeaponKills( victim, weapon, meansOfDeath, weaponType )
{
attacker = self;
kill_ref = undefined;
headshot_ref = undefined;
death_ref = undefined;
switch( weaponType )
{
case "weapon_pistol":
kill_ref = "pistolkills";
headshot_ref = "pistolheadshots";
break;
case "weapon_machine_pistol":
kill_ref = "machinepistolkills";
headshot_ref = "machinepistolheadshots";
break;
case "weapon_smg":
kill_ref = "smgkills";
headshot_ref = "smgheadshots";
break;
case "weapon_assault":
kill_ref = "arkills";
headshot_ref = "arheadshots";
break;
case "weapon_projectile":
if ( weaponClass( weapon ) == "rocketlauncher" )
kill_ref = "rocketkills";
break;
case "weapon_sniper":
kill_ref = "sniperkills";
headshot_ref = "sniperheadshots";
break;
case "weapon_shotgun":
kill_ref = "shotgunkills";
headshot_ref = "shotgunheadshots";
death_ref = "shotgundeaths";
break;
case "weapon_lmg":
kill_ref = "lmgkills";
headshot_ref = "lmgheadshots";
break;
default:
break;
}
if ( isDefined ( kill_ref ) )
attacker incPlayerStat( kill_ref, 1 );
if ( isDefined ( headshot_ref ) && meansOfDeath == "MOD_HEAD_SHOT" )
attacker incPlayerStat( headshot_ref, 1 );
if ( isDefined ( death_ref ) && !matchMakingGame() )
victim incPlayerStat( death_ref, 1 );
if ( attacker PlayerAds() > 0.5 )
{
attacker incPlayerStat( "adskills", 1 );
if ( weaponType == "weapon_sniper" || isSubStr( weapon, "acog" ) )
attacker incPlayerStat( "scopedkills", 1 );
if ( isSubStr( weapon, "thermal" ) )
attacker incPlayerStat( "thermalkills", 1 );
}
else
{
attacker incPlayerStat( "hipfirekills", 1 );
}
}
// Need to make sure these only apply to kills of an enemy, not friendlies or yourself
checkMatchDataEquipmentKills( victim, weapon, meansOfDeath )
{
attacker = self;
// equipment kills
switch( weapon )
{
case "frag_grenade_mp":
if ( attacker != victim )
{
attacker incPlayerStat( "fragkills", 1 );
attacker incPlayerStat( "grenadekills", 1 );
}
isEquipment = true;
break;
case "c4_mp":
if ( attacker != victim )
{
attacker incPlayerStat( "c4kills", 1 );
}
isEquipment = true;
break;
case "semtex_mp":
if ( attacker != victim )
{
attacker incPlayerStat( "semtexkills", 1 );
attacker incPlayerStat( "grenadekills", 1 );
}
isEquipment = true;
break;
case "claymore_mp":
if ( attacker != victim )
{
attacker incPlayerStat( "claymorekills", 1 );
}
isEquipment = true;
break;
case "throwingknife_mp":
attacker incPlayerStat( "throwingknifekills", 1 );
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "knifethrow", maps\mp\gametypes\_rank::getScoreInfoValue( "knifethrow" ) );
isEquipment = true;
break;
default:
isEquipment = false;
break;
}
if ( isEquipment )
attacker incPlayerStat( "equipmentkills", 1 );
}
camperCheck()
{
if ( !isDefined ( self.lastKillLocation ) )
{
self.lastKillLocation = self.origin;
self.lastCampKillTime = getTime();
return;
}
if ( Distance( self.lastKillLocation, self.origin ) < 512 && getTime() - self.lastCampKillTime > 5000 )
{
self incPlayerStat( "mostcamperkills", 1 );
}
self.lastKillLocation = self.origin;
self.lastCampKillTime = getTime();
}
consolation( killId )
{
/*
value = int( maps\mp\gametypes\_rank::getScoreInfoValue( "kill" ) * 0.25 );
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "consolation", value );
self thread maps\mp\gametypes\_rank::giveRankXP( "consolation", value );
*/
}
longshot( killId )
{
self.modifiers["longshot"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "longshot", maps\mp\gametypes\_rank::getScoreInfoValue( "longshot" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "longshot" );
self thread giveAdrenaline( "longshot" );
self incPlayerStat( "longshots", 1 );
self thread maps\mp\_matchdata::logKillEvent( killId, "longshot" );
}
execution( killId )
{
self.modifiers["execution"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "execution", maps\mp\gametypes\_rank::getScoreInfoValue( "execution" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "execution" );
self thread giveAdrenaline( "execution" );
self thread maps\mp\_matchdata::logKillEvent( killId, "execution" );
}
headShot( killId )
{
self.modifiers["headshot"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "headshot", maps\mp\gametypes\_rank::getScoreInfoValue( "headshot" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "headshot" );
self thread giveAdrenaline( "headshot" );
self thread maps\mp\_matchdata::logKillEvent( killId, "headshot" );
}
avengedPlayer( killId )
{
self.modifiers["avenger"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "avenger", maps\mp\gametypes\_rank::getScoreInfoValue( "avenger" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "avenger" );
self thread giveAdrenaline( "avenger" );
self thread maps\mp\_matchdata::logKillEvent( killId, "avenger" );
self incPlayerStat( "avengekills", 1 );
}
assistedSuicide( killId )
{
self.modifiers["assistedsuicide"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "assistedsuicide", maps\mp\gametypes\_rank::getScoreInfoValue( "assistedsuicide" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "assistedsuicide" );
self thread giveAdrenaline( "assistedsuicide" );
self thread maps\mp\_matchdata::logKillEvent( killId, "assistedsuicide" );
}
defendedPlayer( killId )
{
self.modifiers["defender"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "defender", maps\mp\gametypes\_rank::getScoreInfoValue( "defender" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "defender" );
self thread giveAdrenaline( "defender" );
self thread maps\mp\_matchdata::logKillEvent( killId, "defender" );
self incPlayerStat( "rescues", 1 );
}
postDeathKill( killId )
{
self.modifiers["posthumous"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "posthumous", maps\mp\gametypes\_rank::getScoreInfoValue( "posthumous" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "posthumous" );
self thread maps\mp\_matchdata::logKillEvent( killId, "posthumous" );
}
backStab( killId )
{
self iPrintLnBold( "backstab" );
}
revenge( killId )
{
self.modifiers["revenge"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "revenge", maps\mp\gametypes\_rank::getScoreInfoValue( "revenge" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "revenge" );
self thread giveAdrenaline( "revenge" );
self thread maps\mp\_matchdata::logKillEvent( killId, "revenge" );
self incPlayerStat( "revengekills", 1 );
}
multiKill( killId, killCount )
{
assert( killCount > 1 );
if ( killCount == 2 )
{
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "doublekill", maps\mp\gametypes\_rank::getScoreInfoValue( "double" ) );
self thread giveAdrenaline( "double" );
}
else if ( killCount == 3 )
{
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "triplekill", maps\mp\gametypes\_rank::getScoreInfoValue( "triple" ) );
self thread giveAdrenaline( "triple" );
thread teamPlayerCardSplash( "callout_3xkill", self );
}
else
{
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "multikill", maps\mp\gametypes\_rank::getScoreInfoValue( "multi" ) );
self thread giveAdrenaline( "multi" );
thread teamPlayerCardSplash( "callout_3xpluskill", self );
}
self thread maps\mp\_matchdata::logMultiKill( killId, killCount );
// update player multikill record
self setPlayerStatIfGreater( "multikill", killCount );
// update player multikill count
self incPlayerStat( "mostmultikills", 1 );
}
firstBlood( killId )
{
self.modifiers["firstblood"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "firstblood", maps\mp\gametypes\_rank::getScoreInfoValue( "firstblood" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "firstblood" );
self thread maps\mp\_matchdata::logKillEvent( killId, "firstblood" );
self incPlayerStat( "firstblood", 1 );
thread teamPlayerCardSplash( "callout_firstblood", self );
}
winningShot( killId )
{
}
buzzKill( killId, victim )
{
self.modifiers["buzzkill"] = victim.pers["cur_kill_streak"];
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "buzzkill", maps\mp\gametypes\_rank::getScoreInfoValue( "buzzkill" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "buzzkill" );
self thread giveAdrenaline( "buzzkill" );
self thread maps\mp\_matchdata::logKillEvent( killId, "buzzkill" );
self.buzzkillcount++;
}
comeBack( killId )
{
self.modifiers["comeback"] = true;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "comeback", maps\mp\gametypes\_rank::getScoreInfoValue( "comeback" ) );
self thread maps\mp\gametypes\_rank::giveRankXP( "comeback" );
self thread giveAdrenaline( "comeback" );
self thread maps\mp\_matchdata::logKillEvent( killId, "comeback" );
self incPlayerStat( "comebacks", 1 );
}
disconnected()
{
myGuid = self.guid;
for ( entry = 0; entry < level._players.size; entry++ )
{
if ( isDefined( level._players[entry].killedPlayers[myGuid] ) )
level._players[entry].killedPlayers[myGuid] = undefined;
if ( isDefined( level._players[entry].killedPlayersCurrent[myGuid] ) )
level._players[entry].killedPlayersCurrent[myGuid] = undefined;
if ( isDefined( level._players[entry].killedBy[myGuid] ) )
level._players[entry].killedBy[myGuid] = undefined;
}
}
updateRecentKills( killId )
{
self endon ( "disconnect" );
level endon ( "game_ended" );
self notify ( "updateRecentKills" );
self endon ( "updateRecentKills" );
self.recentKillCount++;
wait ( 1.0 );
if ( self.recentKillCount > 1 )
self multiKill( killId, self.recentKillCount );
self.recentKillCount = 0;
}
monitorCrateJacking()
{
level endon( "end_game" );
self endon( "disconnect" );
for( ;; )
{
self waittill( "hijacker", crateType, owner );
if( crateType == "sentry" )
{
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "hijacker", 100 );
self thread maps\mp\gametypes\_rank::giveRankXP( "hijacker", 100 );
if ( isDefined( owner ) )
owner maps\mp\gametypes\_hud_message::playerCardSplashNotify( "hijacked_sentry", self );
self notify( "process", "ch_hijacker" );
}
else if( crateType == "mega" || crateType == "emergency_airdrop" )
{
if ( self.team == owner.team )
continue;
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "hijacker", 100 );
self thread maps\mp\gametypes\_rank::giveRankXP( "hijacker", 100 );
if ( isDefined( owner ) )
owner maps\mp\gametypes\_hud_message::playerCardSplashNotify( "hijacked_emergency_airdrop", self );
self notify( "process", "ch_newjack" );
}
else
{
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "hijacker", 100 );
self thread maps\mp\gametypes\_rank::giveRankXP( "hijacker", 100 );
if ( isDefined( owner ) )
owner maps\mp\gametypes\_hud_message::playerCardSplashNotify( "hijacked_airdrop", self );
self notify( "process", "ch_hijacker" );
}
}
}
monitorObjectives()
{
level endon( "end_game" );
self endon( "disconnect" );
self waittill( "objective", objType );
if ( objType == "captured" )
{
if ( isDefined( self.lastStand ) && self.lastStand )
{
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "heroic", 100 );
self thread maps\mp\gametypes\_rank::giveRankXP( "reviver", 100 );
}
}
}

177
maps/mp/_fantasystats.gsc Normal file
View File

@ -0,0 +1,177 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
MIN_TIME_IN_GAME = 0.25; //Min % of total match's length for which the player has to be in the match in order for his stats to be recorded
MIN_NUM_PLAYERS = 5; //Minimum number of players that need to be at the end of the match in order for the fantasy stats to be tracked
processFantasyStats()
{
if( ( matchMakingGame() )
&& ( level._players.size >= MIN_NUM_PLAYERS )
&& ( getDvarInt( "fantasyStatTracking" ) == 1 ) )
{
topscore = 0;
topPlayer = [];
foreach ( player in level._players )
{
if ( player.score >= topscore )
{
topscore = player.score;
topPlayer [ topPlayer.size ] = player;
}
}
foreach ( player in topPlayer )
{
player incPlayerStat ( "topscore", 1 );
}
localPlayerStatsInt = [
"kills",
"deaths",
"killstreak",
"headshots",
"grenadekills",
"uavs",
"mostmultikills",
"multikill",
"knifekills",
"flankkills",
"laststandkills",
"assists",
"c4kills",
"claymorekills",
"fragkills",
"semtexkills",
"explosionssurvived",
"adskills",
"hipfirekills",
"revengekills",
"longestlife",
"throwbacks",
"mostcamperkills",
"fbhits",
"stunhits",
"scopedkills",
"arkills",
"arheadshots",
"lmgkills",
"lmgheadshots",
"sniperkills",
"sniperheadshots",
"shieldblocks",
"shieldkills",
"smgkills",
"smgheadshots",
"shotgunkills",
"shotgunheadshots",
"pistolkills",
"pistolheadshots",
"rocketkills",
"equipmentkills",
"intelCompleted",
"explosivehits",
"machinepistolkills",
"machinepistolheadshots",
"rescues",
"throwingknifekills",
"killswhilepushingugv",
"killsenemywhopushesugv",
"crouchkills",
"pronekills",
"firstblood",
"backstabber",
"flagscaptured",
"flagsreturned",
"flagscarried",
"bombsplanted",
"bombsdefused",
"bombsdefender",
"targetsdestroyed",
"pointscaptured",
"bulletpenkills",
"killstunnedenemy",
"killcookedgrenade",
"killwithstolenweapons",
"gamewinningkill",
"killwithkillstreaks",
"checkpoints",
"killstreakdestroyed",
"killduringenemyairkillstreak",
"topscore",
"dompointscapturedsingular",
"domdefendwithequipment"
];
localPlayerStatsFloat = [ "kdratio" ];
// matchPlayerStatsInt = [
// "scoreXp",
// "matchXp" ];
// "hits",
// "misses",
// "totalShots",
// "accuracy" ];
gameLength = getTimePassed() / 1000; //getTimePassed returns the time in millisecond
foreach ( player in level._players )
{
if ( player.timePlayed["total"] > ( gameLength * MIN_TIME_IN_GAME ))
{
plat = "win";
if( level._xenon )
{
plat = "xen";
}
if( level._ps3 )
{
plat = "ps3";
}
bbString = "fantasy_cod: username %s plat %s ";
actualString = "fantasy_cod: username " + player.gamertag + " plat " + plat + " ";
bbData = [ player.gamertag, plat ];
println( "Fantasy Ints:" );
foreach( stat in localPlayerStatsInt )
{
if( player doesPlayerStatExist ( stat ))
{
data = player getPlayerStat( stat );
}
else
{
data = "0";
}
bbString += stat + " %d ";
actualString += stat + " " + data + " ";
bbData[ bbData.size ] = data;
println( stat + ": " + data );
}
println( "Fantasy floats:" );
foreach( stat in localPlayerStatsFloat )
{
if( player doesPlayerStatExist ( stat ))
{
data = player getPlayerStat( stat );
}
else
{
data = "0";
}
bbString += stat + " %f ";
actualString += stat + " " + data + " ";
bbData[ bbData.size ] = data;
println( stat + ": " + data );
}
// foreach( stat in matchPlayerStatsInt )
// {
// data = player getPlayerData( "round", stat );
// bbString += stat + " %d ";
// bbData[ bbData.size ] = data;
// }
println( bbString );
println( actualString );
bbprint( bbString, bbData, "uid" );
}
}
}
}

137
maps/mp/_flashgrenades.gsc Normal file
View File

@ -0,0 +1,137 @@
main()
{
precacheShellshock("flashbang_mp");
}
startMonitoringFlash()
{
self thread monitorFlash();
}
stopMonitoringFlash(disconnected)
{
self notify("stop_monitoring_flash");
}
flashRumbleLoop( duration )
{
self endon("stop_monitoring_flash");
self endon("flash_rumble_loop");
self notify("flash_rumble_loop");
goalTime = getTime() + duration * 1000;
while ( getTime() < goalTime )
{
self PlayRumbleOnEntity( "damage_heavy" );
wait( 0.05 );
}
}
monitorFlash()
{
self endon("disconnect");
self.flashEndTime = 0;
while(1)
{
self waittill( "flashbang", origin, amount_distance, amount_angle, attacker );
if ( !isalive( self ) )
continue;
if ( isDefined( self.usingRemote ) )
continue;
hurtattacker = false;
hurtvictim = true;
if ( amount_angle < 0.25 )
amount_angle = 0.25;
else if ( amount_angle > 0.8 )
amount_angle = 1;
duration = amount_distance * amount_angle * 5.5;
//NX1 flash resistance perk
if ( isDefined( self.flashScaler ) )
duration = duration * self.flashScaler;
if ( duration < 0.25 )
continue;
rumbleduration = undefined;
if ( duration > 2 )
rumbleduration = 0.75;
else
rumbleduration = 0.25;
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
{
}
else if(level._friendlyfire == 2) // reflect
{
duration = duration * .5;
rumbleduration = rumbleduration * .5;
hurtvictim = false;
hurtattacker = true;
}
else if(level._friendlyfire == 3) // share
{
duration = duration * .5;
rumbleduration = rumbleduration * .5;
hurtattacker = true;
}
}
else
{
attacker notify( "flash_hit" );
}
if (hurtvictim)
self thread applyFlash(duration, rumbleduration);
if (hurtattacker)
attacker thread applyFlash(duration, rumbleduration);
}
}
applyFlash(duration, rumbleduration)
{
// wait for the highest flash duration this frame,
// and apply it in the following frame
if (!isdefined(self.flashDuration) || duration > self.flashDuration)
self.flashDuration = duration;
if (!isdefined(self.flashRumbleDuration) || rumbleduration > self.flashRumbleDuration)
self.flashRumbleDuration = rumbleduration;
wait .05;
if (isdefined(self.flashDuration)) {
self shellshock( "flashbang_mp", self.flashDuration ); // TODO: avoid shellshock overlap
self.flashEndTime = getTime() + (self.flashDuration * 1000);
}
if (isdefined(self.flashRumbleDuration)) {
self thread flashRumbleLoop( self.flashRumbleDuration ); //TODO: Non-hacky rumble.
}
self.flashDuration = undefined;
self.flashRumbleDuration = undefined;
}
isFlashbanged()
{
return isDefined( self.flashEndTime ) && gettime() < self.flashEndTime;
}

482
maps/mp/_gasgrenades.gsc Normal file
View File

@ -0,0 +1,482 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
level._empInitialBlastTime = getDvarInt( "scr_empInitialEffectDuration", "10");
level._empCloudTickTime = getDvarInt( "scr_empTickEffectDuration", "3");
level._gasCloudDuration = getDvarInt( "scr_gasCloudDuration", "9");
level._gasCloudRadius = getDvarInt( "scr_gasCloudRadius", "185");
level._gasCloudHeight = getDvarInt( "scr_gasCloudHeight", "20");
level._gasCloudTickDamage = getDvarInt( "scr_gasCloudTickDamage", "13");
level._gasCloudTickDamageHardcore = getDvarInt( "scr_gasCloudTickDamageHardcore", "5");
level._empCloudDuration = getDvarInt( "scr_empCloudDuration", "9");
level._empCloudRadius = getDvarInt( "scr_empCloudRadius", "185");
level._empCloudHeight = getDvarInt( "scr_empCloudHeight", "20");
level._empCloudTickDamage = getDvarInt( "scr_empCloudTickDamage", "1");
level._gasCloudList = [];
level._empCloudList = [];
}
increaseEmpCloudedTime( amount )
{
self.empCloudedTime += amount;
}
watchEmpClouded()
{
self endon ( "death" );
self endon ( "disconnect" );
self.empCloudedTime = 0.0;
empCloudDeltaTime = 0.5;
for(;;)
{
self waittill( "emp_cloud_update" );
self playLocalSound( "emp_activate" );
if ( self _hasPerk( "specialty_localjammer" ))
self RadarJamOff();
self setEMPJammed( true );
//wait for the decay to finish
while( self.empCloudedTime > 0 )
{
wait( empCloudDeltaTime );
self.empCloudedTime -= empCloudDeltaTime;
}
if( self.empCLoudedTime < 0 )
{
self.empCloudedTime = 0;
}
//tagZP<NOTE> this should probably make sure that my team is not emp'd so that i do not turn off fx from the killstreak.
self setEMPJammed( false );
if ( self _hasPerk( "specialty_localjammer" ))
self RadarJamOn();
}
}
AddCloudToGasList( cloud )
{
list = level._gasCloudList;
list[ list.size ] = cloud;
level._gasCloudList = list;
}
RemoveCloudFromGasList( cloud )
{
newArray = [];
for( i = 0; i < level._gasCloudList.size; i++ )
{
if( level._gasCloudList[i] != cloud )
{
newArray[ newArray.size ] = level._gasCloudList[i];
}
}
level._gasCloudList = newArray;
}
AddCloudToEMPList( cloud )
{
list = level._empCloudList;
list[ list.size ] = cloud;
level._empCloudList = list;
}
RemoveCloudFromEMPList( cloud )
{
newArray = [];
for( i = 0; i < level._empCloudList.size; i++ )
{
if( level._empCloudList[i] != cloud )
{
newArray[ newArray.size ] = level._empCLoudList[i];
}
}
level._empCloudList = newArray;
}
//used by spawnlogic to determine the safty of this spawn point.
getCloudDanger( spawner )
{
cloudCount = 0;
triggers = level._gasCloudList;
foreach( trigger in triggers )
{
if( spawner isTouching( trigger ))
{
cloudCount++;
}
}
triggers = level._empCloudList;
foreach( trigger in triggers )
{
if( spawner isTouching( trigger ))
{
cloudCount++;
}
}
return cloudCount;
}
//returns true if the entity passed in is in any enemy clouds. Team should be passed in as my team. anyteam that doesnt match what is passed
//in is considered enemy. If team is not passed in all clouds are checked.
checkIsInCloud( entity, list, team )
{
foreach( cloud in list )
{
if( entity isTouching( cloud ))
{
if( isDefined( team ))
{
assert( isDefined( cloud.owner ));
assert( isplayer( cloud.owner ));
if( cloud.owner.pers["team"] != team )
{
return true;
}
}
else
{
return true;
}
}
}
return false;
}
gasGrenadeExplodeWaiter( type )
{
self endon( "end_explode" );
team = self.owner.team;
self waittill( "explode", position );
cloudObj = Spawn( "script_origin", position );
cloudObj.owner = self.owner;
cloudObj.team = team;
if( type == "gas" )
{
cloudObj thread gasCloudMonitor( level._gasCloudDuration );
}
else if( type == "emp" )
{
cloudObj thread empCloudMonitor( level._empCloudDuration );
}
}
gasCloudMonitor( duration )
{
//self endon( "death" );
position = self.origin;
gasCloudRadius = level._gasCloudRadius;
gasCloudHeight = level._gasCloudHeight;
gasCloudTickDamage = level._gasCloudTickDamage;
if ( level._hardcoreMode )
{
gasCloudTickDamage = level._gasCloudTickDamageHardcore;
}
// spawn trigger radius for the effect areas
gasEffectArea = spawn( "trigger_radius", position, 0, gasCloudRadius, gasCloudHeight );
gasEffectArea.owner = self.owner;
AddCloudToGasList( gasEffectArea );
gasTotalTime = 0.0; // keeps track of the total time the gas cloud has been "alive"
gasTickTime = 1.0; // gas cloud ticks damage every second
gasInitialWait = 1.5; // wait this long before the cloud starts ticking for damage
gasTickCounter = 0; // just an internal counter to count gas damage ticks
wait( gasInitialWait );
gasTotalTime += gasInitialWait;
for( ;; )
{
if( gasTotalTime >= duration )
{
break;
}
//send out some radial damage
//RadiusDamage( self.origin, gasCloudRadius, gasCloudTickDamageMax, gasCloudTickDamageMin, self.owner );
//apply shellshock/damage fx to players in the gas cloud
foreach( player in level._players )
{
if( level._teamBased )
{
if( !isDefined( player.team ))
{
continue;
}
if( !isDefined( self.owner ))
{
continue;
}
if( player.team == self.team && player != self.owner )
{
continue;
}
}
if( player istouching( gasEffectArea ) && player.sessionstate == "playing" )
{
if( ! ( player _hasPerk( "specialty_gasmask" )))
{
trace = bullettrace( position, player.origin, false, player );
if ( trace["fraction"] == 1 )
{
// NOTE: DoDamage( <health>, <source position>, <attacker>, <inflictor>, <hit-on-head>, <mod>, <dflags>, <weapon> )
//player DoDamgae( gasCloudTickDamageMin, position, self.owner, self, 0, "MOD_GAS", 0, "gas_grenade_mp" );
player shellShock( "gas_grenade_mp", 2 ); // Long enough...
RadiusDamage( player.origin, 16, gasCloudTickDamage, gasCloudTickDamage, self.owner); // "MOD_GAS", "gas_grenade_mp" );
//play coughing noise
player PlaySoundToPlayer( "breathing_gas_hurt", player );
}
}
}
}
wait( gasTickTime );
gasTotalTime += gasTickTime;
gasTickCounter += 1;
}
//clean up
RemoveCloudFromGasList( gasEffectArea );
gasEffectArea delete();
self delete();
}
empCloudMonitor( duration )
{
//self endon( "death" );
assert( isDefined( self.owner ));
empEffectArea = spawn( "trigger_radius", self.origin, 0, level._empCloudRadius, level._empCloudHeight );
empEffectArea.owner = self.owner;
AddCloudToEMPList( empEffectArea );
empCloudGrenadeInitialBlast( empEffectArea, self.owner );
//println( "added emp cloud to list, size = " + level._empCloudList.size );
empTotalTime = 0.0; // keeps track of the total time the emp cloud has been "alive"
empTickTime = 1.0; // emp cloud ticks damage every second
empInitialWait = 1.5; // wait this long before the cloud starts ticking for damage
empTickCounter = 0; // just an internal counter to count gas damage ticks
wait( empInitialWait );
empTotalTime += empInitialWait;
for( ;; )
{
if( empTotalTime >= duration )
{
break;
}
//apply emp fx to players in the emp cloud
foreach( player in level._players )
{
if( level._teamBased )
{
if( !isDefined( player.team ))
{
continue;
}
if( !isDefined( self.owner ))
{
continue;
}
if( player.team == self.team && player != self.owner )
{
continue;
}
}
if( player istouching( empEffectArea ) && player.sessionstate == "playing" )
{
//player thread maps\mp\killstreaks\_emp::EMPGrenade_JamPlayer( level._empCloudTickTime );
player increaseEmpCloudedTime( level._empCloudTickTime );
player notify( "emp_cloud_update" );
if( level._empCloudTickDamage > 0 )
{
RadiusDamage( player.origin, 16, level._empCloudTickDamage, level._empCloudTickDamage, self.owner);
}
}
}
wait( empTickTime );
empTotalTime += empTickTime;
empTickCounter += 1;
}
//clean up
RemoveCloudFromEMPList( empEffectArea );
//println( "removed emp cloud from list, size = " + level._empCloudList.size );
empEffectArea delete();
self delete();
}
//Apply initial damage to world ents on explosion
empCloudGrenadeInitialBlast( trigger, attacker )
{
assert( isDefined( trigger ));
assert( isDefined( attacker ));
//hit players with the initial blast
foreach( player in level._players )
{
if( level._teamBased )
{
if( !isDefined( player.pers["team"] ))
{
continue;
}
if( !isDefined( attacker ))
{
continue;
}
if( player.pers["team"] == attacker.pers["team"] && player != attacker )
{
continue;
}
}
if( player istouching( trigger ) && player.sessionstate == "playing" )
{
//player thread maps\mp\killstreaks\_emp::EMPGrenade_JamPlayer( level._empInitialBlastTime );
player increaseEmpCloudedTime( level._empInitialBlastTime );
player notify( "emp_cloud_update" );
}
}
//take out enemy c4 in the initial blast
destroyEnemyC4( attacker, trigger );
//take down any helis it hits
foreach ( heli in level._helis )
{
if( heli isTouching( trigger ))
{
radiusDamage( heli.origin, 384, 5000, 5000, attacker );
}
}
//take down any little birds
foreach ( littleBird in level._littleBird )
{
if( littleBird isTouching( trigger ))
{
radiusDamage( littleBird.origin, 384, 5000, 5000, attacker );
}
}
/*
foreach ( turret in level._turrets )
radiusDamage( turret.origin, 16, 5000, 5000, attacker );
foreach ( rocket in level._rockets )
rocket notify ( "death" );
*/
//take down any uavs it hits
if ( level._teamBased )
{
foreach ( uav in level._uavModels["allies"] )
{
if( uav isTouching( trigger ))
{
radiusDamage( uav.origin, 384, 5000, 5000, attacker );
}
}
foreach ( uav in level._uavModels["axis"] )
{
if( uav isTouching( trigger ))
{
radiusDamage( uav.origin, 384, 5000, 5000, attacker );
}
}
}
else
{
foreach ( uav in level._uavModels )
{
if( uav isTouching( trigger ))
{
radiusDamage( uav.origin, 384, 5000, 5000, attacker );
}
}
}
//take down any ac130's it hits
if ( isDefined( level._ac130player ) )
{
if( level._ac130player isTouching( trigger ))
{
radiusDamage( level._ac130.planeModel.origin+(0,0,10), 1000, 5000, 5000, attacker );
}
}
}
destroyEnemyC4( attacker, trigger )
{
foreach ( player in level._players )
{
if ( player.pers["team"] != attacker.pers["team"] || ! level._teambased )
{
if( isDefined( player.c4array ))
{
if ( player.c4Array.size > 0 )
{
for( i = 0; i < player.c4Array.size; i++ )
{
if( player.c4Array[i] isTouching( trigger ))
{
player notify( "alt_detonate" );
}
}
}
}
}
}
}

147
maps/mp/_global_fx.gsc Normal file
View File

@ -0,0 +1,147 @@
#include common_scripts\utility;
#include maps\mp\_utility;
// This script automaticly plays a users specified oneshot effect on all prefabs that have the
// specified "script_struct" and "targetname" It also excepts angles from the "script_struct"
// but will set a default angle of ( 0, 0, 0 ) if none is defined.
//
// example of the syntax:
// global_FX( "targetname", "fxIDname", "fxFile", "delay"
main()
{
randomStartDelay = randomfloatrange( -20, -15 );
// prefabs/misc_models/com_barrel_fire.map
global_FX( "barrel_fireFX_origin", "global_barrel_fire", "fire/firelp_barrel_pm", randomStartDelay, "fire_barrel_small" );
// prefabs/misc_models/ch_street_light_02_on.map
// prefabs/misc_models/ch_street_wall_light_01_on.map
global_FX( "ch_streetlight_02_FX_origin", "ch_streetlight_02_FX", "misc/lighthaze", randomStartDelay );
// prefabs/misc_models/me_streetlight_on.map
// prefabs/misc_models/me_streetlight_on_scaleddown80.map
global_FX( "me_streetlight_01_FX_origin", "me_streetlight_01_FX", "misc/lighthaze_bog_a", randomStartDelay );
// prefabs\village_assault\misc\lamp_post.map
// prefabs\misc_models\ch_street_light_01_on.map
global_FX( "ch_street_light_01_on", "lamp_glow_FX", "misc/light_glow_white", randomStartDelay );
// prefabs\dcburning\lamp_post_globe_on.map
global_FX( "lamp_post_globe_on", "lamp_glow_FX", "misc/light_glow_white", randomStartDelay );
// prefabs\village_assault\misc\highway_lamp_post.map
global_FX( "highway_lamp_post", "ch_streetlight_02_FX", "misc/lighthaze_villassault", randomStartDelay );
// prefabs/misc_models/cs_cargoship_spotlight_on.map
global_FX( "cs_cargoship_spotlight_on_FX_origin", "cs_cargoship_spotlight_on_FX", "misc/lighthaze", randomStartDelay );
// prefabs/misc_models/me_dumpster_fire.map
global_FX( "me_dumpster_fire_FX_origin", "me_dumpster_fire_FX", "fire/firelp_med_pm", randomStartDelay, "fire_dumpster_medium" );
// prefabs/misc_models/com_tires01_burning.map
global_FX( "com_tires_burning01_FX_origin", "com_tires_burning01_FX", "fire/tire_fire_med", randomStartDelay );
// prefabs/icbm/icbm_powerlinetower02.map
global_FX( "icbm_powerlinetower_FX_origin", "icbm_powerlinetower_FX", "misc/power_tower_light_red_blink", randomStartDelay );
// prefabs/icbm/icbm_powerlinetower02.map
global_FX( "icbm_mainframe_FX_origin", "icbm_mainframe_FX", "props/icbm_mainframe_lightblink", randomStartDelay );
// prefabs/misc_model/cs_cargoship_wall_light_red_pulse.map
global_FX( "light_pulse_red_FX_origin", "light_pulse_red_FX", "misc/light_glow_red_generic_pulse", -2 );
// prefabs/misc_model/cs_cargoship_wall_light_red_pulse.map
global_FX( "light_pulse_red_FX_origin", "light_pulse_red_FX", "misc/light_glow_red_generic_pulse", -2 );
// prefabs/misc_model/cs_cargoship_wall_light_orange_pulse.map
global_FX( "light_pulse_orange_FX_origin", "light_pulse_orange_FX", "misc/light_glow_orange_generic_pulse", -2 );
// prefabs/oilrig/lights/light_corner_01.map
// prefabs/oilrig/helipad/helipad_light.map
global_FX( "light_red_blink_FX_origin", "light_red_blink", "misc/power_tower_light_red_blink", -2 );
// prefabs/misc_models/ch_industrial_light_01_on.map
global_FX( "lighthaze_oilrig_FX_origin", "lighthaze_oilrig", "misc/lighthaze_oilrig", randomStartDelay );
// prefabs/misc_models/ch_industrial_light_01_on_white.map
global_FX( "lighthaze_white_FX_origin", "lighthaze_white", "misc/lighthaze_white", randomStartDelay );
// prefabs/misc_models/cs_cargoship_wall_light_on.map
global_FX( "light_glow_walllight_white_FX_origin", "light_glow_walllight_white", "misc/light_glow_walllight_white", randomStartDelay );
// prefabs/misc_models/me_lightfluohang_on.map
global_FX( "fluorescent_glow_FX_origin", "fluorescent_glow", "misc/fluorescent_glow", randomStartDelay );
// prefabs/misc_models/ch_industrial_light_02_on.map
global_FX( "light_glow_industrial_FX_origin", "light_glow_industrial", "misc/light_glow_industrial", randomStartDelay );
// prefabs/cliffhanger/red_light1.map
// prefabs/misc_model/com_emergencylightcase_on.map
global_FX( "light_red_steady_FX_origin", "light_red_steady", "misc/tower_light_red_steady", -2 );
// prefabs/cliffhanger/blue_light1.map
// prefabs/oilrig/helipad/helipad_light.map
// prefabs/misc_model/com_emergencylightcase_blue_on.map
global_FX( "light_blue_steady_FX_origin", "light_blue_steady", "misc/tower_light_blue_steady", -2 );
// prefabs/misc_models/com_emergencylightcase_orange.map
global_FX( "light_orange_steady_FX_origin", "light_orange_steady", "misc/tower_light_orange_steady", -2 );
// prefabs/misc_models/mil_lightstick_pile_on.map
global_FX( "glow_stick_pile_FX_origin", "glow_stick_pile", "misc/glow_stick_glow_pile", -2 );
// prefabs/misc_models/mil_lightstick_pile_on_orange.map
global_FX( "glow_stick_orange_pile_FX_origin", "glow_stick_pile_orange", "misc/glow_stick_glow_pile_orange", -2 );
// prefabs/plaza/blinky_tower.map
global_FX( "highrise_blinky_tower", "highrise_blinky_tower_FX", "misc/power_tower_light_red_blink_large", randomStartDelay );
// prefabs/mil_emergency_flare.map
global_FX( "flare_ambient_FX_origin", "flare_ambient_FX", "misc/flare_ambient", randomStartDelay, "emt_road_flare_burn" );
// prefabs/misc_models/dt_light_on.map
// prefabs/misc_models/com_utility_light_on.map
// prefabs/misc_models/utility_lightbulb_bare_on.map
global_FX( "light_glow_white_bulb_FX_origin", "light_glow_white_bulb_FX", "misc/light_glow_white_bulb", randomStartDelay);
// prefabs/misc_models/com_restaurantceilinglamp_on.map
global_FX( "light_glow_white_lamp_FX_origin", "light_glow_white_lamp_FX", "misc/light_glow_white_lamp", randomStartDelay);
}
global_FX( targetname, fxName, fxFile, delay, soundalias )
{
// script_structs
ents = getstructarray(targetname,"targetname");
if ( !isdefined( ents ) )
return;
if ( ents.size <= 0 )
return;
for ( i = 0 ; i < ents.size ; i++ )
ents[i] global_FX_create( fxName, fxFile, delay, soundalias );
}
global_FX_create( fxName, fxFile, delay, soundalias )
{
if ( !isdefined( level._effect ) )
level._effect = [];
if ( !isdefined( level._effect[ fxName ] ) )
level._effect[ fxName ] = loadfx( fxFile );
// default effect angles if they dont exist
if ( !isdefined( self.angles ) )
self.angles = ( 0, 0, 0 );
ent = createOneshotEffect( fxName );
ent.v[ "origin" ] = ( self.origin );
ent.v[ "angles" ] = ( self.angles );
ent.v[ "fxid" ] = fxName;
ent.v[ "delay" ] = delay;
if ( isdefined( soundalias ) )
{
ent.v[ "soundalias" ] = soundalias;
}
}

16
maps/mp/_highlights.gsc Normal file
View File

@ -0,0 +1,16 @@
#include maps\mp\_utility;
#include common_scripts\utility;
giveHighlight( ref, value )
{
highlightCount = getClientMatchData( "highlightCount" );
if ( highlightCount < 18 ) // must match MaxHighlights in clientmatchdata definition
{
setClientMatchData( "highlights", highlightCount, "award", ref );
setClientMatchData( "highlights", highlightCount, "clientId", self.clientMatchDataId );
setClientMatchData( "highlights", highlightCount, "value", value );
highlightCount++;
setClientMatchData( "highlightCount", highlightCount );
}
}

791
maps/mp/_intel.gsc Normal file
View File

@ -0,0 +1,791 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
INTEL_OFFSET = (0, 0, 24);
INTEL_OFFSET_TOP = (0, 0, 36);
INTEL_ICON_PULSE_SCALE = 1.2;
INTEL_ICON_PULSE_WAIT_SEC = 5;
INTEL_ICON_COLOR = (1,1,1);
//*******************************************************************
// *
// *
//*******************************************************************
init()
{
if( getDvarInt( "prototype_intel_enabled" ) == 1 )
{
println( "Intel enabled" );
intelGamePercentage = getDvarInt( "prototype_intel_percentage" );
if( intelGamePercentage >= randomInt( 100 ))
{
println( "Intel: This will be an intel game" );
initIntel();
level thread onPlayerConnect();
level thread addIntelToGame();
//tempGetStarted();
}
else
{
println( "Intel: This is not going to be an intel game" );
}
}
else
{
println( "Intel not inited ", getDvarInt( "prototype_intel_enabled" ));
}
}
tempGetStarted()
{
level waittill("connected", player);
player thread tempGetStartedSpawned();
}
tempGetStartedSpawned()
{
wait 3;
// setup the team, close the menu, then set our class and wait for our player to spawn
self [[level._onTeamSelection]]( "allies" );
self closepopupMenu();
self closeInGameMenu();
self.selectedClass = true;
self [[level._class]]("class0");
players = getentarray("player", "classname");
while( players.size == 0 )
{
wait 1;
players = getentarray("player", "classname");
}
}
intelDebugging()
{
return false;
}
//*******************************************************************
// *
// *
//*******************************************************************
initIntel()
{
// setup the models and stuff we need for intel
//precacheShader("waypoint_bomb");
precacheModel( "prop_suitcase_intel" );
precacheString(&"MP_AQUIRING_INTEL");
precacheString(&"MP_INTEL_HEADER");
level._intelHUDIcon = "hud_suitcase_bomb";
precacheShader( level._intelHUDIcon );
level._intel = undefined;
// we need to setup our array of intel types
intelInitData = [];
intelInitData["replenish"] = "ammo_primary";
intelKillsEvalData = [];
intelKillsEvalData["kills"]["count"] = 3;
intelKillsEvalData["kills"]["string"] = &"MP_INTEL_KILLS_DESC";
intelKillsAwardData = [];
intelKillsAwardData["experience"] = 1000;
addIntelType( "intel_kills", 0, 15, ::initLifeStats, intelInitData, ::evalLifeStats, intelKillsEvalData, ::intelAward, intelKillsAwardData );
intelInitData = [];
intelInitData["replenish"] = "ammo_primary";
intelKillsEvalData = [];
intelKillsEvalData["headshots"]["count"] = 1;
intelKillsEvalData["headshots"]["string"] = &"MP_INTEL_HEADSHOT_DESC";
intelKillsAwardData = [];
intelKillsAwardData["experience"] = 1000;
addIntelType( "intel_headshot", 0, 15, ::initLifeStats, intelInitData, ::evalLifeStats, intelKillsEvalData, ::intelAward, intelKillsAwardData );
intelInitData = [];
intelInitData["replenish"] = "ammo_primary";
intelKillsEvalData = [];
intelKillsEvalData["mostmultikills"]["count"] = 1;
intelKillsEvalData["mostmultikills"]["string"] = &"MP_INTEL_MULTIKILL_DESC";
intelKillsAwardData = [];
intelKillsAwardData["experience"] = 1000;
addIntelType( "intel_multikills", 0, 15, ::initLifeStats, intelInitData, ::evalLifeStats, intelKillsEvalData, ::intelAward, intelKillsAwardData );
intelInitData = [];
intelInitData["replenish"] = "equipment";
intelKillsEvalData = [];
intelKillsEvalData["equipmentkills"]["count"] = 1;
intelKillsEvalData["equipmentkills"]["string"] = &"MP_INTEL_EQUIPMENT_DESC";
intelKillsAwardData = [];
intelKillsAwardData["experience"] = 1000;
addIntelType( "intel_equipmentkills", 0, 15, ::initLifeStats, intelInitData, ::evalLifeStats, intelKillsEvalData, ::intelAward, intelKillsAwardData );
// generate the max weighted value
level._intelMaxWeight = 0;
foreach ( intelName, intelDef in level._intelDefs )
{
if ( intelDef["weight"] > 0 )
{
level._intelMaxWeight += intelDef["weight"];
level._intelDefs[intelName]["weight"] = level._intelMaxWeight;
// println( "Adding intel " + intelName + " with weight value " + intelDef["weight"] + " max weight is " + level._intelMaxWeight );
}
else
{
println( "Warning: Intel def with 0 weight! name = ", intelName );
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
addIntelType( name, intelLevel, weight, initFunc, initData, evalFunc, evalData, awardFunc, awardData )
{
evalData["name"] = name;
awardData["name"] = name;
level._intelDefs[name]["weight"] = weight;
level._intelDefs[name]["intelLevel"] = intelLevel;
level._intelDefs[name]["initFunc"] = initFunc;
level._intelDefs[name]["initData"] = initData;
level._intelDefs[name]["evalFunc"] = evalFunc;
level._intelDefs[name]["evalData"] = evalData;
level._intelDefs[name]["awardFunc"] = awardFunc;
level._intelDefs[name]["awardData"] = awardData;
foreach( evalPiece, evalDataList in evalData )
{
println( evalPiece );
if( evalPiece != "name" && isDefined( evalDataList["string"] ))
{
PreCacheString( evalDataList["string"] );
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
getRandomIntel()
{
value = randomInt( level._intelMaxWeight );
selectedIntelName = undefined;
foreach ( intelName, intelDef in level._intelDefs )
{
if( intelDef["weight"] > 0 )
{
selectedIntelName = intelName;
if ( intelDef["weight"] > value )
{
break;
}
}
}
return( selectedIntelName );
}
//*******************************************************************
// *
// *
//*******************************************************************
initIntelOnPlayer( player )
{
process = level._intelDefs[ level._intel ][ "initFunc" ];
processInitData = level._intelDefs[ level._intel ][ "initData" ];
processEvalData = level._intelDefs[ level._intel ][ "evalData" ];
return [[ process ]]( player, processInitData, processEvalData );
}
//*******************************************************************
// *
// *
//*******************************************************************
evalIntelOnPlayer( player )
{
process = level._intelDefs[ level._intel ][ "evalFunc" ];
processData = level._intelDefs[ level._intel ][ "evalData" ];
return [[ process ]]( player, processData );
}
//*******************************************************************
// *
// *
//*******************************************************************
awardIntelOnPlayer( player )
{
process = level._intelDefs[ level._intel ][ "awardFunc" ];
processData = level._intelDefs[ level._intel ][ "awardData" ];
[[ process ]]( player, processData );
}
//*******************************************************************
// *
// *
//*******************************************************************
addIntelToGame()
{
level._intel = getRandomIntel();
println( "Intel added to the game ", level._intel );
// wait till we have some player connected
level waittill( "connected", player );
while( level._players.size == 0 )
{
wait 0.05;
}
// find a intel spawn location
spawnPoint = findIntelSpawnLocation();
assert( isDefined( spawnPoint ));
// create the use objects
level._intelEnt = createIntelBreifcase( spawnPoint );
}
//*******************************************************************
// *
// *
//*******************************************************************
findIntelSpawnLocation()
{
// for now, just grab a random dom point
// randomPlayer = level._players[ randomInt( level._players.size ) ];
// randomPlayer waittill( "spawned_player" );
// return randomPlayer [[ level._getSpawnPoint ]]();
while( 1 )
{
wait 0.5;
if( isDefined( level._spawnpoints ))
{
if( level._spawnpoints.size > 0 )
{
break;
}
}
}
return level._spawnpoints[ randomInt( level._spawnpoints.size ) ];
}
//*******************************************************************
// *
// *
//*******************************************************************
createIntelBreifcase( entity )
{
visuals[0] = spawn( "script_model", entity.origin );
visuals[0].angles = entity.angles;
visuals[0] setModel( "prop_suitcase_intel" );
cloneTrigger = spawn( "trigger_radius", entity.origin, 0, 96, 60 );
intelEnt = cloneTrigger;
intelZone = maps\mp\gametypes\_gameobjects::createCarryObject( "friendly", intelEnt, visuals, INTEL_OFFSET );
intelZone maps\mp\gametypes\_gameobjects::setUseTime( 0.5 );
intelZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_AQUIRING_INTEL" );
intelZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
// intelZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
// intelZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
// intelZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_bomb" );
// intelZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_bomb" );
intelZone maps\mp\gametypes\_gameobjects::allowCarry( "any" );
intelZone maps\mp\gametypes\_gameobjects::setCarrierVisible( false );
intelZone thread intelSpinAnimate();
intelZone.onPickup = ::onPickupIntel;
intelZone.onDrop = ::onDropIntel;
intelZone.allowWeapons = true;
intelZone.oldRadius = intelEnt.radius;
return intelZone;
}
//*******************************************************************
// *
// *
//*******************************************************************
intelSpinAnimate()
{
level endon( "game_ended" );
self endon( "reset" );
self endon( "pickup_object" );
bottomPos = self.curOrigin + INTEL_OFFSET;
topPos = self.curOrigin + INTEL_OFFSET_TOP;
while( true )
{
self.visuals[0] moveTo( topPos, 0.5, 0.15, 0.15 );
self.visuals[0] rotateYaw( 180, 0.5 );
wait( 0.5 );
self.visuals[0] moveTo( bottomPos, 0.5, 0.15, 0.15 );
self.visuals[0] rotateYaw( 180, 0.5 );
wait( 0.5 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
onPickupIntel( player )
{
// level._intelEnt maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", undefined );
// level._intelEnt maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", undefined );
// level._intelEnt maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", undefined );
// level._intelEnt maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", undefined );
player thread onIntelAquired();
}
//*******************************************************************
// *
// *
//*******************************************************************
onDropIntel( player )
{
// level._intelEnt maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
// level._intelEnt maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
// level._intelEnt maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_bomb" );
// level._intelEnt maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_bomb" );
level._intelEnt thread intelSpinAnimate();
intelCardSplashEveryone( "intel_dropped_callout", player );
}
//*******************************************************************
// *
// *
//*******************************************************************
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread notifyIntelGame();
player thread onPlayerSpawned();
}
}
//*******************************************************************
// *
// *
//*******************************************************************
onPlayerSpawned()
{
self endon( "disconnect" );
if( intelDebugging())
println( "Intel: onPlayerSpawned" );
for(;;)
{
self waittill( "spawned_player" );
if( intelDebugging())
println( "Intel: Player spawned" );
self._intelHasIntel = 0;
// self thread intelWaitDeath();
}
}
//*******************************************************************
// *
// *
//*******************************************************************
intelWaitDeath()
{
self endon( "intel_cleanup" );
self waittill( "death" );
self notify( "intel_cleanup" );
}
//*******************************************************************
// *
// *
//*******************************************************************
intelWaitCleanup()
{
self waittill( "intel_cleanup" );
wait 1;
self destroyIntelHud();
}
//*******************************************************************
// *
// *
//*******************************************************************
onIntelAquired()
{
self endon( "disconnect" );
self endon( "death" );
//intelCardSplashEveryone( "intel_pickup_callout", self );
self._intelHasIntel = 1;
self createIntelHud();
self thread intelWaitDeath();
self thread intelWaitCleanup();
println( "Intel: intel aquired by ", self.name );
initIntelOnPlayer( self );
while( 1 )
{
if( evalIntelOnPlayer( self ) == 1 )
{
println( "Intel: Awarding intel to player" );
intelCardSplashEveryone( "intel_completed_callout", self );
self incPlayerStat( "intelCompleted", 1 );
awardIntelOnPlayer( self );
// get rid of the intel, it's served it's purpose
//level._intelEnt thread maps\mp\gametypes\_gameobjects::deleteUseObject();
level._intelEnt maps\mp\gametypes\_gameobjects::disableObject();
break;
}
wait 0.05;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// Evaluation and Award funcs
//*******************************************************************
// *
// *
//*******************************************************************
initLifeStats( player, initData, evalData )
{
if( intelDebugging())
println( "Initing Intel on ", player.name );
i = 0;
foreach( intelStat, intelStatValue in evalData )
{
if( intelStat != "name" )
{
player._intelInitValues[intelStat] = getPlayerStat( intelStat );
player._intelHud["lines"][i]["item"] SetText( intelStatValue["string"] );
i += 1;
}
}
if( isDefined( initData["replenish"] ))
{
weaponList = player GetWeaponsListAll();
switch( initData["replenish"] )
{
case "ammo_primary":
foreach ( weaponName in weaponList )
{
if ( maps\mp\gametypes\_weapons::isPrimaryWeapon( weaponName ) )
{
player giveMaxAmmo( weaponName );
}
}
break;
case "equipment":
foreach ( weaponName in weaponList )
{
if ( maps\mp\gametypes\_weapons::isEquipment( weaponName ) )
{
player giveMaxAmmo( weaponName );
}
}
break;
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
evalLifeStats( player, evalData )
{
ret = 0;
allStatsSatisfied = 1;
if( intelDebugging())
println( "Evaluating Intel on ", player.name );
if( isDefined( evalData ))
{
i = 0;
foreach( intelStat, intelDef in evalData )
{
if( intelStat != "name" )
{
intelStatValue = intelDef["count"];
currStatValue = ( getPlayerStat( intelStat ) - player._intelInitValues[intelStat] );
if( intelDebugging())
println( "Checking ", intelStat, " value ", intelStatValue );
if( currStatValue < intelStatValue )
{
allStatsSatisfied = 0;
}
else
{
currStatValue = intelStatValue;
}
// hud text
hudText = currStatValue + "/" + intelStatValue;
if( player._intelHud["lines"][i]["text"] != hudText )
{
player._intelHud["lines"][i]["text"] = hudText;
player._intelHud["lines"][i]["status"] SetText( hudText );
}
i = i + 1;
}
}
if( allStatsSatisfied == 1 )
{
ret = 1;
}
}
else
{
println( "Could not find evaluation data!\n" );
}
return ret;
}
//*******************************************************************
// *
// *
//*******************************************************************
intelAward( player, awardData )
{
println( "Giving Intel Award to ", player.name );
if( isDefined( awardData ))
{
player thread maps\mp\gametypes\_hud_message::SplashNotify( "intel_completed", awardData["experience"] );
foreach( award, value in awardData )
{
if( award != "name" )
{
println( award, " ", value );
switch( award )
{
case "experience":
self thread awardIntelXp( value, awardData );
break;
default:
println( "Didn't understand how to deal with award type ", award );
}
}
}
}
else
{
println( "No awards found!" );
}
player notify( "intel_cleanup" );
}
//*******************************************************************
// *
// *
//*******************************************************************
// Hud Notificaiton Scripts
//*******************************************************************
// *
// *
//*******************************************************************
awardIntelXp( value, awardData )
{
self endon ( "disconnect" );
wait( 0.25 );
self maps\mp\gametypes\_rank::giveRankXP( "challenge", value );
}
//*******************************************************************
// *
// *
//*******************************************************************
notifyIntelGame()
{
self waittill( "spawned_player" );
if( intelDebugging())
println( "We are playing a game with Intel!" );
self thread maps\mp\gametypes\_hud_message::SplashNotify( "intel_ingame", 0 );
}
//*******************************************************************
// *
// *
//*******************************************************************
intelCardSplashEveryone( splash, owner )
{
if ( level._hardCoreMode )
return;
foreach ( player in level._players )
{
player thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( splash, owner );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
hudIconPulse()
{
self endon( "intel_cleanup" );
origWidth = self._intelHud["icon"].width;
origHeight = self._intelHud["icon"].height;
for(;;)
{
self._intelHud["icon"] scaleOverTime( 0.05, int( origWidth * INTEL_ICON_PULSE_SCALE ), int( origHeight * INTEL_ICON_PULSE_SCALE ) );
wait 0.05;
self._intelHud["icon"] scaleOverTime( 0.3, origWidth, origHeight );
wait 0.3;
wait INTEL_ICON_PULSE_WAIT_SEC;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
createIntelHud()
{
self._intelHud["icon"] = createIcon( level._intelHUDIcon, 40, 40 );
self._intelHud["icon"].horzAlign = "left";
self._intelHud["icon"].alignX = "left";
self._intelHud["icon"].y = 110;
self._intelHud["icon"].sort = -10;
self._intelHud["icon"].color = INTEL_ICON_COLOR;
self thread hudIconPulse();
currY = 130;
self._intelHud["header"] = CreateFontString( "objective", 1.3 );
self._intelHud["header"].horzAlign = "left";
self._intelHud["header"].alignX = "left";
self._intelHud["header"] SetText( &"MP_INTEL_HEADER" );
self._intelHud["header"].y = currY;
self._intelHud["header"].x = 42;
currY += 20;
xIndent = 20;
xOffset = 40;
self._intelHud["lines"][0]["item"] = CreateFontString( "objective", 1.25 );
self._intelHud["lines"][0]["item"].horizAlign = "left";
self._intelHud["lines"][0]["item"].alignX = "left";
self._intelHud["lines"][0]["item"].y = currY;
self._intelHud["lines"][0]["item"].x = xIndent + xOffset;
self._intelHud["lines"][0]["status"] = CreateFontString( "objective", 1.25 );
self._intelHud["lines"][0]["status"].horizAlign = "left";
self._intelHud["lines"][0]["status"].alignX = "left";
self._intelHud["lines"][0]["status"].y = currY;
self._intelHud["lines"][0]["status"].x = xIndent;
self._intelHud["lines"][0]["text"] = "";
currY += 20;
self._intelHud["lines"][1]["item"] = CreateFontString( "objective", 1.25 );
self._intelHud["lines"][1]["item"].horizAlign = "left";
self._intelHud["lines"][1]["item"].alignX = "left";
self._intelHud["lines"][1]["item"].y = currY;
self._intelHud["lines"][1]["item"].x = xIndent + xOffset;
self._intelHud["lines"][1]["status"] = CreateFontString( "objective", 1.25 );
self._intelHud["lines"][1]["status"].horizAlign = "left";
self._intelHud["lines"][1]["status"].alignX = "left";
self._intelHud["lines"][1]["status"].y = currY;
self._intelHud["lines"][1]["status"].x = xIndent;
self._intelHud["lines"][1]["text"] = "";
currY += 20;
self._intelHud["lines"][2]["item"] = CreateFontString( "objective", 1.25 );
self._intelHud["lines"][2]["item"].horizAlign = "left";
self._intelHud["lines"][2]["item"].alignX = "left";
self._intelHud["lines"][2]["item"].y = currY;
self._intelHud["lines"][2]["item"].x = xIndent + xOffset;
self._intelHud["lines"][2]["status"] = CreateFontString( "objective", 1.25 );
self._intelHud["lines"][2]["status"].horizAlign = "left";
self._intelHud["lines"][2]["status"].alignX = "left";
self._intelHud["lines"][2]["status"].y = currY;
self._intelHud["lines"][2]["status"].x = xIndent;
self._intelHud["lines"][2]["text"] = "";
}
//*******************************************************************
// *
// *
//*******************************************************************
destroyIntelHud()
{
self._intelHud["icon"] destroy();
self._intelHud["header"] destroy();
self._intelHud["lines"][0]["item"] destroy();
self._intelHud["lines"][0]["status"] destroy();
self._intelHud["lines"][1]["item"] destroy();
self._intelHud["lines"][1]["status"] destroy();
self._intelHud["lines"][2]["item"] destroy();
self._intelHud["lines"][2]["status"] destroy();
}

615
maps/mp/_javelin.gsc Normal file
View File

@ -0,0 +1,615 @@
#include maps\mp\_utility;
#include common_scripts\utility;
InitJavelinUsage()
{
self.javelinStage = undefined;
self.javelinPoints = undefined;
self.javelinNormals = undefined;
self.javelinLockMisses = undefined;
self.javelinTargetPoint = undefined;
self.javelinTargetNormal = undefined;
self.javelinLockStartTime = undefined;
}
ResetJavelinLocking()
{
if ( !IsDefined( self.javelinUseEntered ) )
return;
self.javelinUseEntered = undefined;
self notify( "stop_lockon_sound" );
self WeaponLockFree();
self WeaponLockTargetTooClose( false );
self WeaponLockNoClearance( false );
self.currentlyLocking = false;
self.currentlyLocked = false;
self.javelinTarget = undefined;
self StopLocalSound( "javelin_clu_lock" );
self StopLocalSound( "javelin_clu_aquiring_lock" );
InitJavelinUsage();
}
/#
DrawStar( point, color )
{
Line( point + (10,0,0), point - (10,0,0), color );
Line( point + (0,10,0), point - (0,10,0), color );
Line( point + (0,0,10), point - (0,0,10), color );
}
#/
EyeTraceForward()
{
origin = self GetEye();
angles = self GetPlayerAngles();
forward = AnglesToForward( angles );
endpoint = origin + forward * 15000;
res = BulletTrace( origin, endpoint, false, undefined );
if ( res["surfacetype"] == "none" )
return undefined;
if ( res["surfacetype"] == "default" )
return undefined;
ent = res["entity"];
if ( IsDefined( ent ) )
{
if ( ent == level._ac130.planeModel )
return undefined;
}
results = [];
results[0] = res["position"];
results[1] = res["normal"];
return results;
}
LockMissesReset()
{
self.javelinLockMisses = undefined;
}
LockMissesIncr()
{
if ( !IsDefined( self.javelinLockMisses ) )
self.javelinLockMisses = 1;
else
self.javelinLockMisses++;
}
LockMissesPassedThreshold()
{
MAX_MISSES = 4;
if ( IsDefined( self.javelinLockMisses ) && (self.javelinLockMisses >= MAX_MISSES) )
return true;
return false;
}
TargetPointTooClose( targetPoint )
{
// changed by NS JKU was 1100. since this is no longer a secondary, we can be a little more liberal with the targeting.
MY_MIN_DIST = 700;
dist = Distance( self.origin, targetPoint );
if ( dist < MY_MIN_DIST )
return true;
return false;
}
LoopLocalSeekSound( alias, interval )
{
self endon ( "death" );
self endon ( "disconnect" );
self endon ( "stop_lockon_sound" );
for ( ;; )
{
self PlayLocalSound( alias );
wait interval;
}
}
TopAttackPasses( targPoint, targNormal )
{
origin = targPoint + (targNormal * 10.0);
endpoint = origin + (0,0,2000);
result = BulletTrace( origin, endpoint, false, undefined );
if ( BulletTracePassed( origin, endpoint, false, undefined ) )
return true;
return false;
}
JavelinUsageLoop()
{
self endon("death");
self endon("disconnect");
LOCK_LENGTH = 1150;
GATHER_DELAY = 25;
ADS_DELAY = 100;
MAX_POINT_PEER_DIST = 400;
POINTS_NEEDED_TO_START_LOCK = 12;
lastGatherTime = 0;
lastOutOfADS = 0;
self.javelinTarget = undefined;
InitJavelinUsage();
for( ;; )
{
wait 0.05;
debugDraw = false;
if ( GetDVar( "missileDebugDraw" ) == "1" )
debugDraw = true;
debugText = false;
if ( GetDVar( "missileDebugText" ) == "1" )
debugText = true;
weapon = self getCurrentWeapon();
if ( !isSubStr( weapon, "javelin" ) || self isEMPed() )
{
ResetJavelinLocking();
continue;
}
if ( self PlayerADS() < 0.95 )
{
lastOutOfADS = GetTime();
ResetJavelinLocking();
continue;
}
self.javelinUseEntered = true;
if ( !IsDefined( self.javelinStage ) )
self.javelinStage = 1;
if ( self.javelinStage == 1 ) // SCANNING: try to find a good point to lock to
{
targets = GetTargetList();
if ( targets.size != 0 )
{
targetsInReticle = [];
foreach ( target in targets )
{
insideReticle = self WorldPointInReticle_Circle( target.origin, 65, 40 );
if ( insideReticle )
targetsInReticle[targetsInReticle.size] = target;
}
if ( targetsInReticle.size != 0 )
{
sortedTargets = SortByDistance( targetsInReticle, self.origin );
if ( !( self VehicleLockSightTest( sortedTargets[0] ) ) )
continue;
if ( debugText )
PrintLn( "Javeling found a vehicle target to lock to." );
self.javelinTarget = sortedTargets[0];
if ( !isDefined( self.javelinLockStartTime ) )
self.javelinLockStartTime = GetTime();
self.javelinStage = 2;
self.javelinLostSightlineTime = 0;
self javelinLockVehicle( LOCK_LENGTH );
self.javelinStage = 1;
continue;
}
}
if ( LockMissesPassedThreshold() )
{
ResetJavelinLocking();
continue;
}
timePassed = GetTime() - lastOutOfADS;
if ( timePassed < ADS_DELAY )
continue;
/#
if ( debugDraw && IsDefined( self.javelinPoints ) )
{
foreach( javPoint in self.javelinPoints )
DrawStar( javPoint, (0.8, 1.0, 0.8) );
DrawStar( self.javelinPoints[self.javelinPoints.size - 1], (1, 1, 0.2) );
DrawStar( AveragePoint( self.javelinPoints ), (0.2, 0.2, 1) );
}
#/
timePassed = GetTime() - lastGatherTime;
if ( timePassed < GATHER_DELAY )
continue;
lastGatherTime = GetTime();
traceRes = (self EyeTraceForward());
if ( !IsDefined( traceRes ) )
{
self LockMissesIncr();
continue;
}
if ( self TargetPointTooClose( traceRes[0] ) )
{
self WeaponLockTargetTooClose( true );
continue;
}
else
{
self WeaponLockTargetTooClose( false );
}
// make sure we haven't strayed too far
if ( IsDefined( self.javelinPoints ) )
{
prevAvgPoint = AveragePoint( self.javelinPoints );
dist = Distance( prevAvgPoint, traceRes[0] );
//PrintLn( "[", self.javelinPoints.size, "] - Dist: ", dist );
if ( dist > MAX_POINT_PEER_DIST )
{
LockMissesIncr();
continue;
}
}
else
{
self.javelinPoints = [];
self.javelinNormals = [];
}
self.javelinPoints[self.javelinPoints.size] = traceRes[0];
self.javelinNormals[self.javelinNormals.size] = traceRes[1];
self LockMissesReset();
if ( self.javelinPoints.size < POINTS_NEEDED_TO_START_LOCK )
continue;
// Go to stage 2:
self.javelinTargetPoint = AveragePoint( self.javelinPoints );;
self.javelinTargetNormal = AverageNormal( self.javelinNormals );;
self.javelinLockMisses = undefined;
self.javelinPoints = undefined;
self.javelinNormals = undefined;
self.javelinLockStartTime = GetTime();
self WeaponLockStart( self.javelinTargetPoint );
self thread LoopLocalSeekSound( "javelin_clu_aquiring_lock", 0.6 );
self.javelinStage = 2;
}
if ( self.javelinStage == 2 ) // LOCKING: complete lockon to point
{
/#
if ( debugDraw )
DrawStar( self.javelinTargetPoint, (0.5, 1.0, 0.6) );
#/
insideReticle = self WorldPointInReticle_Circle( self.javelinTargetPoint, 65, 45 );
if ( !insideReticle )
{
ResetJavelinLocking();
continue;
}
if ( self TargetPointTooClose( self.javelinTargetPoint ) )
self WeaponLockTargetTooClose( true );
else
self WeaponLockTargetTooClose( false );
timePassed = getTime() - self.javelinLockStartTime;
//PrintLn( "Locking [", timePassed, "]..." );
if ( timePassed < LOCK_LENGTH )
continue;
self WeaponLockFinalize( self.javelinTargetPoint, (0,0,0), true );
self notify( "stop_lockon_sound" );
self PlayLocalSound( "javelin_clu_lock" );
self.javelinStage = 3;
}
if ( self.javelinStage == 3 ) // LOCKED: try and hold it
{
/#
if ( debugDraw )
DrawStar( self.javelinTargetPoint, (0.1, 0.15, 1.0) );
#/
insideReticle = self WorldPointInReticle_Circle( self.javelinTargetPoint, 65, 45 );
if ( !insideReticle )
{
ResetJavelinLocking();
continue;
}
if ( self TargetPointTooClose( self.javelinTargetPoint ) )
self WeaponLockTargetTooClose( true );
else
self WeaponLockTargetTooClose( false );
continue;
}
}
}
GetTargetList()
{
targets = [];
if ( level._teamBased )
{
if ( IsDefined( level._chopper ) && ( level._chopper.team != self.team || level._chopper.owner == self ) ) ///check for teams
targets[targets.size] = level._chopper;
if ( IsDefined( level._raven ) && ( level._raven.team != self.team || level._raven.owner == self ) ) ///check for teams
targets[targets.size] = level._raven;
if ( isDefined( level._harriers) )
{
foreach( harrier in level._harriers )
{
if ( isDefined( harrier ) && ( harrier.team != self.team || ( isDefined( harrier.owner ) && harrier.owner == self ) ) )
targets[targets.size] = harrier;
}
}
foreach( target_player in level._players )
{
if (( target_player.team != self.team ) && (target_player _hasPerk("specialty_juggersuit")))
{
targets[targets.size] = target_player;
}
}
if( level._multiTeamBased )
{
//for all teams
for( i = 0; i < level._teamNameList.size; i++ )
{
//that are not our team
if( self.team != level._teamNameList[i] )
{
//does that team have any uav's
if( level._UAVModels[level._teamNameList[i]].size )
{
//add each uav to the target list
foreach ( UAV in level._UAVModels[level._teamNameList[i]] )
{
targets[targets.size] = UAV;
}
}
}
}
}
else if ( level._UAVModels[level._otherTeam[self.team]].size )
{
foreach ( UAV in level._UAVModels[level._otherTeam[self.team]] )
targets[targets.size] = UAV;
}
if ( isDefined(level._ac130player) && ( level._ac130player.team != self.team ) )
targets[targets.size] = level._ac130.planeModel;
}
else
{
if ( IsDefined( level._chopper ) && ( level._chopper.owner != self ) ) ///check for teams
targets[targets.size] = level._chopper;
if ( isDefined(level._ac130player) )
targets[targets.size] = level._ac130;
if ( isDefined( level._harriers) )
{
foreach( harrier in level._harriers )
{
if ( isDefined( harrier ) )
targets[targets.size] = harrier;
}
}
foreach( target_player in level._players )
{
if (( target_player != self ) && (target_player _hasPerk("specialty_juggersuit")))
{
targets[targets.size] = target_player;
}
}
if ( level._UAVModels.size )
{
foreach ( ownerGuid, UAV in level._UAVModels )
{
if ( isDefined( UAV.owner ) && UAV.owner == self )
continue;
targets[targets.size] = UAV;
}
}
}
return targets;
}
DebugSightLine( start, end, passed )
{
/#
if ( GetDVar( "missileDebugDraw" ) != "1" )
return;
if ( passed )
color = ( 0.3, 1.0, 0.3 );
else
color = ( 1.0, 0.2, 0.2 );
MY_OFFSET = ( 0, 0, 5 );
Line( start + MY_OFFSET, end, color );
#/
}
VehicleLockSightTest( target )
{
eyePos = self GetEye();
center = target GetPointInBounds( 0, 0, 0 );
passed = BulletTracePassed( eyePos, center, false, target );
DebugSightLine( eyePos, center, passed );
if ( passed )
return true;
front = target GetPointInBounds( 1, 0, 0 );
passed = BulletTracePassed( eyePos, front, false, target );
DebugSightLine( eyePos, front, passed );
if ( passed )
return true;
back = target GetPointInBounds( -1, 0, 0 );
passed = BulletTracePassed( eyePos, back, false, target );
DebugSightLine( eyePos, back, passed );
if ( passed )
return true;
return false;
}
javelinLockVehicle( lockLength )
{
if ( self.javelinStage == 2 ) // locking on to a target
{
self WeaponLockStart( self.javelinTarget );
if ( !(self StillValidJavelinLock( self.javelinTarget ) ) )
{
ResetJavelinLocking();
self.javelinLockStartTime = undefined;
return;
}
passed = SoftSightTest();
if ( !passed )
{
self.javelinLockStartTime = undefined;
return;
}
if ( !isDefined( self.currentlyLocking ) || !self.currentlyLocking )
{
self thread LoopLocalSeekSound( "javelin_clu_aquiring_lock", 0.6 );
self.currentlyLocking = true;
}
timePassed = getTime() - self.javelinLockStartTime;
if ( timePassed < lockLength )
return;
//strangely buggy with the moving target...
//javTarg = eyeTraceForward();
//if ( !isDefined( javTarg ) )
// return;
//topAttack = TopAttackPasses( javTarg[0], javTarg[1] );
if( isPlayer( self.javelinTarget ))
{
self WeaponLockFinalize( self.javelinTarget, (0,0,32), false );
}
else
{
self WeaponLockFinalize( self.javelinTarget, (0,0,0), false );
}
self notify( "stop_lockon_sound" );
if ( !isDefined( self.currentlyLocked ) || !self.currentlyLocked )
{
self PlayLocalSound( "javelin_clu_lock" );
self.currentlyLocked = true;
}
self.javelinStage = 3;
}
if ( self.javelinStage == 3 ) // target locked
{
passed = SoftSightTest();
if ( !passed )
return;
if ( !(self StillValidJavelinLock( self.javelinTarget ) ) )
{
ResetJavelinLocking();
return;
}
}
}
StillValidJavelinLock( ent )
{
assert( IsDefined( self ) );
if ( !IsDefined( ent ) )
return false;
if ( !(self WorldPointInReticle_Circle( ent.origin, 65, 85 )) )
return false;
return true;
}
SoftSightTest()
{
LOST_SIGHT_LIMIT = 500;
if ( self VehicleLockSightTest( self.javelinTarget ) )
{
self.javelinLostSightlineTime = 0;
return true;
}
if ( self.javelinLostSightlineTime == 0 )
self.javelinLostSightlineTime = getTime();
timePassed = GetTime() - self.javelinLostSightlineTime;
if ( timePassed >= LOST_SIGHT_LIMIT )
{
ResetJavelinLocking();
return false;
}
return true;
}

318
maps/mp/_killingdoor.gsc Normal file
View File

@ -0,0 +1,318 @@
//****************************************************************************
// **
// Confidential - (C) Activision Publishing, Inc. 2010 **
// **
//****************************************************************************
// **
// Module: Phase 3 Check-In: Script controlling multiple sets of two **
// moving doors that will kill players who are stuck in between **
// This script works for the following setups for each door set **
// in Radiant: **
// 2 door models: **
// script_model: "targetname" "killing_door_1" **
// script_model: "targetname" "killing_door_2" **
// 2 clips: **
// script_brushmodel: "targetname" "killing_clip_1" **
// script_brushmodel: "targetname" "killing_clip_2" **
// 3 triggers: **
// trigger_multiple: "targetname" "killing_trigger_1" **
// trigger_multiple: "targetname" "killing_trigger_2" **
// trigger_multiple: "targetname" "killing_trigger_center"**
// **
// Created: May 17th, 2011 - James Chen **
// **
//***************************************************************************/
//tagJC<NOTE>: For demonstration, please run mp_nx_killtest.
//tagJC<TODO>: Custom key values are added into the Radiant key table. Their impact on Radiant will need to be assessed over time
//tagJC<TODO>: Like in phase1, the doors will not kill if multiple players are stuck in between the doors.
// A potential solution will be to introduce a delay time before the trigger in the center start to conduct the killings.
// However, the delay-time solution needs to be assessed in terms of its impact on gameplay (delay etc.).
//tagJC<NOTE>: Because of the double doors setup, it is not practical nor realistic to move the doors vertically along the 'z' direction
main()
{
//tagJC<NOTE>: Getting all the entities into corresponding arrays and do basic error checking
level._killingDoor1 = getentArray_and_assert( "killing_door_1" );
level._killingDoor2 = getentArray_and_assert( "killing_door_2" );
level._killingClip1 = getentArray_and_assert( "killing_clip_1" );
level._killingClip2 = getentArray_and_assert( "killing_clip_2" );
level._killingTrigger1 = getentArray_and_assert( "killing_trigger_1" );
level._killingTrigger2 = getentArray_and_assert( "killing_trigger_2" );
level._killingTriggerCenter = getentArray_and_assert( "killing_trigger_center" );
//tagJC<NOTE>: Checking for the correct numbers of models, clips and triggers in order to make sure that the script will function
// correctly.
checking_setup();
//tagJC<NOTE>: Linking the door models and triggers to the clips
linking( level._killingClip1 , level._killingDoor1 );
linking( level._killingClip1 , level._killingTrigger1 );
linking( level._killingClip2 , level._killingDoor2 );
linking( level._killingClip2 , level._killingTrigger2 );
//tagJC<NOTE>: Based on proximity, pair up clip1, clip2, and all the three corresponding triggers into sets
pairing( level._killingClip1, level._killingClip2, level._killingTriggerCenter, level._killingTrigger1, level._killingTrigger2 );
//tagJC<NOTE>: Make the doors move
move_doors();
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Linking entities in object_list_2 to that in object_list_1 based on proximity
linking( object_list_1 , object_list_2 )
{
for ( i = 0; i < object_list_1.size; i++ )
{
//tagJC<NOTE>: Use an arbitrary distance as the base for comparision
paired_object2 = find_closest( object_list_1[i], object_list_2 );
//tagJC<NOTE>: Link the paired objects to that in object_list_1
paired_object2 LinkTo( object_list_1[i] );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: This function pairs up the clips with each other as well as the corresponding triggers
pairing( clip1_list , clip2_list, cTrigger_list, Trigger1_list, Trigger2_list )
{
for ( i = 0; i < clip1_list.size; i++ )
{
//tagJC<NOTE>: Determine the clip2 that is the closest to the current clip1 under examination
paired_clip2 = find_closest( clip1_list[i], clip2_list );
//tagJC<NOTE>: Determine the center trigger that is the closest to the current clip1 under examination
paired_cTrigger = find_closest( clip1_list[i], cTrigger_list );
//tagJC<NOTE>: Determine the trigger1 that is the closest to the current clip1 under examination
paired_Trigger1 = find_closest( clip1_list[i], Trigger1_list );
//tagJC<NOTE>: Determine the trigger2 that is the closest to the current clip1 under examination
paired_Trigger2 = find_closest( clip1_list[i], Trigger2_list );
//tagJC<NOTE>: Putting the set into a level array
level._killingSet[i][ "clip1" ] = clip1_list[i];
level._killingSet[i][ "clip2" ] = paired_clip2;
level._killingSet[i][ "cTrigger" ] = paired_cTrigger;
level._killingSet[i][ "Trigger1" ] = paired_Trigger1;
level._killingSet[i][ "Trigger2" ] = paired_Trigger2;
//tagJC<NOTE>: Useful debugging message
//IPrintLnBold( "clip1 at " + level._killingSet[i][ "clip1" ].origin + " is paired with clip2 at " + level._killingSet[i][ "clip2" ].origin + " and Center Trigger at " + level._killingSet[i][ "cTrigger" ].origin + " and Trigger1 at " + level._killingSet[i][ "Trigger1" ].origin + " and Trigger2 at " + level._killingSet[i][ "Trigger2" ].origin);
}
}
//*******************************************************************
// *
// *
//*******************************************************************
find_closest( entity, entity_list )
{
//tagJC<NOTE>: Use an arbitrary distance as the base for comparision
closest_distance = distance( entity.origin , entity_list[0].origin );
closest_entity = entity_list[0];
for ( i = 1; i < entity_list.size; i++ )
{
//tagJC<NOTE>: If another entity on the list results in a shorter distance, update the results accordingly
if ( distance( entity.origin , entity_list[i].origin ) < closest_distance )
{
closest_distance = distance( entity.origin , entity_list[i].origin );
closest_entity = entity_list[i];
}
}
return closest_entity;
}
//*******************************************************************
// *
// *
//*******************************************************************
move_doors()
{
for ( i = 0; i < level._killingSet.size ; i++ )
{
//tagJC<NOTE>: Starting moving the clips
level thread moving_doors( level._killingSet[i][ "clip1" ], level._killingSet[i][ "clip2" ] );
//tagJC<NOTE>: Starting to spawn the triggers and detect players' contact
level._killingSet[i][ "cTrigger" ] thread kill_stuck_players( level._killingSet[i][ "Trigger1" ], level._killingSet[i][ "Trigger2" ]);
}
}
//*******************************************************************
// *
// *
//*******************************************************************
moving_doors( clip1, clip2 )
{
//tagJC<NOTE>: Determine the distance and the vector of which the doors will move
dis = distance( clip1.origin, clip2.origin );
moving_vector = clip1.origin - clip2.origin;
//tagJC<NOTE>: Start to move the two clips in opposite directions
if ( isDefined ( level.KillingDoorControllingLogic ))
{
if ( ! isDefined ( level.escortPlusKillingDoorClosed ) )
{
level.escortPlusKillingDoorClosed = 0;
}
clip1 thread [[level.KillingDoorControllingLogic]]( moving_vector * -1/3, ( dis/clip1.speed ), clip1.door_time_remain_open, clip1.door_time_remain_close );
clip2 thread [[level.KillingDoorControllingLogic]]( moving_vector * 1/3, ( dis/clip1.speed ), clip1.door_time_remain_open, clip1.door_time_remain_close );
}
else
{
clip1 thread move_one_door( moving_vector, ( dis/clip1.speed ), clip1.door_time_remain_open, clip1.door_time_remain_close );
clip2 thread move_one_door( moving_vector * -1, ( dis/clip1.speed ), clip1.door_time_remain_open, clip1.door_time_remain_close );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Moving one door back and forth according to the values sspecified by the designer
move_one_door( moving_vector, moving_time, door_time_remain_open, door_time_remain_close )
{
while ( 1 )
{
self moveTo( self.origin + moving_vector, moving_time, moving_time * 0.5, moving_time * 0.5 );
self waittill( "movedone" );
wait door_time_remain_open;
self moveTo( self.origin - moving_vector, moving_time, moving_time * 0.5, moving_time * 0.5 );
self waittill( "movedone" );
wait door_time_remain_close;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
kill_stuck_players( Trigger1, Trigger2 )
{
while ( 1 )
{
//tagJC<NOTE>: Detecting whether death_trig has been touched
self waittill( "trigger", player);
//tagJC<NOTE>: Depending on how death_trig is setup in Radiant, this might be a useful debug message
//IPrintLnBold( "death_trig has been touched!" );
//tagJC<NOTE>: Depending on the setup in Radiant, the following two are useful debugging functions
//Trigger1 thread testing1();
//Trigger2 thread testing2();
//tagJC<NOTE>: If a player is inside death_trig and is touching both death_trig1 and death_trig2 at the same time,
// kill the player
if (( player IsTouching( Trigger1 )) && ( player IsTouching( Trigger2 )))
{
player thread [[level._callbackPlayerDamage]](
player, // eInflictor The entity that causes the damage.(e.g. a turret)
player, // eAttacker The entity that is attacking.
500, // iDamage Integer specifying the amount of damage done
0, // iDFlags Integer specifying flags that are to be applied to the damage
"MOD_SUICIDE", // sMeansOfDeath Integer specifying the method of death MOD_RIFLE_BULLET
player.primaryweapon, // sWeapon The weapon number of the weapon used to inflict the damage
player.origin, // vPoint The point the damage is from?
(0, 0, 0), // vDir The direction of the damage
"none", // sHitLoc The location of the hit
0 // psOffsetTime The time offset for the damage
);
}
else
{
wait .05;
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Check for matching numbers of entities for door models, clips and triggers
checking_setup ()
{
set_count = level._killingDoor1.size;
if ( level._killingDoor2.size != set_count )
{
AssertEX( false , "The number of door 2 needs to equal to the number of door 1" );
}
if ( level._killingClip1.size != set_count )
{
AssertEX( false , "The number of clip 1 needs to equal to the number of door 1" );
}
if ( level._killingClip2.size != set_count )
{
AssertEX( false , "The number of clip 2 needs to equal to the number of door 1" );
}
if ( level._killingTrigger1.size != set_count )
{
AssertEX( false , "The number of trigger 1 needs to equal to the number of door 1" );
}
if ( level._killingTrigger2.size != set_count )
{
AssertEX( false , "The number of trigger 2 needs to equal to the number of door 1" );
}
if ( level._killingTriggerCenter.size != set_count )
{
AssertEX( false , "The number of center trigger needs to equal to the number of door 1" );
}
for ( i = 0; i < level._killingClip1.size; i++ )
{
AssertEX( isDefined( level._killingClip1[i].speed ), "Clip1 located at " + level._killingClip1[i].origin + " does not have the speed specified." );
}
for ( i = 0; i < level._killingClip1.size; i++ )
{
AssertEX( isDefined( level._killingClip1[i].door_time_remain_open ), "Clip1 located at " + level._killingClip1[i].origin + " does not have the door_time_remain_open specified." );
}
for ( i = 0; i < level._killingClip1.size; i++ )
{
AssertEX( isDefined( level._killingClip1[i].door_time_remain_close ), "Clip1 located at " + level._killingClip1[i].origin + " does not have the door_time_remain_close specified." );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Useful helper function to get the requested entity and check for any errors
getentArray_and_assert( ent_name )
{
object = getEntArray( ent_name, "targetname" );
AssertEX( object.size > 0 , "There is no entity for " + ent_name );
return object;
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Useful debugging function to test killing_trigger_1
testing1()
{
while ( 1 )
{
self waittill( "trigger", player);
IPrintLnBold( "killing_trigger_1 has been touched!" );
wait 0.05;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Useful debugging function to test killing_trigger_2
testing2()
{
while ( 1 )
{
self waittill( "trigger", player);
IPrintLnBold( "killing_trigger_2 has been touched!" );
wait 0.05;
}
}

351
maps/mp/_load.gsc Normal file
View File

@ -0,0 +1,351 @@
#include common_scripts\utility;
#include common_scripts\_fx;
#include maps\mp\_utility;
main()
{
if ( isDefined( level._loadStarted ) )
{
//println( "level loading has already started returning out!!!!" );
return;
}
level._loadStarted = true;
level._createFX_enabled = ( getdvar( "createfx" ) == "on" );
struct_class_init();
initGameFlags();
initLevelFlags();
level._generic_index = 0;
// flag_struct is used as a placeholder when a flag is set without an entity
level._flag_struct = spawnstruct();
level._flag_struct assign_unique_id();
if ( !isdefined( level._flag ) )
{
level._flag = [];
level._flags_lock = [];
}
level._requiredMapAspectRatio = getDvarFloat( "scr_RequiredMapAspectratio", 1 );
level._createClientFontString_func = maps\mp\gametypes\_hud_util::createFontString;
level._HUDsetPoint_func = maps\mp\gametypes\_hud_util::setPoint;
level._leaderDialogOnPlayer_func = maps\mp\_utility::leaderDialogOnPlayer;
thread maps\mp\gametypes\_tweakables::init();
if ( !isdefined( level._func ) )
level._func = [];
level._func[ "precacheMpAnim" ] = ::precacheMpAnim;
level._func[ "scriptModelPlayAnim" ] = ::scriptModelPlayAnim;
level._func[ "scriptModelClearAnim" ] = ::scriptModelClearAnim;
// dodge this stuff for createfx tool.
if( !level._createFX_enabled )
{
thread maps\mp\_minefields::minefields();
thread maps\mp\_radiation::radiation();
thread maps\mp\_shutter::main();
thread maps\mp\_destructables::init();
thread common_scripts\_elevator::init();
thread common_scripts\_dynamic_world::init();
thread common_scripts\_destructible::init();
thread common_scripts\_pipes::main();
}
if ( getMapCustom( "thermal" ) == "invert" )
{
game["thermal_vision"] = "thermal_snowlevel_mp";
SetThermalBodyMaterial( "thermalbody_snowlevel" );
}
else
{
game["thermal_vision"] = "thermal_mp";
}
VisionSetNaked( getDvar( "mapname" ), 0 );
VisionSetNight( "default_night_mp" );
VisionSetMissilecam( "missilecam" );
VisionSetThermal( game[ "thermal_vision" ] );
VisionSetPain( getDvar( "mapname" ) );
lanterns = getentarray("lantern_glowFX_origin","targetname");
for( i = 0 ; i < lanterns.size ; i++ )
lanterns[i] thread lanterns();
maps\mp\_art::main();
thread common_scripts\_painter::main("painter_mp");
setupExploders();
thread common_scripts\_fx::initFX();
if ( level._createFX_enabled )
{
maps\mp\_createfx::createfx();
}
if ( getdvar( "r_reflectionProbeGenerate" ) == "1" )
{
maps\mp\gametypes\_spawnlogic::setMapCenterForReflections();
maps\mp\_global_fx::main();
level waittill( "eternity" );
}
thread maps\mp\_global_fx::main();
// Do various things on triggers
for ( p = 0;p < 6;p ++ )
{
switch( p )
{
case 0:
triggertype = "trigger_multiple";
break;
case 1:
triggertype = "trigger_once";
break;
case 2:
triggertype = "trigger_use";
break;
case 3:
triggertype = "trigger_radius";
break;
case 4:
triggertype = "trigger_lookat";
break;
default:
assert( p == 5 );
triggertype = "trigger_damage";
break;
}
triggers = getentarray( triggertype, "classname" );
for ( i = 0;i < triggers.size;i ++ )
{
if( isdefined( triggers[ i ].script_prefab_exploder) )
triggers[i].script_exploder = triggers[ i ].script_prefab_exploder;
if( isdefined( triggers[ i ].script_exploder) )
level thread maps\mp\_load::exploder_load( triggers[ i ] );
}
}
hurtTriggers = getentarray( "trigger_hurt", "classname" );
foreach ( hurtTrigger in hurtTriggers )
{
hurtTrigger thread hurtPlayersThink();
}
thread maps\mp\_animatedmodels::main();
// auto-sentry
level._func[ "damagefeedback" ] = maps\mp\gametypes\_damagefeedback::updateDamageFeedback;
level._func[ "setTeamHeadIcon" ] = maps\mp\_entityheadicons::setTeamHeadIcon;
level._laserOn_func = ::laserOn;
level._laserOff_func = ::laserOff;
// defaults
setDvar( "sm_sunShadowScale", 1 );
setDvar( "r_specularcolorscale", 2.5 );
setDvar( "r_diffusecolorscale", 1 );
setDvar( "r_lightGridEnableTweaks", 0 );
setDvar( "r_lightGridIntensity", 1 );
setDvar( "r_lightGridContrast", 0 );
level._use_moon_gravity = false;
//println( "!!!!!Loading Level Resetting Gravity to Earth !!!!!!!!!!!!" );
setdvar( "phys_global_gravity_scale", 1.0 );
setdvar( "aim_scale_turn_rate", 1.0 );
/#
show_level_notes( true );
#/
}
exploder_load( trigger )
{
level endon( "killexplodertridgers" + trigger.script_exploder );
trigger waittill( "trigger" );
if ( isdefined( trigger.script_chance ) && randomfloat( 1 ) > trigger.script_chance )
{
if ( isdefined( trigger.script_delay ) )
wait trigger.script_delay;
else
wait 4;
level thread exploder_load( trigger );
return;
}
exploder( trigger.script_exploder );
level notify( "killexplodertridgers" + trigger.script_exploder );
}
setupExploders()
{
// Hide exploder models.
ents = getentarray( "script_brushmodel", "classname" );
smodels = getentarray( "script_model", "classname" );
for ( i = 0;i < smodels.size;i ++ )
ents[ ents.size ] = smodels[ i ];
for ( i = 0;i < ents.size;i ++ )
{
if ( isdefined( ents[ i ].script_prefab_exploder ) )
ents[ i ].script_exploder = ents[ i ].script_prefab_exploder;
if ( isdefined( ents[ i ].script_exploder ) )
{
if ( ( ents[ i ].model == "fx" ) && ( ( !isdefined( ents[ i ].targetname ) ) || ( ents[ i ].targetname != "exploderchunk" ) ) )
ents[ i ] hide();
else if ( ( isdefined( ents[ i ].targetname ) ) && ( ents[ i ].targetname == "exploder" ) )
{
ents[ i ] hide();
ents[ i ] notsolid();
//if ( isdefined( ents[ i ].script_disconnectpaths ) )
//ents[ i ] connectpaths();
}
else if ( ( isdefined( ents[ i ].targetname ) ) && ( ents[ i ].targetname == "exploderchunk" ) )
{
ents[ i ] hide();
ents[ i ] notsolid();
//if ( isdefined( ents[ i ].spawnflags ) && ( ents[ i ].spawnflags & 1 ) )
//ents[ i ] connectpaths();
}
}
}
script_exploders = [];
potentialExploders = getentarray( "script_brushmodel", "classname" );
for ( i = 0;i < potentialExploders.size;i ++ )
{
if ( isdefined( potentialExploders[ i ].script_prefab_exploder ) )
potentialExploders[ i ].script_exploder = potentialExploders[ i ].script_prefab_exploder;
if ( isdefined( potentialExploders[ i ].script_exploder ) )
script_exploders[ script_exploders.size ] = potentialExploders[ i ];
}
potentialExploders = getentarray( "script_model", "classname" );
for ( i = 0;i < potentialExploders.size;i ++ )
{
if ( isdefined( potentialExploders[ i ].script_prefab_exploder ) )
potentialExploders[ i ].script_exploder = potentialExploders[ i ].script_prefab_exploder;
if ( isdefined( potentialExploders[ i ].script_exploder ) )
script_exploders[ script_exploders.size ] = potentialExploders[ i ];
}
potentialExploders = getentarray( "item_health", "classname" );
for ( i = 0;i < potentialExploders.size;i ++ )
{
if ( isdefined( potentialExploders[ i ].script_prefab_exploder ) )
potentialExploders[ i ].script_exploder = potentialExploders[ i ].script_prefab_exploder;
if ( isdefined( potentialExploders[ i ].script_exploder ) )
script_exploders[ script_exploders.size ] = potentialExploders[ i ];
}
if ( !isdefined( level._createFXent ) )
level._createFXent = [];
acceptableTargetnames = [];
acceptableTargetnames[ "exploderchunk visible" ] = true;
acceptableTargetnames[ "exploderchunk" ] = true;
acceptableTargetnames[ "exploder" ] = true;
for ( i = 0; i < script_exploders.size; i ++ )
{
exploder = script_exploders[ i ];
ent = createExploder( exploder.script_fxid );
ent.v = [];
ent.v[ "origin" ] = exploder.origin;
ent.v[ "angles" ] = exploder.angles;
ent.v[ "delay" ] = exploder.script_delay;
ent.v[ "firefx" ] = exploder.script_firefx;
ent.v[ "firefxdelay" ] = exploder.script_firefxdelay;
ent.v[ "firefxsound" ] = exploder.script_firefxsound;
ent.v[ "firefxtimeout" ] = exploder.script_firefxtimeout;
ent.v[ "earthquake" ] = exploder.script_earthquake;
ent.v[ "damage" ] = exploder.script_damage;
ent.v[ "damage_radius" ] = exploder.script_radius;
ent.v[ "soundalias" ] = exploder.script_soundalias;
ent.v[ "repeat" ] = exploder.script_repeat;
ent.v[ "delay_min" ] = exploder.script_delay_min;
ent.v[ "delay_max" ] = exploder.script_delay_max;
ent.v[ "target" ] = exploder.target;
ent.v[ "ender" ] = exploder.script_ender;
ent.v[ "type" ] = "exploder";
// ent.v[ "worldfx" ] = true;
if ( !isdefined( exploder.script_fxid ) )
ent.v[ "fxid" ] = "No FX";
else
ent.v[ "fxid" ] = exploder.script_fxid;
ent.v[ "exploder" ] = exploder.script_exploder;
assertEx( isdefined( exploder.script_exploder ), "Exploder at origin " + exploder.origin + " has no script_exploder" );
if ( !isdefined( ent.v[ "delay" ] ) )
ent.v[ "delay" ] = 0;
if ( isdefined( exploder.target ) )
{
org = getent( ent.v[ "target" ], "targetname" ).origin;
ent.v[ "angles" ] = vectortoangles( org - ent.v[ "origin" ] );
// forward = anglestoforward( angles );
// up = anglestoup( angles );
}
// this basically determines if its a brush / model exploder or not
if ( exploder.classname == "script_brushmodel" || isdefined( exploder.model ) )
{
ent.model = exploder;
ent.model.disconnect_paths = exploder.script_disconnectpaths;
}
if ( isdefined( exploder.targetname ) && isdefined( acceptableTargetnames[ exploder.targetname ] ) )
ent.v[ "exploder_type" ] = exploder.targetname;
else
ent.v[ "exploder_type" ] = "normal";
ent common_scripts\_createfx::post_entity_creation_function();
}
}
lanterns()
{
if (!isdefined(level._effect["lantern_light"]))
level._effect["lantern_light"] = loadfx("props/glow_latern");
loopfx("lantern_light", self.origin, 0.3, self.origin + (0,0,1));
}
hurtPlayersThink()
{
level endon ( "game_ended" );
wait ( randomFloat( 1.0 ) );
for ( ;; )
{
foreach ( player in level._players )
{
if ( player isTouching( self ) && isReallyAlive( player ) )
player _suicide();
}
wait ( 0.5 );
}
}

374
maps/mp/_matchdata.gsc Normal file
View File

@ -0,0 +1,374 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
if ( !isDefined( game["gamestarted"] ) )
{
//setMatchDataDef( "mp/matchdata_" + level.gametype + ".def" );
setMatchDataDef( "mp/matchdata.def" );
setMatchData( "map", level._script );
setMatchData( "gametype", level._gametype );
setMatchData( "buildVersion", getBuildVersion() );
setMatchData( "buildNumber", getBuildNumber() );
setMatchData( "dateTime", getSystemTime() );
}
level._MaxLives = 250; // must match MaxKills in matchdata definition
level._MaxNameLength = 21; // must match Player xuid size in clientmatchdata definition
level._MaxEvents = 150;
level._MaxKillstreaks = 125;
level._MaxLogClients = 128;
level thread gameEndListener();
}
logKillstreakEvent( event, position )
{
assertEx( isPlayer( self ), "self is not a player: " + self.code_classname );
if ( !matchMakingGame() || !canLogClient( self ) || !canLogKillstreak() )
return;
eventId = getMatchData( "killstreakCount" );
setMatchData( "killstreakCount", eventId+1 );
setMatchData( "killstreaks", eventId, "eventType", event );
setMatchData( "killstreaks", eventId, "player", self.clientid );
setMatchData( "killstreaks", eventId, "eventTime", getTime() );
setMatchData( "killstreaks", eventId, "eventPos", 0, int( position[0] ) );
setMatchData( "killstreaks", eventId, "eventPos", 1, int( position[1] ) );
setMatchData( "killstreaks", eventId, "eventPos", 2, int( position[2] ) );
}
logGameEvent( event, position )
{
assertEx( isPlayer( self ), "self is not a player: " + self.code_classname );
if ( !matchMakingGame() || !canLogClient( self ) || !canLogEvent() )
return;
eventId = getMatchData( "eventCount" );
setMatchData( "eventCount", eventId+1 );
setMatchData( "events", eventId, "eventType", event );
setMatchData( "events", eventId, "player", self.clientid );
setMatchData( "events", eventId, "eventTime", getTime() );
setMatchData( "events", eventId, "eventPos", 0, int( position[0] ) );
setMatchData( "events", eventId, "eventPos", 1, int( position[1] ) );
setMatchData( "events", eventId, "eventPos", 2, int( position[2] ) );
}
logKillEvent( lifeId, eventRef )
{
if ( !matchMakingGame() || !canLogLife( lifeId ) )
return;
setMatchData( "lives", lifeId, "modifiers", eventRef, true );
}
logMultiKill( lifeId, multikillCount )
{
if ( !matchMakingGame() || !canLogLife( lifeId ) )
return;
setMatchData( "lives", lifeId, "multikill", multikillCount );
}
logPlayerLife( lifeId )
{
if ( !matchMakingGame() || !canLogClient( self ) || !canLogLife( lifeId ) )
return;
setMatchData( "lives", lifeId, "player", self.clientid );
setMatchData( "lives", lifeId, "spawnPos", 0, int( self.spawnPos[0] ) );
setMatchData( "lives", lifeId, "spawnPos", 1, int( self.spawnPos[1] ) );
setMatchData( "lives", lifeId, "spawnPos", 2, int( self.spawnPos[2] ) );
setMatchData( "lives", lifeId, "wasTacticalInsertion", self.wasTI );
setMatchData( "lives", lifeId, "team", self.team );
setMatchData( "lives", lifeId, "spawnTime", self.spawnTime );
setMatchData( "lives", lifeId, "duration", getTime() - self.spawnTime );
self logLoadout( lifeId );
}
logLoadout( lifeId )
{
if ( !matchMakingGame() || !canLogClient( self ) || !canLogLife( lifeId ) )
return;
class = self.curClass;
if ( class == "copycat" )
{
clonedLoadout = self.pers["copyCatLoadout"];
loadoutPrimary = clonedLoadout["loadoutPrimary"];
loadoutPrimaryAttachment = clonedLoadout["loadoutPrimaryAttachment"];
loadoutPrimaryAttachment2 = clonedLoadout["loadoutPrimaryAttachment2"] ;
loadoutPrimaryCamo = clonedLoadout["loadoutPrimaryCamo"];
loadoutSecondary = clonedLoadout["loadoutSecondary"];
loadoutSecondaryAttachment = clonedLoadout["loadoutSecondaryAttachment"];
loadoutSecondaryAttachment2 = clonedLoadout["loadoutSecondaryAttachment2"];
loadoutSecondaryCamo = clonedLoadout["loadoutSecondaryCamo"];
loadoutLethal = clonedLoadout["loadoutLethal"];
loadoutEquipment = clonedLoadout["loadoutEquipment"];
loadoutPerk1 = clonedLoadout["loadoutPerk1"];
loadoutPerk2 = clonedLoadout["loadoutPerk2"];
loadoutPerk3 = clonedLoadout["loadoutPerk3"];
loadoutOffhand = clonedLoadout["loadoutOffhand"];
loadoutDeathStreak = "specialty_copycat";
}
else if( isSubstr( class, "custom" ) )
{
class_num = maps\mp\gametypes\_class::getClassIndex( class );
loadoutPrimary = maps\mp\gametypes\_class::cac_getWeapon( class_num, 0 );
loadoutPrimaryAttachment = maps\mp\gametypes\_class::cac_getWeaponAttachment( class_num, 0 );
loadoutPrimaryAttachment2 = maps\mp\gametypes\_class::cac_getWeaponAttachmentTwo( class_num, 0 );
loadoutSecondary = maps\mp\gametypes\_class::cac_getWeapon( class_num, 1 );
loadoutSecondaryAttachment = maps\mp\gametypes\_class::cac_getWeaponAttachment( class_num, 1 );
loadoutSecondaryAttachment2 = maps\mp\gametypes\_class::cac_getWeaponAttachmentTwo( class_num, 1 );
loadoutOffhand = maps\mp\gametypes\_class::cac_getOffhand( class_num );
loadoutLethal = maps\mp\gametypes\_class::cac_getPerk( class_num, 0 );
loadoutEquipment = maps\mp\gametypes\_class::cac_getPerk( class_num, 7 );
loadoutPerk1 = maps\mp\gametypes\_class::cac_getPerk( class_num, 1 );
loadoutPerk2 = maps\mp\gametypes\_class::cac_getPerk( class_num, 2 );
loadoutPerk3 = maps\mp\gametypes\_class::cac_getPerk( class_num, 3 );
}
else
{
class_num = maps\mp\gametypes\_class::getClassIndex( class );
loadoutPrimary = maps\mp\gametypes\_class::table_getWeapon( level._classTableName, class_num, 0 );
loadoutPrimaryAttachment = maps\mp\gametypes\_class::table_getWeaponAttachment( level._classTableName, class_num, 0 , 0);
loadoutPrimaryAttachment2 = maps\mp\gametypes\_class::table_getWeaponAttachment( level._classTableName, class_num, 0, 1 );
loadoutSecondary = maps\mp\gametypes\_class::table_getWeapon( level._classTableName, class_num, 1 );
loadoutSecondaryAttachment = maps\mp\gametypes\_class::table_getWeaponAttachment( level._classTableName, class_num, 1 , 0);
loadoutSecondaryAttachment2 = maps\mp\gametypes\_class::table_getWeaponAttachment( level._classTableName, class_num, 1, 1 );;
loadoutOffhand = maps\mp\gametypes\_class::table_getOffhand( level._classTableName, class_num );
loadoutLethal = maps\mp\gametypes\_class::table_getLethal( level._classTableName, class_num, 0 );
loadoutEquipment = maps\mp\gametypes\_class::table_getEquipment( level._classTableName, class_num, 7 );
loadoutPerk1 = maps\mp\gametypes\_class::table_getPerk( level._classTableName, class_num, 1 );
loadoutPerk2 = maps\mp\gametypes\_class::table_getPerk( level._classTableName, class_num, 2 );
loadoutPerk3 = maps\mp\gametypes\_class::table_getPerk( level._classTableName, class_num, 3 );
}
setMatchData( "lives", lifeId, "primaryWeapon", loadoutPrimary );
setMatchData( "lives", lifeId, "primaryAttachments", 0, loadoutPrimaryAttachment );
setMatchData( "lives", lifeId, "primaryAttachments", 1, loadoutPrimaryAttachment2 );
setMatchData( "lives", lifeId, "secondaryWeapon", loadoutSecondary );
setMatchData( "lives", lifeId, "secondaryAttachments", 0, loadoutSecondaryAttachment );
setMatchData( "lives", lifeId, "secondaryAttachments", 1, loadoutSecondaryAttachment );
setMatchData( "lives", lifeId, "offhandWeapon", loadoutOffhand );
setMatchData( "lives", lifeId, "equipment", loadoutEquipment );
setMatchData( "lives", lifeId, "lethal", loadoutLethal );
setMatchData( "lives", lifeId, "perks", 0, loadoutPerk1 );
setMatchData( "lives", lifeId, "perks", 1, loadoutPerk2 );
setMatchData( "lives", lifeId, "perks", 2, loadoutPerk3 );
}
logPlayerDeath( lifeId, attacker, iDamage, sMeansOfDeath, sWeapon, sPrimaryWeapon, sHitLoc )
{
if ( !matchMakingGame() || !canLogClient( self ) || ( isPlayer( attacker ) && !canLogClient( attacker ) ) || !canLogLife( lifeId ) )
return;
if ( lifeId >= level._MaxLives )
return;
if( !isDefined( sWeapon ))
{
sWeapon = "none";
}
if ( sWeapon == "none" )
{
sWeaponType = "none";
sWeaponClass = "none";
}
else
{
sWeaponType = weaponInventoryType( sWeapon );
sWeaponClass = weaponClass( sWeapon );
}
if ( isDefined( sWeaponType ) && (sWeaponType == "primary" || sWeaponType == "altmode") && (sWeaponClass == "pistol" || sWeaponClass == "smg" || sWeaponClass == "rifle" || sWeaponClass == "spread" || sWeaponClass == "mg" || sWeaponClass == "grenade" || sWeaponClass == "rocketlauncher" || sWeaponClass == "sniper") )
{
sWeaponOriginal = undefined;
if ( sWeaponType == "altmode" )
{
sWeaponOriginal = sWeapon;
sWeapon = sPrimaryWeapon;
setMatchData( "lives", lifeId, "altMode", true );
}
weaponTokens = strTok( sWeapon, "_" );
/#
if ( !(weaponTokens.size > 1 && weaponTokens.size <= 4) )
{
PrintLn( "attacker: ", attacker );
PrintLn( "iDamage: ", iDamage );
PrintLn( "sMeansOfDeath: ", sMeansOfDeath );
if ( isDefined( sWeaponOriginal ) )
PrintLn( "sWeaponOriginal: ", sWeaponOriginal );
PrintLn( "sWeapon: ", sWeapon );
PrintLn( "sPrimaryWeapon: ", sPrimaryWeapon );
PrintLn( "--------------------------------" );
PrintLn( "sWeaponType: ", sWeaponType );
PrintLn( "sWeaponClass: ", sWeaponClass );
PrintLn( "--------------------------------" );
PrintLn( "weaponTokens.size: ", weaponTokens.size );
tokenCount = 0;
foreach ( token in weaponTokens )
{
PrintLn( "weaponTokens[", tokenCount, "]: ", weaponTokens[tokenCount] );
tokenCount++;
}
}
#/
assert( weaponTokens.size > 1 && weaponTokens.size <= 4 );
assertEx( weaponTokens[weaponTokens.size - 1] == "mp", "weaponTokens[weaponTokens.size - 1]: " + weaponTokens[weaponTokens.size - 1] );
weaponTokens[weaponTokens.size - 1] = undefined; // remove the trailing "mp"
setMatchData( "lives", lifeId, "weapon", weaponTokens[0] );
//TagZP<Hack> weapon sharing between mp and sp is looking more and more like a bad idea. atbr_detonate as a primary tries to pass
//"detonate" as the attachmant name...
if( weaponTokens[0] != "atbr" && weaponTokens[0] != "miniuav" )
{
if ( isDefined( weaponTokens[1] ) )
setMatchData( "lives", lifeId, "attachments", 0, weaponTokens[1] );
if ( isDefined( weaponTokens[2] ) )
setMatchData( "lives", lifeId, "attachments", 1, weaponTokens[2] );
}
}
else if ( sWeaponType == "item" || sWeaponType == "offhand" )
{
weaponName = strip_suffix( sWeapon, "_mp" );
setMatchData( "lives", lifeId, "weapon", weaponName );
}
else
{
setMatchData( "lives", lifeId, "weapon", sWeapon );
}
if ( isKillstreakWeapon( sWeapon ) )
setMatchData( "lives", lifeId, "modifiers", "killstreak", true );
setMatchData( "lives", lifeId, "mod", sMeansOfDeath );
if ( isPlayer( attacker ) )
{
setMatchData( "lives", lifeId, "attacker", attacker.clientid );
setMatchData( "lives", lifeId, "attackerPos", 0, int( attacker.origin[0] ) );
setMatchData( "lives", lifeId, "attackerPos", 1, int( attacker.origin[1] ) );
setMatchData( "lives", lifeId, "attackerPos", 2, int( attacker.origin[2] ) );
victimForward = anglesToForward( (0,self.angles[1],0) );
attackDirection = (self.origin - attacker.origin);
attackDirection = VectorNormalize( (attackDirection[0], attackDirection[1], 0) );
setMatchData( "lives", lifeId, "dotOfDeath", VectorDot( victimForward, attackDirection ) );
}
else
{
// 255 is world
setMatchData( "lives", lifeId, "attacker", 255 );
setMatchData( "lives", lifeId, "attackerPos", 0, int( self.origin[0] ) );
setMatchData( "lives", lifeId, "attackerPos", 1, int( self.origin[1] ) );
setMatchData( "lives", lifeId, "attackerPos", 2, int( self.origin[2] ) );
}
setMatchData( "lives", lifeId, "player", self.clientid );
setMatchData( "lives", lifeId, "deathPos", 0, int( self.origin[0] ) );
setMatchData( "lives", lifeId, "deathPos", 1, int( self.origin[1] ) );
setMatchData( "lives", lifeId, "deathPos", 2, int( self.origin[2] ) );
setMatchData( "lives", lifeId, "deathAngles", 0, int( self.angles[0] ) );
setMatchData( "lives", lifeId, "deathAngles", 1, int( self.angles[1] ) );
setMatchData( "lives", lifeId, "deathAngles", 2, int( self.angles[2] ) );
}
logPlayerData()
{
if ( !matchMakingGame() || !canLogClient( self ) )
return;
setMatchData( "players", self.clientid, "score", self getPersStat( "score" ) );
setMatchData( "players", self.clientid, "assists", self getPersStat( "assists" ) );
setMatchData( "players", self.clientid, "checkpoints", self getPersStat( "checkpoints" ) );
setMatchData( "players", self.clientid, "longestStreak", self getPersStat( "longestStreak" ) );
}
// log the lives of players who are still alive at match end.
gameEndListener()
{
if ( !matchMakingGame() )
return;
level waittill ( "game_ended" );
setMatchData( "gameLength", int( getTimePassed() ) );
foreach ( player in level._players )
{
if ( player.team != "allies" && player.team != "axis" )
continue;
player logPlayerData();
if ( !isAlive( player ) )
continue;
lifeId = getNextLifeId();
player logPlayerLife( lifeId );
}
}
canLogClient( client )
{
assertEx( isPlayer( client ) , "Client is not a player: " + client.code_classname );
return ( client.clientid < level._MaxLogClients );
}
canLogEvent()
{
return ( getMatchData( "eventCount" ) < level._MaxEvents );
}
canLogKillstreak()
{
return ( getMatchData( "killstreakCount" ) < level._MaxKillstreaks );
}
canLogLife( lifeId )
{
return ( getMatchData( "lifeCount" ) < level._MaxLives );
}

50
maps/mp/_minefields.gsc Normal file
View File

@ -0,0 +1,50 @@
minefields()
{
minefields = getentarray("minefield", "targetname");
if (minefields.size > 0)
{
level._effect["mine_explosion"] = loadfx ("explosions/grenadeExp_dirt");
}
for(i = 0; i < minefields.size; i++)
{
minefields[i] thread minefield_think();
}
}
minefield_think()
{
while (1)
{
self waittill ("trigger",other);
if(isPlayer(other))
other thread minefield_kill(self);
}
}
minefield_kill(trigger)
{
if(isDefined(self.minefield))
return;
self.minefield = true;
self playsound ("minefield_click");
wait(.5);
wait(randomFloat(.5));
if(isdefined(self) && self istouching(trigger))
{
origin = self getorigin();
range = 300;
maxdamage = 2000;
mindamage = 50;
self playsound("explo_mine");
playfx(level._effect["mine_explosion"], origin);
radiusDamage(origin, range, maxdamage, mindamage);
}
self.minefield = undefined;
}

70
maps/mp/_moon_mp.gsc Normal file
View File

@ -0,0 +1,70 @@
//TagZP<NOTE> We want this to do the same thing that the sp setup does. If any of these commented out
//tweak values are changed move them into constatns so both sp and mp has access.
main()
{
//gravity_scale = common_scripts\_moon::getMoonGlobalGravityScale();
turn_scale = 1.0; //common_scripts\_moon::getMoonGlobalTurnRateScale();
ads_yaw = common_scripts\_moon::getMoonGlobalADSYaw();
ads_pitch = common_scripts\_moon::getMoonGlobalADSPitch();
//moongrav = getdvarint( "player_moon_grav_scale" );
//println( "!!!!!setting global gravity scale!!!!!!!!!!!!" );
setdvar( "phys_global_gravity_scale", 0.25 );
setdvar( "aim_scale_turn_rate", turn_scale );
setdvar( "aim_turnrate_pitch_ads", ads_pitch);
setdvar( "aim_turnrate_yaw_ads", ads_yaw);
level._use_moon_gravity = true;
//these values can be changed to effect the way in which the player behaves in gravity.
//Setting values to 1.0 will make them behave like on earth. I've given them values here
//of their defaults, ones that seemed correct for me. They will have no effect without
//the below call to SetMoonGravity as they are only used in the player movement code.
//These shouldn't stay dvars, but become #define once we're happy with them.
//setdvar( "player_moon_grav_stop_scalar", "0.20");
//setdvar( "player_moon_grav_start_scalar", "0.20");
//setdvar( "player_moon_grav_speed_scalar", "0.65");
//These values effect the way in which the player rig behaves in moon gravity.
//Larger vertical bob amplitude will cause the player to bob higher in their steps.
//Larger horizontal bob amplitude will give the impression of more sway in the walk.
//Smaller bob speeds will decrease how quickly the player rig bob cycles, not the actual movement speed.
//They will have no effect without the below call to SetMoonGravity as they are
//only used in the player movement code.
//These shouldn't stay dvars, but become #define once we're happy with them.
//setdvar( "weapon_view_moon_vertical_bob_amp", "4.0" );
//setdvar( "weapon_view_moon_horizontal_bob_amp", "1.5" );
//setdvar( "weapon_view_moon_bob_speed", "0.5" );
//This value effects the overall height of the jump. Adding in variable jump height, I had to suppress some of
//jump height because it was getting too high.
//setdvar( "player_moon_grav_variable_jump_scalar", "0.2" );
}
init_moon_player()
{
if( isDefined( level._use_moon_gravity ))
{
if( level._use_moon_gravity == true )
{
//println( "!!!!!setting player moon gravity!!!!!!!!!!!!" );
self SetMoonGravity( true );
self EnableMoonHelmetHUD();
maps\mp\perks\_perks::givePerk( "specialty_moonsuit" );
}
else
{
//println( "!!!!!setting player Earth gravity!!!!!!!!!!!!" );
self SetMoonGravity( false );
self DisableMoonHelmetHud();
}
}
else
{
//println( "!!!!!setting player Earth gravity!!!!!!!!!!!!" );
self SetMoonGravity( false );
self DisableMoonHelmetHud();
}
}

View File

@ -0,0 +1,226 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
//*******************************************************************
// *
// *
//*******************************************************************
// Min distance to start to track projectile.
CONST_TROPHY_MAX_TRACK_DISTANCE = 500;
CONST_MAX_TRACK_TIME_MS = 500;
TROPHY_SOUND_AFTER_COOLDOWN = "weap_recharge_stop";
TROPHY_RELOAD_TIME_SEC = 3.0;
TROPHY_ACTIVE_RADIUS = 400.0;
TROPHY_INACTIVE_RADIUS = 200.0;
TROPHY_TABLE_FILE = "mp/trophyTable.csv";
//*******************************************************************
// *
// *
//*******************************************************************
find_closest_projectile( pos, current_projectile, friendlyTeam )
{
projectiles = GetEntArray( "grenade", "classname" );
// Is there a better way to do this?
rockets = GetEntArray( "rocket", "classname" );
foreach ( ent in rockets )
{
projectiles[ projectiles.size ] = ent;
}
min_distance = 999999999999999.0;
return_obj = undefined;
// First check for the current projectile.
if ( isdefined( current_projectile ))
{
foreach ( ent in projectiles )
{
if ( current_projectile == ent )
{
return_obj = ent;
break;
}
}
}
// No dice, find a new one by range.
if ( !isdefined( return_obj ))
{
foreach ( ent in projectiles )
{
team = ent MissileGetTeam();
if ( "invalid" == team )
{
// projectiles from vehicles fall under "invalid", so we'll check the team of their owner
team = ent VehicleMissleGetTeam();
}
// team check
if( isDefined( friendlyTeam ))
{
if( team == friendlyTeam )
{
continue;
}
}
if( isDefined( ent.type ))
{
if( ent.type == "remote" )
{
// remote missile, those are ok
continue;
}
}
// Distance.
d = DistanceSquared( ent.origin, pos );
if ( d < min_distance )
{
min_distance = d;
return_obj = ent;
}
}
}
return return_obj;
}
//*******************************************************************
// *
// *
//*******************************************************************
trophy_turret_update()
{
// Exit cases.
self endon( "death" );
// Locals.
soundEnt = self;
turret = self.trophy_turret;
if( isDefined( turret ))
{
soundEnt = turret;
}
soundorg = Spawn( "script_origin", soundEnt.origin );
soundorg LinkTo( soundEnt );
projectile = undefined;
tracked_time = 0;
self.trophyLastFireTime = 0;
// Think.
for( ;; )
{
wait( 0.05 );
//println( "update" );
friendlyTeam = undefined;
// this is a escort plus check
if( isDefined( self.curr_owner ))
{
// if the current owner is neutral, trophy system is off
if( self.curr_owner == "neutral" )
{
continue;
}
if( isDefined( game[self.curr_owner] ))
{
friendlyTeam = game[self.curr_owner];
}
}
else
{
friendlyTeam = self.owner.team;
}
//println( "friendly team is ", friendlyTeam );
// Get target.
prev = projectile;
projectile = find_closest_projectile( self.origin, projectile, friendlyTeam );
if ( isdefined( projectile ))
{
//println( "got projectile" );
distance_squared = DistanceSquared( projectile.origin, self.origin );
if ( distance_squared < ( CONST_TROPHY_MAX_TRACK_DISTANCE * CONST_TROPHY_MAX_TRACK_DISTANCE ))
{
canFire = false;
if( TROPHY_RELOAD_TIME_SEC * 1000 < getTime() - self.trophyLastFireTime )
{
canFire = true;
}
inRange = false;
if( distance_squared < TROPHY_ACTIVE_RADIUS * TROPHY_ACTIVE_RADIUS )
{
if( distance_squared > TROPHY_INACTIVE_RADIUS * TROPHY_INACTIVE_RADIUS )
{
inRange = true;
}
}
if( canFire && inRange )
{
weaponName = projectile getWeaponName();
if( !canGoThroughTrophy ( weaponName, "ugv" ))
{
//projectile MissileTryTrophyExplode( self );
self notify( "trophy_kill_projectile", TROPHY_RELOAD_TIME_SEC );
self.trophyLastFireTime = getTime();
PlayFX ( level._effect[ "trophy_explosion" ], projectile.origin );
projectile delete();
projectile = undefined;
self PlaySound( TROPHY_SOUND_AFTER_COOLDOWN );
}
}
}
else
{
// println( "not close enough... dsqr ", distance_squared, " ", projectile.origin, " ", self.origin );
}
}
else
{
if( isDefined( turret ))
{
turret ClearTargetEntity();
}
}
}
}
canGoThroughTrophy ( weaponName, type )
{
index = undefined;
switch ( type )
{
case "suit":
index = 2;
break;
case "ugv":
index = 3;
break;
default:
assertMsg( "Invalid trophy type. Must be either 'suit' or 'ugv'" );
}
result = tablelookup( TROPHY_TABLE_FILE, 1, weaponName, index );
if ( result == "1")
{
return true;
}
else
{
return false;
}
}

227
maps/mp/_radiation.gsc Normal file
View File

@ -0,0 +1,227 @@
#include maps\mp\_utility;
#include common_scripts\utility;
radiation()
{
precacheString( &"SCRIPT_RADIATION_DEATH" );
radiationFields = getentarray("radiation", "targetname");
if (radiationFields.size > 0)
{
precacheshellshock( "mp_radiation_low" );
precacheshellshock( "mp_radiation_med" );
precacheshellshock( "mp_radiation_high" );
foreach ( trigger in radiationFields )
trigger thread common_scripts\_dynamic_world::triggerTouchThink( ::playerEnterArea, ::playerLeaveArea );
thread onPlayerConnect();
}
}
onPlayerConnect()
{
for ( ;; )
{
level waittill ( "connected", player );
player.numAreas = 0;
}
}
playerEnterArea( trigger )
{
self.numAreas++;
if ( self.numAreas == 1 )
self radiationEffect();
}
playerLeaveArea( trigger )
{
self.numAreas--;
assert( self.numAreas >= 0 );
if ( self.numAreas != 0 )
return;
self.poison = 0;
self notify( "leftTrigger");
if ( isDefined( self.radiationOverlay ) )
self.radiationOverlay fadeoutBlackOut( .10, 0 );
}
soundWatcher( soundOrg )
{
self waittill_any( "death", "leftTrigger" );
self stopLoopSound();
}
radiationEffect()
{
self endon( "disconnect" );
self endon( "game_ended" );
self endon( "death" );
self endon( "leftTrigger" );
self.poison = 0;
self thread soundWatcher( self );
while (1)
{
self.poison ++;
switch( self.poison )
{
case 1:
self.radiationSound = "item_geigercouner_level2";
self playLoopSound( self.radiationSound );
self ViewKick( 1, self.origin );
break;
case 3:
self shellshock( "mp_radiation_low", 4);
self.radiationSound = "item_geigercouner_level3";
self stopLoopSound();
self playLoopSound( self.radiationSound );
self ViewKick( 3, self.origin );
self doRadiationDamage(15);
break;
case 4:
self shellshock( "mp_radiation_med", 5);
self.radiationSound = "item_geigercouner_level3";
self stopLoopSound();
self playLoopSound( self.radiationSound );
self ViewKick( 15, self.origin );
self thread blackout();
self doRadiationDamage(25);
break;
case 6:
self shellshock( "mp_radiation_high", 5);
self.radiationSound = "item_geigercouner_level4";
self stopLoopSound();
self playLoopSound( self.radiationSound );
self ViewKick( 75, self.origin );
self doRadiationDamage(45);
break;
case 8:
self shellshock( "mp_radiation_high", 5);
self.radiationSound = "item_geigercouner_level4";
self stopLoopSound();
self playLoopSound( self.radiationSound );
self ViewKick( 127, self.origin );
self doRadiationDamage(175);
break;
}
wait(1);
}
wait(5);
}
blackout( )
{
self endon( "disconnect" );
self endon( "game_ended" );
self endon( "death" );
self endon( "leftTrigger" );
if ( !isDefined( self.radiationOverlay ) )
{
self.radiationOverlay = newClientHudElem( self );
self.radiationOverlay.x = 0;
self.radiationOverlay.y = 0;
self.radiationOverlay setshader( "black", 640, 480 );
self.radiationOverlay.alignX = "left";
self.radiationOverlay.alignY = "top";
self.radiationOverlay.horzAlign = "fullscreen";
self.radiationOverlay.vertAlign = "fullscreen";
self.radiationOverlay.alpha = 0;
}
min_length = 1;
max_length = 2;
min_alpha = .25;
max_alpha = 1;
min_percent = 5;
max_percent = 100;
fraction = 0;
for ( ;; )
{
while ( self.poison > 1 )
{
percent_range = max_percent - min_percent;
fraction = ( self.poison - min_percent ) / percent_range;
if ( fraction < 0 )
fraction = 0;
else if ( fraction > 1 )
fraction = 1;
length_range = max_length - min_length;
length = min_length + ( length_range * ( 1 - fraction ) );
alpha_range = max_alpha - min_alpha;
alpha = min_alpha + ( alpha_range * fraction );
end_alpha = fraction * 0.5;
if ( fraction == 1 )
break;
duration = length / 2;
self.radiationOverlay fadeinBlackOut( duration, alpha );
self.radiationOverlay fadeoutBlackOut( duration, end_alpha);
// wait a variable amount based on self.radiation.totalpercent, this is the space in between pulses
//wait 1;
wait( fraction * 0.5 );
}
if ( fraction == 1 )
break;
if ( self.radiationOverlay.alpha != 0 )
self.radiationOverlay fadeoutBlackOut( 1, 0);
wait 0.05;
}
self.radiationOverlay fadeinBlackOut( 2, 0);
}
doRadiationdamage( iDamage )
{
self thread [[ level._callbackPlayerDamage ]](
self,// eInflictor The entity that causes the damage.( e.g. a turret )
self,// eAttacker The entity that is attacking.
iDamage,// iDamage Integer specifying the amount of damage done
0,// iDFlags Integer specifying flags that are to be applied to the damage
"MOD_SUICIDE",// sMeansOfDeath Integer specifying the method of death
"claymore_mp",// sWeapon The weapon number of the weapon used to inflict the damage
self.origin,// vPoint The point the damage is from?
( 0,0,0 ) - self.origin,// vDir The direction of the damage
"none",// sHitLoc The location of the hit
0// psOffsetTime The time offset for the damage
);
}
fadeinBlackOut( duration, alpha )
{
self fadeOverTime( duration );
self.alpha = alpha;
wait duration;
}
fadeoutBlackOut( duration, alpha )
{
self fadeOverTime( duration );
self.alpha = alpha;
wait duration;
}

770
maps/mp/_remotedog.gsc Normal file
View File

@ -0,0 +1,770 @@
#include maps\mp\_utility;
#include common_scripts\utility;
DOG_TIMEOUT_SEC = 45;
DOG_HUD_TIMER_POS_X = 0;
DOG_HUD_TIMER_POS_Y = -35;
DOG_TURRET_MAX_TARGETING_RANGE = 600; // 45 feet
DOG_TURRET_SPAWN_GRACE_TIME = 3; // dog wont shoot any anyone who hasn't been spawned for 3 seconds
DOG_TURRET_MIN_SHOTS = 10; // minimum shots to fire at a player
DOG_TURRET_MAX_SHOTS = 20; // maximum shots to fire at a player
DOG_TURRET_FIRE_DELAY = .1; // how long to wait between shots at a target
DOG_TURRET_MIN_BARRAGE_DELAY = 0; // how long to wait between firing bursts of shots at a target
DOG_TURRET_MAX_BARRAGE_DELAY = .1; // how long between burts of shots
DOG_TURRET_MAX_YAW = 60; // how far the turret can turn from the dogs centerline
//*******************************************************************
// *
// *
//*******************************************************************
init()
{
level._killstreakFuncs["remote_dog"] = ::tryRemoteDog;
level._remoteDogVehicleInfo = "PROTO_nx_remote_dog_play_mp";
level._remoteDogVehicleModel = "prototype_vehicle_remotedog_vehicle"; // "defaultvehicle"
level._remoteDogScriptModel = "prototype_vehicle_remotedog";
level._remoteDogMoveAnim = "german_shepherd_run";
level._remoteDogIdleAnim = "german_shepherd_idle";
level._remoteDogTranProp = "miniuav_transition_prop";
level._remoteDogTurretInfo = "proto_robot_dog_turret_mp";
level._remoteDogTurretModel = "proto_remotedog_turret";
level._remoteDogFOV = 120;
level._remoteDogHealth = 200;
level._remoteDogAmmo = 100;
level._remoteDogFireRate = 1; // in tenths of a second, so 10 is fires once a second
level._remoteDogCrossHair = "ac130_overlay_25mm";
PreCacheItem( level._remoteDogTranProp );
precacheString( &"NX_MINIUAV_USE_DRONE" );
PreCacheShader( "ac130_overlay_grain" );
PreCacheShader( level._remoteDogCrossHair );
precacheVehicle( level._remoteDogVehicleInfo );
precacheModel( level._remoteDogVehicleModel );
precacheMpAnim( level._remoteDogMoveAnim );
precacheMpAnim( level._remoteDogIdleAnim );
precacheModel( level._remoteDogScriptModel );
precacheTurret( level._remoteDogTurretInfo );
precacheModel( level._remoteDogTurretModel );
}
//*******************************************************************
// *
// *
//*******************************************************************
remoteDogDebugPrint( msg )
{
IPrintLnBold( msg );
}
//*******************************************************************
// *
// *
//*******************************************************************
tryRemoteDog( lifeId )
{
self thread remoteDogStartup(); // Kick of main UAV loop.
msg = self waittill_any_return( "death", "cleanup_remote_dog" ); // Wait for death or timeout.
if( msg == "cleanup_remote_dog" )
{
// Wait for weapon transition to happen.
wait 2.0;
}
return true;
}
//*******************************************************************
// *
// *
//*******************************************************************
remoteDogPlayerEventListenerThread()
{
self waittill( "exit_remote_dog" );
self.remotedog notify( "exit_remote_dog" );
}
//*******************************************************************
// *
// *
//*******************************************************************
remoteDogStartup()
{
self endon( "death" );
self endon( "remote_dog_time_is_up" );
self endon( "remote_dog_out_of_ammo" );
// self NotifyOnPlayerCommand( "switch_to_remote_dog", "+actionslot 4" );
self DisableOffhandWeapons();
self._dogPlayerOrigin = self GetOrigin();
self._dogPlayerAngles = self GetPlayerAngles();
// Wait for transition anim to finish.
wait 1.75;
// Enter the Dawg.
pos = self._dogPlayerOrigin + ( 0, 0, 50 );
// setup vehicle
self.remotedog = spawnVehicle( level._remoteDogVehicleModel, "test_dog", level._remoteDogVehicleInfo, pos, self._dogPlayerAngles );
self.remotedog.health = level._remoteDogHealth;
self.remotedog.maxhealth = self.remotedog.health;
self.remotedog setCanDamage( true );
self.remotedog.owner = self;
self.remotedog.team = self.team;
self.remotedog.ammo = level._remoteDogAmmo;
self.remotedog.fireRate = level._remoteDogFireRate;
self.remotedog.damageCallback = ::Callback_DogDamage;
// hide the remote dog, we're going to attach another model to it
self.remotedog Hide();
// setup dog model
self.remotedog.remoteDogModel = spawn( "script_model", pos );
self.remotedog.remoteDogModel.owner = self;
self.remotedog.remoteDogModel setModel( level._remoteDogScriptModel );
self.remotedog.remoteDogModel ScriptModelPlayAnim( level._remoteDogIdleAnim );
self.remotedog.remoteDogModel.angles = self._dogPlayerAngles;
self.remotedog.currAnim = level._remoteDogIdleAnim;
self.remotedog.remoteDogModel linkto( self.remotedog );
// setup hud and stuff
self.remotedog notify( "stop_turret_shoot" );
self.in_dog = true;
self thread remotedogHud();
self CameraLinkTo( self.remotedog, "tag_player" );
self.remote_dog_orig_fov = GetDvarFloat( "cg_fov" );
self setClientDvar( "cg_fov", level._remoteDogFOV );
self ThermalVisionFOFOverlayOn();
self visionSetNakedForPlayer( "cheat_bw", 0 );
// create the turret for the dawg
turretPoint = self.remotedog getTagOrigin( "TAG_TURRET" );
self.remotedog.turret = spawnTurret( "misc_turret", turretPoint, level._remoteDogTurretInfo );
self.remotedog.turret linkTo( self.remotedog, "TAG_TURRET", (0,0,0), (0,0,0) );
self.remotedog.turret setModel( level._remoteDogTurretModel );
self.remotedog.turret.angles = self.remotedog.angles;
self.remotedog.turret.owner = self.remotedog.owner;
self.remotedog.turret makeTurretInoperable();
self.remotedog.turret SetDefaultDropPitch( 0 );
//self.remotedog.turret.owner = self;
// find a point to for the turret to look at when it isn't trying to fire
offset = turretPoint - self.remotedog.origin;
neutralTargetEnt = spawn("script_origin", self.remotedog.turret getTagOrigin("tag_flash") );
neutralTargetEnt linkTo( self, "tag_origin", offset, (0,0,0) );
neutralTargetEnt hide();
self.remotedog.neutralTarget = neutralTargetEnt;
// spawn a thread to control the turret
self.remotedog thread remoteDogFindTargets();
// get them controls hooked up!
// self ControlsLinkTo( self.remotedog );
self MiniUAVOn( self.remotedog );
// Kick off timer.
self hudRemoteDogTimer( DOG_TIMEOUT_SEC );
self.remotedog thread RemoteDogWaitForTimeout( DOG_TIMEOUT_SEC );
// loop for the dog
self thread remoteDogLoop( self.remotedog );
// setup a thread to listen for the exit
self thread remoteDogPlayerEventListenerThread();
self.remotedog thread remoteDogExitCleanup();
return true;
}
//*******************************************************************
// *
// *
//*******************************************************************
remoteDogExitCleanup()
{
remoteDogDebugPrint( "remoteDogExitCleanup()" );
msg = self waittill_any_return( "death", "exit_remote_dog", "remote_dog_time_is_up", "remote_dog_out_of_ammo" ); // Wait for either way of exiting a uav.
remoteDogDebugPrint( "Running cleanup after msg " + msg );
self.owner thread remoteDogExitPlayer();
self notify( "cleanup_remote_dog" );
self.owner notify( "cleanup_remote_dog" );
}
//*******************************************************************
// *
// *
//*******************************************************************
remoteDogFindTargets()
{
self endon( "death" );
self endon( "cleanup_remote_dog" );
println( "Geting Targets" );
for ( ;; )
{
targets = [];
players = level._players;
for (i = 0; i <= players.size; i++)
{
if ( isDogTarget( players[i] ) && isdefined( players[i] ) )
{
targets[targets.size] = players[i];
}
else
{
continue;
}
wait( .05 );
}
if ( targets.size > 0 )
{
self acquireTarget( targets );
return;
}
else
{
wait( .05 );
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
isDogTarget( potentialTarget )
{
self endon( "death" );
if ( !isalive( potentialTarget ) || potentialTarget.sessionstate != "playing" )
return false;
if ( !isdefined( potentialTarget.pers["team"] ) )
return false;
if ( potentialTarget == self.owner )
return false;
if ( distanceSquared( potentialTarget.origin , self.origin ) > DOG_TURRET_MAX_TARGETING_RANGE*DOG_TURRET_MAX_TARGETING_RANGE )
return false;
if ( level._teamBased && potentialTarget.pers["team"] == self.team )
return false;
if ( potentialTarget.pers["team"] == "spectator" )
return false;
if ( isdefined( potentialTarget.spawntime ) && ( gettime() - potentialTarget.spawntime )/1000 <= DOG_TURRET_SPAWN_GRACE_TIME )
return false;
// check to see if they are in our yaw range
vecToTarget = potentialTarget.origin - self.origin;
targetYaw = AngleClamp( VectorToYaw( vecToTarget ) );
turretYaw = AngleClamp( self.angles[1] );
degrees = abs( targetYaw - self.angles[1] );
degrees = AngleClamp( degrees );
if( degrees > DOG_TURRET_MAX_YAW && ( 360 - degrees ) > DOG_TURRET_MAX_YAW )
{
// println( "bad degrees " + degrees + " angles " + turretYaw + " target yaw " + targetYaw );
return false;
}
// println( "good degrees " + degrees + " angles " + turretYaw + " target yaw " + targetYaw );
if ( isDefined( self ) )
{
minTurretEye = self.turret.origin + ( 0, 0, 64 );
minTurretCanSeeTarget = potentialTarget sightConeTrace( minTurretEye, self );
if ( minTurretCanSeeTarget < 1 )
return false;
}
return true;
}
//*******************************************************************
// *
// *
//*******************************************************************
getBestTarget( targets )
{
self endon( "death" );
origin = self.origin;
closest = undefined;
bestTarget = undefined;
foreach ( targ in targets )
{
curDist = Distance( self.origin, targ.origin );
if ( !isDefined( closest ) )
{
closest = curDist;
bestTarget = targ;
}
else if ( closest > curDist )
{
closest = curDist;
bestTarget = targ;
}
}
return ( bestTarget );
}
//*******************************************************************
// *
// *
//*******************************************************************
acquireTarget( targets )
{
self endon( "death" );
if ( targets.size == 1 )
{
self.bestTarget = targets[0];
}
else
{
self.bestTarget = self getBestTarget( targets );
}
self notify( "acquiringTarget" );
self.turret SetTargetEntity( self.bestTarget, ( 0,0,42 ) ); // sets turret to target entity
wait( .15 );
self thread fireOnTarget(); // fires on current target.
self thread watchTargetDeath( targets ); //abandons target when target killed
self thread watchTargetDistance( targets );
self thread watchTargetAngle( targets );
self thread watchTargetThreat( self.bestTarget );
}
//*******************************************************************
// *
// *
//*******************************************************************
fireOnTarget()
{
self endon( "death" );
self endon( "abandonedTarget" );
self endon( "killedTarget" );
noTargTime = undefined;
acquiredTime = getTime();
if ( !isDefined( self.bestTarget ) )
{
println("No Targ to fire on");
return;
}
println("firing on best target");
while( 1 )
{
if ( !isDefined ( self.turret getTurretTarget( true ) ) )
{
if ( !isDefined( noTargTime ) )
noTargTime = getTime();
curTime = getTime();
if ( noTargTime - curTime > 1 )
{
noTargTime = undefined;
self thread explicitAbandonTarget();
return;
}
println("Waiting because the turret doesnt have a target" );
wait ( .5 );
continue;
}
numShots = randomIntRange( DOG_TURRET_MIN_SHOTS, DOG_TURRET_MAX_SHOTS );
for ( i = 0; i < numShots; i++ )
{
println( "actually shooting turret" );
self.turret ShootTurret();
wait ( DOG_TURRET_FIRE_DELAY );
}
wait ( randomFloatRange( DOG_TURRET_MIN_BARRAGE_DELAY, DOG_TURRET_MAX_BARRAGE_DELAY ) );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
watchTargetDeath( targets )
{
self endon( "abandonedTarget" );
self endon( "death" );
if ( !isDefined( self.bestTarget ) )
return;
self.bestTarget waittill( "death" );
self notify( "killedTarget" );
println( "Killed Target" );
self.bestTarget = undefined;
self.turret ClearTargetEntity();
self remoteDogFindTargets();
}
//*******************************************************************
// *
// *
//*******************************************************************
watchTargetAngle( targets )
{
self endon( "abandonedTarget" );
self endon( "death" );
for ( ;; )
{
if ( !isDefined( self.bestTarget ) )
return;
// check to see if they are in our yaw range
vecToTarget = self.bestTarget.origin - self.origin;
targetYaw = AngleClamp( VectorToYaw( vecToTarget ) );
turretYaw = AngleClamp( self.angles[1] );
degrees = abs( targetYaw - self.angles[1] );
degrees = AngleClamp( degrees );
if( degrees > DOG_TURRET_MAX_YAW && ( 360 - degrees ) > DOG_TURRET_MAX_YAW )
{
println( "Abandon! degrees " + degrees + " angles " + self.angles[1] + " target yaw " + targetYaw );
self thread explicitAbandonTarget();
return;
}
wait ( 0.5 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
watchTargetDistance( targets )
{
self endon( "abandonedTarget" );
self endon( "death" );
for ( ;; )
{
if ( !isDefined( self.bestTarget ) )
return;
trace = BulletTrace( self.turret.origin, self.bestTarget.origin, false, self );
traceDistance = Distance(self.origin, trace["position"] );
if ( traceDistance > DOG_TURRET_MAX_TARGETING_RANGE )
{
println( "TARGET DIST TOO FAR!!!" );
self thread explicitAbandonTarget();
return;
}
println( traceDistance );
wait ( 2 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
watchTargetThreat( curTarget )
{
self endon( "abandonedTarget" );
self endon( "death" );
self endon( "killedTarget" );
for ( ;; )
{
targets = [];
players = level._players;
for (i = 0; i <= players.size; i++)
{
if ( isDogTarget( players[i] ) )
{
if( !isdefined( players[i] ) )
continue;
if( !isdefined(curTarget) )
return;
traceOldTarg = Distance(self.origin, CurTarget.origin );
traceNewTarg = Distance(self.origin, players[i].origin );
if ( traceNewTarg < traceOldTarg )
{
self thread explicitAbandonTarget();
return;
}
}
wait( .05 );
}
wait( .25 );
}
}
explicitAbandonTarget( noNewTarget )
{
self notify( "abandonedTarget" );
println( "ABANDONED TARGET" );
self.bestTarget = undefined;
self.turret ClearTargetEntity();
if ( isDefined(noNewTarget) && noNewTarget )
return;
self thread remoteDogFindTargets();
return;
}
//*******************************************************************
// *
// *
//*******************************************************************
remoteDogLoop( vehicle )
{
self endon( "death" );
vehicle endon( "cleanup_remote_dog" );
self NotifyOnPlayerCommand( "exit_remote_dog", "+usereload" ); // BUTTON_X
vehicle._oldOrigin = vehicle.origin;
vehicle.fireCycle = 0;
while ( isalive( self ) )
{
if( vehicle.fireCycle > 0 )
{
vehicle.fireCycle = vehicle.fireCycle - 1;
}
// steal the player's angles to control turning the dog, for now...
angles = vehicle.angles;
player_angles = self GetPlayerAngles();
angles = ( player_angles[0], angles[1], angles[2] );
target = vehicle.origin + vector_multiply( AnglesToForward( angles ), 2000.0 );
// don't do this anymore, the turret is auto targetting now
// vehicle SetTurretTargetVec( target );
vehicle.remoteDogModel.angels = vehicle.angles;
// no more attack buttons to shoot
/* if( self AttackButtonPressed() )
{
if( vehicle.ammo > 0 && vehicle.fireCycle == 0)
{
vehicle fireweapon();
vehicle.fireCycle = vehicle.fireRate;
vehicle.ammo = vehicle.ammo - 1;
// out of ammo! lets get out of this thing!
if( vehicle.ammo == 0 )
{
self thread remotedogOutOfAmmoThead( vehicle );
}
}
}*/
if( distance( vehicle._oldOrigin, vehicle.origin ) > 0 )
{
if( vehicle.currAnim != level._remoteDogMoveAnim )
{
vehicle.remoteDogModel ScriptModelPlayAnim( level._remoteDogMoveAnim );
vehicle.currAnim = level._remoteDogMoveAnim;
}
}
else
{
if( vehicle.currAnim != level._remoteDogIdleAnim )
{
vehicle.remoteDogModel ScriptModelPlayAnim( level._remoteDogIdleAnim );
vehicle.currAnim = level._remoteDogIdleAnim;
}
}
vehicle._oldOrigin = vehicle.origin;
wait 0.1;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
remotedogOutOfAmmoThead( vehicle )
{
remoteDogDebugPrint( "remotedogOutOfAmmoThead() out of ammo!" );
vehicle endon( "cleanup_remote_dog" );
wait 2;
vehicle notify( "remote_dog_out_of_ammo" );
}
//*******************************************************************
// *
// *
//*******************************************************************
Callback_DogDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName )
{
remoteDogDebugPrint( "damage callback" );
if ( ( attacker == self || ( isDefined( attacker.pers ) && attacker.pers["team"] == self.team ) ) && attacker != self.owner )
return;
remoteDogDebugPrint( "damaged dog! " + damage );
self Vehicle_FinishDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
}
//*******************************************************************
// *
// *
//*******************************************************************
remoteDogExitPlayer()
{
// cleanup the models
self.remotedog.remoteDogModel Unlink();
self.remotedog.remoteDogModel Delete();
// cleanup the actual things
self.remotedog.turret Delete();
self.remotedog Delete();
self ThermalVisionFOFOverlayOff();
self CameraUnlink();
self setClientDvar( "cg_fov", self.remote_dog_orig_fov );
self MiniUAVOff();
// self ControlsUnlink();
self visionSetNakedForPlayer( getDvar( "mapname" ), 0 );
self setVelocity(( 0, 0, 0 ));
self setOrigin( self._dogPlayerOrigin );
self setPlayerAngles( self._dogPlayerAngles );
self switchToWeapon( self._pre_killstreak_weapon_name );
self destroyRemoteDogTimer();
wait 2.0;
self EnableOffhandWeapons();
self.in_dog = false;
}
//*******************************************************************
// *
// *
//*******************************************************************
remotedogHud()
{
// crossHair = newClientHudElem( self );
// crossHair.x = 0;
// crossHair.y = 0;
// crossHair.alignX = "center";
// crossHair.alignY = "middle";
// crossHair.horzAlign = "center";
// crossHair.vertAlign = "middle";
// crossHair setshader( level._remoteDogCrossHair, 640, 480 );
// static = NewClientHudElem( self );
// static.horzAlign = "fullscreen";
// static.vertAlign = "fullscreen";
// static SetShader( "ac130_overlay_grain", 640, 480 );
//
// self waittill( "cleanup_remote_dog" ); // Wait for either way of exiting a uav.
// crossHair Destroy();
}
//*******************************************************************
// *
// *
//*******************************************************************
hudRemoteDogTimer( duration )
{
remoteDogDebugPrint( "hudRemoteDogTimer()" );
self.remoteDogTimer = newClientHudElem( self );
self.remoteDogTimer.x = DOG_HUD_TIMER_POS_X;
self.remoteDogTimer.y = DOG_HUD_TIMER_POS_Y;
self.remoteDogTimer.alignX = "center";
self.remoteDogTimer.alignY = "bottom";
self.remoteDogTimer.horzAlign = "center_adjustable";
self.remoteDogTimer.vertAlign = "bottom_adjustable";
self.remoteDogTimer.fontScale = 2.5;
self.remoteDogTimer setTimer( 1.0 );
self.remoteDogTimer.alpha = 1.0;
self.remoteDogTimer setTimer( duration );
println( "done setting hud timer" );
}
//*******************************************************************
// *
// *
//*******************************************************************
RemoteDogWaitForTimeout( duration )
{
self endon( "cleanup_remote_dog" );
wait duration;
remoteDogDebugPrint( "RemoteDogWaitForTimeout() Time's up!" );
self notify( "remote_dog_time_is_up" );
self._time_is_up = 1;
}
//*******************************************************************
// *
// *
//*******************************************************************
destroyRemoteDogTimer()
{
remoteDogDebugPrint( "cleanup timer!" );
self.remoteDogTimer Destroy();
}
/*
QUAKED script_vehicle_nx_miniuav_player_mp (1 0 0) (-16 -16 -24) (16 16 32) USABLE SPAWNER
put this in your GSC:
maps\mp\killstreaks\_miniuav::main( "nx_vehicle_miniuav" );
and these lines in your CSV:
include,nx_vehicle_miniuav_player
defaultmdl="nx_vehicle_miniuav"
default:"vehicletype" "nx_miniuav_player"
default:"script_team" "allies"
*/

164
maps/mp/_scoreboard.gsc Normal file
View File

@ -0,0 +1,164 @@
#include maps\mp\_utility;
#include common_scripts\utility;
processLobbyScoreboards()
{
foreach ( player in level._placement["all"] )
player setPlayerScoreboardInfo();
if( level._multiTeamBased )
{
buildScoreboardType( "multiteam" );
foreach ( player in level._players )
player setPlayerData( "round", "scoreboardType", "multiteam" );
}
else if ( level._teamBased )
{
alliesScore = getTeamScore( "allies" );
axisScore = getTeamScore( "axis" );
if ( alliesScore == axisScore )
winner = "tied";
else if ( alliesScore > axisScore )
winner = "allies";
else
winner = "axis";
if ( winner == "tied" )
{
// build both, assign type to your team
buildScoreboardType( "allies" );
buildScoreboardType( "axis" );
foreach ( player in level._players )
{
if ( player.pers["team"] == "spectator" )
player setPlayerData( "round", "scoreboardType", "allies" );
else
player setPlayerData( "round", "scoreboardType", player.pers["team"] );
}
}
else
{
// build just winner, assign type to winner
buildScoreboardType( winner );
foreach ( player in level._players )
player setPlayerData( "round", "scoreboardType", winner );
}
}
else // not teambased
{
buildScoreboardType( "neutral" );
foreach ( player in level._players )
player setPlayerData( "round", "scoreboardType", "neutral" );
}
foreach ( player in level._players )
{
// TODO: convert this to round stats
player setClientDvars(
"player_summary_xp", player.pers["summary"]["xp"],
"player_summary_score", player.pers["summary"]["score"],
"player_summary_challenge", player.pers["summary"]["challenge"],
"player_summary_match", player.pers["summary"]["match"],
"player_summary_misc", player.pers["summary"]["misc"]
);
}
}
setPlayerScoreboardInfo()
{
scoreboardPlayerCount = getClientMatchData( "scoreboardPlayerCount" );
if ( scoreboardPlayerCount <= 24 ) //MaxPlayers
{
setClientMatchData( "players", self.clientMatchDataId, "score", self.pers["score"] );
println( "Scoreboard: [" + self.name + "(" + self.clientMatchDataId + ")][score]: " + self.pers["score"] );
kills = self getPlayerStat( "kills" );
setClientMatchData( "players", self.clientMatchDataId, "kills", kills );
println( "Scoreboard: [" + self.name + "(" + self.clientMatchDataId + ")][kills]: " + kills );
assists = self getPlayerStat( "assists" );
setClientMatchData( "players", self.clientMatchDataId, "assists", assists );
println( "Scoreboard: [" + self.name + "(" + self.clientMatchDataId + ")][assists]: " + assists );
deaths = self getPlayerStat( "deaths" );
setClientMatchData( "players", self.clientMatchDataId, "deaths", deaths );
println( "Scoreboard: [" + self.name + "(" + self.clientMatchDataId + ")][deaths]: " + deaths );
checkpoints = self getPlayerStat( "checkpoints" );
setClientMatchData( "players", self.clientMatchDataId, "checkpoints", checkpoints );
println( "Scoreboard: [" + self.name + "(" + self.clientMatchDataId + ")][checkpoints]: " + checkpoints );
team = self.pers["team"];
setClientMatchData( "players", self.clientMatchDataId, "team", team );
println( "Scoreboard: [" + self.name + "(" + self.clientMatchDataId + ")][team]: " + team );
faction = game[self.pers["team"]];
setClientMatchData( "players", self.clientMatchDataId, "faction", faction );
println( "Scoreboard: [" + self.name + "(" + self.clientMatchDataId + ")][faction]: " + faction );
println( "Scoreboard: scoreboardPlayerCount was " + scoreboardPlayerCount );
scoreboardPlayerCount++;
setClientMatchData( "scoreboardPlayerCount", scoreboardPlayerCount );
println( "Scoreboard: scoreboardPlayerCount now " + scoreboardPlayerCount );
}
else
{
println( "Scoreboard: scoreboardPlayerCount is greater than 24 (" + scoreboardPlayerCount + ")" );
}
}
buildScoreboardType( team )
{
assert( team == "allies" || team == "axis" || team == "neutral" || team == "multiteam" );
println( "Scoreboard: Building scoreboard (" + team + ")" );
if ( team == "multiteam" )
{
index = 0;
foreach( teamname in level._teamNameList )
{
foreach ( player in level._placement[teamname] )
{
setClientMatchData( "scoreboards", "multiteam", index, player.clientMatchDataId );
println( "Scoreboard: [scoreboards][" + team + "][" + index + "][" + player.clientMatchDataId + "]" );
index++;
}
}
}
else if ( team == "neutral" )
{
index = 0;
foreach ( player in level._placement["all"] )
{
setClientMatchData( "scoreboards", team, index, player.clientMatchDataId );
println( "Scoreboard: [scoreboards][" + team + "][" + index + "][" + player.clientMatchDataId + "]" );
index++;
}
}
else
{
otherTeam = getOtherTeam( team );
index = 0;
foreach ( player in level._placement[team] )
{
setClientMatchData( "scoreboards", team, index, player.clientMatchDataId );
println( "Scoreboard: [scoreboards][" + team + "][" + index + "][" + player.name + "(" + player.clientMatchDataId + ")]" );
index++;
}
foreach ( player in level._placement[otherTeam] )
{
setClientMatchData( "scoreboards", team, index, player.clientMatchDataId );
println( "Scoreboard: [scoreboards][" + team + "][" + index + "][" + player.name + "(" + player.clientMatchDataId + ")]" );
index++;
}
}
}

179
maps/mp/_shutter.gsc Normal file
View File

@ -0,0 +1,179 @@
#include common_scripts\utility;
#include maps\mp\_utility;
main()
{
// thread windController();
level._inc = 0;
array_levelthread (getentarray("wire","targetname"), ::wireWander);
leftShutters = getentarray ("shutter_left","targetname");
addShutters = getentarray ("shutter_right_open","targetname");
for (i=0;i<addShutters.size;i++)
leftShutters[leftShutters.size] = addShutters[i];
addShutters = getentarray ("shutter_left_closed","targetname");
for (i=0;i<addShutters.size;i++)
leftShutters[leftShutters.size] = addShutters[i];
for (i=0;i<leftShutters.size;i++)
{
shutter = leftShutters[i];
shutter rotateto((shutter.angles[0], shutter.angles[1] + 180, shutter.angles[2]), 0.1);
}
wait (0.2);
for (i=0;i<leftShutters.size;i++)
leftShutters[i].startYaw = leftShutters[i].angles[1];
rightShutters = getentarray ("shutter_right","targetname");
addShutters = getentarray ("shutter_left_open","targetname");
for (i=0;i<addShutters.size;i++)
rightShutters[rightShutters.size] = addShutters[i];
addShutters = getentarray ("shutter_right_closed","targetname");
for (i=0;i<addShutters.size;i++)
rightShutters[rightShutters.size] = addShutters[i];
for (i=0;i<rightShutters.size;i++)
rightShutters[i].startYaw = rightShutters[i].angles[1];
addShutters = undefined;
windDirection = "left";
for (;;)
{
array_levelthread (leftShutters, ::shutterWanderLeft, windDirection);
array_levelthread (rightShutters, ::shutterWanderRight, windDirection);
level waittill ("wind blows", windDirection);
}
}
windController()
{
for (;;)
{
windDirection = "left";
if (randomint(100) > 50)
windDirection = "right";
level notify ("wind blows", windDirection);
wait (2 + randomfloat(10));
}
}
shutterWanderLeft(shutter, windDirection)
{
// println ("shutter angles ", shutter.angles[1]);
// assert (shutter.angles[1] >= shutter.startYaw);
// assert (shutter.angles[1] < shutter.startYaw + 180);
// println ("Wind + ", level.inc);
level._inc++;
level endon ("wind blows");
newYaw = shutter.startYaw;
if (windDirection == "left")
newYaw += 179.9;
newTime = 0.2;
shutter rotateto((shutter.angles[0], newYaw, shutter.angles[2]), newTime);
wait (newTime + 0.1);
for (;;)
{
rot = randomint(80);
if (randomint(100) > 50)
rot *= -1;
newYaw = shutter.angles[1] + rot;
altYaw = shutter.angles[1] + (rot*-1);
if ((newYaw < shutter.startYaw) || (newYaw > shutter.startYaw + 179))
{
newYaw = altYaw;
}
dif = abs(shutter.angles[1] - newYaw);
newTime = dif*0.02 + randomfloat(2);
if (newTime < 0.3)
newTime = 0.3;
// println ("startyaw " + shutter.startyaw + " newyaw " + newYaw);
// assert (newYaw >= shutter.startYaw);
// assert (newYaw < shutter.startYaw + 179);
shutter rotateto((shutter.angles[0], newYaw, shutter.angles[2]), newTime, newTime * 0.5, newTime * 0.5);
wait (newTime);
}
}
shutterWanderRight(shutter, windDirection)
{
// println ("shutter angles ", shutter.angles[1]);
// assert (shutter.angles[1] >= shutter.startYaw);
// assert (shutter.angles[1] < shutter.startYaw + 180);
// println ("Wind + ", level.inc);
level._inc++;
level endon ("wind blows");
newYaw = shutter.startYaw;
if (windDirection == "left")
newYaw += 179.9;
newTime = 0.2;
shutter rotateto((shutter.angles[0], newYaw, shutter.angles[2]), newTime);
wait (newTime + 0.1);
for (;;)
{
rot = randomint(80);
if (randomint(100) > 50)
rot *= -1;
newYaw = shutter.angles[1] + rot;
altYaw = shutter.angles[1] + (rot*-1);
if ((newYaw < shutter.startYaw) || (newYaw > shutter.startYaw + 179))
{
newYaw = altYaw;
}
dif = abs(shutter.angles[1] - newYaw);
newTime = dif*0.02 + randomfloat(2);
if (newTime < 0.3)
newTime = 0.3;
// println ("startyaw " + shutter.startyaw + " newyaw " + newYaw);
// assert (newYaw >= shutter.startYaw);
// assert (newYaw < shutter.startYaw + 179);
shutter rotateto((shutter.angles[0], newYaw, shutter.angles[2]), newTime, newTime * 0.5, newTime * 0.5);
wait (newTime);
}
}
wireWander (wire)
{
origins = getentarray (wire.target,"targetname");
org1 = origins[0].origin;
org2 = origins[1].origin;
angles = vectortoangles (org1 - org2);
ent = spawn ("script_model",(0,0,0));
ent.origin = vector_multiply(org1, 0.5) + vector_multiply(org2, 0.5);
// ent setmodel ("temp");
ent.angles = angles;
wire linkto (ent);
rottimer = 2;
rotrange = 0.9;
dist = 4 + randomfloat(2);
ent rotateroll(dist*0.5,0.2);
wait (0.2);
for (;;)
{
rottime = rottimer + randomfloat (rotRange) - (rotRange * 0.5);
ent rotateroll(dist,rottime, rottime*0.5, rottime*0.5);
wait (rottime);
ent rotateroll(dist * -1,rottime, rottime*0.5, rottime*0.5);
wait (rottime);
}
}

71
maps/mp/_skill.gsc Normal file
View File

@ -0,0 +1,71 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
level thread onPlayerConnect();
level thread onPlayerDisconnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
// look at how spawning works
player.connectTime = getTime();
player.targets = [];
player thread onWeaponFired();
player thread onDeath();
}
}
onPlayerDisconnect()
{
for(;;)
{
level waittill( "disconnected", player );
player.targets = [];
}
}
onWeaponFired()
{
level endon( "game_ended" );
self endon( "disconnected" );
for ( ;; )
{
self waittill( "weapon_fired" );
// find likely target
// find target and tag when they shot me.
//self.target
}
}
onDeath()
{
level endon( "game_ended" );
self endon( "disconnected" );
for ( ;; )
{
self waittill( "death" );
//
// find target and tag when they shot me.
//self.target
}
}
processKill( attacker, defender )
{
updateSkill( attacker, defender, "tdm", 1.0 );
}

419
maps/mp/_stinger.gsc Normal file
View File

@ -0,0 +1,419 @@
#include maps\mp\_utility;
InitStingerUsage()
{
self.stingerStage = undefined;
self.stingerTarget = undefined;
self.stingerLockStartTime = undefined;
self.stingerLostSightlineTime = undefined;
self thread ResetStingerLockingOnDeath();
level._stingerTargets = [];
}
ResetStingerLocking()
{
if ( !IsDefined( self.stingerUseEntered ) )
return;
self.stingerUseEntered = undefined;
self notify( "stop_javelin_locking_feedback" );
self notify( "stop_javelin_locked_feedback" );
self WeaponLockFree();
InitStingerUsage();
}
ResetStingerLockingOnDeath()
{
self endon( "disconnect" );
self notify ( "ResetStingerLockingOnDeath" );
self endon ( "ResetStingerLockingOnDeath" );
for ( ;; )
{
self waittill( "death" );
self ResetStingerLocking();
}
}
StillValidStingerLock( ent )
{
assert( IsDefined( self ) );
if ( !IsDefined( ent ) )
return false;
if ( !(self WorldPointInReticle_Circle( ent.origin, 65, 85 )) )
return false;
if ( self.stingerTarget == level._ac130.planeModel && !isDefined( level._ac130player ) )
return false;
return true;
}
LoopStingerLockingFeedback()
{
self endon( "stop_javelin_locking_feedback" );
for ( ;; )
{
if ( isDefined( level._chopper ) && isDefined( level._chopper.gunner ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._chopper.gunner )
level._chopper.gunner playLocalSound( "missile_locking" );
if ( isDefined( level._ac130player ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._ac130.planeModel )
level._ac130player playLocalSound( "missile_locking" );
self playLocalSound( "stinger_locking" );
self PlayRumbleOnEntity( "ac130_25mm_fire" );
wait 0.6;
}
}
LoopStingerLockedFeedback()
{
self endon( "stop_javelin_locked_feedback" );
for ( ;; )
{
if ( isDefined( level._chopper ) && isDefined( level._chopper.gunner ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._chopper.gunner )
level._chopper.gunner playLocalSound( "missile_locking" );
if ( isDefined( level._ac130player ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._ac130.planeModel )
level._ac130player playLocalSound( "missile_locking" );
self playLocalSound( "stinger_locked" );
self PlayRumbleOnEntity( "ac130_25mm_fire" );
wait 0.25;
}
}
/#
DrawStar( point )
{
Line( point + (10,0,0), point - (10,0,0) );
Line( point + (0,10,0), point - (0,10,0) );
Line( point + (0,0,10), point - (0,0,10) );
}
#/
LockSightTest( target )
{
eyePos = self GetEye();
if ( !isDefined( target ) ) //targets can disapear during targeting.
return false;
passed = BulletTracePassed( eyePos, target.origin, false, target );
if ( passed )
return true;
front = target GetPointInBounds( 1, 0, 0 );
passed = BulletTracePassed( eyePos, front, false, target );
if ( passed )
return true;
back = target GetPointInBounds( -1, 0, 0 );
passed = BulletTracePassed( eyePos, back, false, target );
if ( passed )
return true;
return false;
}
StingerDebugDraw( target )
{
/#
if ( GetDVar( "missileDebugDraw" ) != "1" )
return;
if ( !IsDefined( target ) )
return;
org = target.origin;
DrawStar( org );
org = target GetPointInBounds( 1, 0, 0 );
DrawStar( org );
org = target GetPointInBounds( -1, 0, 0 );
DrawStar( org );
#/
}
SoftSightTest()
{
LOST_SIGHT_LIMIT = 500;
if ( self LockSightTest( self.stingerTarget ) )
{
self.stingerLostSightlineTime = 0;
return true;
}
if ( self.stingerLostSightlineTime == 0 )
self.stingerLostSightlineTime = getTime();
timePassed = GetTime() - self.stingerLostSightlineTime;
//PrintLn( "Losing sight of target [", timePassed, "]..." );
if ( timePassed >= LOST_SIGHT_LIMIT )
{
//PrintLn( "Lost sight of target." );
ResetStingerLocking();
return false;
}
return true;
}
GetTargetList()
{
targets = [];
if ( level._teamBased )
{
if ( IsDefined( level._chopper ) && ( level._chopper.team != self.team || level._chopper.owner == self ) )
targets[targets.size] = level._chopper;
if ( IsDefined( level._raven ) && ( level._raven.team != self.team || level._raven.owner == self ) )
targets[targets.size] = level._raven;
if ( isDefined( level._ac130player ) && level._ac130player.team != self.team )
targets[targets.size] = level._ac130.planemodel;
if ( isDefined( level._harriers) )
{
foreach( harrier in level._harriers )
{
if ( isDefined( harrier ) && ( harrier.team != self.team || ( isDefined( harrier.owner ) && harrier.owner == self ) ) )
targets[targets.size] = harrier;
}
}
foreach( target_player in level._players )
{
if (( target_player.team != self.team ) && (target_player _hasPerk("specialty_juggersuit")))
{
targets[targets.size] = target_player;
}
}
if( level._multiTeamBased )
{
//for all teams
for( i = 0; i < level._teamNameList.size; i++ )
{
//that are not our team
if( self.team != level._teamNameList[i] )
{
//does that team have any uav's
if( level._UAVModels[level._teamNameList[i]].size )
{
//add each uav to the target list
foreach ( UAV in level._UAVModels[level._teamNameList[i]] )
{
targets[targets.size] = UAV;
}
}
}
}
}
else if ( level._UAVModels[level._otherTeam[self.team]].size )
{
foreach ( UAV in level._UAVModels[level._otherTeam[self.team]] )
targets[targets.size] = UAV;
}
if ( isDefined( level._littleBird ) )
{
foreach ( bird in level._littleBird )
{
if ( !isDefined( bird ) )
continue;
if ( self.team != bird.owner.team || self == bird.owner )
targets[targets.size] = bird;
}
}
}
else
{
if ( IsDefined( level._chopper ) && ( level._chopper.owner != self ) ) ///check for teams
targets[targets.size] = level._chopper;
if ( isDefined( level._ac130player ) )
targets[targets.size] = level._ac130.planemodel;
if ( isDefined( level._harriers) )
{
foreach( harrier in level._harriers )
{
if ( isDefined( harrier ) )
targets[targets.size] = harrier;
}
}
foreach( target_player in level._players )
{
if (( target_player != self ) && (target_player _hasPerk("specialty_juggersuit")))
{
targets[targets.size] = target_player;
}
}
if ( level._UAVModels.size )
{
foreach ( ownerGuid, UAV in level._UAVModels )
{
if ( isDefined( UAV.owner ) && UAV.owner == self )
continue;
targets[targets.size] = UAV;
}
}
}
return targets;
}
StingerUsageLoop()
{
self endon("death");
self endon("disconnect");
LOCK_LENGTH = 1000;
InitStingerUsage();
for( ;; )
{
wait 0.05;
weapon = self getCurrentWeapon();
if ( weapon != "stinger_mp" && weapon != "at4_mp" )
{
ResetStingerLocking();
continue;
}
if ( self PlayerADS() < 0.95 )
{
ResetStingerLocking();
continue;
}
self.stingerUseEntered = true;
if ( !IsDefined( self.stingerStage ) )
self.stingerStage = 0;
StingerDebugDraw( self.stingerTarget );
if ( self.stingerStage == 0 ) // searching for target
{
targets = GetTargetList();
if ( targets.size == 0 )
continue;
targetsInReticle = [];
foreach ( target in targets )
{
if ( !isDefined( target ) )
continue;
insideReticle = self WorldPointInReticle_Circle( target.origin, 65, 75 );
if ( insideReticle )
targetsInReticle[targetsInReticle.size] = target;
}
if ( targetsInReticle.size == 0 )
continue;
sortedTargets = SortByDistance( targetsInReticle, self.origin );
if ( !( self LockSightTest( sortedTargets[0] ) ) )
continue;
//PrintLn( "Found a target to lock to..." );
thread LoopStingerLockingFeedback();
self.stingerTarget = sortedTargets[0];
self.stingerLockStartTime = GetTime();
self.stingerStage = 1;
self.stingerLostSightlineTime = 0;
}
if ( self.stingerStage == 1 ) // locking on to a target
{
if ( !(self StillValidStingerLock( self.stingerTarget )) )
{
//PrintLn( "Failed to get lock." );
ResetStingerLocking();
continue;
}
passed = SoftSightTest();
if ( !passed )
continue;
timePassed = getTime() - self.stingerLockStartTime;
//PrintLn( "Locking [", timePassed, "]..." );
if( self _hasPerk( "specialty_fasterlockon" ))
{
if( timePassed < ( LOCK_LENGTH * 0.5 ))
{
continue;
}
}
else
{
if ( timePassed < LOCK_LENGTH )
continue;
}
self notify( "stop_javelin_locking_feedback" );
thread LoopStingerLockedFeedback();
//PrintLn( "Locked!");
if ( self.stingerTarget.model == "vehicle_av8b_harrier_jet_mp" || self.stingerTarget.model == "vehicle_little_bird_armed" )
{
self WeaponLockFinalize( self.stingerTarget );
}
else if ( IsPlayer( self.stingerTarget ) )
{
self WeaponLockFinalize( self.stingerTarget, (0,0,32) );
}
else
{
self WeaponLockFinalize( self.stingerTarget, (100,0,-32) );
}
self.stingerStage = 2;
}
if ( self.stingerStage == 2 ) // target locked
{
passed = SoftSightTest();
if ( !passed )
continue;
if ( !(self StillValidStingerLock( self.stingerTarget )) )
{
//PrintLn( "Gave up lock." );
ResetStingerLocking();
continue;
}
}
}
}

745
maps/mp/_upgrade.gsc Normal file
View File

@ -0,0 +1,745 @@
//****************************************************************************
// **
// Confidential - (C) Activision Publishing, Inc. 2010 **
// **
//****************************************************************************
// **
// Module: The Combat Awareness Upgrade System **
// (1) Players are displayed with Earned Strike Points (ESP) **
// while alive. **
// (2) The ESP will increment when a new killstreak is earned. **
// (3) If enough ESP is earned, players will be presented with **
// options that they can spend the earned ESP. **
// (4) If spending occurs, the ESP counters as well as players' **
// killstreak queue will be adjusted accordingly. **
// **
// This script is organized into four major components: **
// **
// Components **
// ------------------------------------------------------------------- **
// initialization functions **
// major logic functions **
// HUD element functions **
// helper functions **
// **
// Created: September 21st, 2011 - James Chen **
// **
//***************************************************************************/
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
//*******************************************************************
// Beginning of initialization functions *
// *
//*******************************************************************
KILLSTREAK_STRING_TABLE = "mp/killstreakTable.csv";
//tagJC<NOTE>: The beginning branching function. Use the dvar "upgradeEnabling" to decide whether the upgrade is enabled for the level
init()
{
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
println( "Upgrade: Enabled" );
initUpgrade();
level thread onPlayerConnect();
}
else
{
println ( "Upgrade: Disabled" );
level thread onPlayerConnectNoUpGrade();
}
}
//tagJC<NOTE>: Initialize the award types and precache all the necessary assets
initUpgrade()
{
level._upgrade = undefined;
//tagJC<NOTE>: Initialize the award types
//addUpgradeType ( "threatID", 15, ::activateThreatID, false );
addUpgradeType ( "attackHelicopter", 9, ::giveAttackHelicopter, false );
addUpgradeType ( "lightWeight", 12, ::activateExtraLightWeight, true );
addUpgradeType ( "chopperGunner", 15, ::giveChopperGunner, false );
precacheString ( &"MP_A_BUTTON" );
precacheString ( &"MP_B_BUTTON" );
precacheString ( &"MP_Y_BUTTON" );
precacheString ( &"MP_ESP" );
for ( i = 1; true; i++ )
{
retVal = tableLookup( KILLSTREAK_STRING_TABLE, 0, i, 1 );
if ( !isDefined( retVal ) || retVal == "" )
break;
streakRef = tableLookupIString( KILLSTREAK_STRING_TABLE, 0, i, 2 );
assert( streakRef != &"" );
precacheString( streakRef );
}
}
//tagJC<NOTE>: Build and add the upgrade types
addUpgradeType( name, requiredPoints, activationFunc, reactivateWhenSpawn )
{
level._upgradeDefs[name]["requiredPoints"] = requiredPoints;
level._upgradeDefs[name]["activationFunc"] = activationFunc;
level._upgradeDefs[name]["reactivateWhenSpawn"] = reactivateWhenSpawn;
}
//tagJC<NOTE>: The call-back function for the threadID
//tagJC<NOTE>: Self is the player
activateThreatID()
{
self ThermalVisionFOFOverlayOn();
}
//tagJC<NOTE>: The call-back function for the extra light weight
//tagJC<NOTE>: Self is the player
activateExtraLightWeight()
{
self.moveSpeedScaler = 1.30;
self maps\mp\gametypes\_weapons::updateMoveSpeedScale( "primary" );
}
//tagJC<NOTE>: The call-back function for giving the attacker helicopter. Since the killstreak is given on the button press during killcam, no action is necessary when player spawns
giveAttackHelicopter()
{
}
//tagJC<NOTE>: The call-back function for giving the chopper gunner. Since the killstreak is given on the button press during killcam, no action is necessary when player spawns
giveChopperGunner()
{
}
//tagJC<NOTE>: Initialize all the data necessary on player connect
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player.earnedStrikePoints = 0;
player createESPCounter();
player.acquiredUpgrades = [];
player thread onPlayerSpawned();
player.upgradeList["switchWeap"] = "chopperGunner";
player.killstreakToRemove["switchWeap"] = [];
player.upgradeList["prone"] = "lightWeight";
player.killstreakToRemove["prone"] = [];
player.upgradeList["jump"] = "attackHelicopter";
player.killstreakToRemove["jump"] = [];
}
}
//tagJC<NOTE>: In order to wait for the button presses for Y and B during killcam, the following two member data is necessary.
onPlayerConnectNoUpGrade()
{
for(;;)
{
level waittill( "connected", player );
player.YbuttonPressedDuringKillCam = false;
player.BbuttonPressedDuringKillCam = false;
}
}
//tagJC<NOTE>: The call-back function for when player spawns
//tagJC<NOTE>: Self is the player
onPlayerSpawned()
{
self endon( "disconnect" );
for(;;)
{
self waittill( "spawned_player" );
self thread waitForChangeTeam();
self.YbuttonPressedDuringKillCam = false;
self.BbuttonPressedDuringKillCam = false;
if ( isDefined ( self.ESPCounter_a ))
{
self.ESPCounter_a.alpha = 1;
}
if ( isDefined ( self.ESPCounter_b ))
{
self.ESPCounter_b.alpha = 1;
}
//tagJC<NOTE>: If there is anything in the player's acquired upgrade list, reactivate the effects
for ( i = 0; i < self.acquiredUpgrades.size; i++ )
{
upgradeName = self.acquiredUpgrades[i];
if (( isDefined (level._upgradeDefs[upgradeName]["reactivateWhenSpawn"])) && (level._upgradeDefs[upgradeName]["reactivateWhenSpawn"] == true ))
{
self [[level._upgradeDefs[upgradename]["activationFunc"]]]();
}
}
}
}
//tagJC<NOTE>: Thread running on players for team changes
//tagJC<NOTE>: Self is the player
waitForChangeTeam()
{
self endon ( "disconnect" );
self notify ( "waitForChangeTeam" );
self endon ( "waitForChangeTeam" );
for ( ;; )
{
self waittill ( "joined_team" );
self.earnedStrikePoints = 0;
}
}
//*******************************************************************
// End of initialization functions *
// Beginning of main logic functions *
//*******************************************************************
//tagJC<NOTE>: Based on the point values passed in, this function remove earned killstreak from player's killstreak until enough points are cumulated.
//tagJC<NOTE>: Self is the player
removeKillstreakToGetUpgrade ( earnedStrikePointLimit )
{
earnedStrikePoints = 0;
removeCounter = 0;
size = self.pers["killstreaks"].size;
foreach ( index, streakStruct in self.pers["killstreaks"] )
{
earnedStrikePoints += streakStruct.strikePoints;
self.pers["killstreaks"][index] = undefined;
removeCounter += 1;
if ( earnedStrikePoints >= earnedStrikePointLimit )
{
break;
}
}
streakRemain = size - removeCounter;
for ( i = 0; i < size ; i++ )
{
if ( i <= ( streakRemain - 1 ))
{
self.pers["killstreaks"][i] = self.pers["killstreaks"][i + removeCounter];
}
else
{
self.pers["killstreaks"][i] = undefined;
}
}
self.earnedStrikePoints = 0;
for ( i = 0; i < self.pers["killstreaks"].size; i++ )
{
self.earnedStrikePoints += self.pers["killstreaks"][i].strikePoints;
}
self updateESPNumber();
}
//tagJC<NOTE>: This function is called during player's killcam and process the upgrade selection accordingly. Currently, given
// the players killstreak is hard-coded. In the future, if such selection is desirable, a more generic approach
// will be implemented by then.
//tagJC<NOTE>: Self is the player
processUpgradeSelections()
{
if (( self.killCamButtonPressed == "jump") && ( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["jump"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["jump"] )))
{
self.acquiredUpgrades[self.acquiredUpgrades.size] = self.upgradeList["jump"];
self removeKillstreakToGetUpgrade( level._upgradeDefs[self.upgradeList["jump"]]["requiredPoints"]);
self thread maps\mp\killstreaks\_killstreaks::giveKillstreak( "helicopter", false, false, self, true );
}
else if (( self.killCamButtonPressed == "prone") && ( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["prone"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["prone"] )))
{
self.acquiredUpgrades[self.acquiredUpgrades.size] = self.upgradeList["prone"];
self removeKillstreakToGetUpgrade( level._upgradeDefs[self.upgradeList["prone"]]["requiredPoints"]);
}
else if (( self.killCamButtonPressed == "switchWeap") && ( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["switchWeap"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["switchWeap"] )))
{
self.acquiredUpgrades[self.acquiredUpgrades.size] = self.upgradeList["switchWeap"];
self removeKillstreakToGetUpgrade( level._upgradeDefs[self.upgradeList["switchWeap"]]["requiredPoints"]);
self thread maps\mp\killstreaks\_killstreaks::giveKillstreak( "helicopter_minigun", false, false, self, true );
}
}
//*******************************************************************
// End of main logic functions *
// Beginning of HUD element functions *
//*******************************************************************
//tagJC<NOTE>: Creating the A, B, and Y buttons that will be shown during the killcam
//tagJC<NOTE>: Self is the player
initUpgradeElements()
{
if ( !isDefined( self.kc_A_button ) )
{
self.kc_A_button = newClientHudElem(self);
self.kc_A_button.label = &"MP_A_BUTTON";
self.kc_A_button.archived = false;
self.kc_A_button.x = 0;
self.kc_A_button.alignX = "left";
self.kc_A_button.alignY = "middle";
self.kc_A_button.horzAlign = "left";
self.kc_A_button.vertAlign = "middle";
self.kc_A_button.sort = 1; // force to draw after the bars
self.kc_A_button.font = "default";
self.kc_A_button.foreground = true;
self.kc_A_button.hideWhenInMenu = true;
self.kc_A_button.alpha = 0;
self.kc_A_button.color = ( 0, 1, 0 );
if ( level._splitscreen )
{
self.kc_A_button.y = 20;
self.kc_A_button.fontscale = 1.2; // 1.8/1.5
}
else
{
self.kc_A_button.y = 32;
self.kc_A_button.fontscale = 1.8;
}
}
if ( !isDefined( self.kc_B_button ) )
{
self.kc_B_button = newClientHudElem(self);
self.kc_B_button.label = &"MP_B_BUTTON";
self.kc_B_button.archived = false;
self.kc_B_button.x = 160;
self.kc_B_button.alignX = "left";
self.kc_B_button.alignY = "top";
self.kc_B_button.horzAlign = "left";
self.kc_B_button.vertAlign = "top";
self.kc_B_button.sort = 1; // force to draw after the bars
self.kc_B_button.font = "default";
self.kc_B_button.foreground = true;
self.kc_B_button.hideWhenInMenu = true;
self.kc_B_button.alpha = 0;
self.kc_B_button.color = ( 0, 1, 0 );
if ( level._splitscreen )
{
self.kc_B_button.y = 20;
self.kc_B_button.fontscale = 1.2; // 1.8/1.5
}
else
{
self.kc_B_button.y = 128;
self.kc_B_button.fontscale = 1.8;
}
}
if ( !isDefined( self.kc_Y_button ) )
{
self.kc_Y_button = newClientHudElem(self);
self.kc_Y_button.label = &"MP_Y_BUTTON";
self.kc_Y_button.archived = false;
self.kc_Y_button.x = 0;
self.kc_Y_button.alignX = "left";
self.kc_Y_button.alignY = "top";
self.kc_Y_button.horzAlign = "left";
self.kc_Y_button.vertAlign = "top";
self.kc_Y_button.sort = 1; // force to draw after the bars
self.kc_Y_button.font = "default";
self.kc_Y_button.foreground = true;
self.kc_Y_button.hideWhenInMenu = true;
self.kc_Y_button.alpha = 0;
self.kc_Y_button.color = ( 0, 1, 0 );
if ( level._splitscreen )
{
self.kc_Y_button.y = 20;
self.kc_Y_button.fontscale = 1.2; // 1.8/1.5
}
else
{
self.kc_Y_button.y = 0;
self.kc_Y_button.fontscale = 1.8;
}
}
}
//tagJC<NOTE>: This function displays the killstreak icons and names that the player is about to lose when making the upgrade
//tagJC<NOTE>: Self is the player
showRemovedKillstreaks ( pointRequirement, buttonAssignment )
{
earnedStrikePoints = 0;
removeCounter = 0;
foreach ( index, streakStruct in self.pers["killstreaks"] )
{
earnedStrikePoints += streakStruct.strikePoints;
removeCounter += 1;
if ( earnedStrikePoints >= pointRequirement )
{
break;
}
}
if ( !(isDefined ( self.killstreakToRemove[buttonAssignment] )))
{
self.killstreakToRemove[buttonAssignment] = [];
}
for ( i = 0; i < removeCounter; i++)
{
self.killstreakToRemove[buttonAssignment][i] = showKillstreakIcon ( self.pers["killstreaks"][i].streakName, buttonAssignment, i * 0, i * 25 );
self.killstreakToRemove[buttonAssignment][i+removeCounter] = showKillstreakName ( self.pers["killstreaks"][i].streakName, buttonAssignment, i * 0, i * 25 );
}
}
//tagJC<NOTE>: This function returns a HUD element for the killstreak icons
//tagJC<NOTE>: Self is the player
showKillstreakIcon ( streakName, buttonAssignment, xOffset, yOffset )
{
iconName = getKillstreakIcon (streakName );
real_yOffset = 32;
if ( buttonAssignment == "prone" )
{
real_yOffset = 128;
}
else if ( buttonAssignment == "switchWeap" )
{
real_yOffset = 0;
}
real_yOffset += 30;
real_yOffset += yOffset;
xValue = 0;
if ( buttonAssignment == "prone" )
{
xValue = 160;
}
xValue += xOffset;
alignYValue = "top";
if ( buttonAssignment == "jump" )
{
alignYValue = "middle";
}
vertAlignValue = "top";
if ( buttonAssignment == "jump" )
{
vertAlignValue = "middle";
}
killstreakIcon = newClientHudElem(self);
killstreakIcon setShader ( iconName );
killstreakIcon.archived = false;
killstreakIcon.x = xValue;
killstreakIcon.alignX = "left";
killstreakIcon.alignY = alignYValue;
killstreakIcon.horzAlign = "left";
killstreakIcon.vertAlign = vertAlignValue;
killstreakIcon.sort = 1; // force to draw after the bars
killstreakIcon.font = "default";
killstreakIcon.foreground = true;
killstreakIcon.hideWhenInMenu = true;
killstreakIcon.alpha = 1;
//killstreakIcon.color = ( 0, 1, 0 );
if ( level._splitscreen )
{
killstreakIcon.y = real_yOffset + 20;
killstreakIcon.fontscale = 1.2; // 1.8/1.5
}
else
{
killstreakIcon.y = real_yOffset;
killstreakIcon.fontscale = 1.8;
}
return killstreakIcon;
}
//tagJC<NOTE>: This function returns a HUD element for the killstreak names
//tagJC<NOTE>: Self is the player
showKillstreakName ( streakName, buttonAssignment, xOffset, yOffset )
{
iconName = getKillstreakIcon (streakName );
real_yOffset = 32;
if ( buttonAssignment == "prone" )
{
real_yOffset = 128;
}
else if ( buttonAssignment == "switchWeap" )
{
real_yOffset = 0;
}
real_yOffset += 30;
real_yOffset += yOffset;
xValue = 0;
if ( buttonAssignment == "prone" )
{
xValue = 160;
}
xValue += xOffset;
alignYValue = "top";
if ( buttonAssignment == "jump" )
{
alignYValue = "middle";
}
vertAlignValue = "top";
if ( buttonAssignment == "jump" )
{
vertAlignValue = "middle";
}
killstreakIcon = CreateFontString( "objective", 1.25 );;
killstreakIcon SetText( getKillstreakUserFriendlyName ( streakName ));
killstreakIcon.archived = false;
killstreakIcon.x = xValue + 20;
killstreakIcon.alignX = "left";
killstreakIcon.alignY = alignYValue;
killstreakIcon.horzAlign = "left";
killstreakIcon.vertAlign = vertAlignValue;
killstreakIcon.sort = 1; // force to draw after the bars
killstreakIcon.font = "default";
killstreakIcon.foreground = true;
killstreakIcon.hideWhenInMenu = true;
killstreakIcon.alpha = 1;
//killstreakIcon.color = ( 0, 1, 0 );
if ( level._splitscreen )
{
killstreakIcon.y = real_yOffset + 20;
killstreakIcon.fontscale = 1.5; // 1.8/1.5
}
else
{
killstreakIcon.y = real_yOffset;
killstreakIcon.fontscale = 1.5;
}
return killstreakIcon;
}
//tagJC<NOTE>: The ESP counter is displayed while the player is alive
//tagJC<NOTE>: Self is the player
createESPCounter()
{
if ( !isDefined( self.ESPCounter_a ) )
{
self.ESPCounter_a = newClientHudElem(self);
self.ESPCounter_a.label = &"MP_ESP";
self.ESPCounter_a.archived = false;
self.ESPCounter_a.x = 0;
self.ESPCounter_a.alignX = "left";
self.ESPCounter_a.alignY = "top";
self.ESPCounter_a.horzAlign = "left";
self.ESPCounter_a.vertAlign = "top";
self.ESPCounter_a.sort = 1; // force to draw after the bars
self.ESPCounter_a.font = "default";
self.ESPCounter_a.foreground = true;
self.ESPCounter_a.hideWhenInMenu = true;
self.ESPCounter_a.alpha = 1;
self.ESPCounter_a.color = ( 0, 1, 0 );
if ( level._splitscreen )
{
self.ESPCounter_a.y = 20;
self.ESPCounter_a.fontscale = 1.2; // 1.8/1.5
}
else
{
self.ESPCounter_a.y = 100;
self.ESPCounter_a.fontscale = 1.8;
}
}
if ( !isDefined( self.ESPCounter_b ) )
{
self.ESPCounter_b = CreateFontString( "objective", 1.25 );;
self.ESPCounter_b SetText( "" + self.earnedStrikePoints );
self.ESPCounter_b.archived = false;
self.ESPCounter_b.x = 40;
self.ESPCounter_b.alignX = "left";
self.ESPCounter_b.alignY = "top";
self.ESPCounter_b.horzAlign = "left";
self.ESPCounter_b.vertAlign = "top";
self.ESPCounter_b.sort = 1; // force to draw after the bars
self.ESPCounter_b.font = "default";
self.ESPCounter_b.foreground = true;
self.ESPCounter_b.hideWhenInMenu = true;
self.ESPCounter_b.alpha = 1;
self.ESPCounter_b.color = ( 0, 1, 0 );
if ( level._splitscreen )
{
self.ESPCounter_b.y = 20;
self.ESPCounter_b.fontscale = 1.2; // 1.8/1.5
}
else
{
self.ESPCounter_b.y = 100;
self.ESPCounter_b.fontscale = 1.8;
}
}
}
//tagJC<NOTE>: This function is called at the beginning of the killcam, it will display all the HUD elements depending on the
// ESP earning situation.
//tagJC<NOTE>: Self is the player
showUpgradeHUDElement()
{
if ( isDefined ( self.ESPCounter_a ))
{
self.ESPCounter_a.alpha = 0;
}
if ( isDefined ( self.ESPCounter_b ))
{
self.ESPCounter_b.alpha = 0;
}
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["jump"]]["requiredPoints"] )
&& !( hasUpgrade(self, self.upgradeList["jump"] )))
{
if ( isDefined( self.kc_A_button ))
{
self.kc_A_button.alpha = 1;
}
self showRemovedKillstreaks ( level._upgradeDefs[self.upgradeList["jump"]]["requiredPoints"], "jump" );
}
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["prone"]]["requiredPoints"] )
&& !( hasUpgrade(self, self.upgradeList["prone"] )))
{
if ( isDefined( self.kc_B_button ))
{
self.kc_B_button.alpha = 1;
}
self showRemovedKillstreaks ( level._upgradeDefs[self.upgradeList["prone"]]["requiredPoints"], "prone" );
}
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["switchWeap"]]["requiredPoints"] )
&& !( hasUpgrade(self, self.upgradeList["switchWeap"] )))
{
if ( isDefined( self.kc_Y_button ))
{
self.kc_Y_button.alpha = 1;
}
self showRemovedKillstreaks ( level._upgradeDefs[self.upgradeList["switchWeap"]]["requiredPoints"], "switchWeap" );
}
}
//tagJC<NOTE>: Updating the numerical value for the ESP counter.
//tagJC<NOTE>: Self is the player
updateESPNumber()
{
if ( isDefined( self.ESPCounter_b ) )
{
self.ESPCounter_b SetText( "" + self.earnedStrikePoints );
}
}
//tagJC<NOTE>: Clean up all the upgrade related HUD elements once the killcam is complete.
//tagJC<NOTE>: Self is the player
upgradeHUDCleanUp()
{
if ( isDefined( self.kc_A_button ))
self.kc_A_button.alpha = 0;
if ( isDefined( self.kc_B_button ))
self.kc_B_button.alpha = 0;
if ( isDefined( self.kc_Y_button ))
self.kc_Y_button.alpha = 0;
if ( isDefined( self.killstreakToRemove["jump"] ))
{
for ( i = 0; i < self.killstreakToRemove["jump"].size ; i++)
{
self.killstreakToRemove["jump"][i] Destroy();
}
self.killstreakToRemove["jump"] = undefined;
}
if ( isDefined( self.killstreakToRemove["prone"] ))
{
for ( i = 0; i < self.killstreakToRemove["prone"].size ; i++)
{
self.killstreakToRemove["prone"][i] Destroy();
}
self.killstreakToRemove["prone"] = undefined;
}
if ( isDefined( self.killstreakToRemove["switchWeap"] ))
{
for ( i = 0; i < self.killstreakToRemove["switchWeap"].size ; i++)
{
self.killstreakToRemove["switchWeap"][i] Destroy();
}
self.killstreakToRemove["switchWeap"] = undefined;
}
}
//*******************************************************************
// End of HUD element functions *
// Beginning of helper functions *
//*******************************************************************
//tagJC<NOTE>: Check a specific upgrade is already acquired by the player.
//tagJC<NOTE>: player is the player that owns the killstreak.
hasUpgrade ( player, upgradeName )
{
result = false;
if ( isDefined ( player.acquiredUpgrades ))
{
for ( i = 0; i < player.acquiredUpgrades.size; i++ )
{
if (( isDefined (player.acquiredUpgrades[i] )) && ( player.acquiredUpgrades[i] == upgradeName ))
{
result = true;
break;
}
}
}
return result;
}
//tagJC<NOTE>: Returning the name of the kill streak icons.
getKillstreakIcon ( killstreakName )
{
return tableLookup( KILLSTREAK_STRING_TABLE, 1, killstreakName, 14 );
}
//tagJC<NOTE>: Waiting for the Y button press
//tagJC<NOTE>: Self is the player
waitForYButtonPress()
{
self endon ("disconnect");
self endon ("killcam_ended");
self notifyOnPlayerCommand ( "Y button pressed" , "weapnext" );
self waittill ( "Y button pressed" );
self.YbuttonPressedDuringKillCam = true;
}
//tagJC<NOTE>: Waiting for the B button press
//tagJC<NOTE>: Self is the player
waitForBButtonPress()
{
self endon ("disconnect");
self endon ("killcam_ended");
self notifyOnPlayerCommand ( "B button pressed" , "+stance" );
self waittill ( "B button pressed" );
self.BbuttonPressedDuringKillCam = true;
}
//tagJC<NOTE>: Returning the status for whether the Y button is pressed.
//tagJC<NOTE>: Self is the player
ReloadButtonPressed()
{
return self.YbuttonPressedDuringKillCam;
}
//tagJC<NOTE>: Returning the status for whether the B button is pressed.
//tagJC<NOTE>: Self is the player
ProneButtonPressed()
{
return self.BbuttonPressedDuringKillCam;
}
//tagJC<NOTE>: Returning the name of the kill streak reference.
getKillstreakUserFriendlyName ( killstreakName )
{
return tableLookupIString( KILLSTREAK_STRING_TABLE, 1, killstreakName, 2 );
}
//*******************************************************************
// End of helper functions *
// *
//*******************************************************************

2914
maps/mp/_utility.gsc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,211 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
if( level._multiTeamBased == true )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
level._isTeamSpeaking[level._teamNameList[i]] = false;
level._speakers[level._teamNameList[i]] = [];
}
}
level._isTeamSpeaking["allies"] = false;
level._isTeamSpeaking["axis"] = false;
level._speakers["allies"] = [];
level._speakers["axis"] = [];
level._bcSounds = [];
level._bcSounds["reload"] = "inform_reloading_generic";
level._bcSounds["frag_out"] = "inform_attack_grenade";
level._bcSounds["flash_out"] = "inform_attack_flashbang";
level._bcSounds["smoke_out"] = "inform_attack_smoke";
level._bcSounds["conc_out"] = "inform_attack_stun";
level._bcSounds["c4_plant"] = "inform_attack_thwc4";
level._bcSounds["claymore_plant"] = "inform_plant_claymore";
level._bcSounds["kill"] = "inform_killfirm_infantry";
level._bcSounds["casualty"] = "inform_casualty_generic";
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill ( "connected", player );
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon( "disconnect" );
for(;;)
{
self waittill( "spawned_player" );
// help players be stealthy in splitscreen by not announcing their intentions
if ( level._splitscreen )
continue;
self thread claymoreTracking();
self thread reloadTracking();
self thread grenadeTracking();
}
}
claymoreTracking()
{
self endon ( "death" );
self endon ( "disconnect" );
while(1)
{
self waittill( "begin_firing" );
weaponName = self getCurrentWeapon();
if ( weaponName == "claymore_mp" )
level thread sayLocalSound( self, "claymore_plant" );
}
}
reloadTracking()
{
self endon ( "death" );
self endon ( "disconnect" );
for( ;; )
{
self waittill ( "reload_start" );
level thread sayLocalSound( self, "reload" );
}
}
grenadeTracking()
{
self endon ( "death" );
self endon ( "disconnect" );
for( ;; )
{
self waittill ( "grenade_fire", grenade, weaponName );
if ( weaponName == "frag_grenade_mp" )
level thread sayLocalSound( self, "frag_out" );
else if ( weaponName == "flash_grenade_mp" )
level thread sayLocalSound( self, "flash_out" );
else if ( weaponName == "concussion_grenade_mp" )
level thread sayLocalSound( self, "conc_out" );
else if ( weaponName == "smoke_grenade_mp" )
level thread sayLocalSound( self, "smoke_out" );
else if ( weaponName == "c4_mp" )
level thread sayLocalSound( self, "c4_plant" );
}
}
sayLocalSoundDelayed( player, soundType, delay )
{
player endon ( "death" );
player endon ( "disconnect" );
wait ( delay );
sayLocalSound( player, soundType );
}
sayLocalSound( player, soundType )
{
player endon ( "death" );
player endon ( "disconnect" );
if ( isSpeakerInRange( player ) )
return;
if( player.team != "spectator" )
{
prefix = maps\mp\gametypes\_teams::getTeamVoicePrefix( player.team ) + "1_";
soundAlias = prefix + level._bcSounds[soundType];
player thread doSound( soundAlias );
}
}
doSound( soundAlias )
{
team = self.pers["team"];
level addSpeaker( self, team );
self playSoundToTeam( soundAlias, team, self );
self thread timeHack( soundAlias ); // workaround because soundalias notify isn't happening
self waittill_any( soundAlias, "death", "disconnect" );
level removeSpeaker( self, team );
}
timeHack( soundAlias )
{
self endon ( "death" );
self endon ( "disconnect" );
wait ( 2.0 );
self notify ( soundAlias );
}
isSpeakerInRange( player )
{
player endon ( "death" );
player endon ( "disconnect" );
distSq = 1000 * 1000;
// to prevent player switch to spectator after throwing a granade causing damage to someone and result in attacker.pers["team"] = "spectator"
if( isdefined( player ) && isdefined( player.pers["team"] ) && player.pers["team"] != "spectator" )
{
for ( index = 0; index < level._speakers[player.pers["team"]].size; index++ )
{
teammate = level._speakers[player.pers["team"]][index];
if ( teammate == player )
return true;
if ( distancesquared( teammate.origin, player.origin ) < distSq )
return true;
}
}
return false;
}
addSpeaker( player, team )
{
level._speakers[team][level._speakers[team].size] = player;
}
// this is lazy... fix up later by tracking ID's and doing array slot swapping
removeSpeaker( player, team )
{
newSpeakers = [];
for ( index = 0; index < level._speakers[team].size; index++ )
{
if ( level._speakers[team][index] == player )
continue;
newSpeakers[newSpeakers.size] = level._speakers[team][index];
}
level._speakers[team] = newSpeakers;
}

View File

@ -0,0 +1,274 @@
// Callback Setup
// This script provides the hooks from code into script for the gametype callback functions.
//=============================================================================
// Code Callback functions
/*================
Called by code after the level's main script function has run.
================*/
CodeCallback_StartGameType()
{
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
level waittill( "eternity" );
// If the gametype has not beed started, run the startup
if(!isDefined(level._gametypestarted) || !level._gametypestarted)
{
[[level._callbackStartGameType]]();
level._gametypestarted = true; // so we know that the gametype has been started up
}
}
/*================
Called when a player begins connecting to the server.
Called again for every map change or tournement restart.
Return undefined if the client should be allowed, otherwise return
a string with the reason for denial.
Otherwise, the client will be sent the current gamestate
and will eventually get to ClientBegin.
firstTime will be qtrue the very first time a client connects
to the server machine, but qfalse on map changes and tournement
restarts.
================*/
CodeCallback_PlayerConnect()
{
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
level waittill( "eternity" );
self endon("disconnect");
[[level._callbackPlayerConnect]]();
// tagGHS< BB adds >
lpselfnum = self getEntityNumber();
bbPrint( "mpjoins: name %s client %s", self.name, lpselfnum );
}
/*================
Called when a player drops from the server.
Will not be called between levels.
self is the player that is disconnecting.
================*/
CodeCallback_PlayerDisconnect()
{
self maps\mp\gametypes\_gamelogic::dump_score_board_to_black_box_for_player_bailed_early();
self notify("disconnect");
[[level._callbackPlayerDisconnect]]();
lpselfnum = self getEntityNumber();
bbPrint( "mpquits: name %s client %d", self.name, lpselfnum );
}
/*================
Called when a player has taken damage.
self is the player that took damage.
================*/
CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
{
self endon("disconnect");
[[level._callbackPlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
}
/*================
Called when a player has been killed.
self is the player that was killed.
================*/
CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
{
self endon("disconnect");
//println( "mpattacks: victimxuid='" + self GetXUID() + "', victimweapon='" + self GetCurrentWeapon() + "'\n" );
//bbPrint( "breakpoint:" );
if(self.sessionstate != "dead")
{
attackerweaponiskillstreak = 0;
if ( maps\mp\_utility::isKillstreakWeapon( sWeapon ) )
{
attackerweaponiskillstreak = 1;
}
attackerweaponisequipment = 0;
if( maps\mp\gametypes\_weapons::isEquipment( sWeapon ) )
{
attackerweaponisequipment = 1;
}
attackerweaponisnormal = 1; // assume weapon is normal unless it's a killstreak or equipment weapon.
if( ( attackerweaponiskillstreak != 0 ) || ( attackerweaponisequipment != 0 ) )
{
attackerweaponisnormal = 0;
}
lpattackerorigin = ( 0, 0, 0 );
if(isPlayer(eAttacker))
{
lpattacknum = eAttacker getEntityNumber();
lpattackGuid = eAttacker getGuid();
lpattackname = eAttacker.name;
lpattackerteam = eAttacker.pers["team"];
lpattackerorigin = eAttacker.origin;
//println( "mpattacks: victimxuid='" + self GetXUID() + "', attackerxuid='" + eAttacker GetXUID() + "'\n" );
//bbPrint( "breakpoint:" );
bbPrint( "mpattacks: gametime %d attackerspawnid %d attackerxuid %llu attackerweapon %s attackerx %f attackery %f attackerz %f victimspawnid %d victimxuid %llu victimweapon %s victimx %f victimy %f victimz %f damage %d damagetype %s damagelocation %s death 0 attackerweaponisnormal %d attackerweaponiskillstreak %d attackerweaponisequipment %d attackersuit %s victimsuit %s",
gettime(), eAttacker getplayerspawnid(), eAttacker GetXUID(), sWeapon, lpattackerorigin, self getplayerspawnid(), self GetXUID(), self GetCurrentWeapon(), self.origin, iDamage, sMeansOfDeath, sHitLoc, attackerweaponisnormal, attackerweaponiskillstreak, attackerweaponisequipment, eAttacker.currentSuit, self.currentSuit );
}
else
{
//println( "mpattacks: victimxuid='" + self GetXUID() + "'\n" );
lpattacknum = -1;
lpattackGuid = "";
lpattackname = "";
lpattackerteam = "world";
bbPrint( "mpattacks: gametime %d attackerweapon %s victimspawnid %d victimxuid %llu victimweapon %s victimx %f victimy %f victimz %f damage %d damagetype %s damagelocation %s death 0 attackerweaponisnormal %d attackerweaponiskillstreak %d attackerweaponisequipment %d",
gettime(), sWeapon, self getplayerspawnid(), self GetXUID(), self GetCurrentWeapon(), self.origin, iDamage, sMeansOfDeath, sHitLoc, attackerweaponisnormal, attackerweaponiskillstreak, attackerweaponisequipment );
}
//bbPrint( "breakpoint:" );
}
// We need to do the bbprint before here since the level callbacks will respawn the player by the time this next line returns
[[level._callbackPlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
}
/*================
Called when a vehicle has taken damage.
self is the vehicle that took damage.
================*/
CodeCallback_VehicleDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName )
{
if ( isDefined( self.damageCallback ) )
self [[self.damageCallback]]( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
else
self Vehicle_FinishDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
}
/*================
Called when code is forcibly ending the game.
e.g. we suck as host.
================*/
CodeCallback_CodeEndGame()
{
self endon("disconnect");
[[level._callbackCodeEndGame]]();
}
/*================
Called when a player has been killed, but has last stand perk.
self is the player that was killed.
================*/
CodeCallback_PlayerLastStand(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
{
self endon("disconnect");
[[level._callbackPlayerLastStand]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
}
/*================
Called when a player reconnects to the server
following a host migration.
================*/
CodeCallback_PlayerMigrated()
{
self endon("disconnect");
[[level._callbackPlayerMigrated]]();
}
/*================
Called once when a host migration has occured.
================*/
CodeCallback_HostMigration()
{
[[level._callbackHostMigration]]();
}
//=============================================================================
// Damage flags used in the playerDamage callback
SetupDamageFlags()
{
// code-defined:
level._iDFLAGS_RADIUS = 1; // damage was indirect
level._iDFLAGS_NO_ARMOR = 2; // armor does not protect from this damage
level._iDFLAGS_NO_KNOCKBACK = 4; // do not affect velocity, just view angles
level._iDFLAGS_PENETRATION = 8; // damage occurred after one or more penetrations
level._iDFLAGS_STUN = 16; // non-lethal
level._iDFLAGS_SHIELD_EXPLOSIVE_IMPACT = 32; // missile impacted on the front of the victim's shield
level._iDFLAGS_SHIELD_EXPLOSIVE_IMPACT_HUGE = 64; // ...and was from a projectile with "Big Explosion" checked on.
level._iDFLAGS_SHIELD_EXPLOSIVE_SPLASH = 128; // explosive splash, somewhat deflected by the victim's shield
// script-defined:
level._iDFLAGS_NO_TEAM_PROTECTION = 256;
level._iDFLAGS_NO_PROTECTION = 512;
level._iDFLAGS_PASSTHRU = 1024;
}
/*================
Setup any misc callbacks stuff like defines and default callbacks
================*/
SetupCallbacks()
{
SetDefaultCallbacks();
SetupDamageFlags();
}
/*================
Called from the gametype script to store off the default callback functions.
This allows the callbacks to be overridden by level script, but not lost.
================*/
SetDefaultCallbacks()
{
level._callbackStartGameType = maps\mp\gametypes\_gamelogic::Callback_StartGameType;
level._callbackPlayerConnect = maps\mp\gametypes\_playerlogic::Callback_PlayerConnect;
level._callbackPlayerDisconnect = maps\mp\gametypes\_playerlogic::Callback_PlayerDisconnect;
level._callbackPlayerDamage = maps\mp\gametypes\_damage::Callback_PlayerDamage;
level._callbackPlayerKilled = maps\mp\gametypes\_damage::Callback_PlayerKilled;
level._callbackCodeEndGame = maps\mp\gametypes\_gamelogic::Callback_CodeEndGame;
level._callbackPlayerLastStand = maps\mp\gametypes\_damage::Callback_PlayerLastStand;
level._callbackPlayerMigrated = maps\mp\gametypes\_playerlogic::Callback_PlayerMigrated;
level._callbackHostMigration = maps\mp\gametypes\_hostmigration::Callback_HostMigration;
}
/*================
Called when a gametype is not supported.
================*/
AbortLevel()
{
println("Aborting level - gametype is not supported");
level._callbackStartGameType = ::callbackVoid;
level._callbackPlayerConnect = ::callbackVoid;
level._callbackPlayerDisconnect = ::callbackVoid;
level._callbackPlayerDamage = ::callbackVoid;
level._callbackPlayerKilled = ::callbackVoid;
level._callbackCodeEndGame = ::callbackVoid;
level._callbackPlayerLastStand = ::callbackVoid;
level._callbackPlayerMigrated = ::callbackVoid;
level._callbackHostMigration = ::callbackVoid;
setdvar("g_gametype", "dm");
exitLevel(false);
}
/*================
================*/
callbackVoid()
{
}

2896
maps/mp/gametypes/_class.gsc Normal file

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,94 @@
init()
{
precacheShader("damage_feedback");
precacheShader("damage_feedback_j");
precacheShader("damage_feedback_trophy");
precacheShader("damage_feedback_endgame");
precacheShader("scavenger_pickup");
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player.hud_damagefeedback = newClientHudElem(player);
player.hud_damagefeedback.horzAlign = "center";
player.hud_damagefeedback.vertAlign = "middle";
player.hud_damagefeedback.x = -12;
player.hud_damagefeedback.y = -12;
player.hud_damagefeedback.alpha = 0;
player.hud_damagefeedback.archived = true;
player.hud_damagefeedback setShader("damage_feedback", 24, 48);
}
}
updateDamageFeedback( typeHit )
{
if ( !isPlayer( self ) )
return;
x = -12;
y = -12;
if ( getDvarInt( "camera_thirdPerson" ) )
yOffset = self GetThirdPersonCrosshairOffset() * 240;
else
yOffset = getdvarfloat( "cg_crosshairVerticalOffset" ) * 240;
if ( level._splitscreen )
yOffset *= 0.5;
feedbackDurationOverride = 0;
startAlpha = 1;
if ( typeHit == "hitBodyArmor" )
{
self.hud_damagefeedback setShader("damage_feedback_trophy", 24, 48);
self playlocalsound("MP_hit_alert"); // TODO: change sound?
}
else if ( typeHit == "hitEndGame" )
{
self.hud_damagefeedback setShader("damage_feedback_endgame", 24, 48);
self playlocalsound("MP_hit_alert");
}
else if ( typeHit == "stun" )
{
return;
}
else if ( typeHit == "none" )
{
return;
}
else if ( typeHit == "scavenger" && !level._hardcoreMode )
{
x = -36;
y = 32;
self.hud_damagefeedback setShader("scavenger_pickup", 64, 32);
feedbackDurationOverride = 2.5;
}
else
{
self.hud_damagefeedback setShader("damage_feedback", 24, 48);
self playlocalsound("MP_hit_alert");
}
self.hud_damagefeedback.alpha = startAlpha;
if ( feedBackDurationOverride != 0 )
self.hud_damagefeedback fadeOverTime(feedbackDurationOverride);
else
self.hud_damagefeedback fadeOverTime(1);
self.hud_damagefeedback.alpha = 0;
// only update hudelem positioning when necessary
if ( self.hud_damagefeedback.x != x )
self.hud_damagefeedback.x = x;
y = y - int( yOffset );
if ( self.hud_damagefeedback.y != y )
self.hud_damagefeedback.y = y;
}

View File

@ -0,0 +1,87 @@
#include maps\mp\_utility;
init()
{
if (!level._teambased)
return;
precacheShader("headicon_dead");
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player.selfDeathIcons = []; // icons that other people see which point to this player when he's dead
}
}
updateDeathIconsEnabled()
{
//if (!self.enableDeathIcons)
// self removeOtherDeathIcons();
}
addDeathIcon( entity, dyingplayer, team, timeout )
{
if ( !level._teambased )
return;
//tagZP<TODO> fix death icons in MTDM
if( level._multiTeamBased )
{
println( "tagZP<TODO> Fix death icons in MTMD" );
return;
}
iconOrg = entity.origin;
dyingplayer endon("spawned_player");
dyingplayer endon("disconnect");
wait .05;
WaitTillSlowProcessAllowed();
assert(team == "allies" || team == "axis");
if ( getDvar( "ui_hud_showdeathicons" ) == "0" )
return;
if ( level._hardcoreMode )
return;
if ( isdefined( self.lastDeathIcon ) )
self.lastDeathIcon destroy();
newdeathicon = newTeamHudElem( team );
newdeathicon.x = iconOrg[0];
newdeathicon.y = iconOrg[1];
newdeathicon.z = iconOrg[2] + 54;
newdeathicon.alpha = .61;
newdeathicon.archived = true;
if ( level._splitscreen )
newdeathicon setShader("headicon_dead", 14, 14);
else
newdeathicon setShader("headicon_dead", 7, 7);
newdeathicon setwaypoint( true, false );
self.lastDeathIcon = newdeathicon;
newdeathicon thread destroySlowly ( timeout );
}
destroySlowly( timeout )
{
self endon("death");
wait timeout;
self fadeOverTime(1.0);
self.alpha = 0;
wait 1.0;
self destroy();
}

1661
maps/mp/gametypes/_dev.gsc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,120 @@
init()
{
// Draws a team icon over teammates
level._drawfriend = 0;
game["headicon_allies"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "allies" );
game["headicon_axis"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "axis" );
precacheHeadIcon( game["headicon_allies"] );
precacheHeadIcon( game["headicon_axis"] );
precacheShader( "waypoint_revive" );
level thread onPlayerConnect();
for(;;)
{
updateFriendIconSettings();
wait 5;
}
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
player thread onPlayerKilled();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
self thread showFriendIcon();
}
}
onPlayerKilled()
{
self endon("disconnect");
for(;;)
{
self waittill("killed_player");
self.headicon = "";
}
}
showFriendIcon()
{
if(level._drawfriend)
{
if(self.pers["team"] == "allies")
{
self.headicon = game["headicon_allies"];
self.headiconteam = "allies";
}
else
{
self.headicon = game["headicon_axis"];
self.headiconteam = "axis";
}
}
}
updateFriendIconSettings()
{
drawfriend = maps\mp\_utility::getIntProperty("scr_drawfriend", level._drawfriend);
if(level._drawfriend != drawfriend)
{
level._drawfriend = drawfriend;
updateFriendIcons();
}
}
updateFriendIcons()
{
// for all living players, show the appropriate headicon
players = level._players;
for(i = 0; i < players.size; i++)
{
player = players[i];
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
{
if(level._drawfriend)
{
if(player.pers["team"] == "allies")
{
player.headicon = game["headicon_allies"];
player.headiconteam = "allies";
}
else
{
player.headicon = game["headicon_axis"];
player.headiconteam = "axis";
}
}
else
{
players = level._players;
for(i = 0; i < players.size; i++)
{
player = players[i];
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
player.headicon = "";
}
}
}
}
}

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,529 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
getHighestScoringPlayer()
{
updatePlacement();
if ( !level._placement["all"].size )
return ( undefined );
else
return ( level._placement["all"][0] );
}
getLosingPlayers()
{
updatePlacement();
players = level._placement["all"];
losingPlayers = [];
foreach ( player in players )
{
if ( player == level._placement["all"][0] )
continue;
losingPlayers[losingPlayers.size] = player;
}
return losingPlayers;
}
givePlayerScore( event, player, victim, overrideCheckPlayerScoreLimitSoon )
{
if ( isDefined( level._nukeIncoming ) )
return;
score = player.pers["score"];
onPlayerScore( event, player, victim );
if ( score == player.pers["score"] )
return;
if ( !player rankingEnabled() && !level._hardcoreMode )
player thread maps\mp\gametypes\_rank::scorePopup( (player.pers["score"] - score), false, (0.85,0.85,0.85), 0 );
player maps\mp\gametypes\_persistence::statAdd( "score", (player.pers["score"] - score) );
if( getDvarInt( "prototype_adrenaline_enabled" ) == 1 )
{
player maps\mp\_adrenaline::adrenalineAddScore( (player.pers["score"] - score) );
}
player.score = player.pers["score"];
player maps\mp\gametypes\_persistence::statSetChild( "round", "score", player.score );
if ( !level._teambased )
thread sendUpdatedDMScores();
// tagJC<NOTE>: In game mode where winning is not dependent on players' or team's score, it is unnecessary to check whether
// the score limit will be reached soon.
if ( !isDefined( overrideCheckPlayerScoreLimitSoon ) || !overrideCheckPlayerScoreLimitSoon )
player maps\mp\gametypes\_gamelogic::checkPlayerScoreLimitSoon();
scoreEndedMatch = player maps\mp\gametypes\_gamelogic::checkScoreLimit();
if ( scoreEndedMatch && event == "kill" )
player.finalKill = true;
}
onPlayerScore( event, player, victim )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( event );
assert( isDefined( score ) );
player.pers["score"] += score * level._objectivePointsMod;
}
// Seems to only be used for reducing a player's score due to suicide
_setPlayerScore( player, score )
{
if ( score == player.pers["score"] )
return;
player.pers["score"] = score;
player.score = player.pers["score"];
player thread maps\mp\gametypes\_gamelogic::checkScoreLimit();
}
_getPlayerScore( player )
{
return player.pers["score"];
}
giveTeamScoreForObjective( team, score )
{
if ( isDefined( level._nukeIncoming ) )
return;
score *= level._objectivePointsMod;
teamScore = game["teamScores"][team];
/*
otherTeam = level._otherTeam[team];
if ( game["teamScores"][team] > game["teamScores"][otherTeam] )
level._wasWinning = team;
else if ( game["teamScores"][otherTeam] > game["teamScores"][team] )
level._wasWinning = otherTeam;
*/
level._wasWinning = getWinningTeam();
_setTeamScore( team, _getTeamScore( team ) + score );
isWinning = getWinningTeam();
/*
isWinning = "none";
if ( game["teamScores"][team] > game["teamScores"][otherTeam] )
isWinning = team;
else if ( game["teamScores"][otherTeam] > game["teamScores"][team] )
isWinning = otherTeam;
*/
if ( !level._splitScreen && isWinning != "none" && isWinning != level._wasWinning && getTime() - level._lastStatusTime > 5000 && getScoreLimit() != 1 )
{
level._lastStatusTime = getTime();
leaderDialog( "lead_taken", isWinning, "status" );
if ( level._wasWinning != "none")
leaderDialog( "lead_lost", level._wasWinning, "status" );
}
if ( isWinning != "none" )
level._wasWinning = isWinning;
}
getWinningTeam()
{
//if( level._multiTeamBased == true )
//{
winning_team = level._teamNameList[0];
winning_score = game["teamScores"][level._teamNameList[0]];
num_teams_tied_for_winning = 1;
for( i = 1; i < level._teamNameList.size; i++ )
{
if( game["teamScores"][level._teamNameList[i]] > winning_score )
{
//new winning team found
winning_team = level._teamNameList[i];
winning_score = game["teamScores"][level._teamNameList[i]];
num_teams_tied_for_winning = 1;
}
else if( game["teamScores"][level._teamNameList[i]] == winning_score )
{
num_teams_tied_for_winning = num_teams_tied_for_winning + 1;
winning_team = "none";
}
}
return( winning_team );
//}
/*
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
return ( "allies" );
else if ( game["teamScores"]["allies"] < game["teamScores"]["axis"] )
return ( "axis" );
*/
return ( "none" );
}
_setTeamScore( team, teamScore )
{
if ( teamScore == game["teamScores"][team] )
return;
if ( isDefined( level._nukeIncoming ) )
return;
game["teamScores"][team] = teamScore;
updateTeamScore( team );
if ( game["status"] == "overtime" )
thread [[level._onScoreLimit]]();
else
{
thread maps\mp\gametypes\_gamelogic::checkTeamScoreLimitSoon( team );
thread maps\mp\gametypes\_gamelogic::checkScoreLimit();
}
}
updateTeamScore( team )
{
assert( level._teamBased );
teamScore = 0;
if ( !isRoundBased() || !isObjectiveBased() )
teamScore = _getTeamScore( team );
else
teamScore = game["roundsWon"][team];
setTeamScore( team, teamScore );
//thread sendUpdatedTeamScores();
}
_getTeamScore( team )
{
return game["teamScores"][team];
}
sendUpdatedTeamScores()
{
level notify("updating_scores");
level endon("updating_scores");
wait .05;
WaitTillSlowProcessAllowed();
foreach ( player in level._players )
player updateScores();
}
sendUpdatedDMScores()
{
level notify("updating_dm_scores");
level endon("updating_dm_scores");
wait .05;
WaitTillSlowProcessAllowed();
for ( i = 0; i < level._players.size; i++ )
{
level._players[i] updateDMScores();
level._players[i].updatedDMScores = true;
}
}
removeDisconnectedPlayerFromPlacement()
{
offset = 0;
numPlayers = level._placement["all"].size;
found = false;
for ( i = 0; i < numPlayers; i++ )
{
if ( level._placement["all"][i] == self )
found = true;
if ( found )
level._placement["all"][i] = level._placement["all"][ i + 1 ];
}
if ( !found )
return;
level._placement["all"][ numPlayers - 1 ] = undefined;
assert( level._placement["all"].size == numPlayers - 1 );
if( level._multiTeamBased )
{
MTDM_updateTeamPlacement();
}
else if ( level._teamBased )
{
updateTeamPlacement();
return;
}
numPlayers = level._placement["all"].size;
for ( i = 0; i < numPlayers; i++ )
{
player = level._placement["all"][i];
player notify( "update_outcome" );
}
}
updatePlacement()
{
prof_begin("updatePlacement");
placementAll = [];
foreach ( player in level._players )
{
if ( isDefined( player.connectedPostGame ))
{
continue;
}
if( player.pers["team"] == "spectator" )
{
continue;
}
if( player.pers["team"] == "none" )
{
continue;
}
placementAll[placementAll.size] = player;
}
for ( i = 1; i < placementAll.size; i++ )
{
player = placementAll[i];
playerScore = player.score;
// for ( j = i - 1; j >= 0 && (player.score > placementAll[j].score || (player.score == placementAll[j].score && player.deaths < placementAll[j].deaths)); j-- )
for ( j = i - 1; j >= 0 && getBetterPlayer( player, placementAll[j] ) == player; j-- )
placementAll[j + 1] = placementAll[j];
placementAll[j + 1] = player;
}
level._placement["all"] = placementAll;
if( level._multiTeamBased )
{
MTDM_updateTeamPlacement();
}
else if ( level._teamBased )
{
updateTeamPlacement();
}
prof_end("updatePlacement");
}
getBetterPlayer( playerA, playerB )
{
if ( playerA.score > playerB.score )
return playerA;
if ( playerB.score > playerA.score )
return playerB;
if ( playerA.deaths < playerB.deaths )
return playerA;
if ( playerB.deaths < playerA.deaths )
return playerB;
// TODO: more metrics for getting the better player
if ( cointoss() )
return playerA;
else
return playerB;
}
updateTeamPlacement()
{
placement["allies"] = [];
placement["axis"] = [];
placement["spectator"] = [];
assert( level._teamBased );
placementAll = level._placement["all"];
placementAllSize = placementAll.size;
for ( i = 0; i < placementAllSize; i++ )
{
player = placementAll[i];
team = player.pers["team"];
placement[team][ placement[team].size ] = player;
}
level._placement["allies"] = placement["allies"];
level._placement["axis"] = placement["axis"];
}
//TagZP<TODO> consolidate with updateTeamPlacement()
MTDM_updateTeamPlacement()
{
placement["spectator"] = [];
foreach( teamname in level._teamNameList )
{
placement[teamname] = [];
}
assert( level._multiTeamBased );
placementAll = level._placement["all"];
placementAllSize = placementAll.size;
for ( i = 0; i < placementAllSize; i++ )
{
player = placementAll[i];
team = player.pers["team"];
placement[team][ placement[team].size ] = player;
}
foreach( teamname in level._teamNameList )
{
level._placement[teamname] = placement[teamname];
}
}
initialDMScoreUpdate()
{
// the first time we call updateDMScores on a player, we have to send them the whole scoreboard.
// by calling updateDMScores on each player one at a time,
// we can avoid having to send the entire scoreboard to every single player
// the first time someone kills someone else.
wait .2;
numSent = 0;
while(1)
{
didAny = false;
players = level._players;
for ( i = 0; i < players.size; i++ )
{
player = players[i];
if ( !isdefined( player ) )
continue;
if ( isdefined( player.updatedDMScores ) )
continue;
player.updatedDMScores = true;
player updateDMScores();
didAny = true;
wait .5;
}
if ( !didAny )
wait 3; // let more players connect
}
}
processAssist( killedplayer )
{
self endon("disconnect");
killedplayer endon("disconnect");
wait .05; // don't ever run on the same frame as the playerkilled callback.
WaitTillSlowProcessAllowed();
if( !level._multiteambased )
{
if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
{
return;
}
}
if ( self.pers["team"] == killedplayer.pers["team"] )
return;
damagedone = killedplayer.attackerData[self.guid].damage;
// If the attacker has conducted some damages using any grenades with lasting effect, the player should receive a minimum reward that is not porpotional to the damages done
playerMaxHealth = getDvarInt ( "scr_player_maxhealth" );
//Assuming there are four levels for assist rewards, divide player's max health by 4 to get the amount of damage per assist level
damagePerAssistLevel = playerMaxHealth / 4;
if ( isDefined ( killedplayer.attackerData[self.guid].isGrenadeWithLastingEffect ) && killedplayer.attackerData[self.guid].isGrenadeWithLastingEffect == true )
{
if ( damagedone <= 50 )
{
assist_event = "assist_grenade";
}
else
{
assist_event = "assist_level_" + int( ceil( damagedone / damagePerAssistLevel ) );
}
}
else
{
assist_event = "assist_level_" + int( ceil( damagedone / damagePerAssistLevel ) );
}
self thread [[level._onXPEvent]]( assist_event );
self incPersStat( "assists", 1 );
self.assists = self getPersStat( "assists" );
self incPlayerStat( "assists", 1 );
givePlayerScore( assist_event, self, killedplayer );
self thread giveAdrenaline( "assist" );
self thread maps\mp\gametypes\_missions::playerAssist();
}
processShieldAssist( killedPlayer )
{
self endon( "disconnect" );
killedPlayer endon( "disconnect" );
wait .05; // don't ever run on the same frame as the playerkilled callback.
WaitTillSlowProcessAllowed();
if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
return;
if ( self.pers["team"] == killedplayer.pers["team"] )
return;
self thread [[level._onXPEvent]]( "assist" );
self thread [[level._onXPEvent]]( "assist" );
self incPersStat( "assists", 1 );
self.assists = self getPersStat( "assists" );
self incPlayerStat( "assists", 1 );
givePlayerScore( "assist", self, killedplayer );
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "shield_assist" );
self thread maps\mp\gametypes\_missions::playerAssist();
}

View File

@ -0,0 +1,279 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
level._splitscreen = isSplitScreen();
level._ps3 = (getDvar( "ps3Game" ) == "true");
level._xenon = (getDvar( "xenonGame" ) == "true");
level._console = (level._ps3 || level._xenon);
level._onlineGame = getDvarInt( "onlinegame" );
level._rankedMatch = ( !level._onlineGame || !getDvarInt( "xblive_privatematch" ) );
if ( !level._console )
{
if ( !getDvarInt( "sv_pure" ) )
{
oldvalue = level._rankedMatch;
level._rankedMatch = false;
/#
level._rankedMatch = oldvalue;
#/
}
}
/#
if ( getdvarint( "scr_forcerankedmatch" ) == 1 )
{
level._onlineGame = true;
level._rankedMatch = true;
}
#/
level._script = toLower( getDvar( "mapname" ) );
level._gametype = toLower( getDvar( "g_gametype" ) );
//TagZP<NOTE>blocking this out in MTDM will force crashes/asserts where these are used. So nothing slips by.
if( level._gametype != "mtdm" )
{
level._otherTeam["allies"] = "axis";
level._otherTeam["axis"] = "allies";
}
level._maxNumTeams = 2;
level._teamNameList = ["allies", "axis"];
level._teamBased = false;
level._multiTeamBased = false;
level._objectiveBased = false;
level._endGameOnTimeLimit = true;
level._showingFinalKillcam = false;
level._tiSpawnDelay = getDvarInt( "scr_tispawndelay" );
// hack to allow maps with no scripts to run correctly
if ( !isDefined( level._tweakablesInitialized ) )
maps\mp\gametypes\_tweakables::init();
precacheString( &"MP_HALFTIME" );
precacheString( &"MP_OVERTIME" );
precacheString( &"MP_ROUNDEND" );
precacheString( &"MP_INTERMISSION" );
precacheString( &"MP_SWITCHING_SIDES" );
precacheString( &"MP_FRIENDLY_FIRE_WILL_NOT" );
precacheString( &"PLATFORM_REVIVE" );
precacheString( &"MP_OBITUARY_NEUTRAL" );
precacheString( &"MP_OBITUARY_FRIENDLY" );
precacheString( &"MP_OBITUARY_ENEMY" );
if ( level._splitScreen )
precacheString( &"MP_ENDED_GAME" );
else
precacheString( &"MP_HOST_ENDED_GAME" );
level._halftimeType = "halftime";
level._halftimeSubCaption = &"MP_SWITCHING_SIDES";
level._lastStatusTime = 0;
level._wasWinning = "none";
level._lastSlowProcessFrame = 0;
for( i = 0; i < level._teamNameList.size; i++ )
{
level._placement[level._teamNameList[i]] = [];
}
level._placement["all"] = [];
/*
level._placement["allies"] = [];
level._placement["axis"] = [];
level._placement["all"] = [];
*/
level._postRoundTime = 5.0;
level._playersLookingForSafeSpawn = [];
registerDvars();
precacheModel( "vehicle_mig29_desert" );
precacheModel( "projectile_cbu97_clusterbomb" );
precacheModel( "tag_origin" );
level._fx_airstrike_afterburner = loadfx ("fire/jet_afterburner");
level._fx_airstrike_contrail = loadfx ("smoke/jet_contrail");
if ( level._console )
precacheLeaderboards( "LB_KILLS LB_WINS LB_TOTALXP LB_ACCURACY" );
for( i = 0; i < level._teamNameList.size; i++ )
{
level._teamCount[level._teamNameList[i]] = 0;
level._aliveCount[level._teamNameList[i]] = 0;
level._livesCount[level._teamNameList[i]] = 0;
level._hasSpawned[level._teamNameList[i]] = 0;
}
level._teamCount["spectator"] = 0;
level._aliveCount["spectator"] = 0;
level._oneLeftTime = [];
/#
if ( getdvarint( "scr_runlevelandquit" ) == 1 )
{
thread runLevelAndQuit();
}
#/
}
/#
runLevelAndQuit()
{
wait 1;
while ( level._players.size < 1 )
{
wait 0.5;
}
wait 0.5;
level notify( "game_ended" );
exitLevel();
}
#/
registerDvars()
{
makeDvarServerInfo( "ui_bomb_timer", 0 );
makeDvarServerInfo( "ui_danger_team", "" );
}
SetupCallbacks()
{
level._onXPEvent = ::onXPEvent;
level._getSpawnPoint = ::blank;
level._onSpawnPlayer = ::blank;
level._onRespawnDelay = ::blank;
level._onTimeLimit = maps\mp\gametypes\_gamelogic::default_onTimeLimit;
level._onScoreLimit = maps\mp\gametypes\_gamelogic::default_onScoreLimit;
level._onHalfTime = maps\mp\gametypes\_gamelogic::default_onHalfTime;
level._onDeadEvent = maps\mp\gametypes\_gamelogic::default_onDeadEvent;
level._onOneLeftEvent = maps\mp\gametypes\_gamelogic::default_onOneLeftEvent;
level._onPrecacheGametype = ::blank;
level._onStartGameType = ::blank;
level._onPlayerKilled = ::blank;
level._autoassign = maps\mp\gametypes\_menus::menuAutoAssign;
level._spectator = maps\mp\gametypes\_menus::menuSpectator;
level._class = maps\mp\gametypes\_menus::menuClass;
level._onTeamSelection = maps\mp\gametypes\_menus::onMenuTeamSelect;
}
blank( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 )
{
}
/#
xpRateThread()
{
self endon ( "death" );
self endon ( "disconnect" );
level endon ( "game_ended" );
gameFlagWait( "prematch_done" );
for ( ;; )
{
wait ( 5.0 );
if ( level._players[0].pers["team"] == "allies" || level._players[0].pers["team"] == "axis" )
self maps\mp\gametypes\_rank::giveRankXP( "kill", int(min( getDvarInt( "scr_xprate" ), 50 )) );
}
}
#/
testMenu()
{
self endon ( "death" );
self endon ( "disconnect" );
for ( ;; )
{
wait ( 10.0 );
notifyData = spawnStruct();
notifyData.titleText = &"MP_CHALLENGE_COMPLETED";
notifyData.notifyText = "wheee";
notifyData.sound = "mp_challenge_complete";
self thread maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
}
}
testShock()
{
self endon ( "death" );
self endon ( "disconnect" );
for ( ;; )
{
wait ( 3.0 );
numShots = randomInt( 6 );
for ( i = 0; i < numShots; i++ )
{
iPrintLnBold( numShots );
self shellShock( "frag_grenade_mp", 0.2 );
wait ( 0.1 );
}
}
}
onXPEvent( event )
{
//self thread maps\mp\_loot::giveMoney( event, 10 );
self thread maps\mp\gametypes\_rank::giveRankXP( event );
}
fakeLag()
{
self endon ( "disconnect" );
self.fakeLag = randomIntRange( 50, 150 );
for ( ;; )
{
self setClientDvar( "fakelag_target", self.fakeLag );
wait ( randomFloatRange( 5.0, 15.0 ) );
}
}
debugLine( start, end )
{
for ( i = 0; i < 50; i++ )
{
line( start, end );
wait .05;
}
}

View File

@ -0,0 +1,235 @@
#include maps\mp\_utility;
init()
{
level._healthOverlayCutoff = 0.55;
regenTime = 5;
regenTime = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "healthregentime" );
regenRatePercent = 10;
regenRatePercent = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "healthregenratepercent" );
level._playerHealth_RegularRegenDelay = regenTime * 1000;
level._playerHealth_RegenRate = 1.0 / regenRatePercent;
level._healthRegenDisabled = (level._playerHealth_RegularRegenDelay <= 0);
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon("disconnect");
self.healthRegenDelay = level._playerHealth_RegularRegenDelay;
self.healthRegenRate = level._playerHealth_RegenRate;
for(;;)
{
self waittill("spawned_player");
self thread playerHealthRegen();
self thread showTempDamage();
}
}
showTempDamage()
{
self endon ( "death" );
self endon ( "disconnect" );
/#
setDevDvar( "scr_damage_wait", 0 );
setDevDvar( "scr_damage_fadein", 0.25 );
setDevDvar( "scr_damage_fadeout", 0.5 );
setDevDvar( "scr_damage_holdtime", 0.5 );
setDevDvar( "scr_damage_numfades", 5 );
for ( ;; )
{
while ( getDvarFloat( "scr_damage_wait" ) <= 0 )
wait ( 1.0 );
wait ( getDvarFloat( "scr_damage_wait" ) );
for ( i = 0; i < getDvarInt( "scr_damage_numfades" ); i++ )
{
self VisionSetNakedForPlayer( "mp_crash_damage", getDvarFloat( "scr_damage_fadein" ) * (getDvarInt( "scr_damage_numfades" ) - i) );
wait ( getDvarFloat( "scr_damage_fadein" ) + getDvarFloat( "scr_damage_holdtime" ) );
self VisionSetNakedForPlayer( "mp_crash", getDvarFloat( "scr_damage_fadeout" ) * getDvarInt( "scr_damage_numfades" ) );
wait ( getDvarFloat( "scr_damage_fadeout" ) );
}
}
#/
}
playerHealthRegen()
{
self endon ( "death" );
self endon ( "disconnect" );
self endon ( "joined_team" );
self endon ( "joined_spectators" );
if ( self.health <= 0 )
{
assert( !isalive( self ) );
return;
}
oldhealth = self.maxhealth;
regenRate = 0.1;
veryHurt = false;
self.breathingStopTime = -10000;
thread playerBreathingSound( self.maxhealth * 0.35 );
lastSoundTime_Recover = 0;
hurtTime = 0;
newHealth = 0;
for (;;)
{
wait ( 0.05 );
if ( isDefined( level._hostMigrationTimer ) )
{
timePassed = maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
hurtTime += timePassed;
lastSoundTime_Recover += timePassed;
}
if ( self.health == self.maxhealth || ( level._dieHardMode && isDefined( self.healthClamped ) && self.health >= self.healthClamped ) ) // runs every frame
{
oldHealth = self.maxhealth;
veryHurt = false;
self.atBrinkOfDeath = false;
continue;
}
if ( self.health <= 0 ) // player dead
return;
curTime = getTime();
ratio = self.health / self.maxHealth;
if ( ratio <= level._healthOverlayCutoff )
{
if ( !veryHurt )
hurtTime = curTime;
veryHurt = true;
self.atBrinkOfDeath = true;
}
if ( self.health >= oldhealth )
{
if ( curTime - hurtTime < self.healthRegenDelay )
{
continue;
}
if ( level._healthRegenDisabled )
{
wait ( 3.0 );
self.maxHealth = int( max( self.health, 2 ) );
self.health = self.maxHealth;
continue;
}
if ( curTime - lastSoundTime_Recover > self.healthRegenDelay )
{
lastSoundTime_Recover = curTime;
if ( !level._gameEnded )
self playLocalSound("breathing_better");
}
if ( veryHurt )
{
newHealth = ratio;
if ( curTime > hurtTime + 3000 )
{
newHealth += self.healthRegenRate;
}
}
else
{
newHealth = 1;
}
if ( newHealth >= 1.0 )
{
if ( veryHurt )
{
self maps\mp\gametypes\_missions::healthRegenerated();
}
self maps\mp\gametypes\_damage::resetAttackerList();
newHealth = 1.0;
}
if (newHealth <= 0)
{
// Player is dead
return;
}
self setNormalHealth (newHealth);
oldHealth = self.health;
continue;
}
// first time damaged
oldHealth = self.health;
hurtTime = curTime;
self.breathingStopTime = hurtTime + 6000;
}
}
playerBreathingSound( healthcap )
{
level endon ( "game_ended" );
self endon ( "death" );
self endon ( "disconnect" );
self endon ( "joined_team" );
self endon ( "joined_spectators" );
wait ( 2 );
for (;;)
{
wait ( 0.2 );
if ( self.health <= 0 )
return;
// Player still has a lot of health so no breathing sound
if ( self.health >= healthcap )
continue;
if ( level._healthRegenDisabled && gettime() > self.breathingStopTime )
continue;
self playLocalSound( "breathing_hurt" );
wait ( .784 );
wait ( 0.1 + randomfloat (0.8) );
}
}

View File

@ -0,0 +1,167 @@
#include maps\mp\_utility;
#include common_scripts\utility;
Callback_HostMigration()
{
level._hostMigrationReturnedPlayerCount = 0;
if ( level._gameEnded )
{
println( "Migration starting at time " + gettime() + ", but game has ended, so no countdown." );
return;
}
println( "Migration starting at time " + gettime() );
level._hostMigrationTimer = true;
level notify( "host_migration_begin" );
maps\mp\gametypes\_gamelogic::UpdateTimerPausedness();
foreach ( player in level._players )
{
player thread hostMigrationTimerThink();
}
level endon( "host_migration_begin" );
hostMigrationWait();
level._hostMigrationTimer = undefined;
println( "Migration finished at time " + gettime() );
level notify( "host_migration_end" );
maps\mp\gametypes\_gamelogic::UpdateTimerPausedness();
}
hostMigrationWait()
{
level endon( "game_ended" );
level endon( "nuke_death" );
// start with a 20 second wait.
// once we get enough players, or the first 15 seconds pass, switch to a 5 second timer.
thread maps\mp\gametypes\_gamelogic::matchStartTimerConsole( "waiting_for_players", 20.0 );
hostMigrationWaitForPlayers();
thread maps\mp\gametypes\_gamelogic::matchStartTimerConsole( "match_resuming_in", 5.0 );
wait 5;
}
hostMigrationWaitForPlayers()
{
level endon( "hostmigration_enoughplayers" );
wait 15;
}
hostMigrationTimerThink_Internal()
{
level endon( "host_migration_begin" );
level endon( "host_migration_end" );
self.hostMigrationControlsFrozen = false;
while ( !isReallyAlive( self ) )
{
self waittill( "spawned" );
}
self.hostMigrationControlsFrozen = true;
self freezeControlsWrapper( true );
level waittill( "host_migration_end" );
}
hostMigrationTimerThink()
{
self endon( "disconnect" );
self setClientDvar( "cg_scoreboardPingGraph", "0" );
hostMigrationTimerThink_Internal();
if ( self.hostMigrationControlsFrozen )
self freezeControlsWrapper( false );
self setClientDvar( "cg_scoreboardPingGraph", "1" );
}
waitTillHostMigrationDone()
{
if ( !isDefined( level._hostMigrationTimer ) )
return 0;
starttime = gettime();
level waittill( "host_migration_end" );
return gettime() - starttime;
}
waitTillHostMigrationStarts( duration )
{
if ( isDefined( level._hostMigrationTimer ) )
return;
level endon( "host_migration_begin" );
wait duration;
}
waitLongDurationWithHostMigrationPause( duration )
{
if ( duration == 0 )
return;
assert( duration > 0 );
starttime = gettime();
endtime = gettime() + duration * 1000;
while ( gettime() < endtime )
{
waitTillHostMigrationStarts( (endtime - gettime()) / 1000 );
if ( isDefined( level._hostMigrationTimer ) )
{
timePassed = waitTillHostMigrationDone();
endtime += timePassed;
}
}
assert( gettime() == endtime );
waitTillHostMigrationDone();
return gettime() - starttime;
}
waitLongDurationWithGameEndTimeUpdate( duration )
{
if ( duration == 0 )
return;
assert( duration > 0 );
starttime = gettime();
endtime = gettime() + duration * 1000;
while ( gettime() < endtime )
{
waitTillHostMigrationStarts( (endtime - gettime()) / 1000 );
while ( isDefined( level._hostMigrationTimer ) )
{
endTime += 1000;
setGameEndTime( int( endTime ) );
wait 1;
}
}
assert( gettime() == endtime );
while ( isDefined( level._hostMigrationTimer ) )
{
endTime += 1000;
setGameEndTime( int( endTime ) );
wait 1;
}
return gettime() - starttime;
}

160
maps/mp/gametypes/_hud.gsc Normal file
View File

@ -0,0 +1,160 @@
// Edge relative placement values for rect->h_align and rect->v_align
#define HORIZONTAL_ALIGN_SUBLEFT 0 // left edge of a 4:3 screen (safe area not included)
#define HORIZONTAL_ALIGN_LEFT 1 // left viewable (safe area) edge
#define HORIZONTAL_ALIGN_CENTER 2 // center of the screen (reticle)
#define HORIZONTAL_ALIGN_RIGHT 3 // right viewable (safe area) edge
#define HORIZONTAL_ALIGN_FULLSCREEN 4 // disregards safe area
#define HORIZONTAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
#define HORIZONTAL_ALIGN_TO640 6 // scales a real-screen resolution x down into the 0 - 640 range
#define HORIZONTAL_ALIGN_CENTER_SAFEAREA 7 // center of the safearea
#define HORIZONTAL_ALIGN_MAX HORIZONTAL_ALIGN_CENTER_SAFEAREA
#define HORIZONTAL_ALIGN_DEFAULT HORIZONTAL_ALIGN_SUBLEFT
#define VERTICAL_ALIGN_SUBTOP 0 // top edge of the 4:3 screen (safe area not included)
#define VERTICAL_ALIGN_TOP 1 // top viewable (safe area) edge
#define VERTICAL_ALIGN_CENTER 2 // center of the screen (reticle)
#define VERTICAL_ALIGN_BOTTOM 3 // bottom viewable (safe area) edge
#define VERTICAL_ALIGN_FULLSCREEN 4 // disregards safe area
#define VERTICAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
#define VERTICAL_ALIGN_TO480 6 // scales a real-screen resolution y down into the 0 - 480 range
#define VERTICAL_ALIGN_CENTER_SAFEAREA 7 // center of the save area
#define VERTICAL_ALIGN_MAX VERTICAL_ALIGN_CENTER_SAFEAREA
#define VERTICAL_ALIGN_DEFAULT VERTICAL_ALIGN_SUBTOP
static const char *g_he_font[] =
{
"default", // HE_FONT_DEFAULT
"bigfixed", // HE_FONT_BIGFIXED
"smallfixed", // HE_FONT_SMALLFIXED
"objective", // HE_FONT_OBJECTIVE
};
// These values correspond to the defines in q_shared.h
static const char *g_he_alignx[] =
{
"left", // HE_ALIGN_LEFT
"center", // HE_ALIGN_CENTER
"right", // HE_ALIGN_RIGHT
};
static const char *g_he_aligny[] =
{
"top", // HE_ALIGN_TOP
"middle", // HE_ALIGN_MIDDLE
"bottom", // HE_ALIGN_BOTTOM
};
// These values correspond to the defines in menudefinition.h
static const char *g_he_horzalign[] =
{
"subleft", // HORIZONTAL_ALIGN_SUBLEFT
"left", // HORIZONTAL_ALIGN_LEFT
"center", // HORIZONTAL_ALIGN_CENTER
"right", // HORIZONTAL_ALIGN_RIGHT
"fullscreen", // HORIZONTAL_ALIGN_FULLSCREEN
"noscale", // HORIZONTAL_ALIGN_NOSCALE
"alignto640", // HORIZONTAL_ALIGN_TO640
"center_safearea", // HORIZONTAL_ALIGN_CENTER_SAFEAREA
};
cassert( ARRAY_COUNT( g_he_horzalign ) == HORIZONTAL_ALIGN_MAX + 1 );
static const char *g_he_vertalign[] =
{
"subtop", // VERTICAL_ALIGN_SUBTOP
"top", // VERTICAL_ALIGN_TOP
"middle", // VERTICAL_ALIGN_CENTER
"bottom", // VERTICAL_ALIGN_BOTTOM
"fullscreen", // VERTICAL_ALIGN_FULLSCREEN
"noscale", // VERTICAL_ALIGN_NOSCALE
"alignto480", // VERTICAL_ALIGN_TO480
"center_safearea", // VERTICAL_ALIGN_CENTER_SAFEAREA
};
cassert( ARRAY_COUNT( g_he_vertalign ) == VERTICAL_ALIGN_MAX + 1 );
*/
init()
{
precacheShader( "progress_bar_bg" );
precacheShader( "progress_bar_fg" );
precacheShader( "progress_bar_fill" );
level._uiParent = spawnstruct();
level._uiParent.horzAlign = "left";
level._uiParent.vertAlign = "top";
level._uiParent.alignX = "left";
level._uiParent.alignY = "top";
level._uiParent.x = 0;
level._uiParent.y = 0;
level._uiParent.width = 0;
level._uiParent.height = 0;
level._uiParent.children = [];
level._fontHeight = 12;
level._hud["allies"] = spawnstruct();
level._hud["axis"] = spawnstruct();
// we can, of course, separate out the following constants for splitscreen.
// primary progress bars are for things like capturing flags or planting bombs - big, important things that happen as you play a gametype
level._primaryProgressBarY = -61; // from center
level._primaryProgressBarX = 0;
level._primaryProgressBarHeight = 9; //28; // this is the height and width of the whole progress bar, including the outline. the part that actually moves is 2 pixels smaller.
level._primaryProgressBarWidth = 120;
level._primaryProgressBarTextY = -75;
level._primaryProgressBarTextX = 0;
level._primaryProgressBarFontSize = .6; // 1.4 before font change from "objective"
level._teamProgressBarY = 32; // 205;
level._teamProgressBarHeight = 14;
level._teamProgressBarWidth = 192;
level._teamProgressBarTextY = 8; // 155;
level._teamProgressBarFontSize = 1.65;
if ( level._splitscreen )
{
level._lowerTextYAlign = "BOTTOM";
level._lowerTextY = -76;
level._lowerTextFontSize = 1.14;
}
else
{
level._lowerTextYAlign = "CENTER";
level._lowerTextY = 70;
level._lowerTextFontSize = 1.6;
}
}
fontPulseInit( maxFontScale )
{
self.baseFontScale = self.fontScale;
if ( isDefined( maxFontScale ) )
self.maxFontScale = min( maxFontScale, 6.3 );
else
self.maxFontScale = min( self.fontScale * 2, 6.3 );
self.inFrames = 2;
self.outFrames = 4;
}
fontPulse(player)
{
self notify ( "fontPulse" );
self endon ( "fontPulse" );
self endon( "death" );
player endon("disconnect");
player endon("joined_team");
player endon("joined_spectators");
self ChangeFontScaleOverTime( self.inFrames * 0.05 );
self.fontScale = self.maxFontScale;
wait self.inFrames * 0.05;
self ChangeFontScaleOverTime( self.outFrames * 0.05 );
self.fontScale = self.baseFontScale;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,792 @@
#include maps\mp\_utility;
setParent( element )
{
if ( isDefined( self.parent ) && self.parent == element )
return;
if ( isDefined( self.parent ) )
self.parent removeChild( self );
self.parent = element;
self.parent addChild( self );
if ( isDefined( self.point ) )
self setPoint( self.point, self.relativePoint, self.xOffset, self.yOffset );
else
self setPoint( "TOPLEFT" );
}
getParent()
{
return self.parent;
}
addChild( element )
{
element.index = self.children.size;
self.children[self.children.size] = element;
}
removeChild( element )
{
element.parent = undefined;
if ( self.children[self.children.size-1] != element )
{
self.children[element.index] = self.children[self.children.size-1];
self.children[element.index].index = element.index;
}
self.children[self.children.size-1] = undefined;
element.index = undefined;
}
setPoint( point, relativePoint, xOffset, yOffset, moveTime )
{
if ( !isDefined( moveTime ) )
moveTime = 0;
element = self getParent();
if ( moveTime )
self moveOverTime( moveTime );
if ( !isDefined( xOffset ) )
xOffset = 0;
self.xOffset = xOffset;
if ( !isDefined( yOffset ) )
yOffset = 0;
self.yOffset = yOffset;
self.point = point;
self.alignX = "center";
self.alignY = "middle";
if ( isSubStr( point, "TOP" ) )
self.alignY = "top";
if ( isSubStr( point, "BOTTOM" ) )
self.alignY = "bottom";
if ( isSubStr( point, "LEFT" ) )
self.alignX = "left";
if ( isSubStr( point, "RIGHT" ) )
self.alignX = "right";
if ( !isDefined( relativePoint ) )
relativePoint = point;
self.relativePoint = relativePoint;
relativeX = "center_adjustable";
relativeY = "middle";
if ( isSubStr( relativePoint, "TOP" ) )
relativeY = "top_adjustable";
if ( isSubStr( relativePoint, "BOTTOM" ) )
relativeY = "bottom_adjustable";
if ( isSubStr( relativePoint, "LEFT" ) )
relativeX = "left_adjustable";
if ( isSubStr( relativePoint, "RIGHT" ) )
relativeX = "right_adjustable";
if ( element == level._uiParent )
{
self.horzAlign = relativeX;
self.vertAlign = relativeY;
}
else
{
self.horzAlign = element.horzAlign;
self.vertAlign = element.vertAlign;
}
if ( strip_suffix( relativeX, "_adjustable" ) == element.alignX )
{
offsetX = 0;
xFactor = 0;
}
else if ( relativeX == "center" || element.alignX == "center" )
{
offsetX = int(element.width / 2);
if ( relativeX == "left_adjustable" || element.alignX == "right" )
xFactor = -1;
else
xFactor = 1;
}
else
{
offsetX = element.width;
if ( relativeX == "left_adjustable" )
xFactor = -1;
else
xFactor = 1;
}
self.x = element.x + (offsetX * xFactor);
if ( strip_suffix( relativeY, "_adjustable" ) == element.alignY )
{
offsetY = 0;
yFactor = 0;
}
else if ( relativeY == "middle" || element.alignY == "middle" )
{
offsetY = int(element.height / 2);
if ( relativeY == "top_adjustable" || element.alignY == "bottom" )
yFactor = -1;
else
yFactor = 1;
}
else
{
offsetY = element.height;
if ( relativeY == "top_adjustable" )
yFactor = -1;
else
yFactor = 1;
}
self.y = element.y + (offsetY * yFactor);
self.x += self.xOffset;
self.y += self.yOffset;
switch ( self.elemType )
{
case "bar":
setPointBar( point, relativePoint, xOffset, yOffset );
break;
}
self updateChildren();
}
setPointBar( point, relativePoint, xOffset, yOffset )
{
self.bar.horzAlign = self.horzAlign;
self.bar.vertAlign = self.vertAlign;
self.bar.alignX = "left";
self.bar.alignY = self.alignY;
self.bar.y = self.y;
if ( self.alignX == "left" )
self.bar.x = self.x;
else if ( self.alignX == "right" )
self.bar.x = self.x - self.width;
else
self.bar.x = self.x - int(self.width / 2);
if ( self.alignY == "top" )
self.bar.y = self.y;
else if ( self.alignY == "bottom" )
self.bar.y = self.y;
self updateBar( self.bar.frac );
}
updateBar( barFrac, rateOfChange )
{
if ( self.elemType == "bar" )
updateBarScale( barFrac, rateOfChange );
}
updateBarScale( barFrac, rateOfChange ) // rateOfChange is optional and is in "(entire bar lengths) per second"
{
barWidth = int(self.width * barFrac + 0.5); // (+ 0.5 rounds)
if ( !barWidth )
barWidth = 1;
self.bar.frac = barFrac;
self.bar setShader( self.bar.shader, barWidth, self.height );
assertEx( barWidth <= self.width, "barWidth <= self.width: " + barWidth + " <= " + self.width + " - barFrac was " + barFrac );
//if barWidth is bigger than self.width then we are drawing more than 100%
if ( isDefined( rateOfChange ) && barWidth < self.width )
{
if ( rateOfChange > 0 )
{
//printLn( "scaling from: " + barWidth + " to " + self.width + " at " + ((1 - barFrac) / rateOfChange) );
assertex( ((1 - barFrac) / rateOfChange) > 0, "barFrac: " + barFrac + "rateOfChange: " + rateOfChange );
self.bar scaleOverTime( (1 - barFrac) / rateOfChange, self.width, self.height );
}
else if ( rateOfChange < 0 )
{
//printLn( "scaling from: " + barWidth + " to " + 0 + " at " + (barFrac / (-1 * rateOfChange)) );
assertex( (barFrac / (-1 * rateOfChange)) > 0, "barFrac: " + barFrac + "rateOfChange: " + rateOfChange );
self.bar scaleOverTime( barFrac / (-1 * rateOfChange), 1, self.height );
}
}
self.bar.rateOfChange = rateOfChange;
self.bar.lastUpdateTime = getTime();
}
createFontString( font, fontScale )
{
fontElem = newClientHudElem( self );
fontElem.elemType = "font";
fontElem.font = font;
fontElem.fontscale = fontScale;
fontElem.baseFontScale = fontScale;
fontElem.x = 0;
fontElem.y = 0;
fontElem.width = 0;
fontElem.height = int(level._fontHeight * fontScale);
fontElem.xOffset = 0;
fontElem.yOffset = 0;
fontElem.children = [];
fontElem setParent( level._uiParent );
fontElem.hidden = false;
return fontElem;
}
createServerFontString( font, fontScale, team )
{
if ( isDefined( team ) )
fontElem = newTeamHudElem( team );
else
fontElem = newHudElem();
fontElem.elemType = "font";
fontElem.font = font;
fontElem.fontscale = fontScale;
fontElem.baseFontScale = fontScale;
fontElem.x = 0;
fontElem.y = 0;
fontElem.width = 0;
fontElem.height = int(level._fontHeight * fontScale);
fontElem.xOffset = 0;
fontElem.yOffset = 0;
fontElem.children = [];
fontElem setParent( level._uiParent );
fontElem.hidden = false;
return fontElem;
}
createServerTimer( font, fontScale, team )
{
if ( isDefined( team ) )
timerElem = newTeamHudElem( team );
else
timerElem = newHudElem();
timerElem.elemType = "timer";
timerElem.font = font;
timerElem.fontScale = fontScale;
timerElem.baseFontScale = fontScale;
timerElem.x = 0;
timerElem.y = 0;
timerElem.width = 0;
timerElem.height = int(level._fontHeight * fontScale);
timerElem.xOffset = 0;
timerElem.yOffset = 0;
timerElem.children = [];
timerElem setParent( level._uiParent );
timerElem.hidden = false;
return timerElem;
}
createTimer( font, fontScale )
{
timerElem = newClientHudElem( self );
timerElem.elemType = "timer";
timerElem.font = font;
timerElem.fontScale = fontScale;
timerElem.baseFontScale = fontScale;
timerElem.x = 0;
timerElem.y = 0;
timerElem.width = 0;
timerElem.height = int(level._fontHeight * fontScale);
timerElem.xOffset = 0;
timerElem.yOffset = 0;
timerElem.children = [];
timerElem setParent( level._uiParent );
timerElem.hidden = false;
return timerElem;
}
createIcon( shader, width, height )
{
iconElem = newClientHudElem( self );
iconElem.elemType = "icon";
iconElem.x = 0;
iconElem.y = 0;
iconElem.width = width;
iconElem.height = height;
iconElem.baseWidth = iconElem.width;
iconElem.baseHeight = iconElem.height;
iconElem.xOffset = 0;
iconElem.yOffset = 0;
iconElem.children = [];
iconElem setParent( level._uiParent );
iconElem.hidden = false;
if ( isDefined( shader ) )
{
iconElem setShader( shader, width, height );
iconElem.shader = shader;
}
return iconElem;
}
createServerIcon( shader, width, height, team )
{
if ( isDefined( team ) )
iconElem = newTeamHudElem( team );
else
iconElem = newHudElem();
iconElem.elemType = "icon";
iconElem.x = 0;
iconElem.y = 0;
iconElem.width = width;
iconElem.height = height;
iconElem.baseWidth = iconElem.width;
iconElem.baseHeight = iconElem.height;
iconElem.xOffset = 0;
iconElem.yOffset = 0;
iconElem.children = [];
iconElem setParent( level._uiParent );
iconElem.hidden = false;
if ( isDefined( shader ) )
{
iconElem setShader( shader, width, height );
iconElem.shader = shader;
}
return iconElem;
}
createServerBar( color, width, height, flashFrac, team, selected )
{
if ( isDefined( team ) )
barElem = newTeamHudElem( team );
else
barElem = newHudElem();
barElem.x = 0;
barElem.y = 0;
barElem.frac = 0;
barElem.color = color;
barElem.sort = -2;
barElem.shader = "progress_bar_fill";
barElem setShader( "progress_bar_fill", width, height );
barElem.hidden = false;
if ( isDefined( flashFrac ) )
{
barElem.flashFrac = flashFrac;
// barElem thread flashThread();
}
if ( isDefined( team ) )
barElemBG = newTeamHudElem( team );
else
barElemBG = newHudElem();
barElemBG.elemType = "bar";
barElemBG.x = 0;
barElemBG.y = 0;
barElemBG.width = width;
barElemBG.height = height;
barElemBG.xOffset = 0;
barElemBG.yOffset = 0;
barElemBG.bar = barElem;
barElemBG.children = [];
barElemBG.sort = -3;
barElemBG.color = (0,0,0);
barElemBG.alpha = 0.5;
barElemBG setParent( level._uiParent );
barElemBG setShader( "progress_bar_bg", width, height );
barElemBG.hidden = false;
return barElemBG;
}
createBar( color, width, height, flashFrac )
{
barElem = newClientHudElem( self );
barElem.x = 0 ;
barElem.y = 0;
barElem.frac = 0;
barElem.color = color;
barElem.sort = -2;
barElem.shader = "progress_bar_fill";
barElem setShader( "progress_bar_fill", width, height );
barElem.hidden = false;
if ( isDefined( flashFrac ) )
{
barElem.flashFrac = flashFrac;
// barElem thread flashThread();
}
barElemBG = newClientHudElem( self );
barElemBG.elemType = "bar";
barElemBG.width = width;
barElemBG.height = height;
barElemBG.xOffset = 0;
barElemBG.yOffset = 0;
barElemBG.bar = barElem;
barElemBG.children = [];
barElemBG.sort = -3;
barElemBG.color = (0,0,0);
barElemBG.alpha = 0.5;
barElemBG setParent( level._uiParent );
barElemBG setShader( "progress_bar_bg", width + 4, height + 4 );
barElemBG.hidden = false;
return barElemBG;
}
getCurrentFraction()
{
frac = self.bar.frac;
if (isdefined(self.bar.rateOfChange))
{
frac += (getTime() - self.bar.lastUpdateTime) * self.bar.rateOfChange;
if (frac > 1) frac = 1;
if (frac < 0) frac = 0;
}
return frac;
}
createPrimaryProgressBar( yOffset )
{
if ( !isDefined( yOffset ) )
yOffset = 0;
bar = createBar( (1, 1, 1), level._primaryProgressBarWidth, level._primaryProgressBarHeight );
bar setPoint("CENTER", undefined, level._primaryProgressBarX, level._primaryProgressBarY - yOffset );
return bar;
}
createPrimaryProgressBarText( yOffset )
{
if ( !isDefined( yOffset ) )
yOffset = 0;
text = createFontString( "hudbig", level._primaryProgressBarFontSize );
text setPoint("CENTER", undefined, level._primaryProgressBarTextX, level._primaryProgressBarTextY - yOffset );
text.sort = -1;
return text;
}
createTeamProgressBar( team )
{
bar = createServerBar( (1,0,0), level._teamProgressBarWidth, level._teamProgressBarHeight, undefined, team );
bar setPoint("TOP", undefined, 0, level._teamProgressBarY);
return bar;
}
createTeamProgressBarText( team )
{
text = createServerFontString( "default", level._teamProgressBarFontSize, team );
text setPoint("TOP", undefined, 0, level._teamProgressBarTextY);
return text;
}
setFlashFrac( flashFrac )
{
self.bar.flashFrac = flashFrac;
}
hideElem()
{
if ( self.hidden )
return;
self.hidden = true;
if ( self.alpha != 0 )
self.alpha = 0;
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
{
self.bar.hidden = true;
if ( self.bar.alpha != 0 )
self.bar.alpha = 0;
}
}
showElem()
{
if ( !self.hidden )
return;
self.hidden = false;
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
{
if ( self.alpha != .5 )
self.alpha = .5;
self.bar.hidden = false;
if ( self.bar.alpha != 1 )
self.bar.alpha = 1;
}
else
{
if ( self.alpha != 1 )
self.alpha = 1;
}
}
flashThread()
{
self endon ( "death" );
if ( !self.hidden )
self.alpha = 1;
while(1)
{
if ( self.frac >= self.flashFrac )
{
if ( !self.hidden )
{
self fadeOverTime(0.3);
self.alpha = .2;
wait(0.35);
self fadeOverTime(0.3);
self.alpha = 1;
}
wait(0.7);
}
else
{
if ( !self.hidden && self.alpha != 1 )
self.alpha = 1;
wait ( 0.05 );
}
}
}
destroyElem()
{
tempChildren = [];
for ( index = 0; index < self.children.size; index++ )
{
if ( isDefined( self.children[index] ) )
tempChildren[tempChildren.size] = self.children[index];
}
for ( index = 0; index < tempChildren.size; index++ )
tempChildren[index] setParent( self getParent() );
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
{
self.bar destroy();
}
self destroy();
}
setIconShader( shader )
{
self setShader( shader );
self.shader = shader;
}
getIconShader( shader )
{
return self.shader;
}
setIconSize( width, height )
{
assert( isDefined( self.shader ) );
self setShader( self.shader, width, height );
}
setWidth( width )
{
self.width = width;
}
setHeight( height )
{
self.height = height;
}
setSize( width, height )
{
self.width = width;
self.height = height;
}
updateChildren()
{
for ( index = 0; index < self.children.size; index++ )
{
child = self.children[index];
child setPoint( child.point, child.relativePoint, child.xOffset, child.yOffset );
}
}
transitionReset()
{
self.x = self.xOffset;
self.y = self.yOffset;
if ( self.elemType == "font" )
{
self.fontScale = self.baseFontScale;
self.label = &"";
}
else if ( self.elemType == "icon" )
{
//self scaleOverTime( 0.001, self.width, self.height );
self setShader( self.shader, self.width, self.height );
}
self.alpha = 0;
}
transitionZoomIn( duration )
{
switch ( self.elemType )
{
case "font":
case "timer":
self.fontScale = 6.3;
self changeFontScaleOverTime( duration );
self.fontScale = self.baseFontScale;
break;
case "icon":
self setShader( self.shader, self.width * 6, self.height * 6 );
self scaleOverTime( duration, self.width, self.height );
break;
}
}
transitionPulseFXIn( inTime, duration )
{
transTime = int(inTime)*1000;
showTime = int(duration)*1000;
switch ( self.elemType )
{
case "font":
case "timer":
self setPulseFX( transTime+250, showTime+transTime, transTime+250 );
break;
default:
break;
}
}
transitionSlideIn( duration, direction )
{
if ( !isDefined( direction ) )
direction = "left";
switch ( direction )
{
case "left":
self.x += 1000;
break;
case "right":
self.x -= 1000;
break;
case "up":
self.y -= 1000;
break;
case "down":
self.y += 1000;
break;
}
self moveOverTime( duration );
self.x = self.xOffset;
self.y = self.yOffset;
}
transitionSlideOut( duration, direction )
{
if ( !isDefined( direction ) )
direction = "left";
gotoX = self.xOffset;
gotoY = self.yOffset;
switch ( direction )
{
case "left":
gotoX += 1000;
break;
case "right":
gotoX -= 1000;
break;
case "up":
gotoY -= 1000;
break;
case "down":
gotoY += 1000;
break;
}
self.alpha = 1;
self moveOverTime( duration );
self.x = gotoX;
self.y = gotoY;
}
transitionZoomOut( duration )
{
switch ( self.elemType )
{
case "font":
case "timer":
self changeFontScaleOverTime( duration );
self.fontScale = 6.3;
case "icon":
self scaleOverTime( duration, self.width * 6, self.height * 6 );
break;
}
}
transitionFadeIn( duration )
{
self fadeOverTime( duration );
if ( isDefined( self.maxAlpha ) )
self.alpha = self.maxAlpha;
else
self.alpha = 1;
}
transitionFadeOut( duration )
{
self fadeOverTime( 0.15 );
self.alpha = 0;
}

View File

@ -0,0 +1,691 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
precacheString(&"PLATFORM_PRESS_TO_SKIP");
precacheString(&"PLATFORM_PRESS_TO_RESPAWN");
precacheString(&"PLATFORM_PRESS_TO_COPYCAT");
precacheShader("specialty_copycat");
level._killcam = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "allowkillcam" );
}
killcam(
attackerNum, // entity number of the attacker
killcamentityindex, // entity number of the entity to view (grenade, airstrike, etc)
killcamentitystarttime, // time at which the killcamentity came into being
sWeapon, // killing weapon
predelay, // time between player death and beginning of killcam
offsetTime, // something to do with how far back in time the killer was seeing the world when he made the kill; latency related, sorta
timeUntilRespawn, // will the player be allowed to respawn after the killcam?
maxtime, // time remaining until map ends; the killcam will never last longer than this. undefined = no limit
attacker, // entity object of attacker
victim // entity object of the victim
)
{
// monitors killcam and hides HUD elements during killcam session
//if ( !level.splitscreen )
// self thread killcam_HUD_off();
self endon("disconnect");
self endon("spawned");
level endon("game_ended");
if ( attackerNum < 0 )
return;
// length from killcam start to killcam end
if (getdvar("scr_killcam_time") == "")
{
if ( sWeapon == "artillery_mp" || sWeapon == "stealth_bomb_mp" )
camtime = (gettime() - killcamentitystarttime) / 1000 - predelay - .1;
else if ( level._showingFinalKillcam )
camtime = 4.0;
else if ( sWeapon == "javelin_mp" )
camtime = 8;
else if ( issubstr( sWeapon, "remotemissile_" ) )
camtime = 5;
else if ( !timeUntilRespawn || timeUntilRespawn > 5.0 ) // if we're not going to respawn, we can take more time to watch what happened
camtime = 5.0;
else if ( sWeapon == "frag_grenade_mp" || sWeapon == "frag_grenade_short_mp" || sWeapon == "semtex_mp" )
camtime = 4.25; // show long enough to see grenade thrown
else
camtime = 2.5;
}
else
camtime = getdvarfloat("scr_killcam_time");
if (isdefined(maxtime)) {
if (camtime > maxtime)
camtime = maxtime;
if (camtime < .05)
camtime = .05;
}
// time after player death that killcam continues for
if (getdvar("scr_killcam_posttime") == "")
postdelay = 2;
else {
postdelay = getdvarfloat("scr_killcam_posttime");
if (postdelay < 0.05)
postdelay = 0.05;
}
/* timeline:
| camtime | postdelay |
| | predelay |
^ killcam start ^ player death ^ killcam end
^ player starts watching killcam
*/
killcamlength = camtime + postdelay;
// don't let the killcam last past the end of the round.
if (isdefined(maxtime) && killcamlength > maxtime)
{
// first trim postdelay down to a minimum of 1 second.
// if that doesn't make it short enough, trim camtime down to a minimum of 1 second.
// if that's still not short enough, cancel the killcam.
if ( maxtime < 2 )
return;
if (maxtime - camtime >= 1) {
// reduce postdelay so killcam ends at end of match
postdelay = maxtime - camtime;
}
else {
// distribute remaining time over postdelay and camtime
postdelay = 1;
camtime = maxtime - 1;
}
// recalc killcamlength
killcamlength = camtime + postdelay;
}
killcamoffset = camtime + predelay;
startTime = getTime();
self notify ( "begin_killcam", startTime );
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
// To specifically wait for the button presses for Y or B
self thread maps\mp\_upgrade::waitForYButtonPress();
self thread maps\mp\_upgrade::waitForBButtonPress();
}
self.sessionstate = "spectator";
self.forcespectatorclient = attackerNum;
self.killcamentity = -1;
if ( killcamentityindex >= 0 )
self thread setKillCamEntity( killcamentityindex, killcamoffset, killcamentitystarttime );
self.archivetime = killcamoffset;
self.killcamlength = killcamlength;
self.psoffsettime = offsetTime;
// ignore spectate permissions
self allowSpectateTeam("allies", true);
self allowSpectateTeam("axis", true);
self allowSpectateTeam("freelook", true);
self allowSpectateTeam("none", true);
if( level._multiTeamBased )
{
foreach( teamname in level._teamNameList )
{
self allowSpectateTeam( teamname, true );
}
}
if ( isDefined( attacker ) && level._showingFinalKillcam ) // attacker may have disconnected
{
self openMenu( "killedby_card_display" );
self SetCardDisplaySlot( attacker, 7 );
}
self thread endedKillcamCleanup();
// wait till the next server frame to allow code a chance to update archivetime if it needs trimming
wait 0.05;
assertex( self.archivetime <= killcamoffset + 0.0001, "archivetime: " + self.archivetime + ", killcamoffset: " + killcamoffset );
if ( self.archivetime < killcamoffset )
println( "WARNING: Code trimmed killcam time by " + (killcamoffset - self.archivetime) + " seconds because it doesn't have enough game time recorded!" );
camtime = self.archivetime - .05 - predelay;
killcamlength = camtime + postdelay;
self.killcamlength = killcamlength;
if ( camtime <= 0 ) // if we're not looking back in time far enough to even see the death, cancel
{
println( "Cancelling killcam because we don't even have enough recorded to show the death." );
self.sessionstate = "dead";
self.forcespectatorclient = -1;
self.killcamentity = -1;
self.archivetime = 0;
self.psoffsettime = 0;
self notify ( "killcam_ended" );
return;
}
if ( level._showingFinalKillcam )
thread doFinalKillCamFX( camtime );
self.killcam = true;
self initKCElements();
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
self maps\mp\_upgrade::initUpgradeElements();
}
if ( !level._splitscreen )
{
self.kc_timer.alpha = 1;
self.kc_timer setTenthsTimer(camtime);
}
if ( timeUntilRespawn && !level._gameEnded )
{
if ( timeUntilRespawn > 0 )
if ( isDefined( level._showSpawnTimer ) && level._showSpawnTimer )
{
setLowerMessage( "kc_info", game["strings"]["waiting_to_spawn"], timeUntilRespawn, 1, true );
}
else
{
setLowerMessage( "kc_info", game["strings"]["waiting_to_spawn"], timeUntilRespawn );
}
else
setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_SKIP" );
}
else if ( !level._gameEnded )
{
setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_RESPAWN" );
}
if ( !level._showingFinalKillcam )
{
self.kc_skiptext.alpha = 1;
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
self maps\mp\_upgrade::showUpgradeHUDElement();
}
}
else
self.kc_skiptext.alpha = 0;
self.kc_othertext.alpha = 0;
self.kc_icon.alpha = 0;
self thread spawnedKillcamCleanup();
if ( self == victim && victim _hasPerk( "specialty_copycat" ) && isDefined( victim.pers["copyCatLoadout"] ) )
self thread waitKCCopyCatButton( attacker );
if ( !level._showingFinalKillcam )
self thread waitSkipKillcamButton( timeUntilRespawn );
else
self notify ( "showing_final_killcam" );
self thread endKillcamIfNothingToShow();
self waittillKillcamOver();
if ( level._showingFinalKillcam )
{
self thread maps\mp\gametypes\_playerlogic::spawnEndOfGame();
return;
}
self thread calculateKillCamTime( startTime );
self thread killcamCleanup( true );
}
doFinalKillCamFX( camTime )
{
if ( isDefined( level._doingFinalKillcamFx ) )
return;
level._doingFinalKillcamFx = true;
intoSlowMoTime = camTime;
if ( intoSlowMoTime > 1.0 )
{
intoSlowMoTime = 1.0;
wait( camTime - 1.0 );
}
setSlowMotion( 1.0, 0.25, intoSlowMoTime ); // start timescale, end timescale, lerp duration
wait( intoSlowMoTime + .5 );
setSlowMotion( 0.25, 1, 1.0 );
level._doingFinalKillcamFx = undefined;
}
calculateKillCamTime( startTime )
{
watchedTime = int(getTime() - startTime);
self incPlayerStat( "killcamtimewatched", watchedTime );
}
waittillKillcamOver()
{
self endon("abort_killcam");
wait(self.killcamlength - 0.05);
}
setKillCamEntity( killcamentityindex, killcamoffset, starttime )
{
self endon("disconnect");
self endon("killcam_ended");
killcamtime = (gettime() - killcamoffset * 1000);
if ( starttime > killcamtime )
{
wait .05;
// code may have trimmed archivetime after the first frame if we couldn't go back in time as far as requested.
killcamoffset = self.archivetime;
killcamtime = (gettime() - killcamoffset * 1000);
if ( starttime > killcamtime )
wait (starttime - killcamtime) / 1000;
}
self.killcamentity = killcamentityindex;
}
waitSkipKillcamButton( timeUntilRespawn )
{
self endon("disconnect");
self endon("killcam_ended");
while(self cancelKillCamUseButton())
wait .05;
while(!(self cancelKillCamUseButton()))
wait .05;
if ( !matchMakingGame() )
self incPlayerStat( "killcamskipped", 1 );
if ( timeUntilRespawn <= 0 )
clearLowerMessage( "kc_info" );
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
self maps\mp\_upgrade::processUpgradeSelections();
}
self notify("abort_killcam");
}
waitKCCopyCatButton( attacker )
{
self endon("disconnect");
self endon("killcam_ended");
self waitCopyCatButton( attacker );
self notify("abort_killcam");
}
waitDeathCopyCatButton( attacker )
{
self endon ( "disconnect" );
self initKCElements();
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
self maps\mp\_upgrade::initUpgradeElements();
}
usedCopycat = self waitCopyCatButton( attacker );
if ( !isDefined( usedCopycat ) )
{
self.kc_icon.alpha = 0;
self.kc_othertext.alpha = 0;
}
}
waitCopyCatButton( attacker )
{
self endon ( "spawned_player" );
self endon ( "death_delay_finished" );
self.kc_icon setShader( "specialty_copycat", 48, 48 );
self.kc_othertext setText( &"PLATFORM_PRESS_TO_COPYCAT" );
self.kc_othertext.alpha = 1;
self.kc_icon.alpha = 1;
self notifyOnPlayerCommand( "use_copycat", "weapnext" );
self waittill( "use_copycat" );
self.pers["copyCatLoadout"]["inUse"] = true;
self.pers["copyCatLoadout"]["owner"] = attacker;
self.kc_othertext fadeOverTime( 0.5 );
self.kc_othertext.alpha = 0;
self.kc_icon fadeOverTime( 0.25 );
self.kc_icon scaleOverTime( 0.25, 512, 512 );
self.kc_icon.alpha = 0;
if ( isDefined( attacker ) )
attacker thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "copied", self );
self playLocalSound( "copycat_steal_class" );
return true;
}
waitSkipKillcamSafeSpawnButton()
{
self endon("disconnect");
self endon("killcam_ended");
if ( !self maps\mp\gametypes\_playerlogic::maySpawn() )
return;
while(self fragButtonPressed())
wait .05;
while(!(self fragButtonPressed()))
wait .05;
self.wantSafeSpawn = true;
self notify("abort_killcam");
}
endKillcamIfNothingToShow()
{
self endon("disconnect");
self endon("killcam_ended");
while(1)
{
// code may trim our archivetime to zero if there is nothing "recorded" to show.
// this can happen when the person we're watching in our killcam goes into killcam himself.
// in this case, end the killcam.
if ( self.archivetime <= 0 )
break;
wait .05;
}
self notify("abort_killcam");
}
spawnedKillcamCleanup()
{
self endon("disconnect");
self endon("killcam_ended");
self waittill("spawned");
self thread killcamCleanup( false );
}
endedKillcamCleanup()
{
self endon("disconnect");
self endon("killcam_ended");
level waittill("game_ended");
self thread killcamCleanup( true );
}
killcamCleanup( clearState )
{
if(isDefined(self.kc_skiptext))
self.kc_skiptext.alpha = 0;
if(isDefined(self.kc_timer))
self.kc_timer.alpha = 0;
if(isDefined(self.kc_icon))
self.kc_icon.alpha = 0;
if(isDefined(self.kc_othertext))
self.kc_othertext.alpha = 0;
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
maps\mp\_upgrade::upgradeHUDCleanUp();
}
self.killcam = undefined;
if ( !level._gameEnded )
self clearLowerMessage( "kc_info" );
self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
self notify("killcam_ended"); // do this last, in case this function was called from a thread ending on it
if ( !clearState )
return;
self.sessionstate = "dead";
self ClearKillcamState();
}
cancelKillCamOnUse()
{
self.cancelKillcam = false;
self thread cancelKillCamOnUse_specificButton( ::cancelKillCamUseButton, ::cancelKillCamCallback );
//self thread cancelKillCamOnUse_specificButton( ::cancelKillCamSafeSpawnButton, ::cancelKillCamSafeSpawnCallback );
}
cancelKillCamUseButton()
{
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
if ( self useButtonPressed())
{
self.killCamButtonPressed = "use";
return true;
}
else if ( self JumpButtonPressed())
{
self.killCamButtonPressed = "jump";
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["jump"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["jump"] )))
{
return true;
}
else
{
return false;
}
}
else if ( self maps\mp\_upgrade::ReloadButtonPressed())
{
self.killCamButtonPressed = "switchWeap";
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["switchWeap"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["switchWeap"] )))
{
return true;
}
else
{
return false;
}
}
else if ( self maps\mp\_upgrade::ProneButtonPressed())
{
self.killCamButtonPressed = "prone";
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["prone"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["prone"] )))
{
return true;
}
else
{
return false;
}
}
return false;
}
else
{
return self useButtonPressed();
}
}
cancelKillCamSafeSpawnButton()
{
return self fragButtonPressed();
}
cancelKillCamCallback()
{
self.cancelKillcam = true;
}
cancelKillCamSafeSpawnCallback()
{
self.cancelKillcam = true;
self.wantSafeSpawn = true;
}
cancelKillCamOnUse_specificButton( pressingButtonFunc, finishedFunc )
{
self endon ( "death_delay_finished" );
self endon ( "disconnect" );
level endon ( "game_ended" );
for ( ;; )
{
if ( !self [[pressingButtonFunc]]() )
{
wait ( 0.05 );
continue;
}
buttonTime = 0;
while( self [[pressingButtonFunc]]() )
{
buttonTime += 0.05;
wait ( 0.05 );
}
if ( buttonTime >= 0.5 )
continue;
buttonTime = 0;
while ( !self [[pressingButtonFunc]]() && buttonTime < 0.5 )
{
buttonTime += 0.05;
wait ( 0.05 );
}
if ( buttonTime >= 0.5 )
continue;
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
self maps\mp\_upgrade::processUpgradeSelections();
}
self [[finishedFunc]]();
return;
}
}
initKCElements()
{
if ( !isDefined( self.kc_skiptext ) )
{
self.kc_skiptext = newClientHudElem(self);
self.kc_skiptext.archived = false;
self.kc_skiptext.x = 0;
self.kc_skiptext.alignX = "center";
self.kc_skiptext.alignY = "top";
self.kc_skiptext.horzAlign = "center_adjustable";
self.kc_skiptext.vertAlign = "top_adjustable";
self.kc_skiptext.sort = 1; // force to draw after the bars
self.kc_skiptext.font = "default";
self.kc_skiptext.foreground = true;
self.kc_skiptext.hideWhenInMenu = true;
if ( level._splitscreen )
{
self.kc_skiptext.y = 20;
self.kc_skiptext.fontscale = 1.2; // 1.8/1.5
}
else
{
self.kc_skiptext.y = 32;
self.kc_skiptext.fontscale = 1.8;
}
}
if ( !isDefined( self.kc_othertext ) )
{
self.kc_othertext = newClientHudElem(self);
self.kc_othertext.archived = false;
self.kc_othertext.y = 48;
self.kc_othertext.alignX = "left";
self.kc_othertext.alignY = "top";
self.kc_othertext.horzAlign = "center";
self.kc_othertext.vertAlign = "middle";
self.kc_othertext.sort = 10; // force to draw after the bars
self.kc_othertext.font = "small";
self.kc_othertext.foreground = true;
self.kc_othertext.hideWhenInMenu = true;
if ( level._splitscreen )
{
self.kc_othertext.x = 16;
self.kc_othertext.fontscale = 1.2;
}
else
{
self.kc_othertext.x = 32;
self.kc_othertext.fontscale = 1.6;
}
}
if ( !isDefined( self.kc_icon ) )
{
self.kc_icon = newClientHudElem(self);
self.kc_icon.archived = false;
self.kc_icon.x = 16;
self.kc_icon.y = 16;
self.kc_icon.alignX = "left";
self.kc_icon.alignY = "top";
self.kc_icon.horzAlign = "center";
self.kc_icon.vertAlign = "middle";
self.kc_icon.sort = 1; // force to draw after the bars
self.kc_icon.foreground = true;
self.kc_icon.hideWhenInMenu = true;
}
if ( !level._splitscreen )
{
if ( !isdefined( self.kc_timer ) )
{
self.kc_timer = createFontString( "hudbig", 1.0 );
self.kc_timer.archived = false;
self.kc_timer.x = 0;
self.kc_timer.alignX = "center";
self.kc_timer.alignY = "middle";
self.kc_timer.horzAlign = "center_safearea";
self.kc_timer.vertAlign = "top_adjustable";
self.kc_timer.y = 42;
self.kc_timer.sort = 1; // force to draw after the bars
self.kc_timer.font = "hudbig";
self.kc_timer.foreground = true;
self.kc_timer.color = (0.85,0.85,0.85);
self.kc_timer.hideWhenInMenu = true;
}
}
}

View File

@ -0,0 +1,589 @@
#include maps\mp\_utility;
init()
{
if ( !isDefined( game["gamestarted"] ) )
{
game["menu_team"] = "team_marinesopfor";
if( level._multiTeamBased )
{
game["menu_team"] = "team_mtdm_options";
}
game["menu_class_allies"] = "class_marines";
game["menu_changeclass_allies"] = "changeclass_marines";
game["menu_initteam_allies"] = "initteam_marines";
game["menu_class_axis"] = "class_opfor";
game["menu_changeclass_axis"] = "changeclass_opfor";
game["menu_initteam_axis"] = "initteam_opfor";
game["menu_class"] = "class";
game["menu_changeclass"] = "changeclass";
game["menu_onemanarmy"] = "onemanarmy";
game["menu_exosuit"] = "exosuit";
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
str_menu_class = "menu_class_" + level._teamNameList[i];
str_menu_changeclass = "menu_changeclass_" + level._teamNameList[i];
str_menu_initteam = "menu_initteam_" + level._teamNameList[i];
game[str_menu_class] = "class_marines";
game[str_menu_changeclass] = "changeclass_marines";
game[str_menu_initteam] = "initteam_marines";
}
}
if ( !level._console )
{
game["menu_callvote"] = "callvote";
game["menu_muteplayer"] = "muteplayer";
precacheMenu(game["menu_callvote"]);
precacheMenu(game["menu_muteplayer"]);
}
else
{
game["menu_controls"] = "ingame_controls";
//game["menu_options"] = "ingame_options";
game["menu_leavegame"] = "popup_leavegame";
if(level._splitscreen)
{
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
str_menu_class = "menu_class_" + level._teamNameList[i];
str_menu_changeclass = "menu_changeclass_" + level._teamNameList[i];
game[str_menu_class] += "_splitscreen";
game[str_menu_changeclass] += "_splitscreen";
}
}
game["menu_team"] += "_splitscreen";
game["menu_class_allies"] += "_splitscreen";
game["menu_changeclass_allies"] += "_splitscreen";
game["menu_class_axis"] += "_splitscreen";
game["menu_changeclass_axis"] += "_splitscreen";
game["menu_class"] += "_splitscreen";
game["menu_controls"] += "_splitscreen";
//game["menu_options"] += "_splitscreen";
game["menu_leavegame"] += "_splitscreen";
game["menu_onemanarmy"] += "_splitscreen";
game["menu_changeclass_defaults_splitscreen"] = "changeclass_defaults_splitscreen";
game["menu_changeclass_custom_splitscreen"] = "changeclass_custom_splitscreen";
game["menu_onemanarmy_defaults_splitscreen"] = "onemanarmy_defaults_splitscreen";
game["menu_onemanarmy_custom_splitscreen"] = "onemanarmy_custom_splitscreen";
precacheMenu(game["menu_changeclass_defaults_splitscreen"]);
precacheMenu(game["menu_changeclass_custom_splitscreen"]);
precacheMenu(game["menu_onemanarmy_defaults_splitscreen"]);
precacheMenu(game["menu_onemanarmy_custom_splitscreen"]);
}
precacheMenu(game["menu_controls"]);
//precacheMenu(game["menu_options"]);
precacheMenu(game["menu_leavegame"]);
//precacheMenu("status_update");
}
precacheMenu("scoreboard");
precacheMenu(game["menu_team"]);
precacheMenu(game["menu_class_allies"]);
precacheMenu(game["menu_changeclass_allies"]);
precacheMenu(game["menu_initteam_allies"]);
precacheMenu(game["menu_class_axis"]);
precacheMenu(game["menu_changeclass_axis"]);
precacheMenu(game["menu_class"]);
precacheMenu(game["menu_changeclass"]);
precacheMenu(game["menu_initteam_axis"]);
precacheMenu(game["menu_onemanarmy"]);
precacheMenu(game["menu_exosuit"]);
precacheString( &"MP_HOST_ENDED_GAME" );
precacheString( &"MP_HOST_ENDGAME_RESPONSE" );
}
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onMenuResponse();
}
}
onMenuResponse()
{
self endon("disconnect");
for(;;)
{
self waittill("menuresponse", menu, response);
if ( response == "back" )
{
self closepopupMenu();
self closeInGameMenu();
if ( level._console )
{
if ( menu == game["menu_changeclass"] ||
menu == game["menu_team"] ||
menu == game["menu_controls"] ||
( isDefined( game["menu_changeclass_defaults_splitscreen"] ) && menu == game["menu_changeclass_defaults_splitscreen"] ) ||
( isDefined( game["menu_changeclass_custom_splitscreen"] ) && menu == game["menu_changeclass_custom_splitscreen"] ) )
{
if( self.pers["team"] == "allies" )
self openpopupMenu( game["menu_class_allies"] );
if( self.pers["team"] == "axis" )
self openpopupMenu( game["menu_class_axis"] );
}
}
continue;
}
if(response == "changeteam")
{
self closepopupMenu();
self closeInGameMenu();
self openpopupMenu(game["menu_team"]);
}
if(response == "changeclass_marines" )
{
self closepopupMenu();
self closeInGameMenu();
self openpopupMenu( game["menu_changeclass_allies"] );
continue;
}
if(response == "changeclass_opfor" )
{
self closepopupMenu();
self closeInGameMenu();
self openpopupMenu( game["menu_changeclass_axis"] );
continue;
}
if(response == "changeclass_marines_splitscreen" )
self openpopupMenu( "changeclass_marines_splitscreen" );
if(response == "changeclass_opfor_splitscreen" )
self openpopupMenu( "changeclass_opfor_splitscreen" );
if(response == "endgame")
{
if(level._splitscreen)
{
endparty();
if ( !level._gameEnded )
{
level thread maps\mp\gametypes\_gamelogic::forceEnd();
}
}
continue;
}
if ( response == "endround" )
{
if ( !level._gameEnded )
{
level thread maps\mp\gametypes\_gamelogic::forceEnd();
}
else
{
self closepopupMenu();
self closeInGameMenu();
self iprintln( &"MP_HOST_ENDGAME_RESPONSE" );
}
continue;
}
if ( menu == game["menu_team"] )
{
switch( response )
{
case "autoassign":
self [[level._autoassign]]();
break;
case "spectator":
self [[level._spectator]]();
break;
default:
self [[level._onTeamSelection]]( response );
}
} // the only responses remain are change class events
else if ( menu == game["menu_changeclass"] ||
( isDefined( game["menu_changeclass_defaults_splitscreen"] ) && menu == game["menu_changeclass_defaults_splitscreen"] ) ||
( isDefined( game["menu_changeclass_custom_splitscreen"] ) && menu == game["menu_changeclass_custom_splitscreen"] ) )
{
self closepopupMenu();
self closeInGameMenu();
self.selectedClass = true;
self [[level._class]](response);
}
else if ( !level._console )
{
if(menu == game["menu_quickcommands"])
maps\mp\gametypes\_quickmessages::quickcommands(response);
else if(menu == game["menu_quickstatements"])
maps\mp\gametypes\_quickmessages::quickstatements(response);
else if(menu == game["menu_quickresponses"])
maps\mp\gametypes\_quickmessages::quickresponses(response);
}
}
}
onMenuTeamSelect( selection )
{
self closeMenus();
if(self.pers["team"] != selection)
{
if( level._teamBased && !maps\mp\gametypes\_teams::getJoinTeamPermissions( selection ) )
{
self openpopupMenu(game["menu_team"]);
return;
}
// allow respawn when switching teams during grace period.
if ( level._inGracePeriod && !self.hasDoneCombat )
self.hasSpawned = false;
if(self.sessionstate == "playing")
{
self.switching_teams = true;
self.joining_team = selection;
self.leaving_team = self.pers["team"];
self suicide();
}
self addToTeam( selection );
self.pers["class"] = undefined;
self.class = undefined;
self notify("end_respawn");
}
self beginClassChoice();
}
getTeamAssignment()
{
teams[0] = "allies";
teams[1] = "axis";
if ( !level._teamBased )
return teams[randomInt(2)];
//If sessionteam is already set, it is probably because you are in a matchmaking game
if ( self.sessionteam != "none" && self.sessionteam != "spectator" && self.sessionstate != "playing" && self.sessionstate != "dead" )
{
assignment = self.sessionteam;
}
else if( level._multiTeamBased )
{
/#
println( "" );
println( "SETTING TEAM ASSIGNMENT" );
println( "max num teams = " + level._teamNameList.size );
#/
numTeams = level._teamNameList.size;
//scan for smallest team, assign new player to that team
teamAssignment = level._teamNameList[0];
for( i = 0; i < level._teamNameList.size; i++ )
{
/#
println( level._teamNameList[i] + " has " + level._teamCount[level._teamNameList[i]] + " players on it." );
#/
if ( level._teamCount[level._teamNameList[i]] < level._teamCount[teamAssignment] )
{
teamAssignment = level._teamNameList[i];
}
}
/#
println( "Team assignment = " + teamAssignment );
println( "" );
#/
return teamAssignment;
}
else
{
playerCounts = self maps\mp\gametypes\_teams::CountPlayers();
// if teams are equal return the team with the lowest score
if ( playerCounts["allies"] == playerCounts["axis"] )
{
if( getTeamScore( "allies" ) == getTeamScore( "axis" ) )
assignment = teams[randomInt(2)];
else if ( getTeamScore( "allies" ) < getTeamScore( "axis" ) )
assignment = "allies";
else
assignment = "axis";
}
else if( playerCounts["allies"] < playerCounts["axis"] )
{
assignment = "allies";
}
else
{
assignment = "axis";
}
}
return assignment;
}
menuAutoAssign()
{
self closeMenus();
assignment = getTeamAssignment();
if ( isDefined( self.pers["team"] ) && (self.sessionstate == "playing" || self.sessionstate == "dead") )
{
if ( assignment == self.pers["team"] )
{
self beginClassChoice();
return;
}
else
{
self.switching_teams = true;
self.joining_team = assignment;
self.leaving_team = self.pers["team"];
self suicide();
}
}
self addToTeam( assignment );
self.pers["class"] = undefined;
self.class = undefined;
if ( !isAlive( self ) )
self.statusicon = "hud_status_dead";
self notify("end_respawn");
self beginClassChoice();
}
beginClassChoice( forceNewChoice )
{
if( !level._multiTeamBased )
{
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
}
team = self.pers["team"];
// menu_changeclass_team is the one where you choose one of the n classes to play as.
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
self openpopupMenu( game[ "menu_changeclass_" + team ] );
if ( !isAlive( self ) )
self thread maps\mp\gametypes\_playerlogic::predictAboutToSpawnPlayerOverTime( 0.1 );
}
beginTeamChoice()
{
self openpopupMenu( game["menu_team"] );
}
showMainMenuForTeam()
{
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
team = self.pers["team"];
// menu_changeclass_team is the one where you choose one of the n classes to play as.
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
self openpopupMenu( game[ "menu_class_" + team ] );
}
menuSpectator()
{
self closeMenus();
if( isDefined( self.pers["team"] ) && self.pers["team"] == "spectator" )
return;
if( isAlive( self ) )
{
assert( isDefined( self.pers["team"] ) );
self.switching_teams = true;
self.joining_team = "spectator";
self.leaving_team = self.pers["team"];
self suicide();
}
self addToTeam( "spectator" );
self.pers["class"] = undefined;
self.class = undefined;
self thread maps\mp\gametypes\_playerlogic::spawnSpectator();
}
menuClass( response )
{
self closeMenus();
// clear new status of unlocked classes
if ( response == "demolitions_mp,0" && self getPlayerData( "featureNew", "demolitions" ) )
{
self setPlayerData( "featureNew", "demolitions", false );
}
if ( response == "sniper_mp,0" && self getPlayerData( "featureNew", "sniper" ) )
{
self setPlayerData( "featureNew", "sniper", false );
}
// this should probably be an assert
if( !level._multiTeamBased )
{
if(!isDefined(self.pers["team"]) || (self.pers["team"] != "allies" && self.pers["team"] != "axis"))
return;
}
class = self maps\mp\gametypes\_class::getClassChoice( response );
primary = self maps\mp\gametypes\_class::getWeaponChoice( response );
if ( class == "restricted" )
{
self beginClassChoice();
return;
}
if( (isDefined( self.pers["class"] ) && self.pers["class"] == class) &&
(isDefined( self.pers["primary"] ) && self.pers["primary"] == primary) )
return;
if ( self.sessionstate == "playing" )
{
self.pers["class"] = class;
self.class = class;
self.pers["primary"] = primary;
if ( game["state"] == "postgame" )
return;
if ( level._inGracePeriod && !self.hasDoneCombat ) // used weapons check?
{
if ( !isGameModeBlockingClassChange())
{
self maps\mp\gametypes\_class::setClass( self.pers["class"] );
self.tag_stowed_back = undefined;
self.tag_stowed_hip = undefined;
self maps\mp\gametypes\_class::giveLoadout( self.pers["team"], self.pers["class"] );
}
}
else
{
if ( !isGameModeBlockingClassChange())
{
self iPrintLnBold( game["strings"]["change_class"] );
}
}
}
else
{
self.pers["class"] = class;
self.class = class;
self.pers["primary"] = primary;
if ( game["state"] == "postgame" )
return;
if ( game["state"] == "playing" && !isInKillcam() )
self thread maps\mp\gametypes\_playerlogic::spawnClient();
}
self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
}
addToTeam( team, firstConnect )
{
// UTS update playerCount remove from team
if ( isDefined( self.team ) )
self maps\mp\gametypes\_playerlogic::removeFromTeamCount();
self.pers["team"] = team;
// this is the only place self.team should ever be set
self.team = team;
// session team is readonly in ranked matches on console
if ( !matchMakingGame() || isDefined( self.pers["isBot"] ) )
{
if ( level._teamBased )
{
self.sessionteam = team;
}
else
{
if ( team == "spectator" )
self.sessionteam = "spectator";
else
self.sessionteam = "none";
}
}
// UTS update playerCount add to team
if ( game["state"] != "postgame" )
self maps\mp\gametypes\_playerlogic::addToTeamCount();
self updateObjectiveText();
// give "joined_team" and "joined_spectators" handlers a chance to start
// these are generally triggered from the "connected" notify, which can happen on the same
// frame as these notifies
if ( isDefined( firstConnect ) && firstConnect )
waittillframeend;
self updateMainMenu();
if ( team == "spectator" )
{
self notify( "joined_spectators" );
level notify( "joined_team" );
}
else
{
self notify( "joined_team" );
level notify( "joined_team" );
}
}
isGameModeBlockingClassChange()
{
result = false;
if ( isDefined( level._blockClassChange) && level._blockClassChange == true )
{
result = true;
}
return result;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,512 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
if( level._multiTeamBased == true )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
str_spawn_team = "spawn_" + level._teamNameList[i];
str_defeat_team = "defeat_" + level._teamNameList[i];
str_victory_team = "victory_" + level._teamNameList[i];
str_winning_team = "winning_" + level._teamNameList[i];
str_losing_team = "losing_" + level._teamNameList[i];
game["music"][str_spawn_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "spawn_music";
game["music"][str_defeat_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "defeat_music";
game["music"][str_victory_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "victory_music";
game["music"][str_winning_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "winning_music";
game["music"][str_losing_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "losing_music";
game["voice"][level._teamNameList[i]] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "1mc_";
}
}
game["music"]["spawn_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "spawn_music";
game["music"]["defeat_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "defeat_music";
game["music"]["victory_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "victory_music";
game["music"]["winning_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "winning_music";
game["music"]["losing_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "losing_music";
game["voice"]["allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "1mc_";
game["music"]["spawn_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "spawn_music";
game["music"]["defeat_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "defeat_music";
game["music"]["victory_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "victory_music";
game["music"]["winning_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "winning_music";
game["music"]["losing_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "losing_music";
game["voice"]["axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "1mc_";
game["music"]["defeat"] = "mp_defeat";
game["music"]["victory_spectator"] = "mp_defeat";
game["music"]["winning_time"] = "mp_time_running_out_winning";
game["music"]["losing_time"] = "mp_time_running_out_losing";
game["music"]["winning_score"] = "mp_time_running_out_winning";
game["music"]["losing_score"] = "mp_time_running_out_losing";
game["music"]["victory_tie"] = "mp_defeat";
game["music"]["suspense"] = [];
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_01";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_02";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_03";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_04";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_05";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_06";
game["dialog"]["mission_success"] = "mission_success";
game["dialog"]["mission_failure"] = "mission_fail";
game["dialog"]["mission_draw"] = "draw";
game["dialog"]["round_success"] = "encourage_win";
game["dialog"]["round_failure"] = "encourage_lost";
game["dialog"]["round_draw"] = "draw";
// status
game["dialog"]["timesup"] = "timesup";
game["dialog"]["winning_time"] = "winning";
game["dialog"]["losing_time"] = "losing";
game["dialog"]["winning_score"] = "winning_fight";
game["dialog"]["losing_score"] = "losing_fight";
game["dialog"]["lead_lost"] = "lead_lost";
game["dialog"]["lead_tied"] = "tied";
game["dialog"]["lead_taken"] = "lead_taken";
game["dialog"]["last_alive"] = "lastalive";
game["dialog"]["boost"] = "boost";
if ( !isDefined( game["dialog"]["offense_obj"] ) )
game["dialog"]["offense_obj"] = "boost";
if ( !isDefined( game["dialog"]["defense_obj"] ) )
game["dialog"]["defense_obj"] = "boost";
game["dialog"]["hardcore"] = "hardcore";
game["dialog"]["highspeed"] = "highspeed";
game["dialog"]["tactical"] = "tactical";
game["dialog"]["challenge"] = "challengecomplete";
game["dialog"]["promotion"] = "promotion";
game["dialog"]["bomb_taken"] = "acheive_bomb";
game["dialog"]["bomb_lost"] = "bomb_taken";
game["dialog"]["bomb_defused"] = "bomb_defused";
game["dialog"]["bomb_planted"] = "bomb_planted";
game["dialog"]["obj_taken"] = "securedobj";
game["dialog"]["obj_lost"] = "lostobj";
game["dialog"]["obj_defend"] = "obj_defend";
game["dialog"]["obj_destroy"] = "obj_destroy";
game["dialog"]["obj_capture"] = "capture_obj";
game["dialog"]["objs_capture"] = "capture_objs";
game["dialog"]["hq_located"] = "hq_located";
game["dialog"]["hq_enemy_captured"] = "hq_captured";
game["dialog"]["hq_enemy_destroyed"] = "hq_destroyed";
game["dialog"]["hq_secured"] = "hq_secured";
game["dialog"]["hq_offline"] = "hq_offline";
game["dialog"]["hq_online"] = "hq_online";
game["dialog"]["move_to_new"] = "new_positions";
game["dialog"]["push_forward"] = "pushforward";
game["dialog"]["attack"] = "attack";
game["dialog"]["defend"] = "defend";
game["dialog"]["offense"] = "offense";
game["dialog"]["defense"] = "defense";
game["dialog"]["halftime"] = "halftime";
game["dialog"]["overtime"] = "overtime";
game["dialog"]["side_switch"] = "switching";
game["dialog"]["flag_taken"] = "ourflag";
game["dialog"]["flag_dropped"] = "ourflag_drop";
game["dialog"]["flag_returned"] = "ourflag_return";
game["dialog"]["flag_captured"] = "ourflag_capt";
game["dialog"]["flag_getback"] = "getback_ourflag";
game["dialog"]["enemy_flag_bringhome"] = "enemyflag_tobase";
game["dialog"]["enemy_flag_taken"] = "enemyflag";
game["dialog"]["enemy_flag_dropped"] = "enemyflag_drop";
game["dialog"]["enemy_flag_returned"] = "enemyflag_return";
game["dialog"]["enemy_flag_captured"] = "enemyflag_capt";
game["dialog"]["capturing_a"] = "capturing_a";
game["dialog"]["capturing_b"] = "capturing_b";
game["dialog"]["capturing_c"] = "capturing_c";
game["dialog"]["captured_a"] = "capture_a";
game["dialog"]["captured_b"] = "capture_c";
game["dialog"]["captured_c"] = "capture_b";
game["dialog"]["securing_a"] = "securing_a";
game["dialog"]["securing_b"] = "securing_b";
game["dialog"]["securing_c"] = "securing_c";
game["dialog"]["secured_a"] = "secure_a";
game["dialog"]["secured_b"] = "secure_b";
game["dialog"]["secured_c"] = "secure_c";
game["dialog"]["losing_a"] = "losing_a";
game["dialog"]["losing_b"] = "losing_b";
game["dialog"]["losing_c"] = "losing_c";
game["dialog"]["lost_a"] = "lost_a";
game["dialog"]["lost_b"] = "lost_b";
game["dialog"]["lost_c"] = "lost_c";
game["dialog"]["enemy_taking_a"] = "enemy_take_a";
game["dialog"]["enemy_taking_b"] = "enemy_take_b";
game["dialog"]["enemy_taking_c"] = "enemy_take_c";
game["dialog"]["enemy_has_a"] = "enemy_has_a";
game["dialog"]["enemy_has_b"] = "enemy_has_b";
game["dialog"]["enemy_has_c"] = "enemy_has_c";
game["dialog"]["lost_all"] = "take_positions";
game["dialog"]["secure_all"] = "positions_lock";
game["dialog"]["destroy_sentry"] = "dest_sentrygun";
game["music"]["nuke_music"] = "nuke_music";
game["dialog"]["sentry_gone"] = "sentry_gone";
game["dialog"]["sentry_destroyed"] = "sentry_gone";
game["dialog"]["ti_gone"] = "ti_cancelled";
game["dialog"]["ti_destroyed"] = "ti_blocked";
level thread onPlayerConnect();
level thread onLastAlive();
level thread musicController();
level thread onGameEnded();
level thread onRoundSwitch();
}
onPlayerConnect()
{
for(;;)
{
level waittill ( "connected", player );
player thread onPlayerSpawned();
player thread finalKillcamMusic();
}
}
onPlayerSpawned()
{
self endon ( "disconnect" );
self waittill( "spawned_player" );
if ( !level._splitscreen || level._splitscreen && !isDefined( level._playedStartingMusic ) )
{
self playLocalSound( game["music"]["spawn_" + self.team] );
if ( level._splitscreen )
level._playedStartingMusic = true;
}
if ( isDefined( game["dialog"]["gametype"] ) && (!level._splitscreen || self == level._players[0]) )
{
if ( isDefined( game["dialog"]["allies_gametype"] ) && self.team == "allies" )
self leaderDialogOnPlayer( "allies_gametype" );
else if ( isDefined( game["dialog"]["axis_gametype"] ) && self.team == "axis" )
self leaderDialogOnPlayer( "axis_gametype" );
else
self leaderDialogOnPlayer( "gametype" );
}
gameFlagWait( "prematch_done" );
if ( self.team == game["attackers"] )
self leaderDialogOnPlayer( "offense_obj", "introboost" );
else
self leaderDialogOnPlayer( "defense_obj", "introboost" );
}
onLastAlive()
{
level endon ( "game_ended" );
level waittill ( "last_alive", player );
if ( !isAlive( player ) )
return;
player leaderDialogOnPlayer( "last_alive" );
}
onRoundSwitch()
{
level waittill ( "round_switch", switchType );
if( !isDefined( level._disableRoundSwitchVo ))
{
switch( switchType )
{
case "halftime":
foreach ( player in level._players )
player leaderDialogOnPlayer( "halftime" );
break;
case "overtime":
foreach ( player in level._players )
player leaderDialogOnPlayer( "overtime" );
break;
default:
foreach ( player in level._players )
player leaderDialogOnPlayer( "side_switch" );
break;
}
}
}
onGameEnded()
{
level thread roundWinnerDialog();
level thread gameWinnerDialog();
level waittill ( "game_win", winner );
if ( isDefined( level._nukeDetonated ) )
{
if ( !level._splitScreen )
playSoundOnPlayers( game["music"]["nuke_music"] );
else
level._players[0] playLocalSound( game["music"]["nuke_music"] );
return;
}
if ( level._teamBased )
{
if ( level._splitscreen )
{
if ( winner == "allies" )
playSoundOnPlayers( game["music"]["victory_allies"], "allies" );
else if ( winner == "axis" )
playSoundOnPlayers( game["music"]["victory_axis"], "axis" );
else
playSoundOnPlayers( game["music"]["nuke_music"] );
}
else
{
if ( winner == "allies" )
{
playSoundOnPlayers( game["music"]["victory_allies"], "allies" );
playSoundOnPlayers( game["music"]["defeat_axis"], "axis" );
}
else if ( winner == "axis" )
{
playSoundOnPlayers( game["music"]["victory_axis"], "axis" );
playSoundOnPlayers( game["music"]["defeat_allies"], "allies" );
}
else
{
playSoundOnPlayers( game["music"]["nuke_music"] );
}
}
}
else
{
foreach ( player in level._players )
{
if ( player.pers["team"] != "allies" && player.pers["team"] != "axis" )
player playLocalSound( game["music"]["nuke_music"] );
else if ( isDefined( winner ) && player == winner )
player playLocalSound( game["music"]["victory_" + player.pers["team"] ] );
else if ( !level._splitScreen )
player playLocalSound( game["music"]["defeat_" + player.pers["team"] ] );
}
}
}
roundWinnerDialog()
{
level waittill ( "round_win", winner );
delay = level._roundEndDelay / 4;
if ( delay > 0 )
wait ( delay );
if ( !isDefined( winner ) || isPlayer( winner ) || isDefined( level._nukeDetonated ) )
return;
if ( winner == "allies" )
{
leaderDialog( "round_success", "allies" );
leaderDialog( "round_failure", "axis" );
}
else if ( winner == "axis" )
{
leaderDialog( "round_success", "axis" );
leaderDialog( "round_failure", "allies" );
}
}
gameWinnerDialog()
{
level waittill ( "game_win", winner );
delay = level._postRoundTime / 2;
if ( delay > 0 )
wait ( delay );
if ( !isDefined( winner ) || isPlayer( winner ) || isDefined( level._nukeDetonated ) )
return;
if ( winner == "allies" )
{
leaderDialog( "mission_success", "allies" );
leaderDialog( "mission_failure", "axis" );
}
else if ( winner == "axis" )
{
leaderDialog( "mission_success", "axis" );
leaderDialog( "mission_failure", "allies" );
}
else
{
leaderDialog( "mission_draw" );
}
}
musicController()
{
level endon ( "game_ended" );
if ( !level._hardcoreMode )
thread suspenseMusic();
level waittill ( "match_ending_soon", reason );
assert( isDefined( reason ) );
if ( getWatchedDvar( "roundlimit" ) == 1 || game["roundsPlayed"] == (getWatchedDvar( "roundlimit" ) - 1) )
{
if ( !level._splitScreen )
{
if ( reason == "time" )
{
if ( level._teamBased )
{
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
{
if ( !level._hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_allies"], "allies" );
playSoundOnPlayers( game["music"]["losing_axis"], "axis" );
}
leaderDialog( "winning_time", "allies" );
leaderDialog( "losing_time", "axis" );
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
if ( !level._hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_axis"], "axis" );
playSoundOnPlayers( game["music"]["losing_allies"], "allies" );
}
leaderDialog( "winning_time", "axis" );
leaderDialog( "losing_time", "allies" );
}
}
else
{
if ( !level._hardcoreMode )
playSoundOnPlayers( game["music"]["losing_time"] );
leaderDialog( "timesup" );
}
}
else if ( reason == "score" )
{
if ( level._teamBased )
{
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
{
if ( !level._hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_allies"], "allies" );
playSoundOnPlayers( game["music"]["losing_axis"], "axis" );
}
leaderDialog( "winning_score", "allies" );
leaderDialog( "losing_score", "axis" );
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
if ( !level._hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_axis"], "axis" );
playSoundOnPlayers( game["music"]["losing_allies"], "allies" );
}
leaderDialog( "winning_score", "axis" );
leaderDialog( "losing_score", "allies" );
}
}
else
{
winningPlayer = maps\mp\gametypes\_gamescore::getHighestScoringPlayer();
losingPlayers = maps\mp\gametypes\_gamescore::getLosingPlayers();
excludeList[0] = winningPlayer;
if ( !level._hardcoreMode )
{
winningPlayer playLocalSound( game["music"]["winning_" + winningPlayer.pers["team"] ] );
foreach ( otherPlayer in level._players )
{
if ( otherPlayer == winningPlayer )
continue;
otherPlayer playLocalSound( game["music"]["losing_" + otherPlayer.pers["team"] ] );
}
}
winningPlayer leaderDialogOnPlayer( "winning_score" );
leaderDialogOnPlayers( "losing_score", losingPlayers );
}
}
level waittill ( "match_ending_very_soon" );
leaderDialog( "timesup" );
}
}
else
{
if ( !level._hardcoreMode )
playSoundOnPlayers( game["music"]["losing_allies"] );
leaderDialog( "timesup" );
}
}
suspenseMusic()
{
level endon ( "game_ended" );
level endon ( "match_ending_soon" );
numTracks = game["music"]["suspense"].size;
for ( ;; )
{
wait ( randomFloatRange( 60, 120 ) );
playSoundOnPlayers( game["music"]["suspense"][randomInt(numTracks)] );
}
}
finalKillcamMusic()
{
self waittill ( "showing_final_killcam" );
//self playLocalSound( game["music"]["winning"] );
}

View File

@ -0,0 +1,163 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
precacheShader("objpoint_default");
level._objPointNames = [];
level._objPoints = [];
if ( level._splitscreen )
level._objPointSize = 15;
else
level._objPointSize = 8;
level._objpoint_alpha_default = .5;
level._objPointScale = 1.0;
}
createTeamObjpoint( name, origin, team, shader, alpha, scale )
{
if( !level._multiteambased )
{
assert( team == "axis" || team == "allies" || team == "all" );
}
objPoint = getObjPointByName( name );
if ( isDefined( objPoint ) )
deleteObjPoint( objPoint );
if ( !isDefined( shader ) )
shader = "objpoint_default";
if ( !isDefined( scale ) )
scale = 1.0;
if ( team != "all" )
objPoint = newTeamHudElem( team );
else
objPoint = newHudElem();
objPoint.name = name;
objPoint.x = origin[0];
objPoint.y = origin[1];
objPoint.z = origin[2];
objPoint.team = team;
objPoint.isFlashing = false;
objPoint.isShown = true;
objPoint setShader( shader, level._objPointSize, level._objPointSize );
objPoint setWaypoint( true, false );
if ( isDefined( alpha ) )
objPoint.alpha = alpha;
else
objPoint.alpha = level._objpoint_alpha_default;
objPoint.baseAlpha = objPoint.alpha;
objPoint.index = level._objPointNames.size;
level._objPoints[name] = objPoint;
level._objPointNames[level._objPointNames.size] = name;
return objPoint;
}
deleteObjPoint( oldObjPoint )
{
assert( level._objPoints.size == level._objPointNames.size );
if ( level._objPoints.size == 1 )
{
assert( level._objPointNames[0] == oldObjPoint.name );
assert( isDefined( level._objPoints[oldObjPoint.name] ) );
level._objPoints = [];
level._objPointNames = [];
oldObjPoint destroy();
return;
}
newIndex = oldObjPoint.index;
oldIndex = (level._objPointNames.size - 1);
objPoint = getObjPointByIndex( oldIndex );
level._objPointNames[newIndex] = objPoint.name;
objPoint.index = newIndex;
level._objPointNames[oldIndex] = undefined;
level._objPoints[oldObjPoint.name] = undefined;
oldObjPoint destroy();
}
updateOrigin( origin )
{
if ( self.x != origin[0] )
self.x = origin[0];
if ( self.y != origin[1] )
self.y = origin[1];
if ( self.z != origin[2] )
self.z = origin[2];
}
setOriginByName( name, origin )
{
objPoint = getObjPointByName( name );
objPoint updateOrigin( origin );
}
getObjPointByName( name )
{
if ( isDefined( level._objPoints[name] ) )
return level._objPoints[name];
else
return undefined;
}
getObjPointByIndex( index )
{
if ( isDefined( level._objPointNames[index] ) )
return level._objPoints[level._objPointNames[index]];
else
return undefined;
}
startFlashing()
{
self endon("stop_flashing_thread");
if ( self.isFlashing )
return;
self.isFlashing = true;
while ( self.isFlashing )
{
self fadeOverTime( 0.75 );
self.alpha = 0.35 * self.baseAlpha;
wait ( 0.75 );
self fadeOverTime( 0.75 );
self.alpha = self.baseAlpha;
wait ( 0.75 );
}
self.alpha = self.baseAlpha;
}
stopFlashing()
{
if ( !self.isFlashing )
return;
self.isFlashing = false;
}

View File

@ -0,0 +1,232 @@
#include maps\mp\_utility;
init()
{
level._persistentDataInfo = [];
maps\mp\gametypes\_class::init();
maps\mp\gametypes\_rank::init();
maps\mp\gametypes\_missions::init();
maps\mp\gametypes\_playercards::init();
level thread updateBufferedStats();
}
initBufferedStats()
{
self.bufferedStats = [];
self.bufferedStats[ "totalShots" ] = self getPlayerData( "totalShots" );
self.bufferedStats[ "accuracy" ] = self getPlayerData( "accuracy" );
self.bufferedStats[ "misses" ] = self getPlayerData( "misses" );
self.bufferedStats[ "hits" ] = self getPlayerData( "hits" );
self.bufferedStats[ "timePlayedAllies" ] = self getPlayerData( "timePlayedAllies" );
self.bufferedStats[ "timePlayedOpfor" ] = self getPlayerData( "timePlayedOpfor" );
self.bufferedStats[ "timePlayedOther" ] = self getPlayerData( "timePlayedOther" );
self.bufferedStats[ "timePlayedTotal" ] = self getPlayerData( "timePlayedTotal" );
self.bufferedChildStats = [];
self.bufferedChildStats[ "round" ] = [];
self.bufferedChildStats[ "round" ][ "timePlayed" ] = self getPlayerData( "round", "timePlayed" );
}
// ==========================================
// Script persistent data functions
// These are made for convenience, so persistent data can be tracked by strings.
// They make use of code functions which are prototyped below.
/*
=============
statGet
Returns the value of the named stat
=============
*/
statGet( dataName )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
return self GetPlayerData( dataName );
}
/*
=============
statSet
Sets the value of the named stat
=============
*/
statSet( dataName, value )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
if ( !self rankingEnabled() )
return;
self SetPlayerData( dataName, value );
}
/*
=============
statAdd
Adds the passed value to the value of the named stat
=============
*/
statAdd( dataName, value )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
if ( !self rankingEnabled() )
return;
curValue = self GetPlayerData( dataName );
self SetPlayerData( dataName, value + curValue );
}
statGetChild( parent, child )
{
return self GetPlayerData( parent, child );
}
statSetChild( parent, child, value )
{
if ( !self rankingEnabled() )
return;
self SetPlayerData( parent, child, value );
}
statAddChild( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
curValue = self GetPlayerData( parent, child );
self SetPlayerData( parent, child, curValue + value );
}
statGetChildBuffered( parent, child )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
return self.bufferedChildStats[ parent ][ child ];
}
statSetChildBuffered( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
self.bufferedChildStats[ parent ][ child ] = value;
}
statAddChildBuffered( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
curValue = statGetChildBuffered( parent, child );
statSetChildBuffered( parent, child, curValue + value );
}
/*
=============
statGetBuffered
Returns the value of the named stat
=============
*/
statGetBuffered( dataName )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
return self.bufferedStats[ dataName ];
}
/*
=============
statSet
Sets the value of the named stat
=============
*/
statSetBuffered( dataName, value )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
if ( !self rankingEnabled() )
return;
self.bufferedStats[ dataName ] = value;
}
/*
=============
statAdd
Adds the passed value to the value of the named stat
=============
*/
statAddBuffered( dataName, value )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
if ( !self rankingEnabled() )
return;
curValue = statGetBuffered( dataName );
statSetBuffered( dataName, curValue + value );
}
updateBufferedStats()
{
// give the first player time to connect
wait ( 0.15 );
nextToUpdate = 0;
while ( !level._gameEnded )
{
nextToUpdate++;
if ( nextToUpdate >= level._players.size )
nextToUpdate = 0;
if ( isDefined( level._players[nextToUpdate] ) )
level._players[nextToUpdate] writeBufferedStats();
wait ( 2.0 );
}
foreach ( player in level._players )
player writeBufferedStats();
}
writeBufferedStats()
{
foreach ( statName, statVal in self.bufferedStats )
{
self setPlayerData( statName, statVal );
}
foreach ( statName, statVal in self.bufferedChildStats )
{
foreach ( childStatName, childStatVal in statVal )
self setPlayerData( statName, childStatName, childStatVal );
}
}

View File

@ -0,0 +1,29 @@
#include common_scripts\utility;
#include maps\mp\_utility;
init()
{
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
//@NOTE: Should we make sure they're really unlocked before setting them? Catch cheaters...
// e.g. isItemUnlocked( iconHandle )
iconHandle = player maps\mp\gametypes\_persistence::statGet( "cardIcon" );
player SetCardIcon( iconHandle );
titleHandle = player maps\mp\gametypes\_persistence::statGet( "cardTitle" );
player SetCardTitle( titleHandle );
nameplateHandle = player maps\mp\gametypes\_persistence::statGet( "cardNameplate" );
player SetCardNameplate( nameplateHandle );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,270 @@
init()
{
game["menu_quickcommands"] = "quickcommands";
game["menu_quickstatements"] = "quickstatements";
game["menu_quickresponses"] = "quickresponses";
precacheMenu(game["menu_quickcommands"]);
precacheMenu(game["menu_quickstatements"]);
precacheMenu(game["menu_quickresponses"]);
precacheHeadIcon("talkingicon");
precacheString( &"QUICKMESSAGE_FOLLOW_ME" );
precacheString( &"QUICKMESSAGE_MOVE_IN" );
precacheString( &"QUICKMESSAGE_FALL_BACK" );
precacheString( &"QUICKMESSAGE_SUPPRESSING_FIRE" );
precacheString( &"QUICKMESSAGE_ATTACK_LEFT_FLANK" );
precacheString( &"QUICKMESSAGE_ATTACK_RIGHT_FLANK" );
precacheString( &"QUICKMESSAGE_HOLD_THIS_POSITION" );
precacheString( &"QUICKMESSAGE_REGROUP" );
precacheString( &"QUICKMESSAGE_ENEMY_SPOTTED" );
precacheString( &"QUICKMESSAGE_ENEMIES_SPOTTED" );
precacheString( &"QUICKMESSAGE_IM_IN_POSITION" );
precacheString( &"QUICKMESSAGE_AREA_SECURE" );
precacheString( &"QUICKMESSAGE_GRENADE" );
precacheString( &"QUICKMESSAGE_SNIPER" );
precacheString( &"QUICKMESSAGE_NEED_REINFORCEMENTS" );
precacheString( &"QUICKMESSAGE_HOLD_YOUR_FIRE" );
precacheString( &"QUICKMESSAGE_YES_SIR" );
precacheString( &"QUICKMESSAGE_NO_SIR" );
precacheString( &"QUICKMESSAGE_IM_ON_MY_WAY" );
precacheString( &"QUICKMESSAGE_SORRY" );
precacheString( &"QUICKMESSAGE_GREAT_SHOT" );
precacheString( &"QUICKMESSAGE_TOOK_LONG_ENOUGH" );
precacheString( &"QUICKMESSAGE_ARE_YOU_CRAZY" );
precacheString( &"QUICKMESSAGE_WATCH_SIX" );
precacheString( &"QUICKMESSAGE_COME_ON" );
}
quickcommands(response)
{
self endon ( "disconnect" );
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_cmd_followme";
saytext = &"QUICKMESSAGE_FOLLOW_ME";
//saytext = "Follow Me!";
break;
case "2":
soundalias = "mp_cmd_movein";
saytext = &"QUICKMESSAGE_MOVE_IN";
//saytext = "Move in!";
break;
case "3":
soundalias = "mp_cmd_fallback";
saytext = &"QUICKMESSAGE_FALL_BACK";
//saytext = "Fall back!";
break;
case "4":
soundalias = "mp_cmd_suppressfire";
saytext = &"QUICKMESSAGE_SUPPRESSING_FIRE";
//saytext = "Suppressing fire!";
break;
case "5":
soundalias = "mp_cmd_attackleftflank";
saytext = &"QUICKMESSAGE_ATTACK_LEFT_FLANK";
//saytext = "Attack left flank!";
break;
case "6":
soundalias = "mp_cmd_attackrightflank";
saytext = &"QUICKMESSAGE_ATTACK_RIGHT_FLANK";
//saytext = "Attack right flank!";
break;
case "7":
soundalias = "mp_cmd_holdposition";
saytext = &"QUICKMESSAGE_HOLD_THIS_POSITION";
//saytext = "Hold this position!";
break;
default:
assert(response == "8");
soundalias = "mp_cmd_regroup";
saytext = &"QUICKMESSAGE_REGROUP";
//saytext = "Regroup!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
quickstatements(response)
{
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_stm_enemyspotted";
saytext = &"QUICKMESSAGE_ENEMY_SPOTTED";
//saytext = "Enemy spotted!";
break;
case "2":
soundalias = "mp_stm_enemiesspotted";
saytext = &"QUICKMESSAGE_ENEMIES_SPOTTED";
//saytext = "Enemy down!";
break;
case "3":
soundalias = "mp_stm_iminposition";
saytext = &"QUICKMESSAGE_IM_IN_POSITION";
//saytext = "I'm in position.";
break;
case "4":
soundalias = "mp_stm_areasecure";
saytext = &"QUICKMESSAGE_AREA_SECURE";
//saytext = "Area secure!";
break;
case "5":
soundalias = "mp_stm_watchsix";
saytext = &"QUICKMESSAGE_WATCH_SIX";
//saytext = "Grenade!";
break;
case "6":
soundalias = "mp_stm_sniper";
saytext = &"QUICKMESSAGE_SNIPER";
//saytext = "Sniper!";
break;
default:
assert(response == "7");
soundalias = "mp_stm_needreinforcements";
saytext = &"QUICKMESSAGE_NEED_REINFORCEMENTS";
//saytext = "Need reinforcements!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
quickresponses(response)
{
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_rsp_yessir";
saytext = &"QUICKMESSAGE_YES_SIR";
//saytext = "Yes Sir!";
break;
case "2":
soundalias = "mp_rsp_nosir";
saytext = &"QUICKMESSAGE_NO_SIR";
//saytext = "No Sir!";
break;
case "3":
soundalias = "mp_rsp_onmyway";
saytext = &"QUICKMESSAGE_IM_ON_MY_WAY";
//saytext = "On my way.";
break;
case "4":
soundalias = "mp_rsp_sorry";
saytext = &"QUICKMESSAGE_SORRY";
//saytext = "Sorry.";
break;
case "5":
soundalias = "mp_rsp_greatshot";
saytext = &"QUICKMESSAGE_GREAT_SHOT";
//saytext = "Great shot!";
break;
default:
assert(response == "6");
soundalias = "mp_rsp_comeon";
saytext = &"QUICKMESSAGE_COME_ON";
//saytext = "Took long enough!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
doQuickMessage( soundalias, saytext )
{
if(self.sessionstate != "playing")
return;
prefix = maps\mp\gametypes\_teams::getTeamVoicePrefix( self.team );
if(isdefined(level._QuickMessageToAll) && level._QuickMessageToAll)
{
self.headiconteam = "none";
self.headicon = "talkingicon";
self playSound( prefix+soundalias );
self sayAll(saytext);
}
else
{
if(self.sessionteam == "allies")
self.headiconteam = "allies";
else if(self.sessionteam == "axis")
self.headiconteam = "axis";
self.headicon = "talkingicon";
self playSound( prefix+soundalias );
self sayTeam( saytext );
self pingPlayer();
}
}
saveHeadIcon()
{
if(isdefined(self.headicon))
self.oldheadicon = self.headicon;
if(isdefined(self.headiconteam))
self.oldheadiconteam = self.headiconteam;
}
restoreHeadIcon()
{
if(isdefined(self.oldheadicon))
self.headicon = self.oldheadicon;
if(isdefined(self.oldheadiconteam))
self.headiconteam = self.oldheadiconteam;
}

799
maps/mp/gametypes/_rank.gsc Normal file
View File

@ -0,0 +1,799 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
//Those are the fraction of total possible assist points that is given to the player
//For example, with level 1 assist, the player is given 25% of the total possible assist points
LEVEL_1_ASSIST = 0.25;
LEVEL_2_ASSIST = 0.50;
LEVEL_3_ASSIST = 0.75;
GRENADE_ASSIST = 0.625;
init()
{
level._scoreInfo = [];
level._xpScale = getDvarInt( "scr_xpscale" );
if ( level._xpScale > 4 || level._xpScale < 0)
exitLevel( false );
level._xpScale = min( level._xpScale, 4 );
level._xpScale = max( level._xpScale, 0 );
level._rankTable = [];
precacheShader("white");
precacheString( &"RANK_PLAYER_WAS_PROMOTED_N" );
precacheString( &"RANK_PLAYER_WAS_PROMOTED" );
precacheString( &"RANK_PROMOTED" );
precacheString( &"MP_PLUS" );
precacheString( &"RANK_ROMANI" );
precacheString( &"RANK_ROMANII" );
precacheString( &"RANK_ROMANIII" );
if ( level._teamBased )
{
registerScoreInfo( "kill", 100 );
registerScoreInfo( "headshot", 100 );
registerScoreInfo( "assist", 80 );
registerScoreInfo( "suicide", 0 );
registerScoreInfo( "teamkill", 0 );
}
else
{
registerScoreInfo( "kill", 50 );
registerScoreInfo( "headshot", 50 );
registerScoreInfo( "assist", 0 );
registerScoreInfo( "suicide", 0 );
registerScoreInfo( "teamkill", 0 );
}
registerScoreInfo( "win", 1 );
registerScoreInfo( "loss", 0.5 );
registerScoreInfo( "tie", 0.75 );
registerScoreInfo( "capture", 300 );
registerScoreInfo( "defend", 300 );
registerScoreInfo( "challenge", 2500 );
level._maxRank = int(tableLookup( "mp/rankTable.csv", 0, "maxrank", 1 ));
level._maxPrestige = int(tableLookup( "mp/rankIconTable.csv", 0, "maxprestige", 1 ));
pId = 0;
rId = 0;
for ( pId = 0; pId <= level._maxPrestige; pId++ )
{
for ( rId = 0; rId <= level._maxRank; rId++ )
precacheShader( tableLookup( "mp/rankIconTable.csv", 0, rId, pId+1 ) );
}
rankId = 0;
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
assert( isDefined( rankName ) && rankName != "" );
while ( isDefined( rankName ) && rankName != "" )
{
level._rankTable[rankId][1] = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
level._rankTable[rankId][2] = tableLookup( "mp/ranktable.csv", 0, rankId, 2 );
level._rankTable[rankId][3] = tableLookup( "mp/ranktable.csv", 0, rankId, 3 );
level._rankTable[rankId][7] = tableLookup( "mp/ranktable.csv", 0, rankId, 7 );
precacheString( tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 ) );
rankId++;
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
}
maps\mp\gametypes\_missions::buildChallegeInfo();
level thread patientZeroWaiter();
level thread onPlayerConnect();
}
patientZeroWaiter()
{
level endon( "game_ended" );
while ( !isDefined( level._players ) || !level._players.size )
wait ( 0.05 );
if ( !matchMakingGame() )
{
if ( (getDvar( "mapname" ) == "mp_rust" && randomInt( 1000 ) == 999) )
level._patientZeroName = level._players[0].name;
}
else
{
if ( getDvar( "scr_patientZero" ) != "" )
level._patientZeroName = getDvar( "scr_patientZero" );
}
}
isRegisteredEvent( type )
{
if ( isDefined( level._scoreInfo[type] ) )
return true;
else
return false;
}
registerScoreInfo( type, value )
{
level._scoreInfo[type]["value"] = value;
}
getScoreInfoValue( type )
{
assist_scalar = 1;
if ( IsSubStr ( type, "assist" ))
{
switch ( type )
{
case "assist_level_1":
assist_scalar = LEVEL_1_ASSIST;
break;
case "assist_level_2":
assist_scalar = LEVEL_2_ASSIST;
break;
case "assist_grenade":
assist_scalar = GRENADE_ASSIST;
break;
case "assist_level_3":
assist_scalar = LEVEL_3_ASSIST;
break;
}
type = "assist";
}
overrideDvar = "scr_" + level._gameType + "_score_" + type;
if ( getDvar( overrideDvar ) != "" )
{
return getDvarInt( overrideDvar );
}
else
{
return ( Int ( floor (level._scoreInfo[type]["value"] * assist_scalar )));
}
}
getScoreInfoLabel( type )
{
return ( level._scoreInfo[type]["label"] );
}
getRankInfoMinXP( rankId )
{
return int(level._rankTable[rankId][2]);
}
getRankInfoXPAmt( rankId )
{
return int(level._rankTable[rankId][3]);
}
getRankInfoMaxXp( rankId )
{
return int(level._rankTable[rankId][7]);
}
getRankInfoFull( rankId )
{
return tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 );
}
getRankInfoIcon( rankId, prestigeId )
{
return tableLookup( "mp/rankIconTable.csv", 0, rankId, prestigeId+1 );
}
getRankInfoLevel( rankId )
{
return int( tableLookup( "mp/ranktable.csv", 0, rankId, 13 ) );
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
/#
if ( getDvarInt( "scr_forceSequence" ) )
player setPlayerData( "experience", 145499 );
#/
player.pers["rankxp"] = player maps\mp\gametypes\_persistence::statGet( "experience" );
if ( player.pers["rankxp"] < 0 ) // paranoid defensive
player.pers["rankxp"] = 0;
player.pers["rankxpstart"] = player.pers["rankxp"]; // let's remember what XP we started with.
rankId = player getRankForXp( player getRankXP() );
player.pers[ "rank" ] = rankId;
player.pers[ "participation" ] = 0;
player.xpUpdateTotal = 0;
player.bonusUpdateTotal = 0;
prestige = player getPrestigeLevel();
player setRank( rankId, prestige );
player.pers["prestige"] = prestige;
player.postGamePromotion = false;
if ( !isDefined( player.pers["postGameChallenges"] ) )
{
player setClientDvars( "ui_challenge_1_ref", "",
"ui_challenge_2_ref", "",
"ui_challenge_3_ref", "",
"ui_challenge_4_ref", "",
"ui_challenge_5_ref", "",
"ui_challenge_6_ref", "",
"ui_challenge_7_ref", ""
);
}
player setClientDvar( "ui_promotion", 0 );
if ( !isDefined( player.pers["summary"] ) )
{
player.pers["summary"] = [];
player.pers["summary"]["xp"] = 0;
player.pers["summary"]["score"] = 0;
player.pers["summary"]["challenge"] = 0;
player.pers["summary"]["match"] = 0;
player.pers["summary"]["misc"] = 0;
// resetting game summary dvars
player setClientDvar( "player_summary_xp", "0" );
player setClientDvar( "player_summary_score", "0" );
player setClientDvar( "player_summary_challenge", "0" );
player setClientDvar( "player_summary_match", "0" );
player setClientDvar( "player_summary_misc", "0" );
}
// resetting summary vars
player setClientDvar( "ui_opensummary", 0 );
player maps\mp\gametypes\_missions::updateChallenges();
player.explosiveKills[0] = 0;
player.xpGains = [];
player.hud_xpEventPopup = player createXpEventPopup();
player.hud_scorePopup = newClientHudElem( player );
player.hud_scorePopup.horzAlign = "center";
player.hud_scorePopup.vertAlign = "middle";
player.hud_scorePopup.alignX = "center";
player.hud_scorePopup.alignY = "middle";
player.hud_scorePopup.x = 0;
if ( level._splitScreen )
player.hud_scorePopup.y = -40;
else
player.hud_scorePopup.y = -60;
player.hud_scorePopup.font = "hudbig";
player.hud_scorePopup.fontscale = 0.75;
player.hud_scorePopup.archived = false;
player.hud_scorePopup.color = (0.5,0.5,0.5);
player.hud_scorePopup.sort = 10000;
player.hud_scorePopup maps\mp\gametypes\_hud::fontPulseInit( 3.0 );
player thread onPlayerSpawned();
player thread onJoinedTeam();
player thread onJoinedSpectators();
}
}
onJoinedTeam()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_team" );
self thread removeRankHUD();
}
}
onJoinedSpectators()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_spectators" );
self thread removeRankHUD();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
}
}
roundUp( floatVal )
{
if ( int( floatVal ) != floatVal )
return int( floatVal+1 );
else
return int( floatVal );
}
giveRankXP( type, value )
{
self endon("disconnect");
lootType = "none";
if ( !self rankingEnabled() )
return;
if( level._multiTeamBased )
{
numteams = 0;
for( i = 0; i < level._teamNameList.size; i++ )
{
if( level._teamCount[level._teamNameList[i]] )
{
numteams = numteams + 1;
}
}
if( numteams < 2 )
{
return;
}
}
else if ( level._teamBased && (!level._teamCount["allies"] || !level._teamCount["axis"]) )
return;
else if ( !level._teamBased && (level._teamCount["allies"] + level._teamCount["axis"] < 2) )
return;
if ( !isDefined( value ) )
value = getScoreInfoValue( type );
if ( !isDefined( self.xpGains[type] ) )
self.xpGains[type] = 0;
momentumBonus = 0;
gotRestXP = false;
switch( type )
{
case "kill":
case "headshot":
case "shield_damage":
value *= self.xpScaler;
case "assist":
case "suicide":
case "teamkill":
case "capture":
case "defend":
case "return":
case "pickup":
case "assault":
case "plant":
case "destroy":
case "save":
case "defuse":
case "escortcheckpoint":
if ( getGametypeNumLives() > 0 )
{
multiplier = max(1,int( 10/getGametypeNumLives() ));
value = int(value * multiplier);
}
value = int( value * level._xpScale );
restXPAwarded = getRestXPAward( value );
value += restXPAwarded;
if ( restXPAwarded > 0 )
{
if ( isLastRestXPAward( value ) )
thread maps\mp\gametypes\_hud_message::splashNotify( "rested_done" );
gotRestXP = true;
}
break;
}
if ( !gotRestXP )
{
// if we didn't get rest XP for this type, we push the rest XP goal ahead so we didn't waste it
if ( self getPlayerData( "restXPGoal" ) > self getRankXP() )
self setPlayerData( "restXPGoal", self getPlayerData( "restXPGoal" ) + value );
}
if( getDvarInt( "prototype_adrenaline_enabled" ) == 1 )
{
value *= self maps\mp\_adrenaline::adrenalineGetXPMultiplier();
self maps\mp\_adrenaline::adrenalineSetXPEarned();
}
oldxp = self getRankXP();
self.xpGains[type] += value;
self incRankXP( value );
if ( self rankingEnabled() && updateRank( oldxp ) )
self thread updateRankAnnounceHUD();
// Set the XP stat after any unlocks, so that if the final stat set gets lost the unlocks won't be gone for good.
self syncXPStat();
if ( !level._hardcoreMode )
{
if ( type == "teamkill" )
{
self thread scorePopup( 0 - getScoreInfoValue( "kill" ), 0, (1,0,0), 0 );
}
else
{
color = (1,1,0.5);
if ( gotRestXP )
color = (1,.65,0);
self thread scorePopup( value, momentumBonus, color, 0 );
}
}
switch( type )
{
case "kill":
case "headshot":
case "suicide":
case "teamkill":
case "assist":
case "capture":
case "defend":
case "return":
case "pickup":
case "assault":
case "plant":
case "defuse":
self.pers["summary"]["score"] += value;
self.pers["summary"]["xp"] += value;
break;
case "win":
case "loss":
case "tie":
self.pers["summary"]["match"] += value;
self.pers["summary"]["xp"] += value;
break;
case "challenge":
self.pers["summary"]["challenge"] += value;
self.pers["summary"]["xp"] += value;
break;
default:
self.pers["summary"]["misc"] += value; //keeps track of ungrouped match xp reward
self.pers["summary"]["match"] += value;
self.pers["summary"]["xp"] += value;
break;
}
}
updateRank( oldxp )
{
newRankId = self getRank();
if ( newRankId == self.pers["rank"] )
return false;
oldRank = self.pers["rank"];
rankId = self.pers["rank"];
self.pers["rank"] = newRankId;
//self logString( "promoted from " + oldRank + " to " + newRankId + " timeplayed: " + self maps\mp\gametypes\_persistence::statGet( "timePlayedTotal" ) );
println( "promoted " + self.name + " from rank " + oldRank + " to " + newRankId + ". Experience went from " + oldxp + " to " + self getRankXP() + "." );
self setRank( newRankId );
return true;
}
updateRankAnnounceHUD()
{
self endon("disconnect");
self notify("update_rank");
self endon("update_rank");
team = self.pers["team"];
if ( !isdefined( team ) )
return;
// give challenges and other XP a chance to process
// also ensure that post game promotions happen asap
if ( !levelFlag( "game_over" ) )
level waittill_notify_or_timeout( "game_over", 0.25 );
newRankName = self getRankInfoFull( self.pers["rank"] );
rank_char = level._rankTable[self.pers["rank"]][1];
subRank = int(rank_char[rank_char.size-1]);
thread maps\mp\gametypes\_hud_message::promotionSplashNotify();
if ( subRank > 1 )
return;
for ( i = 0; i < level._players.size; i++ )
{
player = level._players[i];
playerteam = player.pers["team"];
if ( isdefined( playerteam ) && player != self )
{
if ( playerteam == team )
player iPrintLn( &"RANK_PLAYER_WAS_PROMOTED", self, newRankName );
}
}
}
endGameUpdate()
{
player = self;
}
scorePopup( amount, bonus, hudColor, glowAlpha )
{
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "joined_spectators" );
if ( amount == 0 )
return;
self notify( "scorePopup" );
self endon( "scorePopup" );
self.xpUpdateTotal += amount;
self.bonusUpdateTotal += bonus;
wait ( 0.05 );
if ( self.xpUpdateTotal < 0 )
self.hud_scorePopup.label = &"";
else
self.hud_scorePopup.label = &"MP_PLUS";
self.hud_scorePopup.color = hudColor;
self.hud_scorePopup.glowColor = hudColor;
self.hud_scorePopup.glowAlpha = glowAlpha;
self.hud_scorePopup setValue(self.xpUpdateTotal);
self.hud_scorePopup.alpha = 0.85;
self.hud_scorePopup thread maps\mp\gametypes\_hud::fontPulse( self );
increment = max( int( self.bonusUpdateTotal / 20 ), 1 );
if ( self.bonusUpdateTotal )
{
while ( self.bonusUpdateTotal > 0 )
{
self.xpUpdateTotal += min( self.bonusUpdateTotal, increment );
self.bonusUpdateTotal -= min( self.bonusUpdateTotal, increment );
self.hud_scorePopup setValue( self.xpUpdateTotal );
wait ( 0.05 );
}
}
else
{
wait ( 1.0 );
}
self.hud_scorePopup fadeOverTime( 0.75 );
self.hud_scorePopup.alpha = 0;
self.xpUpdateTotal = 0;
}
removeRankHUD()
{
self.hud_scorePopup.alpha = 0;
}
getRank()
{
rankXp = self.pers["rankxp"];
rankId = self.pers["rank"];
if ( rankXp < (getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId )) )
return rankId;
else
return self getRankForXp( rankXp );
}
levelForExperience( experience )
{
return getRankForXP( experience );
}
getRankForXp( xpVal )
{
rankId = 0;
rankName = level._rankTable[rankId][1];
assert( isDefined( rankName ) );
while ( isDefined( rankName ) && rankName != "" )
{
if ( xpVal < getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId ) )
return rankId;
rankId++;
if ( isDefined( level._rankTable[rankId] ) )
rankName = level._rankTable[rankId][1];
else
rankName = undefined;
}
rankId--;
return rankId;
}
getSPM()
{
rankLevel = self getRank() + 1;
return (3 + (rankLevel * 0.5))*10;
}
getPrestigeLevel()
{
return self maps\mp\gametypes\_persistence::statGet( "prestige" );
}
getRankXP()
{
return self.pers["rankxp"];
}
getRankXPStart()
{
return self.pers["rankxpstart"];
}
incRankXP( amount )
{
if ( !self rankingEnabled() )
return;
if ( isDefined( self.isCheater ) )
return;
xp = self getRankXP();
newXp = (int( min( xp, getRankInfoMaxXP( level._maxRank ) ) ) + amount);
if ( self.pers["rank"] == level._maxRank && newXp >= getRankInfoMaxXP( level._maxRank ) )
newXp = getRankInfoMaxXP( level._maxRank );
self.pers["rankxp"] = newXp;
}
getRestXPAward( baseXP )
{
if ( !getdvarint( "scr_restxp_enable" ) )
return 0;
restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
wantGiveRestXP = int(baseXP * restXPAwardRate);
mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
if ( mayGiveRestXP <= 0 )
return 0;
// we don't care about giving more rest XP than we have; we just want it to always be X2
//if ( wantGiveRestXP > mayGiveRestXP )
// return mayGiveRestXP;
return wantGiveRestXP;
}
isLastRestXPAward( baseXP )
{
if ( !getdvarint( "scr_restxp_enable" ) )
return false;
restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
wantGiveRestXP = int(baseXP * restXPAwardRate);
mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
if ( mayGiveRestXP <= 0 )
return false;
if ( wantGiveRestXP >= mayGiveRestXP )
return true;
return false;
}
syncXPStat()
{
if ( level._xpScale > 4 || level._xpScale <= 0)
exitLevel( false );
xp = self getRankXP();
self maps\mp\gametypes\_persistence::statSet( "experience", xp );
}
createXpEventPopup()
{
hud_xpEventPopup = newClientHudElem( self );
hud_xpEventPopup.children = [];
hud_xpEventPopup.horzAlign = "center";
hud_xpEventPopup.vertAlign = "middle";
hud_xpEventPopup.alignX = "center";
hud_xpEventPopup.alignY = "middle";
hud_xpEventPopup.x = 55;
if ( level._splitScreen )
hud_xpEventPopup.y = -20;
else
hud_xpEventPopup.y = -35;
hud_xpEventPopup.font = "hudbig";
hud_xpEventPopup.fontscale = 0.65;
hud_xpEventPopup.archived = false;
hud_xpEventPopup.color = (0.5,0.5,0.5);
hud_xpEventPopup.sort = 10000;
hud_xpEventPopup.elemType = "msgText";
hud_xpEventPopup maps\mp\gametypes\_hud::fontPulseInit( 3.0 );
return hud_xpEventPopup;
}
xpEventPopup( event, hudColor, glowAlpha )
{
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "joined_spectators" );
self notify( "xpEventPopup" );
self endon( "xpEventPopup" );
wait ( 0.05 );
if ( !isDefined( hudColor ) )
hudColor = (1,1,0.5);
if ( !isDefined( glowAlpha ) )
glowAlpha = 0;
self.hud_xpEventPopup.color = hudColor;
self.hud_xpEventPopup.glowColor = hudColor;
self.hud_xpEventPopup.glowAlpha = glowAlpha;
self.hud_xpEventPopup setText(event);
self.hud_xpEventPopup.alpha = 0.85;
wait ( 1.0 );
self.hud_xpEventPopup fadeOverTime( 0.75 );
self.hud_xpEventPopup.alpha = 0;
}

View File

@ -0,0 +1,103 @@
init()
{
level._hostname = getdvar("sv_hostname");
if(level._hostname == "")
level._hostname = "CoDHost";
setdvar("sv_hostname", level._hostname);
level._allowvote = getdvarint("g_allowvote", 1);
SetDvar("g_allowvote", level._allowvote);
makedvarserverinfo("ui_allowvote", level._allowvote);
level._friendlyfire = maps\mp\gametypes\_tweakables::getTweakableValue( "team", "fftype" );
makedvarserverinfo("ui_friendlyfire", level._friendlyfire);
constrainGameType(getdvar("g_gametype"));
for(;;)
{
updateServerSettings();
wait 5;
}
}
updateServerSettings()
{
sv_hostname = getdvar("sv_hostname");
if(level._hostname != sv_hostname)
{
level._hostname = sv_hostname;
}
g_allowvote = getdvarint("g_allowvote", 1);
if(level._allowvote != g_allowvote)
{
level._allowvote = g_allowvote;
setdvar("ui_allowvote", level._allowvote);
}
scr_friendlyfire = maps\mp\gametypes\_tweakables::getTweakableValue( "team", "fftype" );
if(level._friendlyfire != scr_friendlyfire)
{
level._friendlyfire = scr_friendlyfire;
setdvar("ui_friendlyfire", level._friendlyfire);
}
}
constrainGameType(gametype)
{
entities = getentarray();
for(i = 0; i < entities.size; i++)
{
entity = entities[i];
if(gametype == "dm")
{
if(isdefined(entity.script_gametype_dm) && entity.script_gametype_dm != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "tdm")
{
if(isdefined(entity.script_gametype_tdm) && entity.script_gametype_tdm != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "ctf")
{
if(isdefined(entity.script_gametype_ctf) && entity.script_gametype_ctf != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "hq")
{
if(isdefined(entity.script_gametype_hq) && entity.script_gametype_hq != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "sd")
{
if(isdefined(entity.script_gametype_sd) && entity.script_gametype_sd != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "koth")
{
if(isdefined(entity.script_gametype_koth) && entity.script_gametype_koth != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
}
}

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