mirror of
https://github.com/reaaLx/nx1-gsc-dump.git
synced 2025-06-27 23:01:49 +00:00
Init
This commit is contained in:
22
maps/animated_models/accessories_windsock_wind_medium.gsc
Normal file
22
maps/animated_models/accessories_windsock_wind_medium.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
22
maps/animated_models/com_roofvent2.gsc
Normal file
22
maps/animated_models/com_roofvent2.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "com_roofvent2_animated";
|
||||
if ( SP )
|
||||
{
|
||||
level._anim_prop_models[ model ][ "rotate" ] = %roofvent_rotate;
|
||||
}
|
||||
else
|
||||
level._anim_prop_models[ model ][ "rotate" ] = "roofvent_rotate";
|
||||
}
|
13
maps/animated_models/foliage_dead_pine_lg_sway2.gsc
Normal file
13
maps/animated_models/foliage_dead_pine_lg_sway2.gsc
Normal 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
|
13
maps/animated_models/foliage_dead_pine_med_sway2.gsc
Normal file
13
maps/animated_models/foliage_dead_pine_med_sway2.gsc
Normal 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
|
22
maps/animated_models/foliage_desertbrush_1.gsc
Normal file
22
maps/animated_models/foliage_desertbrush_1.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
22
maps/animated_models/foliage_pacific_fern01.gsc
Normal file
22
maps/animated_models/foliage_pacific_fern01.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
22
maps/animated_models/foliage_pacific_fern02.gsc
Normal file
22
maps/animated_models/foliage_pacific_fern02.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
12
maps/animated_models/foliage_pacific_palms06.gsc
Normal file
12
maps/animated_models/foliage_pacific_palms06.gsc
Normal 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
|
21
maps/animated_models/foliage_pacific_palms08.gsc
Normal file
21
maps/animated_models/foliage_pacific_palms08.gsc
Normal 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";
|
||||
}
|
22
maps/animated_models/foliage_pacific_tropic_shrub01.gsc
Normal file
22
maps/animated_models/foliage_pacific_tropic_shrub01.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
22
maps/animated_models/foliage_red_pine_lg.gsc
Normal file
22
maps/animated_models/foliage_red_pine_lg.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
12
maps/animated_models/foliage_tree_grey_oak_lg_a.gsc
Normal file
12
maps/animated_models/foliage_tree_grey_oak_lg_a.gsc
Normal 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
|
12
maps/animated_models/foliage_tree_grey_oak_xl_a.gsc
Normal file
12
maps/animated_models/foliage_tree_grey_oak_xl_a.gsc
Normal 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
|
22
maps/animated_models/foliage_tree_oak_1.gsc
Normal file
22
maps/animated_models/foliage_tree_oak_1.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
24
maps/animated_models/foliage_tree_palm_bushy_1.gsc
Normal file
24
maps/animated_models/foliage_tree_palm_bushy_1.gsc
Normal 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
|
23
maps/animated_models/foliage_tree_palm_bushy_2.gsc
Normal file
23
maps/animated_models/foliage_tree_palm_bushy_2.gsc
Normal file
@ -0,0 +1,23 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
23
maps/animated_models/foliage_tree_palm_bushy_3.gsc
Normal file
23
maps/animated_models/foliage_tree_palm_bushy_3.gsc
Normal file
@ -0,0 +1,23 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
23
maps/animated_models/foliage_tree_palm_tall_1.gsc
Normal file
23
maps/animated_models/foliage_tree_palm_tall_1.gsc
Normal file
@ -0,0 +1,23 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
23
maps/animated_models/foliage_tree_palm_tall_2.gsc
Normal file
23
maps/animated_models/foliage_tree_palm_tall_2.gsc
Normal file
@ -0,0 +1,23 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
23
maps/animated_models/foliage_tree_palm_tall_3.gsc
Normal file
23
maps/animated_models/foliage_tree_palm_tall_3.gsc
Normal file
@ -0,0 +1,23 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
12
maps/animated_models/foliage_tree_river_birch_lg_a.gsc
Normal file
12
maps/animated_models/foliage_tree_river_birch_lg_a.gsc
Normal 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
|
22
maps/animated_models/foliage_tree_river_birch_med_a.gsc
Normal file
22
maps/animated_models/foliage_tree_river_birch_med_a.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
22
maps/animated_models/highrise_fencetarp_01.gsc
Normal file
22
maps/animated_models/highrise_fencetarp_01.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
22
maps/animated_models/highrise_fencetarp_09.gsc
Normal file
22
maps/animated_models/highrise_fencetarp_09.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
22
maps/animated_models/nx_color_tv_sign.gsc
Normal file
22
maps/animated_models/nx_color_tv_sign.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
#using_animtree( "animated_props" );
|
||||
main()
|
||||
{
|
||||
if( !isdefined ( level._anim_prop_models ) )
|
||||
level._anim_prop_models = [];
|
||||
|
||||
// Would use isSP() but this runs before we can
|
||||
mapname = tolower( getdvar( "mapname" ) );
|
||||
SP = true;
|
||||
if ( string_starts_with( mapname, "mp_" ) )
|
||||
SP = false;
|
||||
|
||||
model = "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";
|
||||
}
|
15
maps/createart/mp_nx_fallout_art.gsc
Normal file
15
maps/createart/mp_nx_fallout_art.gsc
Normal 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 );
|
||||
|
||||
}
|
16
maps/createart/mp_nx_galleria_art.gsc
Normal file
16
maps/createart/mp_nx_galleria_art.gsc
Normal 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 );
|
||||
|
||||
}
|
15
maps/createart/mp_nx_meteor_art.gsc
Normal file
15
maps/createart/mp_nx_meteor_art.gsc
Normal 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 );
|
||||
|
||||
}
|
17
maps/createart/mp_nx_pitstop_art.gsc
Normal file
17
maps/createart/mp_nx_pitstop_art.gsc
Normal 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 );
|
||||
|
||||
}
|
15
maps/createart/mp_nx_skylab_art.gsc
Normal file
15
maps/createart/mp_nx_skylab_art.gsc
Normal 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 );
|
||||
|
||||
}
|
15
maps/createart/mp_nx_stasis_art.gsc
Normal file
15
maps/createart/mp_nx_stasis_art.gsc
Normal 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 );
|
||||
|
||||
}
|
15
maps/createart/mp_nx_ugvhh_art.gsc
Normal file
15
maps/createart/mp_nx_ugvhh_art.gsc
Normal 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 );
|
||||
|
||||
}
|
130
maps/createfx/mp_nx_fallout_fx.gsc
Normal file
130
maps/createfx/mp_nx_fallout_fx.gsc
Normal 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
|
||||
}
|
1889
maps/createfx/mp_nx_galleria_fx.gsc
Normal file
1889
maps/createfx/mp_nx_galleria_fx.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1072
maps/createfx/mp_nx_pitstop_fx.gsc
Normal file
1072
maps/createfx/mp_nx_pitstop_fx.gsc
Normal file
File diff suppressed because it is too large
Load Diff
6
maps/createfx/mp_nx_skylab_fx.gsc
Normal file
6
maps/createfx/mp_nx_skylab_fx.gsc
Normal file
@ -0,0 +1,6 @@
|
||||
//_createfx generated. Do not touch!!
|
||||
#include common_scripts\utility;
|
||||
#include common_scripts\_createfx;
|
||||
main()
|
||||
{
|
||||
}
|
62
maps/createfx/mp_nx_stasis_fx.gsc
Normal file
62
maps/createfx/mp_nx_stasis_fx.gsc
Normal 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
|
||||
}
|
124
maps/createfx/mp_nx_ugvhh_fx.gsc
Normal file
124
maps/createfx/mp_nx_ugvhh_fx.gsc
Normal 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
471
maps/mp/_adrenaline.gsc
Normal 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" );
|
||||
}
|
64
maps/mp/_animatedmodels.gsc
Normal file
64
maps/mp/_animatedmodels.gsc
Normal 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
111
maps/mp/_areas.gsc
Normal 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
189
maps/mp/_art.gsc
Normal 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
1142
maps/mp/_awards.gsc
Normal file
File diff suppressed because it is too large
Load Diff
79
maps/mp/_compass.gsc
Normal file
79
maps/mp/_compass.gsc
Normal 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
82
maps/mp/_createfx.gsc
Normal 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
137
maps/mp/_defcon.gsc
Normal file
@ -0,0 +1,137 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
// if ( game["state"] == "postgame" && game["teamScores"][attacker.team] > game["teamScores"][level.otherTeam[attacker.team]] )
|
||||
|
||||
ICONSIZE = 20;
|
||||
|
||||
init()
|
||||
{
|
||||
if ( !isDefined( level._defconMode ) || level._defconMode == false )
|
||||
return;
|
||||
|
||||
if ( !isDefined( game["defcon"] ) )
|
||||
game["defcon"] = 4;
|
||||
|
||||
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
100
maps/mp/_destructables.gsc
Normal 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
1602
maps/mp/_doorbreach.gsc
Normal file
File diff suppressed because it is too large
Load Diff
490
maps/mp/_doorswitch.gsc
Normal file
490
maps/mp/_doorswitch.gsc
Normal 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);
|
||||
}
|
342
maps/mp/_entityheadicons.gsc
Normal file
342
maps/mp/_entityheadicons.gsc
Normal 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
730
maps/mp/_events.gsc
Normal 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
177
maps/mp/_fantasystats.gsc
Normal 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
137
maps/mp/_flashgrenades.gsc
Normal 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
482
maps/mp/_gasgrenades.gsc
Normal 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
147
maps/mp/_global_fx.gsc
Normal 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
16
maps/mp/_highlights.gsc
Normal 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
791
maps/mp/_intel.gsc
Normal 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
615
maps/mp/_javelin.gsc
Normal 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
318
maps/mp/_killingdoor.gsc
Normal 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
351
maps/mp/_load.gsc
Normal 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
374
maps/mp/_matchdata.gsc
Normal 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
50
maps/mp/_minefields.gsc
Normal 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
70
maps/mp/_moon_mp.gsc
Normal 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();
|
||||
}
|
||||
}
|
226
maps/mp/_mp_trophy_turret.gsc
Normal file
226
maps/mp/_mp_trophy_turret.gsc
Normal 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
227
maps/mp/_radiation.gsc
Normal 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
770
maps/mp/_remotedog.gsc
Normal 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
164
maps/mp/_scoreboard.gsc
Normal 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
179
maps/mp/_shutter.gsc
Normal 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
71
maps/mp/_skill.gsc
Normal 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
419
maps/mp/_stinger.gsc
Normal 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
745
maps/mp/_upgrade.gsc
Normal 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
2914
maps/mp/_utility.gsc
Normal file
File diff suppressed because it is too large
Load Diff
211
maps/mp/gametypes/_battlechatter_mp.gsc
Normal file
211
maps/mp/gametypes/_battlechatter_mp.gsc
Normal 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;
|
||||
}
|
274
maps/mp/gametypes/_callbacksetup.gsc
Normal file
274
maps/mp/gametypes/_callbacksetup.gsc
Normal 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
2896
maps/mp/gametypes/_class.gsc
Normal file
File diff suppressed because it is too large
Load Diff
2558
maps/mp/gametypes/_damage.gsc
Normal file
2558
maps/mp/gametypes/_damage.gsc
Normal file
File diff suppressed because it is too large
Load Diff
94
maps/mp/gametypes/_damagefeedback.gsc
Normal file
94
maps/mp/gametypes/_damagefeedback.gsc
Normal 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;
|
||||
}
|
87
maps/mp/gametypes/_deathicons.gsc
Normal file
87
maps/mp/gametypes/_deathicons.gsc
Normal 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
1661
maps/mp/gametypes/_dev.gsc
Normal file
File diff suppressed because it is too large
Load Diff
120
maps/mp/gametypes/_friendicons.gsc
Normal file
120
maps/mp/gametypes/_friendicons.gsc
Normal 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 = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2782
maps/mp/gametypes/_gamelogic.gsc
Normal file
2782
maps/mp/gametypes/_gamelogic.gsc
Normal file
File diff suppressed because it is too large
Load Diff
2373
maps/mp/gametypes/_gameobjects.gsc
Normal file
2373
maps/mp/gametypes/_gameobjects.gsc
Normal file
File diff suppressed because it is too large
Load Diff
529
maps/mp/gametypes/_gamescore.gsc
Normal file
529
maps/mp/gametypes/_gamescore.gsc
Normal 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();
|
||||
}
|
279
maps/mp/gametypes/_globallogic.gsc
Normal file
279
maps/mp/gametypes/_globallogic.gsc
Normal 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;
|
||||
}
|
||||
}
|
235
maps/mp/gametypes/_healthoverlay.gsc
Normal file
235
maps/mp/gametypes/_healthoverlay.gsc
Normal 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) );
|
||||
}
|
||||
}
|
167
maps/mp/gametypes/_hostmigration.gsc
Normal file
167
maps/mp/gametypes/_hostmigration.gsc
Normal 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
160
maps/mp/gametypes/_hud.gsc
Normal 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;
|
||||
}
|
1427
maps/mp/gametypes/_hud_message.gsc
Normal file
1427
maps/mp/gametypes/_hud_message.gsc
Normal file
File diff suppressed because it is too large
Load Diff
792
maps/mp/gametypes/_hud_util.gsc
Normal file
792
maps/mp/gametypes/_hud_util.gsc
Normal 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;
|
||||
}
|
691
maps/mp/gametypes/_killcam.gsc
Normal file
691
maps/mp/gametypes/_killcam.gsc
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
589
maps/mp/gametypes/_menus.gsc
Normal file
589
maps/mp/gametypes/_menus.gsc
Normal 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;
|
||||
}
|
2368
maps/mp/gametypes/_missions.gsc
Normal file
2368
maps/mp/gametypes/_missions.gsc
Normal file
File diff suppressed because it is too large
Load Diff
512
maps/mp/gametypes/_music_and_dialog.gsc
Normal file
512
maps/mp/gametypes/_music_and_dialog.gsc
Normal 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"] );
|
||||
}
|
163
maps/mp/gametypes/_objpoints.gsc
Normal file
163
maps/mp/gametypes/_objpoints.gsc
Normal 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;
|
||||
}
|
232
maps/mp/gametypes/_persistence.gsc
Normal file
232
maps/mp/gametypes/_persistence.gsc
Normal 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 );
|
||||
}
|
||||
}
|
29
maps/mp/gametypes/_playercards.gsc
Normal file
29
maps/mp/gametypes/_playercards.gsc
Normal 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 );
|
||||
}
|
||||
}
|
1595
maps/mp/gametypes/_playerlogic.gsc
Normal file
1595
maps/mp/gametypes/_playerlogic.gsc
Normal file
File diff suppressed because it is too large
Load Diff
270
maps/mp/gametypes/_quickmessages.gsc
Normal file
270
maps/mp/gametypes/_quickmessages.gsc
Normal 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
799
maps/mp/gametypes/_rank.gsc
Normal 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;
|
||||
}
|
103
maps/mp/gametypes/_serversettings.gsc
Normal file
103
maps/mp/gametypes/_serversettings.gsc
Normal 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
Reference in New Issue
Block a user