Pushed raw files

This commit is contained in:
RezTech committed 2017-07-08 14:47:21 -04:00
1 parent 22d0d4d39f
commit 79f967ecc9
5854 files changed
+2989978

No files matched your search

+55
View File
@@ -0,0 +1,55 @@
#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;
}
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()
{
keys = GetArrayKeys( level.anim_prop_models[ self.model ] );
animkey = keys[ RandomInt( keys.size ) ];
//wait( RandomFloatRange( 0, 5 ) ); // TODO: get a way to play animations at random starting points
self ScriptModelPlayAnim( level.anim_prop_models[ self.model ][ animkey ] );
self willNeverChange();
}
+111
View File
@@ -0,0 +1,111 @@
#include maps\mp\_utility;
#include common_scripts\utility;
/*QUAKED trigger_multiple_area (0.12 0.23 1.0)
defaulttexture="trigger"
"script_area" - A localized string that names the area. e.g. "MP_FLOWER_SHOP"
Defines an area that the player is in.*/
/*QUAKED trigger_multiple_softlanding (0.12 0.23 1.0)
defaulttexture="trigger"
"script_type" - "car", "boxes", "trash"
Defines a soft landing area.*/
/*QUAKED script_vehicle_snowmobile_player_mp (1 0 0) (-16 -16 -24) (16 16 32) USABLE SPAWNER
put this in your GSC:
maps\_snowmobile_player::main( "vehicle_snowmobile" );
and these lines in your CSV:
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
View File
@@ -0,0 +1,189 @@
// This function should take care of grain and glow settings for each map, plus anything else that artists
// need to be able to tweak without bothering level designers.
#include common_scripts\utility;
#include common_scripts\_artCommon;
main()
{
/#
setDevDvarIfUninitialized( "scr_art_tweak", 0 );
setDevDvarIfUninitialized( "scr_dof_enable", "1" );
setDevDvarIfUninitialized( "scr_cmd_plr_sun", "0" );
setDevDvarIfUninitialized( "scr_cinematic_autofocus", "1" );
setDevDvarIfUninitialized( "scr_art_visionfile", level.script );
if ( !isDefined( level.dofDefault ) )
{
level.dofDefault[ "nearStart" ] = 0;
level.dofDefault[ "nearEnd" ] = 1;
level.dofDefault[ "farStart" ] = 8000;
level.dofDefault[ "farEnd" ] = 10000;
level.dofDefault[ "nearBlur" ] = 6;
level.dofDefault[ "farBlur" ] = 0;
}
level.curDoF = ( level.dofDefault[ "farStart" ] - level.dofDefault[ "nearEnd" ] ) / 2;
thread tweakart();
if ( !isdefined( level.script ) )
level.script = ToLower( GetDvar( "mapname" ) );
#/
}
tweakart()
{
/#
if ( !isdefined( level.tweakfile ) )
level.tweakfile = false;
// not in DEVGUI
SetDevDvar( "scr_fog_fraction", "1.0" );
SetDevDvar( "scr_art_dump", "0" );
// update the devgui variables to current settings
SetDevDvar( "scr_dof_nearStart", level.dofDefault[ "nearStart" ] );
SetDevDvar( "scr_dof_nearEnd", level.dofDefault[ "nearEnd" ] );
SetDevDvar( "scr_dof_farStart", level.dofDefault[ "farStart" ] );
SetDevDvar( "scr_dof_farEnd", level.dofDefault[ "farEnd" ] );
SetDevDvar( "scr_dof_nearBlur", level.dofDefault[ "nearBlur" ] );
SetDevDvar( "scr_dof_farBlur", level.dofDefault[ "farBlur" ] );
// not in DEVGUI
level.fogfraction = 1.0;
file = undefined;
filename = undefined;
for ( ;; )
{
while ( GetDvarInt( "scr_art_tweak", 0 ) == 0 )
{
AssertEx( GetDvarInt( "scr_art_dump", 0 ) == 0, "Must Enable Art Tweaks to export _art file." );
wait .05;
if ( ! GetDvarInt( "scr_art_tweak", 0 ) == 0 )
common_scripts\_artCommon::setfogsliders();// sets the sliders to whatever the current fog value is
}
if ( GetDvarInt( "scr_art_tweak_message" ) )
{
SetDevDvar( "scr_art_tweak_message", "0" );
IPrintLnBold( "ART TWEAK ENABLED" );
}
//translate the slider values to script variables
common_scripts\_artCommon::translateFogSlidersToScript();
// dofvarupdate();
// catch all those cases where a slider can be pushed to a place of conflict
fovslidercheck();
dump = dumpsettings();// dumps and returns true if the dump dvar is set
common_scripts\_artCommon::updateFogFromScript();
// level.player setDefaultDepthOfField();
if ( dump )
{
IPrintLnBold( "Art settings dumped success!" );
SetdevDvar( "scr_art_dump", "0" );
}
wait .1;
}
#/
}
fovslidercheck()
{
/#
// catch all those cases where a slider can be pushed to a place of conflict
if ( level.dofDefault[ "nearStart" ] >= level.dofDefault[ "nearEnd" ] )
{
level.dofDefault[ "nearStart" ] = level.dofDefault[ "nearEnd" ] - 1;
SetDevDvar( "scr_dof_nearStart", level.dofDefault[ "nearStart" ] );
}
if ( level.dofDefault[ "nearEnd" ] <= level.dofDefault[ "nearStart" ] )
{
level.dofDefault[ "nearEnd" ] = level.dofDefault[ "nearStart" ] + 1;
SetDevDvar( "scr_dof_nearEnd", level.dofDefault[ "nearEnd" ] );
}
if ( level.dofDefault[ "farStart" ] >= level.dofDefault[ "farEnd" ] )
{
level.dofDefault[ "farStart" ] = level.dofDefault[ "farEnd" ] - 1;
SetDevDvar( "scr_dof_farStart", level.dofDefault[ "farStart" ] );
}
if ( level.dofDefault[ "farEnd" ] <= level.dofDefault[ "farStart" ] )
{
level.dofDefault[ "farEnd" ] = level.dofDefault[ "farStart" ] + 1;
SetDevDvar( "scr_dof_farEnd", level.dofDefault[ "farEnd" ] );
}
if ( level.dofDefault[ "farBlur" ] >= level.dofDefault[ "nearBlur" ] )
{
level.dofDefault[ "farBlur" ] = level.dofDefault[ "nearBlur" ] - .1;
SetDevDvar( "scr_dof_farBlur", level.dofDefault[ "farBlur" ] );
}
if ( level.dofDefault[ "farStart" ] <= level.dofDefault[ "nearEnd" ] )
{
level.dofDefault[ "farStart" ] = level.dofDefault[ "nearEnd" ] + 1;
SetDevDvar( "scr_dof_farStart", level.dofDefault[ "farStart" ] );
}
#/
}
dumpsettings()
{
/#
if ( GetDvarInt( "scr_art_dump" ) == 0 )
return false;
filename = "createart/" + GetDvar( "scr_art_visionfile" ) + "_art.gsc";
artStartFogFileExport();
fileprint_launcher( "// _createart generated. modify at your own risk. Changing values should be fine." );
fileprint_launcher( "main()" );
fileprint_launcher( "{" );
fileprint_launcher( "" );
fileprint_launcher( "\tlevel.tweakfile = true;" );
fileprint_launcher( " " );
artfxprintlnFog();
fileprint_launcher( "\tVisionSetNaked( \"" + level.script + "\", 0 );" );
fileprint_launcher( "" );
fileprint_launcher( "}" );
artEndFogFileExport();
visionFilename = "vision/" + GetDvar( "scr_art_visionfile" ) + ".vision";
artStartVisionFileExport();
fileprint_launcher( "r_glow \"" + GetDvar( "r_glowTweakEnable" ) + "\"" );
fileprint_launcher( "r_glowRadius0 \"" + GetDvar( "r_glowTweakRadius0" ) + "\"" );
fileprint_launcher( "r_glowBloomCutoff \"" + GetDvar( "r_glowTweakBloomCutoff" ) + "\"" );
fileprint_launcher( "r_glowBloomDesaturation \"" + GetDvar( "r_glowTweakBloomDesaturation" ) + "\"" );
fileprint_launcher( "r_glowBloomIntensity0 \"" + GetDvar( "r_glowTweakBloomIntensity0" ) + "\"" );
fileprint_launcher( " " );
fileprint_launcher( "r_filmEnable \"" + GetDvar( "r_filmTweakEnable" ) + "\"" );
fileprint_launcher( "r_filmContrast \"" + GetDvar( "r_filmTweakContrast" ) + "\"" );
fileprint_launcher( "r_filmBrightness \"" + GetDvar( "r_filmTweakBrightness" ) + "\"" );
fileprint_launcher( "r_filmDesaturation \"" + GetDvar( "r_filmTweakDesaturation" ) + "\"" );
fileprint_launcher( "r_filmDesaturationDark \"" + GetDvar( "r_filmTweakDesaturationDark" ) + "\"" );
fileprint_launcher( "r_filmInvert \"" + GetDvar( "r_filmTweakInvert" ) + "\"" );
fileprint_launcher( "r_filmLightTint \"" + GetDvar( "r_filmTweakLightTint" ) + "\"" );
fileprint_launcher( "r_filmMediumTint \"" + GetDvar( "r_filmTweakMediumTint" ) + "\"" );
fileprint_launcher( "r_filmDarkTint \"" + GetDvar( "r_filmTweakDarkTint" ) + "\"" );
fileprint_launcher( " " );
fileprint_launcher( "r_primaryLightUseTweaks \"" + GetDvar( "r_primaryLightUseTweaks" ) + "\"" );
fileprint_launcher( "r_primaryLightTweakDiffuseStrength \"" + GetDvar( "r_primaryLightTweakDiffuseStrength" ) + "\"" );
fileprint_launcher( "r_primaryLightTweakSpecularStrength \"" + GetDvar( "r_primaryLightTweakSpecularStrength" ) + "\"" );
if ( ! artEndVisionFileExport() )
return false;
IPrintLnBold( "ART DUMPED SUCCESSFULLY" );
return true;
#/
}
+1106
View File
File diff suppressed because it is too large. Load diff
+79
View File
@@ -0,0 +1,79 @@
setupMiniMap(material)
{
// use 0 for no required map aspect ratio.
requiredMapAspectRatio = level.requiredMapAspectRatio;
corners = getentarray("minimap_corner", "targetname");
if (corners.size != 2)
{
println("^1Error: There are not exactly two \"minimap_corner\" entities in the map. Could not set up minimap.");
return;
}
corner0 = (corners[0].origin[0], corners[0].origin[1], 0);
corner1 = (corners[1].origin[0], corners[1].origin[1], 0);
cornerdiff = corner1 - corner0;
north = (cos(getnorthyaw()), sin(getnorthyaw()), 0);
west = (0 - north[1], north[0], 0);
// we need the northwest and southeast corners. all we know is that corner0 is opposite of corner1.
if (vectordot(cornerdiff, west) > 0) {
// corner1 is further west than corner0
if (vectordot(cornerdiff, north) > 0) {
// corner1 is northwest, corner0 is southeast
northwest = corner1;
southeast = corner0;
}
else {
// corner1 is southwest, corner0 is northeast
side = vecscale(north, vectordot(cornerdiff, north));
northwest = corner1 - side;
southeast = corner0 + side;
}
}
else {
// corner1 is further east than corner0
if (vectordot(cornerdiff, north) > 0) {
// corner1 is northeast, corner0 is southwest
side = vecscale(north, vectordot(cornerdiff, north));
northwest = corner0 + side;
southeast = corner1 - side;
}
else {
// corner1 is southeast, corner0 is northwest
northwest = corner0;
southeast = corner1;
}
}
// expand map area to fit required aspect ratio
if ( requiredMapAspectRatio > 0 )
{
northportion = vectordot(northwest - southeast, north);
westportion = vectordot(northwest - southeast, west);
mapAspectRatio = westportion / northportion;
if ( mapAspectRatio < requiredMapAspectRatio )
{
incr = requiredMapAspectRatio / mapAspectRatio;
addvec = vecscale( west, westportion * (incr - 1) * 0.5 );
}
else
{
incr = mapAspectRatio / requiredMapAspectRatio;
addvec = vecscale( north, northportion * (incr - 1) * 0.5 );
}
northwest += addvec;
southeast -= addvec;
}
level.mapSize = vectordot(northwest - southeast, north);
setMiniMap(material, northwest[0], northwest[1], southeast[0], southeast[1]);
}
vecscale(vec, scalar)
{
return (vec[0]*scalar, vec[1]*scalar, vec[2]*scalar);
}
+67
View File
@@ -0,0 +1,67 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include common_scripts\_createFxMenu;
#include common_scripts\_createfx;
#include common_scripts\_fx;
createfx()
{
level.func_position_player = ::void;
level.func_position_player_get = ::func_position_player_get;
level.func_loopfxthread = ::loopfxthread;
level.func_oneshotfxthread = ::oneshotfxthread;
level.func_create_loopsound = ::create_loopsound;
// level.func_exploder_preload = ::exploder_before_load;;
// level.func_exploder_postload = ::exploder_after_load;;
level.func_updatefx = ::restart_fx_looper;
level.func_process_fx_rotater = ::process_fx_rotater;
level.mp_createfx = true;
// MP only stuff
level.callbackStartGameType = ::void;
level.callbackPlayerConnect = ::void;
level.callbackPlayerDisconnect = ::void;
level.callbackPlayerDamage = ::void;
level.callbackPlayerKilled = ::void;
level.callbackCodeEndGame = ::void;
level.callbackPlayerLastStand = ::void;
level.callbackPlayerConnect = ::Callback_PlayerConnect;
level.callbackPlayerMigrated = ::void;
thread func_get_level_fx(); // start gettin these on start
createfx_common();
level waittill( "eternity" );
}
func_position_player_get( lastPlayerOrigin )
{
return level.player.origin;
}
Callback_PlayerConnect()
{
self waittill( "begin" );
if ( !isdefined( level.player ) )
{
spawnpoints = getentarray( "mp_global_intermission", "classname" );
self spawn( spawnpoints[0].origin, spawnpoints[0].angles );
self maps\mp\gametypes\_playerlogic::updateSessionState( "playing", "" );
self.maxhealth = 10000000;
self.health = 10000000;
level.player = self;
thread createFxLogic();
thread ufo_mode();
}
else
kick( self GetEntityNumber() );
}
ufo_mode()
{
level.player openpopupmenu( "painter_mp" );// painter.menu execs some console commands( ufo mode ).. sneaky hacks.
level.player closepopupmenu( "painter_mp" );
}
+727
View File
@@ -0,0 +1,727 @@
#include maps\mp\_utility;
#include common_scripts\utility;
CONST_default_radial_radius = 8; // default distance between radial button and center
CONST_radial_center_extrude_dist = 40; // this is the distance between the floating radial center and the oberver's eye
CONST_direct_travel = 1; // no path, directly zoom to position
CONST_view_travel_unit_dist = 1200; // distance unit per travel interval
CONST_view_travel_unit_time = 1; // in seconds per travel interval
CONST_blur_strength = 3; // blur strength during view travel, sine curved over travel duration
init()
{
precacheShellShock( "frag_grenade_mp" );
radial_button_definitions(); // define radial button sets and buttons
radial_init(); // setup radial button mechanism
view_path_setup(); // setup view flight paths
player_init();
}
// ====================================================================================
// == inits ==
// ====================================================================================
radial_button_definitions()
{
newRadialButtonGroup( "main", "player_view1_start", "player_view1_end" );
// Main menu's buttons:
bWeapons_a = newRadialButton( "main", "Primary Weapon", "radial_weapons_primary", ::action_weapons_primary );
bWeapons_b = newRadialButton( "main", "Secondary Weapon", "radial_weapons_secondary", ::action_weapons_secondary );
bGears = newRadialButton( "main", "Gears", "radial_gears", ::action_gears );
bKillStreaks= newRadialButton( "main", "Kill Streaks", "radial_killstreaks", ::action_killstreak );
bLeadboards = newRadialButton( "main", "Leaderboards", "radial_leaderboards", ::action_leaderboards );
//
newRadialButtonGroup( "gears", "player_view2_start", "player_view2_end" );
newRadialButtonGroup( "weapons_primary", "player_view3_start", "player_view3_end" );
newRadialButtonGroup( "weapons_secondary", "player_view3_start", "player_view3_end" );
newRadialButtonGroup( "killstreak", "player_view4_start", "player_view4_end" );
newRadialButtonGroup( "leaderboards", "player_view5_start", "player_view5_end" );
}
radial_init()
{
// calculate start & end angles of all buttons for range selection
foreach ( button_group in level.radial_button_group )
{
// sort buttons by angle so we can calculate mid angles in sequence
sort_buttons_by_angle( button_group );
for ( i = 0; i < button_group.size; i ++ )
{
if ( isdefined( button_group[ i + 1 ] ) )
{
mid_angle = getMidAngle( button_group[ i ].pos_angle, button_group[ i + 1 ].pos_angle );
button_group[ i ].end_angle = mid_angle;
button_group[ i + 1 ].start_angle = mid_angle;
}
else
{
mid_angle = getMidAngle( button_group[ i ].pos_angle, button_group[ 0 ].pos_angle ) + 180; // +180 to mirror angle
if ( mid_angle > 360 )
mid_angle -= 360;
button_group[ i ].end_angle = mid_angle;
button_group[ 0 ].start_angle = mid_angle;
}
}
}
// monitors
thread updateSelectedButton();
thread watchSelectButtonPress();
thread watchBackButtonPress();
thread debug_toggle();
}
debug_toggle()
{
level endon( "game_ended" );
level.crib_debug = 1;
while ( 1 )
{
if ( !isdefined( level.observer ) )
{
wait 0.05;
continue;
}
button_reset = true;
while ( !( level.observer buttonPressed( "BUTTON_Y" ) ) )
wait 0.05;
level.observer playsound("mouse_click");
if ( button_reset )
{
level.crib_debug *= -1;
button_reset = false;
}
while ( level.observer buttonPressed( "BUTTON_Y" ) )
wait 0.05;
}
}
player_init()
{
level thread onPlayerConnect();
level thread return_hud();
}
return_hud()
{
level waittill( "game_ended" );
setdvar( "cg_draw2d", 1 );
}
onPlayerConnect()
{
level waittill("connected", player);
player thread readyPlayer();
player waittill( "spawned_player" );
wait 1;
player takeallweapons();
setdvar( "cg_draw2d", 0 );
if ( !isdefined( player ) )
return;
else
level.observer = player;
player thread get_right_stick_angle();
zoom_to_radial_menu( "main" ); // fly to the first radial menu
}
readyPlayer()
{
self endon( "disconnect" );
team = "autoassign";
while(!isdefined(self.pers["team"]))
wait .05;
self notify("menuresponse", game["menu_team"], team);
wait 0.5;
classes = getArrayKeys( level.classMap );
okclasses = [];
for ( i = 0; i < classes.size; i++ )
{
if ( !isSubStr( classes[i], "custom" ) )
okclasses[ okclasses.size ] = classes[i];
}
assert( okclasses.size );
while( 1 )
{
class = okclasses[ 0 ];
self notify("menuresponse", "changeclass", class);
self waittill( "spawned_player" );
wait ( 0.10 );
}
}
// ====================================================================================
// == Radial Mechanics ==
// ====================================================================================
get_right_stick_angle()
{
// self is user
level endon( "game_ended" );
self endon( "disconnect" );
while ( 1 )
{
rs_vec = self GetNormalizedMovement();
rs_angles = vectortoangles( rs_vec );
level.rs_angle = int( rs_angles[1] );
wait 0.05; // update rate
}
}
newRadialButtonGroup( group_name, view_start, view_end )
{
if ( isdefined( level.radial_button_group ) && level.radial_button_group.size )
assertex( !isdefined( level.radial_button_group[ group_name ] ), "Radial button group: " + group_name + " is already defined." );
player_view_ent = getent( view_end, "targetname" );
assertex( isdefined( player_view_ent ), "Missing player view entity, can not setup radial menu in space" );
extruded_vec = vector_multiply( VectorNormalize( AnglesToForward( player_view_ent.angles ) ), CONST_radial_center_extrude_dist );
level.radial_button_group[ group_name ] = [];
level.radial_button_group_info[ group_name ][ "view_start" ] = view_start;
level.radial_button_group_info[ group_name ][ "view_pos" ] = player_view_ent.origin + extruded_vec;
level.radial_button_group_info[ group_name ][ "player_view_pos" ] = player_view_ent.origin;
level.radial_button_group_info[ group_name ][ "view_angles" ] = player_view_ent.angles;
}
newRadialButton( button_group, button_label, button_ent_name, action_func )
{
assertex( isdefined( level.radial_button_group[ button_group ] ), "Radial button group: " + button_group + " does not exist." );
ent = getent( button_ent_name, "targetname" );
new_button_angle = getRadialAngleFromEnt( button_group, ent );
button = spawnstruct();
button.pos = ent.origin;
button.label = button_label;
button.font_size = 1;
button.font_color = ( 0.5, 0.5, 1 );
button.pos_angle = new_button_angle;
button.action_func = action_func;
button.radius_pos = CONST_default_radial_radius;
level.radial_button_group[ button_group ][ level.radial_button_group[ button_group ].size ] = button;
return button;
}
updateSelectedButton()
{
level endon( "game_ended" );
while ( 1 )
{
if ( !isdefined( level.radial_button_current_group ) )
{
wait 0.05;
continue;
}
last_active_button = level.active_button;
foreach ( button in level.radial_button_group[ level.radial_button_current_group ] )
{
if ( isInRange( button.start_angle, button.end_angle ) )
level.active_button = button;
else
button.font_color = ( 0.5, 0.5, 1 );
}
if ( isdefined ( level.active_button ) )
{
level.active_button.font_color = ( 1, 1, 0.5 );
if ( isdefined( last_active_button ) && last_active_button != level.active_button )
level.observer playsound("mouse_over");
}
wait 0.05;
}
}
watchSelectButtonPress()
{
level endon( "game_ended" );
while ( 1 )
{
if ( !isdefined( level.observer ) )
{
wait 0.05;
continue;
}
button_reset = true;
while ( !( level.observer buttonPressed( "BUTTON_A" ) ) )
wait 0.05;
level.observer playsound("mouse_click");
if ( isdefined( level.active_button ) && button_reset )
{
level.active_button notify( "select_button_pressed" );
[[level.active_button.action_func]]();
button_reset = false;
}
while ( level.observer buttonPressed( "BUTTON_A" ) )
wait 0.05;
}
}
watchBackButtonPress()
{
level endon( "game_ended" );
while ( 1 )
{
if ( !isdefined( level.observer ) )
{
wait 0.05;
continue;
}
button_reset = true;
while ( !( level.observer buttonPressed( "BUTTON_X" ) ) )
wait 0.05;
level.observer playsound("mouse_click");
if ( button_reset )
{
action_back();
button_reset = false;
}
while ( level.observer buttonPressed( "BUTTON_X" ) )
wait 0.05;
}
}
sort_buttons_by_angle( button_group )
{
// button_group is actual array
// bubble sort buttons
for ( i = 0; i < button_group.size - 1; i++ )
{
for ( j = 0; j < button_group.size - 1 - i; j++ )
{
if ( button_group[ j + 1 ].pos_angle < button_group[ j ].pos_angle )
button_switch( button_group[ j ], button_group[ j + 1 ] );
}
}
}
button_switch( button1, button2 )
{
temp_pos = button1.pos;
temp_label = button1.label;
temp_pos_angle = button1.pos_angle;
temp_action_func = button1.action_func;
temp_radius_pos = button1.radius_pos;
button1.pos = button2.pos;
button1.label = button2.label;
button1.pos_angle = button2.pos_angle;
button1.action_func = button2.action_func;
button1.radius_pos = button2.radius_pos;
button2.pos = temp_pos;
button2.label = temp_label;
button2.pos_angle = temp_pos_angle;
button2.action_func = temp_action_func;
button2.radius_pos = temp_radius_pos;
}
draw_radial_buttons( button_group )
{
foreach ( button in level.radial_button_group[ button_group ] )
button thread draw_radial_button( button_group );
}
//print3d(<origin>, <text>, <color>, <alpha>, <scale>, <duration> )
draw_radial_button( button_group )
{
level endon( "game_ended" );
self endon( "remove_button" );
floating_origin = level.radial_button_group_info[ button_group ][ "view_pos" ];
button_radial_pos = floating_origin + radial_angle_to_vector( self.pos_angle, 4 );
while ( 1 )
{
//line( level.radial_button_group_info[ button_group ][ "view_pos" ], self.pos, ( 0, 1, 0 ), 0.05, false );
range_color = ( 1, 0, 0 );
if ( isInRange( self.start_angle, self.end_angle ) )
range_color = ( 1, 1, 0 );
print3d( self.pos, self.label, self.font_color, 0.75, self.font_size, 1 );
if ( isdefined( level.crib_debug ) && level.crib_debug > 0 )
{
print3d( button_radial_pos, ".("+int(self.pos_angle)+")", range_color, 0.75, 0.05, 1 );
line( floating_origin, floating_origin + radial_angle_to_vector( self.start_angle, 2 ), range_color, 0.05 );
line( floating_origin + radial_angle_to_vector( self.start_angle, 2 ), floating_origin + radial_angle_to_vector( self.end_angle, 2 ), range_color, 0.05 );
// right stick debug ling
r_radial_pos = floating_origin + radial_angle_to_vector( level.rs_angle, 2 );
line( floating_origin, r_radial_pos, ( 1, 1, 1 ), 0.05 );
}
print3d( floating_origin - ( 0, 0, 4.5 ), "(A)=Select (X)=Back", (1, 1, 1), 0.5, 0.05, 1 );
wait 0.05;
}
}
Zoom_To_Radial_Menu( button_group, reverse )
{
level.active_button = undefined;
assertex( isdefined( level.observer ), "Missing observer (connected player), can not attach player to view path" );
if ( isdefined( level.radial_button_current_group ) && level.radial_button_current_group != "" )
{
level.radial_button_previous_group = level.radial_button_current_group;
}
else
{
level.radial_button_previous_group = "main";
level.radial_button_current_group = "main";
}
foreach ( button in level.radial_button_group[ level.radial_button_previous_group ] )
button notify( "remove_button" );
//iPrintLnBold( "flying to: " + button_group );
if ( isdefined( reverse ) && reverse )
level.observer go_path_by_targetname_reverse( level.radial_button_group_info[ level.radial_button_previous_group ][ "view_start" ], button_group );
else
level.observer go_path_by_targetname( level.radial_button_group_info[ button_group ][ "view_start" ] );
level thread draw_radial_buttons( button_group );
level.radial_button_current_group = button_group;
}
// ====================================================================================
// == Radial menu - math ==
// ====================================================================================
// edit function with care, returns orientation-sensistive angles
getRadialAngleFromEnt( button_group, ent )
{
assertex( isdefined( level.radial_button_group[ button_group ] ), "getRadialAngleFromEnt: Radial button group does not exist." );
assertex( isdefined( ent ), "getRadialAngleFromEnt: Missing entity to be measured." );
rAngle = level.radial_button_group_info[ button_group ][ "view_angles" ];
rPos = level.radial_button_group_info[ button_group ][ "view_pos" ];
rPos += vector_multiply( VectorNormalize( AnglesToForward( rAngle ) ), CONST_radial_center_extrude_dist );
rForward = AnglesToForward( rAngle );
rUpwardNorm = VectorNormalize( AnglesToUp( rAngle ) );
eAngle = ent.angles;
ePos = ent.origin;
projNorm = VectorNormalize( VectorFromLineToPoint( rPos, ( rPos + rForward ), ePos ) );
radial_angle = Acos( VectorDot( projNorm, rUpwardNorm ) );
// vector mirroring
if ( VectorDot( AnglesToRight( rAngle ), projNorm ) < 0 )
radial_angle = 360 - radial_angle;
return radial_angle;
}
// converts projected angle into player's view plane into a vector
radial_angle_to_vector( angle, scaler )
{
b_angles = ( 270 - ( angle ), 0 , 0 ); // 270 degrees offset to face the player
b_vec = AnglesToForward( b_angles );
b_vec_norm = VectorNormalize( b_vec );
b_vec_final = vector_multiply( b_vec_norm, scaler );
return b_vec_final;
}
getMidAngle( a1, a2 )
{
// 0 -> 360 domain
mid_angle = ( ( a1 + a2 + 720 ) / 2 ) - 360;
return mid_angle;
}
isInRange( start_angle, end_angle )
{
inside_big_angle = ( level.rs_angle > start_angle && level.rs_angle < 360 );
inside_small_angle = ( level.rs_angle > 0 && level.rs_angle < end_angle );
if ( start_angle > end_angle )
in_range = ( inside_big_angle || inside_small_angle );
else
in_range = ( level.rs_angle > start_angle && level.rs_angle < end_angle );
return in_range;
}
// ====================================================================================
// == Button action functions ==
// ====================================================================================
// close radial buttons
action_back()
{
//if ( isdefined( level.radial_button_previous_group ) && level.radial_button_previous_group != "" )
// zoom_to_radial_menu( level.radial_button_previous_group );
/*else*/ if ( isdefined( level.radial_button_current_group ) && level.radial_button_current_group != "main" )
zoom_to_radial_menu( "main", true );
else
return;
}
// ==== main ====
action_weapons_primary()
{
iPrintLnBold( "action_weapons_primary" );
zoom_to_radial_menu( "weapons_primary" );
}
action_weapons_secondary()
{
iPrintLnBold( "action_weapons_secondary" );
zoom_to_radial_menu( "weapons_secondary" );
}
action_gears()
{
iPrintLnBold( "action_gears" );
zoom_to_radial_menu( "gears" );
}
action_killstreak()
{
iPrintLnBold( "action_killstreak" );
zoom_to_radial_menu( "killstreak" );
}
action_leaderboards()
{
iPrintLnBold( "action_leaderboards" );
zoom_to_radial_menu( "leaderboards" );
}
// ====================================================================================
// == Pathing functions ==
// ====================================================================================
view_path_setup()
{
// setup all paths
level.view_paths = [];
// build paths
build_path_by_targetname( "player_view1_start" );
build_path_by_targetname( "player_view2_start" );
build_path_by_targetname( "player_view3_start" );
build_path_by_targetname( "player_view4_start" );
build_path_by_targetname( "player_view5_start" );
}
build_path_by_targetname( path_name )
{
level.view_paths[ path_name ] = [];
path_node = getent( path_name, "targetname" );
level.view_paths[ path_name ][ level.view_paths[ path_name ].size ] = path_node;
while( isdefined( path_node ) && isdefined( path_node.target ) )
{
next_node = getent( path_node.target, "targetname" );
level.view_paths[ path_name ][ level.view_paths[ path_name ].size ] = next_node;
path_node = next_node;
}
}
go_path_by_targetname( path_name )
{
// self is player
if ( !isdefined( level.dummy_mover ) )
{
start_node = level.view_paths[ path_name ][ 0 ];
level.dummy_mover = spawn( "script_model", start_node.origin );
level.dummy_mover.angles = start_node.angles;
//self AllowedStances( "stand" );
self setOrigin( level.dummy_mover.origin - ( 0, 0, 65 ) );
self linkTo( level.dummy_mover );
wait 0.05;
self setplayerangles ( level.dummy_mover.angles );
self thread force_player_angles();
}
/*
travel_time = 1;
dist = 0;
foreach ( idx, node in level.view_paths[ path_name ] )
{
if ( isdefined( level.view_paths[ path_name ][ idx + 1 ] ) )
dist += abs( distance( level.view_paths[ path_name ][ idx ].origin, level.view_paths[ path_name ][ idx + 1 ].origin ) );
}*/
travel_speed = CONST_view_travel_unit_time;
total_distance = abs( distance( level.dummy_mover.origin, level.view_paths[ path_name ][ level.view_paths[ path_name ].size - 1 ].origin ) );
travel_speed *= total_distance / CONST_view_travel_unit_dist;
travel_speed = max( travel_speed, 0.1 ); // due to repeated button presses, the travel distance can be cut to 0 travel speed at times.
blur_time = travel_speed;
if ( !CONST_direct_travel )
blur_time *= travel_speed * ( level.view_paths[ path_name ].size + 1 );
self thread blur_sine( CONST_blur_strength, blur_time );
foreach ( idx, node in level.view_paths[ path_name ] )
{
//travel_speed = travel_time * ( abs( distance( level.dummy_mover.origin, node.origin ) ) / dist );
//travel_speed += 0.05;
if ( CONST_direct_travel )
{
if ( idx != level.view_paths[ path_name ].size - 1 )
continue;
}
//level.dummy_mover MoveTo( node.origin, travel_speed );
level.dummy_mover MoveTo( node.origin, travel_speed, travel_speed * 0.5, 0 );
level.dummy_mover RotateTo( node.angles, travel_speed, travel_speed * 0.5, 0);
wait travel_speed;
}
}
go_path_by_targetname_reverse( path_name, back_to_button_group )
{
assertex( isdefined( level.dummy_mover ), "go_path_by_targetname_reverse called before go_path_by_targetname" );
travel_speed = CONST_view_travel_unit_time;
total_distance = abs( distance( level.dummy_mover.origin, level.radial_button_group_info[ back_to_button_group ][ "player_view_pos" ] ) );
travel_speed *= total_distance / CONST_view_travel_unit_dist;
travel_speed = max( travel_speed, 0.1 ); // due to repeated button presses, the travel distance can be cut to 0 travel speed at times.
blur_time = travel_speed;
if ( !CONST_direct_travel )
blur_time *= travel_speed * ( level.view_paths[ path_name ].size + 1 );
self thread blur_sine( CONST_blur_strength, blur_time );
if ( !CONST_direct_travel )
{
for ( idx = level.view_paths[ path_name ].size - 1; idx >= 0; idx-- )
{
node = level.view_paths[ path_name ][ idx ];
level.dummy_mover MoveTo( node.origin, travel_speed );
level.dummy_mover RotateTo( node.angles, travel_speed );
//self thread travel_view_fx( travel_speed );
wait travel_speed;
}
}
self thread blur_sine( CONST_blur_strength, travel_speed );
pos = level.radial_button_group_info[ back_to_button_group ][ "player_view_pos" ];
angle = level.radial_button_group_info[ back_to_button_group ][ "view_angles" ];
level.dummy_mover MoveTo( pos, travel_speed, travel_speed * 0.5, 0 );
level.dummy_mover RotateTo( angle, travel_speed, travel_speed * 0.5, 0 );
wait travel_speed;
}
travel_view_fx( time )
{
self setblurforplayer( 20, ( time + 0.2 )/2 );
self setblurforplayer( 0, ( time + 0.2 )/2 );
self shellshock( "frag_grenade_mp", time + 0.2 );
}
blur_sine( strength, time )
{
time_scaled = int( time/0.05 );
for( i = 0; i < time_scaled; i ++ )
{
fraction = ( i / ( time_scaled ) );
cos_fraction= sin( 180 * fraction );
blur_amount = strength * cos_fraction;
setdvar( "r_blur", blur_amount );
wait 0.05;
}
setdvar( "r_blur", 0 );
}
force_player_angles()
{
level endon( "game_ended" );
self endon( "disconnect" );
level.dummy_mover endon( "remove_dummy" );
while ( 1 )
{
self setplayerangles ( level.dummy_mover.angles );
wait 0.05;
}
}
+137
View File
@@ -0,0 +1,137 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
// if ( game["state"] == "postgame" && game["teamScores"][attacker.team] > game["teamScores"][level.otherTeam[attacker.team]] )
ICONSIZE = 20;
init()
{
if ( !isDefined( level.defconMode ) || level.defconMode == false )
return;
if ( !isDefined( game["defcon"] ) )
game["defcon"] = 4;
makeDvarServerInfo( "scr_defcon", game["defcon"] );
/# setDevDvarIfUninitialized( "scr_defconStreak", 10 ); #/
level.defconStreakAdd[5] = 0;
level.defconStreakAdd[4] = 0;
level.defconStreakAdd[3] = -1;
level.defconStreakAdd[2] = -1;
level.defconStreakAdd[1] = -1;
level.defconPointMod[5] = 1;
level.defconPointMod[4] = 1;
level.defconPointMod[3] = 1;
level.defconPointMod[2] = 1;
level.defconPointMod[1] = 2;
updateDefcon( game["defcon"] );
thread defconKillstreakThread();
}
defconKillstreakWait( streakCount )
{
for ( ;; )
{
level waittill ( "player_got_killstreak_" + streakCount, player );
level notify ( "defcon_killstreak", streakCount, player );
}
}
defconKillstreakThread()
{
level endon ( "game_ended" );
requiredKillCount = 10;
/#
requiredKillCount = getDvarInt( "scr_defconStreak" );
#/
level thread defconKillstreakWait( requiredKillCount );
level thread defconKillstreakWait( requiredKillCount - 1 );
level thread defconKillstreakWait( requiredKillCount - 2 );
level thread defconKillstreakWait( (requiredKillCount * 2) );
level thread defconKillstreakWait( (requiredKillCount * 2) - 1 );
level thread defconKillstreakWait( (requiredKillCount * 2) - 2 );
level thread defconKillstreakWait( (requiredKillCount * 3) );
level thread defconKillstreakWait( (requiredKillCount * 3) - 1 );
level thread defconKillstreakWait( (requiredKillCount * 3) - 2 );
for ( ;; )
{
level waittill ( "defcon_killstreak", streakCount, changingPlayer );
if ( game["defcon"] <= 1 )
continue;
if ( (streakCount % requiredKillCount) == requiredKillCount - 2 )
{
foreach ( player in level.players )
{
if ( !isAlive( player ) )
continue;
player thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "two_from_defcon", changingPlayer );
}
}
else if ( (streakCount % requiredKillCount) == requiredKillCount - 1 )
{
foreach ( player in level.players )
{
if ( !isAlive( player ) )
continue;
player thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "one_from_defcon", changingPlayer );
}
}
else
{
updateDefcon( game["defcon"] - 1, changingPlayer, streakCount );
}
}
}
updateDefcon( newDefcon, changingPlayer, streakCount )
{
newDefcon = int( newDefcon );
oldDefcon = game["defcon"];
game["defcon"] = newDefcon;
// level.killStreakMod = level.defconStreakAdd[newDefcon];
level.objectivePointsMod = level.defconPointMod[newDefcon];
setDvar( "scr_defcon", game["defcon"] );
//isdefined used for variable init
if( isDefined( changingPlayer ) )
changingPlayer notify( "changed_defcon" );
if ( newDefcon == oldDefcon )
return;
if ( game["defcon"] == 3 && isDefined( changingPlayer ) )
{
changingPlayer maps\mp\killstreaks\_killstreaks::giveKillstreak( "airdrop_mega" );
changingPlayer thread maps\mp\gametypes\_hud_message::splashNotify( "caused_defcon" , streakCount );
}
foreach ( player in level.players )
{
if ( isAlive( player ) )
{
player thread maps\mp\gametypes\_hud_message::defconSplashNotify( game["defcon"], newDefcon < oldDefcon );
if ( isDefined( changingPlayer ) )
player thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "changed_defcon", changingPlayer );
}
}
}
+100
View File
@@ -0,0 +1,100 @@
init()
{
// level.destructableFX = loadfx("breakables/exp_wall_cinderblock_96");
ents = getentarray("destructable", "targetname");
if (getdvar("scr_destructables") == "0")
{
for (i = 0; i < ents.size; i++)
ents[i] delete();
}
else
{
for (i = 0; i < ents.size; i++)
{
ents[i] thread destructable_think();
}
}
}
destructable_think()
{
accumulate = 40;
threshold = 0;
if (isdefined(self.script_accumulate))
accumulate = self.script_accumulate;
if (isdefined(self.script_threshold))
threshold = self.script_threshold;
if (isdefined(self.script_destructable_area)) {
areas = strtok(self.script_destructable_area, " ");
for (i = 0; i < areas.size; i++)
self blockArea(areas[i]);
}
if ( isdefined( self.script_fxid ) )
self.fx = loadfx( self.script_fxid );
dmg = 0;
self setcandamage(true);
while(1)
{
self waittill("damage", amount, other);
if (amount >= threshold)
{
dmg += amount;
if (dmg >= accumulate)
{
self thread destructable_destruct();
return;
}
}
}
}
destructable_destruct()
{
ent = self;
if (isdefined(self.script_destructable_area)) {
areas = strtok(self.script_destructable_area, " ");
for (i = 0; i < areas.size; i++)
self unblockArea(areas[i]);
}
if ( isdefined( ent.fx ) )
playfx( ent.fx, ent.origin + (0,0,6) );
ent delete();
}
blockArea(area)
{
spawns = getentarray("mp_tdm_spawn", "classname");
blockEntsInArea(spawns, area);
spawns = getentarray("mp_dm_spawn", "classname");
blockEntsInArea(spawns, area);
}
blockEntsInArea(ents, area)
{
for (i = 0; i < ents.size; i++) {
if (!isdefined(ents[i].script_destructable_area) || ents[i].script_destructable_area != area)
continue;
ents[i].blockedoff = true;
}
}
unblockArea(area)
{
spawns = getentarray("mp_tdm_spawn", "classname");
unblockEntsInArea(spawns, area);
spawns = getentarray("mp_dm_spawn", "classname");
unblockEntsInArea(spawns, area);
}
unblockEntsInArea(ents, area)
{
for (i = 0; i < ents.size; i++) {
if (!isdefined(ents[i].script_destructable_area) || ents[i].script_destructable_area != area)
continue;
ents[i].blockedoff = false;
}
}
+292
View File
@@ -0,0 +1,292 @@
#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.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 )
{
if ( !isDefined( self.entityHeadIcons ) )
self.entityHeadIcons = [];
if ( !isPlayer( showTo ) && showTo == "none" )
{
foreach ( key, headIcon in self.entityHeadIcons )
{
// TODO: remove and fix properly after ship
if ( isDefined( headIcon ) )
headIcon destroy();
self.entityHeadIcons[ key ] = undefined;
}
return;
}
if ( isPlayer( showTo ) )
{
if ( isDefined( self.entityHeadIcons[ showTo.guid ] ) )
{
self.entityHeadIcons[ showTo.guid ] destroy();
self.entityHeadIcons[ showTo.guid ] = undefined;
}
if ( icon == "" )
return;
// remove from team or we'd have two icons
if ( isDefined( self.entityHeadIcons[ showTo.team ] ) )
{
self.entityHeadIcons[ showTo.team ] destroy();
self.entityHeadIcons[ showTo.team ] = undefined;
}
headIcon = newClientHudElem( showTo );
self.entityHeadIcons[ showTo.guid ] = headIcon;
}
else
{
assert( showTo == "axis" || showTo == "allies" );
assert( level.teamBased );
if ( isDefined( self.entityHeadIcons[ showTo ] ) )
{
self.entityHeadIcons[ showTo ] destroy();
self.entityHeadIcons[ showTo ] = undefined;
}
if ( icon == "" )
return;
foreach ( key, hudIcon in self.entityHeadIcons )
{
if ( key == "axis" || key == "allies" )
continue;
player = getPlayerForGuid( key );
if ( player.team == showTo )
{
self.entityHeadIcons[ key ] destroy();
self.entityHeadIcons[ key ] = undefined;
}
}
headIcon = newTeamHudElem( showTo );
self.entityHeadIcons[ showTo ] = headIcon;
}
if ( !isDefined( width ) || !isDefined( height ) )
{
width = 10;
height = 10;
}
headIcon.archived = true;
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 );
if ( isPlayer( showTo ) )
headIcon setWaypoint( true, true, false );
else
headIcon setWaypoint( true, true, false );
headIcon thread keepPositioned( self, offset );
self thread destroyIconsOnDeath();
if ( isPlayer( showTo ) )
headIcon thread destroyOnOwnerDisconnect( showTo );
}
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 )
{
self endon ( "death" );
owner endon ( "death" );
pos = owner.origin;
for ( ;; )
{
if ( pos != owner.origin )
{
pos = owner.origin;
self.x = pos[0] + offset[0];
self.y = pos[0] + offset[0];
self.z = pos[0] + offset[0];
}
wait .05;
}
}
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 );
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 );
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];
}
+695
View File
@@ -0,0 +1,695 @@
#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 )
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 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_smg":
case "weapon_assault":
case "weapon_projectile":
case "weapon_sniper":
case "weapon_shotgun":
case "weapon_lmg":
self checkMatchDataWeaponKills( victim, weapon, meansOfDeath, weaponClass );
break;
case "weapon_grenade":
case "weapon_explosive":
self checkMatchDataEquipmentKills( victim, weapon, meansOfDeath );
break;
default:
break;
}
}
// Need to make sure these only apply to kills of an enemy, not friendlies or yourself
checkMatchDataWeaponKills( victim, weapon, meansOfDeath, weaponType )
{
attacker = self;
kill_ref = undefined;
headshot_ref = undefined;
death_ref = undefined;
switch( weaponType )
{
case "weapon_pistol":
kill_ref = "pistolkills";
headshot_ref = "pistolheadshots";
break;
case "weapon_smg":
kill_ref = "smgkills";
headshot_ref = "smgheadshots";
break;
case "weapon_assault":
kill_ref = "arkills";
headshot_ref = "arheadshots";
break;
case "weapon_projectile":
if ( weaponClass( weapon ) == "rocketlauncher" )
kill_ref = "rocketkills";
break;
case "weapon_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":
attacker incPlayerStat( "fragkills", 1 );
attacker incPlayerStat( "grenadekills", 1 );
isEquipment = true;
break;
case "c4_mp":
attacker incPlayerStat( "c4kills", 1 );
isEquipment = true;
break;
case "semtex_mp":
attacker incPlayerStat( "semtexkills", 1 );
attacker incPlayerStat( "grenadekills", 1 );
isEquipment = true;
break;
case "claymore_mp":
attacker incPlayerStat( "claymorekills", 1 );
isEquipment = true;
break;
case "throwingknife_mp":
attacker incPlayerStat( "throwingknifekills", 1 );
self thread maps\mp\gametypes\_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" );
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" );
}
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 );
}
}
}
+402
View File
@@ -0,0 +1,402 @@
main()
{
//------------------
//EFECTS DEFINITIONS
//------------------
qBarrels = false;
precacheItem( "barrel_mp" );
barrels = getentarray ("explodable_barrel","targetname");
if ( (isdefined(barrels)) && (barrels.size > 0) )
qBarrels = true;
barrels = getentarray ("explodable_barrel","script_noteworthy");
if ( (isdefined(barrels)) && (barrels.size > 0) )
qBarrels = true;
if (qBarrels)
{
level.breakables_fx["barrel"]["explode"] = loadfx ("props/barrelExp");
level.breakables_fx["barrel"]["burn_start"] = loadfx ("props/barrel_ignite");
level.breakables_fx["barrel"]["burn"] = loadfx ("props/barrel_fire_top");
}
oilspill = getentarray ("oil_spill","targetname");
if(isdefined(oilspill) && oilspill.size > 0)
{
level.breakables_fx["oilspill"]["burn"] = loadfx ("props/barrel_fire");
level.breakables_fx["oilspill"]["spark"] = loadfx("impacts/small_metalhit_1");
}
//------------------
//------------------
//-----------------
//SOUND DEFINITIONS
//-----------------
level.barrelExpSound = "explo_metal_rand";
//-----------------
//-----------------
level.barrelHealth = 150;
maxBrokenPieces = 25;
//-------------
//-------------
level.precachemodeltype = [];
level.barrelExplodingThisFrame = false;
level.breakables_clip = [];
temp = getentarray ("breakable clip","targetname");
for (i=0;i<temp.size;i++)
level.breakables_clip[level.breakables_clip.size] = temp[i];
level._breakable_utility_modelarray = [];
level._breakable_utility_modelindex = 0;
level._breakable_utility_maxnum = maxBrokenPieces;
common_scripts\utility::array_thread(getentarray ("explodable_barrel","targetname"), ::explodable_barrel_think);
//common_scripts\utility::array_thread(getentarray ("explodable_barrel","script_noteworthy"), ::explodable_barrel_think); ASK MO
common_scripts\utility::array_thread(getentarray ("oil_spill", "targetname"), ::oil_spill_think);
}
oil_spill_think()
{
self.end = getstruct(self.target, "targetname");
self.start = getstruct(self.end.target, "targetname");
self.barrel = getClosestEnt(self.start.origin, getentarray ("explodable_barrel","targetname"));
self.extra = getent(self.target, "targetname");
self setcandamage(true);
if(isdefined(self.barrel))
{
self.barrel.oilspill = true;
self thread oil_spill_burn_after();
}
while(1)
{
self waittill("damage", other, damage, direction_vec, P, type );
if(type == "MOD_MELEE" || type == "MOD_IMPACT")
continue;
self.damageOwner = other;
playfx (level.breakables_fx["oilspill"]["spark"], P, direction_vec);
//P = pointOnSegmentNearestToPoint(self.start.origin, self.end.origin, P);
thread oil_spill_burn_section(P);
self thread oil_spill_burn(P, self.start.origin);
self thread oil_spill_burn(P, self.end.origin);
break;
}
if(isdefined(self.barrel))
self.barrel waittill("exploding");
self.extra delete();
self hide();
wait 10;
self delete();
}
getClosestEnt(org, array)
{
if (array.size < 1)
return;
// dist = distance(array[0] getorigin(), org);
// ent = array[0];
dist = 256;
ent = undefined;
for (i=0;i<array.size;i++)
{
newdist = distance(array[i] getorigin(), org);
if (newdist >= dist)
continue;
dist = newdist;
ent = array[i];
}
return ent;
}
oil_spill_burn_after()
{
while(1)
{
self.barrel waittill("damage", amount ,attacker, direction_vec, P, type);
if(type == "MOD_MELEE" || type == "MOD_IMPACT")
continue;
break;
}
self.damageOwner = attacker;
// do not pass damage owner if they have disconnected before the barrels explode
if ( !isdefined( self.damageOwner ) )
self radiusdamage (self.origin, 4, 10, 10 );
else
self radiusdamage (self.origin, 4, 10, 10, self.damageOwner);
}
oil_spill_burn(P, dest)
{
forward = vectornormalize(dest - P);
dist = distance(p, dest);
range = 8;
interval = common_scripts\utility::vector_multiply(forward, range);
angle = vectortoangles(forward);
right = anglestoright(angle);
barrels = getentarray ("explodable_barrel","targetname");
distsqr = 22 * 22;
test = spawn("script_origin", P);
test hide();
num = 0;
while(1)
{
dist -= range;
if(dist < range *.1)
break;
p += (interval + common_scripts\utility::vector_multiply(right, randomfloatrange(-6, 6)));
thread oil_spill_burn_section(P);
num++;
if(num == 4)
{
num = 0;
}
test.origin = P;
remove = [];
barrels = common_scripts\utility::array_removeUndefined(barrels);
for(i=0; i<barrels.size; i++)
{
vec = anglestoup(barrels[i].angles);
start = barrels[i].origin + (common_scripts\utility::vector_multiply(vec, 22));
pos = physicstrace(start, start + (0,0,-64));
if(distancesquared(P, pos) < distsqr)
{
remove[remove.size] = barrels[i];
d = (80 + randomfloat(10));
if ( !isdefined ( self.damageOwner ) )
self radiusdamage (barrels[i].origin, 4, d, d);
else
self radiusdamage (barrels[i].origin, 4, d, d, self.damageOwner);
//barrels[i] dodamage( , P);
}
}
for(i=0; i<remove.size; i++)
barrels = common_scripts\utility::array_remove(barrels, remove[i]);
wait .1;
}
if(!isdefined(self.barrel))
return;
if( distance(P, self.start.origin) < 32)
{
d = (80 + randomfloat(10));
if ( !isdefined ( self.damageOwner ) )
self radiusdamage (self.barrel.origin, 4, d, d);
else
self radiusdamage (self.barrel.origin, 4, d, d, self.damageOwner);
}
}
oil_spill_burn_section(P)
{
count = 0;
time = 0;
playfx (level.breakables_fx["oilspill"]["burn"], P);
while(time < 5)
{
if ( !isdefined ( self.damageOwner ) )
self radiusdamage(P, 32, 5, 1);
else
self radiusdamage(P, 32, 5, 1, self.damageOwner);
time += 1;
wait 1;
}
}
explodable_barrel_think()
{
if (self.classname != "script_model")
return;
// if ( (self.model != "com_barrel_benzin") && (self.model != "com_barrel_benzin_snow") )
// return;
if(!isdefined(level.precachemodeltype["com_barrel_benzin"]))
{
level.precachemodeltype["com_barrel_benzin"] = true;
precacheModel("com_barrel_piece");
precacheModel("com_barrel_piece2");
}
self endon ("exploding");
self breakable_clip();
self.damageTaken = 0;
self setcandamage(true);
for (;;)
{
self waittill("damage", amount ,attacker, direction_vec, P, type);
if(type == "MOD_MELEE" || type == "MOD_IMPACT")
continue;
self.damagetype = type;
self.damageOwner = attacker;
if (level.barrelExplodingThisFrame)
wait randomfloat(1);
self.damageTaken += amount;
if (self.damageTaken == amount)
self thread explodable_barrel_burn();
}
}
explodable_barrel_burn()
{
count = 0;
startedfx = false;
up = anglestoup(self.angles);
worldup = anglestoup((0,90,0));
dot = vectordot(up, worldup);
offset1 = (0,0,0);
offset2 = common_scripts\utility::vector_multiply(up, 44);
if(dot < .5)
{
offset1 = common_scripts\utility::vector_multiply(up, 22) - (0,0,30);
offset2 = common_scripts\utility::vector_multiply(up, 22) + (0,0,14);
}
if( self.damagetype != "MOD_GRENADE_SPLASH" && self.damagetype != "MOD_GRENADE" )
{
while (self.damageTaken < level.barrelHealth)
{
if (!startedfx)
{
playfx (level.breakables_fx["barrel"]["burn_start"], self.origin + offset1);
startedfx = true;
}
if (count > 20)
count = 0;
playfx (level.breakables_fx["barrel"]["burn"], self.origin + offset2);
if (count == 0)
{
self.damageTaken += (10 + randomfloat(10));
}
count++;
wait 0.05;
}
}
self thread explodable_barrel_explode();
}
explodable_barrel_explode()
{
self notify ("exploding");
self notify ("death");
up = anglestoup(self.angles);
worldup = anglestoup((0,90,0));
dot = vectordot(up, worldup);
offset = (0,0,0);
if(dot < .5)
{
start = (self.origin + common_scripts\utility::vector_multiply(up, 22));
end = physicstrace(start, (start + (0,0,-64)));
offset = end - self.origin;
}
offset += (0,0,4);
self playsound (level.barrelExpSound);
//level thread play_sound_in_space(level.barrelExpSound, self.origin);
playfx (level.breakables_fx["barrel"]["explode"], self.origin + offset);
level.barrelExplodingThisFrame = true;
if (isdefined (self.remove))
{
self.remove delete();
}
phyExpMagnitude = 2;
minDamage = 1;
maxDamage = 250;
blastRadius = 250;
if (isdefined(self.radius))
blastRadius = self.radius;
// do not pass damage owner if they have disconnected before the barrels explode
if ( !isdefined( self.damageOwner ) )
self radiusDamage(self.origin + (0,0,30), blastRadius, maxDamage, minDamage, undefined, "MOD_EXPLOSIVE", "barrel_mp");
else
self radiusDamage(self.origin + (0,0,30), blastRadius, maxDamage, minDamage, self.damageOwner, "MOD_EXPLOSIVE", "barrel_mp" );
physicsExplosionSphere( self.origin + (0,0,30), blastRadius, blastRadius/2, phyExpMagnitude );
self maps\mp\gametypes\_shellshock::barrel_earthQuake();
if (randomint(2) == 0)
self setModel("com_barrel_piece");
else
self setModel("com_barrel_piece2");
self setCanDamage( false );
if(dot < .5)
{
start = (self.origin + common_scripts\utility::vector_multiply(up, 22));
pos = physicstrace(start, (start + (0,0,-64)));
self.origin = pos;
self.angles += (0,0,90);
}
wait 0.05;
level.barrelExplodingThisFrame = false;
}
getstruct(name, type)
{
if(!isdefined(level.struct_class_names))
return undefined;
array = level.struct_class_names[type][name];
if(!isdefined(array))
return undefined;
if(array.size > 1)
{
assertMsg ("getstruct used for more than one struct of type " + type + " called " + name +".");
return undefined;
}
return array[0];
}
breakable_clip()
{
//targeted brushmodels take priority over proximity based breakables - nate
if (isdefined(self.target))
{
targ = getent(self.target,"targetname");
if(targ.classname == "script_brushmodel")
{
self.remove = targ;
return;
}
}
//setup it's removable clip part
if ((isdefined (level.breakables_clip)) && (level.breakables_clip.size > 0))
self.remove = getClosestEnt( self.origin , level.breakables_clip );
if (isdefined (self.remove))
level.breakables_clip = common_scripts\utility::array_remove ( level.breakables_clip , self.remove );
}
+133
View File
@@ -0,0 +1,133 @@
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.5 )
amount_angle = 0.5;
else if ( amount_angle > 0.8 )
amount_angle = 1;
duration = amount_distance * amount_angle * 6;
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;
}
+237
View File
@@ -0,0 +1,237 @@
#include common_scripts\utility;
#include common_scripts\_fx;
#include common_scripts\_createfx;
#include maps\mp\_utility;
#include maps\mp\_createfx;
/*
****************************************************************************************************************
OneShotfx: Fires an effect once.
maps\mp\_fx::OneShotfx( effectname, (x y z), predelay);
Example:
maps\mp\_fx::OneShotfx(level.medFire, // Medium fire effect
(-701, -18361, 148), // Origin
5); // Wait 5 seconds before doing effect
****************************************************************************************************************
****************************************************************************************************************
Loopfx: Loops an effect with a waittime.
maps\mp\_fx::loopfx( effectname, (x y z), delay_between_shots);
Example:
maps\mp\_fx::loopfx(level.medFire, // Medium fire effect
(-701, -18361, 148), // Origin
0.3); // Wait 0.3 seconds between shots
****************************************************************************************************************
****************************************************************************************************************
GunFireLoopfx: Simulates bursts of fire.
maps\mp\_fx::gunfireloopfx(fxId, fxPos, shotsMin, shotsMax, shotdelayMin, shotdelayMax, betweenSetsMin, betweenSetsMax)
Example:
maps\mp\_fx::gunfireloopfx (level.medFire, // Medium fire effect
(-701, -18361, 148), // Origin
10, 15, // 10 to 15 shots
0.1, 0.3, // 0.1 to 0.3 seconds between shots
2.5, 9); // 2.5 to 9 seconds between sets of shots.
****************************************************************************************************************
****************************************************************************************************************
GrenadeExplosionfx: Creates a grenade explosion with view jitter.
maps\mp\_fx::GrenadeExplosionfx((x y z));
Example:
maps\mp\_fx::GrenadeExplosionfx( (-701, -18361, 148) ); // origin
****************************************************************************************************************
*/
script_print_fx()
{
if ( ( !isdefined( self.script_fxid ) ) || ( !isdefined( self.script_fxcommand ) ) || ( !isdefined( self.script_delay ) ) )
{
println( "Effect at origin ", self.origin, " doesn't have script_fxid/script_fxcommand/script_delay" );
self delete();
return;
}
if ( isdefined( self.target ) )
org = getent( self.target ).origin;
else
org = "undefined";
// println ("^a Command:", self.script_fxcommand, " Effect:", self.script_fxID, " Delay:", self.script_delay, " ", self.origin);
if ( self.script_fxcommand == "OneShotfx" )
println( "maps\mp\_fx::OneShotfx(\"" + self.script_fxid + "\", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
if ( self.script_fxcommand == "loopfx" )
println( "maps\mp\_fx::LoopFx(\"" + self.script_fxid + "\", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
if ( self.script_fxcommand == "loopsound" )
println( "maps\mp\_fx::LoopSound(\"" + self.script_fxid + "\", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
}
script_playfx( id, pos, pos2 )
{
if ( !id )
return;
if ( isdefined( pos2 ) )
playfx( id, pos, pos2 );
else
playfx( id, pos );
}
script_playfxontag( id, ent, tag )
{
if ( !id )
return;
playfxontag( id, ent, tag );
}
GrenadeExplosionfx( pos )
{
playfx( level._effect[ "mechanical explosion" ], pos );
earthquake( 0.15, 0.5, pos, 250 );
// TODO: Add explosion effect and view jitter
// println("The script command grenadeExplosionEffect has been removed. maps\\mp\\_fx::GrenadeExplosionfx must be set up to make an effect and jitter the view.");
}
soundfx( fxId, fxPos, endonNotify )
{
org = spawn( "script_origin", ( 0, 0, 0 ) );
org.origin = fxPos;
org playloopsound( fxId );
if ( isdefined( endonNotify ) )
org thread soundfxDelete( endonNotify );
/*
ent = level thread createfx_showOrigin ( fxId, fxPos, undefined, undefined, "soundfx" );
ent.delay = 0;
ent endon ("effect deleted");
ent.soundfx = org;
*/
}
soundfxDelete( endonNotify )
{
level waittill( endonNotify );
self delete();
}
/*rainfx( fxId, fxId2, fxPos )
{
org = spawn( "script_origin", ( 0, 0, 0 ) );
org.origin = fxPos;
org thread rainLoop( fxId, fxId2 );
//ent = level thread createfx_showOrigin( fxId, fxPos, undefined, undefined, "rainfx", undefined, fxId2 );
//ent.delay = 0;
//ent endon ("effect deleted");
//ent.soundfx = org;
}
rainLoop( hardRain, lightRain )
{
// org playloopsound (fxId);
self endon( "death" );
blend = spawn( "sound_blend", ( 0.0, 0.0, 0.0 ) );
blend.origin = self.origin;
self thread blendDelete( blend );
blend2 = spawn( "sound_blend", ( 0.0, 0.0, 0.0 ) );
blend2.origin = self.origin;
self thread blendDelete( blend2 );
// lerp of 0 will play _null only
blend setSoundBlend( lightRain + "_null", lightRain, 0 );
blend2 setSoundBlend( hardRain + "_null", hardRain, 1 );
rain = "hard";
blendTime = undefined;
for ( ;; )
{
level waittill( "rain_change", change, blendTime );
blendTime *= 20;// internal framerate
assert( change == "hard" || change == "light" || change == "none" );
assert( blendtime > 0 );
if ( change == "hard" )
{
if ( rain == "none" )
{
blendTime *= 0.5;// gotta do 2 blends to go from none to hard
for ( i = 0;i < blendtime;i++ )
{
blend setSoundBlend( lightRain + "_null", lightRain, i / blendtime );
wait( 0.05 );
}
rain = "light";
}
if ( rain == "light" )
{
for ( i = 0;i < blendtime;i++ )
{
blend setSoundBlend( lightRain + "_null", lightRain, 1 - ( i / blendtime ) );
blend2 setSoundBlend( hardRain + "_null", hardRain, i / blendtime );
wait( 0.05 );
}
}
}
if ( change == "none" )
{
if ( rain == "hard" )
{
blendTime *= 0.5;// gotta do 2 blends to go from hard to none
for ( i = 0;i < blendtime;i++ )
{
blend setSoundBlend( lightRain + "_null", lightRain, ( i / blendtime ) );
blend2 setSoundBlend( hardRain + "_null", hardRain, 1 - ( i / blendtime ) );
wait( 0.05 );
}
rain = "light";
}
if ( rain == "light" )
{
for ( i = 0;i < blendtime;i++ )
{
blend setSoundBlend( lightRain + "_null", lightRain, 1 - ( i / blendtime ) );
wait( 0.05 );
}
}
}
if ( change == "light" )
{
if ( rain == "none" )
{
for ( i = 0;i < blendtime;i++ )
{
blend setSoundBlend( lightRain + "_null", lightRain, i / blendtime );
wait( 0.05 );
}
}
if ( rain == "hard" )
{
for ( i = 0;i < blendtime;i++ )
{
blend setSoundBlend( lightRain + "_null", lightRain, i / blendtime );
blend2 setSoundBlend( hardRain + "_null", hardRain, 1 - ( i / blendtime ) );
wait( 0.05 );
}
}
}
rain = change;
}
}*/
blendDelete( blend )
{
self waittill( "death" );
blend delete();
}
+147
View File
@@ -0,0 +1,147 @@
#include common_scripts\utility;
#include maps\mp\_utility;
// This script automaticly plays a users specified oneshot effect on all prefabs that have the
// specified "script_struct" and "targetname" It also excepts angles from the "script_struct"
// but will set a default angle of ( 0, 0, 0 ) if none is defined.
//
// example of the syntax:
// global_FX( "targetname", "fxIDname", "fxFile", "delay"
main()
{
randomStartDelay = randomfloatrange( -20, -15 );
// prefabs/misc_models/com_barrel_fire.map
global_FX( "barrel_fireFX_origin", "global_barrel_fire", "fire/firelp_barrel_pm", randomStartDelay, "fire_barrel_small" );
// prefabs/misc_models/ch_street_light_02_on.map
// prefabs/misc_models/ch_street_wall_light_01_on.map
global_FX( "ch_streetlight_02_FX_origin", "ch_streetlight_02_FX", "misc/lighthaze", randomStartDelay );
// prefabs/misc_models/me_streetlight_on.map
// prefabs/misc_models/me_streetlight_on_scaleddown80.map
global_FX( "me_streetlight_01_FX_origin", "me_streetlight_01_FX", "misc/lighthaze_bog_a", randomStartDelay );
// prefabs\village_assault\misc\lamp_post.map
// prefabs\misc_models\ch_street_light_01_on.map
global_FX( "ch_street_light_01_on", "lamp_glow_FX", "misc/light_glow_white", randomStartDelay );
// prefabs\dcburning\lamp_post_globe_on.map
global_FX( "lamp_post_globe_on", "lamp_glow_FX", "misc/light_glow_white", randomStartDelay );
// prefabs\village_assault\misc\highway_lamp_post.map
global_FX( "highway_lamp_post", "ch_streetlight_02_FX", "misc/lighthaze_villassault", randomStartDelay );
// prefabs/misc_models/cs_cargoship_spotlight_on.map
global_FX( "cs_cargoship_spotlight_on_FX_origin", "cs_cargoship_spotlight_on_FX", "misc/lighthaze", randomStartDelay );
// prefabs/misc_models/me_dumpster_fire.map
global_FX( "me_dumpster_fire_FX_origin", "me_dumpster_fire_FX", "fire/firelp_med_pm", randomStartDelay, "fire_dumpster_medium" );
// prefabs/misc_models/com_tires01_burning.map
global_FX( "com_tires_burning01_FX_origin", "com_tires_burning01_FX", "fire/tire_fire_med", randomStartDelay );
// prefabs/icbm/icbm_powerlinetower02.map
global_FX( "icbm_powerlinetower_FX_origin", "icbm_powerlinetower_FX", "misc/power_tower_light_red_blink", randomStartDelay );
// prefabs/icbm/icbm_powerlinetower02.map
global_FX( "icbm_mainframe_FX_origin", "icbm_mainframe_FX", "props/icbm_mainframe_lightblink", randomStartDelay );
// prefabs/misc_model/cs_cargoship_wall_light_red_pulse.map
global_FX( "light_pulse_red_FX_origin", "light_pulse_red_FX", "misc/light_glow_red_generic_pulse", -2 );
// prefabs/misc_model/cs_cargoship_wall_light_red_pulse.map
global_FX( "light_pulse_red_FX_origin", "light_pulse_red_FX", "misc/light_glow_red_generic_pulse", -2 );
// prefabs/misc_model/cs_cargoship_wall_light_orange_pulse.map
global_FX( "light_pulse_orange_FX_origin", "light_pulse_orange_FX", "misc/light_glow_orange_generic_pulse", -2 );
// prefabs/oilrig/lights/light_corner_01.map
// prefabs/oilrig/helipad/helipad_light.map
global_FX( "light_red_blink_FX_origin", "light_red_blink", "misc/power_tower_light_red_blink", -2 );
// prefabs/misc_models/ch_industrial_light_01_on.map
global_FX( "lighthaze_oilrig_FX_origin", "lighthaze_oilrig", "misc/lighthaze_oilrig", randomStartDelay );
// prefabs/misc_models/ch_industrial_light_01_on_white.map
global_FX( "lighthaze_white_FX_origin", "lighthaze_white", "misc/lighthaze_white", randomStartDelay );
// prefabs/misc_models/cs_cargoship_wall_light_on.map
global_FX( "light_glow_walllight_white_FX_origin", "light_glow_walllight_white", "misc/light_glow_walllight_white", randomStartDelay );
// prefabs/misc_models/me_lightfluohang_on.map
global_FX( "fluorescent_glow_FX_origin", "fluorescent_glow", "misc/fluorescent_glow", randomStartDelay );
// prefabs/misc_models/ch_industrial_light_02_on.map
global_FX( "light_glow_industrial_FX_origin", "light_glow_industrial", "misc/light_glow_industrial", randomStartDelay );
// prefabs/cliffhanger/red_light1.map
// prefabs/misc_model/com_emergencylightcase_on.map
global_FX( "light_red_steady_FX_origin", "light_red_steady", "misc/tower_light_red_steady", -2 );
// prefabs/cliffhanger/blue_light1.map
// prefabs/oilrig/helipad/helipad_light.map
// prefabs/misc_model/com_emergencylightcase_blue_on.map
global_FX( "light_blue_steady_FX_origin", "light_blue_steady", "misc/tower_light_blue_steady", -2 );
// prefabs/misc_models/com_emergencylightcase_orange.map
global_FX( "light_orange_steady_FX_origin", "light_orange_steady", "misc/tower_light_orange_steady", -2 );
// prefabs/misc_models/mil_lightstick_pile_on.map
global_FX( "glow_stick_pile_FX_origin", "glow_stick_pile", "misc/glow_stick_glow_pile", -2 );
// prefabs/misc_models/mil_lightstick_pile_on_orange.map
global_FX( "glow_stick_orange_pile_FX_origin", "glow_stick_pile_orange", "misc/glow_stick_glow_pile_orange", -2 );
// prefabs/plaza/blinky_tower.map
global_FX( "highrise_blinky_tower", "highrise_blinky_tower_FX", "misc/power_tower_light_red_blink_large", randomStartDelay );
// prefabs/mil_emergency_flare.map
global_FX( "flare_ambient_FX_origin", "flare_ambient_FX", "misc/flare_ambient", randomStartDelay, "emt_road_flare_burn" );
// prefabs/misc_models/dt_light_on.map
// prefabs/misc_models/com_utility_light_on.map
// prefabs/misc_models/utility_lightbulb_bare_on.map
global_FX( "light_glow_white_bulb_FX_origin", "light_glow_white_bulb_FX", "misc/light_glow_white_bulb", randomStartDelay);
// prefabs/misc_models/com_restaurantceilinglamp_on.map
global_FX( "light_glow_white_lamp_FX_origin", "light_glow_white_lamp_FX", "misc/light_glow_white_lamp", randomStartDelay);
}
global_FX( targetname, fxName, fxFile, delay, soundalias )
{
// script_structs
ents = getstructarray(targetname,"targetname");
if ( !isdefined( ents ) )
return;
if ( ents.size <= 0 )
return;
for ( i = 0 ; i < ents.size ; i++ )
ents[i] global_FX_create( fxName, fxFile, delay, soundalias );
}
global_FX_create( fxName, fxFile, delay, soundalias )
{
if ( !isdefined( level._effect ) )
level._effect = [];
if ( !isdefined( level._effect[ fxName ] ) )
level._effect[ fxName ] = loadfx( fxFile );
// default effect angles if they dont exist
if ( !isdefined( self.angles ) )
self.angles = ( 0, 0, 0 );
ent = createOneshotEffect( fxName );
ent.v[ "origin" ] = ( self.origin );
ent.v[ "angles" ] = ( self.angles );
ent.v[ "fxid" ] = fxName;
ent.v[ "delay" ] = delay;
if ( isdefined( soundalias ) )
{
ent.v[ "soundalias" ] = soundalias;
}
}
+16
View File
@@ -0,0 +1,16 @@
#include maps\mp\_utility;
#include common_scripts\utility;
giveHighlight( ref, value )
{
highlightCount = getClientMatchData( "highlightCount" );
if ( highlightCount < 18 ) // must match MaxHighlights in clientmatchdata definition
{
setClientMatchData( "highlights", highlightCount, "award", ref );
setClientMatchData( "highlights", highlightCount, "clientId", self.clientMatchDataId );
setClientMatchData( "highlights", highlightCount, "value", value );
highlightCount++;
setClientMatchData( "highlightCount", highlightCount );
}
}
+567
View File
@@ -0,0 +1,567 @@
#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 )
{
MY_MIN_DIST = 1100;
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.harriers) )
{
foreach( harrier in level.harriers )
{
if ( isDefined( harrier ) && ( harrier.team != self.team || ( isDefined( harrier.owner ) && harrier.owner == self ) ) )
targets[targets.size] = harrier;
}
}
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;
}
}
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] );
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;
}
+338
View File
@@ -0,0 +1,338 @@
#include common_scripts\utility;
#include common_scripts\_fx;
#include maps\mp\_utility;
main()
{
if ( isDefined( level._loadStarted ) )
return;
level._loadStarted = true;
level.createFX_enabled = ( getdvar( "createfx" ) != "" );
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 );
}
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 );
}
}
+560
View File
@@ -0,0 +1,560 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
/*
level.lootColors = [];
level.lootColors["epic"] = (0.63, 0.2, 0.7) * 1.2;
level.lootColors["rare"] = (0, 0.43, 0.76) * 1.2;
level.lootColors["common"] = (0.11, 1, 0) * 1.0;
level.lootColors["none"] = (1, 1, 0.5);
*/
/*
level.lootColors["epic"] = (0.75, 1, 0.73) * 1.0;
level.lootColors["rare"] = (0.75, 1, 0.73) * 1.0;
level.lootColors["common"] = (0.75, 1, 0.73) * 1.0;
level.lootColors["none"] = (1, 1, 0.5);
*/
precacheString( &"MP_DOLLAR" );
level._effect["money"] = loadfx ("props/cash_player_drop");
maps\mp\gametypes\_rank::registerScoreInfo( "gear", 1000 );
maps\mp\gametypes\_rank::registerScoreInfo( "money", 1000 );
maps\mp\gametypes\_rank::registerScoreInfo( "common", 500 );
maps\mp\gametypes\_rank::registerScoreInfo( "rare", 1000 );
maps\mp\gametypes\_rank::registerScoreInfo( "epic", 2000 );
level.lootMins["epic"] = 90;
level.lootMins["rare"] = 70;
//level.lootMins["common"] = 95;
level.lootIndices["epic"] = 2;
level.lootIndices["rare"] = 1;
level.lootIndices["common"] = 0;
level.lootBaseChance = 0.05;
level.lootIdealTime = (15*60);
/#
thread updateLootDvars();
#/
thread onPlayerConnect();
}
onPlayerConnect()
{
for ( ;; )
{
level waittill( "connected", player );
player.pers["money"] = player maps\mp\gametypes\_persistence::statGet( "money" );
player.displayMoney = player.pers["money"];
player.moneyUpdateTotal = 0;
player.timeSinceLastLoot = player maps\mp\gametypes\_persistence::statGet( "timeSinceLastLoot" );
player thread initLootDisplay();
player thread onPlayerSpawned();
player thread onGameEnded();
}
}
onPlayerSpawned()
{
for ( ;; )
{
self waittill( "spawned_player" );
self thread trackLastLootTime();
}
}
onGameEnded()
{
self endon ( "disconnect" );
level waittill ( "game_ended" );
self maps\mp\gametypes\_persistence::statSet( "timeSinceLastLoot", self.timeSinceLastLoot );
}
trackLastLootTime()
{
self endon ( "death" );
self endon ( "disconnect" );
level endon ( "game_ended" );
for ( ;; )
{
wait ( 1.0 );
self.timeSinceLastLoot += 1;
}
}
initLootDisplay()
{
self.totalMoney = createFontString( "bigfixed", 0.8 );
self.totalMoney setPoint( "TOPRIGHT" );
self.totalMoney setValue( self.pers["money"] );
self.totalMoney.label = &"MP_DOLLAR";
self.totalMoney.glowColor = (0.3, 0.8, 0.3);
self.totalMoney.glowAlpha = 1;
self.totalMoney.alpha = 0;
self.earnedMoney = createFontString( "bigfixed", 0.7 );
self.earnedMoney setParent( self.totalMoney );
self.earnedMoney setPoint( "TOPRIGHT", "BOTTOMRIGHT", 0, 10 );
self.earnedMoney setValue( 0 );
self.earnedMoney.label = &"MP_PLUS";
self.earnedMoney.glowColor = (0.3, 0.8, 0.3);
self.earnedMoney.glowAlpha = 0.1;
self.earnedMoney.alpha = 0;
}
moMoney()
{
self endon ( "disconnect" );
for ( ;; )
{
wait ( randomFloatRange( 8.0, 10.0 ) );
self thread giveMoney( "asdf", randomIntRange( 100, 5000 ) );
}
}
giveMoney( type, amount )
{
if ( !self rankingEnabled() )
return;
self endon ( "disconnect" );
self notify( "giveMoney" );
self endon( "giveMoney" );
self.displayMoney = self.pers["money"];
self.pers["money"] += amount;
self maps\mp\gametypes\_persistence::statSet( "money", self.pers["money"] );
self.moneyUpdateTotal += amount;
self.totalMoney fadeOverTime( 0.5 );
self.totalMoney.alpha = 1;
self.earnedMoney fadeOverTime( 0.5 );
self.earnedMoney.alpha = 1;
self.earnedMoney setValue( self.moneyUpdateTotal );
wait ( 1.0 );
increment = max( int( self.moneyUpdateTotal / 30 ), 1 );
while ( self.moneyUpdateTotal > 0 )
{
addMoney = min( self.moneyUpdateTotal, increment );
self.moneyUpdateTotal -= addMoney;
self.displayMoney += addMoney;
self.totalMoney setValue( self.displayMoney );
self.earnedMoney setValue( self.moneyUpdateTotal );
wait ( 0.05 );
}
self.earnedMoney fadeOverTime( 1.0 );
self.earnedMoney.alpha = 0;
wait ( 2.0 );
self.totalMoney fadeOverTime( 1.0 );
self.totalMoney.alpha = 0;
}
updateLootDvars()
{
if ( getDvar( "scr_loot_epicMin" ) == "" )
setDvar( "scr_loot_epicMin", level.lootMins["epic"] );
if ( getDvar( "scr_loot_rareMin" ) == "" )
setDvar( "scr_loot_rareMin", level.lootMins["rare"] );
//if ( getDvar( "scr_loot_commonMin" ) == "" )
// setDvar( "scr_loot_commonMin", level.lootMins["common"] );
if ( getDvar( "scr_loot_baseChance" ) == "" )
setDvar( "scr_loot_baseChance", level.lootBaseChance );
if ( getDvar( "scr_loot_idealTime" ) == "" )
setDvar( "scr_loot_idealTime", level.lootIdealTime );
/#
if ( getDvar( "scr_forceloot" ) == "" )
setDvar( "scr_forceloot", "0" );
#/
for ( ;; )
{
/#
if ( getDvar( "scr_forceloot" ) != "" && getDvar( "scr_forceloot" ) != "0" )
{
setDvar( "scr_loot_baseChance", 1 );
}
#/
level.lootMins["epic"] = getDvarFloat( "scr_loot_epicMin" );
level.lootMins["rare"] = getDvarFloat( "scr_loot_rareMin" );
//level.lootMins["common"] = getDvarFloat( "scr_loot_commonMin" );
level.lootBaseChance = getDvarFloat( "scr_loot_baseChance" );
level.lootIdealTime = getDvarFloat( "scr_loot_idealTime" );
wait ( 1.0 );
}
}
unlockedCaC()
{
return self isItemUnlocked( "cac" );
}
gotLoot()
{
if ( !self rankingEnabled() )
return false;
if ( !self unlockedCaC() )
{
returnfalse = true;
/#
if ( getDvar( "scr_forceloot" ) != "" && getDvar( "scr_forceloot" ) != "0" )
returnfalse = false;
#/
if ( returnfalse )
return false;
}
baseChance = level.lootBaseChance;
idealLootTime = level.lootIdealTime;
maxLootChance = 0.50; // 50%
chanceMod = min( self.timeSinceLastLoot / idealLootTime, 1 );
chanceMod = chanceMod * chanceMod;
lootChance = baseChance + (maxLootChance - baseChance) * chanceMod;
return randomFloat( 1 ) < lootChance;
}
getLootTier( lootRoll )
{
if ( lootRoll >= level.lootMins["epic"] )
return "epic";
else if ( lootRoll >= level.lootMins["rare"] )
return "rare";
else
return "common";
}
getLootName( tier )
{
if ( !isDefined( self.droppedLootNames ) )
self.droppedLootNames = [];
for ( try = 0; try < 10; try++ )
{
lootName = self GetRandomLoot( tier );
if ( !isDefined( lootName ) )
return undefined;
for ( i = 0; i < self.droppedLootNames.size; i++ )
{
if ( lootName == self.droppedLootNames[i] )
break;
}
if ( i < self.droppedLootNames.size )
continue;
return lootName;
}
return undefined;
}
giveLoot( victim )
{
if ( !gotLoot() )
return false;
lootTier = getLootTier( randomFloat( 100.0 ) );
tierInt = level.lootIndices[lootTier];
lootName = self getLootName( tierInt );
if ( !isDefined( lootName ) )
return false;
self maps\mp\gametypes\_persistence::statSet( "timeSinceLastLoot", 0 );
self.timeSinceLastLoot = 0;
thread maps\mp\_loot::playMoneyFx( victim, self );
if ( lootTier == "epic" )
{
self CreateLootMail( lootName );
self thread showLootNotify( lootTier );
}
else
{
self thread dropLoot( lootTier, lootName, victim );
}
return true;
}
showLootNotify( lootTier )
{
/*
notifyData = spawnStruct();
if ( lootTier == "epic" )
{
notifyData.titleText = "Target of Opportunity!";
notifyData.iconName = "skull_black_plain";
notifyData.iconOverlay = "skull_crosshair_white";
}
else
{
notifyData.titleText = "You've got mail!";
}
//notifyData.sound = "loot_drop_" + lootTier;
notifyData.sound = "mp_last_stand";
notifyData.glowColor = (1, 0, 0);
notifyData.duration = 3.0;
thread maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
*/
}
playMoneyFx( victim, attacker, sMeansOfDeath )
{
/*
victim endon ( "disconnect" );
origin = victim getTagOrigin( "j_spine4" );
victim.fxModel.origin = origin;
wait ( 0.05 );
*/
//playFxOnTag( level._effect["money"], victim.fxModel, "tag_origin" );
//playFxOnTagForClients ( level._effect["money"], victim.fxModel, "tag_origin", attacker );
}
dropLoot( lootTier, lootName, dropEnt )
{
trace = playerPhysicsTrace( dropEnt.origin + (0,0,20), dropEnt.origin - (0,0,2000), false, dropEnt);
angleTrace = bulletTrace( dropEnt.origin + (0,0,20), dropEnt.origin - (0,0,2000), false, dropEnt );
if ( !isDefined( trace ) )
return;
println( "dropping loot" );
tempAngle = randomfloat( 360 );
dropOrigin = trace;
assert( isdefined( self.droppedLootNames ) );
/#
foreach ( droppedLootName in self.droppedLootNames )
{
assert( droppedLootName != lootName );
}
#/
if ( lootName[0] != "$" )
self.droppedLootNames[ self.droppedLootNames.size ] = lootName;
fxEnt = spawn( "script_model", dropOrigin );
//fxEnt.angles = (-90,0,0);
lootIcon = newClientHudElem( self );
lootIcon.x = dropOrigin[0];
lootIcon.y = dropOrigin[1];
lootIcon.z = dropOrigin[2];
lootIcon.alpha = 1;
lootTrigger = spawn( "trigger_radius", dropOrigin, 0, 32, 128 );
//lootTrigger.angles = (-90,0,0);
lootTrigger.fxEnt = fxEnt;
lootTrigger.icon = lootIcon;
lootTrigger.owner = self;
lootTrigger thread lootPickupWaiter( lootTier, lootName );
lootTrigger thread lootDeleteOnDisconnect();
/#
if ( getdvarint( "scr_lootdebug" ) )
lootTrigger thread lootDebugPrint( lootTier, lootName );
#/
lootTrigger endon ( "death" );
wait ( 0.05 );
self playLocalSound( "loot_drop_" + lootTier );
switch ( lootTier )
{
case "epic":
case "rare":
default:
fxEnt setModel( "gamestation_box" );
lootIcon setShader( "hud_overlay_random", 10, 10 );
lootIcon setWaypoint( true, false );
lootIcon.alpha = 0.81;
//playFxOnTagForClients( level._effect["gears"], fxEnt, "tag_origin", self );
break;
}
}
lootDebugPrint( lootTier, lootName )
{
self endon("death");
while ( 1 )
{
print3d( self.origin, "(" + lootTier + ") " + lootName );
wait .05;
}
}
lootPickupWaiter( lootTier, lootName )
{
self endon ( "death" );
self.owner endon ( "disconnect" );
for ( ;; )
{
self waittill ( "trigger", player );
if ( player != self.owner )
continue;
//self.owner playLocalSound( "loot_pickup_" + lootTier ); // need better sound
self.owner playLocalSound( "mp_last_stand" );
/*
switch ( lootTier )
{
case "epic":
streakName = getRandomKillstreak( 7 );
self.owner thread [[level.onXPEvent]]( "gear" );
break;
case "rare":
streakName = getRandomKillstreak( 5 );
self.owner thread [[level.onXPEvent]]( "gear" );
break;
default:
streakName = getRandomKillstreak( 3 );
self.owner thread [[level.onXPEvent]]( "money" );
break;
}
self.owner thread randomKillstreakNotify( streakName );
self.owner maps\mp\killstreaks\_killstreaks::giveKillstreak( streakName );
*/
self.owner pickupLoot( lootTier, lootName );
self.fxEnt delete();
self.icon destroy();
self delete();
}
}
pickupLoot( lootTier, lootName )
{
self thread showLootNotify( lootTier );
self thread [[level.onXPEvent]]( lootTier );
self CreateLootMail( lootName );
if ( lootName[0] != "$" )
{
for ( i = 0; i < self.droppedLootNames.size; i++ )
{
if ( self.droppedLootNames[i] == lootName )
{
break;
}
}
assert( i < self.droppedLootNames.size );
for ( ; i < self.droppedLootNames.size; i++ )
{
self.droppedLootNames[i] = self.droppedLootNames[i + 1];
}
}
}
lootDeleteOnDisconnect()
{
self endon ( "death" );
self.owner waittill ( "disconnect" );
self.fxEnt delete();
//self.icon destroy(); // code seems to take care of this automatically
self delete();
}
getRandomKillstreak( minKillCount )
{
killStreakNames = getArrayKeys( level.killstreakFuncs );
killStreaks = [];
foreach ( streakName in killStreakNames )
{
if ( maps\mp\killstreaks\_killstreaks::getStreakCost( streakName ) < minKillCount )
continue;
killStreaks[killStreaks.size] = streakName;
}
return killStreaks[randomInt( killStreaks.size )];
}
randomKillstreakNotify( streakName )
{
self endon("disconnect");
notifyData = spawnStruct();
notifyData.titleText = "Killstreak In a Box!";
notifyData.notifyText = maps\mp\killstreaks\_killstreaks::getKillstreakHint( streakName );
notifyData.textIsString = true;
notifyData.sound = maps\mp\killstreaks\_killstreaks::getKillstreakSound( streakName );
notifyData.leaderSound = streakName;
notifyData.glowColor = (1, 0.76, 0.35);
notifyData.textGlowColor = (1, 1, 0.5);
self maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
}
+359
View File
@@ -0,0 +1,359 @@
#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"];
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 );
loadoutEquipment = maps\mp\gametypes\_class::cac_getPerk( class_num, 0 );
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 );
loadoutEquipment = maps\mp\gametypes\_class::table_getEquipment( level.classTableName, class_num, 0 );
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, "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 ( 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] );
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, "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
View File
@@ -0,0 +1,50 @@
minefields()
{
minefields = getentarray("minefield", "targetname");
if (minefields.size > 0)
{
level._effect["mine_explosion"] = loadfx ("explosions/grenadeExp_dirt");
}
for(i = 0; i < minefields.size; i++)
{
minefields[i] thread minefield_think();
}
}
minefield_think()
{
while (1)
{
self waittill ("trigger",other);
if(isPlayer(other))
other thread minefield_kill(self);
}
}
minefield_kill(trigger)
{
if(isDefined(self.minefield))
return;
self.minefield = true;
self playsound ("minefield_click");
wait(.5);
wait(randomFloat(.5));
if(isdefined(self) && self istouching(trigger))
{
origin = self getorigin();
range = 300;
maxdamage = 2000;
mindamage = 50;
self playsound("explo_mine");
playfx(level._effect["mine_explosion"], origin);
radiusDamage(origin, range, maxdamage, mindamage);
}
self.minefield = undefined;
}
+228
View File
@@ -0,0 +1,228 @@
#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;
}
+135
View File
@@ -0,0 +1,135 @@
#include maps\mp\_utility;
#include common_scripts\utility;
processLobbyScoreboards()
{
foreach ( player in level.placement["all"] )
player setPlayerScoreboardInfo();
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 );
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" );
println( "Scoreboard: Building scoreboard (" + team + ")" );
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
View File
@@ -0,0 +1,179 @@
#include common_scripts\utility;
#include maps\mp\_utility;
main()
{
// thread windController();
level.inc = 0;
array_levelthread (getentarray("wire","targetname"), ::wireWander);
leftShutters = getentarray ("shutter_left","targetname");
addShutters = getentarray ("shutter_right_open","targetname");
for (i=0;i<addShutters.size;i++)
leftShutters[leftShutters.size] = addShutters[i];
addShutters = getentarray ("shutter_left_closed","targetname");
for (i=0;i<addShutters.size;i++)
leftShutters[leftShutters.size] = addShutters[i];
for (i=0;i<leftShutters.size;i++)
{
shutter = leftShutters[i];
shutter rotateto((shutter.angles[0], shutter.angles[1] + 180, shutter.angles[2]), 0.1);
}
wait (0.2);
for (i=0;i<leftShutters.size;i++)
leftShutters[i].startYaw = leftShutters[i].angles[1];
rightShutters = getentarray ("shutter_right","targetname");
addShutters = getentarray ("shutter_left_open","targetname");
for (i=0;i<addShutters.size;i++)
rightShutters[rightShutters.size] = addShutters[i];
addShutters = getentarray ("shutter_right_closed","targetname");
for (i=0;i<addShutters.size;i++)
rightShutters[rightShutters.size] = addShutters[i];
for (i=0;i<rightShutters.size;i++)
rightShutters[i].startYaw = rightShutters[i].angles[1];
addShutters = undefined;
windDirection = "left";
for (;;)
{
array_levelthread (leftShutters, ::shutterWanderLeft, windDirection);
array_levelthread (rightShutters, ::shutterWanderRight, windDirection);
level waittill ("wind blows", windDirection);
}
}
windController()
{
for (;;)
{
windDirection = "left";
if (randomint(100) > 50)
windDirection = "right";
level notify ("wind blows", windDirection);
wait (2 + randomfloat(10));
}
}
shutterWanderLeft(shutter, windDirection)
{
// println ("shutter angles ", shutter.angles[1]);
// assert (shutter.angles[1] >= shutter.startYaw);
// assert (shutter.angles[1] < shutter.startYaw + 180);
// println ("Wind + ", level.inc);
level.inc++;
level endon ("wind blows");
newYaw = shutter.startYaw;
if (windDirection == "left")
newYaw += 179.9;
newTime = 0.2;
shutter rotateto((shutter.angles[0], newYaw, shutter.angles[2]), newTime);
wait (newTime + 0.1);
for (;;)
{
rot = randomint(80);
if (randomint(100) > 50)
rot *= -1;
newYaw = shutter.angles[1] + rot;
altYaw = shutter.angles[1] + (rot*-1);
if ((newYaw < shutter.startYaw) || (newYaw > shutter.startYaw + 179))
{
newYaw = altYaw;
}
dif = abs(shutter.angles[1] - newYaw);
newTime = dif*0.02 + randomfloat(2);
if (newTime < 0.3)
newTime = 0.3;
// println ("startyaw " + shutter.startyaw + " newyaw " + newYaw);
// assert (newYaw >= shutter.startYaw);
// assert (newYaw < shutter.startYaw + 179);
shutter rotateto((shutter.angles[0], newYaw, shutter.angles[2]), newTime, newTime * 0.5, newTime * 0.5);
wait (newTime);
}
}
shutterWanderRight(shutter, windDirection)
{
// println ("shutter angles ", shutter.angles[1]);
// assert (shutter.angles[1] >= shutter.startYaw);
// assert (shutter.angles[1] < shutter.startYaw + 180);
// println ("Wind + ", level.inc);
level.inc++;
level endon ("wind blows");
newYaw = shutter.startYaw;
if (windDirection == "left")
newYaw += 179.9;
newTime = 0.2;
shutter rotateto((shutter.angles[0], newYaw, shutter.angles[2]), newTime);
wait (newTime + 0.1);
for (;;)
{
rot = randomint(80);
if (randomint(100) > 50)
rot *= -1;
newYaw = shutter.angles[1] + rot;
altYaw = shutter.angles[1] + (rot*-1);
if ((newYaw < shutter.startYaw) || (newYaw > shutter.startYaw + 179))
{
newYaw = altYaw;
}
dif = abs(shutter.angles[1] - newYaw);
newTime = dif*0.02 + randomfloat(2);
if (newTime < 0.3)
newTime = 0.3;
// println ("startyaw " + shutter.startyaw + " newyaw " + newYaw);
// assert (newYaw >= shutter.startYaw);
// assert (newYaw < shutter.startYaw + 179);
shutter rotateto((shutter.angles[0], newYaw, shutter.angles[2]), newTime, newTime * 0.5, newTime * 0.5);
wait (newTime);
}
}
wireWander (wire)
{
origins = getentarray (wire.target,"targetname");
org1 = origins[0].origin;
org2 = origins[1].origin;
angles = vectortoangles (org1 - org2);
ent = spawn ("script_model",(0,0,0));
ent.origin = vector_multiply(org1, 0.5) + vector_multiply(org2, 0.5);
// ent setmodel ("temp");
ent.angles = angles;
wire linkto (ent);
rottimer = 2;
rotrange = 0.9;
dist = 4 + randomfloat(2);
ent rotateroll(dist*0.5,0.2);
wait (0.2);
for (;;)
{
rottime = rottimer + randomfloat (rotRange) - (rotRange * 0.5);
ent rotateroll(dist,rottime, rottime*0.5, rottime*0.5);
wait (rottime);
ent rotateroll(dist * -1,rottime, rottime*0.5, rottime*0.5);
wait (rottime);
}
}
+71
View File
@@ -0,0 +1,71 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
level thread onPlayerConnect();
level thread onPlayerDisconnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
// look at how spawning works
player.connectTime = getTime();
player.targets = [];
player thread onWeaponFired();
player thread onDeath();
}
}
onPlayerDisconnect()
{
for(;;)
{
level waittill( "disconnected", player );
player.targets = [];
}
}
onWeaponFired()
{
level endon( "game_ended" );
self endon( "disconnected" );
for ( ;; )
{
self waittill( "weapon_fired" );
// find likely target
// find target and tag when they shot me.
//self.target
}
}
onDeath()
{
level endon( "game_ended" );
self endon( "disconnected" );
for ( ;; )
{
self waittill( "death" );
//
// find target and tag when they shot me.
//self.target
}
}
processKill( attacker, defender )
{
updateSkill( attacker, defender, "tdm", 1.0 );
}
+360
View File
@@ -0,0 +1,360 @@
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.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;
}
}
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;
}
}
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 ( 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
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;
}
}
}
}
+461
View File
@@ -0,0 +1,461 @@
#include maps\mp\_utility;
#include common_scripts\utility;
SOUND_DELAY_MIN = 0.1;
SOUND_DELAY_MAX = 1;
init()
{
train = getEnt( "the_l_train", "targetname" );
assertex( isdefined( train ), "Calling to setup train in map without having the train in map! [targetname: the_l_train]" );
train thread train_setup();
}
train_setup()
{
precacheItem( "train_mp" );
delay_until_first_train = 2;
Units_per_second = 1200;// train speed
train_cars = 24;
distance_between_cars = 368;
eq_radius = 900;// radius of earthquakes broadcast from the train tracks
min_time_between_trains = 100;
max_time_between_trains = 200;
lead_in_dist = 8000;
lead_out_dist = 4000;
train_car_sound_interval = 3;
flag_init( "train_running" );
yaw = self.angles[ 1 ];
while ( yaw >= 90 )
{
yaw -= 90;
}
assertEx( yaw == 0, "Trains must have a yaw of 0, 90, 180, or 270 currently( for collision purposes )" );
wheels = getentarray( "wheel", "targetname" );
wheel_model = wheels[ 0 ].model;
wheel_offset = [];
foreach ( wheel in wheels )
{
wheel linkto( self );
wheel.offset = self.origin - wheel.origin;
}
// ****************
// Set up the other cars
// ****************
forward = anglestoforward( self.angles );
forward *= distance_between_cars;
car_separation_vec = forward;
cars = [];
for ( i = 0; i < train_cars - 1; i++ )// - 1 car self is the lead car
{
car = spawn( "script_model", self.origin - car_separation_vec );
car.angles = self.angles;
car setmodel( self.model );
car linkto( self );
car_separation_vec += forward;
cars[ cars.size ] = car;
car.wheels = [];
foreach ( owner_wheel in wheels )
{
wheel = spawn( "script_model", car.origin + owner_wheel.offset );
wheel setmodel( wheel_model );
wheel.angles = owner_wheel.angles;
wheel linkto( car );
car.wheels[ car.wheels.size ] = wheel;
}
}
// ****************
// The start and end points for the train, set from script origins
// ****************
start = getent( self.target, "targetname" );
start.origin = ( start.origin[ 0 ], start.origin[ 1 ], self.origin[ 2 ] );
end = getent( start.target, "targetname" );
end.origin = ( end.origin[ 0 ], end.origin[ 1 ], self.origin[ 2 ] );
forward = anglestoforward( self.angles );
start.origin = start.origin - forward * lead_in_dist;
end.origin = end.origin + forward * lead_out_dist;
track_dist = distance( start.origin, end.origin );
travel_dist = track_dist + train_cars * distance_between_cars;
travel_time = travel_dist / Units_per_second;
track_time = track_dist / Units_per_second;
full_train_time = train_cars * distance_between_cars / Units_per_second;
// ****************
// set up the earthquakes that play to make the train tracks rattle
// ****************
distance_between_eq_orgs = eq_radius * 0.5;
eq_count = track_dist / distance_between_eq_orgs;
// the amount of time it takes for all the EQs to start before the train moves in
delay_between_eqs = track_time / eq_count;
travel_time_segment = track_time / eq_count;
min_time_between_trains -= track_time;
if ( min_time_between_trains < 0.1 )
min_time_between_trains = 0.1;
max_time_between_trains -= track_time;
if ( max_time_between_trains < min_time_between_trains )
max_time_between_trains = min_time_between_trains + 0.1;
eq_points = [];
for ( i = 0; i < eq_count; i++ )
{
progress = i / eq_count;
eq_points[ i ] = start.origin * ( 1 - progress ) + end.origin * progress;
}
self.cars = cars;
self.wheels = wheels;
self.origin = start.origin;
wait( delay_until_first_train );
for ( ;; )
{
hide_trains();
wait( 0.05 );
self.origin = start.origin;
// First there is a lead in of small EQs to shake the platform
timer = gettime();
for ( i = 0; i < eq_count; i++ )
{
thread train_eq( eq_points[ i ], eq_radius, track_time, full_train_time );
wait( delay_between_eqs );
}
show_trains();
thread train_kills_players( train_cars, distance_between_cars );
thread train_spawns_dust();
// Now the train goes by
self moveto( end.origin + car_separation_vec, travel_time );
train_play_sounds( train_car_sound_interval );
wait( travel_time );
hide_trains();
train_stop_sounds( train_car_sound_interval );
flag_set( "train_running" );
self notify( "train_stops_killing_players" );
// Wait until the next train
wait( randomfloatrange( min_time_between_trains, max_time_between_trains ) );
}
}
train_play_sound_delayed( alias )
{
wait( randomfloatrange( SOUND_DELAY_MIN, SOUND_DELAY_MAX ) );
self playLoopSound( alias );
}
train_play_sounds( max )
{
self thread train_play_sound_delayed( "veh_train_eng_dist1_loop" );
self thread train_play_sound_delayed( "veh_train_eng_dist2_loop" );
self thread train_play_sound_delayed( "veh_train_eng_mid_loop" );
self thread train_play_sound_delayed( "veh_train_eng_close1_loop" );
self thread train_play_sound_delayed( "veh_train_eng_close2_loop" );
// dont play sounds on every car
count = 0;
for ( i = 0; i < self.cars.size; i++ )
{
count++;
if ( count < max )
continue;
count = 0;
self.cars[ i ] thread train_play_sound_delayed( "veh_train_car_dist_loop" );
self.cars[ i ] thread train_play_sound_delayed( "veh_train_car_mid_loop" );
self.cars[ i ] thread train_play_sound_delayed( "veh_train_car_close_loop" );
}
}
train_stop_sounds( max )
{
self stopLoopSound( "veh_train_eng_dist1_loop" );
self stopLoopSound( "veh_train_eng_dist2_loop" );
self stopLoopSound( "veh_train_eng_mid_loop" );
self stopLoopSound( "veh_train_eng_close1_loop" );
self stopLoopSound( "veh_train_eng_close2_loop" );
count = 0;
for ( i = 0; i < self.cars.size; i++ )
{
count++;
if ( count < max )
continue;
count = 0;
self.cars[ i ] stopLoopSound( "veh_train_car_dist_loop" );
self.cars[ i ] stopLoopSound( "veh_train_car_mid_loop" );
self.cars[ i ] stopLoopSound( "veh_train_car_close_loop" );
}
}
hide_trains()
{
// Hide the train while it warps to position
self hide();
foreach ( wheel in self.wheels )
{
wheel hide();
}
foreach ( car in self.cars )
{
car hide();
foreach ( wheel in car.wheels )
{
wheel hide();
}
}
}
show_trains()
{
// show the train while it warps to position
self show();
foreach ( wheel in self.wheels )
{
wheel show();
}
foreach ( car in self.cars )
{
car show();
foreach ( wheel in car.wheels )
{
wheel show();
}
}
}
train_spawns_dust()
{
if ( !isdefined( level._effect[ "train_dust" ] ) )
return;
range = 40;
self endon( "train_stops_killing_players" );
for ( ;; )
{
/*
for ( i = 0; i < 10; i ++ )
{
x = randomfloatrange( self.min_x, self.max_x );
y = randomfloatrange( self.min_y, self.max_y );
PlayFX( level._effect[ "train_dust" ], ( x, y, self.origin[ 2 ] - 30 ) );
}
*/
count = randomintrange( 1, 3 ); // which means 1 to 2 fx per frame
for ( i = 0; i < count; i ++ )
{
x = randomfloatrange( self.min_x - range, self.max_x + range );
y = randomfloatrange( self.min_y - range, self.max_y + range );
PlayFX( level._effect[ "train_dust_linger" ], ( x, y, self.origin[ 2 ] - 10 ) );
}
wait( 0.05 );
}
}
train_kills_players( train_cars, distance_between_cars )
{
// find the extents of the train, presuming it is going straight n/s/e/w and then test vs player origins to see
// if they should be run over
train_width = 68;
self endon( "train_stops_killing_players" );
forward = anglestoforward( self.angles );
right = anglestoright( self.angles );
full_car_vec = forward * distance_between_cars;
half_car_vec = full_car_vec * 0.5;
train_width_vec = right * train_width;
sides = [];
sides[ "front" ] = self.origin + half_car_vec;
sides[ "rear" ] = self.origin + train_cars * full_car_vec * - 1;
sides[ "right" ] = self.origin + train_width_vec;
sides[ "left" ] = self.origin - train_width_vec;
start = self.origin;
max_x = sides[ "front" ][ 0 ];
min_x = sides[ "front" ][ 0 ];
max_y = sides[ "front" ][ 1 ];
min_y = sides[ "front" ][ 1 ];
foreach ( side in sides )
{
if ( side[ 0 ] > max_x )
max_x = side[ 0 ];
if ( side[ 0 ] < min_x )
min_x = side[ 0 ];
if ( side[ 1 ] > max_y )
max_y = side[ 1 ];
if ( side[ 1 ] < min_y )
min_y = side[ 1 ];
}
for ( ;; )
{
dif = start - self.origin;
start = self.origin;
max_x -= dif[ 0 ];
min_x -= dif[ 0 ];
max_y -= dif[ 1 ];
min_y -= dif[ 1 ];
// store it for the dust fx
self.min_x = min_x;
self.max_x = max_x;
self.min_y = min_y;
self.max_y = max_y;
//print3d( ( max_x, max_y, self.origin[ 2 ] ), " * " );
//print3d( ( min_x, max_y, self.origin[ 2 ] ), " * " );
//print3d( ( max_x, min_y, self.origin[ 2 ] ), " * " );
//print3d( ( min_x, min_y, self.origin[ 2 ] ), " * " );
hit_ents = [];
foreach ( player in level.players )
{
if ( !isalive( player ) )
continue;
if ( player.sessionstate != "playing" )
continue;
if ( !train_hits( player, min_x, min_y, max_x, max_y ) )
continue;
player playsound( "melee_knife_hit_watermelon" );
pos = get_damageable_player_pos( player );
hit_ents[ hit_ents.size ] = get_damageable_player( player, pos );
}
grenades = getentarray( "grenade", "classname" );
foreach ( grenade in grenades )
{
if ( !train_hits( grenade, min_x, min_y, max_x, max_y ) )
continue;
pos = get_damageable_grenade_pos( grenade );
hit_ents[ hit_ents.size ] = get_damageable_grenade( grenade, pos );
}
foreach ( ent in hit_ents )
{
ent.damage = 5000;
ent.pos = self.origin;
ent.damageOwner = self;
ent.eInflictor = self;
ent maps\mp\gametypes\_weapons::damageEnt(
ent.eInflictor, // eInflictor = the entity that causes the damage (e.g. a claymore)
ent.damageOwner, // eAttacker = the player that is attacking
ent.damage, // iDamage = the amount of damage to do
"MOD_PROJECTILE_SPLASH", // sMeansOfDeath = string specifying the method of death (e.g. "MOD_PROJECTILE_SPLASH")
"train_mp", // sWeapon = string specifying the weapon used (e.g. "claymore_mp")
ent.pos, // damagepos = the position damage is coming from
vectornormalize(ent.damageCenter - ent.pos) // damagedir = the direction damage is moving in
);
}
wait( 0.05 );
}
}
train_hits( entity, min_x, min_y, max_x, max_y )
{
if ( entity.origin[ 2 ] < self.origin[ 2 ] - 5 )
return false;
if ( entity.origin[ 2 ] > self.origin[ 2 ] + 162 )
return false;
x = entity.origin[ 0 ];
y = entity.origin[ 1 ];
if ( x < min_x )
return false;
if ( y < min_y )
return false;
if ( x > max_x )
return false;
if ( y > max_y )
return false;
return true;
}
train_eq( origin, eq_radius, track_time, full_train_time )
{
train_eq_lerp_for_time( origin, 0.0, 0.09, eq_radius, track_time, 0.5 );
train_eq_for_time( origin, 0.17, eq_radius, full_train_time, 0.5 );
train_eq_lerp_for_time( origin, 0.09, 0, eq_radius, track_time, 0.5 );
//level notify( "stop_train_debug" + origin );
}
train_eq_for_time( origin, eq, eq_radius, eq_time, eq_time_slice )
{
// earthquake makes the quake taper off over time so we
// are going to do a lot of earthquakes to simulate a steady quake
//thread print3d_eq( origin, eq );
steps = int( eq_time / eq_time_slice );
for ( i = 0; i < steps; i++ )
{
Earthquake( eq, eq_time_slice * 3, origin, eq_radius );
wait( eq_time_slice );
}
remainder = eq_time - steps * eq_time_slice;
if ( remainder > 0 )
{
wait( remainder );
}
}
train_eq_lerp_for_time( origin, eq1, eq2, eq_radius, eq_time, eq_time_slice )
{
// earthquake makes the quake taper off over time so we
// are going to do a lot of earthquakes to simulate a steady quake
//thread print3d_eq( origin, eq );
steps = int( eq_time / eq_time_slice );
for ( i = 0; i < steps; i++ )
{
progress = i / steps;
eq = eq2 * progress + eq1 * ( 1 - progress );
if ( eq > 0 )
Earthquake( eq, eq_time_slice * 3, origin, eq_radius );
wait( eq_time_slice );
}
remainder = eq_time - steps * eq_time_slice;
if ( remainder > 0 )
{
wait( remainder );
}
}
print3d_eq( origin, msg )
{
level notify( "stop_train_debug" + origin );
level endon( "stop_train_debug" + origin );
for ( ;; )
{
Print3d( origin, msg );
wait( 0.05 );
}
}
+2727
View File
File diff suppressed because it is too large. Load diff
@@ -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
@@ -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
@@ -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";
}
@@ -0,0 +1,12 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
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";
}
@@ -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";
}
@@ -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_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";
}
@@ -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";
}
@@ -0,0 +1,12 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level.anim_prop_models ) )
level.anim_prop_models = [];
model = "foliage_tree_palm_bushy_3";
level.anim_prop_models[ model ] = "palmtree_tall3_sway_tropical";
}
@@ -0,0 +1,12 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level.anim_prop_models ) )
level.anim_prop_models = [];
model = "foliage_tree_palm_med_1";
level.anim_prop_models[ model ][ "sway" ] = "palmtree_med1_sway";
}
@@ -0,0 +1,12 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
if( !isdefined ( level.anim_prop_models ) )
level.anim_prop_models = [];
model = "foliage_tree_palm_med_2";
level.anim_prop_models[ model ][ "sway" ] = "palmtree_med2_sway";
}
@@ -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";
}
@@ -0,0 +1,20 @@
#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 = "hanging_apron";
if ( SP )
level.anim_prop_models[ model ][ "wind_medium" ] = %hanging_clothes_apron_wind_medium;
else
level.anim_prop_models[ model ][ "wind_medium" ] = "hanging_clothes_apron_wind_medium";
}
@@ -0,0 +1,20 @@
#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 = "hanging_long_sleeve";
if ( SP )
level.anim_prop_models[ model ][ "wind_medium" ] = %hanging_clothes_long_sleeve_wind_medium;
else
level.anim_prop_models[ model ][ "wind_medium" ] = "hanging_clothes_long_sleeve_wind_medium";
}
@@ -0,0 +1,20 @@
#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 = "hanging_sheet";
if ( SP )
level.anim_prop_models[ model ][ "wind_medium" ] = %hanging_clothes_sheet_wind_medium;
else
level.anim_prop_models[ model ][ "wind_medium" ] = "hanging_clothes_sheet_wind_medium";
}
@@ -0,0 +1,20 @@
#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 = "hanging_short_sleeve";
if ( SP )
level.anim_prop_models[ model ][ "wind_medium" ] = %hanging_clothes_short_sleeve_wind_medium;
else
level.anim_prop_models[ model ][ "wind_medium" ] = "hanging_clothes_short_sleeve_wind_medium";
}
@@ -0,0 +1,13 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level.anim_prop_models ) )
level.anim_prop_models = [];
// Uses .animation
model = "highrise_fencetarp_04b_wind_a";
level.anim_prop_models[ model ][ "wind_a" ] = "mp_storm_fencetarp_04_windA";
}
// SP not currently supported because this requires updating "animated_props" animtree
@@ -0,0 +1,13 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level.anim_prop_models ) )
level.anim_prop_models = [];
// Uses .animation
model = "highrise_fencetarp_04b_wind_b";
level.anim_prop_models[ model ][ "wind_b" ] = "mp_storm_fencetarp_04_windB";
}
// SP not currently supported because this requires updating "animated_props" animtree
@@ -0,0 +1,13 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level.anim_prop_models ) )
level.anim_prop_models = [];
// Uses .animation
model = "highrise_fencetarp_04b_wind_c";
level.anim_prop_models[ model ][ "wind_c" ] = "mp_storm_fencetarp_04_windC";
}
// SP not currently supported because this requires updating "animated_props" animtree
@@ -0,0 +1,13 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level.anim_prop_models ) )
level.anim_prop_models = [];
// Uses .animation
model = "highrise_fencetarp_07b_wind_a";
level.anim_prop_models[ model ][ "wind_a" ] = "mp_storm_fencetarp_07_windA";
}
// SP not currently supported because this requires updating "animated_props" animtree
@@ -0,0 +1,13 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level.anim_prop_models ) )
level.anim_prop_models = [];
// Uses .animation
model = "highrise_fencetarp_07b_wind_b";
level.anim_prop_models[ model ][ "wind_b" ] = "mp_storm_fencetarp_07_windB";
}
// SP not currently supported because this requires updating "animated_props" animtree
@@ -0,0 +1,13 @@
#include common_scripts\utility;
main()
{
if( !isdefined ( level.anim_prop_models ) )
level.anim_prop_models = [];
// Uses .animation
model = "highrise_fencetarp_07b_wind_c";
level.anim_prop_models[ model ][ "wind_c" ] = "mp_storm_fencetarp_07_windC";
}
// SP not currently supported because this requires updating "animated_props" animtree
+202
View File
@@ -0,0 +1,202 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
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;
}
+213
View File
@@ -0,0 +1,213 @@
// 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]]();
}
/*================
Called when a player drops from the server.
Will not be called between levels.
self is the player that is disconnecting.
================*/
CodeCallback_PlayerDisconnect()
{
self notify("disconnect");
[[level.callbackPlayerDisconnect]]();
}
/*================
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");
[[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()
{
}
File diff suppressed because it is too large. Load diff
+828
View File
@@ -0,0 +1,828 @@
init()
{
level.coptermodel = "vehicle_cobra_helicopter_fly";
precacheModel(level.coptermodel);
level.copter_maxaccel = 200;
level.copter_maxvel = 700;
level.copter_rotspeed = 90; // degrees per second
level.copter_accellookahead = 2; // seconds
level.copterCenterOffset = (0,0,72);
level.copterTargetOffset = (0,0,45);
level.copterexplosion = loadfx("explosions/default_explosion");
level.copterfinalexplosion = loadfx("explosions/large_vehicle_explosion");
}
getAboveBuildingsLocation(location)
{
trace = bullettrace(location + (0,0,10000), location, false, undefined);
startorigin = trace["position"] + (0,0,-514);
zpos = 0;
maxxpos = 13; maxypos = 13;
for (xpos = 0; xpos < maxxpos; xpos++) {
for (ypos = 0; ypos < maxypos; ypos++) {
thisstartorigin = startorigin + ((xpos/(maxxpos-1) - .5) * 1024, (ypos/(maxypos-1) - .5) * 1024, 0);
thisorigin = bullettrace(thisstartorigin, thisstartorigin + (0,0,-10000), false, undefined);
zpos += thisorigin["position"][2];
}
}
zpos = zpos / (maxxpos*maxypos);
zpos = zpos + 850;
return (location[0], location[1], zpos);
}
vectorAngle(v1, v2)
{
dot = vectordot(v1, v2);
if (dot >= 1)
return 0;
else if (dot <= -1)
return 180;
return acos(dot);
}
vectorTowardsOtherVector(v1, v2, angle)
{
dot = vectordot(v1, v2);
if (dot <= -1)
{
return v1; // eh
}
v3 = vectornormalize(v2 - vecscale(v1, dot));
return vecscale(v1, cos(angle)) + vecscale(v3, sin(angle));
}
veclength(v)
{
return distance((0,0,0), v);
}
createCopter(location, team, damagetrig)
{
location = getAboveBuildingsLocation(location);
scriptorigin = spawn("script_origin", location);
scriptorigin.angles = vectorToAngles((1, 0, 0));
copter = spawn("script_model", location);
copter.angles = vectorToAngles((0, 1, 0));
copter linkto(scriptorigin);
scriptorigin.copter = copter;
copter setModel(level.coptermodel);
copter playLoopSound("mp_copter_ambience");
damagetrig.origin = scriptorigin.origin;
damagetrig thread mylinkto(scriptorigin);
scriptorigin.damagetrig = damagetrig;
scriptorigin.finalDest = location;
scriptorigin.finalZDest = location[2];
scriptorigin.desiredDir = (1,0,0);
scriptorigin.desiredDirEntity = undefined;
scriptorigin.desiredDirEntityOffset = (0,0,0);
scriptorigin.vel = (0,0,0);
scriptorigin.dontascend = false;
scriptorigin.health = 2000;
if (getdvar("scr_copter_health") != "")
scriptorigin.health = getdvarfloat("scr_copter_health");
scriptorigin.team = team;
scriptorigin thread copterAI();
scriptorigin thread copterDamage(damagetrig);
return scriptorigin;
}
makeCopterPassive()
{
self.damagetrig notify("unlink");
self.damagetrig = undefined;
self notify("passive");
self.desiredDirEntity = undefined;
self.desiredDir = undefined;
}
makeCopterActive(damagetrig)
{
damagetrig.origin = self.origin;
damagetrig thread mylinkto(self);
self.damagetrig = damagetrig;
self thread copterAI();
self thread copterDamage(damagetrig);
}
mylinkto(obj)
{
self endon("unlink");
while(1)
{
self.angles = obj.angles;
self.origin = obj.origin;
wait .1;
}
}
setCopterDefenseArea(areaEnt)
{
self.areaEnt = areaEnt;
self.areaDescentPoints = [];
if (isdefined(areaEnt.target)) {
self.areaDescentPoints = getentarray(areaEnt.target, "targetname");
}
for (i = 0; i < self.areaDescentPoints.size; i++)
{
self.areaDescentPoints[i].targetEnt = getent(self.areaDescentPoints[i].target, "targetname");
}
}
copterAI()
{
self thread copterMove();
self thread copterShoot();
self endon("death");
self endon("passive");
flying = true;
descendingEnt = undefined;
reachedDescendingEnt = false;
returningToArea = false;
while(1)
{
if (!isdefined(self.areaEnt)) {
wait(1);
continue;
}
players = level.players;
enemyTargets = [];
if (self.team != "neutral") {
for (i = 0; i < players.size; i++) {
if (isalive(players[i]) && isdefined(players[i].pers["team"]) && players[i].pers["team"] != self.team && !isdefined(players[i].usingObj)) {
playerorigin = players[i].origin;
playerorigin = (playerorigin[0], playerorigin[1], self.areaEnt.origin[2]);
if (distance(playerorigin, self.areaEnt.origin) < self.areaEnt.radius)
enemyTargets[enemyTargets.size] = players[i];
}
}
}
insideTargets = [];
outsideTargets = [];
skyheight = bullettrace(self.origin, self.origin + (0,0,10000), false, undefined)["position"][2] - 10;
bestTarget = undefined;
bestWeight = 0;
for (i = 0; i < enemyTargets.size; i++) {
inside = false;
trace = bulletTrace(enemyTargets[i].origin + (0,0,10), enemyTargets[i].origin + (0,0,10000), false, undefined);
if (trace["position"][2] >= skyheight)
// outside.
outsideTargets[outsideTargets.size] = enemyTargets[i];
else
// inside.
insideTargets[insideTargets.size] = enemyTargets[i];
}
goToPos = undefined;
calcedGoToPos = false;
oldDescendingEnt = undefined;
// determine if we should change states
if (flying) {
if (outsideTargets.size == 0 && insideTargets.size > 0 && self.areaDescentPoints.size > 0) {
flying = false;
result = determineBestEnt(insideTargets, self.areaDescentPoints, self.origin);
descendingEnt = result["descendEnt"];
if (isdefined(descendingEnt))
goToPos = result["position"];
else
flying = true;
}
}
else {
oldDescendingEnt = descendingEnt;
if (insideTargets.size == 0) {
flying = true;
}
else {
// if we can't get a good target, and there are outside targets, give up and fly
if (outsideTargets.size > 0) {
if (!isdefined(descendingEnt))
flying = true;
else
{
calcedGoToPos = true;
goToPos = determineBestPos(insideTargets, descendingEnt, self.origin);
if (!isdefined(goToPos))
flying = true;
}
}
// determine where to go.
if (isdefined(descendingEnt)) {
// we're already descended. try to find a good place to shoot into the door/window from.
if (!calcedGoToPos)
goToPos = determineBestPos(insideTargets, descendingEnt, self.origin);
}
if (!isdefined(goToPos)) {
result = determineBestEnt(insideTargets, self.areaDescentPoints, self.origin);
if (isdefined(result["descendEnt"])) {
descendingEnt = result["descendEnt"];
goToPos = result["position"];
reachedDescendingEnt = false;
}
else {
if (isdefined(descendingEnt)) {
if (isdefined(self.finalDest))
goToPos = self.finalDest;
else
goToPos = descendingEnt.origin;
}
else
goToPos = undefined;
}
}
// couldn't find a place to descend?
if (!isdefined(goToPos))
flying = true;
}
}
if (flying)
{
// determine best target to shoot outside.
desireddist = 1024*2.5;
distToArea = distance((self.origin[0], self.origin[1], self.areaEnt.origin[2]), self.areaEnt.origin);
if (outsideTargets.size == 0 && distToArea > self.areaEnt.radius + desireddist*.25)
returningToArea = true;
else if (distToArea < self.areaEnt.radius*.5)
returningToArea = false;
if (outsideTargets.size == 0 && !returningToArea)
{
// no outside targets? look again for any enemies outside the radius we're defending - just so
// we don't look stupid when we could be making ourself useful.
if (self.team != "neutral") {
for (i = 0; i < players.size; i++) {
if (isalive(players[i]) && isdefined(players[i].pers["team"]) && players[i].pers["team"] != self.team && !isdefined(players[i].usingObj)) {
playerorigin = players[i].origin;
playerorigin = (playerorigin[0], playerorigin[1], self.areaEnt.origin[2]);
if (distance(players[i].origin, self.areaEnt.origin) > self.areaEnt.radius)
outsideTargets[outsideTargets.size] = players[i];
}
}
}
}
best = undefined;
bestdist = 0;
for (i = 0; i < outsideTargets.size; i++)
{
dist = abs(distance(outsideTargets[i].origin, self.origin) - desireddist);
if (!isdefined(best) || dist < bestdist) {
best = outsideTargets[i];
bestdist = dist;
}
}
if (isdefined(best)) {
// determine best position to go to to get target.
attackpos = best.origin + level.copterTargetOffset;
goToPos = determineBestAttackPos(attackpos, self.origin, desireddist);
//iprintln("going to flying attack pos");
self setCopterDest(goToPos, false);
self.desiredDir = vectornormalize(attackpos - goToPos);
self.desiredDirEntity = best;
self.desiredDirEntityOffset = level.copterTargetOffset;
wait(1);
}
else {
goToPos = getRandomPos(self.areaEnt.origin, self.areaEnt.radius);
self setCopterDest(goToPos, false);
//iprintln("going to random pos");
self.desiredDir = undefined;
self.desiredDirEntity = undefined;
wait(1);
}
}
else
{
if (distance(self.origin, descendingEnt.origin) < descendingEnt.radius)
reachedDescendingEnt = true;
//iprintln("going to descent pos");
goDirectly = (isdefined(oldDescendingEnt) && oldDescendingEnt == descendingEnt);
goDirectly = goDirectly && reachedDescendingEnt;
self.desiredDir = vectornormalize(descendingEnt.targetEnt.origin - (goToPos - level.copterCenterOffset));
self.desiredDirEntity = descendingEnt.targetEnt;
self.desiredDirEntityOffset = (0,0,0);
if (goToPos != self.origin) {
self setCopterDest(goToPos - level.copterCenterOffset, true, goDirectly);
wait(.3);
}
else
wait(.3);
}
}
}
// determines the best position to go to within descendEnt
// from where a target is visible. if no such positions,
// returns undefined.
determineBestPos(targets, descendEnt, startorigin)
{
targetpos = descendEnt.targetEnt.origin;
circleradius = distance(targetpos, descendEnt.origin);
bestpoint = undefined;
bestdist = 0;
for (i = 0; i < targets.size; i++)
{
enemypos = targets[i].origin + level.copterTargetOffset;
passed = bullettracepassed(enemypos, targetpos, false, undefined);
if (passed) {
dir = targetpos - enemypos;
dir = (dir[0], dir[1], 0);
isect = vecscale(vectornormalize(dir),circleradius) + targetpos;
isect = (isect[0], isect[1], descendEnt.origin[2]);
dist = distance(isect, descendEnt.origin);
if (dist <= descendEnt.radius) {
dist = distance(isect, startorigin);
if (!isdefined(bestpoint) || dist < bestdist) {
bestdist = dist;
bestpoint = isect;
}
}
}
}
return bestpoint;
}
// determines the best entity out of descendEnts to go to
// in order to get at one of targets.
// result["descendEnt"] is the winning entity,
// result["position"] is the position to go to.
determineBestEnt(targets, descendEnts, startorigin)
{
result = [];
bestpos = undefined;
bestent = 0;
bestdist = 0;
for (i = 0; i < descendEnts.size; i++)
{
thispos = determineBestPos(targets, descendEnts[i], startorigin);
if (isdefined(thispos)) {
thisdist = distance(thispos, startorigin);
if (!isdefined(bestpos) || thisdist < bestdist) {
bestpos = thispos;
bestent = i;
bestdist = thisdist;
}
}
}
if (isdefined(bestpos)) {
result["descendEnt"] = descendEnts[bestent];
result["position"] = bestpos;
return result;
}
result["descendEnt"] = undefined;
return result;
}
determineBestAttackPos(targetpos, curpos, desireddist)
{
targetposcopterheight = (targetpos[0], targetpos[1], curpos[2]);
attackdirx = curpos - targetposcopterheight;
attackdirx = vectornormalize(attackdirx);
attackdiry = (0-attackdirx[1], attackdirx[0], 0);
bestpos = undefined;
bestdist = 0;
for (i = 0; i < 8; i++) {
theta = (i/8.0) * 360;
thisdir = vecscale(attackdirx, cos(theta)) + vecscale(attackdiry, sin(theta));
traceend = targetposcopterheight + vecscale(thisdir, desireddist);
losexists = bullettracepassed(targetpos, traceend, false, undefined);
if (losexists) {
thisdist = distance(traceend, curpos);
if (!isdefined(bestpos) || thisdist < bestdist) {
bestpos = traceend;
bestdist = thisdist;
}
}
}
goToPos = undefined;
if (isdefined(bestpos)) {
goToPos = bestpos;
}
else {
dist = distance(targetposcopterheight, curpos);
if (dist > desireddist)
goToPos = self.origin + vecscale(vectornormalize(attackdirx), 0-(dist - desireddist));
else
goToPos = self.origin;
}
return goToPos;
}
getRandomPos(origin, radius)
{
// no sqrt so have to do this the guess and check way.
pos = origin + ((randomfloat(2)-1)*radius, (randomfloat(2)-1)*radius, 0);
while(distanceSquared(pos, origin) > radius*radius)
pos = origin + ((randomfloat(2)-1)*radius, (randomfloat(2)-1)*radius, 0);
return pos;
}
copterShoot()
{
self endon("death");
self endon("passive");
cosThreshold = cos(10);
while(1)
{
if (isdefined(self.desiredDirEntity) && isdefined(self.desiredDirEntity.origin)) {
mypos = self.origin + level.copterCenterOffset;
enemypos = self.desiredDirEntity.origin + self.desiredDirEntityOffset;
curdir = anglesToForward(self.angles);
enemydirraw = enemypos - mypos;
enemydir = vectornormalize(enemydirraw);
if (vectordot(curdir, enemydir) > cosThreshold)
{
canseetarget = bullettracepassed(mypos, enemypos, false, undefined);
if (!canseetarget && isplayer(self.desiredDirEntity) && isalive(self.desiredDirEntity))
canseetarget = bullettracepassed(mypos, self.desiredDirEntity getEye(), false, undefined);
if (canseetarget) {
// shoot.
self playSound("mp_copter_shoot");
numshots = 20;
for (i = 0; i < numshots; i++)
{
mypos = self.origin + level.copterCenterOffset;
/*if (isdefined(self.desiredDirEntity)) {
enemypos = self.desiredDirEntity.origin + self.desiredDirEntityOffset;
enemydirraw = enemypos - mypos;
enemydir = vectornormalize(enemydirraw);
dir = enemydir;
}
else*/
dir = anglesToForward(self.angles);
dir = dir + ((randomfloat(2)-1)*.015, (randomfloat(2)-1)*.015, (randomfloat(2)-1)*.015);
dir = vectornormalize(dir);
self myMagicBullet(mypos, dir);
wait(.075);
}
wait(.25);
}
//else
//iprintln("can't see");
}
//else
//iprintln("below cosThreshold: ", vectordot(curdir, enemydir), " < ", cosThreshold);
}
//else
//iprintln("no target");
wait(.25);
}
}
myMagicBullet(pos, dir)
{
damage = 20;
if (getdvar("scr_copter_damage") != "")
damage = getdvarint("scr_copter_damage");
// for now just shoot from origin
trace = bullettrace(pos, pos + vecscale(dir, 10000), true, undefined);
if (isdefined(trace["entity"]) && isplayer(trace["entity"]) && isalive(trace["entity"])) {
// hurt entity shot at
trace["entity"] thread [[level.callbackPlayerDamage]](
self, // eInflictor The entity that causes the damage.(e.g. a turret)
self, // eAttacker The entity that is attacking.
damage, // iDamage Integer specifying the amount of damage done
0, // iDFlags Integer specifying flags that are to be applied to the damage
"MOD_RIFLE_BULLET", // sMeansOfDeath Integer specifying the method of death
"copter", // sWeapon The weapon number of the weapon used to inflict the damage
self.origin, // vPoint The point the damage is from?
dir, // vDir The direction of the damage
"none", // sHitLoc The location of the hit
0 // psOffsetTime The time offset for the damage
);
}
//line(pos, trace["position"], (1,1,1));
}
setCopterDest(newlocation, descend, dontascend)
{
self.finalDest = getAboveBuildingsLocation(newlocation);
if (isdefined(descend) && descend)
self.finalZDest = newlocation[2];
else
self.finalZDest = self.finalDest[2];
self.intransit = true;
self.dontascend = false;
if (isdefined(dontascend))
self.dontascend = dontascend;
}
notifyArrived()
{
wait .05;
self notify("arrived");
}
vecscale(vec, scalar)
{
return (vec[0]*scalar, vec[1]*scalar, vec[2]*scalar);
}
abs(x)
{
if (x < 0)
return 0-x;
return x;
}
copterMove()
{
self endon("death");
if (isdefined(self.copterMoveRunning))
return;
self.copterMoveRunning = true;
self.intransit = false;
interval = .15;
zinterp = .1;
tiltamnt = 0;
while(1)
{
horizDistSquared = distanceSquared((self.origin[0], self.origin[1], 0), (self.finalDest[0], self.finalDest[1], 0));
doneMoving = horizDistSquared < 10*10;
//if (!doneMoving)
{
nearDest = (horizDistSquared < 256*256);
self.intransit = true;
desiredZ = 0;
// movement
movingHorizontally = true;
movingVertically = false;
if (self.dontascend)
movingVertically = true;
else {
// if we're not near our horizontal goal position
if (!nearDest) {
// get the z position we *want* to have before moving horizontally
desiredZ = getAboveBuildingsLocation(self.origin)[2];
movingHorizontally = (abs(self.origin[2] - desiredZ) <= 256); // we're moving horizontally if we're up high enough to do so
movingVertically = !movingHorizontally; // we're moving vertically if we aren't
}
// if we are near our horizontal goal position
else
movingVertically = true;
}
// determine our destination
if (movingHorizontally) {
if (movingVertically)
thisDest = (self.finalDest[0], self.finalDest[1], self.finalZDest);
else
thisDest = self.finalDest;
}
else {
assert(movingVertically);
thisDest = (self.origin[0], self.origin[1], desiredZ);
}
movevec = thisDest - self.origin;
idealAccel = vecscale(thisDest - (self.origin + vecscale(self.vel, level.copter_accellookahead)), interval);
vlen = veclength(idealAccel);
if (vlen > level.copter_maxaccel) {
idealAccel = vecscale(idealAccel, level.copter_maxaccel / vlen);
}
self.vel = self.vel + idealAccel;
vlen = veclength(self.vel);
if (vlen > level.copter_maxvel) {
self.vel = vecscale(self.vel, level.copter_maxvel / vlen);
}
thisDest = self.origin + vecscale(self.vel, interval);
self moveto(thisDest, interval*.999);
speed = veclength(self.vel);
if (isdefined(self.desiredDirEntity) && isdefined(self.desiredDirEntity.origin)) {
self.destDir = vectornormalize((self.desiredDirEntity.origin + self.desiredDirEntityOffset) - (self.origin + level.copterCenterOffset));
}
else if (isdefined(self.desiredDir)) {
self.destDir = self.desiredDir;
}
else if (movingVertically) {
self.destDir = anglesToForward(self.angles);
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], 0));
}
else {
tiltamnt = speed / level.copter_maxvel;
tiltamnt = (tiltamnt - .1) / .9; if (tiltamnt < 0) tiltamnt = 0;
self.destDir = movevec;
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], 0)); // remove z component
tiltamnt = tiltamnt * (1 - (vectorAngle(anglesToForward(self.angles), self.destDir) / 180));
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], tiltamnt * -.4)); // tilt forward while moving
}
}
/*else {
if (self.intransit) {
self.intransit = false;
self.dontascend = false;
// if we descended to get to this point, we'll be ascending to get out
if (self.finalZDest != self.finalDest[2])
self.ascending = true;
self notify("arrived");
}
if (isdefined(self.desiredDir))
self.destDir = self.desiredDir;
else {
self.destDir = anglesToForward(self.angles);
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], 0));
}
}*/
// rotation
newdir = self.destDir;
//line(self.origin + level.copterCenterOffset, self.origin + level.copterCenterOffset + vecscale(self.destDir,10000), (1,0,0));
if (newdir[2] < -.4) {// *never* look too far down
newdir = vectornormalize((newdir[0], newdir[1], -.4));
}
//line(self.origin + level.copterCenterOffset, self.origin + level.copterCenterOffset + vecscale(newdir,10000), (1,1,0));
copterangles = self.angles;
copterangles = combineangles(copterangles, (0,90,0));
olddir = anglesToForward(copterangles);
thisRotSpeed = level.copter_rotspeed;
//if (movelen < 256)
// thisRotSpeed = thisRotSpeed * movelen / 256;
olddir2d = vectornormalize((olddir[0], olddir[1], 0));
newdir2d = vectornormalize((newdir[0], newdir[1], 0));
angle = vectorAngle(olddir2d, newdir2d);
angle3d = vectorAngle(olddir, newdir);
if (angle > .001 && thisRotSpeed > .001) {
thisangle = thisRotSpeed * interval;
if (thisangle > angle)
thisangle = angle;
newdir2d = vectorTowardsOtherVector(olddir2d, newdir2d, thisangle);
oldz = olddir[2]/veclength((olddir[0], olddir[1], 0));
newz = newdir[2]/veclength((newdir[0], newdir[1], 0));
interpz = oldz + (newz - oldz) * (thisangle / angle);
newdir = vectornormalize((newdir2d[0], newdir2d[1], interpz));
copterangles = vectorToAngles(newdir);
copterangles = combineangles(copterangles, (0,-90,0));
self rotateto(copterangles, interval*.999);
}
else if (angle3d > .001 && thisRotSpeed > .001) {
// need to rotate vertically
thisangle = thisRotSpeed * interval;
if (thisangle > angle3d)
thisangle = angle3d;
newdir = vectorTowardsOtherVector(olddir, newdir, thisangle);
newdir = vectornormalize(newdir);
copterangles = vectorToAngles(newdir);
copterangles = combineangles(copterangles, (0,-90,0));
self rotateto(copterangles, interval*.999);
}
wait interval;
}
}
copterDamage(damagetrig)
{
self endon("passive");
while(1)
{
damagetrig waittill("damage", amount, attacker);
// disallow friendly fire
if (isdefined(attacker) && isplayer(attacker) && isdefined(attacker.pers["team"]) && attacker.pers["team"] == self.team)
continue;
self.health -= amount;
if (self.health <= 0) {
self thread copterDie();
return;
}
//iprintln("OW ", amount);
}
}
copterDie()
{
self endon("passive");
self notify("death");
self.dead = true;
self thread copterExplodeFX();
// crash.
interval = .2;
rottime = 15;
self rotateyaw(360 + randomfloat(360), rottime);
self rotatepitch(360 + randomfloat(360), rottime);
self rotateroll(360 + randomfloat(360), rottime);
while(1)
{
self.vel = self.vel + vecscale((0,0,-200), interval);
newpos = self.origin + vecscale(self.vel, interval);
// check for collision with ground
pathclear = bullettracepassed(self.origin, newpos, false, undefined);
if (!pathclear)
break;
self moveto(newpos, interval*.999);
wait (interval);
}
playfx (level.copterfinalexplosion, self.origin);
playsoundatpos( self.origin, "mp_copter_explosion" );
self notify("finaldeath");
deleteCopter();
}
deleteCopter()
{
if (isdefined(self.damagetrig)) {
self.damagetrig notify("unlink");
self.damagetrig = undefined;
}
self.copter delete();
self delete();
}
copterExplodeFX()
{
self endon("finaldeath");
while(1)
{
playfx (level.copterexplosion, self.origin);
self playsound("mp_copter_explosion");
wait .5 + randomfloat(1);
}
}
File diff suppressed because it is too large. Load diff
+93
View File
@@ -0,0 +1,93 @@
init()
{
precacheShader("damage_feedback");
precacheShader("damage_feedback_j");
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_j", 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;
}
+80
View File
@@ -0,0 +1,80 @@
#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;
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();
}
File diff suppressed because it is too large. Load diff
+120
View File
@@ -0,0 +1,120 @@
init()
{
// Draws a team icon over teammates
level.drawfriend = 0;
game["headicon_allies"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "allies" );
game["headicon_axis"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "axis" );
precacheHeadIcon( game["headicon_allies"] );
precacheHeadIcon( game["headicon_axis"] );
precacheShader( "waypoint_revive" );
level thread onPlayerConnect();
for(;;)
{
updateFriendIconSettings();
wait 5;
}
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
player thread onPlayerKilled();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
self thread showFriendIcon();
}
}
onPlayerKilled()
{
self endon("disconnect");
for(;;)
{
self waittill("killed_player");
self.headicon = "";
}
}
showFriendIcon()
{
if(level.drawfriend)
{
if(self.pers["team"] == "allies")
{
self.headicon = game["headicon_allies"];
self.headiconteam = "allies";
}
else
{
self.headicon = game["headicon_axis"];
self.headiconteam = "axis";
}
}
}
updateFriendIconSettings()
{
drawfriend = maps\mp\_utility::getIntProperty("scr_drawfriend", level.drawfriend);
if(level.drawfriend != drawfriend)
{
level.drawfriend = drawfriend;
updateFriendIcons();
}
}
updateFriendIcons()
{
// for all living players, show the appropriate headicon
players = level.players;
for(i = 0; i < players.size; i++)
{
player = players[i];
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
{
if(level.drawfriend)
{
if(player.pers["team"] == "allies")
{
player.headicon = game["headicon_allies"];
player.headiconteam = "allies";
}
else
{
player.headicon = game["headicon_axis"];
player.headiconteam = "axis";
}
}
else
{
players = level.players;
for(i = 0; i < players.size; i++)
{
player = players[i];
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
player.headicon = "";
}
}
}
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+414
View File
@@ -0,0 +1,414 @@
#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 )
{
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) );
player.score = player.pers["score"];
player maps\mp\gametypes\_persistence::statSetChild( "round", "score", player.score );
if ( !level.teambased )
thread sendUpdatedDMScores();
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;
_setTeamScore( team, _getTeamScore( team ) + score );
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 ( 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 maps\mp\gametypes\_gamelogic::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.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 ) || (player.pers["team"] != "allies" && player.pers["team"] != "axis") )
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.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"];
}
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 ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
return;
if ( self.pers["team"] == killedplayer.pers["team"] )
return;
self thread [[level.onXPEvent]]( "assist" );
self incPersStat( "assists", 1 );
self.assists = self getPersStat( "assists" );
self incPlayerStat( "assists", 1 );
givePlayerScore( "assist", 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();
}
+4
View File
@@ -0,0 +1,4 @@
/*QUAKED mp_global_intermission (1.0 0.0 1.0) (-16 -16 -16) (16 16 16)
Intermission is randomly viewed from one of these positions.
Spectators spawn randomly at one of these positions.
*/
+255
View File
@@ -0,0 +1,255 @@
#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 ( getdvarint( "scr_forcerankedmatch" ) == 1 )
{
level.onlineGame = true;
level.rankedMatch = true;
}
#/
level.script = toLower( getDvar( "mapname" ) );
level.gametype = toLower( getDvar( "g_gametype" ) );
level.otherTeam["allies"] = "axis";
level.otherTeam["axis"] = "allies";
level.teamBased = 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;
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" );
level.teamCount["allies"] = 0;
level.teamCount["axis"] = 0;
level.teamCount["spectator"] = 0;
level.aliveCount["allies"] = 0;
level.aliveCount["axis"] = 0;
level.aliveCount["spectator"] = 0;
level.livesCount["allies"] = 0;
level.livesCount["axis"] = 0;
level.oneLeftTime = [];
level.hasSpawned["allies"] = 0;
level.hasSpawned["axis"] = 0;
/#
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", "" );
makeDvarServerInfo( "camera_thirdPerson", getDvarInt( "scr_thirdPerson" ) );
}
SetupCallbacks()
{
level.onXPEvent = ::onXPEvent;
level.getSpawnPoint = ::blank;
level.onSpawnPlayer = ::blank;
level.onRespawnDelay = ::blank;
level.onTimeLimit = maps\mp\gametypes\_gamelogic::default_onTimeLimit;
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.allies = maps\mp\gametypes\_menus::menuAllies;
level.axis = maps\mp\gametypes\_menus::menuAxis;
}
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;
}
}
+221
View File
@@ -0,0 +1,221 @@
#include maps\mp\_utility;
init()
{
level.healthOverlayCutoff = 0.55;
regenTime = 5;
regenTime = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "healthregentime" );
level.playerHealth_RegularRegenDelay = regenTime * 1000;
level.healthRegenDisabled = (level.playerHealth_RegularRegenDelay <= 0);
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon("disconnect");
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 < level.playerHealth_RegularRegenDelay )
continue;
if ( level.healthRegenDisabled )
{
wait ( 3.0 );
self.maxHealth = int( max( self.health, 2 ) );
self.health = self.maxHealth;
continue;
}
if ( curTime - lastSoundTime_Recover > level.playerHealth_RegularRegenDelay )
{
lastSoundTime_Recover = curTime;
if ( !level.gameEnded )
self playLocalSound("breathing_better");
}
if ( veryHurt )
{
newHealth = ratio;
if ( curTime > hurtTime + 3000 )
newHealth += regenRate;
}
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) );
}
}
+168
View File
@@ -0,0 +1,168 @@
#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::matchStartTimer( "waiting_for_players", 20.0 );
hostMigrationWaitForPlayers();
thread maps\mp\gametypes\_gamelogic::matchStartTimer( "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;
}
+162
View File
@@ -0,0 +1,162 @@
/*
// Edge relative placement values for rect->h_align and rect->v_align
#define HORIZONTAL_ALIGN_SUBLEFT 0 // left edge of a 4:3 screen (safe area not included)
#define HORIZONTAL_ALIGN_LEFT 1 // left viewable (safe area) edge
#define HORIZONTAL_ALIGN_CENTER 2 // center of the screen (reticle)
#define HORIZONTAL_ALIGN_RIGHT 3 // right viewable (safe area) edge
#define HORIZONTAL_ALIGN_FULLSCREEN 4 // disregards safe area
#define HORIZONTAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
#define HORIZONTAL_ALIGN_TO640 6 // scales a real-screen resolution x down into the 0 - 640 range
#define HORIZONTAL_ALIGN_CENTER_SAFEAREA 7 // center of the safearea
#define HORIZONTAL_ALIGN_MAX HORIZONTAL_ALIGN_CENTER_SAFEAREA
#define HORIZONTAL_ALIGN_DEFAULT HORIZONTAL_ALIGN_SUBLEFT
#define VERTICAL_ALIGN_SUBTOP 0 // top edge of the 4:3 screen (safe area not included)
#define VERTICAL_ALIGN_TOP 1 // top viewable (safe area) edge
#define VERTICAL_ALIGN_CENTER 2 // center of the screen (reticle)
#define VERTICAL_ALIGN_BOTTOM 3 // bottom viewable (safe area) edge
#define VERTICAL_ALIGN_FULLSCREEN 4 // disregards safe area
#define VERTICAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
#define VERTICAL_ALIGN_TO480 6 // scales a real-screen resolution y down into the 0 - 480 range
#define VERTICAL_ALIGN_CENTER_SAFEAREA 7 // center of the save area
#define VERTICAL_ALIGN_MAX VERTICAL_ALIGN_CENTER_SAFEAREA
#define VERTICAL_ALIGN_DEFAULT VERTICAL_ALIGN_SUBTOP
static const char *g_he_font[] =
{
"default", // HE_FONT_DEFAULT
"bigfixed", // HE_FONT_BIGFIXED
"smallfixed", // HE_FONT_SMALLFIXED
"objective", // HE_FONT_OBJECTIVE
};
// These values correspond to the defines in q_shared.h
static const char *g_he_alignx[] =
{
"left", // HE_ALIGN_LEFT
"center", // HE_ALIGN_CENTER
"right", // HE_ALIGN_RIGHT
};
static const char *g_he_aligny[] =
{
"top", // HE_ALIGN_TOP
"middle", // HE_ALIGN_MIDDLE
"bottom", // HE_ALIGN_BOTTOM
};
// These values correspond to the defines in menudefinition.h
static const char *g_he_horzalign[] =
{
"subleft", // HORIZONTAL_ALIGN_SUBLEFT
"left", // HORIZONTAL_ALIGN_LEFT
"center", // HORIZONTAL_ALIGN_CENTER
"right", // HORIZONTAL_ALIGN_RIGHT
"fullscreen", // HORIZONTAL_ALIGN_FULLSCREEN
"noscale", // HORIZONTAL_ALIGN_NOSCALE
"alignto640", // HORIZONTAL_ALIGN_TO640
"center_safearea", // HORIZONTAL_ALIGN_CENTER_SAFEAREA
};
cassert( ARRAY_COUNT( g_he_horzalign ) == HORIZONTAL_ALIGN_MAX + 1 );
static const char *g_he_vertalign[] =
{
"subtop", // VERTICAL_ALIGN_SUBTOP
"top", // VERTICAL_ALIGN_TOP
"middle", // VERTICAL_ALIGN_CENTER
"bottom", // VERTICAL_ALIGN_BOTTOM
"fullscreen", // VERTICAL_ALIGN_FULLSCREEN
"noscale", // VERTICAL_ALIGN_NOSCALE
"alignto480", // VERTICAL_ALIGN_TO480
"center_safearea", // VERTICAL_ALIGN_CENTER_SAFEAREA
};
cassert( ARRAY_COUNT( g_he_vertalign ) == VERTICAL_ALIGN_MAX + 1 );
*/
init()
{
precacheShader( "progress_bar_bg" );
precacheShader( "progress_bar_fg" );
precacheShader( "progress_bar_fill" );
level.uiParent = spawnstruct();
level.uiParent.horzAlign = "left";
level.uiParent.vertAlign = "top";
level.uiParent.alignX = "left";
level.uiParent.alignY = "top";
level.uiParent.x = 0;
level.uiParent.y = 0;
level.uiParent.width = 0;
level.uiParent.height = 0;
level.uiParent.children = [];
level.fontHeight = 12;
level.hud["allies"] = spawnstruct();
level.hud["axis"] = spawnstruct();
// we can, of course, separate out the following constants for splitscreen.
// primary progress bars are for things like capturing flags or planting bombs - big, important things that happen as you play a gametype
level.primaryProgressBarY = -61; // from center
level.primaryProgressBarX = 0;
level.primaryProgressBarHeight = 9; //28; // this is the height and width of the whole progress bar, including the outline. the part that actually moves is 2 pixels smaller.
level.primaryProgressBarWidth = 120;
level.primaryProgressBarTextY = -75;
level.primaryProgressBarTextX = 0;
level.primaryProgressBarFontSize = .6; // 1.4 before font change from "objective"
level.teamProgressBarY = 32; // 205;
level.teamProgressBarHeight = 14;
level.teamProgressBarWidth = 192;
level.teamProgressBarTextY = 8; // 155;
level.teamProgressBarFontSize = 1.65;
if ( level.splitscreen )
{
level.lowerTextYAlign = "BOTTOM";
level.lowerTextY = -76;
level.lowerTextFontSize = 1.14;
}
else
{
level.lowerTextYAlign = "CENTER";
level.lowerTextY = 70;
level.lowerTextFontSize = 1.6;
}
}
fontPulseInit( maxFontScale )
{
self.baseFontScale = self.fontScale;
if ( isDefined( maxFontScale ) )
self.maxFontScale = min( maxFontScale, 6.3 );
else
self.maxFontScale = min( self.fontScale * 2, 6.3 );
self.inFrames = 2;
self.outFrames = 4;
}
fontPulse(player)
{
self notify ( "fontPulse" );
self endon ( "fontPulse" );
self endon( "death" );
player endon("disconnect");
player endon("joined_team");
player endon("joined_spectators");
self ChangeFontScaleOverTime( self.inFrames * 0.05 );
self.fontScale = self.maxFontScale;
wait self.inFrames * 0.05;
self ChangeFontScaleOverTime( self.outFrames * 0.05 );
self.fontScale = self.baseFontScale;
}
File diff suppressed because it is too large. Load diff
+793
View File
@@ -0,0 +1,793 @@
#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;
}
+594
View File
@@ -0,0 +1,594 @@
#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 );
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 ( 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 ( !level.splitscreen )
{
self.kc_timer.alpha = 1;
self.kc_timer setTenthsTimer(camtime);
}
if ( timeUntilRespawn && !level.gameEnded )
{
if ( timeUntilRespawn > 0 )
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;
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 useButtonPressed())
wait .05;
while(!(self useButtonPressed()))
wait .05;
if ( !matchMakingGame() )
self incPlayerStat( "killcamskipped", 1 );
if ( timeUntilRespawn <= 0 )
clearLowerMessage( "kc_info" );
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();
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;
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()
{
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;
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 = 18;
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 = 62;
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;
}
}
}
+555
View File
@@ -0,0 +1,555 @@
#include maps\mp\_utility;
init()
{
if ( !isDefined( game["gamestarted"] ) )
{
game["menu_team"] = "team_marinesopfor";
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_controls"] = "ingame_controls";
if ( !level.console )
{
game["menu_muteplayer"] = "muteplayer";
precacheMenu(game["menu_muteplayer"]);
}
else
{
//game["menu_options"] = "ingame_options";
game["menu_leavegame"] = "popup_leavegame";
if(level.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"]);
precacheString( &"MP_HOST_ENDED_GAME" );
precacheString( &"MP_HOST_ENDGAME_RESPONSE" );
}
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onMenuResponse();
}
}
isOptionsMenu( menu )
{
if ( menu == game["menu_changeclass"] )
return true;
if ( menu == game["menu_team"] )
return true;
if ( menu == game["menu_controls"] )
return true;
if ( isSubStr( menu, "pc_options" ) )
return true;
return false;
}
onMenuResponse()
{
self endon("disconnect");
for(;;)
{
self waittill("menuresponse", menu, response);
if ( response == "back" )
{
self closepopupMenu();
self closeInGameMenu();
if ( isOptionsMenu( menu ) )
{
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 "allies":
self [[level.allies]]();
break;
case "axis":
self [[level.axis]]();
break;
case "autoassign":
self [[level.autoassign]]();
break;
case "spectator":
self [[level.spectator]]();
break;
}
} // 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);
}
}
}
getTeamAssignment()
{
teams[0] = "allies";
teams[1] = "axis";
if ( !level.teamBased )
return teams[randomInt(2)];
if ( self.sessionteam != "none" && self.sessionteam != "spectator" && self.sessionstate != "playing" && self.sessionstate != "dead" )
{
assignment = self.sessionteam;
}
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 )
{
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 ] );
}
menuAllies()
{
self closeMenus();
if(self.pers["team"] != "allies")
{
if( level.teamBased && !maps\mp\gametypes\_teams::getJoinTeamPermissions( "allies" ) )
{
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 = "allies";
self.leaving_team = self.pers["team"];
self suicide();
}
self addToTeam( "allies" );
self.pers["class"] = undefined;
self.class = undefined;
self notify("end_respawn");
}
self beginClassChoice();
}
menuAxis()
{
self closeMenus();
if(self.pers["team"] != "axis")
{
if( level.teamBased && !maps\mp\gametypes\_teams::getJoinTeamPermissions( "axis" ) )
{
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 = "axis";
self.leaving_team = self.pers["team"];
self suicide();
}
self addToTeam( "axis" );
self.pers["class"] = undefined;
self.class = undefined;
self notify("end_respawn");
}
self beginClassChoice();
}
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(!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?
{
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
{
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" );
}
}
File diff suppressed because it is too large. Load diff
+483
View File
@@ -0,0 +1,483 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
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]) )
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 );
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"] );
}
+160
View File
@@ -0,0 +1,160 @@
#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 )
{
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;
}
+234
View File
@@ -0,0 +1,234 @@
#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
View File
@@ -0,0 +1,29 @@
#include common_scripts\utility;
#include maps\mp\_utility;
init()
{
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
//@NOTE: Should we make sure they're really unlocked before setting them? Catch cheaters...
// e.g. isItemUnlocked( iconHandle )
iconHandle = player maps\mp\gametypes\_persistence::statGet( "cardIcon" );
player SetCardIcon( iconHandle );
titleHandle = player maps\mp\gametypes\_persistence::statGet( "cardTitle" );
player SetCardTitle( titleHandle );
nameplateHandle = player maps\mp\gametypes\_persistence::statGet( "cardNameplate" );
player SetCardNameplate( nameplateHandle );
}
}
File diff suppressed because it is too large. Load diff
+270
View File
@@ -0,0 +1,270 @@
init()
{
game["menu_quickcommands"] = "quickcommands";
game["menu_quickstatements"] = "quickstatements";
game["menu_quickresponses"] = "quickresponses";
precacheMenu(game["menu_quickcommands"]);
precacheMenu(game["menu_quickstatements"]);
precacheMenu(game["menu_quickresponses"]);
precacheHeadIcon("talkingicon");
precacheString( &"QUICKMESSAGE_FOLLOW_ME" );
precacheString( &"QUICKMESSAGE_MOVE_IN" );
precacheString( &"QUICKMESSAGE_FALL_BACK" );
precacheString( &"QUICKMESSAGE_SUPPRESSING_FIRE" );
precacheString( &"QUICKMESSAGE_ATTACK_LEFT_FLANK" );
precacheString( &"QUICKMESSAGE_ATTACK_RIGHT_FLANK" );
precacheString( &"QUICKMESSAGE_HOLD_THIS_POSITION" );
precacheString( &"QUICKMESSAGE_REGROUP" );
precacheString( &"QUICKMESSAGE_ENEMY_SPOTTED" );
precacheString( &"QUICKMESSAGE_ENEMIES_SPOTTED" );
precacheString( &"QUICKMESSAGE_IM_IN_POSITION" );
precacheString( &"QUICKMESSAGE_AREA_SECURE" );
precacheString( &"QUICKMESSAGE_GRENADE" );
precacheString( &"QUICKMESSAGE_SNIPER" );
precacheString( &"QUICKMESSAGE_NEED_REINFORCEMENTS" );
precacheString( &"QUICKMESSAGE_HOLD_YOUR_FIRE" );
precacheString( &"QUICKMESSAGE_YES_SIR" );
precacheString( &"QUICKMESSAGE_NO_SIR" );
precacheString( &"QUICKMESSAGE_IM_ON_MY_WAY" );
precacheString( &"QUICKMESSAGE_SORRY" );
precacheString( &"QUICKMESSAGE_GREAT_SHOT" );
precacheString( &"QUICKMESSAGE_TOOK_LONG_ENOUGH" );
precacheString( &"QUICKMESSAGE_ARE_YOU_CRAZY" );
precacheString( &"QUICKMESSAGE_WATCH_SIX" );
precacheString( &"QUICKMESSAGE_COME_ON" );
}
quickcommands(response)
{
self endon ( "disconnect" );
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_cmd_followme";
saytext = &"QUICKMESSAGE_FOLLOW_ME";
//saytext = "Follow Me!";
break;
case "2":
soundalias = "mp_cmd_movein";
saytext = &"QUICKMESSAGE_MOVE_IN";
//saytext = "Move in!";
break;
case "3":
soundalias = "mp_cmd_fallback";
saytext = &"QUICKMESSAGE_FALL_BACK";
//saytext = "Fall back!";
break;
case "4":
soundalias = "mp_cmd_suppressfire";
saytext = &"QUICKMESSAGE_SUPPRESSING_FIRE";
//saytext = "Suppressing fire!";
break;
case "5":
soundalias = "mp_cmd_attackleftflank";
saytext = &"QUICKMESSAGE_ATTACK_LEFT_FLANK";
//saytext = "Attack left flank!";
break;
case "6":
soundalias = "mp_cmd_attackrightflank";
saytext = &"QUICKMESSAGE_ATTACK_RIGHT_FLANK";
//saytext = "Attack right flank!";
break;
case "7":
soundalias = "mp_cmd_holdposition";
saytext = &"QUICKMESSAGE_HOLD_THIS_POSITION";
//saytext = "Hold this position!";
break;
default:
assert(response == "8");
soundalias = "mp_cmd_regroup";
saytext = &"QUICKMESSAGE_REGROUP";
//saytext = "Regroup!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
quickstatements(response)
{
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_stm_enemyspotted";
saytext = &"QUICKMESSAGE_ENEMY_SPOTTED";
//saytext = "Enemy spotted!";
break;
case "2":
soundalias = "mp_stm_enemiesspotted";
saytext = &"QUICKMESSAGE_ENEMIES_SPOTTED";
//saytext = "Enemy down!";
break;
case "3":
soundalias = "mp_stm_iminposition";
saytext = &"QUICKMESSAGE_IM_IN_POSITION";
//saytext = "I'm in position.";
break;
case "4":
soundalias = "mp_stm_areasecure";
saytext = &"QUICKMESSAGE_AREA_SECURE";
//saytext = "Area secure!";
break;
case "5":
soundalias = "mp_stm_watchsix";
saytext = &"QUICKMESSAGE_WATCH_SIX";
//saytext = "Grenade!";
break;
case "6":
soundalias = "mp_stm_sniper";
saytext = &"QUICKMESSAGE_SNIPER";
//saytext = "Sniper!";
break;
default:
assert(response == "7");
soundalias = "mp_stm_needreinforcements";
saytext = &"QUICKMESSAGE_NEED_REINFORCEMENTS";
//saytext = "Need reinforcements!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
quickresponses(response)
{
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_rsp_yessir";
saytext = &"QUICKMESSAGE_YES_SIR";
//saytext = "Yes Sir!";
break;
case "2":
soundalias = "mp_rsp_nosir";
saytext = &"QUICKMESSAGE_NO_SIR";
//saytext = "No Sir!";
break;
case "3":
soundalias = "mp_rsp_onmyway";
saytext = &"QUICKMESSAGE_IM_ON_MY_WAY";
//saytext = "On my way.";
break;
case "4":
soundalias = "mp_rsp_sorry";
saytext = &"QUICKMESSAGE_SORRY";
//saytext = "Sorry.";
break;
case "5":
soundalias = "mp_rsp_greatshot";
saytext = &"QUICKMESSAGE_GREAT_SHOT";
//saytext = "Great shot!";
break;
default:
assert(response == "6");
soundalias = "mp_rsp_comeon";
saytext = &"QUICKMESSAGE_COME_ON";
//saytext = "Took long enough!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
doQuickMessage( soundalias, saytext )
{
if(self.sessionstate != "playing")
return;
prefix = maps\mp\gametypes\_teams::getTeamVoicePrefix( self.team );
if(isdefined(level.QuickMessageToAll) && level.QuickMessageToAll)
{
self.headiconteam = "none";
self.headicon = "talkingicon";
self playSound( prefix+soundalias );
self sayAll(saytext);
}
else
{
if(self.sessionteam == "allies")
self.headiconteam = "allies";
else if(self.sessionteam == "axis")
self.headiconteam = "axis";
self.headicon = "talkingicon";
self playSound( prefix+soundalias );
self sayTeam( saytext );
self pingPlayer();
}
}
saveHeadIcon()
{
if(isdefined(self.headicon))
self.oldheadicon = self.headicon;
if(isdefined(self.headiconteam))
self.oldheadiconteam = self.headiconteam;
}
restoreHeadIcon()
{
if(isdefined(self.oldheadicon))
self.headicon = self.oldheadicon;
if(isdefined(self.oldheadiconteam))
self.headiconteam = self.oldheadiconteam;
}
+686
View File
@@ -0,0 +1,686 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
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", 20 );
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 )
{
overrideDvar = "scr_" + level.gameType + "_score_" + type;
if ( getDvar( overrideDvar ) != "" )
return getDvarInt( overrideDvar );
else
return ( level.scoreInfo[type]["value"] );
}
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;
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_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.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":
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 );
}
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"];
}
incRankXP( amount )
{
if ( !self rankingEnabled() )
return;
if ( isDefined( self.isCheater ) )
return;
xp = self getRankXP();
newXp = (xp + 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 );
}
+103
View File
@@ -0,0 +1,103 @@
init()
{
level.hostname = getdvar("sv_hostname");
if(level.hostname == "")
level.hostname = "CoDHost";
setdvar("sv_hostname", level.hostname);
level.allowvote = getdvarint("g_allowvote", 1);
SetDvar("g_allowvote", level.allowvote);
makedvarserverinfo("ui_allowvote", level.allowvote);
level.friendlyfire = maps\mp\gametypes\_tweakables::getTweakableValue( "team", "fftype" );
makedvarserverinfo("ui_friendlyfire", level.friendlyfire);
constrainGameType(getdvar("g_gametype"));
for(;;)
{
updateServerSettings();
wait 5;
}
}
updateServerSettings()
{
sv_hostname = getdvar("sv_hostname");
if(level.hostname != sv_hostname)
{
level.hostname = sv_hostname;
}
g_allowvote = getdvarint("g_allowvote", 1);
if(level.allowvote != g_allowvote)
{
level.allowvote = g_allowvote;
setdvar("ui_allowvote", level.allowvote);
}
scr_friendlyfire = maps\mp\gametypes\_tweakables::getTweakableValue( "team", "fftype" );
if(level.friendlyfire != scr_friendlyfire)
{
level.friendlyfire = scr_friendlyfire;
setdvar("ui_friendlyfire", level.friendlyfire);
}
}
constrainGameType(gametype)
{
entities = getentarray();
for(i = 0; i < entities.size; i++)
{
entity = entities[i];
if(gametype == "dm")
{
if(isdefined(entity.script_gametype_dm) && entity.script_gametype_dm != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "tdm")
{
if(isdefined(entity.script_gametype_tdm) && entity.script_gametype_tdm != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "ctf")
{
if(isdefined(entity.script_gametype_ctf) && entity.script_gametype_ctf != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "hq")
{
if(isdefined(entity.script_gametype_hq) && entity.script_gametype_hq != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "sd")
{
if(isdefined(entity.script_gametype_sd) && entity.script_gametype_sd != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "koth")
{
if(isdefined(entity.script_gametype_koth) && entity.script_gametype_koth != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
}
}
+133
View File
@@ -0,0 +1,133 @@
#include maps\mp\_utility;
#include common_scripts\utility;
init()
{
precacheShellShock( "frag_grenade_mp" );
precacheShellShock( "damage_mp" );
precacheRumble( "artillery_rumble" );
precacheRumble( "grenade_rumble" );
precacheMenu( "dirt_effect_center" );
precacheMenu( "dirt_effect_left" );
precacheMenu( "dirt_effect_right" );
}
shellshockOnDamage( cause, damage )
{
if ( self maps\mp\_flashgrenades::isFlashbanged() )
return; // don't interrupt flashbang shellshock
if ( self _hasPerk( "specialty_blastshield" ) )
return;
if ( cause == "MOD_EXPLOSIVE" ||
cause == "MOD_GRENADE" ||
cause == "MOD_GRENADE_SPLASH" ||
cause == "MOD_PROJECTILE" ||
cause == "MOD_PROJECTILE_SPLASH" )
{
time = 0;
if(damage >= 90)
time = 4;
else if(damage >= 50)
time = 3;
else if(damage >= 25)
time = 2;
else if(damage > 10)
time = 2;
if ( time )
{
self shellshock("frag_grenade_mp", 0.5);
}
}
}
endOnDeath()
{
self waittill( "death" );
waittillframeend;
self notify ( "end_explode" );
}
grenade_earthQuake()
{
self thread endOnDeath();
self endon( "end_explode" );
self waittill( "explode", position );
PlayRumbleOnPosition( "grenade_rumble", position );
earthquake( 0.5, 0.75, position, 800 );
foreach ( player in level.players )
{
if ( player isUsingRemote() )
continue;
if ( distance( position, player.origin ) > 600 )
continue;
if ( player DamageConeTrace( position ) )
player thread dirtEffect( position );
}
}
dirtEffect( position )
{
self endon ( "disconnect" );
forwardVec = vectorNormalize( anglesToForward( self.angles ) );
rightVec = vectorNormalize( anglesToRight( self.angles ) );
grenadeVec = vectorNormalize( position - self.origin );
fDot = vectorDot( grenadeVec, forwardVec );
rDot = vectorDot( grenadeVec, rightVec );
printLn( fDot );
printLn( rDot );
effectMenus = [];
if ( fDot > 0 && fDot > 0.5 && self getCurrentWeapon() != "riotshield_mp" )
effectMenus[effectMenus.size] = "dirt_effect_center";
if ( abs(fDot) < 0.866 )
{
if ( rDot > 0 )
effectMenus[effectMenus.size] = "dirt_effect_right";
else
effectMenus[effectMenus.size] = "dirt_effect_left";
}
foreach ( menu in effectMenus )
self openMenu( menu );
if ( isAlive( self ) )
self waittill_notify_or_timeout( "death", 2.0 );
foreach ( menu in effectMenus )
self closeMenu( menu );
}
c4_earthQuake()
{
self thread endOnDeath();
self endon( "end_explode" );
self waittill( "explode", position );
PlayRumbleOnPosition( "grenade_rumble", position );
earthquake( 0.4, 0.75, position, 512 );
}
barrel_earthQuake()
{
PlayRumbleOnPosition( "grenade_rumble", self.origin );
earthquake( 0.4, 0.5, self.origin, 512 );
}
artillery_earthQuake()
{
PlayRumbleOnPosition( "artillery_rumble", self.origin );
earthquake( 0.7, 0.5, self.origin, 800 );
}
File diff suppressed because it is too large. Load diff
+149
View File
@@ -0,0 +1,149 @@
init()
{
level.spectateOverride["allies"] = spawnstruct();
level.spectateOverride["axis"] = spawnstruct();
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread onJoinedTeam();
player thread onJoinedSpectators();
player thread onSpectatingClient();
}
}
onJoinedTeam()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_team" );
self setSpectatePermissions();
}
}
onJoinedSpectators()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_spectators" );
self setSpectatePermissions();
}
}
onSpectatingClient()
{
self endon("disconnect");
for( ;; )
{
self waittill( "spectating_cycle" );
// show the card for the player we're viewing. Could be undefined if the cyling failed
spectatedPlayer = self GetSpectatingPlayer();
if ( isDefined( spectatedPlayer ) )
{
self SetCardDisplaySlot( spectatedPlayer, 6 );
}
}
}
updateSpectateSettings()
{
level endon ( "game_ended" );
for ( index = 0; index < level.players.size; index++ )
level.players[index] setSpectatePermissions();
}
getOtherTeam( team )
{
if ( team == "axis" )
return "allies";
else if ( team == "allies" )
return "axis";
else
return "none";
}
setSpectatePermissions()
{
team = self.sessionteam;
if ( level.gameEnded && gettime() - level.gameEndTime >= 2000 )
{
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", true );
return;
}
spectateType = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "spectatetype" );
switch( spectateType )
{
case 0: // disabled
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
break;
case 1: // team/player only
if ( !level.teamBased )
{
self allowSpectateTeam( "allies", true );
self allowSpectateTeam( "axis", true );
self allowSpectateTeam( "none", true );
self allowSpectateTeam( "freelook", false );
}
else if ( isDefined( team ) && (team == "allies" || team == "axis") )
{
self allowSpectateTeam( team, true );
self allowSpectateTeam( getOtherTeam( team ), false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
}
else
{
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
}
break;
case 2: // free
self allowSpectateTeam( "allies", true );
self allowSpectateTeam( "axis", true );
self allowSpectateTeam( "freelook", true );
self allowSpectateTeam( "none", true );
break;
}
if ( isDefined( team ) && (team == "axis" || team == "allies") )
{
if ( isdefined(level.spectateOverride[team].allowFreeSpectate) )
self allowSpectateTeam( "freelook", true );
if (isdefined(level.spectateOverride[team].allowEnemySpectate))
self allowSpectateTeam( getOtherTeam( team ), true );
}
}
+892
View File
@@ -0,0 +1,892 @@
#include maps\mp\_utility;
FACTION_REF_COL = 0;
FACTION_NAME_COL = 1;
FACTION_SHORT_NAME_COL = 2;
FACTION_ELIMINATED_COL = 3;
FACTION_FORFEITED_COL = 4;
FACTION_ICON_COL = 5;
FACTION_HUD_ICON_COL = 6;
FACTION_VOICE_PREFIX_COL = 7;
FACTION_SPAWN_MUSIC_COL = 8;
FACTION_WIN_MUSIC_COL = 9;
FACTION_FLAG_MODEL_COL = 10;
FACTION_FLAG_CARRY_MODEL_COL = 11;
FACTION_FLAG_ICON_COL = 12;
FACTION_FLAG_FX_COL = 13;
FACTION_COLOR_R_COL = 14;
FACTION_COLOR_G_COL = 15;
FACTION_COLOR_B_COL = 16;
FACTION_HEAD_ICON_COL = 17;
FACTION_CRATE_MODEL_COL = 18;
init()
{
initScoreBoard();
level.teamBalance = getDvarInt("scr_teambalance");
level.maxClients = getDvarInt( "sv_maxclients" );
level._effect["thermal_beacon"] = loadFx("misc/thermal_beacon_inverted");
effect = level._effect["thermal_beacon"];
PrecacheFxTeamThermal( effect, "J_Spine4" );
setPlayerModels();
level.freeplayers = [];
if( level.teamBased )
{
level thread onPlayerConnect();
level thread updateTeamBalance();
wait .15;
level thread updatePlayerTimes();
}
else
{
level thread onFreePlayerConnect();
wait .15;
level thread updateFreePlayerTimes();
}
}
initScoreBoard()
{
setDvar("g_TeamName_Allies", getTeamShortName( "allies" ));
setDvar("g_TeamIcon_Allies", getTeamIcon( "allies" ));
setDvar("g_TeamIcon_MyAllies", getTeamIcon( "allies" ));
setDvar("g_TeamIcon_EnemyAllies", getTeamIcon( "allies" ));
scoreColor = getTeamColor( "allies" );
setDvar("g_ScoresColor_Allies", scoreColor[0] + " " + scoreColor[1] + " " + scoreColor[2] );
setDvar("g_TeamName_Axis", getTeamShortName( "axis" ));
setDvar("g_TeamIcon_Axis", getTeamIcon( "axis" ));
setDvar("g_TeamIcon_MyAxis", getTeamIcon( "axis" ));
setDvar("g_TeamIcon_EnemyAxis", getTeamIcon( "axis" ));
scoreColor = getTeamColor( "axis" );
setDvar("g_ScoresColor_Axis", scoreColor[0] + " " + scoreColor[1] + " " + scoreColor[2] );
setdvar("g_ScoresColor_Spectator", ".25 .25 .25");
setdvar("g_ScoresColor_Free", ".76 .78 .10");
setdvar("g_teamColor_MyTeam", ".6 .8 .6" );
setdvar("g_teamColor_EnemyTeam", "1 .45 .5" );
setdvar("g_teamTitleColor_MyTeam", ".6 .8 .6" );
setdvar("g_teamTitleColor_EnemyTeam", "1 .45 .5" );
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread onJoinedTeam();
player thread onJoinedSpectators();
player thread onPlayerSpawned();
player thread trackPlayedTime();
}
}
onFreePlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread trackFreePlayedTime();
}
}
onJoinedTeam()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_team" );
//self logString( "joined team: " + self.pers["team"] );
self updateTeamTime();
}
}
onJoinedSpectators()
{
self endon("disconnect");
for(;;)
{
self waittill("joined_spectators");
self.pers["teamTime"] = undefined;
}
}
trackPlayedTime()
{
self endon( "disconnect" );
self.timePlayed["allies"] = 0;
self.timePlayed["axis"] = 0;
self.timePlayed["free"] = 0;
self.timePlayed["other"] = 0;
self.timePlayed["total"] = 0;
gameFlagWait( "prematch_done" );
for ( ;; )
{
if ( game["state"] == "playing" )
{
if ( self.sessionteam == "allies" )
{
self.timePlayed["allies"]++;
self.timePlayed["total"]++;
}
else if ( self.sessionteam == "axis" )
{
self.timePlayed["axis"]++;
self.timePlayed["total"]++;
}
else if ( self.sessionteam == "spectator" )
{
self.timePlayed["other"]++;
}
}
wait ( 1.0 );
}
}
updatePlayerTimes()
{
if ( !level.rankedmatch )
return;
level endon( "game_ended" );
for ( ;; )
{
foreach ( player in level.players )
player updatePlayedTime();
wait( 1.0 );
}
}
updatePlayedTime()
{
if ( !self rankingEnabled() )
return;
if ( self.timePlayed["allies"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedAllies", self.timePlayed["allies"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["allies"] );
self maps\mp\gametypes\_persistence::statAddChildBuffered( "round", "timePlayed", self.timePlayed["allies"] );
}
if ( self.timePlayed["axis"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOpfor", self.timePlayed["axis"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["axis"] );
self maps\mp\gametypes\_persistence::statAddChildBuffered( "round", "timePlayed", self.timePlayed["axis"] );
}
if ( self.timePlayed["other"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOther", self.timePlayed["other"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["other"] );
self maps\mp\gametypes\_persistence::statAddChildBuffered( "round", "timePlayed", self.timePlayed["other"] );
}
if ( game["state"] == "postgame" )
return;
self.timePlayed["allies"] = 0;
self.timePlayed["axis"] = 0;
self.timePlayed["other"] = 0;
}
updateTeamTime()
{
if ( game["state"] != "playing" )
return;
self.pers["teamTime"] = getTime();
}
updateTeamBalanceDvar()
{
for(;;)
{
teambalance = getdvarInt("scr_teambalance");
if(level.teambalance != teambalance)
level.teambalance = getdvarInt("scr_teambalance");
wait 1;
}
}
updateTeamBalance()
{
level.teamLimit = level.maxclients / 2;
level thread updateTeamBalanceDvar();
wait .15;
if ( level.teamBalance && isRoundBased() )
{
if( isDefined( game["BalanceTeamsNextRound"] ) )
iPrintLnbold( &"MP_AUTOBALANCE_NEXT_ROUND" );
// TODO: add or change
level waittill( "restarting" );
if( isDefined( game["BalanceTeamsNextRound"] ) )
{
level balanceTeams();
game["BalanceTeamsNextRound"] = undefined;
}
else if( !getTeamBalance() )
{
game["BalanceTeamsNextRound"] = true;
}
}
else
{
level endon ( "game_ended" );
for( ;; )
{
if( level.teamBalance )
{
if( !getTeamBalance() )
{
iPrintLnBold( &"MP_AUTOBALANCE_SECONDS", 15 );
wait 15.0;
if( !getTeamBalance() )
level balanceTeams();
}
wait 59.0;
}
wait 1.0;
}
}
}
getTeamBalance()
{
level.team["allies"] = 0;
level.team["axis"] = 0;
players = level.players;
for(i = 0; i < players.size; i++)
{
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
level.team["allies"]++;
else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
level.team["axis"]++;
}
if((level.team["allies"] > (level.team["axis"] + level.teamBalance)) || (level.team["axis"] > (level.team["allies"] + level.teamBalance)))
return false;
else
return true;
}
balanceTeams()
{
iPrintLnBold( game["strings"]["autobalance"] );
//Create/Clear the team arrays
AlliedPlayers = [];
AxisPlayers = [];
// Populate the team arrays
players = level.players;
for(i = 0; i < players.size; i++)
{
if(!isdefined(players[i].pers["teamTime"]))
continue;
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
AlliedPlayers[AlliedPlayers.size] = players[i];
else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
AxisPlayers[AxisPlayers.size] = players[i];
}
MostRecent = undefined;
while((AlliedPlayers.size > (AxisPlayers.size + 1)) || (AxisPlayers.size > (AlliedPlayers.size + 1)))
{
if(AlliedPlayers.size > (AxisPlayers.size + 1))
{
// Move the player that's been on the team the shortest ammount of time (highest teamTime value)
for(j = 0; j < AlliedPlayers.size; j++)
{
if(isdefined(AlliedPlayers[j].dont_auto_balance))
continue;
if(!isdefined(MostRecent))
MostRecent = AlliedPlayers[j];
else if(AlliedPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"])
MostRecent = AlliedPlayers[j];
}
MostRecent [[level.axis]]();
}
else if(AxisPlayers.size > (AlliedPlayers.size + 1))
{
// Move the player that's been on the team the shortest ammount of time (highest teamTime value)
for(j = 0; j < AxisPlayers.size; j++)
{
if(isdefined(AxisPlayers[j].dont_auto_balance))
continue;
if(!isdefined(MostRecent))
MostRecent = AxisPlayers[j];
else if(AxisPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"])
MostRecent = AxisPlayers[j];
}
MostRecent [[level.allies]]();
}
MostRecent = undefined;
AlliedPlayers = [];
AxisPlayers = [];
players = level.players;
for(i = 0; i < players.size; i++)
{
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
AlliedPlayers[AlliedPlayers.size] = players[i];
else if((isdefined(players[i].pers["team"])) &&(players[i].pers["team"] == "axis"))
AxisPlayers[AxisPlayers.size] = players[i];
}
}
}
setGhillieModels( env )
{
level.environment = env;
switch ( env )
{
case "desert":
mptype\mptype_ally_ghillie_desert::precache();
mptype\mptype_opforce_ghillie_desert::precache();
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_desert::main;
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_desert::main;
break;
case "arctic":
mptype\mptype_ally_ghillie_arctic::precache();
mptype\mptype_opforce_ghillie_arctic::precache();
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_arctic::main;
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_arctic::main;
break;
case "urban":
mptype\mptype_ally_ghillie_urban::precache();
mptype\mptype_opforce_ghillie_urban::precache();
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_urban::main;
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_urban::main;
break;
case "forest":
mptype\mptype_ally_ghillie_forest::precache();
mptype\mptype_opforce_ghillie_forest::precache();
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_forest::main;
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_forest::main;
break;
default:
break;
}
}
setTeamModels( team, charSet )
{
switch ( charSet )
{
case "seals_udt":
mptype\mptype_seal_udt_sniper::precache();
mptype\mptype_seal_udt_lmg::precache();
mptype\mptype_seal_udt_assault::precache();
mptype\mptype_seal_udt_shotgun::precache();
mptype\mptype_seal_udt_smg::precache();
mptype\mptype_seal_udt_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_seal_udt_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_seal_udt_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_seal_udt_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_seal_udt_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_seal_udt_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_seal_udt_riot::main;
break;
case "us_army":
mptype\mptype_us_army_sniper::precache();
mptype\mptype_us_army_lmg::precache();
mptype\mptype_us_army_assault::precache();
mptype\mptype_us_army_shotgun::precache();
mptype\mptype_us_army_smg::precache();
mptype\mptype_us_army_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_us_army_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_us_army_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_us_army_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_us_army_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_us_army_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_us_army_riot::main;
break;
case "opforce_composite":
mptype\mptype_opforce_comp_assault::precache();
mptype\mptype_opforce_comp_lmg::precache();
mptype\mptype_opforce_comp_shotgun::precache();
mptype\mptype_opforce_comp_smg::precache();
mptype\mptype_opforce_comp_sniper::precache();
mptype\mptype_opforce_comp_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_comp_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_opforce_comp_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_comp_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_comp_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_opforce_comp_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_comp_riot::main;
break;
case "opforce_arctic":
mptype\mptype_opforce_arctic_assault::precache();
mptype\mptype_opforce_arctic_lmg::precache();
mptype\mptype_opforce_arctic_shotgun::precache();
mptype\mptype_opforce_arctic_smg::precache();
mptype\mptype_opforce_arctic_sniper::precache();
mptype\mptype_opforce_arctic_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_arctic_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_opforce_arctic_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_arctic_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_arctic_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_opforce_arctic_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_arctic_riot::main;
break;
case "opforce_airborne":
mptype\mptype_opforce_airborne_assault::precache();
mptype\mptype_opforce_airborne_lmg::precache();
mptype\mptype_opforce_airborne_shotgun::precache();
mptype\mptype_opforce_airborne_smg::precache();
mptype\mptype_opforce_airborne_sniper::precache();
mptype\mptype_opforce_airborne_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_airborne_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_opforce_airborne_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_airborne_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_airborne_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_opforce_airborne_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_airborne_riot::main;
break;
case "militia":
mptype\mptype_opforce_militia_assault::precache();
mptype\mptype_opforce_militia_lmg::precache();
mptype\mptype_opforce_militia_shotgun::precache();
mptype\mptype_opforce_militia_smg::precache();
mptype\mptype_opforce_militia_sniper::precache();
mptype\mptype_opforce_militia_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_militia_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_opforce_militia_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_militia_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_militia_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_opforce_militia_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_militia_riot::main;
break;
case "socom_141":
mptype\mptype_socom_assault::precache();
mptype\mptype_socom_lmg::precache();
mptype\mptype_socom_shotgun::precache();
mptype\mptype_socom_smg::precache();
mptype\mptype_socom_sniper::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_socom_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_socom_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_socom_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_socom_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_socom_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_socom_smg::main;
break;
case "socom_141_desert":
mptype\mptype_tf141_desert_assault::precache();
mptype\mptype_tf141_desert_lmg::precache();
mptype\mptype_tf141_desert_smg::precache();
mptype\mptype_tf141_desert_shotgun::precache();
mptype\mptype_tf141_desert_sniper::precache();
mptype\mptype_tf141_desert_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_tf141_desert_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_tf141_desert_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_tf141_desert_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_tf141_desert_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_tf141_desert_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_tf141_desert_riot::main;
break;
case "socom_141_forest":
mptype\mptype_tf141_forest_assault::precache();
mptype\mptype_tf141_forest_lmg::precache();
mptype\mptype_tf141_forest_smg::precache();
mptype\mptype_tf141_forest_shotgun::precache();
mptype\mptype_tf141_forest_sniper::precache();
mptype\mptype_tf141_forest_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_tf141_forest_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_tf141_forest_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_tf141_forest_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_tf141_forest_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_tf141_forest_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_tf141_forest_riot::main;
break;
case "socom_141_arctic":
mptype\mptype_tf141_arctic_assault::precache();
mptype\mptype_tf141_arctic_lmg::precache();
mptype\mptype_tf141_arctic_smg::precache();
mptype\mptype_tf141_arctic_shotgun::precache();
mptype\mptype_tf141_arctic_sniper::precache();
mptype\mptype_tf141_arctic_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_tf141_arctic_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_tf141_arctic_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_tf141_arctic_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_tf141_arctic_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_tf141_arctic_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_tf141_arctic_riot::main;
break;
}
}
setPlayerModels()
{
//mptype\mptype_us_army_riot::precache();
//game["allies_model"]["riotshield"] = mptype\mptype_us_army_riot::main;
//game["axis_model"]["riotshield"] = mptype\mptype_us_army_riot::main;
setTeamModels( "allies", game["allies"] );
setTeamModels( "axis", game["axis"] );
setGhillieModels( getMapCustom( "environment" ) );
}
playerModelForWeapon( weapon, secondary )
{
team = self.team;
if ( isDefined( game[team + "_model"][weapon] ) )
{
[[game[team+"_model"][weapon]]]();
return;
}
weaponClass = tablelookup( "mp/statstable.csv", 4, weapon, 2 );
switch ( weaponClass )
{
case "weapon_smg":
[[game[team+"_model"]["SMG"]]]();
break;
case "weapon_assault":
weaponClass = tablelookup( "mp/statstable.csv", 4, secondary, 2 );
if ( weaponClass == "weapon_shotgun" )
[[game[team+"_model"]["SHOTGUN"]]]();
else
[[game[team+"_model"]["ASSAULT"]]]();
break;
case "weapon_sniper":
if ( level.environment != "" && self isItemUnlocked( "ghillie_" + level.environment ) )
[[game[team+"_model"]["GHILLIE"]]]();
else
[[game[team+"_model"]["SNIPER"]]]();
break;
case "weapon_lmg":
[[game[team+"_model"]["LMG"]]]();
break;
case "weapon_riot":
[[game[team+"_model"]["RIOT"]]]();
break;
default:
[[game[team+"_model"]["ASSAULT"]]]();
break;
}
}
CountPlayers()
{
//chad
players = level.players;
allies = 0;
axis = 0;
for(i = 0; i < players.size; i++)
{
if ( players[i] == self )
continue;
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
allies++;
else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
axis++;
}
players["allies"] = allies;
players["axis"] = axis;
return players;
}
trackFreePlayedTime()
{
self endon( "disconnect" );
self.timePlayed["allies"] = 0;
self.timePlayed["axis"] = 0;
self.timePlayed["other"] = 0;
self.timePlayed["total"] = 0;
for ( ;; )
{
if ( game["state"] == "playing" )
{
if ( isDefined( self.pers["team"] ) && self.pers["team"] == "allies" && self.sessionteam != "spectator" )
{
self.timePlayed["allies"]++;
self.timePlayed["total"]++;
}
else if ( isDefined( self.pers["team"] ) && self.pers["team"] == "axis" && self.sessionteam != "spectator" )
{
self.timePlayed["axis"]++;
self.timePlayed["total"]++;
}
else
{
self.timePlayed["other"]++;
}
}
wait ( 1.0 );
}
}
/#
playerConnectedTest()
{
if ( getdvarint( "scr_runlevelandquit" ) == 1 )
return;
level endon( "exitLevel_called" );
// every frame, do a getPlayerData on each player in level.players.
// this will force a script error if a player in level.players isn't connected.
for ( ;; )
{
foreach ( player in level.players )
{
player getPlayerData( "experience" );
}
wait .05;
}
}
#/
updateFreePlayerTimes()
{
if ( !level.rankedmatch )
return;
/#
thread playerConnectedTest();
#/
nextToUpdate = 0;
for ( ;; )
{
nextToUpdate++;
if ( nextToUpdate >= level.players.size )
nextToUpdate = 0;
if ( isDefined( level.players[nextToUpdate] ) )
level.players[nextToUpdate] updateFreePlayedTime();
wait ( 1.0 );
}
}
updateFreePlayedTime()
{
if ( !self rankingEnabled() )
return;
if ( self.timePlayed["allies"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedAllies", self.timePlayed["allies"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["allies"] );
}
if ( self.timePlayed["axis"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOpfor", self.timePlayed["axis"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["axis"] );
}
if ( self.timePlayed["other"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOther", self.timePlayed["other"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["other"] );
}
if ( game["state"] == "postgame" )
return;
self.timePlayed["allies"] = 0;
self.timePlayed["axis"] = 0;
self.timePlayed["other"] = 0;
}
getJoinTeamPermissions( team )
{
teamcount = 0;
players = level.players;
for(i = 0; i < players.size; i++)
{
player = players[i];
if((isdefined(player.pers["team"])) && (player.pers["team"] == team))
teamcount++;
}
if( teamCount < level.teamLimit )
return true;
else
return false;
}
onPlayerSpawned()
{
level endon ( "game_ended" );
for ( ;; )
{
self waittill ( "spawned_player" );
}
}
getTeamName( teamRef )
{
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_NAME_COL ) );
}
getTeamShortName( teamRef )
{
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_SHORT_NAME_COL ) );
}
getTeamForfeitedString( teamRef )
{
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FORFEITED_COL ) );
}
getTeamEliminatedString( teamRef )
{
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_ELIMINATED_COL ) );
}
getTeamIcon( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_ICON_COL ) );
}
getTeamHudIcon( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_HUD_ICON_COL ) );
}
getTeamHeadIcon( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_HEAD_ICON_COL ) );
}
getTeamVoicePrefix( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_VOICE_PREFIX_COL ) );
}
getTeamSpawnMusic( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_SPAWN_MUSIC_COL ) );
}
getTeamWinMusic( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_WIN_MUSIC_COL ) );
}
getTeamFlagModel( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_MODEL_COL ) );
}
getTeamFlagCarryModel( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_CARRY_MODEL_COL ) );
}
getTeamFlagIcon( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_ICON_COL ) );
}
getTeamFlagFX( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_FX_COL ) );
}
getTeamColor( teamRef )
{
return ( (stringToFloat( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_COLOR_R_COL ) ),
stringToFloat( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_COLOR_G_COL ) ),
stringToFloat( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_COLOR_B_COL ) ))
);
}
getTeamCrateModel( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_CRATE_MODEL_COL ) );
}
+365
View File
@@ -0,0 +1,365 @@
#include maps\mp\_utility;
getTweakableDVarValue( category, name )
{
switch( category )
{
case "rule":
dVar = level.rules[name].dVar;
break;
case "game":
dVar = level.gameTweaks[name].dVar;
break;
case "team":
dVar = level.teamTweaks[name].dVar;
break;
case "player":
dVar = level.playerTweaks[name].dVar;
break;
case "class":
dVar = level.classTweaks[name].dVar;
break;
case "weapon":
dVar = level.weaponTweaks[name].dVar;
break;
case "hardpoint":
dVar = level.hardpointTweaks[name].dVar;
break;
case "hud":
dVar = level.hudTweaks[name].dVar;
break;
default:
dVar = undefined;
break;
}
assert( isDefined( dVar ) );
value = getDvarInt( dVar );
return value;
}
getTweakableDVar( category, name )
{
switch( category )
{
case "rule":
value = level.rules[name].dVar;
break;
case "game":
value = level.gameTweaks[name].dVar;
break;
case "team":
value = level.teamTweaks[name].dVar;
break;
case "player":
value = level.playerTweaks[name].dVar;
break;
case "class":
value = level.classTweaks[name].dVar;
break;
case "weapon":
value = level.weaponTweaks[name].dVar;
break;
case "hardpoint":
value = level.hardpointTweaks[name].dVar;
break;
case "hud":
value = level.hudTweaks[name].dVar;
break;
default:
value = undefined;
break;
}
assert( isDefined( value ) );
return value;
}
getTweakableValue( category, name )
{
switch( category )
{
case "rule":
value = level.rules[name].value;
break;
case "game":
value = level.gameTweaks[name].value;
break;
case "team":
value = level.teamTweaks[name].value;
break;
case "player":
value = level.playerTweaks[name].value;
break;
case "class":
value = level.classTweaks[name].value;
break;
case "weapon":
value = level.weaponTweaks[name].value;
break;
case "hardpoint":
value = level.hardpointTweaks[name].value;
break;
case "hud":
value = level.hudTweaks[name].value;
break;
default:
value = undefined;
break;
}
/#
overrideDvar = "scr_" + level.gameType + "_" + category + "_" + name;
return getDvarInt( overrideDvar, value );
#/
assert( isDefined( value ) );
return value;
}
getTweakableLastValue( category, name )
{
switch( category )
{
case "rule":
value = level.rules[name].lastValue;
break;
case "game":
value = level.gameTweaks[name].lastValue;
break;
case "team":
value = level.teamTweaks[name].lastValue;
break;
case "player":
value = level.playerTweaks[name].lastValue;
break;
case "class":
value = level.classTweaks[name].lastValue;
break;
case "weapon":
value = level.weaponTweaks[name].lastValue;
break;
case "hardpoint":
value = level.hardpointTweaks[name].lastValue;
break;
case "hud":
value = level.hudTweaks[name].lastValue;
break;
default:
value = undefined;
break;
}
assert( isDefined( value ) );
return value;
}
setTweakableValue( category, name, value )
{
switch( category )
{
case "rule":
dVar = level.rules[name].dVar;
break;
case "game":
dVar = level.gameTweaks[name].dVar;
break;
case "team":
dVar = level.teamTweaks[name].dVar;
break;
case "player":
dVar = level.playerTweaks[name].dVar;
break;
case "class":
dVar = level.classTweaks[name].dVar;
break;
case "weapon":
dVar = level.weaponTweaks[name].dVar;
break;
case "hardpoint":
dVar = level.hardpointTweaks[name].dVar;
break;
case "hud":
dVar = level.hudTweaks[name].dVar;
break;
default:
dVar = undefined;
break;
}
setDvar( dVar, value );
}
setTweakableLastValue( category, name, value )
{
switch( category )
{
case "rule":
level.rules[name].lastValue = value;
break;
case "game":
level.gameTweaks[name].lastValue = value;
break;
case "team":
level.teamTweaks[name].lastValue = value;
break;
case "player":
level.playerTweaks[name].lastValue = value;
break;
case "class":
level.classTweaks[name].lastValue = value;
break;
case "weapon":
level.weaponTweaks[name].lastValue = value;
break;
case "hardpoint":
level.hardpointTweaks[name].lastValue = value;
break;
case "hud":
level.hudTweaks[name].lastValue = value;
break;
default:
break;
}
}
registerTweakable( category, name, dvar, value )
{
if ( isString( value ) )
{
value = getDvar( dvar, value );
}
else
{
value = getDvarInt( dvar, value );
}
switch( category )
{
case "rule":
if ( !isDefined( level.rules[name] ) )
level.rules[name] = spawnStruct();
level.rules[name].value = value;
level.rules[name].lastValue = value;
level.rules[name].dVar = dvar;
break;
case "game":
if ( !isDefined( level.gameTweaks[name] ) )
level.gameTweaks[name] = spawnStruct();
level.gameTweaks[name].value = value;
level.gameTweaks[name].lastValue = value;
level.gameTweaks[name].dVar = dvar;
break;
case "team":
if ( !isDefined( level.teamTweaks[name] ) )
level.teamTweaks[name] = spawnStruct();
level.teamTweaks[name].value = value;
level.teamTweaks[name].lastValue = value;
level.teamTweaks[name].dVar = dvar;
break;
case "player":
if ( !isDefined( level.playerTweaks[name] ) )
level.playerTweaks[name] = spawnStruct();
level.playerTweaks[name].value = value;
level.playerTweaks[name].lastValue = value;
level.playerTweaks[name].dVar = dvar;
break;
case "class":
if ( !isDefined( level.classTweaks[name] ) )
level.classTweaks[name] = spawnStruct();
level.classTweaks[name].value = value;
level.classTweaks[name].lastValue = value;
level.classTweaks[name].dVar = dvar;
break;
case "weapon":
if ( !isDefined( level.weaponTweaks[name] ) )
level.weaponTweaks[name] = spawnStruct();
level.weaponTweaks[name].value = value;
level.weaponTweaks[name].lastValue = value;
level.weaponTweaks[name].dVar = dvar;
break;
case "hardpoint":
if ( !isDefined( level.hardpointTweaks[name] ) )
level.hardpointTweaks[name] = spawnStruct();
level.hardpointTweaks[name].value = value;
level.hardpointTweaks[name].lastValue = value;
level.hardpointTweaks[name].dVar = dvar;
break;
case "hud":
if ( !isDefined( level.hudTweaks[name] ) )
level.hudTweaks[name] = spawnStruct();
level.hudTweaks[name].value = value;
level.hudTweaks[name].lastValue = value;
level.hudTweaks[name].dVar = dvar;
break;
}
}
init()
{
level.clientTweakables = [];
level.tweakablesInitialized = true;
level.rules = [];
level.gameTweaks = [];
level.teamTweaks = [];
level.playerTweaks = [];
level.classTweaks = [];
level.weaponTweaks = [];
level.hardpointTweaks = [];
level.hudTweaks = [];
// commented out tweaks have not yet been implemented
if ( level.console )
{
registerTweakable( "game", "graceperiod", "scr_game_graceperiod", 15 ); //*
}
else
{
registerTweakable( "game", "playerwaittime", "scr_game_playerwaittime", 15 ); //*
registerTweakable( "game", "matchstarttime", "scr_game_matchstarttime", 5 ); //*
}
registerTweakable( "game", "onlyheadshots", "scr_game_onlyheadshots", 0 ); //*
registerTweakable( "game", "allowkillcam", "scr_game_allowkillcam", 1 ); //*
registerTweakable( "game", "spectatetype", "scr_game_spectatetype", 2 ); //*
registerTweakable( "game", "deathpointloss", "scr_game_deathpointloss", 0 ); //*
registerTweakable( "game", "suicidepointloss", "scr_game_suicidepointloss", 0 ); //*
registerTweakable( "team", "teamkillpointloss", "scr_team_teamkillpointloss", 0 ); //*
// registerTweakable( "team", "respawntime", "scr_team_respawntime", 0 );
registerTweakable( "team", "fftype", "scr_team_fftype", 0 );
registerTweakable( "team", "teamkillspawndelay", "scr_team_teamkillspawndelay", 0 );
// registerTweakable( "player", "respawndelay", "scr_player_respawndelay", 0 ); //*
registerTweakable( "player", "maxhealth", "scr_player_maxhealth", 100 ); //*
registerTweakable( "player", "healthregentime", "scr_player_healthregentime", 5 ); //*
registerTweakable( "player", "forcerespawn", "scr_player_forcerespawn", 1 ); //*
registerTweakable( "weapon", "allowfrag", "scr_weapon_allowfrags", 1 );
registerTweakable( "weapon", "allowsmoke", "scr_weapon_allowsmoke", 1 );
registerTweakable( "weapon", "allowflash", "scr_weapon_allowflash", 1 );
registerTweakable( "weapon", "allowc4", "scr_weapon_allowc4", 1 );
registerTweakable( "weapon", "allowclaymores", "scr_weapon_allowclaymores", 1 );
registerTweakable( "weapon", "allowrpgs", "scr_weapon_allowrpgs", 1 );
registerTweakable( "weapon", "allowmines", "scr_weapon_allowmines", 1 );
registerTweakable( "hardpoint", "allowartillery", "scr_hardpoint_allowartillery", 1 );
registerTweakable( "hardpoint", "allowuav", "scr_hardpoint_allowuav", 1 );
registerTweakable( "hardpoint", "allowsupply", "scr_hardpoint_allowsupply", 1 );
registerTweakable( "hardpoint", "allowhelicopter", "scr_hardpoint_allowhelicopter", 1 );
registerTweakable( "hud", "showobjicons", "ui_hud_showobjicons", 1 ); //*
makeDVarServerInfo( "ui_hud_showobjicons", 1 );
}
File diff suppressed because it is too large. Load diff
+532
View File
@@ -0,0 +1,532 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Arena
Objective: Eliminate the enemy team
Map ends: When one team eliminates the enemy team, or the flag is reached
Respawning: Beginning of next round
Level requirementss
------------------
Spawnpoints:
classname mp_tdm_spawn
All players spawn from these. The spawnpoint chosen is dependent on the current locations of teammates and enemies
at the time of spawn. Players generally spawn behind their teammates relative to the direction of enemies.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
*/
/*QUAKED mp_tdm_spawn (0.0 0.0 1.0) (-16 -16 0) (16 16 72)
Players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_tdm_spawn_axis_start (0.5 0.0 1.0) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_tdm_spawn_allies_start (0.0 0.5 1.0) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 500, 0, 5000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.teamBased = true;
level.objectiveBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onNormalDeath = ::onNormalDeath;
level.onPlayerKilled = ::onPlayerKilled;
level.onDeadEvent = ::onDeadEvent;
game["dialog"]["gametype"] = "arena";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
game["strings"]["overtime_hint"] = &"MP_FIRST_BLOOD";
}
onPrecacheGameType()
{
precacheShader( "compass_waypoint_captureneutral" );
precacheShader( "compass_waypoint_capture" );
precacheShader( "compass_waypoint_defend" );
precacheShader( "waypoint_captureneutral" );
precacheShader( "waypoint_capture" );
precacheShader( "waypoint_defend" );
}
onStartGameType()
{
setClientNameMode("auto_change");
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setObjectiveText( "allies", &"OBJECTIVES_ARENA" );
setObjectiveText( "axis", &"OBJECTIVES_ARENA" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_ARENA" );
setObjectiveScoreText( "axis", &"OBJECTIVES_ARENA" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_ARENA_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_ARENA_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_ARENA_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_ARENA_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = "dom";
allowed[1] = "airdrop_pallet";
allowed[2] = "arena";
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 200 );
maps\mp\gametypes\_gameobjects::main(allowed);
precacheFlag();
thread arenaFlagWaiter();
thread arenaTimeFlagWaiter();
}
precacheFlag()
{
game["flagmodels"] = [];
game["flagmodels"]["neutral"] = "prop_flag_neutral";
game["flagmodels"]["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
game["flagmodels"]["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
precacheModel( game["flagmodels"]["neutral"] );
precacheModel( game["flagmodels"]["allies"] );
precacheModel( game["flagmodels"]["axis"] );
precacheString( &"MP_CAPTURING_FLAG" );
precacheString( &"MP_LOSING_FLAG" );
precacheString( &"MP_DOM_YOUR_FLAG_WAS_CAPTURED" );
precacheString( &"MP_DOM_ENEMY_FLAG_CAPTURED" );
precacheString( &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
precacheString( &"MP_ENEMY_FLAG_CAPTURED_BY" );
precacheString( &"MP_NEUTRAL_FLAG_CAPTURED_BY" );
precacheString( &"MP_FRIENDLY_FLAG_CAPTURED_BY" );
}
arenaTimeFlagWaiter()
{
level endon( "down_to_one" );
level endon( "game_end" );
for( ;; )
{
timeLeft = maps\mp\gametypes\_gamelogic::getTimeRemaining();
if ( timeLeft < 61000 )
break;
wait ( 1 );
}
level notify( "arena_flag_time" );
thread arenaFlag();
}
arenaFlagWaiter()
{
level endon( "game_end" );
level endon( "arena_flag_time" );
for ( ;; )
{
if ( level.inGracePeriod == 0 )
break;
wait ( 0.05 );
}
for ( ;; )
{
if ( getTeamPlayersAlive ( "axis" ) == 1 )
{
thread arenaFlag();
level notify( "down_to_one" );
break;
}
if ( getTeamPlayersAlive ( "allies" ) == 1 )
{
thread arenaFlag();
level notify( "down_to_one" );
break;
}
wait( 1 );
}
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + spawnteam + "_start" );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onSpawnPlayer()
{
self.usingObj = undefined;
level notify ( "spawned_player" );
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
attacker maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( attacker.pers["team"], score );
team = victim.team;
if ( game["state"] == "postgame" )
attacker.finalKill = true;
}
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
{
thread checkAllowSpectating();
}
onTimeLimit()
{
if ( game["status"] == "overtime" )
{
winner = "forfeit";
}
else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
{
winner = "overtime";
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
winner = "axis";
}
else
{
winner = "allies";
}
thread maps\mp\gametypes\_gamelogic::endGame( winner, game["strings"]["time_limit_reached"] );
}
checkAllowSpectating()
{
wait ( 0.05 );
update = false;
if ( !level.aliveCount[ game["attackers"] ] )
{
level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
update = true;
}
if ( !level.aliveCount[ game["defenders"] ] )
{
level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
update = true;
}
if ( update )
maps\mp\gametypes\_spectating::updateSpectateSettings();
}
arenaFlag()
{
level.lastStatus["allies"] = 0;
level.lastStatus["axis"] = 0;
arenaFlag = getEntArray("flag_arena", "targetname");
primaryFlags = getEntArray( "flag_primary", "targetname" );
secondaryFlags = getEntArray( "flag_secondary", "targetname" );
// check to see if arena flag is present otherwise throw a warning and use the dom Flag.
if ( !isDefined( arenaFlag[0] ) )
{
println("WARNING: no arena flags specified attempting to use Dom flag_b" );
if ( (primaryFlags.size + secondaryFlags.size) < 1 )
{
printLn( "^1Not enough domination flags found in level!" );
maps\mp\gametypes\_callbacksetup::AbortLevel();
return;
}
self setupDomFlag(primaryFlags, secondaryFlags);
}
else
level.arenaFlag = arenaFlag[0];
trigger = level.arenaFlag;
if ( isDefined( trigger.target ) )
{
visuals[0] = getEnt( trigger.target, "targetname" );
}
else
{
visuals[0] = spawn( "script_model", trigger.origin );
visuals[0].angles = trigger.angles;
}
visuals[0] setModel( game["flagmodels"]["neutral"] );
arenaFlag = maps\mp\gametypes\_gameobjects::createUseObject( "neutral", trigger, visuals, (0,0,100) );
arenaFlag maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
arenaFlag maps\mp\gametypes\_gameobjects::setUseTime( 20.0 );
arenaFlag maps\mp\gametypes\_gameobjects::setUseText( &"MP_CAPTURING_FLAG" );
label = arenaFlag maps\mp\gametypes\_gameobjects::getLabel();
arenaFlag.label = label;
arenaFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
arenaFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend");
arenaFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral");
arenaFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral");
arenaFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
arenaFlag.onUse = ::onUse;
arenaFlag.onBeginUse = ::onBeginUse;
arenaFlag.onUseUpdate = ::onUseUpdate;
arenaFlag.onEndUse = ::onEndUse;
arenaFlag.isArena = true;
//play sound to show flag is now available for capture
iPrintLnBold( "Arena flag spawned" );
level.arenaFlag playSound( "flag_spawned" );
traceStart = visuals[0].origin + (0,0,32);
traceEnd = visuals[0].origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
upangles = vectorToAngles( trace["normal"] );
arenaFlag.baseeffectforward = anglesToForward( upangles );
arenaFlag.baseeffectright = anglesToRight( upangles );
arenaFlag.baseeffectpos = trace["position"];
arenaFlag.levelFlag = level.arenaFlag;
level.arenaFlag = arenaFlag;
}
setupDomFlag( primaryFlags, secondaryFlags )
{
for ( index = 0; index < primaryFlags.size; index++ )
{
label = primaryFlags[index].script_label;
if ( label != "_b" )
{
primaryFlags[index] delete();
}
else
{
level.arenaFlag = primaryFlags[index];
return;
}
}
}
onDeadEvent( team )
{
if ( team == game["attackers"] )
{
level thread arena_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
level thread arena_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
arena_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
giveFlagCaptureXP( touchList )
{
level endon ( "game_ended" );
wait .05;
WaitTillSlowProcessAllowed();
players = getArrayKeys( touchList );
for ( index = 0; index < players.size; index++ )
{
player = touchList[players[index]].player;
player thread [[level.onXPEvent]]( "capture" );
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
}
}
onUse( player )
{
team = player.pers["team"];
oldTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
label = self maps\mp\gametypes\_gameobjects::getLabel();
//player logString( "flag captured: " + self.label );
self.captureTime = getTime();
self maps\mp\gametypes\_gameobjects::setOwnerTeam( team );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_capture" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_capture" );
self.visuals[0] setModel( game["flagmodels"][team] );
assert( team != "neutral" );
if ( oldTeam == "neutral" )
{
otherTeam = getOtherTeam( team );
thread printAndSoundOnEveryone( team, otherTeam, &"MP_NEUTRAL_FLAG_CAPTURED_BY", &"MP_NEUTRAL_FLAG_CAPTURED_BY", "mp_war_objective_taken", undefined, player );
statusDialog( "captured_a", team );
statusDialog( "enemy_has_a", otherTeam );
}
else
thread printAndSoundOnEveryone( team, oldTeam, &"MP_ENEMY_FLAG_CAPTURED_BY", &"MP_FRIENDLY_FLAG_CAPTURED_BY", "mp_war_objective_taken", "mp_war_objective_lost", player );
thread giveFlagCaptureXP( self.touchList[team] );
player notify( "objective", "captured" );
thread flagCaptured( team, &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
}
onBeginUse( player )
{
ownerTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
self.didStatusNotify = false;
if ( ownerTeam == "neutral" )
{
otherTeam = getOtherTeam( player.pers["team"] );
statusDialog( "securing", player.pers["team"] );
self.objPoints[player.pers["team"]] thread maps\mp\gametypes\_objpoints::startFlashing();
statusDialog( "enemy_taking", otherTeam );
return;
}
if ( ownerTeam == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::startFlashing();
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::startFlashing();
}
onUseUpdate( team, progress, change )
{
if ( progress > 0.05 && change && !self.didStatusNotify )
{
otherTeam = getOtherTeam( team );
statusDialog( "losing_a", otherTeam );
statusDialog( "securing_a", team );
self.didStatusNotify = true;
}
}
onEndUse( team, player, success )
{
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::stopFlashing();
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::stopFlashing();
}
statusDialog( dialog, team )
{
time = getTime();
if ( getTime() < level.lastStatus[team] + 6000 )
return;
thread delayedLeaderDialog( dialog, team );
level.lastStatus[team] = getTime();
}
delayedLeaderDialog( sound, team )
{
level endon ( "game_ended" );
wait .1;
WaitTillSlowProcessAllowed();
leaderDialog( sound, team );
}
delayedLeaderDialogBothTeams( sound1, team1, sound2, team2 )
{
level endon ( "game_ended" );
wait .1;
WaitTillSlowProcessAllowed();
leaderDialogBothTeams( sound1, team1, sound2, team2 );
}
flagCaptured( winningTeam, endReasonText )
{
maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
+761
View File
@@ -0,0 +1,761 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
One Flag CTF
*/
/*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
registerScoreLimitDvar( level.gameType, 1, 0, 10000 );
registerRoundLimitDvar( level.gameType, 0, 0, 30 );
registerWinLimitDvar( level.gameType, 4, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 1, 0, 1 );
setOverTimeLimitDvar( 4 );
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onPlayerKilled = ::onPlayerKilled;
level.initGametypeAwards = ::initGametypeAwards;
level.onTimeLimit = ::onTimeLimit;
level.onSpawnPlayer = ::onSpawnPlayer;
level.flagReturnTime = getIntProperty( "scr_ctf_returntime", 30 );
game["dialog"]["gametype"] = "captureflag";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "capture_obj";
game["dialog"]["defense_obj"] = "capture_obj";
}
onPrecacheGameType()
{
precacheString(&"MP_FLAG_TAKEN_BY");
precacheString(&"MP_ENEMY_FLAG_TAKEN_BY");
precacheString(&"MP_FLAG_CAPTURED_BY");
precacheString(&"MP_ENEMY_FLAG_CAPTURED_BY");
precacheString(&"MP_FLAG_RETURNED");
precacheString(&"MP_ENEMY_FLAG_RETURNED");
precacheString(&"MP_YOUR_FLAG_RETURNING_IN");
precacheString(&"MP_ENEMY_FLAG_RETURNING_IN");
precacheString(&"MP_ENEMY_FLAG_DROPPED_BY");
precacheString(&"MP_DOM_NEUTRAL_FLAG_CAPTURED");
precacheString(&"MP_GRABBING_FLAG");
precacheString(&"MP_RETURNING_FLAG");
}
onSpawnPlayer()
{
if( ( inOvertime() ) && !isDefined( self.otSpawned ) )
self thread printOTHint();
}
printOTHint()
{
self endon ( "disconnect" );
// give the "Overtime!" message time to show
wait ( 0.25 );
self.otSpawned = true;
hintMessage = getObjectiveHintText( self.team );
self thread maps\mp\gametypes\_hud_message::hintMessage( hintMessage );
}
onStartGameType()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( !isdefined( game["original_defenders"] ) )
game["original_defenders"] = game["defenders"];
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setClientNameMode("auto_change");
if ( level.splitscreen )
{
if ( inOvertime() )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GRAB_FLAG" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GRAB_FLAG" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER" );
}
}
else
{
if ( inOvertime() )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GRAB_FLAG_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GRAB_FLAG_SCORE" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_SCORE" );
}
}
if ( inOvertime() )
{
setObjectiveText( game["attackers"], &"OBJECTIVES_OVERTIME_CTF" );
setObjectiveText( game["defenders"], &"OBJECTIVES_OVERTIME_CTF" );
setObjectiveHintText( game["attackers"], &"OBJECTIVES_GRAB_FLAG_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_GRAB_FLAG_HINT" );
}
else
{
setObjectiveText( game["attackers"], &"OBJECTIVES_CTF" );
setObjectiveText( game["defenders"], &"OBJECTIVES_CTF" );
setObjectiveHintText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_HINT" );
}
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_ctf_spawn_allies" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_ctf_spawn_axis" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
thread maps\mp\gametypes\_dev::init();
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "pickup", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "return", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 250 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill_carrier", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend_assist", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault", 200 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault_assist", 40 );
allowed[0] = "ctf";
maps\mp\gametypes\_gameobjects::main(allowed);
thread ctf();
}
getSpawnPoint()
{
if ( self.team == "axis" )
{
spawnTeam = game["attackers"];
}
else
{
spawnTeam = game["defenders"];
}
// if ( game["switchedsides"] )
// spawnTeam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = getentarray("mp_ctf_spawn_" + spawnteam + "_start", "classname");
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
ctf()
{
level.flagModel["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
level.icon2D["allies"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "allies" );
level.carryFlag["allies"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "allies" );
precacheModel( level.flagModel["allies"] );
precacheModel( level.carryFlag["allies"] );
level.flagModel["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
level.icon2D["axis"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "axis" );
level.carryFlag["axis"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "axis" );
precacheModel( level.flagModel["axis"] );
precacheModel( level.carryFlag["axis"] );
level.iconEscort3D = "waypoint_escort";
level.iconEscort2D = "waypoint_escort";
precacheShader( level.iconEscort3D );
precacheShader( level.iconEscort2D );
//level.iconEscort2D = level.iconEscort3D; // flags with words on compass
level.iconKill3D = "waypoint_kill";
level.iconKill2D = "waypoint_kill";
precacheShader( level.iconKill3D );
precacheShader( level.iconKill2D );
//level.iconKill2D = level.iconKill3D; // flags with words on compass
level.iconCaptureFlag3D = "waypoint_capture_flag";
level.iconCaptureFlag2D = "waypoint_capture_flag";
precacheShader( level.iconCaptureFlag3D );
precacheShader( level.iconCaptureFlag2D );
//level.iconCaptureFlag2D = level.iconCaptureFlag3D; // flags with words on compass
level.iconDefendFlag3D = "waypoint_defend_flag";
level.iconDefendFlag2D = "waypoint_defend_flag";
precacheShader( level.iconDefendFlag3D );
precacheShader( level.iconDefendFlag2D );
//level.iconDefendFlag2D = level.iconDefendFlag3D; // flags with words on compass
level.iconReturnFlag3D = "waypoint_return_flag";
level.iconReturnFlag2D = "waypoint_return_flag";
precacheShader( level.iconReturnFlag3D );
precacheShader( level.iconReturnFlag2D );
//level.iconReturnFlag2D = level.iconReturnFlag3D; // flags with words on compass
level.iconWaitForFlag3D = "waypoint_waitfor_flag";
level.iconWaitForFlag2D = "waypoint_waitfor_flag";
precacheShader( level.iconWaitForFlag3D );
precacheShader( level.iconWaitForFlag2D );
//level.iconWaitForFlag2D = level.iconWaitForFlag3D; // flags with words on compass
precacheShader( level.icon2D["axis"] );
precacheShader( level.icon2D["allies"] );
precacheShader( "waypoint_flag_friendly" );
precacheShader( "waypoint_flag_enemy" );
precacheString( &"OBJECTIVES_FLAG_HOME" );
precacheString( &"OBJECTIVES_FLAG_NAME" );
precacheString( &"OBJECTIVES_FLAG_AWAY" );
level.teamFlags[game["defenders"]] = createTeamFlag( game["defenders"], "allies" );
level.teamFlags[game["attackers"]] = createTeamFlag( game["attackers"], level.otherTeam["allies"] );
level.capZones[game["defenders"]] = createCapZone( game["defenders"], "allies" );
level.capZones[game["attackers"]] = createCapZone( game["attackers"], level.otherTeam["allies"] );
if ( level.splitScreen )
hudElemAlpha = 0;
else
hudElemAlpha = 0.85;
level.friendlyFlagStatusIcon["allies"] = createServerIcon( "waypoint_flag_friendly", 32, 32, "allies" );
level.friendlyFlagStatusIcon["allies"] setPoint( "TOP LEFT", "TOP LEFT", 132, 0 );
level.friendlyFlagStatusIcon["allies"].alpha = hudElemAlpha;
level.friendlyFlagStatusIcon["allies"].hideWhenInMenu = true;
level.friendlyFlagStatusText["allies"] = createServerFontString( "small", 1.6, "allies" );
level.friendlyFlagStatusText["allies"] setParent( level.friendlyFlagStatusIcon["allies"] );
level.friendlyFlagStatusText["allies"] setPoint( "LEFT", "RIGHT", 4 );
level.friendlyFlagStatusText["allies"] setText( &"OBJECTIVES_FLAG_HOME" );
level.friendlyFlagStatusText["allies"].alpha = hudElemAlpha;
level.friendlyFlagStatusText["allies"].color = (1,1,1);
level.friendlyFlagStatusText["allies"].glowAlpha = 1;
level.friendlyFlagStatusText["allies"].hideWhenInMenu = true;
level.enemyFlagStatusIcon["allies"] = createServerIcon( "waypoint_flag_enemy", 24, 24, "allies" );
level.enemyFlagStatusIcon["allies"] setPoint( "TOP LEFT", "TOP LEFT", 132, 26 );
level.enemyFlagStatusIcon["allies"].alpha = hudElemAlpha;
level.enemyFlagStatusIcon["allies"].hideWhenInMenu = true;
level.enemyFlagStatusText["allies"] = createServerFontString( "small", 1.6, "allies" );
level.enemyFlagStatusText["allies"] setParent( level.enemyFlagStatusIcon["allies"] );
level.enemyFlagStatusText["allies"] setPoint( "LEFT", "RIGHT", 4 );
level.enemyFlagStatusText["allies"] setText( &"OBJECTIVES_FLAG_HOME" );
level.enemyFlagStatusText["allies"].alpha = hudElemAlpha;
level.enemyFlagStatusText["allies"].color = (1,1,1);
level.enemyFlagStatusText["allies"].glowAlpha = 1;
level.enemyFlagStatusText["allies"].hideWhenInMenu = true;
level.friendlyFlagStatusIcon["axis"] = createServerIcon( "waypoint_flag_friendly", 32, 32, "axis" );
level.friendlyFlagStatusIcon["axis"] setPoint( "TOP LEFT", "TOP LEFT", 132, 0 );
level.friendlyFlagStatusIcon["axis"].alpha = hudElemAlpha;
level.friendlyFlagStatusIcon["axis"].hideWhenInMenu = true;
level.friendlyFlagStatusText["axis"] = createServerFontString( "small", 1.6, "axis" );
level.friendlyFlagStatusText["axis"] setParent( level.friendlyFlagStatusIcon["axis"] );
level.friendlyFlagStatusText["axis"] setPoint( "LEFT", "RIGHT", 4 );
level.friendlyFlagStatusText["axis"] setText( &"OBJECTIVES_FLAG_HOME" );
level.friendlyFlagStatusText["axis"].alpha = hudElemAlpha;
level.friendlyFlagStatusText["axis"].color = (1,1,1);
level.friendlyFlagStatusText["axis"].glowAlpha = 1;
level.friendlyFlagStatusText["axis"].hideWhenInMenu = true;
level.enemyFlagStatusIcon["axis"] = createServerIcon( "waypoint_flag_enemy", 24, 24, "axis" );
level.enemyFlagStatusIcon["axis"] setPoint( "TOP LEFT", "TOP LEFT", 132, 26 );
level.enemyFlagStatusIcon["axis"].alpha = hudElemAlpha;
level.enemyFlagStatusIcon["axis"].hideWhenInMenu = true;
level.enemyFlagStatusText["axis"] = createServerFontString( "small", 1.6, "axis" );
level.enemyFlagStatusText["axis"] setParent( level.enemyFlagStatusIcon["axis"] );
level.enemyFlagStatusText["axis"] setPoint( "LEFT", "RIGHT", 4 );
level.enemyFlagStatusText["axis"] setText( &"OBJECTIVES_FLAG_HOME" );
level.enemyFlagStatusText["axis"].alpha = hudElemAlpha;
level.enemyFlagStatusText["axis"].color = (1,1,1);
level.enemyFlagStatusText["axis"].glowAlpha = 1;
level.enemyFlagStatusText["axis"].hideWhenInMenu = true;
}
//sets overtime and associated variables
onTimeLimit()
{
if ( !inOvertime() && game["teamScores"]["allies"] == game["teamScores"]["axis"] && game["switchedsides"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "overtime", game["strings"]["time_limit_reached"] );
}
else if( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
}
else if( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
}
else if ( inOvertime() )
{
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game["strings"]["time_limit_reached"] );
}
}
spawnFxDelay( fxid, pos, forward, right, delay )
{
wait delay;
effect = spawnFx( fxid, pos, forward, right );
triggerFx( effect );
}
createTeamFlag( team, entityTeam )
{
trigger = getEnt( "ctf_zone_" + entityTeam, "targetname" );
if ( !isDefined( trigger ) )
{
error( "No ctf_zone_" + entityTeam + " trigger found in map." );
return;
}
visuals[0] = getEnt( "ctf_flag_" + entityTeam, "targetname" );
if ( !isDefined( visuals[0] ) )
{
error( "No ctf_flag_" + entityTeam + " script_model found in map." );
return;
}
cloneTrigger = spawn( "trigger_radius", trigger.origin, 0, 96, trigger.height );
trigger = cloneTrigger;
visuals[0] setModel( level.flagModel[team] );
teamFlag = maps\mp\gametypes\_gameobjects::createCarryObject( team, trigger, visuals, (0,0,85) );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "friendly", 0.5 );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "enemy", 0.5 );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "enemy", &"MP_GRABBING_FLAG" );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "friendly", &"MP_RETURNING_FLAG" );
teamFlag maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
teamFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill2D );
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconEscort2D );
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconEscort3D );
teamFlag maps\mp\gametypes\_gameobjects::setCarryIcon( level.icon2D[team] );
teamFlag.objIDPingFriendly = true;
teamFlag.allowWeapons = true;
teamFlag.onPickup = ::onPickup;
teamFlag.onPickupFailed = ::onPickup;
teamFlag.onDrop = ::onDrop;
teamFlag.onReset = ::onReset;
teamFlag.oldRadius = trigger.radius;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
return teamFlag;
}
createCapZone( team, entityTeam )
{
trigger = getEnt( "ctf_zone_" + entityTeam, "targetname" );
if ( !isDefined( trigger ) )
{
error("No ctf_zone_" + entityTeam + " trigger found in map.");
return;
}
visuals = [];
capZone = maps\mp\gametypes\_gameobjects::createUseObject( team, trigger, visuals, (0,0,85) );
capZone maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
capZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
capZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefendFlag2D );
capZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefendFlag3D );
capZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCaptureFlag2D );
capZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCaptureFlag3D );
capZone maps\mp\gametypes\_gameobjects::setUseTime( 0 );
capZone maps\mp\gametypes\_gameobjects::setKeyObject( level.teamFlags[ getOtherTeam( team ) ] );
capZone.onUse = ::onUse;
capZone.onCantUse = ::onCantUse;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
return capZone;
}
onBeginUse( player )
{
team = player.pers["team"];
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
self.trigger.radius = 1024;
else
self.trigger.radius = self.oldRadius;
}
onEndUse( player, team, success )
{
self.trigger.radius = self.oldRadius;
}
onPickup( player )
{
self notify ( "picked_up" );
team = player.pers["team"];
if ( team == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
{
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagreturn", maps\mp\gametypes\_rank::getScoreInfoValue( "return" ) );
player thread [[level.onXPEvent]]( "return" );
self thread returnFlag();
player incPlayerStat( "flagsreturned", 1 );
player thread maps\mp\_matchdata::logGameEvent( "return", player.origin );
printAndSoundOnEveryone( team, getOtherTeam( team ), &"MP_FLAG_RETURNED", &"MP_ENEMY_FLAG_RETURNED", "mp_obj_returned", "mp_obj_returned", "" );
leaderDialog( "enemy_flag_returned", otherteam, "status" );
leaderDialog( "flag_returned", team, "status" );
level.friendlyFlagStatusText[team] setText( &"OBJECTIVES_FLAG_HOME" );
level.friendlyFlagStatusText[team].glowColor = (1,1,1);
level.friendlyFlagStatusText[team].glowAlpha = 0;
level.enemyFlagStatusText[otherTeam] setText( &"OBJECTIVES_FLAG_HOME" );
level.enemyFlagStatusText[otherTeam].glowColor = (1,1,1);
level.enemyFlagStatusText[otherTeam].glowAlpha = 0;
}
else
{
if ( inOvertime() )
{
if ( isDefined( level.flagCaptured ) )
{
// denied splash!
return;
}
level thread teamPlayerCardSplash( "callout_grabbedtheflag", player );
level.teamFlags[team] maps\mp\gametypes\_gameobjects::allowUse( "none" );
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::allowUse( "none" );
level.capZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.flagCaptured = true;
//wait ( 1.5 );
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
thread maps\mp\gametypes\_gamelogic::endGame( "winner", game["strings"]["grabbed_flag"] );
}
player attachFlag();
level.friendlyFlagStatusText[otherTeam] setPlayerNameString( player );
level.friendlyFlagStatusText[otherTeam].glowColor = (0.75,0.25,0.25);
level.friendlyFlagStatusText[otherTeam].glowAlpha = 1;
level.enemyFlagStatusText[team] setPlayerNameString( player );
level.enemyFlagStatusText[team].glowColor = (0.25,0.75,0.25);
level.enemyFlagStatusText[team].glowAlpha = 1;
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconEscort2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconEscort3D );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::allowUse( "none" );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
//level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
//level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill3D );
if ( !level.teamFlags[ team ] maps\mp\gametypes\_gameobjects::isHome() )
{
level.capZones[ team ].trigger maps\mp\_entityheadIcons::setHeadIcon( player, level.iconWaitForFlag3D, (0,0,85) );
if ( isDefined( level.teamFlags[ team ].carrier ) )
level.capZones[ otherTeam ].trigger maps\mp\_entityheadIcons::setHeadIcon( level.teamFlags[ team ].carrier, level.iconWaitForFlag3D, (0,0,85) );
}
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_TAKEN_BY", &"MP_FLAG_TAKEN_BY", "mp_obj_taken", "mp_enemy_obj_taken", player );
leaderDialog( "enemy_flag_taken", team, "status" );
leaderDialog( "flag_taken", otherteam, "status" );
thread teamPlayerCardSplash( "callout_flagpickup", player );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagpickup", maps\mp\gametypes\_rank::getScoreInfoValue( "pickup" ) );
maps\mp\gametypes\_gamescore::givePlayerScore( "pickup", player );
player thread [[level.onXPEvent]]( "pickup" );
player incPlayerStat( "flagscarried", 1 );
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
}
}
returnFlag()
{
self maps\mp\gametypes\_gameobjects::returnHome();
}
onDrop( player )
{
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
otherTeam = level.otherTeam[team];
self maps\mp\gametypes\_gameobjects::allowCarry( "any" );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconReturnFlag2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconReturnFlag3D );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCaptureFlag2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCaptureFlag3D );
level.friendlyFlagStatusText[team] setText( &"OBJECTIVES_FLAG_AWAY" );
level.friendlyFlagStatusText[team].glowColor = (1,1,1);
level.friendlyFlagStatusText[team].glowAlpha = 0;
level.enemyFlagStatusText[otherTeam] setText( &"OBJECTIVES_FLAG_AWAY" );
level.enemyFlagStatusText[otherTeam].glowColor = (1,1,1);
level.enemyFlagStatusText[otherTeam].glowAlpha = 0;
level.capZones[otherTeam].trigger maps\mp\_entityheadIcons::setHeadIcon( "none", "", (0,0,0) );
if ( isDefined( player ) )
{
if ( isDefined( player.carryFlag ) )
player detachFlag();
printAndSoundOnEveryone( otherTeam, "none", &"MP_ENEMY_FLAG_DROPPED_BY", "", "mp_war_objective_lost", "", player );
}
else
{
playSoundOnPlayers( "mp_war_objective_lost", otherTeam );
}
leaderDialog( "enemy_flag_dropped", otherTeam, "status" );
leaderDialog( "flag_dropped", team, "status" );
self thread returnAfterTime();
}
returnAfterTime()
{
self endon ( "picked_up" );
wait ( level.flagReturnTime );
self maps\mp\gametypes\_gameobjects::returnHome();
}
onReset()
{
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
otherTeam = level.otherTeam[team];
self maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconEscort2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconEscort3D );
level.friendlyFlagStatusText[team] setText( &"OBJECTIVES_FLAG_HOME" );
level.friendlyFlagStatusText[team].glowColor = (1,1,1);
level.friendlyFlagStatusText[team].glowAlpha = 0;
level.enemyFlagStatusText[otherTeam] setText( &"OBJECTIVES_FLAG_HOME" );
level.enemyFlagStatusText[otherTeam].glowColor = (1,1,1);
level.enemyFlagStatusText[otherTeam].glowAlpha = 0;
level.capZones[team] maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
level.capZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
level.capZones[team] maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefendFlag2D );
level.capZones[team] maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefendFlag3D );
level.capZones[team] maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCaptureFlag2D );
level.capZones[team] maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCaptureFlag3D );
level.capZones[team].trigger maps\mp\_entityheadIcons::setHeadIcon( "none", "", (0,0,0) );
}
onUse( player )
{
team = player.pers["team"];
if ( team == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
leaderDialog( "enemy_flag_captured", team, "status" );
leaderDialog( "flag_captured", otherteam, "status" );
thread teamPlayerCardSplash( "callout_flagcapture", player );
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flag_capture", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) );
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
player thread [[level.onXPEvent]]( "capture" );
player incPlayerStat( "flagscaptured", 1 );
player notify( "objective", "captured" );
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_CAPTURED_BY", &"MP_FLAG_CAPTURED_BY", "mp_obj_captured", "mp_enemy_obj_captured", player );
if ( isDefined( player.carryFlag ) )
player detachFlag();
level.teamFlags[otherTeam] returnFlag();
}
onCantUse( player )
{
// player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId )
{
if ( isDefined( attacker ) && isPlayer( attacker ) && attacker.pers["team"] != self.pers["team"] )
{
if ( isDefined( attacker.carryFlag ) )
attacker incPlayerStat( "killsasflagcarrier", 1 );
if ( isDefined( self.carryFlag ) )
{
attacker thread [[level.onXPEvent]]( "kill_carrier" );
maps\mp\gametypes\_gamescore::givePlayerScore( "kill_carrier", attacker );
attacker incPlayerStat( "flagcarrierkills", 1 );
thread maps\mp\_matchdata::logKillEvent( killId, "carrying" );
self detachFlag();
}
}
}
attachFlag()
{
otherTeam = level.otherTeam[self.pers["team"]];
self attach( level.carryFlag[otherTeam], "J_spine4", true );
self.carryFlag = level.carryFlag[otherTeam];
}
detachFlag()
{
self detach( self.carryFlag, "J_spine4" );
self.carryFlag = undefined;
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "flagscaptured", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagsreturned", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasflagcarrier", 0, maps\mp\_awards::highestWins );
}
+870
View File
@@ -0,0 +1,870 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Action SAB/SD = DD
Attackers objective: Bomb both of 2 positions
Defenders objective: Defend these 2 positions / Defuse planted bombs
Round ends: When one team defends for duration of match, both sites are destroyed.
Map ends: When one team reaches the score limit, or time limit or round limit is reached
Respawning: Players respawn indefinetly and immediately
Level requirements
------------------
Allied Spawnpoints:
classname mp_sd_spawn_attacker
Allied players spawn from these. Place at least 16 of these relatively close together.
Axis Spawnpoints:
classname mp_sd_spawn_defender
Axis players spawn from these. Place at least 16 of these relatively close together.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
Bombzones:
classname trigger_multiple
targetname bombzone
script_gameobjectname bombzone
script_bombmode_original <if defined this bombzone will be used in the original bomb mode>
script_bombmode_single <if defined this bombzone will be used in the single bomb mode>
script_bombmode_dual <if defined this bombzone will be used in the dual bomb mode>
script_team Set to allies or axis. This is used to set which team a bombzone is used by in dual bomb mode.
script_label Set to A or B. This sets the letter shown on the compass in original mode.
This is a volume of space in which the bomb can planted. Must contain an origin brush.
Bomb:
classname trigger_lookat
targetname bombtrigger
script_gameobjectname bombzone
This should be a 16x16 unit trigger with an origin brush placed so that it's center lies on the bottom plane of the trigger.
Must be in the level somewhere. This is the trigger that is used when defusing a bomb.
It gets moved to the position of the planted bomb model.
Level script requirements
-------------------------
Team Definitions:
game["attackers"] = "allies";
game["defenders"] = "axis";
This sets which team is attacking and which team is defending. Attackers plant the bombs. Defenders protect the targets.
Exploder Effects:
Setting script_noteworthy on a bombzone trigger to an exploder group can be used to trigger additional effects.
multiple bombs
multiple targets
spawning
round handling when both sites are destroyed
*/
/*QUAKED mp_dd_spawn_attacker_a (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn near bomb a.*/
/*QUAKED mp_dd_spawn_attacker_b (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn near bomb b.*/
/*QUAKED mp_dd_spawn_attacker (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_dd_spawn_defender (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_dd_spawn_defender_a (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn near bomb site a.*/
/*QUAKED mp_dd_spawn_defender_b (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn near bomb site b.*/
/*QUAKED mp_dd_spawn_attacker_start (0.0 1.0 0.0) (-16 -16 0) (16 16 72)
Attacking players spawn randomly at one of these positions at the beginning of a round.*/
/*QUAKED mp_dd_spawn_defender_start (1.0 0.0 0.0) (-16 -16 0) (16 16 72)
Defending players spawn randomly at one of these positions at the beginning of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 1, 0, 9 );
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
registerScoreLimitDvar( level.gameType, 0, 0, 500 );
registerRoundLimitDvar( level.gameType, 3, 0, 12 );
registerWinLimitDvar( level.gameType, 2, 0, 12 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.objectiveBased = true;
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onDeadEvent = ::onDeadEvent;
level.onTimeLimit = ::onTimeLimit;
level.onNormalDeath = ::onNormalDeath;
level.initGametypeAwards = ::initGametypeAwards;
level.dd = true;
level.bombsPlanted = 0;
level.ddBombModel = []
setBombTimerDvar();
makeDvarServerInfo( "ui_bombtimer_a", -1 );
makeDvarServerInfo( "ui_bombtimer_b", -1 );
game["dialog"]["gametype"] = "demolition";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "obj_destroy";
game["dialog"]["defense_obj"] = "obj_defend";
}
onPrecacheGameType()
{
game["bomb_dropped_sound"] = "mp_war_objective_lost";
game["bomb_recovered_sound"] = "mp_war_objective_taken";
precacheShader("waypoint_bomb");
precacheShader("hud_suitcase_bomb");
precacheShader("waypoint_target");
precacheShader("waypoint_target_a");
precacheShader("waypoint_target_b");
precacheShader("waypoint_defend");
precacheShader("waypoint_defend_a");
precacheShader("waypoint_defend_b");
precacheShader("waypoint_defuse_a");
precacheShader("waypoint_defuse_b");
precacheShader("waypoint_target");
precacheShader("waypoint_target_a");
precacheShader("waypoint_target_b");
precacheShader("waypoint_defend");
precacheShader("waypoint_defend_a");
precacheShader("waypoint_defend_b");
precacheShader("waypoint_defuse");
precacheShader("waypoint_defuse_a");
precacheShader("waypoint_defuse_b");
precacheString( &"MP_EXPLOSIVES_RECOVERED_BY" );
precacheString( &"MP_EXPLOSIVES_DROPPED_BY" );
precacheString( &"MP_EXPLOSIVES_PLANTED_BY" );
precacheString( &"MP_EXPLOSIVES_DEFUSED_BY" );
precacheString( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
precacheString( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
precacheString( &"MP_CANT_PLANT_WITHOUT_BOMB" );
precacheString( &"MP_PLANTING_EXPLOSIVE" );
precacheString( &"MP_DEFUSING_EXPLOSIVE" );
precacheString( &"MP_BOMB_A_TIMER" );
precacheString( &"MP_BOMB_B_TIMER" );
precacheString( &"MP_BOMBSITE_IN_USE" );
}
onStartGameType()
{
if ( !isDefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
level.useStartSpawns = true;
setClientNameMode( "manual_change" );
game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
game["strings"]["bomb_defused"] = &"MP_BOMB_DEFUSED";
precacheString( game["strings"]["target_destroyed"] );
precacheString( game["strings"]["bomb_defused"] );
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
setObjectiveText( game["attackers"], &"OBJECTIVES_DD_ATTACKER" );
setObjectiveText( game["defenders"], &"OBJECTIVES_DD_DEFENDER" );
if ( level.splitscreen )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_DD_ATTACKER" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_DD_DEFENDER" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_DD_ATTACKER_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_DD_DEFENDER_SCORE" );
}
setObjectiveHintText( game["attackers"], &"OBJECTIVES_DD_ATTACKER_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_DD_DEFENDER_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender_a", true );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender_b", true );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dd_spawn_defender_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker_a", true );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker_b", true );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dd_spawn_attacker_start" );
level.spawn_defenders = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender" );
level.spawn_defenders_a = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_a" );
level.spawn_defenders_a = array_combine( level.spawn_defenders, level.spawn_defenders_a );
level.spawn_defenders_b = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_b" );
level.spawn_defenders_b = array_combine( level.spawn_defenders, level.spawn_defenders_b );
level.spawn_attackers = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker" );
level.spawn_attackers_a = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_a" );
level.spawn_attackers_a = array_combine( level.spawn_attackers, level.spawn_attackers_a );
level.spawn_attackers_b = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_b" );
level.spawn_attackers_b = array_combine( level.spawn_attackers, level.spawn_attackers_b );
level.spawn_defenders_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_start" );
level.spawn_attackers_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_start" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
level.aPlanted = false;
level.bPlanted = false;
setMapCenter( level.mapCenter );
maps\mp\gametypes\_rank::registerScoreInfo( "win", 2 );
maps\mp\gametypes\_rank::registerScoreInfo( "loss", 1 );
maps\mp\gametypes\_rank::registerScoreInfo( "tie", 1.5 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "plant", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 100 );
thread updateGametypeDvars();
thread waitToProcess();
winlimit = getWatchedDvar("winlimit");
allowed[0] = "dd";
allowed[1] = "bombzone";
allowed[2] = "blocker";
maps\mp\gametypes\_gameobjects::main(allowed);
thread bombs();
}
waitToProcess()
{
level endon( "game_end" );
for ( ;; )
{
if ( level.inGracePeriod == 0 )
break;
wait ( 0.05 );
}
level.useStartSpawns = false;
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( level.useStartSpawns )
{
if ( spawnteam == game["attackers"] )
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_attackers_start);
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_defenders_start);
}
else
{
if (spawnteam == game["attackers"] )
{
if ( (!level.aPlanted && !level.bPlanted) )
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
else if ( level.aPlanted && !level.bPlanted )
spawnPoints = level.spawn_attackers_a;
else if ( level.bPlanted && !level.aPlanted )
spawnPoints = level.spawn_attackers_b;
else
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
else
{
if ( (!level.aPlanted && !level.bPlanted) )
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
else if ( level.aPlanted && !level.bPlanted )
spawnPoints = level.spawn_defenders_a;
else if ( level.bPlanted && !level.aPlanted )
spawnPoints = level.spawn_defenders_b;
else
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
}
assert( isDefined(spawnpoint) );
return spawnpoint;
}
onSpawnPlayer()
{
if ( self.pers["team"] == game["attackers"] )
{
self.isPlanting = false;
self.isDefusing = false;
self.isBombCarrier = true;
if ( level.splitscreen )
{
self.carryIcon = createIcon( "hud_suitcase_bomb", 33, 33 );
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", 0, -78 );
self.carryIcon.alpha = 0.75;
}
else
{
self.carryIcon = createIcon( "hud_suitcase_bomb", 50, 50 );
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -90, -65 );
self.carryIcon.alpha = 0.75;
}
}
else
{
self.isPlanting = false;
self.isDefusing = false;
self.isBombCarrier = false;
if ( isDefined( self.carryIcon ) )
{
self.carryIcon Destroy();
}
}
level notify ( "spawned_player" );
}
dd_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
onDeadEvent( team )
{
if ( level.bombExploded || level.bombDefused )
return;
if ( team == "all" )
{
if ( level.bombPlanted )
dd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
else
dd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["attackers"] )
{
if ( level.bombPlanted )
return;
level thread dd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
level thread dd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
team = victim.team;
if ( game["state"] == "postgame" && (victim.team == game["defenders"] || !level.bombPlanted) )
attacker.finalKill = true;
if ( victim.isPlanting )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
}
else if ( victim.isDefusing )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
}
}
onTimeLimit()
{
dd_endGame( game["defenders"], game["strings"]["time_limit_reached"] );
}
updateGametypeDvars()
{
level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
level.bombTimer = dvarIntValue( "bombtimer", 45, 1, 300 );
level.ddTimeToAdd = dvarFloatValue( "addtime", 2, 0, 5 );; //how much time is added to the match when a target is destroyed
}
bombs()
{
level.bombPlanted = false;
level.bombDefused = false;
level.bombExploded = 0;
level.bombZones = [];
bombZones = getEntArray( "bombzone", "targetname" );
for ( index = 0; index < bombZones.size; index++ )
{
trigger = bombZones[index];
visuals = getEntArray( bombZones[index].target, "targetname" );
bombZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,64) );
bombZone maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
bombZone maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
bombZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
bombZone maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
bombZone maps\mp\gametypes\_gameobjects::setKeyObject( level.ddBomb );
label = bombZone maps\mp\gametypes\_gameobjects::getLabel();
bombZone.label = label;
bombZone.index = index;
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + label );
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + label );
bombZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
bombZone.onBeginUse = ::onBeginUse;
bombZone.onEndUse = ::onEndUse;
bombZone.onUse = ::onUseObject;
bombZone.onCantUse = ::onCantUse;
bombZone.useWeapon = "briefcase_bomb_mp";
bombZone.visuals[0].killCamEnt = spawn( "script_model", bombZone.visuals[0].origin + (0,0,128) );
for ( i = 0; i < visuals.size; i++ )
{
if ( isDefined( visuals[i].script_exploder ) )
{
bombZone.exploderIndex = visuals[i].script_exploder;
break;
}
}
level.bombZones[level.bombZones.size] = bombZone;
bombZone.bombDefuseTrig = getent( visuals[0].target, "targetname" );
assert( isdefined( bombZone.bombDefuseTrig ) );
bombZone.bombDefuseTrig.origin += (0,0,-10000);
bombZone.bombDefuseTrig.label = label;
}
for ( index = 0; index < level.bombZones.size; index++ )
{
array = [];
for ( otherindex = 0; otherindex < level.bombZones.size; otherindex++ )
{
if ( otherindex != index )
array[ array.size ] = level.bombZones[otherindex];
}
level.bombZones[index].otherBombZones = array;
}
}
onUseObject( player )
{
team = player.pers["team"];
otherTeam = level.otherTeam[team];
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
player notify ( "bomb_planted" );
player playSound( "mp_bomb_plant" );
thread teamPlayerCardSplash( "callout_bombplanted", player );
//iPrintLn( &"MP_EXPLOSIVES_PLANTED_BY", player );
leaderDialog( "bomb_planted" );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
player incPlayerStat( "bombsplanted", 1 );
player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
player.bombPlantedTime = getTime();
level thread bombPlanted( self, player );
level.bombOwner = player;
self.useWeapon = "briefcase_bomb_defuse_mp";
self setUpForDefusing();
}
else // defused the bomb
{
self thread bombHandler( player, "defused" );
}
}
resetBombZone()
{
self maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
self maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
self maps\mp\gametypes\_gameobjects::setKeyObject( level.ddBomb );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + self.label );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self.useWeapon = "briefcase_bomb_mp";
}
setUpForDefusing()
{
self maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
self maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
self maps\mp\gametypes\_gameobjects::setKeyObject( undefined );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" + self.label );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
}
onBeginUse( player )
{
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
player playSound( "mp_bomb_defuse" );
player.isDefusing = true;
bestDistance = 9000000;
closestBomb = undefined;
if ( isDefined( level.ddBombModel ) )
{
foreach ( bomb in level.ddBombModel )
{
if ( !isDefined( bomb ) )
continue;
dist = distanceSquared( player.origin, bomb.origin );
if ( dist < bestDistance )
{
bestDistance = dist;
closestBomb = bomb;
}
}
assert( isDefined(closestBomb) );
player.defusing = closestBomb;
closestBomb hide();
}
}
else
{
player.isPlanting = true;
}
}
onEndUse( team, player, result )
{
if ( !isDefined( player ) )
return;
if ( isAlive( player ) )
{
player.isDefusing = false;
player.isPlanting = false;
}
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
if ( isDefined( player.defusing ) && !result )
{
player.defusing show();
}
}
}
onCantUse( player )
{
player iPrintLnBold( &"MP_BOMBSITE_IN_USE" );
}
onReset()
{
}
bombPlanted( destroyedObj, player )
{
destroyedObj endon( "defused" );
level.bombsPlanted += 1;
self setBombTimerDvar();
maps\mp\gametypes\_gamelogic::pauseTimer();
level.timePauseStart = getTime();
level.timeLimitOverride = true;
level.bombPlanted = true;
level.destroyedObject = destroyedObj;
if ( level.destroyedObject.label == "_a" )
level.aPlanted = true;
else
level.bPlanted = true;
level.destroyedObject.bombPlanted = true;
destroyedObj.visuals[0] thread playDemolitionTickingSound(destroyedObj);
level.tickingObject = destroyedObj.visuals[0];
self dropBombModel( player, destroyedObj.label );
destroyedObj.bombDefused = false;
destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" );
destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
destroyedObj setUpForDefusing();
destroyedObj BombTimerWait(destroyedObj); //waits for bomb to explode!
destroyedObj thread bombHandler( player ,"explode" );
}
bombHandler( player, destType )
{
self.visuals[0] notify( "stopTicking" );
level.bombsPlanted -= 1;
if ( self.label == "_a" )
level.aPlanted = false;
else
level.bPlanted = false;
self.bombPlanted = 0;
self restartTimer();
self setBombTimerDvar();
setDvar( "ui_bombtimer" + self.label, -1 );
//self maps\mp\gametypes\_gameobjects::updateTimer( 0, false );
if ( level.gameEnded )
return;
if ( destType == "explode" )
{
level.bombExploded += 1;
explosionOrigin = self.curorigin;
level.ddBombModel[ self.label ] Delete();
if ( isdefined( player ) )
{
self.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player );
player incPlayerStat( "targetsdestroyed", 1 );
}
else
{
self.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
}
rot = randomfloat(360);
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
triggerFx( explosionEffect );
PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
earthquake( 0.75, 2.0, explosionOrigin, 2000 );
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
if ( isDefined( self.exploderIndex ) )
exploder( self.exploderIndex );
self maps\mp\gametypes\_gameobjects::disableObject();
if ( level.bombExploded < 2 )
{
foreach ( splashPlayer in level.players )
splashPlayer thread maps\mp\gametypes\_hud_message::SplashNotify( "time_added" );
}
wait 2;
if ( level.bombExploded > 1 )
dd_endGame( game["attackers"], game["strings"]["target_destroyed"] );
else
level thread teamPlayerCardSplash( "callout_time_added", player );
}
else //defused
{
player notify ( "bomb_defused" );
self notify( "defused" );
// if ( !level.hardcoreMode )
// iPrintLn( &"MP_EXPLOSIVES_DEFUSED_BY", player );
leaderDialog( "bomb_defused" );
level thread teamPlayerCardSplash( "callout_bombdefused", player );
level thread bombDefused( self );
self resetBombzone();
if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 4000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
else
player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
player incPlayerStat( "bombsdefused", 1 );
player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origIn );
}
}
playDemolitionTickingSound( site )
{
self endon("death");
self endon("stopTicking");
level endon("game_ended");
while(1)
{
self playSound( "ui_mp_suitcasebomb_timer" );
if ( !isDefined( site.waitTime ) || site.waitTime > 10 )
wait 1.0;
else if ( isDefined( site.waitTime ) && site.waitTime > 5 )
wait 0.5;
else
wait 0.25;
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
}
}
setBombTimerDvar()
{
println( "BOMBS PLANTED: " + level.bombsPlanted );
if ( level.bombsPlanted == 1 )
setDvar( "ui_bomb_timer", 2 );
else if ( level.bombsPlanted == 2 )
setDvar( "ui_bomb_timer", 3 );
else
setDvar( "ui_bomb_timer", 0 );
}
dropBombModel( player, site )
{
trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000), false, player );
tempAngle = randomfloat( 360 );
forward = (cos( tempAngle ), sin( tempAngle ), 0);
forward = vectornormalize( forward - common_scripts\utility::vector_multiply( trace["normal"], vectordot( forward, trace["normal"] ) ) );
dropAngles = vectortoangles( forward );
level.ddBombModel[ site ] = spawn( "script_model", trace["position"] );
level.ddBombModel[ site ].angles = dropAngles;
level.ddBombModel[ site ] setModel( "prop_suitcase_bomb" );
}
restartTimer()
{
if ( level.bombsPlanted <= 0 )
{
maps\mp\gametypes\_gamelogic::resumeTimer();
level.timePaused = ( getTime() - level.timePauseStart ) ;
level.timeLimitOverride = false;
}
}
BombTimerWait(siteLoc)
{
level endon("game_ended");
level endon("bomb_defused" + siteLoc.label );
siteLoc.waitTime = level.bombTimer;
while ( siteLoc.waitTime >= 0 )
{
siteLoc.waitTime--;
setDvar( "ui_bombtimer" + siteLoc.label, siteLoc.waitTime );
//self maps\mp\gametypes\_gameobjects::updateTimer( waitTime, true );
if ( siteLoc.waitTime >= 0 )
wait( 1 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
}
}
bombDefused( siteDefused )
{
level.tickingObject maps\mp\gametypes\_gamelogic::stopTickingSound();
siteDefused.bombDefused = true;
self setBombTimerDvar();
setDvar( "ui_bombtimer" + siteDefused.label, -1 );
level notify("bomb_defused" + siteDefused.label);
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
}
+100
View File
@@ -0,0 +1,100 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Deathmatch
Objective: Score points by eliminating other players
Map ends: When one player reaches the score limit, or time limit is reached
Respawning: No wait / Away from other players
Level requirements
------------------
Spawnpoints:
classname mp_dm_spawn
All players spawn from these. The spawnpoint chosen is dependent on the current locations of enemies at the time of spawn.
Players generally spawn away from enemies.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
*/
/*QUAKED mp_dm_spawn (1.0 0.5 0.0) (-16 -16 0) (16 16 72)
Players spawn away from enemies at one of these positions.*/
main()
{
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 1000, 0, 5000 );
registerWinLimitDvar( level.gameType, 1, 0, 5000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
game["dialog"]["gametype"] = "freeforall";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
}
onStartGameType()
{
setClientNameMode("auto_change");
setObjectiveText( "allies", &"OBJECTIVES_DM" );
setObjectiveText( "axis", &"OBJECTIVES_DM" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_DM" );
setObjectiveScoreText( "axis", &"OBJECTIVES_DM" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_DM_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_DM_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_DM_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_DM_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_dm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_dm_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = "dm";
maps\mp\gametypes\_gameobjects::main(allowed);
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 10 );
maps\mp\gametypes\_rank::registerScoreInfo( "suicide", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "teamkill", 0 );
level.QuickMessageToAll = true;
}
getSpawnPoint()
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( self.pers["team"] );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_DM( spawnPoints );
return spawnPoint;
}
+968
View File
@@ -0,0 +1,968 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Domination
Objective: Capture all the flags by touching them
Map ends: When one team captures all the flags, or time limit is reached
Respawning: No wait / Near teammates
Level requirements
------------------
Spawnpoints:
classname mp_tdm_spawn
All players spawn from these. The spawnpoint chosen is dependent on the current locations of owned flags, teammates and
enemies at the time of spawn. Players generally spawn behind their teammates relative to the direction of enemies.
Optionally, give a spawnpoint a script_linkto to specify which flag it "belongs" to (see Flag Descriptors).
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
Flags:
classname trigger_radius
targetname flag_primary or flag_secondary
Flags that need to be captured to win. Primary flags take time to capture; secondary flags are instant.
Flag Descriptors:
classname script_origin
targetname flag_descriptor
Place one flag descriptor close to each flag. Use the script_linkname and script_linkto properties to say which flags
it can be considered "adjacent" to in the level. For instance, if players have a primary path from flag1 to flag2, and
from flag2 to flag3, flag2 would have a flag_descriptor with these properties:
script_linkname flag2
script_linkto flag1 flag3
Set scr_domdebug to 1 to see flag connections and what spawnpoints are considered connected to each flag.
*/
/*QUAKED mp_dom_spawn (0.5 0.5 1.0) (-16 -16 0) (16 16 72)
Players spawn near their flags at one of these positions.*/
/*QUAKED mp_dom_spawn_axis_start (1.0 0.0 1.0) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_dom_spawn_allies_start (0.0 1.0 1.0) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 30, 0, 1440 );
registerScoreLimitDvar( level.gameType, 300, 0, 1000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.teamBased = true;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onPlayerKilled = ::onPlayerKilled;
level.onPrecacheGameType = ::onPrecacheGameType;
level.initGametypeAwards = ::initGametypeAwards;
level.onSpawnPlayer = ::onSpawnPlayer;
game["dialog"]["gametype"] = "domination";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "capture_objs";
game["dialog"]["defense_obj"] = "capture_objs";
}
onPrecacheGameType()
{
precacheShader( "waypoint_captureneutral" );
precacheShader( "waypoint_capture" );
precacheShader( "waypoint_defend" );
precacheShader( "waypoint_captureneutral_a" );
precacheShader( "waypoint_capture_a" );
precacheShader( "waypoint_defend_a" );
precacheShader( "waypoint_captureneutral_b" );
precacheShader( "waypoint_capture_b" );
precacheShader( "waypoint_defend_b" );
precacheShader( "waypoint_captureneutral_c" );
precacheShader( "waypoint_capture_c" );
precacheShader( "waypoint_defend_c" );
precacheShader( "waypoint_captureneutral" );
precacheShader( "waypoint_capture" );
precacheShader( "waypoint_defend" );
precacheShader( "waypoint_captureneutral_a" );
precacheShader( "waypoint_capture_a" );
precacheShader( "waypoint_defend_a" );
precacheShader( "waypoint_captureneutral_b" );
precacheShader( "waypoint_capture_b" );
precacheShader( "waypoint_defend_b" );
precacheShader( "waypoint_captureneutral_c" );
precacheShader( "waypoint_capture_c" );
precacheShader( "waypoint_defend_c" );
}
onStartGameType()
{
setObjectiveText( "allies", &"OBJECTIVES_DOM" );
setObjectiveText( "axis", &"OBJECTIVES_DOM" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_DOM" );
setObjectiveScoreText( "axis", &"OBJECTIVES_DOM" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_DOM_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_DOM_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_DOM_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_DOM_HINT" );
setClientNameMode("auto_change");
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dom_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dom_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_dom_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_dom_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
level.spawn_all = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn" );
level.spawn_axis_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn_axis_start" );
level.spawn_allies_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn_allies_start" );
level.startPos["allies"] = level.spawn_allies_start[0].origin;
level.startPos["axis"] = level.spawn_axis_start[0].origin;
level.flagBaseFXid[ "allies" ] = loadfx( maps\mp\gametypes\_teams::getTeamFlagFX( "allies" ) );
level.flagBaseFXid[ "axis" ] = loadfx( maps\mp\gametypes\_teams::getTeamFlagFX( "axis" ) );
allowed[0] = "dom";
// allowed[1] = "hardpoint";
maps\mp\gametypes\_gameobjects::main(allowed);
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 10 );
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 150 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend_assist", 10 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault_assist", 10 );
thread domFlags();
thread updateDomScores();
}
getSpawnPoint()
{
spawnpoint = undefined;
if ( !level.useStartSpawns )
{
flagsOwned = 0;
enemyFlagsOwned = 0;
myTeam = self.pers["team"];
enemyTeam = getOtherTeam( myTeam );
for ( i = 0; i < level.flags.size; i++ )
{
team = level.flags[i] getFlagTeam();
if ( team == myTeam )
flagsOwned++;
else if ( team == enemyTeam )
enemyFlagsOwned++;
}
if ( flagsOwned == level.flags.size )
{
// own all flags! pretend we don't own the last one we got, so enemies can spawn there
enemyBestSpawnFlag = level.bestSpawnFlag[ getOtherTeam( self.pers["team"] ) ];
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all, getSpawnsBoundingFlag( enemyBestSpawnFlag ) );
}
else if ( flagsOwned > 0 )
{
// spawn near any flag we own that's nearish something we can capture
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all, getBoundaryFlagSpawns( myTeam ) );
}
else
{
// own no flags!
bestFlag = undefined;
if ( enemyFlagsOwned > 0 && enemyFlagsOwned < level.flags.size )
{
// there should be an unowned one to use
bestFlag = getUnownedFlagNearestStart( myTeam );
}
if ( !isdefined( bestFlag ) )
{
// pretend we still own the last one we lost
bestFlag = level.bestSpawnFlag[ self.pers["team"] ];
}
level.bestSpawnFlag[ self.pers["team"] ] = bestFlag;
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all, bestFlag.nearbyspawns );
}
}
if ( !isdefined( spawnpoint ) )
{
if (self.pers["team"] == "axis")
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_axis_start);
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_allies_start);
}
//spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all );
assert( isDefined(spawnpoint) );
return spawnpoint;
}
domFlags()
{
level.lastStatus["allies"] = 0;
level.lastStatus["axis"] = 0;
game["flagmodels"] = [];
game["flagmodels"]["neutral"] = "prop_flag_neutral";
game["flagmodels"]["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
game["flagmodels"]["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
precacheModel( game["flagmodels"]["neutral"] );
precacheModel( game["flagmodels"]["allies"] );
precacheModel( game["flagmodels"]["axis"] );
precacheString( &"MP_SECURING_POSITION" );
primaryFlags = getEntArray( "flag_primary", "targetname" );
secondaryFlags = getEntArray( "flag_secondary", "targetname" );
if ( (primaryFlags.size + secondaryFlags.size) < 2 )
{
printLn( "^1Not enough domination flags found in level!" );
maps\mp\gametypes\_callbacksetup::AbortLevel();
return;
}
level.flags = [];
for ( index = 0; index < primaryFlags.size; index++ )
level.flags[level.flags.size] = primaryFlags[index];
for ( index = 0; index < secondaryFlags.size; index++ )
level.flags[level.flags.size] = secondaryFlags[index];
level.domFlags = [];
for ( index = 0; index < level.flags.size; index++ )
{
trigger = level.flags[index];
if ( isDefined( trigger.target ) )
{
visuals[0] = getEnt( trigger.target, "targetname" );
}
else
{
visuals[0] = spawn( "script_model", trigger.origin );
visuals[0].angles = trigger.angles;
}
visuals[0] setModel( game["flagmodels"]["neutral"] );
domFlag = maps\mp\gametypes\_gameobjects::createUseObject( "neutral", trigger, visuals, (0,0,100) );
domFlag maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
domFlag maps\mp\gametypes\_gameobjects::setUseTime( 10.0 );
domFlag maps\mp\gametypes\_gameobjects::setUseText( &"MP_SECURING_POSITION" );
label = domFlag maps\mp\gametypes\_gameobjects::getLabel();
domFlag.label = label;
domFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
domFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
domFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_captureneutral" + label );
domFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" + label );
domFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
domFlag.onUse = ::onUse;
domFlag.onBeginUse = ::onBeginUse;
domFlag.onUseUpdate = ::onUseUpdate;
domFlag.onEndUse = ::onEndUse;
traceStart = visuals[0].origin + (0,0,32);
traceEnd = visuals[0].origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
upangles = vectorToAngles( trace["normal"] );
domFlag.baseeffectforward = anglesToForward( upangles );
domFlag.baseeffectright = anglesToRight( upangles );
domFlag.baseeffectpos = trace["position"];
// legacy spawn code support
level.flags[index].useObj = domFlag;
level.flags[index].adjflags = [];
level.flags[index].nearbyspawns = [];
domFlag.levelFlag = level.flags[index];
level.domFlags[level.domFlags.size] = domFlag;
}
// level.bestSpawnFlag is used as a last resort when the enemy holds all flags.
level.bestSpawnFlag = [];
level.bestSpawnFlag[ "allies" ] = getUnownedFlagNearestStart( "allies", undefined );
level.bestSpawnFlag[ "axis" ] = getUnownedFlagNearestStart( "axis", level.bestSpawnFlag[ "allies" ] );
flagSetup();
/#
thread domDebug();
#/
}
getUnownedFlagNearestStart( team, excludeFlag )
{
best = undefined;
bestdistsq = undefined;
for ( i = 0; i < level.flags.size; i++ )
{
flag = level.flags[i];
if ( flag getFlagTeam() != "neutral" )
continue;
distsq = distanceSquared( flag.origin, level.startPos[team] );
if ( (!isDefined( excludeFlag ) || flag != excludeFlag) && (!isdefined( best ) || distsq < bestdistsq) )
{
bestdistsq = distsq;
best = flag;
}
}
return best;
}
/#
domDebug()
{
while(1)
{
if (getdvar("scr_domdebug") != "1") {
wait 2;
continue;
}
while(1)
{
if (getdvar("scr_domdebug") != "1")
break;
// show flag connections and each flag's spawnpoints
for (i = 0; i < level.flags.size; i++) {
for (j = 0; j < level.flags[i].adjflags.size; j++) {
line(level.flags[i].origin, level.flags[i].adjflags[j].origin, (1,1,1));
}
for (j = 0; j < level.flags[i].nearbyspawns.size; j++) {
line(level.flags[i].origin, level.flags[i].nearbyspawns[j].origin, (.2,.2,.6));
}
if ( level.flags[i] == level.bestSpawnFlag["allies"] )
print3d( level.flags[i].origin, "allies best spawn flag" );
if ( level.flags[i] == level.bestSpawnFlag["axis"] )
print3d( level.flags[i].origin, "axis best spawn flag" );
}
wait .05;
}
}
}
#/
onBeginUse( player )
{
ownerTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
self.didStatusNotify = false;
if ( ownerTeam == "neutral" )
{
statusDialog( "securing"+self.label, player.pers["team"] );
self.objPoints[player.pers["team"]] thread maps\mp\gametypes\_objpoints::startFlashing();
return;
}
if ( ownerTeam == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::startFlashing();
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::startFlashing();
}
onUseUpdate( team, progress, change )
{
if ( progress > 0.05 && change && !self.didStatusNotify )
{
ownerTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
if ( ownerTeam == "neutral" )
{
statusDialog( "securing"+self.label, team );
}
else
{
statusDialog( "losing"+self.label, ownerTeam );
statusDialog( "securing"+self.label, team );
}
self.didStatusNotify = true;
}
}
statusDialog( dialog, team, forceDialog )
{
time = getTime();
if ( getTime() < level.lastStatus[team] + 5000 && (!isDefined( forceDialog ) || !forceDialog) )
return;
thread delayedLeaderDialog( dialog, team );
level.lastStatus[team] = getTime();
}
onEndUse( team, player, success )
{
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::stopFlashing();
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::stopFlashing();
}
resetFlagBaseEffect()
{
if ( isdefined( self.baseeffect ) )
self.baseeffect delete();
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
if ( team != "axis" && team != "allies" )
return;
fxid = level.flagBaseFXid[ team ];
self.baseeffect = spawnFx( fxid, self.baseeffectpos, self.baseeffectforward, self.baseeffectright );
triggerFx( self.baseeffect );
}
onUse( player )
{
team = player.pers["team"];
oldTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
label = self maps\mp\gametypes\_gameobjects::getLabel();
//player logString( "flag captured: " + self.label );
self.captureTime = getTime();
self maps\mp\gametypes\_gameobjects::setOwnerTeam( team );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_capture" + label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_capture" + label );
self.visuals[0] setModel( game["flagmodels"][team] );
self resetFlagBaseEffect();
level.useStartSpawns = false;
assert( team != "neutral" );
if ( oldTeam == "neutral" )
{
otherTeam = getOtherTeam( team );
thread printAndSoundOnEveryone( team, otherTeam, undefined, undefined, "mp_war_objective_taken", undefined, player );
statusDialog( "secured"+self.label, team, true );
statusDialog( "enemy_has"+self.label, otherTeam, true );
}
else
{
thread printAndSoundOnEveryone( team, oldTeam, undefined, undefined, "mp_war_objective_taken", "mp_war_objective_lost", player );
// thread delayedLeaderDialogBothTeams( "obj_lost", oldTeam, "obj_taken", team );
if ( getTeamFlagCount( team ) == level.flags.size )
{
statusDialog( "secure_all", team );
statusDialog( "lost_all", oldTeam );
}
else
{
statusDialog( "secured"+self.label, team, true );
statusDialog( "lost"+self.label, oldTeam, true );
}
level.bestSpawnFlag[ oldTeam ] = self.levelFlag;
}
player notify( "objective", "captured" );
self thread giveFlagCaptureXP( self.touchList[team] );
}
giveFlagCaptureXP( touchList )
{
level endon ( "game_ended" );
players = getArrayKeys( touchList );
for ( index = 0; index < players.size; index++ )
{
player = touchList[players[index]].player;
player thread maps\mp\gametypes\_hud_message::SplashNotify( "capture", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) );
player thread updateCPM();
player thread maps\mp\gametypes\_rank::giveRankXP( "capture", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) * player getCapXPScale() );
printLn( maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) * player getCapXPScale() );
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
player incPlayerStat( "pointscaptured", 1 );
}
player = self maps\mp\gametypes\_gameobjects::getEarliestClaimPlayer();
level thread teamPlayerCardSplash( "callout_securedposition" + self.label, player );
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
}
delayedLeaderDialog( sound, team )
{
level endon ( "game_ended" );
wait .1;
WaitTillSlowProcessAllowed();
leaderDialog( sound, team );
}
delayedLeaderDialogBothTeams( sound1, team1, sound2, team2 )
{
level endon ( "game_ended" );
wait .1;
WaitTillSlowProcessAllowed();
leaderDialogBothTeams( sound1, team1, sound2, team2 );
}
updateDomScores()
{
level endon ( "game_ended" );
while ( !level.gameEnded )
{
domFlags = getOwnedDomFlags();
if ( domFlags.size )
{
for ( i = 1; i < domFlags.size; i++ )
{
domFlag = domFlags[i];
flagScore = getTime() - domFlag.captureTime;
for ( j = i - 1; j >= 0 && flagScore > (getTime() - domFlags[j].captureTime); j-- )
domFlags[j + 1] = domFlags[j];
domFlags[j + 1] = domFlag;
}
foreach( domFlag in domFlags )
{
team = domFlag maps\mp\gametypes\_gameobjects::getOwnerTeam();
assert( team == "allies" || team == "axis" );
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
}
}
// end the game if people aren't playing
if ( (((getTimePassed() / 1000) > 120 && domFlags.size < 2) || ((getTimePassed() / 1000) > 300 && domFlags.size < 3)) && matchMakingGame() )
{
thread maps\mp\gametypes\_gamelogic::endGame( "none", game["strings"]["time_limit_reached"] );
return;
}
wait ( 5.0 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
}
}
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId )
{
if ( !isPlayer( attacker ) || (!self.touchTriggers.size && !attacker.touchTriggers.size) || attacker.pers["team"] == self.pers["team"] )
return;
awardedAssault = false;
awardedDefend = false;
foreach ( trigger in self.touchTriggers )
{
// TODO: way to check for dom specific triggers
if ( !isDefined( trigger.useObj ) )
continue;
ownerTeam = trigger.useObj.ownerTeam;
team = self.pers["team"];
if ( ownerTeam == "neutral" )
continue;
if ( team == ownerTeam )
{
awardedAssault = true;
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "assault", maps\mp\gametypes\_rank::getScoreInfoValue( "assault" ) );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "assault" );
maps\mp\gametypes\_gamescore::givePlayerScore( "assault", attacker );
thread maps\mp\_matchdata::logKillEvent( killId, "defending" );
}
else
{
awardedDefend = true;
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "defend", maps\mp\gametypes\_rank::getScoreInfoValue( "defend" ) );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "defend" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defend", attacker );
thread maps\mp\_matchdata::logKillEvent( killId, "assaulting" );
}
}
foreach ( trigger in attacker.touchTriggers )
{
// TODO: way to check for dom specific triggers
if ( !isDefined( trigger.useObj ) )
continue;
ownerTeam = trigger.useObj.ownerTeam;
team = attacker.pers["team"];
if ( ownerTeam == "neutral" )
continue;
if ( team == ownerTeam )
{
if ( !awardedDefend )
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "defend", maps\mp\gametypes\_rank::getScoreInfoValue( "defend" ) );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "defend" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defend", attacker );
thread maps\mp\_matchdata::logKillEvent( killId, "assaulting" );
}
else
{
if ( !awardedAssault )
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "assault", maps\mp\gametypes\_rank::getScoreInfoValue( "assault" ) );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "assault" );
maps\mp\gametypes\_gamescore::givePlayerScore( "assault", attacker );
thread maps\mp\_matchdata::logKillEvent( killId, "defending" );
}
}
}
getOwnedDomFlags()
{
domFlags = [];
foreach ( domFlag in level.domFlags )
{
if ( domFlag maps\mp\gametypes\_gameobjects::getOwnerTeam() != "neutral" && isDefined( domFlag.captureTime ) )
domFlags[domFlags.size] = domFlag;
}
return domFlags;
}
getTeamFlagCount( team )
{
score = 0;
for (i = 0; i < level.flags.size; i++)
{
if ( level.domFlags[i] maps\mp\gametypes\_gameobjects::getOwnerTeam() == team )
score++;
}
return score;
}
getFlagTeam()
{
return self.useObj maps\mp\gametypes\_gameobjects::getOwnerTeam();
}
getBoundaryFlags()
{
// get all flags which are adjacent to flags that aren't owned by the same team
bflags = [];
for (i = 0; i < level.flags.size; i++)
{
for (j = 0; j < level.flags[i].adjflags.size; j++)
{
if (level.flags[i].useObj maps\mp\gametypes\_gameobjects::getOwnerTeam() != level.flags[i].adjflags[j].useObj maps\mp\gametypes\_gameobjects::getOwnerTeam() )
{
bflags[bflags.size] = level.flags[i];
break;
}
}
}
return bflags;
}
getBoundaryFlagSpawns(team)
{
spawns = [];
bflags = getBoundaryFlags();
for (i = 0; i < bflags.size; i++)
{
if (isdefined(team) && bflags[i] getFlagTeam() != team)
continue;
for (j = 0; j < bflags[i].nearbyspawns.size; j++)
spawns[spawns.size] = bflags[i].nearbyspawns[j];
}
return spawns;
}
getSpawnsBoundingFlag( avoidflag )
{
spawns = [];
for (i = 0; i < level.flags.size; i++)
{
flag = level.flags[i];
if ( flag == avoidflag )
continue;
isbounding = false;
for (j = 0; j < flag.adjflags.size; j++)
{
if ( flag.adjflags[j] == avoidflag )
{
isbounding = true;
break;
}
}
if ( !isbounding )
continue;
for (j = 0; j < flag.nearbyspawns.size; j++)
spawns[spawns.size] = flag.nearbyspawns[j];
}
return spawns;
}
// gets an array of all spawnpoints which are near flags that are
// owned by the given team, or that are adjacent to flags owned by the given team.
getOwnedAndBoundingFlagSpawns(team)
{
spawns = [];
for (i = 0; i < level.flags.size; i++)
{
if ( level.flags[i] getFlagTeam() == team )
{
// add spawns near this flag
for (s = 0; s < level.flags[i].nearbyspawns.size; s++)
spawns[spawns.size] = level.flags[i].nearbyspawns[s];
}
else
{
for (j = 0; j < level.flags[i].adjflags.size; j++)
{
if ( level.flags[i].adjflags[j] getFlagTeam() == team )
{
// add spawns near this flag
for (s = 0; s < level.flags[i].nearbyspawns.size; s++)
spawns[spawns.size] = level.flags[i].nearbyspawns[s];
break;
}
}
}
}
return spawns;
}
// gets an array of all spawnpoints which are near flags that are
// owned by the given team
getOwnedFlagSpawns(team)
{
spawns = [];
for (i = 0; i < level.flags.size; i++)
{
if ( level.flags[i] getFlagTeam() == team )
{
// add spawns near this flag
for (s = 0; s < level.flags[i].nearbyspawns.size; s++)
spawns[spawns.size] = level.flags[i].nearbyspawns[s];
}
}
return spawns;
}
flagSetup()
{
maperrors = [];
descriptorsByLinkname = [];
// (find each flag_descriptor object)
descriptors = getentarray("flag_descriptor", "targetname");
flags = level.flags;
for (i = 0; i < level.domFlags.size; i++)
{
closestdist = undefined;
closestdesc = undefined;
for (j = 0; j < descriptors.size; j++)
{
dist = distance(flags[i].origin, descriptors[j].origin);
if (!isdefined(closestdist) || dist < closestdist) {
closestdist = dist;
closestdesc = descriptors[j];
}
}
if (!isdefined(closestdesc)) {
maperrors[maperrors.size] = "there is no flag_descriptor in the map! see explanation in dom.gsc";
break;
}
if (isdefined(closestdesc.flag)) {
maperrors[maperrors.size] = "flag_descriptor with script_linkname \"" + closestdesc.script_linkname + "\" is nearby more than one flag; is there a unique descriptor near each flag?";
continue;
}
flags[i].descriptor = closestdesc;
closestdesc.flag = flags[i];
descriptorsByLinkname[closestdesc.script_linkname] = closestdesc;
}
if (maperrors.size == 0)
{
// find adjacent flags
for (i = 0; i < flags.size; i++)
{
if (isdefined(flags[i].descriptor.script_linkto))
adjdescs = strtok(flags[i].descriptor.script_linkto, " ");
else
adjdescs = [];
for (j = 0; j < adjdescs.size; j++)
{
otherdesc = descriptorsByLinkname[adjdescs[j]];
if (!isdefined(otherdesc) || otherdesc.targetname != "flag_descriptor") {
maperrors[maperrors.size] = "flag_descriptor with script_linkname \"" + flags[i].descriptor.script_linkname + "\" linked to \"" + adjdescs[j] + "\" which does not exist as a script_linkname of any other entity with a targetname of flag_descriptor (or, if it does, that flag_descriptor has not been assigned to a flag)";
continue;
}
adjflag = otherdesc.flag;
if (adjflag == flags[i]) {
maperrors[maperrors.size] = "flag_descriptor with script_linkname \"" + flags[i].descriptor.script_linkname + "\" linked to itself";
continue;
}
flags[i].adjflags[flags[i].adjflags.size] = adjflag;
}
}
}
// assign each spawnpoint to nearest flag
spawnpoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn" );
for (i = 0; i < spawnpoints.size; i++)
{
if (isdefined(spawnpoints[i].script_linkto)) {
desc = descriptorsByLinkname[spawnpoints[i].script_linkto];
if (!isdefined(desc) || desc.targetname != "flag_descriptor") {
maperrors[maperrors.size] = "Spawnpoint at " + spawnpoints[i].origin + "\" linked to \"" + spawnpoints[i].script_linkto + "\" which does not exist as a script_linkname of any entity with a targetname of flag_descriptor (or, if it does, that flag_descriptor has not been assigned to a flag)";
continue;
}
nearestflag = desc.flag;
}
else {
nearestflag = undefined;
nearestdist = undefined;
for (j = 0; j < flags.size; j++)
{
dist = distancesquared(flags[j].origin, spawnpoints[i].origin);
if (!isdefined(nearestflag) || dist < nearestdist)
{
nearestflag = flags[j];
nearestdist = dist;
}
}
}
nearestflag.nearbyspawns[nearestflag.nearbyspawns.size] = spawnpoints[i];
}
if (maperrors.size > 0)
{
println("^1------------ Map Errors ------------");
for(i = 0; i < maperrors.size; i++)
println(maperrors[i]);
println("^1------------------------------------");
error("Map errors. See above");
maps\mp\gametypes\_callbacksetup::AbortLevel();
return;
}
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "pointscaptured", 0, maps\mp\_awards::highestWins );
}
onSpawnPlayer()
{
}
updateCPM()
{
if ( !isDefined( self.CPM ) )
{
self.numCaps = 0;
self.CPM = 0;
}
self.numCaps++;
if ( getMinutesPassed() < 1 )
return;
self.CPM = self.numCaps / getMinutesPassed();
}
getCapXPScale()
{
if ( self.CPM < 4 )
return 1;
else
return 0.25;
}
+498
View File
@@ -0,0 +1,498 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Global Thermal Nuclear War
*/
/*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
registerScoreLimitDvar( level.gameType, 101, 0, 10000 );
registerRoundLimitDvar( level.gameType, 1, 0, 30 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerRoundSwitchDvar( level.gameType, 0, 0, 30 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onDeadEvent = ::onDeadEvent;
level.initGametypeAwards = ::initGametypeAwards;
level.onTimeLimit = ::onTimeLimit;
level.onNormalDeath = ::onNormalDeath;
level.gtnw = true;
game["dialog"]["gametype"] = "gtw";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "obj_destroy";
game["dialog"]["defense_obj"] = "obj_defend";
level thread onPlayerConnect();
}
gtnw_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
useBar = player createPrimaryProgressBar();
useBarText = player createPrimaryProgressBarText();
useBarText setText( &"MP_CAPTURING_NUKE" );
useBar.useTime = 100;
player.useBar = useBar;
player.useBar hideElem();
player.useBarText = useBarText;
player.useBarText hideElem();
}
}
onStartGameType()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( !isdefined( game["original_defenders"] ) )
game["original_defenders"] = game["defenders"];
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setClientNameMode("auto_change");
if ( level.splitscreen )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GTNW" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GTNW" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GTNW_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GTNW_SCORE" );
}
setObjectiveText( game["attackers"], &"OBJECTIVES_GTNW" );
setObjectiveText( game["defenders"], &"OBJECTIVES_GTNW" );
setObjectiveHintText( game["attackers"], &"OBJECTIVES_GTNW_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_GTNW_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_ctf_spawn_allies" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_ctf_spawn_axis" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
thread maps\mp\gametypes\_dev::init();
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 500 );
allowed[0] = "airdrop_pallet";
allowed[1] = "gtnw";
allowed[2] = "gtnw_zone";
maps\mp\gametypes\_gameobjects::main(allowed);
thread setupNukeSite();
}
onPrecacheGameType()
{
precacheShader("waypoint_defend");
precacheShader("waypoint_target");
precacheShader("waypoint_capture");
precacheShader("compass_waypoint_target");
precacheShader("compass_waypoint_defend");
precacheShader("compass_waypoint_capture");
precacheString( &"MP_CAPTURING_NUKE" );
return;
}
setupNukeSite()
{
level.lastStatus["allies"] = 0;
level.lastStatus["axis"] = 0;
nukeZone = getEnt( "gtnw_zone", "targetname" );
assertEx( isDefined( nukeZone ), "GTNW Zone prefab doesn't exist in this map" );
visuals = [];
nukeSite = maps\mp\gametypes\_gameobjects::createUseObject( "neutral", nukeZone, visuals, (0,0,100) );
nukeSite maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
nukeSite maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" );
nukeSite maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral" );
nukeSite maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" );
nukeSite maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
nukeSite.noUseBar = true;
nukeSite maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
nukeSite.onBeginUse = ::onBeginUse;
nukeSite.onEndUse = ::onEndUse;
level.nukeSite = nukeSite;
nukeSite thread scoreCounter();
}
getSpawnPoint()
{
if ( self.team == "axis" )
{
spawnTeam = game["attackers"];
}
else
{
spawnTeam = game["defenders"];
}
if ( level.inGracePeriod )
{
spawnPoints = getentarray("mp_ctf_spawn_" + spawnteam + "_start", "classname");
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
spawnFxDelay( fxid, pos, forward, right, delay )
{
wait delay;
effect = spawnFx( fxid, pos, forward, right );
triggerFx( effect );
}
onDeadEvent( team )
{
if ( ( isDefined( level.nukeIncoming ) && level.nukeIncoming ) || ( isDefined( level.nukeDetonated ) && level.nukeDetonated ) )
return;
if ( team == game["attackers"] )
{
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
level thread gtnw_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
level thread gtnw_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
initGametypeAwards()
{
return;
}
onTimeLimit()
{
if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
{
level thread overtimeThread();
}
else if( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
}
else if( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
}
}
overtimeThread( time )
{
level endon( "game_ended" );
level.inOvertime = true;
level thread disableSpawning( 5 );
level.endGameTime = 120;
time = level.endGameTime;
foreach ( player in level.players )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "gtnw_overtime" );
maps\mp\gametypes\_gamelogic::pauseTimer();
level.timeLimitOverride = true;
setGameEndTime( int( getTime() + ( level.endGameTime * 1000 ) ) );
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( time );
if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
}
else if ( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
}
else
{
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game["strings"]["time_limit_reached"] );
}
}
disableSpawning( waitTime )
{
level endon( "game_ended" );
wait ( 5 );
level.disableSpawning = true;
}
onBeginUse( player )
{
player.useBar showElem();
player.useBarText showElem();
return;
}
onEndUse( team, player, success )
{
player.useBar hideElem();
player.useBarText hideElem();
return;
}
scoreCounter()
{
level endon( "game_ended" );
self endon( "stop_counting" );
for ( ;; )
{
if ( !self.touchList["axis"].size && !self.touchlist["allies"].size )
{
setDvar( "ui_danger_team", "none" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" );
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "none" );
self updateHudElems();
wait 1;
continue;
}
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_capture" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_capture" );
if ( self.touchList["axis"].size > self.touchList["allies"].size )
{
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "axis" ) < 100 )
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( "axis", 1 );
self thread setUseBarScore( "axis" );
setDvar( "ui_danger_team", "allies" );
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "axis" );
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "axis" ) >= 100 )
{
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
activateNuke( "axis" );
self notify( "stop_counting" );
}
}
else if ( self.touchList["axis"].size < self.touchList["allies"].size )
{
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "allies" ) < 100 )
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( "allies", 1 );
self thread setUseBarScore( "allies" );
setDvar( "ui_danger_team", "axis" );
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "allies" );
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "allies" ) >= 100 )
{
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
activateNuke( "allies" );
self notify( "stop_counting" );
}
}
else
{
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" );
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "none" );
setDvar( "ui_danger_team", "contested" );
}
updateHudElems();
wait( 1 );
}
}
activateNuke( team )
{
self giveFlagCaptureXP( self.touchList[team] );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
bestTime = 99999999;
nukeOwner = undefined;
foreach( player in level.players )
{
if ( !isDefined( player ) )
continue;
player.useBar hideElem();
player.useBarText hideElem();
if ( player.team != team )
continue;
if ( !isDefined( self.touchlist[team][player.guid] ) )
continue;
timeStarted = self.touchlist[team][player.guid].startTime;
if ( timeStarted < bestTime )
{
nukeOwner = player;
bestTime = timeStarted;
}
}
assert( isDefined( nukeOwner ) );
nukeOwner maps\mp\killstreaks\_nuke::tryUseNuke( 1 );
}
giveFlagCaptureXP( touchList )
{
level endon ( "game_ended" );
wait .05;
WaitTillSlowProcessAllowed();
players = getArrayKeys( touchList );
for ( index = 0; index < players.size; index++ )
{
player = touchList[players[index]].player;
player thread maps\mp\gametypes\_hud_message::SplashNotify( "captured_nuke", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) );
player thread [[level.onXPEvent]]( "capture" );
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
}
}
setUseBarScore( team )
{
teamScore = getTeamScore( team );
foreach( player in level.players )
{
if ( !isDefined( player ) )
continue;
if ( player.team != team )
continue;
if ( !isDefined( self.touchlist[team][player.guid] ) )
continue;
//player thread maps\mp\gametypes\_rank::giveRankXP( "challenge",50 );
player.useBar updateBar( teamScore/100, 0 );
}
}
updateHudElems()
{
foreach( player in level.players )
{
if ( !isDefined( player ) )
continue;
if ( !isDefined( self.touchlist["axis"][player.guid] ) && !isDefined( self.touchlist["allies"][player.guid] ) )
{
player.useBar hideElem();
player.useBarText hideElem();
}
if ( isDefined( self.touchlist["axis"][player.guid] ) || isDefined( self.touchlist["allies"][player.guid] ) )
{
player.useBar showElem();
player.useBarText showElem();
}
}
}
onNormalDeath( victim, attacker, lifeId )
{
if ( !isDefined( level.inOvertime ) || !level.inOvertime )
return;
team = victim.team;
if ( game["state"] == "postgame" )
attacker.finalKill = true;
}
File diff suppressed because it is too large. Load diff
+558
View File
@@ -0,0 +1,558 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
One Flag CTF
*/
/*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
registerScoreLimitDvar( level.gameType, 1, 0, 10000 );
registerRoundLimitDvar( level.gameType, 0, 0, 30 );
registerWinLimitDvar( level.gameType, 4, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.objectiveBased = true;
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onPlayerKilled = ::onPlayerKilled;
level.onTimeLimit = ::onTimeLimit;
level.initGametypeAwards = ::initGametypeAwards;
game["dialog"]["gametype"] = "oneflag";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
if ( getdvar("scr_oneflag_returntime") == "" )
setdvar("scr_oneflag_returntime", "15");
level.flagReturnTime = getdvarint( "scr_oneflag_returntime" );
}
onPrecacheGameType()
{
precacheString(&"MP_FLAG_TAKEN_BY");
precacheString(&"MP_ENEMY_FLAG_TAKEN_BY");
precacheString(&"MP_FLAG_CAPTURED_BY");
precacheString(&"MP_ENEMY_FLAG_CAPTURED_BY");
//precacheString(&"MP_FLAG_RETURNED_BY");
precacheString(&"MP_FLAG_RETURNED");
precacheString(&"MP_ENEMY_FLAG_RETURNED");
precacheString(&"MP_YOUR_FLAG_RETURNING_IN");
precacheString(&"MP_ENEMY_FLAG_RETURNING_IN");
precacheString(&"MP_ENEMY_FLAG_DROPPED_BY");
precacheString( &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
}
onStartGameType()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( !isdefined( game["original_defenders"] ) )
game["original_defenders"] = game["defenders"];
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setClientNameMode("auto_change");
setObjectiveText( game["attackers"], &"OBJECTIVES_CTF" );
setObjectiveText( game["defenders"], &"OBJECTIVES_CTF" );
if ( level.splitscreen )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_SCORE" );
}
setObjectiveHintText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_ctf_spawn_allies" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_ctf_spawn_axis" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
thread maps\mp\gametypes\_dev::init();
allowed[0] = "ctf";
maps\mp\gametypes\_gameobjects::main(allowed);
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "pickup", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "return", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 500 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill_carrier", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend_assist", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault", 200 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault_assist", 40 );
thread oneflag_ctf();
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = getentarray("mp_ctf_spawn_" + spawnteam + "_start", "classname");
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onSpawnPlayer()
{
self.usingObj = undefined;
}
oneflag_ctf()
{
level.flagModel["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
level.icon2D["allies"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "allies" );
level.carryFlag["allies"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "allies" );
precacheModel( level.flagModel["allies"] );
precacheModel( level.carryFlag["allies"] );
level.flagModel["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
level.icon2D["axis"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "axis" );
level.carryFlag["axis"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "axis" );
precacheModel( level.flagModel["axis"] );
precacheModel( level.carryFlag["axis"] );
level.iconCapture3D = "waypoint_capture";
level.iconCapture2D = "compass_waypoint_capture";
level.iconDefend3D = "waypoint_defend";
level.iconDefend2D = "compass_waypoint_defend";
level.iconTarget3D = "waypoint_target";
level.iconTarget2D = "compass_waypoint_target";
precacheShader( level.icon2D["axis"] );
precacheShader( level.icon2D["allies"] );
precacheShader( level.iconCapture3D );
precacheShader( level.iconDefend3D );
precacheShader( level.iconCapture2D );
precacheShader( level.iconDefend2D );
precacheShader( level.iconTarget3D );
precacheShader( level.iconTarget2D );
precacheShader( "waypoint_kill" );
level.teamFlags[game["defenders"]] = createTeamFlag( game["defenders"] );
level.capZones[game["attackers"]] = createCapZone( game["attackers"] );
level.flagCaptured = false;
}
spawnFxDelay( fxid, pos, forward, right, delay )
{
wait delay;
effect = spawnFx( fxid, pos, forward, right );
triggerFx( effect );
}
createTeamFlag( team )
{
entityTeam = game["original_defenders"];
trigger = getEnt( "ctf_trig_" + entityTeam, "targetname" );
if ( !isDefined( trigger ) )
{
error( "No ctf_trig_" + entityTeam + " trigger found in map." );
return;
}
visuals[0] = getEnt( "ctf_flag_" + entityTeam, "targetname" );
if ( !isDefined( visuals[0] ) )
{
error( "No ctf_flag_" + entityTeam + " script_model found in map." );
return;
}
cloneTrigger = spawn( "trigger_radius", trigger.origin, 0, 96, trigger.height );
trigger delete();
trigger = cloneTrigger;
visuals[0] setModel( level.flagModel[team] );
teamFlag = maps\mp\gametypes\_gameobjects::createCarryObject( team, trigger, visuals, (0,0,85) );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "friendly", 15.0 );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "enemy", 0 );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "enemy", &"MP_CAPTURING_FLAG" );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "friendly", &"MP_RETURNING_FLAG" );
teamFlag maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
teamFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefend2D );
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefend3D );
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCapture2D );
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCapture3D );
teamFlag maps\mp\gametypes\_gameobjects::setCarryIcon( level.icon2D[team] );
teamFlag.allowWeapons = true;
teamFlag.onPickup = ::onPickup;
teamFlag.onPickupFailed = ::onPickup;
teamFlag.onDrop = ::onDrop;
teamFlag.onReset = ::onReset;
//teamFlag.onBeginUse = ::onBeginUse;
//teamFlag.onEndUse = ::onEndUse;
teamFlag.oldRadius = trigger.radius;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
return teamFlag;
}
createCapZone( team )
{
entityTeam = level.otherTeam[game["original_defenders"]];
trigger = getEnt( "ctf_zone_" + entityTeam, "targetname" );
if ( !isDefined( trigger ) )
{
error("No ctf_zone_" + entityTeam + " trigger found in map.");
return;
}
visuals[0] = getEnt( "ctf_flag_" + entityTeam, "targetname" );
if ( !isDefined( visuals[0] ) )
{
error( "No ctf_flag_" + entityTeam + " script_model found in map." );
return;
}
visuals[0] hide();
visuals = [];
capZone = maps\mp\gametypes\_gameobjects::createUseObject( team, trigger, visuals, (0,0,85) );
capZone maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
capZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
capZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconTarget2D );
capZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconTarget3D );
capZone maps\mp\gametypes\_gameobjects::setUseTime( 0 );
capZone maps\mp\gametypes\_gameobjects::setKeyObject( level.teamFlags[ getOtherTeam( team ) ] );
capZone.onUse = ::onUse;
capZone.onCantUse = ::onCantUse;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
return capZone;
}
onBeginUse( player )
{
team = player.pers["team"];
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
self.trigger.radius = 1024;
else
self.trigger.radius = self.oldRadius;
}
onEndUse( player, team, success )
{
self.trigger.radius = self.oldRadius;
}
onPickup( player )
{
team = player.pers["team"];
if ( team == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
{
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagreturn", maps\mp\gametypes\_rank::getScoreInfoValue( "pickup" ) );
player thread [[level.onXPEvent]]( "pickup" );
self thread returnFlag();
player incPlayerStat( "flagsreturned", 1 );
player thread maps\mp\_matchdata::logGameEvent( "return", player.origin );
}
else
{
player attachFlag();
level.capZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
//self maps\mp\gametypes\_gameobjects::setVisibleTeam( "enemy" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_kill" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconTarget2D );
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_TAKEN_BY", &"MP_FLAG_TAKEN_BY", "mp_obj_taken", "mp_enemy_obj_taken", player );
leaderDialog( "enemy_flag_taken", team, "status" );
leaderDialog( "flag_taken", otherteam, "status" );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagpickup", maps\mp\gametypes\_rank::getScoreInfoValue( "pickup" ) );
maps\mp\gametypes\_gamescore::givePlayerScore( "pickup", player );
player thread [[level.onXPEvent]]( "pickup" );
player incPlayerStat( "flagscarried", 1 );
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
}
}
returnFlag()
{
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
otherTeam = level.otherTeam[team];
self maps\mp\gametypes\_gameobjects::returnHome();
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
printAndSoundOnEveryone( team, getOtherTeam( team ), &"MP_FLAG_RETURNED", &"MP_ENEMY_FLAG_RETURNED", "mp_obj_returned", "mp_obj_returned", "" );
leaderDialog( "enemy_flag_returned", otherteam, "status" );
leaderDialog( "flag_returned", team, "status" );
}
onDrop( player )
{
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
otherTeam = level.otherTeam[team];
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefend3D );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefend2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCapture3D );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::allowCarry( "any" );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
if ( isDefined( player ) )
{
if ( isDefined( player.carryFlag ) )
player detachFlag();
printAndSoundOnEveryone( otherTeam, "none", &"MP_ENEMY_FLAG_DROPPED_BY", "", "mp_war_objective_lost", "", player );
}
else
{
playSoundOnPlayers( "mp_war_objective_lost", otherTeam );
}
leaderDialog( "enemy_flag_dropped", otherTeam, "status" );
leaderDialog( "flag_dropped", team, "status" );
}
onReset()
{
self notify ( "flag_reset" );
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
otherTeam = level.otherTeam[team];
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefend3D );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefend2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCapture3D );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
}
onUse( player )
{
team = player.pers["team"];
if ( team == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
leaderDialog( "enemy_flag_captured", team, "status" );
leaderDialog( "flag_captured", otherteam, "status" );
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
player thread [[level.onXPEvent]]( "capture" );
player incPlayerStat( "flagscaptured", 1 );
player notify( "objective", "captured" );
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
// round win here, no reset necessary
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_CAPTURED_BY", &"MP_FLAG_CAPTURED_BY", "mp_obj_captured", "mp_enemy_obj_captured", player );
thread flagCaptured( team, &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::allowCarry( "none" );
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::disableObject();
level.capZones[team] maps\mp\gametypes\_gameobjects::allowUse( "none" );
if ( isDefined( player.carryFlag ) )
player detachFlag();
}
flagCaptured( winningTeam, endReasonText )
{
maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
level.flagCaptured = true;
}
onTimeLimit()
{
if ( level.flagCaptured )
return;
// TODO: change to "Flag Defended" or some such
maps\mp\gametypes\_gamelogic::endGame( game["defenders"], game["strings"]["time_limit_reached"] );
}
onCantUse( player )
{
// player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId )
{
if ( isDefined( attacker ) && isPlayer( attacker ) && attacker.pers["team"] != self.pers["team"] )
{
if ( isDefined( attacker.carryFlag ) )
attacker incPlayerStat( "killsasflagcarrier", 1 );
if ( isDefined( self.carryFlag ) )
{
attacker thread [[level.onXPEvent]]( "kill_carrier" );
maps\mp\gametypes\_gamescore::givePlayerScore( "kill_carrier", attacker );
attacker incPlayerStat( "flagcarrierkills", 1 );
thread maps\mp\_matchdata::logKillEvent( killId, "carrying" );
self detachFlag();
}
}
}
attachFlag()
{
otherTeam = level.otherTeam[self.pers["team"]];
self attach( level.carryFlag[otherTeam], "J_spine4", true );
self.carryFlag = level.carryFlag[otherTeam];
}
detachFlag()
{
self detach( self.carryFlag, "J_spine4" );
self.carryFlag = undefined;
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "flagscaptured", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagsreturned", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasflagcarrier", 0, maps\mp\_awards::highestWins );
}
+907
View File
@@ -0,0 +1,907 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Sabotage
// ...etc...
*/
/*QUAKED mp_sab_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_sab_spawn_axis_planted (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_sab_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_sab_spawn_allies_planted (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_sab_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_sab_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
if ( getdvar("mapname") == "mp_background" )
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
//level.objectiveBased = true;
level.teamBased = true;
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 0, 0, 500 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
setOverTimeLimitDvar( 2 );
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onOneLeftEvent = ::onOneLeftEvent;
level.onTimeLimit = ::onTimeLimit;
level.onNormalDeath = ::onNormalDeath;
level.initGametypeAwards = ::initGametypeAwards;
game["dialog"]["gametype"] = "sabotage";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "capture_obj";
game["dialog"]["defense_obj"] = "capture_obj";
badtrig = getent( "sab_bomb_defuse_allies", "targetname" );
if ( isdefined( badtrig ) )
badtrig delete();
badtrig = getent( "sab_bomb_defuse_axis", "targetname" );
if ( isdefined( badtrig ) )
badtrig delete();
}
onPrecacheGameType()
{
game["bomb_dropped_sound"] = "mp_war_objective_lost";
game["bomb_recovered_sound"] = "mp_war_objective_taken";
precacheShader("waypoint_bomb");
precacheShader("waypoint_kill");
precacheShader("waypoint_bomb_enemy");
precacheShader("waypoint_defend");
precacheShader("waypoint_defuse");
precacheShader("waypoint_target");
precacheShader("waypoint_escort");
precacheShader("waypoint_bomb");
precacheShader("waypoint_defend");
precacheShader("waypoint_defuse");
precacheShader("waypoint_target");
precacheShader("hud_suitcase_bomb");
precacheString(&"MP_EXPLOSIVES_RECOVERED_BY");
precacheString(&"MP_EXPLOSIVES_DROPPED_BY");
precacheString(&"MP_EXPLOSIVES_PLANTED_BY");
precacheString(&"MP_EXPLOSIVES_DEFUSED_BY");
precacheString(&"MP_YOU_HAVE_RECOVERED_THE_BOMB");
precacheString(&"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES");
precacheString(&"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES");
precacheString(&"MP_PLANTING_EXPLOSIVE");
precacheString(&"MP_DEFUSING_EXPLOSIVE");
precacheString(&"MP_TARGET_DESTROYED");
precacheString(&"MP_NO_RESPAWN");
precacheString(&"MP_TIE_BREAKER");
precacheString(&"MP_NO_RESPAWN");
precacheString(&"MP_SUDDEN_DEATH");
}
onStartGameType()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
setClientNameMode("auto_change");
game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
game["strings"]["target_defended"] = &"MP_TARGET_DEDEFEND";
setObjectiveText( "allies", &"OBJECTIVES_SAB" );
setObjectiveText( "axis", &"OBJECTIVES_SAB" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_SAB" );
setObjectiveScoreText( "axis", &"OBJECTIVES_SAB" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_SAB_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_SAB_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_SAB_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_SAB_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sab_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sab_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_sab_spawn_allies" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_sab_spawn_axis" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints("allies", "mp_sab_spawn_allies_planted", true );
maps\mp\gametypes\_spawnlogic::addSpawnPoints("axis", "mp_sab_spawn_axis_planted", true );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
level.spawn_axis = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_axis" );
level.spawn_axis_planted = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_axis_planted" );
level.spawn_axis_planted = array_combine( level.spawn_axis_planted, level.spawn_axis );
level.spawn_allies = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_allies" );
level.spawn_allies_planted = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_allies_planted" );
level.spawn_allies_planted = array_combine( level.spawn_allies_planted, level.spawn_allies );
level.spawn_axis_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_axis_start" );
level.spawn_allies_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_allies_start" );
maps\mp\gametypes\_rank::registerScoreInfo( "plant", 200 );
maps\mp\gametypes\_rank::registerScoreInfo( "destroy", 1000 );
maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 150 );
allowed[0] = "sab";
maps\mp\gametypes\_gameobjects::main(allowed);
thread updateGametypeDvars();
thread sabotage();
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.useStartSpawns )
{
if (spawnteam == "axis")
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_axis_start);
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_allies_start);
}
else
{
if ( isDefined( level.bombplanted ) && level.bombplanted && ( isDefined( level.bombOwner ) && spawnTeam == level.bombOwner.team ) )
{
if (spawnteam == "axis")
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_axis_planted );
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_allies_planted );
}
else
{
if (spawnteam == "axis")
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam(level.spawn_axis);
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam(level.spawn_allies);
}
}
assert( isDefined(spawnpoint) );
return spawnpoint;
}
onSpawnPlayer()
{
self.isPlanting = false;
self.isDefusing = false;
self.isBombCarrier = false;
if( ( inOvertime() ) && !isDefined( self.otSpawned ) )
self thread printOTHint();
}
printOTHint()
{
self endon ( "disconnect" );
// give the "Overtime!" message time to show
wait ( 0.25 );
self thread maps\mp\gametypes\_hud_message::SplashNotify( "sudden_death" );
self.otSpawned = true;
}
updateGametypeDvars()
{
level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
level.bombTimer = dvarFloatValue( "bombtimer", 45, 1, 300 );
level.hotPotato = dvarIntValue( "hotpotato", 1, 0, 1 );
level.scoreMode = getWatchedDvar( "scorelimit" );
}
sabotage()
{
level.bombPlanted = false;
level.bombExploded = false;
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
trigger = getEnt( "sab_bomb_pickup_trig", "targetname" );
if ( !isDefined( trigger ) )
{
error( "No sab_bomb_pickup_trig trigger found in map." );
return;
}
visuals[0] = getEnt( "sab_bomb", "targetname" );
if ( !isDefined( visuals[0] ) )
{
error( "No sab_bomb script_model found in map." );
return;
}
precacheModel( "prop_suitcase_bomb" );
visuals[0] setModel( "prop_suitcase_bomb" );
level.sabBomb = maps\mp\gametypes\_gameobjects::createCarryObject( "neutral", trigger, visuals, (0,0,32) );
level.sabBomb maps\mp\gametypes\_gameobjects::allowCarry( "any" );
level.sabBomb maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_bomb" );
level.sabBomb maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_bomb" );
level.sabBomb maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
level.sabBomb maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
level.sabBomb maps\mp\gametypes\_gameobjects::setCarryIcon( "hud_suitcase_bomb" );
level.sabBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
level.sabBomb.objIDPingEnemy = true;
level.sabBomb.onPickup = ::onPickup;
level.sabBomb.onDrop = ::onDrop;
level.sabBomb.allowWeapons = true;
level.sabBomb.objPoints["allies"].archived = true;
level.sabBomb.objPoints["axis"].archived = true;
level.sabBomb.autoResetTime = 60.0;
if ( !isDefined( getEnt( "sab_bomb_axis", "targetname" ) ) )
{
error("No sab_bomb_axis trigger found in map.");
return;
}
if ( !isDefined( getEnt( "sab_bomb_allies", "targetname" ) ) )
{
error("No sab_bomb_allies trigger found in map.");
return;
}
if ( game["switchedsides"] )
{
level.bombZones["allies"] = createBombZone( "allies", getEnt( "sab_bomb_axis", "targetname" ) );
level.bombZones["axis"] = createBombZone( "axis", getEnt( "sab_bomb_allies", "targetname" ) );
}
else
{
level.bombZones["allies"] = createBombZone( "allies", getEnt( "sab_bomb_allies", "targetname" ) );
level.bombZones["axis"] = createBombZone( "axis", getEnt( "sab_bomb_axis", "targetname" ) );
}
if ( level.scoreMode )
level thread scoreThread();
if ( inOvertime() )
level thread overtimeThread();
}
getClosestSite()
{
if ( distance2d( self.origin, level.bombZones["allies"].trigger.origin ) < distance2d( self.origin, level.bombZones["axis"].trigger.origin ) )
return ( "allies" );
else
return ( "axis" );
}
distanceToSite( team )
{
return ( distance2d( self.origin, level.bombZones[team].trigger.origin ) );
}
scoreThread()
{
level.bombDistance = distance2d( getEnt( "sab_bomb_axis", "targetname" ) getOrigin(), getEnt( "sab_bomb_allies", "targetname" ) getOrigin() );
threatDistance = (level.bombDistance/2) - 384;
bombEnt = level.sabBomb.trigger;
// failsafe for bad bomb placement
if ( threatDistance > bombEnt distanceToSite( "allies" ) || threatDistance > bombEnt distanceToSite( "axis" ) )
threatDistance = bombEnt distanceToSite( bombEnt getClosestSite() ) - 128;
dangerTeam = "";
for ( ;; )
{
if ( isDefined( level.sabBomb.carrier ) )
bombEnt = level.sabBomb.carrier;
else
bombEnt = level.sabBomb.trigger;
lastDangerTeam = dangerTeam;
dangerTeam = "none";
if ( bombEnt distanceToSite( "allies" ) < threatDistance )
dangerTeam = level.bombZones["allies"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
else if ( bombEnt distanceToSite( "axis" ) < threatDistance )
dangerTeam = level.bombZones["axis"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
else if ( bombEnt distanceToSite( "allies" ) > level.bombDistance && bombEnt getClosestSite() != "allies" )
dangerTeam = level.bombZones["axis"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
else if ( bombEnt distanceToSite( "axis" ) > level.bombDistance && bombEnt getClosestSite() != "axis" )
dangerTeam = level.bombZones["allies"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
if ( dangerTeam != "none" )
{
if ( !level.bombPlanted || !getWatchedDvar( "scorelimit" ) || (level.bombPlanted && (maps\mp\gametypes\_gamescore::_getTeamScore( level.otherTeam[dangerTeam] ) < getWatchedDvar( "scorelimit" ) - 1)) )
{
maps\mp\gametypes\_gamescore::_setTeamScore( level.otherTeam[dangerTeam], maps\mp\gametypes\_gamescore::_getTeamScore( level.otherTeam[dangerTeam] ) + 1 );
maps\mp\gametypes\_gamescore::updateTeamScore( level.otherTeam[dangerTeam] );
}
}
if ( dangerTeam != lastDangerTeam && !level.bombExploded )
{
setDvar( "ui_danger_team", dangerTeam );
}
wait ( 2.5 );
}
}
createBombZone( team, trigger )
{
visuals = getEntArray( trigger.target, "targetname" );
bombZone = maps\mp\gametypes\_gameobjects::createUseObject( team, trigger, visuals, (0,0,64) );
bombZone resetBombsite();
bombZone.onUse = ::onUse;
bombZone.onBeginUse = ::onBeginUse;
bombZone.onEndUse = ::onEndUse;
bombZone.onCantUse = ::onCantUse;
bombZone.useWeapon = "briefcase_bomb_mp";
for ( i = 0; i < visuals.size; i++ )
{
if ( isDefined( visuals[i].script_exploder ) )
{
bombZone.exploderIndex = visuals[i].script_exploder;
break;
}
}
return bombZone;
}
onBeginUse( player )
{
// planted the bomb
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
player.isPlanting = true;
else
player.isDefusing = true;
}
onEndUse( team, player, result )
{
if ( !isAlive( player ) )
return;
player.isPlanting = false;
player.isDefusing = false;
}
onPickup( player )
{
level notify ( "bomb_picked_up" );
self.autoResetTime = 60.0;
level.useStartSpawns = false;
team = player.pers["team"];
if ( team == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
player playLocalSound( "mp_suitcase_pickup" );
player leaderDialogOnPlayer( "obj_destroy", "bomb" );
excludeList[0] = player;
leaderDialog( "bomb_taken", team, "bomb", excludeList );
if ( !level.splitscreen )
{
leaderDialog( "bomb_lost", otherTeam, "bomb" );
leaderDialog( "obj_defend", otherTeam, "bomb" );
}
player.isBombCarrier = true;
// recovered the bomb before abandonment timer elapsed
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
{
//printOnTeamArg( &"MP_EXPLOSIVES_RECOVERED_BY", team, player );
playSoundOnPlayers( game["bomb_recovered_sound"], team );
}
else
{
//printOnTeamArg( &"MP_EXPLOSIVES_RECOVERED_BY", team, player );
playSoundOnPlayers( game["bomb_recovered_sound"] );
}
self maps\mp\gametypes\_gameobjects::setOwnerTeam( team );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_kill" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_escort" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_escort" );
level.bombZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.bombZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
player incPlayerStat( "bombscarried", 1 );
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
}
onDrop( player )
{
if ( level.bombPlanted )
{
}
else
{
if ( isDefined( player ) )
printOnTeamArg( &"MP_EXPLOSIVES_DROPPED_BY", self maps\mp\gametypes\_gameobjects::getOwnerTeam(), player );
playSoundOnPlayers( game["bomb_dropped_sound"], self maps\mp\gametypes\_gameobjects::getOwnerTeam() );
thread abandonmentThink( 0.0 );
}
}
abandonmentThink( delay )
{
level endon ( "bomb_picked_up" );
wait ( delay );
if ( isDefined( self.carrier ) )
return;
if ( self maps\mp\gametypes\_gameobjects::getOwnerTeam() == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
// printOnTeamArg( &"MP_EXPLOSIVES_DROPPED_BY", otherTeam, &"MP_THE_ENEMY" );
playSoundOnPlayers( game["bomb_dropped_sound"], otherTeam );
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "neutral" );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_bomb" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_bomb" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
level.bombZones["allies"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.bombZones["axis"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
}
onUse( player )
{
team = player.pers["team"];
otherTeam = level.otherTeam[team];
// planted the bomb
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
player notify ( "bomb_planted" );
player playSound( "mp_bomb_plant" );
level thread teamPlayerCardSplash( "callout_bombplanted", player );
leaderDialog( "bomb_planted" );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
player incPlayerStat( "bombsplanted", 1 );
player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
player.bombPlantedTime = getTime();
//if ( !inOvertime() )
level thread bombPlanted( self, player.pers["team"] );
level.bombOwner = player;
level.sabBomb.autoResetTime = undefined;
level.sabBomb maps\mp\gametypes\_gameobjects::allowCarry( "none" );
level.sabBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.sabBomb maps\mp\gametypes\_gameobjects::setDropped();
self.useWeapon = "briefcase_bomb_defuse_mp";
self setUpForDefusing();
}
else // defused the bomb
{
player notify ( "bomb_defused" );
leaderDialog( "bomb_defused" );
level thread teamPlayerCardSplash( "callout_bombdefused", player );
if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 3000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
else
player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
player incPlayerStat( "bombsdefused", 1 );
player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origin );
if ( inOvertime() )
{
thread maps\mp\gametypes\_gamelogic::endGame( team, game["strings"]["target_destroyed"] );
return;
}
level thread bombDefused( self );
self resetBombsite();
level.sabBomb maps\mp\gametypes\_gameobjects::allowCarry( "any" );
level.sabBomb maps\mp\gametypes\_gameobjects::setPickedUp( player );
}
}
onCantUse( player )
{
player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
bombPlanted( destroyedObj, team )
{
level endon ( "overtime" );
maps\mp\gametypes\_gamelogic::pauseTimer();
level.bombPlanted = true;
level.timeLimitOverride = true;
level.scoreLimitOverride = true;
setDvar( "ui_bomb_timer", 1 );
// communicate timer information to menus
setGameEndTime( int( getTime() + (level.bombTimer * 1000) ) );
destroyedObj.visuals[0] thread maps\mp\gametypes\_gamelogic::playTickingSound();
starttime = gettime();
bombTimerWait();
setDvar( "ui_bomb_timer", 0 );
destroyedObj.visuals[0] maps\mp\gametypes\_gamelogic::stopTickingSound();
if ( !level.bombPlanted )
{
if ( level.hotPotato )
{
timePassed = (gettime() - starttime) / 1000;
level.bombTimer -= timePassed;
}
return;
}
explosionOrigin = level.sabBomb.visuals[0].origin;
level.bombExploded = true;
setDvar( "ui_danger_team", "BombExploded" );
if ( isdefined( level.bombowner ) )
{
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, level.bombowner );
level.bombowner incPlayerStat( "targetsdestroyed", 1 );
}
else
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
rot = randomfloat(360);
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
triggerFx( explosionEffect );
PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
earthquake( 0.75, 2.0, explosionOrigin, 2000 );
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
if ( isDefined( destroyedObj.exploderIndex ) )
exploder( destroyedObj.exploderIndex );
level.sabBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.bombZones["allies"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.bombZones["axis"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
setGameEndTime( 0 );
level.scoreLimitOverride = true;
if ( level.scoreMode )
maps\mp\gametypes\_gamescore::_setTeamScore( team, int( max( getWatchedDvar( "scorelimit" ), maps\mp\gametypes\_gamescore::_getTeamScore( level.otherTeam[team] ) + 1 ) ) );
else
maps\mp\gametypes\_gamescore::_setTeamScore( team, 1 );
maps\mp\gametypes\_gamescore::updateTeamScore( team );
if ( isDefined( level.bombOwner ) )
{
level.bombOwner thread maps\mp\gametypes\_rank::giveRankXP( "destroy" );
maps\mp\gametypes\_gamescore::givePlayerScore( "destroy", level.bombOwner );
level thread teamPlayerCardSplash( "callout_destroyed_objective", level.bombOwner );
}
wait 3;
thread maps\mp\gametypes\_gamelogic::endGame( team, game["strings"]["target_destroyed"] );
}
bombTimerWait()
{
level endon("bomb_defused");
level endon("overtime_ended");
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( level.bombTimer );
}
giveLastOnTeamWarning()
{
self endon("death");
self endon("disconnect");
level endon( "game_ended" );
self waitTillRecoveredHealth( 3 );
otherTeam = getOtherTeam( self.pers["team"] );
level thread teamPlayerCardSplash( "callout_lastteammemberalive", self, self.pers["team"] );
level thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
level notify ( "last_alive", self );
//self maps\mp\gametypes\_missions::lastManSD();
}
onTimeLimit()
{
if ( level.bombExploded )
return;
if( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
}
else if( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
}
else if( game["teamScores"]["axis"] == game["teamScores"]["allies"] )
{
if ( inOvertime() )
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game["strings"]["time_limit_reached"] );
else
thread maps\mp\gametypes\_gamelogic::endGame( "overtime", game["strings"]["time_limit_reached"] );
}
}
overtimeThread( time )
{
level endon( "game_ended" );
level.inOvertime = true;
wait ( 5.0 );
level.disableSpawning = true;
}
/*
overtimeThread()
{
level.inOvertime = getTime();
level notify ( "overtime" );
thread bombDistanceThread();
foreach ( player in level.players )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "sab_overtime" );
maps\mp\gametypes\_gamelogic::pauseTimer();
level.bombPlanted = true;
level.timeLimitOverride = true;
setDvar( "ui_bomb_timer", 1 );
// communicate timer information to menus
setGameEndTime( int( getTime() + (level.bombTimer * 1000) ) );
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( level.bombTimer );
setDvar( "ui_bomb_timer", 0 );
if ( isDefined( level.sabBomb.carrier ) )
{
explosionEnt = level.sabBomb.carrier;
}
else
{
explosionEnt = level.sabBomb.visuals[0];
}
level.bombExploded = true;
if ( isdefined( level.bombowner ) )
explosionEnt radiusDamage( explosionEnt.origin, 512, 200, 20, level.bombowner );
else
explosionEnt radiusDamage( explosionEnt.origin, 512, 200, 20 );
rot = randomfloat(360);
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionEnt.origin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
triggerFx( explosionEffect );
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionEnt.origin );
setGameEndTime( 0 );
team = getOtherTeam( level.dangerTeam );
wait 3;
//maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
maps\mp\gametypes\_gamelogic::endGame( team, game["strings"]["target_destroyed"] );
}
*/
bombDistanceThread()
{
level endon ( "game_ended" );
if ( cointoss() )
level.dangerTeam = "allies";
else
level.dangerTeam = "axis";
for ( ;; )
{
if ( isDefined( level.sabBomb.carrier ) )
bombEnt = level.sabBomb.carrier;
else
bombEnt = level.sabBomb.visuals[0];
if ( distance( bombEnt.origin, level.bombZones[getOtherTeam(level.dangerTeam)].visuals[0].origin ) < distance( bombEnt.origin, level.bombZones[level.dangerTeam].visuals[0].origin ) )
level.dangerTeam = getOtherTeam( level.dangerTeam );
wait ( 0.05 );
}
}
resetBombsite()
{
self maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
self maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
self maps\mp\gametypes\_gameobjects::setKeyObject( level.sabBomb );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
self.useWeapon = "briefcase_bomb_mp";
}
setUpForDefusing()
{
self maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
self maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
self maps\mp\gametypes\_gameobjects::setKeyObject( undefined );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
}
bombDefused( object )
{
setDvar( "ui_bomb_timer", 0 );
maps\mp\gametypes\_gamelogic::resumeTimer();
level.bombPlanted = false;
level.timeLimitOverride = false;
level.scoreLimitOverride = false;
level notify("bomb_defused");
}
onOneLeftEvent( team )
{
if ( level.bombExploded )
return;
lastPlayer = getLastLivingPlayer( team );
lastPlayer thread giveLastOnTeamWarning();
}
onNormalDeath( victim, attacker, lifeId, lifeId )
{
if ( victim.isPlanting )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
}
else if ( victim.isBombCarrier )
{
attacker incPlayerStat( "bombcarrierkills", 1 );
thread maps\mp\_matchdata::logKillEvent( lifeId, "carrying" );
}
else if ( victim.isDefusing )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
}
if ( attacker.isBombCarrier )
attacker incPlayerStat( "killsasbombcarrier", 1 );
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
}
+794
View File
@@ -0,0 +1,794 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
// Rallypoints should be destroyed on leaving your team/getting killed
// Compass icons need to be looked at
// Doesn't seem to be setting angle on spawn so that you are facing your rallypoint
/*
Search and Destroy
Attackers objective: Bomb one of 2 positions
Defenders objective: Defend these 2 positions / Defuse planted bombs
Round ends: When one team is eliminated, bomb explodes, bomb is defused, or roundlength time is reached
Map ends: When one team reaches the score limit, or time limit or round limit is reached
Respawning: Players remain dead for the round and will respawn at the beginning of the next round
Level requirements
------------------
Allied Spawnpoints:
classname mp_sd_spawn_attacker
Allied players spawn from these. Place at least 16 of these relatively close together.
Axis Spawnpoints:
classname mp_sd_spawn_defender
Axis players spawn from these. Place at least 16 of these relatively close together.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
Bombzones:
classname trigger_multiple
targetname bombzone
script_gameobjectname bombzone
script_bombmode_original <if defined this bombzone will be used in the original bomb mode>
script_bombmode_single <if defined this bombzone will be used in the single bomb mode>
script_bombmode_dual <if defined this bombzone will be used in the dual bomb mode>
script_team Set to allies or axis. This is used to set which team a bombzone is used by in dual bomb mode.
script_label Set to A or B. This sets the letter shown on the compass in original mode.
This is a volume of space in which the bomb can planted. Must contain an origin brush.
Bomb:
classname trigger_lookat
targetname bombtrigger
script_gameobjectname bombzone
This should be a 16x16 unit trigger with an origin brush placed so that it's center lies on the bottom plane of the trigger.
Must be in the level somewhere. This is the trigger that is used when defusing a bomb.
It gets moved to the position of the planted bomb model.
Level script requirements
-------------------------
Team Definitions:
game["attackers"] = "allies";
game["defenders"] = "axis";
This sets which team is attacking and which team is defending. Attackers plant the bombs. Defenders protect the targets.
Exploder Effects:
Setting script_noteworthy on a bombzone trigger to an exploder group can be used to trigger additional effects.
*/
/*QUAKED mp_sd_spawn_attacker (0.0 1.0 0.0) (-16 -16 0) (16 16 72)
Attacking players spawn randomly at one of these positions at the beginning of a round.*/
/*QUAKED mp_sd_spawn_defender (1.0 0.0 0.0) (-16 -16 0) (16 16 72)
Defending players spawn randomly at one of these positions at the beginning of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 3, 0, 9 );
registerTimeLimitDvar( level.gameType, 2.5, 0, 1440 );
registerScoreLimitDvar( level.gameType, 1, 0, 500 );
registerRoundLimitDvar( level.gameType, 0, 0, 12 );
registerWinLimitDvar( level.gameType, 4, 0, 12 );
registerNumLivesDvar( level.gameType, 1, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.objectiveBased = true;
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onPlayerKilled = ::onPlayerKilled;
level.onDeadEvent = ::onDeadEvent;
level.onOneLeftEvent = ::onOneLeftEvent;
level.onTimeLimit = ::onTimeLimit;
level.onNormalDeath = ::onNormalDeath;
level.initGametypeAwards = ::initGametypeAwards;
game["dialog"]["gametype"] = "searchdestroy";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "obj_destroy";
game["dialog"]["defense_obj"] = "obj_defend";
}
onPrecacheGameType()
{
game["bomb_dropped_sound"] = "mp_war_objective_lost";
game["bomb_recovered_sound"] = "mp_war_objective_taken";
precacheShader("waypoint_bomb");
precacheShader("hud_suitcase_bomb");
precacheShader("waypoint_target");
precacheShader("waypoint_target_a");
precacheShader("waypoint_target_b");
precacheShader("waypoint_defend");
precacheShader("waypoint_defend_a");
precacheShader("waypoint_defend_b");
precacheShader("waypoint_defuse");
precacheShader("waypoint_defuse_a");
precacheShader("waypoint_defuse_b");
precacheShader("waypoint_escort");
/*
precacheShader("waypoint_target");
precacheShader("waypoint_target_a");
precacheShader("waypoint_target_b");
precacheShader("waypoint_defend");
precacheShader("waypoint_defend_a");
precacheShader("waypoint_defend_b");
precacheShader("waypoint_defuse");
precacheShader("waypoint_defuse_a");
precacheShader("waypoint_defuse_b");
*/
precacheString( &"MP_EXPLOSIVES_RECOVERED_BY" );
precacheString( &"MP_EXPLOSIVES_DROPPED_BY" );
precacheString( &"MP_EXPLOSIVES_PLANTED_BY" );
precacheString( &"MP_EXPLOSIVES_DEFUSED_BY" );
precacheString( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
precacheString( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
precacheString( &"MP_CANT_PLANT_WITHOUT_BOMB" );
precacheString( &"MP_PLANTING_EXPLOSIVE" );
precacheString( &"MP_DEFUSING_EXPLOSIVE" );
}
onStartGameType()
{
if ( !isDefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setClientNameMode( "manual_change" );
game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
game["strings"]["bomb_defused"] = &"MP_BOMB_DEFUSED";
precacheString( game["strings"]["target_destroyed"] );
precacheString( game["strings"]["bomb_defused"] );
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
setObjectiveText( game["attackers"], &"OBJECTIVES_SD_ATTACKER" );
setObjectiveText( game["defenders"], &"OBJECTIVES_SD_DEFENDER" );
if ( level.splitscreen )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_SD_ATTACKER" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_SD_DEFENDER" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_SD_ATTACKER_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_SD_DEFENDER_SCORE" );
}
setObjectiveHintText( game["attackers"], &"OBJECTIVES_SD_ATTACKER_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_SD_DEFENDER_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sd_spawn_attacker" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sd_spawn_defender" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = "sd";
allowed[1] = "bombzone";
allowed[2] = "blocker";
maps\mp\gametypes\_gameobjects::main(allowed);
maps\mp\gametypes\_rank::registerScoreInfo( "win", 2 );
maps\mp\gametypes\_rank::registerScoreInfo( "loss", 1 );
maps\mp\gametypes\_rank::registerScoreInfo( "tie", 1.5 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "plant", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 100 );
thread updateGametypeDvars();
thread bombs();
}
getSpawnPoint()
{
if(self.pers["team"] == game["attackers"])
spawnPointName = "mp_sd_spawn_attacker";
else
spawnPointName = "mp_sd_spawn_defender";
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( spawnPointName );
assert( spawnPoints.size );
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
return spawnpoint;
}
onSpawnPlayer()
{
self.isPlanting = false;
self.isDefusing = false;
self.isBombCarrier = false;
if ( level.multiBomb && !isDefined( self.carryIcon ) && self.pers["team"] == game["attackers"] && !level.bombPlanted )
{
if ( level.splitscreen )
{
self.carryIcon = createIcon( "hud_suitcase_bomb", 33, 33 );
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", 0, -78 );
self.carryIcon.alpha = 0.75;
}
else
{
self.carryIcon = createIcon( "hud_suitcase_bomb", 50, 50 );
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -90, -65 );
self.carryIcon.alpha = 0.75;
}
}
level notify ( "spawned_player" );
}
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
{
thread checkAllowSpectating();
}
checkAllowSpectating()
{
wait ( 0.05 );
update = false;
if ( !level.aliveCount[ game["attackers"] ] )
{
level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
update = true;
}
if ( !level.aliveCount[ game["defenders"] ] )
{
level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
update = true;
}
if ( update )
maps\mp\gametypes\_spectating::updateSpectateSettings();
}
sd_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
onDeadEvent( team )
{
if ( level.bombExploded || level.bombDefused )
return;
if ( team == "all" )
{
if ( level.bombPlanted )
sd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
else
sd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["attackers"] )
{
if ( level.bombPlanted )
return;
level thread sd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
level thread sd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
onOneLeftEvent( team )
{
if ( level.bombExploded || level.bombDefused )
return;
lastPlayer = getLastLivingPlayer( team );
lastPlayer thread giveLastOnTeamWarning();
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
team = victim.team;
if ( game["state"] == "postgame" && (victim.team == game["defenders"] || !level.bombPlanted) )
attacker.finalKill = true;
if ( victim.isPlanting )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
}
else if ( victim.isBombCarrier )
{
attacker incPlayerStat( "bombcarrierkills", 1 );
thread maps\mp\_matchdata::logKillEvent( lifeId, "carrying" );
}
else if ( victim.isDefusing )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
}
if ( attacker.isBombCarrier )
attacker incPlayerStat( "killsasbombcarrier", 1 );
}
giveLastOnTeamWarning()
{
self endon("death");
self endon("disconnect");
level endon( "game_ended" );
self waitTillRecoveredHealth( 3 );
otherTeam = getOtherTeam( self.pers["team"] );
level thread teamPlayerCardSplash( "callout_lastteammemberalive", self, self.pers["team"] );
level thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
level notify ( "last_alive", self );
self maps\mp\gametypes\_missions::lastManSD();
}
onTimeLimit()
{
sd_endGame( game["defenders"], game["strings"]["time_limit_reached"] );
}
updateGametypeDvars()
{
level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
level.bombTimer = dvarFloatValue( "bombtimer", 45, 1, 300 );
level.multiBomb = dvarIntValue( "multibomb", 0, 0, 1 );
}
bombs()
{
level.bombPlanted = false;
level.bombDefused = false;
level.bombExploded = false;
trigger = getEnt( "sd_bomb_pickup_trig", "targetname" );
if ( !isDefined( trigger ) )
{
error("No sd_bomb_pickup_trig trigger found in map.");
return;
}
visuals[0] = getEnt( "sd_bomb", "targetname" );
if ( !isDefined( visuals[0] ) )
{
error("No sd_bomb script_model found in map.");
return;
}
precacheModel( "prop_suitcase_bomb" );
visuals[0] setModel( "prop_suitcase_bomb" );
if ( !level.multiBomb )
{
level.sdBomb = maps\mp\gametypes\_gameobjects::createCarryObject( game["attackers"], trigger, visuals, (0,0,32) );
level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "friendly" );
level.sdBomb maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
level.sdBomb maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
level.sdBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
level.sdBomb maps\mp\gametypes\_gameobjects::setCarryIcon( "hud_suitcase_bomb" );
level.sdBomb.allowWeapons = true;
level.sdBomb.onPickup = ::onPickup;
level.sdBomb.onDrop = ::onDrop;
}
else
{
trigger delete();
visuals[0] delete();
}
level.bombZones = [];
bombZones = getEntArray( "bombzone", "targetname" );
for ( index = 0; index < bombZones.size; index++ )
{
trigger = bombZones[index];
visuals = getEntArray( bombZones[index].target, "targetname" );
bombZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,64) );
bombZone maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
bombZone maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
bombZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
bombZone maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
if ( !level.multiBomb )
bombZone maps\mp\gametypes\_gameobjects::setKeyObject( level.sdBomb );
label = bombZone maps\mp\gametypes\_gameobjects::getLabel();
bombZone.label = label;
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + label );
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + label );
bombZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
bombZone.onBeginUse = ::onBeginUse;
bombZone.onEndUse = ::onEndUse;
bombZone.onUse = ::onUsePlantObject;
bombZone.onCantUse = ::onCantUse;
bombZone.useWeapon = "briefcase_bomb_mp";
for ( i = 0; i < visuals.size; i++ )
{
if ( isDefined( visuals[i].script_exploder ) )
{
bombZone.exploderIndex = visuals[i].script_exploder;
break;
}
}
level.bombZones[level.bombZones.size] = bombZone;
bombZone.bombDefuseTrig = getent( visuals[0].target, "targetname" );
assert( isdefined( bombZone.bombDefuseTrig ) );
bombZone.bombDefuseTrig.origin += (0,0,-10000);
bombZone.bombDefuseTrig.label = label;
}
for ( index = 0; index < level.bombZones.size; index++ )
{
array = [];
for ( otherindex = 0; otherindex < level.bombZones.size; otherindex++ )
{
if ( otherindex != index )
array[ array.size ] = level.bombZones[otherindex];
}
level.bombZones[index].otherBombZones = array;
}
}
onBeginUse( player )
{
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
player playSound( "mp_bomb_defuse" );
player.isDefusing = true;
if ( isDefined( level.sdBombModel ) )
level.sdBombModel hide();
}
else
{
player.isPlanting = true;
if ( level.multibomb )
{
for ( i = 0; i < self.otherBombZones.size; i++ )
{
//self.otherBombZones[i] maps\mp\gametypes\_gameobjects::disableObject();
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::allowUse( "none" );
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
}
}
}
}
onEndUse( team, player, result )
{
if ( !isDefined( player ) )
return;
if ( isAlive( player ) )
{
player.isDefusing = false;
player.isPlanting = false;
}
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
if ( isDefined( level.sdBombModel ) && !result )
{
level.sdBombModel show();
}
}
else
{
if ( level.multibomb && !result )
{
for ( i = 0; i < self.otherBombZones.size; i++ )
{
//self.otherBombZones[i] maps\mp\gametypes\_gameobjects::enableObject();
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
}
}
}
}
onCantUse( player )
{
player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
onUsePlantObject( player )
{
// planted the bomb
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
level thread bombPlanted( self, player );
//player logString( "bomb planted: " + self.label );
// disable all bomb zones except this one
for ( index = 0; index < level.bombZones.size; index++ )
{
if ( level.bombZones[index] == self )
continue;
level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
}
player playSound( "mp_bomb_plant" );
player notify ( "bomb_planted" );
//if ( !level.hardcoreMode )
// iPrintLn( &"MP_EXPLOSIVES_PLANTED_BY", player );
leaderDialog( "bomb_planted" );
level thread teamPlayerCardSplash( "callout_bombplanted", player );
level.bombOwner = player;
player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
player.bombPlantedTime = getTime();
maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
player incPlayerStat( "bombsplanted", 1 );
player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
}
}
onUseDefuseObject( player )
{
player notify ( "bomb_defused" );
//player logString( "bomb defused: " + self.label );
level thread bombDefused();
// disable this bomb zone
self maps\mp\gametypes\_gameobjects::disableObject();
//if ( !level.hardcoreMode )
// iPrintLn( &"MP_EXPLOSIVES_DEFUSED_BY", player );
leaderDialog( "bomb_defused" );
level thread teamPlayerCardSplash( "callout_bombdefused", player );
if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 3000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
else
player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
player incPlayerStat( "bombsdefused", 1 );
player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origin );
}
onDrop( player )
{
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
maps\mp\_utility::playSoundOnPlayers( game["bomb_dropped_sound"], game["attackers"] );
}
onPickup( player )
{
player.isBombCarrier = true;
player incPlayerStat( "bombscarried", 1 );
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_escort" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_escort" );
if ( !level.bombDefused )
{
teamPlayerCardSplash( "callout_bombtaken", player, player.team );
leaderDialog( "bomb_taken", player.pers["team"] );
}
maps\mp\_utility::playSoundOnPlayers( game["bomb_recovered_sound"], game["attackers"] );
}
onReset()
{
}
bombPlanted( destroyedObj, player )
{
maps\mp\gametypes\_gamelogic::pauseTimer();
level.bombPlanted = true;
destroyedObj.visuals[0] thread maps\mp\gametypes\_gamelogic::playTickingSound();
level.tickingObject = destroyedObj.visuals[0];
level.timeLimitOverride = true;
setGameEndTime( int( gettime() + (level.bombTimer * 1000) ) );
setDvar( "ui_bomb_timer", 1 );
if ( !level.multiBomb )
{
level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "none" );
level.sdBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.sdBomb maps\mp\gametypes\_gameobjects::setDropped();
level.sdBombModel = level.sdBomb.visuals[0];
}
else
{
for ( index = 0; index < level.players.size; index++ )
{
if ( isDefined( level.players[index].carryIcon ) )
level.players[index].carryIcon destroyElem();
}
trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000), false, player );
tempAngle = randomfloat( 360 );
forward = (cos( tempAngle ), sin( tempAngle ), 0);
forward = vectornormalize( forward - common_scripts\utility::vector_multiply( trace["normal"], vectordot( forward, trace["normal"] ) ) );
dropAngles = vectortoangles( forward );
level.sdBombModel = spawn( "script_model", trace["position"] );
level.sdBombModel.angles = dropAngles;
level.sdBombModel setModel( "prop_suitcase_bomb" );
}
destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" );
destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
/*
destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", undefined );
destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", undefined );
destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", undefined );
destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", undefined );
*/
label = destroyedObj maps\mp\gametypes\_gameobjects::getLabel();
// create a new object to defuse with.
trigger = destroyedObj.bombDefuseTrig;
trigger.origin = level.sdBombModel.origin;
visuals = [];
defuseObject = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,32) );
defuseObject maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
defuseObject maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
defuseObject maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
defuseObject maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
defuseObject maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
defuseObject maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" + label );
defuseObject maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" + label );
defuseObject maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" + label );
defuseObject maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" + label );
defuseObject.label = label;
defuseObject.onBeginUse = ::onBeginUse;
defuseObject.onEndUse = ::onEndUse;
defuseObject.onUse = ::onUseDefuseObject;
defuseObject.useWeapon = "briefcase_bomb_defuse_mp";
BombTimerWait();
setDvar( "ui_bomb_timer", 0 );
destroyedObj.visuals[0] maps\mp\gametypes\_gamelogic::stopTickingSound();
if ( level.gameEnded || level.bombDefused )
return;
level.bombExploded = true;
explosionOrigin = level.sdBombModel.origin;
level.sdBombModel hide();
if ( isdefined( player ) )
{
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player );
player incPlayerStat( "targetsdestroyed", 1 );
}
else
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
rot = randomfloat(360);
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
triggerFx( explosionEffect );
PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
earthquake( 0.75, 2.0, explosionOrigin, 2000 );
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
if ( isDefined( destroyedObj.exploderIndex ) )
exploder( destroyedObj.exploderIndex );
for ( index = 0; index < level.bombZones.size; index++ )
level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
defuseObject maps\mp\gametypes\_gameobjects::disableObject();
setGameEndTime( 0 );
wait 3;
sd_endGame( game["attackers"], game["strings"]["target_destroyed"] );
}
BombTimerWait()
{
level endon( "game_ended" );
level endon( "bomb_defused" );
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( level.bombTimer );
}
bombDefused()
{
level.tickingObject maps\mp\gametypes\_gamelogic::stopTickingSound();
level.bombDefused = true;
setDvar( "ui_bomb_timer", 0 );
level notify("bomb_defused");
wait 1.5;
setGameEndTime( 0 );
sd_endGame( game["defenders"], game["strings"]["bomb_defused"] );
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
}
+447
View File
@@ -0,0 +1,447 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
VIP
Objective: Escort the VIP to safety, or eliminate the VIP beofore he reaches extraction
Map ends: When one team eliminates the enemy team, or the flag is reached
Respawning: Beginning of next round
Level requirementss
------------------
Spawnpoints:
classname mp_tdm_spawn
Spectator Spawnpoints:
classname mp_global_intermission
*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 500, 0, 5000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 1, 0, 10 );
registerWatchDvarInt( "halftime", 0 );
level.teamBased = true;
level.objectiveBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onNormalDeath = ::onNormalDeath;
level.onPlayerKilled = ::onPlayerKilled;
level.onDeadEvent = ::onDeadEvent;
game["dialog"]["gametype"] = "VIP";
}
onPrecacheGameType()
{
precacheShader( "compass_waypoint_captureneutral" );
precacheShader( "compass_waypoint_capture" );
precacheShader( "compass_waypoint_defend" );
precacheShader( "waypoint_captureneutral" );
precacheShader( "waypoint_capture" );
precacheShader( "waypoint_defend" );
precacheString( &"MP_ELIMINATED_VIP" );
precacheString( &"MP_DEFENDED_VIP" );
precacheString( &"SPLASHES_VIP" );
game["flagmodels"] = [];
game["flagmodels"]["neutral"] = "prop_flag_neutral";
game["flagmodels"]["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
game["flagmodels"]["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
precacheModel( game["flagmodels"]["neutral"] );
precacheModel( game["flagmodels"]["allies"] );
precacheModel( game["flagmodels"]["axis"] );
}
onStartGameType()
{
setClientNameMode("auto_change");
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setObjectiveText( "allies", &"OBJECTIVES_VIP" );
setObjectiveText( "axis", &"OBJECTIVES_VIP" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_VIP" );
setObjectiveScoreText( "axis", &"OBJECTIVES_VIP" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_VIP_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_VIP_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_VIP_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_VIP_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = "vip";
allowed[1] = "sd";
//maps\mp\gametypes\_rank::registerScoreInfo( "capture", 200 );
maps\mp\gametypes\_gameobjects::main(allowed);
self thread waitToProcess();
}
waitToProcess()
{
level endon( "game_end" );
level endon( "waitSkipped" );
self thread extractionZone();
self thread skipWait();
gameFlagWait( "prematch_done" );
gameFlagWait( "graceperiod_done" );
self notify( "graceComplete" );
self thread vipSelection();
}
skipWait()
{
self endon( "graceComplete" );
for(;;)
{
if( level.players.size > 2 )
break;
wait( .5 );
}
self notify( "waitSkipped" );
self thread vipSelection();
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + spawnteam + "_start" );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onSpawnPlayer()
{
self.isVip = false;
self.usingObj = undefined;
level notify ( "spawned_player" );
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
attacker maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( attacker.pers["team"], score );
team = victim.team;
if ( isDefined( victim.isVip ) && victim.isVip )
{
level thread vip_endGame( game["attackers"], &"MP_ELIMINATED_VIP" );
attacker.finalKill = true;
}
}
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
{
thread checkAllowSpectating();
}
onTimeLimit()
{
if ( game["status"] == "overtime" )
{
winner = "forfeit";
}
else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
{
winner = "overtime";
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
winner = "axis";
}
else
{
winner = "allies";
}
thread maps\mp\gametypes\_gamelogic::endGame( winner, game["strings"]["time_limit_reached"] );
}
checkAllowSpectating()
{
wait ( 0.05 );
update = false;
if ( !level.aliveCount[ game["attackers"] ] )
{
level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
update = true;
}
if ( !level.aliveCount[ game["defenders"] ] )
{
level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
update = true;
}
if ( update )
maps\mp\gametypes\_spectating::updateSpectateSettings();
}
onDeadEvent( team )
{
if ( team == game["attackers"] )
{
level thread vip_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
level thread vip_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
vip_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
vipSelection()
{
println( "SELECTION" );
potentialVIPs = [];
abortTime = 0;
for( ;; )
{
if ( level.players.size >= 2 )
break;
if ( abortTime >= 100 )
{
iPrintlnBold( "Game mode only playable with 2 or more players" );
wait( 2 );
maps\mp\gametypes\_callbacksetup::AbortLevel();
}
abortTime++;
wait( .1 );
}
foreach ( player in level.players )
{
if ( player.team == game["defenders"] )
potentialVIPs[ potentialVIPs.size ] = player;
}
selectedVIPNum = RandomIntRange( 0, potentialVIPs.size );
selectedPlayer = potentialVIPs[ selectedVIPNum ];
if ( !isAlive(selectedPlayer ) && !isSubStr( selectedPlayer.guid, "bot" ) )
selectedPlayer forceVIPSpawn();
setupVip( selectedPlayer );
}
setupVip ( vipPlayer )
{
vipPlayer TakeAllWeapons();
vipPlayer _clearPerks();
vipPlayer.isVip = true;
vipPlayer giveWeapon( "deserteagle_fmj_mp" );
vipPlayer giveStartAmmo( "deserteagle_fmj_mp" );
vipPlayer giveWeapon( "riotshield_mp" );
vipPlayer switchToWeapon( "riotshield_mp" );
vipPlayer _setPerk( "specialty_armorvest" );
vipPlayer _setPerk( "specialty_finalstand" );
vipPlayer iPrintlnBold( "You Are the VIP" );
//TO DO: add defend icon on the VIP
}
extractionZone()
{
extractionZone = getEntArray("extraction_vip", "targetname");
// check to see if zone is available.
if ( !isDefined( extractionZone ) )
{
println("WARNING: no extraction zone specified" );
printLn( "^1Not enough extraction zones found in level!" );
maps\mp\gametypes\_callbacksetup::AbortLevel();
return;
}
else
level.extractionZone = extractionZone;
trigger = level.extractionZone[0];
if ( isDefined( trigger.target ) )
{
visuals[0] = getEnt( trigger.target, "targetname" );
}
else
{
visuals[0] = spawn( "script_model", trigger.origin );
visuals[0].angles = trigger.angles;
}
extractionZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,100) );
extractionZone maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
extractionZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
extractionZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_CALLING_EXTRACTION" );
extractionZone maps\mp\gametypes\_gameobjects::setUseTime( 0 );
extractionZone.onUse = ::onUse;
extractionZone.onCantUse = ::onCantUse;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( game["defenders"] );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
extractionZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
extractionZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend");
extractionZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
level.extractionZone = extractionZone;
}
setVIPUse()
{
foreach (player in level.players)
{
if ( ! player.isVip )
self.trigger disablePlayerUse(player);
}
}
onUse( player )
{
if ( !isDefined( player.isVip ) || ! player.isVip )
{
return;
}
iPrintlnBold( "Extraction on its way" );
self handleTimer( player );
}
handleTimer( player )
{
player endon( "death" );
level endon( "game_end" );
level.extractionTime = 45;
maps\mp\gametypes\_gamelogic::pauseTimer();
level.timeLimitOverride = true;
setGameEndTime( int( getTime() + (level.extractionTime * 1000) ) );
wait level.extractionTime;
//call the sentry airdrops
level thread vip_endGame( game["defenders"], &"MP_DEFENDED_VIP" );
}
onEndUse( team, player, success )
{
println( "End Use" );
}
onCantUse( player )
{
// player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
spawnFxDelay( fxid, pos, forward, right, delay )
{
wait delay;
effect = spawnFx( fxid, pos, forward, right );
triggerFx( effect );
}
forceVIPSpawn()
{
self endon ( "death" );
self endon ( "disconnect" );
self endon ( "spawned" );
if ( self.hasSpawned )
return;
if ( !isValidClass( self.pers["class"] ) )
{
self.pers["class"] = "CLASS_CUSTOM1";
self.class = self.pers["class"];
}
self closeMenus();
self thread maps\mp\gametypes\_playerlogic::spawnClient();
}
+171
View File
@@ -0,0 +1,171 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
War
Objective: Score points for your team by eliminating players on the opposing team
Map ends: When one team reaches the score limit, or time limit is reached
Respawning: No wait / Near teammates
Level requirementss
------------------
Spawnpoints:
classname mp_tdm_spawn
All players spawn from these. The spawnpoint chosen is dependent on the current locations of teammates and enemies
at the time of spawn. Players generally spawn behind their teammates relative to the direction of enemies.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
*/
/*QUAKED mp_tdm_spawn (0.0 0.0 1.0) (-16 -16 0) (16 16 72)
Players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_tdm_spawn_axis_start (0.5 0.0 1.0) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_tdm_spawn_allies_start (0.0 0.5 1.0) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 500, 0, 5000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.teamBased = true;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onNormalDeath = ::onNormalDeath;
//level.onTimeLimit = ::onTimeLimit; // overtime not fully supported yet
game["dialog"]["gametype"] = "tm_death";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["strings"]["overtime_hint"] = &"MP_FIRST_BLOOD";
}
onStartGameType()
{
setClientNameMode("auto_change");
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setObjectiveText( "allies", &"OBJECTIVES_WAR" );
setObjectiveText( "axis", &"OBJECTIVES_WAR" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_WAR" );
setObjectiveScoreText( "axis", &"OBJECTIVES_WAR" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_WAR_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_WAR_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_WAR_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_WAR_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = level.gameType;
allowed[1] = "airdrop_pallet";
maps\mp\gametypes\_gameobjects::main(allowed);
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + spawnteam + "_start" );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
attacker maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( attacker.pers["team"], score );
if ( game["state"] == "postgame" && game["teamScores"][attacker.team] > game["teamScores"][level.otherTeam[attacker.team]] )
attacker.finalKill = true;
}
onTimeLimit()
{
if ( game["status"] == "overtime" )
{
winner = "forfeit";
}
else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
{
winner = "overtime";
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
winner = "axis";
}
else
{
winner = "allies";
}
thread maps\mp\gametypes\_gamelogic::endGame( winner, game["strings"]["time_limit_reached"] );
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
Loaded 100 of 5854 files, more files were not shown because too many files have changed in this diff. Show more