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

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

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

View File

@ -0,0 +1,64 @@
#include common_scripts\utility;
#using_animtree( "animated_props" );
main()
{
//level.init_animatedmodels_dump = false;
if ( !isdefined( level._anim_prop_models ) )
level._anim_prop_models = []; // this is what the LD puts in their map
// Do special MP anim precaching
model_keys = GetArrayKeys( level._anim_prop_models );
foreach ( model_key in model_keys )
{
anim_keys = GetArrayKeys( level._anim_prop_models[model_key] );
foreach ( anim_key in anim_keys )
PrecacheMpAnim( level._anim_prop_models[model_key][anim_key] );
//PrecacheMpAnim( level.anim_prop_models[ "foliage_tree_palm_bushy_1" ][ "strong" ] );
}
// wait until the end of the frame so that maps can init their trees
// in their _anim instead of only above _load
waittillframeend;
level._init_animatedmodels = [];
animated_models = getentarray( "animated_model", "targetname" );
//array_thread( animated_models, ::model_init );
// one or more of the models initialized by model_init() was not setup by the map
// so print this helpful note so the designer can see how to add it ot their level
//if ( level.init_animatedmodels_dump )
//assertmsg( "anims not cached for animated prop model, Repackage Zones and Rebuild Precache Script in Launcher:" );
array_thread( animated_models, ::animateModel );
level._init_animatedmodels = undefined;
}
// Disabled for now since we are precaching .animation prefabs in a non-standard way
/*model_init()
{
if ( !isdefined( level.anim_prop_models[ self.model ] ) )
level.init_animatedmodels_dump = true;
}*/
// TODO: When we have multiple animations, instead of choosing randomly, do round-robin to get an even spread
animateModel()
{
if ( IsDefined( self.animation ) )
{
animation = self.animation;
}
else
{
keys = GetArrayKeys( level._anim_prop_models[ self.model ] );
animkey = keys[ RandomInt( keys.size ) ];
animation = level._anim_prop_models[ self.model ][ animkey ];
}
//wait( RandomFloatRange( 0, 5 ) ); // TODO: get a way to play animations at random starting points
self ScriptModelPlayAnim( animation );
self willNeverChange();
}

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

@ -0,0 +1,111 @@
#include maps\mp\_utility;
#include common_scripts\utility;
/*QUAKED trigger_multiple_area (0.12 0.23 1.0)
defaulttexture="trigger"
"script_area" - A localized string that names the area. e.g. "MP_FLOWER_SHOP"
Defines an area that the player is in.*/
/*QUAKED trigger_multiple_softlanding (0.12 0.23 1.0)
defaulttexture="trigger"
"script_type" - "car", "boxes", "trash"
Defines a soft landing area.*/
/*QUAKED script_vehicle_snowmobile_player_mp (1 0 0) (-16 -16 -24) (16 16 32) USABLE SPAWNER
maps\_snowmobile_player::main( "vehicle_snowmobile" );
include,vehicle_snowmobile_snowmobile_player
sound,vehicle_snowmobile,vehicle_standard,all_sp
defaultmdl="vehicle_snowmobile"
default:"vehicletype" "snowmobile_player_mp"
*/
init()
{
level._softLandingTriggers = getEntArray( "trigger_multiple_softlanding", "classname" );
destructibles = getEntArray( "destructible_vehicle", "targetname" );
foreach ( trigger in level._softLandingTriggers )
{
if ( trigger.script_type != "car" )
continue;
foreach ( destructible in destructibles )
{
/*
if ( !trigger isTouching( destructible ) )
{
println( distance( trigger.origin, destructible.origin ) );
continue;
}
*/
if ( distance( trigger.origin, destructible.origin ) > 64.0 )
continue;
assert( !isDefined( trigger.destructible ) );
trigger.destructible = destructible;
}
}
//foreach ( trigger in level.softLandingTriggers )
// trigger thread common_scripts\_dynamic_world::triggerTouchThink( ::playerEnterSoftLanding, ::playerLeaveSoftLanding );
thread onPlayerConnect();
}
onPlayerConnect()
{
for ( ;; )
{
level waittill ( "connected", player );
player.softLanding = undefined;
player thread softLandingWaiter();
}
}
playerEnterSoftLanding( trigger )
{
self.softLanding = trigger;
}
playerLeaveSoftLanding( trigger )
{
self.softLanding = undefined;
}
softLandingWaiter()
{
self endon ( "disconnect" );
for ( ;; )
{
self waittill ( "soft_landing", trigger, damage );
//if ( damage < 10 )
// continue;
if ( !isDefined( trigger.destructible ) )
continue;
//magicBullet( "mp5_mp", self.origin, self.origin + (0,0,-100), self );
//self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, dflags );
//traceData = bulletTrace( self.origin, self.origin + (0,0,-100), true, self );
}
}

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

@ -0,0 +1,189 @@
// This function should take care of grain and glow settings for each map, plus anything else that artists
// need to be able to tweak without bothering level designers.
#include common_scripts\utility;
#include common_scripts\_artCommon;
main()
{
/#
setDevDvarIfUninitialized( "scr_art_tweak", 0 );
setDevDvarIfUninitialized( "scr_dof_enable", "1" );
setDevDvarIfUninitialized( "scr_cmd_plr_sun", "0" );
setDevDvarIfUninitialized( "scr_cinematic_autofocus", "1" );
setDevDvarIfUninitialized( "scr_art_visionfile", level._script );
if ( !isDefined( level._dofDefault ) )
{
level._dofDefault[ "nearStart" ] = 0;
level._dofDefault[ "nearEnd" ] = 1;
level._dofDefault[ "farStart" ] = 8000;
level._dofDefault[ "farEnd" ] = 10000;
level._dofDefault[ "nearBlur" ] = 6;
level._dofDefault[ "farBlur" ] = 0;
}
level._curDoF = ( level._dofDefault[ "farStart" ] - level._dofDefault[ "nearEnd" ] ) / 2;
thread tweakart();
if ( !isdefined( level._script ) )
level._script = ToLower( GetDvar( "mapname" ) );
#/
}
tweakart()
{
/#
if ( !isdefined( level._tweakfile ) )
level._tweakfile = false;
// not in DEVGUI
SetDevDvar( "scr_fog_fraction", "1.0" );
SetDevDvar( "scr_art_dump", "0" );
// update the devgui variables to current settings
SetDevDvar( "scr_dof_nearStart", level._dofDefault[ "nearStart" ] );
SetDevDvar( "scr_dof_nearEnd", level._dofDefault[ "nearEnd" ] );
SetDevDvar( "scr_dof_farStart", level._dofDefault[ "farStart" ] );
SetDevDvar( "scr_dof_farEnd", level._dofDefault[ "farEnd" ] );
SetDevDvar( "scr_dof_nearBlur", level._dofDefault[ "nearBlur" ] );
SetDevDvar( "scr_dof_farBlur", level._dofDefault[ "farBlur" ] );
// not in DEVGUI
level._fogfraction = 1.0;
file = undefined;
filename = undefined;
for ( ;; )
{
while ( GetDvarInt( "scr_art_tweak", 0 ) == 0 )
{
AssertEx( GetDvarInt( "scr_art_dump", 0 ) == 0, "Must Enable Art Tweaks to export _art file." );
wait .05;
if ( ! GetDvarInt( "scr_art_tweak", 0 ) == 0 )
common_scripts\_artCommon::setfogsliders();// sets the sliders to whatever the current fog value is
}
if ( GetDvarInt( "scr_art_tweak_message" ) )
{
SetDevDvar( "scr_art_tweak_message", "0" );
IPrintLnBold( "ART TWEAK ENABLED" );
}
//translate the slider values to script variables
common_scripts\_artCommon::translateFogSlidersToScript();
// dofvarupdate();
// catch all those cases where a slider can be pushed to a place of conflict
fovslidercheck();
dump = dumpsettings();// dumps and returns true if the dump dvar is set
common_scripts\_artCommon::updateFogFromScript();
// level.player setDefaultDepthOfField();
if ( dump )
{
IPrintLnBold( "Art settings dumped success!" );
SetdevDvar( "scr_art_dump", "0" );
}
wait .1;
}
#/
}
fovslidercheck()
{
/#
// catch all those cases where a slider can be pushed to a place of conflict
if ( level._dofDefault[ "nearStart" ] >= level._dofDefault[ "nearEnd" ] )
{
level._dofDefault[ "nearStart" ] = level._dofDefault[ "nearEnd" ] - 1;
SetDevDvar( "scr_dof_nearStart", level._dofDefault[ "nearStart" ] );
}
if ( level._dofDefault[ "nearEnd" ] <= level._dofDefault[ "nearStart" ] )
{
level._dofDefault[ "nearEnd" ] = level._dofDefault[ "nearStart" ] + 1;
SetDevDvar( "scr_dof_nearEnd", level._dofDefault[ "nearEnd" ] );
}
if ( level._dofDefault[ "farStart" ] >= level._dofDefault[ "farEnd" ] )
{
level._dofDefault[ "farStart" ] = level._dofDefault[ "farEnd" ] - 1;
SetDevDvar( "scr_dof_farStart", level._dofDefault[ "farStart" ] );
}
if ( level._dofDefault[ "farEnd" ] <= level._dofDefault[ "farStart" ] )
{
level._dofDefault[ "farEnd" ] = level._dofDefault[ "farStart" ] + 1;
SetDevDvar( "scr_dof_farEnd", level._dofDefault[ "farEnd" ] );
}
if ( level._dofDefault[ "farBlur" ] >= level._dofDefault[ "nearBlur" ] )
{
level._dofDefault[ "farBlur" ] = level._dofDefault[ "nearBlur" ] - .1;
SetDevDvar( "scr_dof_farBlur", level._dofDefault[ "farBlur" ] );
}
if ( level._dofDefault[ "farStart" ] <= level._dofDefault[ "nearEnd" ] )
{
level._dofDefault[ "farStart" ] = level._dofDefault[ "nearEnd" ] + 1;
SetDevDvar( "scr_dof_farStart", level._dofDefault[ "farStart" ] );
}
#/
}
dumpsettings()
{
/#
if ( GetDvarInt( "scr_art_dump" ) == 0 )
return false;
filename = "createart/" + GetDvar( "scr_art_visionfile" ) + "_art.gsc";
artStartFogFileExport();
fileprint_launcher( "// _createart generated. modify at your own risk. Changing values should be fine." );
fileprint_launcher( "main()" );
fileprint_launcher( "{" );
fileprint_launcher( "" );
fileprint_launcher( "\tlevel.tweakfile = true;" );
fileprint_launcher( " " );
artfxprintlnFog();
fileprint_launcher( "\tVisionSetNaked( \"" + level._script + "\", 0 );" );
fileprint_launcher( "" );
fileprint_launcher( "}" );
artEndFogFileExport();
visionFilename = "vision/" + GetDvar( "scr_art_visionfile" ) + ".vision";
artStartVisionFileExport();
fileprint_launcher( "r_glow \"" + GetDvar( "r_glowTweakEnable" ) + "\"" );
fileprint_launcher( "r_glowRadius0 \"" + GetDvar( "r_glowTweakRadius0" ) + "\"" );
fileprint_launcher( "r_glowBloomCutoff \"" + GetDvar( "r_glowTweakBloomCutoff" ) + "\"" );
fileprint_launcher( "r_glowBloomDesaturation \"" + GetDvar( "r_glowTweakBloomDesaturation" ) + "\"" );
fileprint_launcher( "r_glowBloomIntensity0 \"" + GetDvar( "r_glowTweakBloomIntensity0" ) + "\"" );
fileprint_launcher( " " );
fileprint_launcher( "r_filmEnable \"" + GetDvar( "r_filmTweakEnable" ) + "\"" );
fileprint_launcher( "r_filmContrast \"" + GetDvar( "r_filmTweakContrast" ) + "\"" );
fileprint_launcher( "r_filmBrightness \"" + GetDvar( "r_filmTweakBrightness" ) + "\"" );
fileprint_launcher( "r_filmDesaturation \"" + GetDvar( "r_filmTweakDesaturation" ) + "\"" );
fileprint_launcher( "r_filmDesaturationDark \"" + GetDvar( "r_filmTweakDesaturationDark" ) + "\"" );
fileprint_launcher( "r_filmInvert \"" + GetDvar( "r_filmTweakInvert" ) + "\"" );
fileprint_launcher( "r_filmLightTint \"" + GetDvar( "r_filmTweakLightTint" ) + "\"" );
fileprint_launcher( "r_filmMediumTint \"" + GetDvar( "r_filmTweakMediumTint" ) + "\"" );
fileprint_launcher( "r_filmDarkTint \"" + GetDvar( "r_filmTweakDarkTint" ) + "\"" );
fileprint_launcher( " " );
fileprint_launcher( "r_primaryLightUseTweaks \"" + GetDvar( "r_primaryLightUseTweaks" ) + "\"" );
fileprint_launcher( "r_primaryLightTweakDiffuseStrength \"" + GetDvar( "r_primaryLightTweakDiffuseStrength" ) + "\"" );
fileprint_launcher( "r_primaryLightTweakSpecularStrength \"" + GetDvar( "r_primaryLightTweakSpecularStrength" ) + "\"" );
if ( ! artEndVisionFileExport() )
return false;
IPrintLnBold( "ART DUMPED SUCCESSFULLY" );
return true;
#/
}

1142
maps/mp/_awards.gsc Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,79 @@
setupMiniMap(material)
{
// use 0 for no required map aspect ratio.
requiredMapAspectRatio = level._requiredMapAspectRatio;
corners = getentarray("minimap_corner", "targetname");
if (corners.size != 2)
{
println("^1Error: There are not exactly two \"minimap_corner\" entities in the map. Could not set up minimap.");
return;
}
corner0 = (corners[0].origin[0], corners[0].origin[1], 0);
corner1 = (corners[1].origin[0], corners[1].origin[1], 0);
cornerdiff = corner1 - corner0;
north = (cos(getnorthyaw()), sin(getnorthyaw()), 0);
west = (0 - north[1], north[0], 0);
// we need the northwest and southeast corners. all we know is that corner0 is opposite of corner1.
if (vectordot(cornerdiff, west) > 0) {
// corner1 is further west than corner0
if (vectordot(cornerdiff, north) > 0) {
// corner1 is northwest, corner0 is southeast
northwest = corner1;
southeast = corner0;
}
else {
// corner1 is southwest, corner0 is northeast
side = vecscale(north, vectordot(cornerdiff, north));
northwest = corner1 - side;
southeast = corner0 + side;
}
}
else {
// corner1 is further east than corner0
if (vectordot(cornerdiff, north) > 0) {
// corner1 is northeast, corner0 is southwest
side = vecscale(north, vectordot(cornerdiff, north));
northwest = corner0 + side;
southeast = corner1 - side;
}
else {
// corner1 is southeast, corner0 is northwest
northwest = corner0;
southeast = corner1;
}
}
// expand map area to fit required aspect ratio
if ( requiredMapAspectRatio > 0 )
{
northportion = vectordot(northwest - southeast, north);
westportion = vectordot(northwest - southeast, west);
mapAspectRatio = westportion / northportion;
if ( mapAspectRatio < requiredMapAspectRatio )
{
incr = requiredMapAspectRatio / mapAspectRatio;
addvec = vecscale( west, westportion * (incr - 1) * 0.5 );
}
else
{
incr = mapAspectRatio / requiredMapAspectRatio;
addvec = vecscale( north, northportion * (incr - 1) * 0.5 );
}
northwest += addvec;
southeast -= addvec;
}
level._mapSize = vectordot(northwest - southeast, north);
setMiniMap(material, northwest[0], northwest[1], southeast[0], southeast[1]);
}
vecscale(vec, scalar)
{
return (vec[0]*scalar, vec[1]*scalar, vec[2]*scalar);
}

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

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

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

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

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

@ -0,0 +1,100 @@
init()
{
// level.destructableFX = loadfx("breakables/exp_wall_cinderblock_96");
ents = getentarray("destructable", "targetname");
if (getdvar("scr_destructables") == "0")
{
for (i = 0; i < ents.size; i++)
ents[i] delete();
}
else
{
for (i = 0; i < ents.size; i++)
{
ents[i] thread destructable_think();
}
}
}
destructable_think()
{
accumulate = 40;
threshold = 0;
if (isdefined(self.script_accumulate))
accumulate = self.script_accumulate;
if (isdefined(self.script_threshold))
threshold = self.script_threshold;
if (isdefined(self.script_destructable_area)) {
areas = strtok(self.script_destructable_area, " ");
for (i = 0; i < areas.size; i++)
self blockArea(areas[i]);
}
if ( isdefined( self.script_fxid ) )
self.fx = loadfx( self.script_fxid );
dmg = 0;
self setcandamage(true);
while(1)
{
self waittill("damage", amount, other);
if (amount >= threshold)
{
dmg += amount;
if (dmg >= accumulate)
{
self thread destructable_destruct();
return;
}
}
}
}
destructable_destruct()
{
ent = self;
if (isdefined(self.script_destructable_area)) {
areas = strtok(self.script_destructable_area, " ");
for (i = 0; i < areas.size; i++)
self unblockArea(areas[i]);
}
if ( isdefined( ent.fx ) )
playfx( ent.fx, ent.origin + (0,0,6) );
ent delete();
}
blockArea(area)
{
spawns = getentarray("mp_tdm_spawn", "classname");
blockEntsInArea(spawns, area);
spawns = getentarray("mp_dm_spawn", "classname");
blockEntsInArea(spawns, area);
}
blockEntsInArea(ents, area)
{
for (i = 0; i < ents.size; i++) {
if (!isdefined(ents[i].script_destructable_area) || ents[i].script_destructable_area != area)
continue;
ents[i].blockedoff = true;
}
}
unblockArea(area)
{
spawns = getentarray("mp_tdm_spawn", "classname");
unblockEntsInArea(spawns, area);
spawns = getentarray("mp_dm_spawn", "classname");
unblockEntsInArea(spawns, area);
}
unblockEntsInArea(ents, area)
{
for (i = 0; i < ents.size; i++) {
if (!isdefined(ents[i].script_destructable_area) || ents[i].script_destructable_area != area)
continue;
ents[i].blockedoff = false;
}
}

1602
maps/mp/_doorbreach.gsc Normal file

File diff suppressed because it is too large Load Diff

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

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

View File

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

View File

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2914
maps/mp/_utility.gsc Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

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

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

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

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

View File

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

View File

@ -0,0 +1,168 @@
#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" );
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread dtp_dirt_land();
}
}
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 );
}
dtp_dirt_land()
{
self endon( "disconnect" );
for(;;)
{
self waittill( "dtp_land" );
// always play the effect from the center
effectMenus = [];
effectMenus[effectMenus.size] = "dirt_effect_center";
// open effects
foreach ( menu in effectMenus )
self openMenu( menu );
if ( isAlive( self ) )
self waittill_notify_or_timeout( "death", 2.0 );
// get rid of them
foreach ( menu in effectMenus )
self closeMenu( menu );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,210 @@
init()
{
//tagZP<NOTE> what is this, may or may not need to extend for MTDM
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( level._multiTeamBased )
{
assertMsg( "getOtherTeam() should not be called in Multi Team Based gametypes" );
}
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 );
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
self allowSpectateTeam( level._teamNameList[i], 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 );
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
self allowSpectateTeam( level._teamNameList[i], 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") && !level._multiTeamBased )
{
self allowSpectateTeam( team, true );
self allowSpectateTeam( getOtherTeam( team ), false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
}
else if ( isDefined( team ) && level._multiTeamBased )
{
//the multi team case will drop in here
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
for( i = 0; i < level._teamNameList.size; i++ )
{
if( team == level._teamNameList[i] )
{
self allowSpectateTeam( level._teamNameList[i], true );
}
else
{
self allowSpectateTeam( level._teamNameList[i], 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 );
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
self allowSpectateTeam( level._teamNameList[i], false );
}
}
}
break;
case 2: // free
self allowSpectateTeam( "allies", true );
self allowSpectateTeam( "axis", true );
self allowSpectateTeam( "freelook", true );
self allowSpectateTeam( "none", true );
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
self allowSpectateTeam( level._teamNameList[i], true );
}
}
break;
}
if ( isDefined( team ) && (team == "axis" || team == "allies") && !level._multiTeamBased )
{
if ( isdefined( level._spectateOverride[team].allowFreeSpectate ))
self allowSpectateTeam( "freelook", true );
if ( isdefined( level._spectateOverride[team].allowEnemySpectate ))
self allowSpectateTeam( getOtherTeam( team ), true );
}
}

View File

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

2121
maps/mp/gametypes/_teams.gsc Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,364 @@
#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", 125 ); //*
registerTweakable( "player", "healthregentime", "scr_player_healthregentime", 5 ); //*
registerTweakable( "player", "healthregenratepercent", "scr_player_healthregenratepercent", 10 ); //*
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

1885
maps/mp/gametypes/convoy.gsc Normal file

File diff suppressed because it is too large Load Diff

100
maps/mp/gametypes/dm.gsc Normal file
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;
}

File diff suppressed because it is too large Load Diff

1083
maps/mp/gametypes/hvt.gsc Normal file

File diff suppressed because it is too large Load Diff

171
maps/mp/gametypes/war.gsc Normal file
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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,211 @@
#include maps\mp\_utility;
#include common_scripts\utility;
// Each Killstreak has its own initialization function. This Script has two main purposes.
// (1). All global data and assets used by this killstreak should be initialized here.
// (2). The callback that executes when a player activates this killstreak should be set here.
// TODO: A call to this script must be added to the script init() in the file c:\trees\nx1\game\share\raw\maps\mp\killstreaks\_killstreaks.gsc,
// this is were each individual killstreak is initialized.
init()
{
//This is a good place to precache assets, load up fx, or setup any global data that might be needed, NOTE: Everything defined in killstreakTable.csv
//will be precached automatically ( see initKillstreakData() in _killstreaks.gsc if interested ) so you do not need to worry about initializing the
//strings/weapons/materials/sounds defined there. If, for example, you were going to manually script up a plane flyiing over when this killstreak was
//activated you would want to precache that model here.
//load the fx
level._effect[ "blueshell" ] = loadfx( "nx/misc/prototype_saul" );
//This is were the killstreak activation callback is set
//TODO: Replace "killstreak_template" with the name of the new killstreak as defined in killstreakTable.csv
//Most killstreaks use a try fuction ( which i recommend, even if it is not necessary for this particualr killstreak it is nice to have a consistent model )
//the try script will make sure it is ok to fire the killstreak before the actual killstreak script is called.
level._killstreakFuncs["blueshell"] = ::try_use_killstreak;
//Use this script to update/initialize players as they connect to the game
level thread onPlayerConnect();
}
// This script is running on the global level object, it monitors players connecting to the game.
// Its main purpose is to apply the onPlayerSpawned script to each player as they connect to the game.
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
}
}
// This script is running on each player in the game, it recieves a notification each time the player it is running on spawns in the game
// Its main purpose is to initialize any per player data, as well as update the player subject to any global killstreak data when that player spawns.
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill( "spawned_player" );
println( "player spwaned" );
// init/manage any per player killstreak data here
}
}
//Many of the killstreaks have a try block that will test level conditions to make sure it is ok to fire the killstreak now. A good example of this is for the air killstreaks.
//Only a certain number of vehicles are allowed in the air at any given time, so if the airspace is full and the killstreak cannot be fired this try should return false.
//If there are any preconditions that must be met in order to fire this killstreak they should be checked in this script.
//NOTE: If this script returns true the killstreak system will consider this killstreak usage complete and the dpad icon will be removed, if this script returns false nothing will
//change and the system will just continue to wait for the the player to activate the killstreak by pressing right on the dpad.
try_use_killstreak( lifeId )
{
is_ok_to_use_killstreak = true;
if( is_ok_to_use_killstreak )
{
if( killstreak_template_use( lifeId ))
{
return true;
}
}
return false;
}
// This is the callback that executes when the killstreak is activated by a player pressing on the dpad. This is called from the script killstreakUsePressed()
// located in the file _killstreaks.gsc
killstreak_template_use( lifeId )
{
assert( isDefined( self ) );
println( "Killstreak Template Fired!!" );
player = self getHighestKillstreakPlayerNotOnMyTeam();
//if we couldnt find a target bail out.
if( !isDefined( player ))
{
return false;
}
fxObj = player createFxObj();
wait( 0.10 ); //wait two server frames before playing fx
fxobj thread doTheFx();
fxobj thread waitAndDelete( 10.0 );
wait( 1.6 );
player playSound( "prototype_missile_incoming" );
// This works
/*
PlayFX( level._effect["blueshell"], player.origin );
wait( 1.7 );
player playSound( "prototype_missile_incoming" );
*/
wait( 3.4 );
RadiusDamage( fxobj.origin, 100, 300, 25, self );
return true;
}
waitAndDelete( time )
{
wait( time );
self delete();
}
doTheFx()
{
PlayFXOnTagForClients( level._effect["blueshell"], self, "TAG_ORIGIN", level._players );
}
createFxObj()
{
tag_origin = spawn( "script_model", self.origin );
tag_origin setmodel( "tag_origin" );
//tag_origin hide();
if ( isdefined( self.origin ) )
tag_origin.origin = self.origin;
if ( isdefined( self.angles ) )
tag_origin.angles = self.angles;
return tag_origin;
}
getHighestKillstreakPlayerNotOnMyTeam()
{
team = self.pers["team"];
curr_highest_killstreak = -1;
curr_player = undefined;
//TagZP<TODO> add los checks from above to make sure the player is outside.
//possibly return a list of random targets for fun.
//possibly use player score insted of killstreak to select a target.
//this implies that we are in a team based game mode such as TDM or DOM
if( level._teamBased )
{
foreach( player in level._players )
{
//if the player is not on my team check if they have the highest killstreak!!!!!
if( player.pers["team"] != team )
{
if( player.pers["cur_kill_streak"] > curr_highest_killstreak )
{
curr_highest_killstreak = player.pers["cur_kill_streak"];
curr_player = player;
}
}
}
}
else
{
//If we are not in a team based game we must be in a FFA game
foreach( player in level._players )
{
//if the player is not on my team kill them!!!!!
if( player != self )
{
if( player.pers["cur_kill_streak"] > curr_highest_killstreak )
{
curr_highest_killstreak = player.pers["cur_kill_streak"];
curr_player = player;
}
}
}
}
assert( isDefined( curr_player ));
return curr_player;
}
// A helper script that will kill a player. Used by the example killstreak.
killPlayer( player )
{
player thread [[level._callbackPlayerDamage]](
self, // eInflictor The entity that causes the damage.(e.g. a turret)
self, // eAttacker The entity that is attacking.
500, // iDamage Integer specifying the amount of damage done
0, // iDFlags Integer specifying flags that are to be applied to the damage
"MOD_SUICIDE", // sMeansOfDeath Integer specifying the method of death MOD_RIFLE_BULLET
player.primaryweapon, // sWeapon The weapon number of the weapon used to inflict the damage
player.origin, // vPoint The point the damage is from?
(0, 0, 0), // vDir The direction of the damage
"none", // sHitLoc The location of the hit
0 // psOffsetTime The time offset for the damage
);
}

View File

@ -0,0 +1,414 @@
#include maps\mp\_utility;
#include common_scripts\utility;
init()
{
level._effect[ "emp_flash" ] = loadfx( "explosions/emp_flash_mp" );
level._teamEMPed["allies"] = false;
level._teamEMPed["axis"] = false;
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
level._teamEMPed[level._teamNameList[i]] = false;
}
}
level._empPlayer = undefined;
if ( level._teamBased )
level thread EMP_TeamTracker();
else
level thread EMP_PlayerTracker();
level._killstreakFuncs["emp"] = ::EMP_Use;
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill( "spawned_player" );
if ( (level._teamBased && level._teamEMPed[self.team]) || (!level._teamBased && isDefined( level._empPlayer ) && level._empPlayer != self) )
self setEMPJammed( true );
}
}
EMP_Use( lifeId, delay )
{
assert( isDefined( self ) );
if ( !isDefined( delay ) )
delay = 5.0;
myTeam = self.pers["team"];
if ( level._teamBased )
self thread EMP_JamTeams( myTeam, 60.0, delay );
else
self thread EMP_JamPlayers( self, 60.0, delay );
self maps\mp\_matchdata::logKillstreakEvent( "emp", self.origin );
self notify( "used_emp" );
return true;
}
EMP_JamTeams( teamName, duration, delay )
{
level endon ( "game_ended" );
thread teamPlayerCardSplash( "used_emp", self );
level notify ( "EMP_JamTeams" + teamName );
level endon ( "EMP_JamTeams" + teamName );
foreach ( player in level._players )
{
player playLocalSound( "emp_activate" );
if ( player.team == teamName )
{
continue;
}
else
{
player.gotEMPed = true;
if ( player _hasPerk( "specialty_flakjacket" ))
{
player notify ( "disableTrophy" );
}
}
if ( player _hasPerk( "specialty_localjammer" ) )
player RadarJamOff();
}
visionSetNaked( "coup_sunblind", 0.1 );
thread empEffects();
wait ( 0.1 );
// resetting the vision set to the same thing won't normally have an effect.
// however, if the client receives the previous visionset change in the same packet as this one,
// this will force them to lerp from the bright one to the normal one.
visionSetNaked( "coup_sunblind", 0 );
visionSetNaked( getDvar( "mapname" ), 3.0 );
foreach( team in level._teamNameList )
{
if ( team != teamName )
{
level._teamEMPed[team] = true;
}
}
level notify ( "emp_update" );
level destroyActiveVehicles( self );
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( duration );
foreach( team in level._teamNameList )
{
if ( team != teamName )
{
level._teamEMPed[team] = false;
}
}
foreach ( player in level._players )
{
if ( player.team == teamName )
{
continue;
}
else
{
player.gotEMPed = false;
if ( (player _hasPerk( "specialty_flakjacket" )) && !(isDefined ( player.gotEMPGrenaded ) && player.gotEMPGrenaded == true))
{
player notify ( "enableTrophy" );
}
}
if ( player _hasPerk( "specialty_localjammer" ) )
player RadarJamOn();
}
level notify ( "emp_update" );
level notify ( "enableTrophy" );
}
EMPGrenade_JamPlayer( duration )
{
level endon ( "EMP_JamPlayers" );
self endon ( "death" );
self endon ( "disconnect" );
self playLocalSound( "emp_activate" );
if ( self _hasPerk( "specialty_localjammer" ) )
self RadarJamOff();
self.gotEMPGrenaded = true;
if (self _hasPerk( "specialty_flakjacket" ))
{
self notify ( "disableTrophy" );
}
wait ( 0.1 );
self setEMPJammed( true );
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( duration );
self setEMPJammed( false );
if ( self _hasPerk( "specialty_localjammer" ) )
self RadarJamOn();
self.gotEMPGrenaded = false;
if ( (self _hasPerk( "specialty_flakjacket" )) && !(isDefined ( self.gotEMPed ) && self.gotEMPed == true ))
{
self notify ( "enableTrophy" );
}
}
EMP_JamPlayers( owner, duration, delay )
{
level notify ( "EMP_JamPlayers" );
level endon ( "EMP_JamPlayers" );
assert( isDefined( owner ) );
//wait ( delay );
foreach ( player in level._players )
{
player playLocalSound( "emp_activate" );
if ( player == owner )
{
continue;
}
else
{
player.gotEMPed = true;
if ( player _hasPerk( "specialty_flakjacket" ))
{
player notify ( "disableTrophy" );
}
}
if ( player _hasPerk( "specialty_localjammer" ) )
player RadarJamOff();
}
visionSetNaked( "coup_sunblind", 0.1 );
thread empEffects();
wait ( 0.1 );
// resetting the vision set to the same thing won't normally have an effect.
// however, if the client receives the previous visionset change in the same packet as this one,
// this will force them to lerp from the bright one to the normal one.
visionSetNaked( "coup_sunblind", 0 );
visionSetNaked( getDvar( "mapname" ), 3.0 );
level notify ( "emp_update" );
level._empPlayer = owner;
level._empPlayer thread empPlayerFFADisconnect();
level destroyActiveVehicles( owner );
level notify ( "emp_update" );
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( duration );
foreach ( player in level._players )
{
if ( player == owner )
{
continue;
}
else
{
player.gotEMPed = false;
if ( (player _hasPerk( "specialty_flakjacket" )) && !(isDefined ( player.gotEMPGrenaded ) && player.gotEMPGrenaded == true))
{
player notify ( "enableTrophy" );
}
}
if ( player _hasPerk( "specialty_localjammer" ) )
player RadarJamOn();
}
level._empPlayer = undefined;
level notify ( "emp_update" );
level notify ( "emp_ended" );
level notify ( "enableTrophy" );
}
empPlayerFFADisconnect()
{
level endon ( "EMP_JamPlayers" );
level endon ( "emp_ended" );
self waittill( "disconnect" );
level notify ( "emp_update" );
}
empEffects()
{
foreach( player in level._players )
{
playerForward = anglestoforward( player.angles );
playerForward = ( playerForward[0], playerForward[1], 0 );
playerForward = VectorNormalize( playerForward );
empDistance = 20000;
empEnt = Spawn( "script_model", player.origin + ( 0, 0, 8000 ) + Vector_Multiply( playerForward, empDistance ) );
empEnt setModel( "tag_origin" );
empEnt.angles = empEnt.angles + ( 270, 0, 0 );
empEnt thread empEffect( player );
}
}
empEffect( player )
{
player endon( "disconnect" );
wait( 0.5 );
PlayFXOnTagForClients( level._effect[ "emp_flash" ], self, "tag_origin", player );
}
EMP_TeamTracker()
{
level endon ( "game_ended" );
for ( ;; )
{
level waittill_either ( "joined_team", "emp_update" );
foreach ( player in level._players )
{
if ( player.team == "spectator" )
continue;
player setEMPJammed( level._teamEMPed[player.team] );
}
}
}
EMP_PlayerTracker()
{
level endon ( "game_ended" );
for ( ;; )
{
level waittill_either ( "joined_team", "emp_update" );
foreach ( player in level._players )
{
if ( player.team == "spectator" )
continue;
if ( isDefined( level._empPlayer ) && level._empPlayer != player )
player setEMPJammed( true );
else
player setEMPJammed( false );
}
}
}
destroyActiveVehicles( attacker )
{
if ( isDefined( attacker ) )
{
foreach ( heli in level._helis )
radiusDamage( heli.origin, 384, 5000, 5000, attacker );
foreach ( littleBird in level._littleBird )
radiusDamage( littleBird.origin, 384, 5000, 5000, attacker );
foreach ( turret in level._turrets )
radiusDamage( turret.origin, 2, 5000, 5000, attacker );
foreach ( rocket in level._rockets )
rocket notify ( "death" );
if ( level._teamBased )
{
foreach ( uav in level._uavModels["allies"] )
radiusDamage( uav.origin, 384, 5000, 5000, attacker );
foreach ( uav in level._uavModels["axis"] )
radiusDamage( uav.origin, 384, 5000, 5000, attacker );
}
else
{
foreach ( uav in level._uavModels )
radiusDamage( uav.origin, 384, 5000, 5000, attacker );
}
if ( isDefined( level._ac130player ) )
radiusDamage( level._ac130.planeModel.origin+(0,0,10), 1000, 5000, 5000, attacker );
}
else
{
foreach ( heli in level._helis )
radiusDamage( heli.origin, 384, 5000, 5000 );
foreach ( littleBird in level._littleBird )
radiusDamage( littleBird.origin, 384, 5000, 5000 );
foreach ( turret in level._turrets )
radiusDamage( turret.origin, 2, 5000, 5000 );
foreach ( rocket in level._rockets )
rocket notify ( "death" );
if ( level._teamBased )
{
foreach ( uav in level._uavModels["allies"] )
radiusDamage( uav.origin, 384, 5000, 5000 );
foreach ( uav in level._uavModels["axis"] )
radiusDamage( uav.origin, 384, 5000, 5000 );
}
else
{
foreach ( uav in level._uavModels )
radiusDamage( uav.origin, 384, 5000, 5000 );
}
if ( isDefined( level._ac130player ) )
radiusDamage( level._ac130.planeModel.origin+(0,0,10), 1000, 5000, 5000 );
}
}

View File

@ -0,0 +1,229 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
EXOSUIT_CHANGE_TIME_SECONDS = 3.0;
EXOSUIT_TABLE_FILE = "mp/exosuitTable.csv";
//*******************************************************************
// *
// *
//*******************************************************************
init()
{
precacheString( &"MPUI_CHANGING_SUIT" );
PrecacheItem( "aresminigun_mp" );
level._killStreakFuncs[ "exosuit" ] = ::tryUseExosuit;
}
//*******************************************************************
// *
// *
//*******************************************************************
tryUseExosuit( lifeId )
{
self thread chooseExosuit();
self waittill ( "suit_chosen" );
// suit perk will be set if the function above is successful
if ( self _hasPerk( "specialty_stealthsuit" ) || self _hasPerk( "specialty_agisuit" ) ||
self _hasPerk( "specialty_tacsuit" ) || self _hasPerk( "specialty_juggersuit" ) ||
self _hasPerk( "specialty_jetsuit" ))
{
return true;
}
else
{
return false;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
chooseExosuit()
{
self endon ( "death" );
self endon ( "disconnect" );
level endon ( "game_ended" );
suitName = "specialty_juggersuit";
if ( self isUsingRemote() )
{
if ( self getCurrentWeapon() == "killstreak_uav_mp" )
{
self _disableWeaponSwitch();
self _disableOffhandWeapons();
self _disableUsability();
self switchToWeapon( self getLastWeapon() );
self waittill ( "weapon_change" );
self _enableWeaponSwitch();
self _enableOffhandWeapons();
self _enableUsability();
}
self notify ( "suit_chosen" );
return;
}
else
{
assert( suitName == "specialty_stealthsuit" || suitName == "specialty_agisuit" ||
suitName == "specialty_tacsuit" || suitName == "specialty_juggersuit" ||
suitName == "specialty_jetsuit" );
self thread tryWearSuit( suitName );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
closeExosuitMenuOnDeath()
{
self endon ( "menuresponse" );
self endon ( "disconnect" );
level endon ( "game_ended" );
self waittill ( "death" );
self closePopupMenu();
}
//*******************************************************************
// *
// *
//*******************************************************************
tryWearSuit( suitName )
{
self endon ( "death" );
self endon ( "disconnect" );
level endon ( "game_ended" );
// tagTMR<TODO>: Add playLocalSound and playTeamSound here
if ( self _hasPerk( "specialty_twoprimaries" ))
{
self thread maps\mp\gametypes\_class::cleanHULChud();
self notify ( "disable_HULC" );
}
self _disableWeapon();
self _disableOffhandWeapons();
self _disableUsability();
// Don't want overpowered combinations so no perks will coexist with suits for now
self _clearPerks();
maps\mp\perks\_perks::givePerk( suitName );
self _enableWeapon();
self _enableOffhandWeapons();
self _enableUsability();
// tagSS<NOTE>: No attempt is made to save the previous model. This would be needed if the suit was able to be removed
// before dying, in order to restore the proper randomized character. Note that this also sets the model.
self detachAll();
self giveSuitWeapons( suitName );
// tagTMR<NOTE>: The detatchAll() above will remove the flag carried, reattached if the player's spoda have one
if ( isDefined( self.carryFlag ))
{
self attach( self.carryFlag, "J_spine4", true );
}
waitframe();
self notify ( "suit_chosen" );
}
//*******************************************************************
// *
// *
//*******************************************************************
exosuitUseBar()
{
self endon ( "disconnect" );
useBar = createPrimaryProgressBar( 25 );
useBarText = createPrimaryProgressBarText( 25 );
useBarText setText( &"MPUI_CHANGING_SUIT" );
useBar updateBar( 0, 1 / EXOSUIT_CHANGE_TIME_SECONDS );
for ( waitedTime = 0; waitedTime < EXOSUIT_CHANGE_TIME_SECONDS && isAlive( self ) && !level._gameEnded; waitedTime += 0.05 )
{
wait ( 0.05 );
}
useBar destroyElem();
useBarText destroyElem();
}
//*******************************************************************
// *
// *
//*******************************************************************
giveSuitWeapons( suitName )
{
primaryWeapon = tablelookup( EXOSUIT_TABLE_FILE, 1, suitName, 2 );
primaryAttachment = tablelookup( EXOSUIT_TABLE_FILE, 1, suitName, 3 );
primaryAttachment2 = tablelookup( EXOSUIT_TABLE_FILE, 1, suitName, 4 );
secondaryWeapon = tablelookup( EXOSUIT_TABLE_FILE, 1, suitName, 5 );
secondaryAttachment = tablelookup( EXOSUIT_TABLE_FILE, 1, suitName, 6 );
secondaryAttachment2 = tablelookup( EXOSUIT_TABLE_FILE, 1, suitName, 7 );
equipment = tablelookup( EXOSUIT_TABLE_FILE, 1, suitName, 8 );
loadoutOffhand = tablelookup( EXOSUIT_TABLE_FILE, 1, suitName, 9 );
// tagTMR<NOTE>: if there is no primary weapon, this suit will not have a weapon loadout to sub
if (primaryWeapon != "none")
{
self takeAllWeapons();
self.loadoutPrimary = primaryWeapon;
self.loadoutSecondary = secondaryWeapon;
primaryName = maps\mp\gametypes\_class::buildWeaponName( primaryWeapon, primaryAttachment, primaryAttachment2 );
self _giveWeapon( primaryName, self.loadoutPrimaryCamo );
self SwitchToWeapon ( primaryWeapon + "_mp" );
secondaryName = maps\mp\gametypes\_class::buildWeaponName( secondaryWeapon, secondaryAttachment, secondaryAttachment2 );
self _giveWeapon( secondaryName, self.loadoutSecondaryCamo );
self SetOffhandPrimaryClass( "other" );
equipment = maps\mp\perks\_perks::validatePerk( 1, equipment );
self maps\mp\perks\_perks::givePerk( equipment );
// Secondary Offhand
offhandSecondaryWeapon = loadoutOffhand + "_mp";
if ( loadoutOffhand == "flash_grenade" )
self SetOffhandSecondaryClass( "flash" );
else
self SetOffhandSecondaryClass( "smoke" );
self giveWeapon( offhandSecondaryWeapon );
if( loadOutOffhand == "smoke_grenade" )
self setWeaponAmmoClip( offhandSecondaryWeapon, 1 );
else if( loadOutOffhand == "flash_grenade" )
self setWeaponAmmoClip( offhandSecondaryWeapon, 2 );
else if( loadOutOffhand == "concussion_grenade" )
self setWeaponAmmoClip( offhandSecondaryWeapon, 2 );
else
self setWeaponAmmoClip( offhandSecondaryWeapon, 1 );
self.primaryWeapon = primaryName;
self.secondaryWeapon = secondaryName;
primaryTokens = strtok( primaryName, "_" );
self.pers["primaryWeapon"] = primaryTokens[0];
self.isSniper = (weaponClass( self.primaryWeapon ) == "sniper");
}
self maps\mp\gametypes\_teams::playerModelForWeapon( self.pers["primaryWeapon"], getBaseWeaponName( self.secondaryWeapon ) );
self maps\mp\gametypes\_weapons::updateMoveSpeedScale( "primary" );
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,440 @@
#include maps\mp\_utility;
#include common_scripts\utility;
JET_MISSILE_DIRECTION = ( 1.0, 1.0, 20.0 );
// Each Killstreak has its own initialization function. This Script has two main purposes.
// (1). All global data and assets used by this killstreak should be initialized here.
// (2). The callback that executes when a player activates this killstreak should be set here.
// TODO: A call to this script must be added to the script init() in the file c:\trees\nx1\game\share\raw\maps\mp\killstreaks\_killstreaks.gsc,
// this is were each individual killstreak is initialized.
init()
{
//precacheItem( "f50_remote_mp" );
precacheModel( "vehicle_f50" );
PrecacheMiniMapIcon( "compass_objpoint_airstrike_friendly" );
PrecacheMiniMapIcon( "compass_objpoint_airstrike_busy" );
PrecacheMiniMapIcon( "compass_objpoint_b2_airstrike_friendly" );
PrecacheMiniMapIcon( "compass_objpoint_b2_airstrike_enemy" );
level._killStreakFuncs["jet"] = ::tryUseJet;
level._onfirefx = loadfx ("fire/fire_smoke_trail_L");
level._fx_airstrike_afterburner = loadfx ("fire/jet_afterburner");
level._fx_airstrike_contrail = loadfx ("smoke/jet_contrail");
level._planes = 0;
level._rockets = [];
}
tryUseJet( lifeId )
{
println( "tryuseJet" );
if ( isDefined( level._civilianJetFlyBy ) )
{
self iPrintLnBold( &"MP_CIVILIAN_AIR_TRAFFIC" );
return false;
}
if ( self isUsingRemote() )
{
return false;
}
result = self selectJetLocation( lifeId );
if ( !isDefined( result ) || !result )
return false;
return true;
}
selectJetLocation( lifeId )
{
println( "SelectJetLocation" );
chooseDirection = true;
targetSize = level._mapSize / 5.625; // 138 in 720
if ( level._splitscreen )
targetSize *= 1.5;
self beginLocationSelection( "map_artillery_selector", chooseDirection, false, targetSize );
self.selectingLocation = true;
self setblurforplayer( 4.0, 0.3 );
self thread waitForJetCancel();
self thread endJetSelectionOn( "cancel_location" );
self thread endJetSelectionOn( "death" );
self thread endJetSelectionOn( "disconnect" );
self thread endJetSelectionOn( "used" ); // so that this thread doesn't kill itself when we use an airstrike
self thread endJetSelectionOnGameEnd();
self thread endJetSelectionOnEMP();
self endon( "stop_location_selection" );
// wait for the selection. randomize the yaw if we're not doing a precision airstrike.
self waittill( "confirm_location", location, directionYaw );
self setblurforplayer( 0, 0.3 );
self thread finishJetUsage( lifeId, location, directionYaw );
return true;
}
finishJetUsage( lifeId, location, directionYaw )
{
println( "finishJetUsage" );
self notify( "used" );
// find underside of top of skybox
trace = bullettrace( level._mapCenter + (0,0,1000000), level._mapCenter, false, undefined );
location = (location[0], location[1], trace["position"][2] - 514);
self thread doJetAirStrike( lifeId, location, directionYaw, self, self.pers["team"] );
}
doJetAirStrike( lifeId, origin, yaw, owner, team )
{
println( "doJetAirStrike" );
assert( isDefined( origin ) );
assert( isDefined( yaw ) );
if ( isDefined( level._airstrikeInProgress ) )
{
while ( isDefined( level._airstrikeInProgress ) )
level waittill ( "begin_airstrike" );
level._airstrikeInProgress = true;
wait ( 2.0 );
}
if ( !isDefined( owner ) )
{
return;
}
level._airstrikeInProgress = true;
num = 17 + randomint(3);
trace = bullettrace(origin, origin + (0,0,-1000000), false, undefined);
targetpos = trace["position"];
if ( level._teambased )
{
players = level._players;
for ( i = 0; i < level._players.size; i++ )
{
player = level._players[i];
playerteam = player.pers["team"];
if ( isdefined( playerteam ) )
{
player iprintln( &"MP_WAR_AIRSTRIKE_INBOUND", owner );
}
}
}
self callJetStrike( lifeId, owner, targetpos, yaw );
wait( 1.0 );
level._airstrikeInProgress = undefined;
owner notify ( "begin_airstrike" );
level notify ( "begin_airstrike" );
wait 7.5;
found = false;
}
callJetStrike( lifeId, owner, coord, yaw )
{
println( "calljetstrike" );
heightEnt = undefined;
// Get starting and ending point for the plane
direction = ( 0, yaw, 0 );
heightEnt = GetEnt( "airstrikeheight", "targetname" );
thread teamPlayerCardSplash( "used_stealth_airstrike", owner, owner.team );
planeHalfDistance = 12000;
planeFlySpeed = 2000;
if ( !isDefined( heightEnt ) )//old system
{
println( "NO DEFINED AIRSTRIKE HEIGHT SCRIPT_ORIGIN IN LEVEL" );
planeFlyHeight = 2000;
if ( isdefined( level._airstrikeHeightScale ) )
{
planeFlyHeight *= level._airstrikeHeightScale;
}
}
else
{
planeFlyHeight = heightEnt.origin[2];
}
startPoint = coord + vector_multiply( anglestoforward( direction ), -1 * planeHalfDistance );
if ( isDefined( heightEnt ) )// used in the new height system
startPoint *= (1,1,0);
startPoint += ( 0, 0, planeFlyHeight );
endPoint = coord + vector_multiply( anglestoforward( direction ), planeHalfDistance*4 );
if ( isDefined( heightEnt ) )// used in the new height system
endPoint *= (1,1,0);
endPoint += ( 0, 0, planeFlyHeight );
// Make the plane fly by
d = length( startPoint - endPoint );
flyTime = ( d / planeFlySpeed );
owner endon("disconnect");
requiredDeathCount = lifeId;
self doJetStrike( lifeId, owner, startPoint+(0,0,randomInt(1000)), endPoint+(0,0,randomInt(1000)), flyTime, direction );
}
endJetSelectionOn( waitfor )
{
self endon( "stop_location_selection" );
self waittill( waitfor );
self thread stopJetLocationSelection( (waitfor == "disconnect") );
}
endJetSelectionOnGameEnd()
{
self endon( "stop_location_selection" );
level waittill( "game_ended" );
self thread stopJetLocationSelection( false );
}
endJetSelectionOnEMP()
{
self endon( "stop_location_selection" );
for ( ;; )
{
level waittill( "emp_update" );
if ( !self isEMPed() )
continue;
self thread stopJetLocationSelection( false );
return;
}
}
doJetStrike( lifeId, owner, startPoint, endPoint, flyTime, direction )
{
self notifyOnPlayerCommand( "trigger_pulled", "+attack" );
// plane spawning randomness = up to 125 units, biased towards 0
// radius of bomb damage is 512
println( "doJetStrike" );
if ( !isDefined( owner ) )
return;
startPathRandomness = 100;
endPathRandomness = 150;
pathStart = startPoint + ( (randomfloat(2) - 1)*startPathRandomness, (randomfloat(2) - 1)*startPathRandomness, 0 );
pathEnd = endPoint + ( (randomfloat(2) - 1)*endPathRandomness , (randomfloat(2) - 1)*endPathRandomness , 0 );
// Spawn the planes
plane = spawnplane( owner, "script_model", pathStart, "compass_objpoint_b2_airstrike_friendly", "compass_objpoint_b2_airstrike_enemy" );
plane playLoopSound( "veh_b2_dist_loop" );
plane setModel( "vehicle_f50" );
plane thread handleJetEMP( owner );
plane.lifeId = lifeId;
plane.angles = direction;
forward = anglesToForward( direction );
plane thread playJetPlaneFx();
//self HideHud();
//self VisionSetMissilecamForPlayer( game["thermal_vision"], 1.0 );
self PlayerLinkWeaponviewToDelta( plane, "tag_player", 1.0, 45, 45, 0, 45, false );
//self CameraLinkTo( plane, "tag_player" );
//self ThermalVisionOn();
//self ThermalVisionFOFOverlayOn();
self _giveWeapon("heli_remote_mp");
self SwitchToWeapon( "heli_remote_mp" );
self DisableWeaponSwitch();
self _disableOffhandWeapons();
plane moveTo( pathEnd, flyTime, 0, 0 );
println ("Before loop");
plane thread jetTimeout( flyTime );
self waittill ("trigger_pulled");
println ("Fired Gun" );
origin = self GetEye();
forward = AnglesToForward( self GetPlayerAngles() );
endpoint = origin + forward;
println ( "origin :" + origin );
println ( "endpoint :" + endpoint );
println ( "forward :" + forward );
//bomb = spawnbomb( plane.origin, plane.angles );
//bomb moveGravity( vector_multiply( anglestoforward( plane.angles ), 7000/1.5 ), 3.0 );
rocket = MagicBullet( "remotemissile_projectile_mp", origin, endpoint, owner );
rocket thread JetMissilehandleDamage();
self unlink();
self CameraLinkTo( rocket, "tag_origin" );
self ControlsLinkTo( rocket );
//self ThermalVisionFOFOverlayOff();
rocket thread JetRocket_CleanupOnDeath();
rocket waittill( "death" );
self thread staticEffect( 0.5 );
self ControlsUnlink();
self CameraUnlink();
self thread Weapon_Return ();
println ("done with loop");
}
jetTimeout( flyTime )
{
// Delete the plane after its flyby
wait ( flyTime / 2.3 );
self notify( "delete" );
self delete();
}
waitForJetCancel()
{
self waittill( "cancel_location" );
self setblurforplayer( 0, 0.3 );
}
stopJetLocationSelection( disconnected )
{
if ( !disconnected )
{
self setblurforplayer( 0, 0.3 );
self endLocationSelection();
self.selectingLocation = undefined;
}
self notify( "stop_location_selection" );
}
useJet( lifeId, pos, yaw )
{
}
handleJetEMP( owner )
{
self endon ( "death" );
if ( owner isEMPed() )
{
playFxOnTag( level._onfirefx, self, "tag_engine_right" );
playFxOnTag( level._onfirefx, self, "tag_engine_left" );
return;
}
for ( ;; )
{
level waittill ( "emp_update" );
if ( !owner isEMPed() )
continue;
playFxOnTag( level._onfirefx, self, "tag_engine_right" );
playFxOnTag( level._onfirefx, self, "tag_engine_left" );
}
}
JetRocket_CleanupOnDeath()
{
entityNumber = self getEntityNumber();
level._rockets[ entityNumber ] = self;
self waittill( "death" );
level._rockets[ entityNumber ] = undefined;
}
Weapon_Return()
{
//self showhud;
self takeWeapon( "heli_remote_mp" );
self enableWeaponSwitch();
self switchToWeapon( self getLastWeapon() );
self _enableOffhandWeapons();
}
JetMissilehandleDamage()
{
self endon ( "death" );
self endon ( "deleted" );
self setCanDamage( true );
for ( ;; )
{
self waittill( "damage" );
println ( "projectile damaged!" );
}
}
playJetPlaneFx()
{
self endon ( "death" );
wait( 0.5);
playfxontag( level._fx_airstrike_afterburner, self, "tag_engine_right" );
wait( 0.5);
playfxontag( level._fx_airstrike_afterburner, self, "tag_engine_left" );
wait( 0.5);
playfxontag( level._fx_airstrike_contrail, self, "tag_right_wingtip" );
wait( 0.5);
playfxontag( level._fx_airstrike_contrail, self, "tag_left_wingtip" );
}
staticEffect( duration )
{
self endon ( "disconnect" );
staticBG = newClientHudElem( self );
staticBG.horzAlign = "fullscreen";
staticBG.vertAlign = "fullscreen";
staticBG setShader( "white", 640, 480 );
staticBG.archive = true;
staticBG.sort = 10;
static = newClientHudElem( self );
static.horzAlign = "fullscreen";
static.vertAlign = "fullscreen";
static setShader( "ac130_overlay_grain", 640, 480 );
static.archive = true;
static.sort = 20;
wait ( duration );
static destroy();
staticBG destroy();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,316 @@
#include common_scripts\utility;
#include maps\mp\_utility;
init()
{
precacheItem( "nuke_mp" );
precacheLocationSelector( "map_nuke_selector" );
precacheString( &"MP_TACTICAL_NUKE_CALLED" );
precacheString( &"MP_FRIENDLY_TACTICAL_NUKE" );
precacheString( &"MP_TACTICAL_NUKE" );
level._effect[ "nuke_player" ] = loadfx( "explosions/player_death_nuke" );
level._effect[ "nuke_flash" ] = loadfx( "explosions/player_death_nuke_flash" );
level._effect[ "nuke_aftermath" ] = loadfx( "dust/nuke_aftermath_mp" );
game["strings"]["nuclear_strike"] = &"MP_TACTICAL_NUKE";
level._killstreakFuncs["nuke"] = ::tryUseNuke;
setDvarIfUninitialized( "scr_nukeTimer", 10 );
setDvarIfUninitialized( "scr_nukeCancelMode", 0 );
level._nukeTimer = getDvarInt( "scr_nukeTimer" );
level._cancelMode = getDvarInt( "scr_nukeCancelMode" );
/#
setDevDvarIfUninitialized( "scr_nukeDistance", 5000 );
setDevDvarIfUninitialized( "scr_nukeEndsGame", true );
setDevDvarIfUninitialized( "scr_nukeDebugPosition", false );
#/
}
tryUseNuke( lifeId, allowCancel )
{
if( isDefined( level._nukeIncoming ) )
{
self iPrintLnBold( &"MP_NUKE_ALREADY_INBOUND" );
return false;
}
if ( self isUsingRemote() && ( !isDefined( level._gtnw ) || !level._gtnw ) )
return false;
if ( !isDefined( allowCancel ) )
allowCancel = true;
self thread doNuke( allowCancel );
self notify( "used_nuke" );
return true;
}
delaythread_nuke( delay, func )
{
level endon ( "nuke_cancelled" );
wait ( delay );
thread [[ func ]]();
}
doNuke( allowCancel )
{
level endon ( "nuke_cancelled" );
level._nukeInfo = spawnStruct();
level._nukeInfo.player = self;
level._nukeInfo.team = self.pers["team"];
level._nukeIncoming = true;
maps\mp\gametypes\_gamelogic::pauseTimer();
level._timeLimitOverride = true;
setGameEndTime( int( gettime() + (level._nukeTimer * 1000) ) );
setDvar( "ui_bomb_timer", 4 ); // Nuke sets '4' to avoid briefcase icon showing
if ( level._teambased )
{
thread teamPlayerCardSplash( "used_nuke", self, self.team );
/*
players = level.players;
foreach( player in level.players )
{
playerteam = player.pers["team"];
if ( isdefined( playerteam ) )
{
if ( playerteam == self.pers["team"] )
player iprintln( &"MP_TACTICAL_NUKE_CALLED", self );
}
}
*/
}
else
{
if ( !level._hardcoreMode )
self iprintlnbold(&"MP_FRIENDLY_TACTICAL_NUKE");
}
level thread delaythread_nuke( (level._nukeTimer - 3.3), ::nukeSoundIncoming );
level thread delaythread_nuke( level._nukeTimer, ::nukeSoundExplosion );
level thread delaythread_nuke( level._nukeTimer, ::nukeSlowMo );
level thread delaythread_nuke( level._nukeTimer, ::nukeEffects );
level thread delaythread_nuke( (level._nukeTimer + 0.25), ::nukeVision );
level thread delaythread_nuke( (level._nukeTimer + 1.5), ::nukeDeath );
level thread delaythread_nuke( (level._nukeTimer + 1.5), ::nukeEarthquake );
level thread nukeAftermathEffect();
if ( level._cancelMode && allowCancel )
level thread cancelNukeOnDeath( self );
// leaks if lots of nukes are called due to endon above.
clockObject = spawn( "script_origin", (0,0,0) );
clockObject hide();
while ( !isDefined( level._nukeDetonated ) )
{
clockObject playSound( "ui_mp_nukebomb_timer" );
wait( 1.0 );
}
}
cancelNukeOnDeath( player )
{
player waittill_any( "death", "disconnect" );
if ( isDefined( player ) && level._cancelMode == 2 )
player thread maps\mp\killstreaks\_emp::EMP_Use( 0, 0 );
maps\mp\gametypes\_gamelogic::resumeTimer();
level._timeLimitOverride = false;
setDvar( "ui_bomb_timer", 0 ); // Nuke sets '4' to avoid briefcase icon showing
level notify ( "nuke_cancelled" );
}
nukeSoundIncoming()
{
level endon ( "nuke_cancelled" );
foreach( player in level._players )
player playlocalsound( "nuke_incoming" );
}
nukeSoundExplosion()
{
level endon ( "nuke_cancelled" );
foreach( player in level._players )
{
player playlocalsound( "nuke_explosion" );
player playlocalsound( "nuke_wave" );
}
}
nukeEffects()
{
level endon ( "nuke_cancelled" );
setDvar( "ui_bomb_timer", 0 );
setGameEndTime( 0 );
level._nukeDetonated = true;
level maps\mp\killstreaks\_emp::destroyActiveVehicles( level._nukeInfo.player );
foreach( player in level._players )
{
playerForward = anglestoforward( player.angles );
playerForward = ( playerForward[0], playerForward[1], 0 );
playerForward = VectorNormalize( playerForward );
nukeDistance = 5000;
/# nukeDistance = getDvarInt( "scr_nukeDistance" ); #/
nukeEnt = Spawn( "script_model", player.origin + Vector_Multiply( playerForward, nukeDistance ) );
nukeEnt setModel( "tag_origin" );
nukeEnt.angles = ( 0, (player.angles[1] + 180), 90 );
/#
if ( getDvarInt( "scr_nukeDebugPosition" ) )
{
lineTop = ( nukeEnt.origin[0], nukeEnt.origin[1], (nukeEnt.origin[2] + 500) );
thread draw_line_for_time( nukeEnt.origin, lineTop, 1, 0, 0, 10 );
}
#/
nukeEnt thread nukeEffect( player );
player.nuked = true;
}
}
nukeEffect( player )
{
level endon ( "nuke_cancelled" );
player endon( "disconnect" );
waitframe();
PlayFXOnTagForClients( level._effect[ "nuke_flash" ], self, "tag_origin", player );
}
nukeAftermathEffect()
{
level endon ( "nuke_cancelled" );
level waittill ( "spawning_intermission" );
afermathEnt = getEntArray( "mp_global_intermission", "classname" );
afermathEnt = afermathEnt[0];
up = anglestoup( afermathEnt.angles );
right = anglestoright( afermathEnt.angles );
PlayFX( level._effect[ "nuke_aftermath" ], afermathEnt.origin, up, right );
}
nukeSlowMo()
{
level endon ( "nuke_cancelled" );
//SetSlowMotion( <startTimescale>, <endTimescale>, <deltaTime> )
setSlowMotion( 1.0, 0.25, 0.5 );
level waittill( "nuke_death" );
setSlowMotion( 0.25, 1, 2.0 );
}
nukeVision()
{
level endon ( "nuke_cancelled" );
level._nukeVisionInProgress = true;
visionSetNaked( "mpnuke", 3 );
level waittill( "nuke_death" );
visionSetNaked( "mpnuke_aftermath", 5 );
wait 5;
level._nukeVisionInProgress = undefined;
}
nukeDeath()
{
level endon ( "nuke_cancelled" );
level notify( "nuke_death" );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
AmbientStop(1);
foreach( player in level._players )
{
if ( isAlive( player ) )
player thread maps\mp\gametypes\_damage::finishPlayerDamageWrapper( level._nukeInfo.player, level._nukeInfo.player, 999999, 0, "MOD_EXPLOSIVE", "nuke_mp", player.origin, player.origin, "none", 0, 0 );
}
level._postRoundTime = 10;
nukeEndsGame = true;
if ( level._teamBased )
thread maps\mp\gametypes\_gamelogic::endGame( level._nukeInfo.team, game["strings"]["nuclear_strike"], true );
else
{
if ( isDefined( level._nukeInfo.player ) )
thread maps\mp\gametypes\_gamelogic::endGame( level._nukeInfo.player, game["strings"]["nuclear_strike"], true );
else
thread maps\mp\gametypes\_gamelogic::endGame( level._nukeInfo, game["strings"]["nuclear_strike"], true );
}
}
nukeEarthquake()
{
level endon ( "nuke_cancelled" );
level waittill( "nuke_death" );
// TODO: need to get a different position to call this on
//earthquake( 0.6, 10, nukepos, 100000 );
//foreach( player in level.players )
//player PlayRumbleOnEntity( "damage_heavy" );
}
waitForNukeCancel()
{
self waittill( "cancel_location" );
self setblurforplayer( 0, 0.3 );
}
endSelectionOn( waitfor )
{
self endon( "stop_location_selection" );
self waittill( waitfor );
self thread stopNukeLocationSelection( (waitfor == "disconnect") );
}
endSelectionOnGameEnd()
{
self endon( "stop_location_selection" );
level waittill( "game_ended" );
self thread stopNukeLocationSelection( false );
}
stopNukeLocationSelection( disconnected )
{
if ( !disconnected )
{
self setblurforplayer( 0, 0.3 );
self endLocationSelection();
self.selectingLocation = undefined;
}
self notify( "stop_location_selection" );
}

View File

@ -0,0 +1,711 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
precacheString( &"MP_LASE_TARGET_FOR_GUIDED_MORTAR" );
precacheString( &"MP_WAIT_FOR_MORTAR_READY" );
precacheString( &"MP_MORTAR_ROUNDS_DEPLETED" );
precacheString( &"SPLASHES_DESTROYED_REMOTE_MORTAR" );
precacheModel( "vehicle_predator_b" );
precacheItem( "remote_mortar_missile_mp" );
precacheItem( "mortar_remote_mp" );
precacheItem( "mortar_remote_zoom_mp" );
precacheShader( "compass_waypoint_bomb" );
precacheShader( "viper_locked_box" );
PrecacheMiniMapIcon( "compass_objpoint_reaper_friendly" );
PrecacheMiniMapIcon( "compass_objpoint_reaper_enemy" );
level._remote_mortar_fx["laserTarget"] = loadfx("nx/misc/nx_laser_glow");
level._killstreakFuncs["reaper"] = ::tryUseRemoteMortar;
/#
SetDevDvarIfUninitialized( "scr_remote_mortar_timeout", 40.0 );
#/
}
tryUseRemoteMortar( lifeId )
{
if ( isDefined( self.lastStand ) && !self _hasPerk( "specialty_finalstand" ) )
{
self iPrintLnBold( &"MP_UNAVILABLE_IN_LASTSTAND" );
return false;
}
self setUsingRemote( "remote_mortar" );
/* result = self maps\mp\killstreaks\_killstreaks::initRideKillstreak();
if ( result != "success" )
{
if ( result != "disconnect" )
self clearUsingRemote();
return false;
}
*/
self maps\mp\_matchdata::logKillstreakEvent( "remote_mortar", self.origin );
return startRemoteMortar( lifeId );
}
startRemoteMortar( lifeId )
{
remote = spawnRemote( lifeId, self );
if ( !isDefined( remote ) )
return false;
self setPlayerData( "reaperHUD", "targetDistance", -1 );
self remoteRide( remote );
self thread teamPlayerCardSplash( "used_remote_mortar", self );
return true;
}
spawnRemote( lifeId, owner )
{
remote = spawnPlane( owner, "script_model", level._UAVRig getTagOrigin( "tag_origin" ), "compass_objpoint_reaper_friendly", "compass_objpoint_reaper_enemy" );
if ( !isDefined( remote ) )
return undefined;
remote setModel( "vehicle_predator_b" );
remote.lifeId = lifeId;
remote.team = owner.team;
remote.owner = owner;
remote.numFlares = 1;
remote setCanDamage( true );
remote thread damageTracker();
remote.heliType = "remote_mortar";
// for target lists (javelin, stinger, sam, emp, etc)
remote.uavType = "remote_mortar";
maps\mp\killstreaks\_uav::addUAVModel( remote );
// same height and radius as the AC130 with random angle and counter rotation
zOffset = 6300;
angle = randomInt( 360 );
radiusOffset = 6100;
xOffset = cos( angle ) * radiusOffset;
yOffset = sin( angle ) * radiusOffset;
angleVector = vectorNormalize( (xOffset,yOffset,zOffset) );
angleVector = ( angleVector * 6100 );
remote linkTo( level._UAVRig, "tag_origin", angleVector, (0,angle-90,10) );
remote thread handleDeath( owner );
remote thread handleTimeout( owner );
remote thread handleOwnerChangeTeam( owner );
remote thread handleOwnerDisconnect( owner );
remote thread handleIncomingStinger();
remote thread handleIncomingSAM();
return remote;
}
lookCenter()
{
wait( 0.05 );
lookVec = vectorToAngles( level._UAVRig.origin - self GetEye() );
self setPlayerAngles( lookVec );
}
remoteRide( remote )
{
self setPlayerData( "reaperHUD", "zoomed", false );
self _giveWeapon("mortar_remote_mp");
self SwitchToWeapon("mortar_remote_mp");
self ThermalVisionFOFOverlayOn();
if ( getDvarInt( "camera_thirdPerson" ) )
self setThirdPersonDOF( false );
self PlayerLinkWeaponviewToDelta( remote, "tag_player", 1.0, 35, 35, 15, 55 );
self thread lookCenter();
self thread remoteTargeting( remote );
self thread remoteFiring( remote );
self thread remoteZoom( remote );
}
remoteTargeting( remote )
{
level endon( "game_ended" );
self endon( "disconnect" );
remote endon( "remote_done" );
remote endon( "death" );
remote.targetEnt = SpawnFx( level._remote_mortar_fx["laserTarget"], (0,0,0) );
remote.targetEnt.icon = remote.targetEnt maps\mp\_entityheadIcons::setHeadIcon( self, "viper_locked_box", (0,0,-270), 100, 100, false, 0.05, false, false, false, false );
remote.targetEnt.icon.color = (0.9, 0.7, 0.2);
/*laserPos = remote getTagOrigin( "tag_player" );
remote.laserEnt = Spawn( "script_model", laserPos );
remote.laserEnt linkTo( remote, "tag_player", (0,0,0), (0,0,0) );
remote.laserEnt LaserOn();*/
while ( true )
{
origin = self GetEye();
forward = AnglesToForward( self GetPlayerAngles() );
endpoint = origin + forward * 15000;
traceData = BulletTrace( origin, endpoint, false, remote.targetEnt );
if ( isDefined( traceData["position"] ) )
{
remote.targetEnt.origin = traceData["position"];
triggerFX( remote.targetEnt );
}
wait( 0.05 );
}
}
remoteFiring( remote )
{
level endon( "game_ended" );
self endon( "disconnect" );
remote endon( "remote_done" );
remote endon( "death" );
curTime = getTime();
lastFireTime = curTime-750;
shotsFired = 0;
while( true )
{
curTime = getTime();
if ( self attackButtonPressed() && ( curTime - lastFireTime > 3000 ) )
{
shotsFired++;
lastFireTime = curTime;
self playLocalSound( "stinger_locking" );
self PlayRumbleOnEntity( "damage_heavy" );
origin = self GetEye();
forward = AnglesToForward( self GetPlayerAngles() );
right = AnglesToRight( self GetPlayerAngles() );
offset = origin + ( forward * 100 ) + ( right * -100 );
missile = MagicBullet( "remote_mortar_missile_mp", offset, remote.targetEnt.origin, self );
missile Missile_SetTargetEnt( remote.targetEnt );
missile Missile_SetFlightmodeDirect();
missile.icon = missile maps\mp\_entityheadIcons::setHeadIcon( self, "compass_waypoint_bomb", (0,0,-10), 10, 10, false, 0.05, false, false, false, false );
missile thread remoteMissileDistance( remote );
remote.missileIcon = missile.icon;
missile waittill( "death" );
if ( isDefined( missile.icon ) )
{
missile.icon destroy();
missile.icon = undefined;
}
self setPlayerData( "reaperHUD", "targetDistance", -1 );
if ( shotsFired == 14 )
break;
}
else
wait( 0.05 );
}
self remoteEndRide( remote );
remote thread remoteLeave();
}
remoteZoom( remote )
{
level endon( "game_ended" );
self endon( "disconnect" );
remote endon( "remote_done" );
remote endon( "death" );
remote.zoomed = false;
while ( true )
{
if ( self adsButtonPressed() )
{
if ( remote.zoomed == false )
{
self _giveWeapon("mortar_remote_zoom_mp");
self SwitchToWeapon("mortar_remote_zoom_mp");
remote.zoomed = true;
self setPlayerData( "reaperHUD", "zoomed", true );
if ( isDefined( remote.targetEnt.icon ) )
{
remote.targetEnt.icon destroy();
remote.targetEnt.icon = undefined;
remote.targetEnt.icon = remote.targetEnt maps\mp\_entityheadIcons::setHeadIcon( self, "viper_locked_box", (0,0,-50), 100, 100, false, 0.05, false, false, false, false );
remote.targetEnt.icon.color = (0.9, 0.7, 0.2);
}
}
}
else
{
if ( remote.zoomed == true )
{
self _giveWeapon("mortar_remote_mp");
self SwitchToWeapon("mortar_remote_mp");
remote.zoomed = false;
self setPlayerData( "reaperHUD", "zoomed", false );
if ( isDefined( remote.targetEnt.icon ) )
{
remote.targetEnt.icon destroy();
remote.targetEnt.icon = undefined;
remote.targetEnt.icon = remote.targetEnt maps\mp\_entityheadIcons::setHeadIcon( self, "viper_locked_box", (0,0,-270), 100, 100, false, 0.05, false, false, false, false );
remote.targetEnt.icon.color = (0.9, 0.7, 0.2);
}
}
}
wait( 0.05 );
}
}
remoteMissileDistance( remote )
{
level endon( "game_ended" );
remote endon( "death" );
remote endon( "remote_done" );
self endon( "death" );
while( true )
{
targetDist = distance( self.origin, remote.targetent.origin );
remote.owner setPlayerData( "reaperHUD", "targetDistance", int( targetDist / 12 ) );
wait( 0.05 );
}
}
remoteEndRide( remote )
{
if ( isDefined( remote ) )
{
remote notify( "helicopter_done" );
if ( isDefined( remote.laserEnt ) )
remote.laserEnt LaserOff();
if ( isDefined( remote.targetEnt ) && isDefined( remote.targetEnt.icon ) )
{
remote.targetEnt.icon destroy();
remote.targetEnt.icon = undefined;
}
if ( isDefined( remote.missileIcon ) )
{
remote.missileIcon destroy();
remote.missileIcon = undefined;
}
}
self ThermalVisionFOFOverlayOff();
self unlink();
self clearUsingRemote();
if ( getDvarInt( "camera_thirdPerson" ) )
self setThirdPersonDOF( true );
self switchToWeapon( self getLastWeapon() );
weaponList = self GetWeaponsListExclusives();
foreach ( weapon in weaponList )
self takeWeapon( weapon );
}
handleTimeout( owner )
{
level endon( "game_ended" );
owner endon( "disconnect" );
self endon( "death" );
lifeSpan = 40.0;
/#
lifeSpan = GetDvarInt( "scr_remote_mortar_timeout", lifeSpan );
#/
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( lifeSpan );
if ( isDefined( owner ) )
owner remoteEndRide( self );
self thread remoteLeave();
}
handleDeath( owner )
{
level endon( "game_ended" );
owner endon( "disconnect" );
self endon( "remote_done" );
self waittill( "death" );
if ( isDefined( owner ) )
owner remoteEndRide( self );
level thread removeRemote( self );
}
handleOwnerChangeTeam( owner )
{
level endon( "game_ended" );
self endon( "remote_done" );
self endon( "death" );
owner endon( "disconnect" );
owner waittill_any( "joined_team", "joined_spectators" );
if ( isDefined( owner ) )
owner remoteEndRide( self );
self thread remoteLeave();
}
handleOwnerDisconnect( owner )
{
level endon( "game_ended" );
self endon( "remote_done" );
self endon( "death" );
owner waittill( "disconnect" );
self thread remoteLeave();
}
removeRemote( remote )
{
self notify( "remote_removed" );
if ( isDefined( remote.targetEnt ) )
{
if ( isDefined( remote.targetEnt.icon ) )
{
remote.targetEnt.icon destroy();
remote.targetEnt.icon = undefined;
}
remote.targetEnt delete();
}
if ( isDefined( remote.laserEnt ) )
remote.laserEnt delete();
if( IsDefined( remote ) )
{
remote delete();
maps\mp\killstreaks\_uav::removeUAVModel( remote );
}
}
remoteLeave()
{
level endon( "game_ended" );
self endon( "death" );
self notify( "remote_done" );
self unlink();
destPoint = self.origin + ( AnglesToForward( self.angles ) * 20000 );
self moveTo( destPoint, 30 );
PlayFXOnTag( level._effect[ "ac130_engineeffect" ] , self, "tag_origin" );
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 3 );
self moveTo( destPoint, 4, 4, 0.0 );
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 4 );
level thread removeRemote( self );
}
// Entities spawned from SpawnPlane do not respond to pre-damage callbacks
// so we have to wait until we get the post-damage event.
//
// Because the damage has already happened by the time we find out about it,
// we need to use an artificially high health value, restore it on erroneous damage
// events and track a virtual damage taken against a virtual max health.
damageTracker()
{
level endon( "game_ended" );
self.owner endon( "disconnect" );
self.health = 999999; // keep it from dying anywhere in code
self.maxHealth = 1000; // this is the health we'll check
self.damageTaken = 0; // how much damage has it taken
while( true )
{
self waittill( "damage", damage, attacker, direction_vec, point, meansOfDeath, modelName, tagName, partName, iDFlags, weapon );
// don't allow people to destroy things on their team if FF is off
if ( !maps\mp\gametypes\_weapons::friendlyFireCheck( self.owner, attacker ) )
continue;
if ( !IsDefined( self ) )
return;
if ( isDefined( iDFlags ) && ( iDFlags & level._iDFLAGS_PENETRATION ) )
self.wasDamagedFromBulletPenetration = true;
self.wasDamaged = true;
modifiedDamage = damage;
if( IsPlayer( attacker ) )
{
attacker maps\mp\gametypes\_damagefeedback::updateDamageFeedback( "" );
if( meansOfDeath == "MOD_RIFLE_BULLET" || meansOfDeath == "MOD_PISTOL_BULLET" )
{
if ( attacker _hasPerk( "specialty_armorpiercing" ) )
modifiedDamage += damage * level._armorPiercingMod;
}
}
if( IsDefined( weapon ) )
{
switch( weapon )
{
case "stinger_mp":
case "javelin_mp":
self.largeProjectileDamage = true;
modifiedDamage = self.maxhealth + 1;
break;
case "sam_projectile_mp":
self.largeProjectileDamage = true;
modifiedDamage *= 2.0; // takes about 1 burst of sam rockets
break;
}
}
self.damageTaken += modifiedDamage;
if ( self.damageTaken >= self.maxHealth )
{
if ( isPlayer( attacker ) && ( !isDefined( self.owner ) || attacker != self.owner ) )
{
self Hide();
forward = ( AnglesToRight( self.angles ) * 200 );
playFx ( level._uav_fx[ "explode" ], self.origin, forward );
attacker notify( "destroyed_killstreak", weapon );
thread teamPlayerCardSplash( "callout_destroyed_remote_mortar", attacker );
//attacker thread maps\mp\gametypes\_rank::giveRankXP( "kill", 50, weapon, meansOfDeath );
//attacker thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_DESTROYED_REMOTE_MORTAR" );
//thread maps\mp\gametypes\_missions::vehicleKilled( self.owner, self, undefined, attacker, damage, meansOfDeath, weapon );
}
self notify( "death" );
return;
}
}
}
handleIncomingStinger() // self == remote mortar
{
level endon ( "game_ended" );
self endon ( "death" );
while( true )
{
level waittill ( "stinger_fired", player, missile, lockTarget );
if ( !IsDefined( lockTarget ) || (lockTarget != self) )
continue;
missile thread stingerProximityDetonate( lockTarget, player );
}
}
stingerProximityDetonate( missileTarget, player ) // self == missile
{
self endon ( "death" );
if( IsDefined( missileTarget.owner ) )
missileTarget.owner PlayLocalSound( "missile_incoming" );
self Missile_SetTargetEnt( missileTarget );
minDist = Distance( self.origin, missileTarget GetPointInBounds( 0, 0, 0 ) );
lastCenter = missileTarget GetPointInBounds( 0, 0, 0 );
while( true )
{
// already destroyed
if( !IsDefined( missileTarget ) )
center = lastCenter;
else
center = missileTarget GetPointInBounds( 0, 0, 0 );
lastCenter = center;
curDist = Distance( self.origin, center );
if( curDist < 3000 && missileTarget.numFlares > 0 )
{
missileTarget.numFlares--;
missileTarget thread maps\mp\killstreaks\_helicopter::playFlareFx();
newTarget = missileTarget maps\mp\killstreaks\_helicopter::deployFlares();
self Missile_SetTargetEnt( newTarget );
missileTarget = newTarget;
if( IsDefined( missileTarget.owner ) )
missileTarget.owner StopLocalSound( "missile_incoming" );
return;
}
if( curDist < minDist )
minDist = curDist;
if( curDist > minDist )
{
if( curDist > 1536 )
return;
if( IsDefined( missileTarget.owner ) )
{
missileTarget.owner stopLocalSound( "missile_incoming" );
if( level._teambased )
{
if( missileTarget.team != player.team )
RadiusDamage( self.origin, 1000, 1000, 1000, player, "MOD_EXPLOSIVE", "stinger_mp" );
}
else
{
RadiusDamage( self.origin, 1000, 1000, 1000, player, "MOD_EXPLOSIVE", "stinger_mp" );
}
}
self Hide();
wait( 0.05 );
self delete();
}
wait ( 0.05 );
}
}
handleIncomingSAM() // self == remote mortar
{
level endon ( "game_ended" );
self endon ( "death" );
while( true )
{
level waittill ( "sam_fired", player, missileGroup, lockTarget );
if ( !IsDefined( lockTarget ) || (lockTarget != self) )
continue;
level thread samProximityDetonate( lockTarget, player, missileGroup );
}
}
samProximityDetonate( missileTarget, player, missileGroup )
{
missileTarget endon( "death" );
if( IsDefined( missileTarget.owner ) )
missileTarget.owner PlayLocalSound( "missile_incoming" );
sam_projectile_damage = 150; // this should match the gdt entry
sam_projectile_damage_radius = 1000;
minDist = [];
for( i = 0; i < missileGroup.size; i++ )
{
if( IsDefined( missileGroup[ i ] ) )
minDist[ i ] = Distance( missileGroup[ i ].origin, missileTarget GetPointInBounds( 0, 0, 0 ) );
else
minDist[ i ] = undefined;
}
while( true )
{
center = missileTarget GetPointInBounds( 0, 0, 0 );
curDist = [];
for( i = 0; i < missileGroup.size; i++ )
{
if( IsDefined( missileGroup[ i ] ) )
curDist[ i ] = Distance( missileGroup[ i ].origin, center );
}
for( i = 0; i < curDist.size; i++ )
{
if( IsDefined( curDist[ i ] ) )
{
// if one of the missiles in the group get close, set off flares and redirect them all
if( curDist[ i ] < 3000 && missileTarget.numFlares > 0 )
{
missileTarget.numFlares--;
missileTarget thread maps\mp\killstreaks\_helicopter::playFlareFx();
newTarget = missileTarget maps\mp\killstreaks\_helicopter::deployFlares();
for( j = 0; j < missileGroup.size; j++ )
{
if( IsDefined( missileGroup[ j ] ) )
{
missileGroup[ j ] Missile_SetTargetEnt( newTarget );
}
}
if( IsDefined( missileTarget.owner ) )
missileTarget.owner StopLocalSound( "missile_incoming" );
return;
}
if( curDist[ i ] < minDist[ i ] )
minDist[ i ] = curDist[ i ];
if( curDist[ i ] > minDist[ i ] )
{
if( curDist[ i ] > 1536 )
return;
if( IsDefined( missileTarget.owner ) )
{
missileTarget.owner StopLocalSound( "missile_incoming" );
if( level._teambased )
{
if( missileTarget.team != player.team )
RadiusDamage( missileGroup[ i ].origin, sam_projectile_damage_radius, sam_projectile_damage, sam_projectile_damage, player, "MOD_EXPLOSIVE", "sam_projectile_mp" );
}
else
{
RadiusDamage( missileGroup[ i ].origin, sam_projectile_damage_radius, sam_projectile_damage, sam_projectile_damage, player, "MOD_EXPLOSIVE", "sam_projectile_mp" );
}
}
missileGroup[ i ] Hide();
wait ( 0.05 );
missileGroup[ i ] delete();
}
}
}
wait ( 0.05 );
}
}

View File

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

View File

@ -0,0 +1,461 @@
#include maps\mp\_utility;
#include common_scripts\utility;
init()
{
mapname = getDvar( "mapname" );
if ( mapname == "mp_suburbia" )
{
level._missileRemoteLaunchVert = 7000;
level._missileRemoteLaunchHorz = 10000;
level._missileRemoteLaunchTargetDist = 2000;
}
else if ( mapname == "mp_mainstreet" )
{
level._missileRemoteLaunchVert = 7000;
level._missileRemoteLaunchHorz = 10000;
level._missileRemoteLaunchTargetDist = 2000;
}
else
{
level._missileRemoteLaunchVert = 14000;
level._missileRemoteLaunchHorz = 7000;
level._missileRemoteLaunchTargetDist = 1500;
}
precacheItem( "remotemissile_projectile_mp" );
precacheShader( "ac130_overlay_grain" );
precacheString( &"MP_CIVILIAN_AIR_TRAFFIC" );
level._rockets = [];
level._killstreakFuncs["predator_missile"] = ::tryUsePredatorMissile;
level._killstreakFuncs["predator_marker"] = ::tryUsePredatorMarker;
level._missilesForSightTraces = [];
}
tryUsePredatorMarker( lifeId )
{
//okToUsePredatorMarker = true;
//level endon( "game_ended" );
//self endon( "death" );
//println( "Got off" );
//if (okToUsePredatorMarker == true)
//{
self usePredatorMarker();
return true;
//}
//msg = self waittill_any_return( "pred_grenade_thrown" );
//if ( msg != "pred_grenade_thrown" )
// self switchToOffhand( grenade );
//return false;
}
usePredatorMarker()
{
level endon( "game_ended" );
self endon( "death" );
self endon("disconnect");
ognade = self GetCurrentOffhand();
ognadeCount = self GetWeaponAmmoClip(ognade);
self SetWeaponAmmoClip( ognade, 0 );
self _giveWeapon("pred_grenade_mp");
//println( "gave pred" );
self thread waitForPredatorMarker( ognade, ognadeCount );
}
waitForPredatorMarker( nadeId, nadeCount){
level endon( "game_ended" );
self endon( "death" );
self endon("disconnect");
for(;;)
{
self waittill( "grenade_fire", grenade, weaponName );
//println( weaponName );
if( weaponName == "pred_grenade_mp" )
{
break;
}
}
if (nadeCount > 0)
{
self _giveWeapon(nadeId);
//println( "gave grenade back" );
}
}
/*
dontLosePredMarker()
{
self endon( "grenade_fire");
self waittill("death");
println( "in dontLose FOR" );
predNadeCheck = self GetCurrentOffhand();
predNadeCount = self GetWeaponAmmoClip(predNadeCheck);
if ( predNadeCheck != "pred_grenade_mp" && predNadeCount != 1 )
{
self SetWeaponAmmoClip( "pred_grenade_mp" , 1 );
println( "not gonna lose it!" );
}
}
*/
tryUsePredatorMissile( lifeId )
{
if ( isDefined( level._civilianJetFlyBy ) )
{
self iPrintLnBold( &"MP_CIVILIAN_AIR_TRAFFIC" );
return false;
}
self setUsingRemote( "remotemissile" );
result = self maps\mp\killstreaks\_killstreaks::initRideKillstreak();
if ( result != "success" )
{
if ( result != "disconnect" )
self clearUsingRemote();
return false;
}
level thread _fire( lifeId, self );
return true;
}
getBestSpawnPoint( remoteMissileSpawnPoints )
{
validEnemies = [];
foreach ( spawnPoint in remoteMissileSpawnPoints )
{
spawnPoint.validPlayers = [];
spawnPoint.spawnScore = 0;
}
foreach ( player in level._players )
{
if ( !isReallyAlive( player ) )
continue;
if ( player.team == self.team )
continue;
if ( player.team == "spectator" )
continue;
bestDistance = 999999999;
bestSpawnPoint = undefined;
foreach ( spawnPoint in remoteMissileSpawnPoints )
{
//could add a filtering component here but i dont know what it would be.
spawnPoint.validPlayers[spawnPoint.validPlayers.size] = player;
potentialBestDistance = Distance2D( spawnPoint.targetent.origin, player.origin );
if ( potentialBestDistance <= bestDistance )
{
bestDistance = potentialBestDistance;
bestSpawnpoint = spawnPoint;
}
}
assertEx( isDefined( bestSpawnPoint ), "Closest remote-missile spawnpoint undefined for player: " + player.name );
bestSpawnPoint.spawnScore += 2;
}
bestSpawn = remoteMissileSpawnPoints[0];
foreach ( spawnPoint in remoteMissileSpawnPoints )
{
foreach ( player in spawnPoint.validPlayers )
{
spawnPoint.spawnScore += 1;
if ( bulletTracePassed( player.origin + (0,0,32), spawnPoint.origin, false, player ) )
spawnPoint.spawnScore += 3;
if ( spawnPoint.spawnScore > bestSpawn.spawnScore )
{
bestSpawn = spawnPoint;
}
else if ( spawnPoint.spawnScore == bestSpawn.spawnScore ) // equal spawn weights so we toss a coin.
{
if ( coinToss() )
bestSpawn = spawnPoint;
}
}
}
return ( bestSpawn );
}
drawLine( start, end, timeSlice, color )
{
drawTime = int(timeSlice * 20);
for( time = 0; time < drawTime; time++ )
{
line( start, end, color,false, 1 );
wait ( 0.05 );
}
}
_fire( lifeId, player )
{
remoteMissileSpawnArray = getEntArray( "remoteMissileSpawn" , "targetname" );
//assertEX( remoteMissileSpawnArray.size > 0 && getMapCustom( "map" ) != "", "No remote missile spawn points found. Contact friendly neighborhood designer" );
foreach ( spawn in remoteMissileSpawnArray )
{
if ( isDefined( spawn.target ) )
spawn.targetEnt = getEnt( spawn.target, "targetname" );
}
if ( remoteMissileSpawnArray.size > 0 )
remoteMissileSpawn = player getBestSpawnPoint( remoteMissileSpawnArray );
else
remoteMissileSpawn = undefined;
if ( isDefined( remoteMissileSpawn ) )
{
startPos = remoteMissileSpawn.origin;
targetPos = remoteMissileSpawn.targetEnt.origin;
//thread drawLine( startPos, targetPos, 30, (0,1,0) );
vector = vectorNormalize( startPos - targetPos );
startPos = vector_multiply( vector, 14000 ) + targetPos;
//thread drawLine( startPos, targetPos, 15, (1,0,0) );
rocket = MagicBullet( "remotemissile_projectile_mp", startpos, targetPos, player );
}
else
{
upVector = (0, 0, level._missileRemoteLaunchVert );
backDist = level._missileRemoteLaunchHorz;
targetDist = level._missileRemoteLaunchTargetDist;
forward = AnglesToForward( player.angles );
startpos = player.origin + upVector + forward * backDist * -1;
targetPos = player.origin + forward * targetDist;
rocket = MagicBullet( "remotemissile_projectile_mp", startpos, targetPos, player );
}
if ( !IsDefined( rocket ) )
{
player clearUsingRemote();
return;
}
rocket thread maps\mp\gametypes\_weapons::AddMissileToSightTraces( player.team );
rocket thread handleDamage();
rocket.lifeId = lifeId;
rocket.type = "remote";
MissileEyes( player, rocket );
}
/#
_fire_noplayer( lifeId, player )
{
upVector = (0, 0, level._missileRemoteLaunchVert );
backDist = level._missileRemoteLaunchHorz;
targetDist = level._missileRemoteLaunchTargetDist;
forward = AnglesToForward( player.angles );
startpos = player.origin + upVector + forward * backDist * -1;
targetPos = player.origin + forward * targetDist;
rocket = MagicBullet( "remotemissile_projectile_mp", startpos, targetPos, player );
if ( !IsDefined( rocket ) )
return;
rocket thread handleDamage();
rocket.lifeId = lifeId;
rocket.type = "remote";
player CameraLinkTo( rocket, "tag_origin" );
player ControlsLinkTo( rocket );
rocket thread Rocket_CleanupOnDeath();
wait ( 2.0 );
player ControlsUnlink();
player CameraUnlink();
}
#/
handleDamage()
{
self endon ( "death" );
self endon ( "deleted" );
self setCanDamage( true );
for ( ;; )
{
self waittill( "damage" );
println ( "projectile damaged!" );
}
}
MissileEyes( player, rocket )
{
//level endon ( "game_ended" );
player endon ( "joined_team" );
player endon ( "joined_spectators" );
rocket thread Rocket_CleanupOnDeath();
player thread Player_CleanupOnGameEnded( rocket );
player thread Player_CleanupOnTeamChange( rocket );
player VisionSetMissilecamForPlayer( "black_bw", 0 );
player endon ( "disconnect" );
if ( isDefined( rocket ) )
{
player VisionSetMissilecamForPlayer( game["thermal_vision"], 1.0 );
player thread delayedFOFOverlay();
player CameraLinkTo( rocket, "tag_origin" );
player ControlsLinkTo( rocket );
if ( getDvarInt( "camera_thirdPerson" ) )
player setThirdPersonDOF( false );
rocket waittill( "death" );
// is defined check required because remote missile doesnt handle lifetime explosion gracefully
// instantly deletes its self after an explode and death notify
if ( isDefined(rocket) )
player maps\mp\_matchdata::logKillstreakEvent( "predator_missile", rocket.origin );
player ControlsUnlink();
player freezeControlsWrapper( true );
// If a player gets the final kill with a hellfire, level.gameEnded will already be true at this point
if ( !level._gameEnded || isDefined( player.finalKill ) )
player thread staticEffect( 0.5 );
wait ( 0.5 );
player ThermalVisionFOFOverlayOff();
player CameraUnlink();
if ( getDvarInt( "camera_thirdPerson" ) )
player setThirdPersonDOF( true );
}
player clearUsingRemote();
}
delayedFOFOverlay()
{
self endon ( "death" );
self endon ( "disconnect" );
level endon ( "game_ended" );
wait ( 0.15 );
self ThermalVisionFOFOverlayOn();
}
staticEffect( duration )
{
self endon ( "disconnect" );
staticBG = newClientHudElem( self );
staticBG.horzAlign = "fullscreen";
staticBG.vertAlign = "fullscreen";
staticBG setShader( "white", 640, 480 );
staticBG.archive = true;
staticBG.sort = 10;
static = newClientHudElem( self );
static.horzAlign = "fullscreen";
static.vertAlign = "fullscreen";
static setShader( "ac130_overlay_grain", 640, 480 );
static.archive = true;
static.sort = 20;
wait ( duration );
static destroy();
staticBG destroy();
}
Player_CleanupOnTeamChange( rocket )
{
rocket endon ( "death" );
self endon ( "disconnect" );
self waittill_any( "joined_team" , "joined_spectators" );
if ( self.team != "spectator" )
{
self ThermalVisionFOFOverlayOff();
self ControlsUnlink();
self CameraUnlink();
if ( getDvarInt( "camera_thirdPerson" ) )
self setThirdPersonDOF( true );
}
self clearUsingRemote();
level._remoteMissileInProgress = undefined;
}
Rocket_CleanupOnDeath()
{
entityNumber = self getEntityNumber();
level._rockets[ entityNumber ] = self;
self waittill( "death" );
level._rockets[ entityNumber ] = undefined;
}
Player_CleanupOnGameEnded( rocket )
{
rocket endon ( "death" );
self endon ( "death" );
level waittill ( "game_ended" );
self ThermalVisionFOFOverlayOff();
self ControlsUnlink();
self CameraUnlink();
if ( getDvarInt( "camera_thirdPerson" ) )
self setThirdPersonDOF( true );
}

View File

@ -0,0 +1,334 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
precacheString( &"MP_LASE_TARGET_FOR_GUIDED_MORTAR" );
precacheString( &"MP_WAIT_FOR_MORTAR_READY" );
precacheString( &"MP_MORTAR_ROUNDS_DEPLETED" );
precacheItem( "remote_mortar_missile_mp" );
PreCacheItem( "mortar_remote_mp" );
level._remote_mortar_fx["tracer"] = loadFx( "misc/tracer_incoming" );
level._remote_mortar_fx["explosion"] = loadFx( "explosions/building_explosion_huge_gulag" );
level._effect[ "laserTarget" ] = loadfx("nx/misc/nx_laser_glow");
level._killstreakFuncs["remote_mortar"] = ::tryUseRemoteMortar;
}
tryUseRemoteMortar( lifeId )
{
if ( isDefined( self.lastStand ) && !self _hasPerk( "specialty_finalstand" ) )
{
self iPrintLnBold( &"MP_UNAVILABLE_IN_LASTSTAND" );
return false;
}
self setUsingRemote( "remote_mortar" );
result = self maps\mp\killstreaks\_killstreaks::initRideKillstreak();
if ( result != "success" )
{
if ( result != "disconnect" )
self clearUsingRemote();
return false;
}
self thread teamPlayerCardSplash( "used_remote_mortar", self );
return startRemoteMortar( lifeId );
}
startRemoteMortar( lifeId )
{
remote = spawnRemote( lifeId, self );
if ( !isDefined( remote ) )
return false;
self thread linkRemoteTargeting( remote );
self maps\mp\_matchdata::logKillstreakEvent( "remote_mortar", self.origin );
return true;
}
spawnRemote( lifeId, owner )
{
remote = spawnplane( owner, "script_model", level._UAVRig getTagOrigin( "tag_origin" ) );
if ( !isDefined( remote ) )
return undefined;
remote setModel( "vehicle_uav_static_mp" );
remote thread maps\mp\killstreaks\_uav::damageTracker( false );
remote.team = owner.team;
remote.owner = owner;
remote.lifeId = lifeId;
remote.heliType = "remote_mortar";
remote thread maps\mp\killstreaks\_helicopter::heli_flares_monitor();
maps\mp\killstreaks\_uav::addUAVModel( remote );
// 3000, 4000, and 6500 are all average numbers pulled from the random ranges UAV uses
// since the player's camera is linked to this vehicle, we want to control the location
zOffset = 3000;
angle = 0;
radiusOffset = 4000;
xOffset = cos( angle ) * radiusOffset;
yOffset = sin( angle ) * radiusOffset;
angleVector = vectorNormalize( (xOffset,yOffset,zOffset) );
angleVector = ( angleVector * 6500 );
remote linkTo( level._UAVRig, "tag_origin", angleVector, (0,angle-90,0) );
remote thread handleDeath( owner );
remote thread handleTimeout( owner );
remote thread handleOwnerDisconnect( owner );
return remote;
}
showLazeMessage( remote, state, time )
{
level endon( "game_ended" );
self endon ( "disconnect" );
remote endon ( "death" );
self notify( "showing_laze_message" );
self endon( "showing_laze_message" );
if ( isDefined( remote.msg ) )
remote.msg destroyElem();
text = "";
switch( state )
{
case "ready":
text = &"MP_LASE_TARGET_FOR_GUIDED_MORTAR";
color = (0.2, 1.0, 0.2);
break;
case "wait":
text = &"MP_WAIT_FOR_MORTAR_READY";
color = (0.8, 0.8, 0.2);
break;
case "done":
text = &"MP_MORTAR_ROUNDS_DEPLETED";
color = (1.0, 0.2, 0.2);
break;
default:
return;
}
remote.msg = self maps\mp\gametypes\_hud_util::createFontString( "objective", 1.5 );
remote.msg maps\mp\gametypes\_hud_util::setPoint( "CENTER", "CENTER", 0 , 150 );
remote.msg setText( text );
remote.msg.color = color;
if ( !isDefined( time ) )
time = 2.0;
wait( time );
if ( isDefined( remote.msg ) )
remote.msg destroyElem();
}
lookCenter()
{
wait( 0.05 );
lookVec = vectorToAngles( level._UAVRig.origin - self GetEye() );
self setPlayerAngles( lookVec );
}
linkRemoteTargeting( remote )
{
level endon( "game_ended" );
self endon( "disconnect" );
remote endon( "helicopter_done" );
remote endon( "death" );
self VisionSetThermalForPlayer( game["thermal_vision"], 0 );
self _giveWeapon("mortar_remote_mp");
self SwitchToWeapon("mortar_remote_mp");
self ThermalVisionOn();
self ThermalVisionFOFOverlayOn();
self thread maps\mp\killstreaks\_helicopter::thermalVision( remote );
if ( getDvarInt( "camera_thirdPerson" ) )
self setThirdPersonDOF( false );
self PlayerLinkWeaponviewToDelta( remote, "tag_player", 1.0, 180, 180, 0, 180, true );
self thread lookCenter();
remote thread maps\mp\killstreaks\_helicopter::heli_targeting();
self thread maps\mp\killstreaks\_helicopter::weaponLockThink( remote );
// msg
self thread showLazeMessage( remote, "ready", 5 );
// fire
shotsFired = 0;
while ( true )
{
if ( self attackButtonPressed() )
{
origin = self GetEye();
forward = AnglesToForward( self GetPlayerAngles() );
endpoint = origin + forward * 15000;
traceData = BulletTrace( origin, endpoint, true, self );
if ( isDefined( traceData["position"] ) )
{
self playLocalSound( "stinger_locking" );
self PlayRumbleOnEntity( "ac130_25mm_fire" );
remote.fxEnt = SpawnFx( level._effect[ "laserTarget" ], traceData["position"] );
TriggerFx( remote.fxEnt );
// wait ( 1.0 );
self thread launchMortar( remote, traceData["position"] );
shotsFired++;
if ( shotsFired < 3 )
{
self thread showLazeMessage( remote, "wait" );
wait( 2.0 );
remote.fxEnt delete();
self thread showLazeMessage( remote, "ready" );
}
else
{
self thread showLazeMessage( remote, "wait" );
wait( 2.0 );
remote.fxEnt delete();
self thread showLazeMessage( remote, "done" );
wait( 2.0 );
break;
}
}
else
wait( 0.05 );
}
else
wait( 0.05 );
}
self unlinkRemoteTargeting();
remote thread remoteLeave();
}
launchMortar( remote, pos )
{
PlayFx( level._remote_mortar_fx["tracer"], pos );
thread playSoundinSpace( "fast_artillery_round", pos );
wait( 1 );
PlayFx( level._remote_mortar_fx["explosion"], pos );
Earthquake( 1.0, 0.6, pos, 2000 );
thread playSoundinSpace( "exp_suitcase_bomb_main", pos );
physicsExplosionSphere( pos + (0,0,30), 250, 125, 2 );
if ( isDefined( self ) )
remote RadiusDamage( pos, 400, 200, 50, self, "MOD_EXPLOSIVE", "remote_mortar_missile_mp" );
else
remote RadiusDamage( pos, 400, 200, 50, undefined, "MOD_EXPLOSIVE", "remote_mortar_missile_mp" );
}
unlinkRemoteTargeting()
{
self RemoteCameraSoundscapeOff();
self ThermalVisionOff();
self ThermalVisionFOFOverlayOff();
self unlink();
self clearUsingRemote();
if ( getDvarInt( "camera_thirdPerson" ) )
self setThirdPersonDOF( true );
self visionSetThermalForPlayer( game["thermal_vision"], 0 );
self switchToWeapon( self getLastWeapon() );
weaponList = self GetWeaponsListExclusives();
foreach ( weapon in weaponList )
self takeWeapon( weapon );
}
handleTimeout( owner )
{
level endon( "game_ended" );
owner endon( "disconnect" );
self endon( "death" );
self endon( "helicopter_done" );
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 45.0 );
if ( isDefined( owner ) )
owner unlinkRemoteTargeting();
self thread remoteLeave();
}
handleDeath( owner )
{
level endon( "game_ended" );
owner endon( "disconnect" );
self endon( "helicopter_done" );
self waittill( "death" );
owner unlinkRemoteTargeting();
forward = ( AnglesToRight( self.angles ) * 200 );
playFx ( level._uav_fx[ "explode" ], self.origin, forward );
level thread removeRemote( self );
self notify( "helicopter_done" );
}
handleOwnerDisconnect( owner )
{
level endon( "game_ended" );
owner endon( "death" );
self endon( "death" );
owner waittill( "disconnect" );
self thread remoteLeave();
}
removeRemote( remote )
{
if ( isDefined( remote.msg ) )
remote.msg destroyElem();
if ( isDefined( remote.fxEnt ) )
remote.fxEnt delete();
remote delete();
maps\mp\killstreaks\_uav::removeUAVModel( remote );
}
remoteLeave()
{
level endon( "game_ended" );
self endon( "death" );
self notify( "helicopter_done" );
self unlink();
destPoint = self.origin + ( AnglesToForward( self.angles ) * 20000 );
self moveTo( destPoint, 60 );
PlayFXOnTag( level._effect[ "ac130_engineeffect" ] , self, "tag_origin" );
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 3 );
self moveTo( destPoint, 4, 4, 0.0 );
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 4 );
level thread removeRemote( self );
}

View File

@ -0,0 +1,816 @@
#include maps\mp\_utility;
#include common_scripts\utility;
//****************************************************************************
// **
// Confidential - (C) Activision Publishing, Inc. 2010 **
// **
//****************************************************************************
// **
// Module: Prototype killstreak - Roboturret **
// Once the killstreak is deployed, it will follow the player **
// around the map and kill enemies. **
// **
// Created: May 31th, 2011 - James Chen **
// **
//***************************************************************************/
//tagJC<NOTE>: The current implementation consists of three components: one very small joint as vehicle serving as the connecting
// base for the turret and the legs.
//tagJC<TODO>: Known Issues (bugs)
// (1) The animation for the turret is controlled by the another underlying (turret) script. Currently, the turret
// does not play the proper animation when tracking/shooting enemies.
// (2) The robo legs is 90 degree from the correct orientation of the vehicle.
//tagJC<TODO>: Determine a better pathing logic under the current vehicle pathing limitation so the roboturret can really follow
// the players around the level.
init()
{
//tagJC<NOTE>: Precache all the assets needed.
//tagJC<NOTE>: nx_vehicle_roboturret_legs_vehicle is a very small joint which has all the required TAG for a vehicle.
// It is used so the robo legs and the roboturrets can be attached to it and the game will handle it properly
// according to the default vehicle animation.
PrecacheVehicle( "proto_nx_vehicle_roboturret_legs_vehicle" );
precacheModel( "nx_vehicle_roboturret_legs_vehicle" );
//tagJC<NOTE>: nx_vehicle_spider is the robo legs.
PrecacheVehicle( "nx_spider_mp" );
precacheModel( "nx_vehicle_spider" );
//tagJC<NOTE>: nx_ugv_robo_turret is the robo turret.
precacheTurret( "ugv_robo_turret_mp" );
precacheModel( "nx_ugv_robo_turret" );
//tagJC<NOTE>: These are the animations for the robo legs.
precacheMpAnim( "nx_vh_roboturret_run" );
precacheMpAnim( "nx_vh_roboturret_walk" );
precacheMpAnim( "nx_vh_roboturret_idle" );
//level._spiderSpawners = Vehicle_GetSpawnerArray();
//tagJC<NOTE>: This is the killstreak activation callback for the roboturret.
level._killstreakFuncs["spider"] = ::try_use_killstreak;
//tagJC<NOTE>: Use this script to update/initialize players as they connect to the game.
level thread onPlayerConnect();
//tagJC<NOTE>: In order for the roboturret to work correctly, the level needs to have at least one "spidernode".
level._spiderNodes = getVehicleNodeArray( "spidernode", "script_noteworthy" );
StartNodeMappingTable();
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Checking whether the level is properly set up for the roboturret killstreak.
try_use_killstreak( lifeId )
{
if ( ! level._spiderNodes.size )
{
self iPrintLnBold( "Spider is currently not supported in this level, bug your friendly neighborhood Level Designer, Failed to locate valid spider node." );
return false;
}
//tagJC<NOTE>: Test script of which any desired testing can be performed before integrated into working prototype.
//testscript();
killstreak_template_use( lifeId );
return true;
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: This function creates a mapping table for all the start nodes. It uses the coordinate of the start node as the
// the index for the first dimension of the array. The second dimension of the array stores all the start nodes that
// the current start node can travel to.
StartNodeMappingTable()
{
println( "StartNodeMappingTable" );
level._StartNodeMapping = [];
println( "################################" );
for ( i = 0; i < level._spiderNodes.size; i++ )
{
StartNode = level._spiderNodes[i];
//tagJC<NOTE>: Getting the end node of the path whose start node is StartNode
EndNode = GetVehicleNode( StartNode.target, "targetname" );
//tagJC<NOTE>: Creating the index using the StartNode's coordinate
index = "X" + StartNode.origin[0] + "Y" + StartNode.origin[1] + "Z" + StartNode.origin[2];
println( "The index is " + index );
for ( j = 0; j < level._spiderNodes.size; j++ )
{
TargetStartNode = level._spiderNodes[j];
//tagJC<NOTE>: Store the TargetStartNode into the array if its distance is less than 250 units from the EndNode
if ( distance( EndNode.origin, TargetStartNode.origin ) < 250 )
{
if ( ! IsDefined (level._StartNodeMapping[index]) )
{
level._StartNodeMapping[index][0] = TargetStartNode;
}
else
{
ArraySize = level._StartNodeMapping[index].size;
level._StartNodeMapping[index][ArraySize] = TargetStartNode;
}
}
}
//tagJC<NOTE>: Debugging output to look at the array
println( "There are " + level._StartNodeMapping[index].size + " startnodes connected" );
for ( r = 0; r < level._StartNodeMapping[index].size; r++)
{
println( " The coordinate is " + level._StartNodeMapping[index][r].origin );
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Test script for any desired functionality, such as loading model, playing certain animation etc..
// This is to make sure things are working properly before they are integrated into the working prototype.
testscript()
{
}
//*******************************************************************
// *
// *
//*******************************************************************
// tagJC<NOTE>: This is the callback that executes when the killstreak is activated by a player pressing on the dpad.
killstreak_template_use( lifeId )
{
assert( isDefined( self ) );
//tagJC<NOTE>: spawning the small joint as the vehicle and setting the associated attributes.
level._spider = spawnVehicle( "nx_vehicle_roboturret_legs_vehicle", "roboturret", "proto_nx_vehicle_roboturret_legs_vehicle", (0, 0, 0), (0, 0, 0) );
level._spider.health = 3000;
level._spider.targeting_delay = 1;
level._spider.team = self.team;
level._spider.pers["team"] = level._spider.team;
level._spider.owner = self;
level._spider setCanDamage( true );
level._spider.standardSpeed = 10;
level._spider.evadeSpeed = 50;
level._spider.dangerSpeed = 15;
level._spider.miniEngagementSpeed = 15;
level._spider.engagementSpeed = 15;
//tagJC<NOTE>: Kill the vehicle if it is dropped for more than 2048 units
level._spider thread deleteOnZ();
//tagJC<NOTE>: Spawning the robo legs
spiderScriptModel = spawn ( "script_model", level._spider.origin );
spiderScriptModel setModel ( "nx_vehicle_spider" );
spiderScriptModel ScriptModelPlayAnim ( "nx_vh_roboturret_idle" );
level._spiderCurrentAnimation = "nx_vh_roboturret_idle";
//tagJC<NOTE>: Linking the robo legs to the vehicle.
spiderScriptModel linkTo ( level._spider, "TAG_ORIGIN" , (0, 0, 0), (0, 0, 0) );
spiderScriptModel thread loopOnLegs ( level._spider );
//tagJC<NOTE>: Spawning the roboturret and setting its attributes.
spiderTurret = spawnTurret( "misc_turret", level._spider.origin, "ugv_main_turret_mp" );
//tagJC<NOTE>: Linking the turret to the scripted robo legs model.
spiderTurret linkTo( spiderScriptModel, "TAG_TURRET", (0,0,0), (0,0,0) );
spiderTurret setModel( "nx_ugv_robo_turret" );
spiderTurret.angles = level._spider.angles;
spiderTurret.owner = level._spider.owner;
spiderTurret makeTurretInoperable();
level._spider.mgTurret = spiderTurret;
level._spider.mgTurret SetDefaultDropPitch( 0 );
//tagJC<NOTE>: Start the turret to track and shoot enemies.
level._spider thread tankGetMiniTargets();
//tagJC<NOTE>: Finding the spider start node that is closest to the player.
closest_spidernode = find_closest_spidernode( self, level._spiderNodes );
//tagJC<NOTE>: Start moving the roboturret according to player's position.
level._spider thread move_spider ( self, closest_spidernode );
return true;
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: There are three animations that the robo legs can play: idel, walk and run
loopOnLegs ( vehicle )
{
timer = 0;
while ( 1 )
{
self.angle = vehicle.angle;
speed = vehicle Vehicle_GetSpeed();
//tagJC<NOTE>: If the vehicle speed is faster than 10 MPH, the legs will run
if ( speed > 10 )
{
timer = 0;
if ( level._spiderCurrentAnimation != "nx_vh_roboturret_run" )
{
self ScriptModelPlayAnim ( "nx_vh_roboturret_run" );
level._spiderCurrentAnimation = "nx_vh_roboturret_run";
self stoploopsound("robot_sentry_walk");
self playloopsound("robot_sentry_run");
}
}
//tagJC<NOTE>: If the vehicle speed is between 10 and 0 MPH, the legs will walk
else if ( speed < 10 && speed > 0 )
{
timer = 0;
if ( level._spiderCurrentAnimation != "nx_vh_roboturret_walk" )
{
self ScriptModelPlayAnim ( "nx_vh_roboturret_walk" );
level._spiderCurrentAnimation = "nx_vh_roboturret_walk";
self stoploopsound("robot_sentry_run");
self playloopsound("robot_sentry_walk");
}
}
//tagJC<NOTE>: If the vehicle speed is 0 MPH, the legs will be idel
else
{
timer = timer + 1;
//tagJC<NOTE>: If the roboturret has been idle for 15 seconds
if ( timer == 30 )
{
vehicle playsound ( "roboturret_idle_vo" );
//vehicle playsound ( "roboturret_kill_vo" );
timer = 0;
}
if ( level._spiderCurrentAnimation != "nx_vh_roboturret_idle" )
{
self stoploopsound("robot_sentry_run");
self stoploopsound("robot_sentry_walk");
self ScriptModelPlayAnim ( "nx_vh_roboturret_idle" );
level._spiderCurrentAnimation = "nx_vh_roboturret_idle";
}
}
println ( "timer is: " + timer );
wait ( 0.5 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Currently, in order for this implementation to work, designers would have to place many pairs of bi-directional vehicle nodes
// in the level. Given the limitation that vehicle seems to be only moving when it is on a vehicle path, the roboturret
// cannot quite follow the players perfectly yet. Players would have to get close to the roboturret and then guide
// it to a different position.
move_spider ( owner, startNode )
{
//self playsound( "roboturret_deploy_vo" );
self Vehicle_SetSpeed( 30, 5, 5 );
//tagJC<NOTE>: Starting the roboturret along the path where its starting node is the roboturret's spawning node
self AttachPath( startNode );
self StartPath( startNode );
self waittill( "reached_end_node" );
self playsound( "roboturret_deploy_vo" );
prev_node = startNode;
while ( 1 )
{
index = "X" + prev_node.origin[0] + "Y" + prev_node.origin[1] + "Z" + prev_node.origin[2];
best_node = find_best_spidernode( owner, level._StartNodeMapping[index] );
//if ( distance ( owner.origin, level._spider.origin ) > 50 )
if ( isGettingCloserToPlayer ( owner, best_node ) )
{
//if ( prev_node != best_node )
//{
self StartPath( best_node );
self waittill( "reached_end_node" );
prev_node = best_node;
//println( "This is after subsequent reached_end_node" );
//}
}
else
{
wait 0.5;
}
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: This function checks whether the turret will be moving away from the player or not
isGettingCloserToPlayer ( owner, StartNode )
{
EndNode = GetVehicleNode( StartNode.target, "targetname" );
if ( distance ( owner.origin, EndNode.origin ) > distance ( owner.origin, StartNode.origin ) )
{
return false;
}
else
{
return true;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: From the ReachableNodeList, determine the node that is will lead the turret to the player
find_best_spidernode( owner, ReachableNodeList )
{
target_vector = VectorNormalize ( owner.origin - level._spider.origin );
//tagJC<NOTE>: Creating an arbitrary base line using the first node in the node awway
best_node = ReachableNodeList [0];
best_dot_product = VectorDot ( VectorNormalize( best_node.origin - level._spider.origin ), target_vector );
for ( i = 1; i < ReachableNodeList.size; i++)
{
//tagJC<NOTE>: If another node in the list can produce a larger dot product, that node is the best node
dot_product = VectorDot ( VectorNormalize( ReachableNodeList[i].origin - level._spider.origin ), target_vector );
if ( dot_product > best_dot_product )
{
best_node = ReachableNodeList[i];
}
}
return best_node;
}
//*******************************************************************
// *
// *
//*******************************************************************
tankGetMiniTargets()
{
self endon( "death" );
self endon( "leaving" );
miniTargets = [];
println( "Geting Mini Targets" );
for ( ;; )
{
miniTargets = [];
players = level._players;
//tagJC<NOTE>: Putting all the players on the oppositing team into a array.
for (i = 0; i <= players.size; i++)
{
if ( isMiniTarget( players[i] ) )
{
if( isdefined( players[i] ) )
miniTargets[miniTargets.size] = players[i];
}
else
{
continue;
}
wait( .05 );
}
//tagJC<NOTE>: If there is at least one enemy, start acquiring the target
if ( miniTargets.size > 0 )
{
self acquireMiniTarget( miniTargets );
return;
}
else
wait( 0.5 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: From the potential target list, determine whether there is any target that is feasible/practical for the turret
// to target.
isMiniTarget( potentialTarget )
{
self endon( "death" );
if ( !isalive( potentialTarget ) || potentialTarget.sessionstate != "playing" )
return false;
if ( !isdefined( potentialTarget.pers["team"] ) )
return false;
if ( potentialTarget == self.owner )
return false;
if ( distanceSquared( potentialTarget.origin , self.origin ) > 1024*1024 )
return false;
if ( level._teamBased && potentialTarget.pers["team"] == self.team )
return false;
if ( potentialTarget.pers["team"] == "spectator" )
return false;
if ( isdefined( potentialTarget.spawntime ) && ( gettime() - potentialTarget.spawntime )/1000 <= 5 )
return false;
if ( isDefined( self ) )
{
minTurretEye = self.mgTurret.origin + ( 0, 0, 64 );
minTurretCanSeeTarget = potentialTarget sightConeTrace( minTurretEye, self );
if ( minTurretCanSeeTarget < 1 )
{
return false;
}
}
return true;
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: From the target list, determine which one is the best target and shoot it.
acquireMiniTarget( targets )
{
self endon( "death" );
//tagJC<NOTE>: If there is only one target in the list, it is the best target.
if ( targets.size == 1 )
{
self.bestMiniTarget = targets[0];
}
//tagJC<NOTE>: Else, determine the best target in the list.
else
{
self.bestMiniTarget = self getBestMiniTarget( targets );
}
self notify( "acquiringMiniTarget" );
//tagJC<NOTE>: Set turret to target the best target.
self.mgTurret SetTargetEntity( self.bestMiniTarget, ( 0,0,42 ) );
wait( .15 );
//tagJC<NOTE>: Set turret to fire at the best target.
self thread fireMiniOnTarget();
//tagJC<NOTE>: Abandon the target when it is killed.
self thread watchMiniTargetDeath( targets );
self thread watchMiniTargetDistance( targets );
self thread watchMiniTargetThreat( self.bestMiniTarget );
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Determine the best target from the target list
getBestMiniTarget( targets )
{
self endon( "death" );
tankOrigin = self.origin;
closest = undefined;
bestTarget = undefined;
foreach ( targ in targets )
{
curDist = Distance( self.origin, targ.origin );
//tagJC<NOTE>: If the target is holding or using explosives, push the target to a higher priority
curWeaon = targ GetCurrentWeapon();
if ( isSubStr( curWeaon, "at4" ) || isSubStr( curWeaon, "jav" ) || isSubStr( curWeaon, "c4" ) || isSubStr( curWeaon, "smart" ) || isSubStr( curWeaon, "grenade" ) )
{
curDist -= 200;
}
if ( !isDefined( closest ) )
{
closest = curDist;
bestTarget = targ;
}
else if ( closest > curDist )
{
closest = curDist;
bestTarget = targ;
}
}
return ( bestTarget );
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Firing the turret at the target.
fireMiniOnTarget()
{
self endon( "death" );
self endon( "abandonedMiniTarget" );
self endon( "killedMiniTarget" );
noTargTime = undefined;
miniAcquiredTime = getTime();
if ( !isDefined( self.bestMiniTarget ) )
{
println( "No Targ to fire on" );
return;
}
println( "firing at best target" );
while( 1 )
{
if ( !isDefined ( self.mgTurret getTurretTarget( true ) ) )
{
if ( !isDefined( noTargTime ) )
{
noTargTime = getTime();
}
curTime = getTime();
//tagJC<NOTE>: If there has been more than 1 milliseconds without a target, abandon the target.
if ( noTargTime - curTime > 1 )
{
noTargTime = undefined;
self thread explicitAbandonMiniTarget();
return;
}
println("Waiting because the turret doesnt have a target" );
wait ( .5 );
continue;
}
//tagJC<NOTE>: Firing a random number of shots between 2 to 6.
numShots = randomIntRange( 2, 6 );
for ( i = 0; i < numShots; i++ )
{
println( "actually shooting turret" );
self.mgTurret ShootTurret();
wait ( .25 );
}
wait ( randomFloatRange( 0.05, 0.1 ) );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Clearing the current target list for the turret and starting to get more targets.
explicitAbandonMiniTarget( noNewTarget )
{
self notify( "abandonedMiniTarget" );
println( "ABANDONED MINI TARGET" );
self.bestMiniTarget = undefined;
self.mgTurret ClearTargetEntity();
if ( isDefined(noNewTarget) && noNewTarget )
{
return;
}
self thread tankGetMiniTargets();
return;
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Wait for the target's death. Once the target is killed, clear the target list and get more targets.
watchMiniTargetDeath( targets )
{
self endon( "abandonedMiniTarget" );
self endon( "death" );
if ( ! isDefined( self.bestMiniTarget ) )
return;
self.bestMiniTarget waittill( "death" );
//self playsound ( "roboturret_idle_vo" );
self playsound ( "roboturret_kill_vo" );
self notify( "killedMiniTarget" );
println( "Killed Mini Target" );
self.bestMiniTarget = undefined;
self.mgTurret ClearTargetEntity();
self tankGetMiniTargets();
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: If the target is more than 1024 units away, abandon the target
watchMiniTargetDistance( targets )
{
self endon( "abandonedMiniTarget" );
self endon( "death" );
for ( ;; )
{
if (! isDefined( self.bestMiniTarget ) )
return;
trace = BulletTrace( self.mgTurret.origin, self.bestMiniTarget.origin, false, self );
traceDistance = Distance(self.origin, trace["position"] );
if ( traceDistance > 1024 )
{
println( "MINI TARGET DIST TOO FAR!!!" );
self thread explicitAbandonMiniTarget();
return;
}
println( traceDistance );
wait ( 2 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: If there is a target that is closer to the current target, abandon the curret target
watchMiniTargetThreat( curTarget )
{
self endon( "abandonedMiniTarget" );
self endon( "death" );
self endon( "killedMiniTarget" );
for ( ;; )
{
miniTargets = [];
players = level._players;
for (i = 0; i <= players.size; i++)
{
if ( isMiniTarget( players[i] ) )
{
if( !isdefined( players[i] ) )
{
continue;
}
if( !isdefined(curTarget) )
{
return;
}
traceOldTarg = Distance(self.origin, CurTarget.origin );
traceNewTarg = Distance(self.origin, players[i].origin );
if ( traceNewTarg < traceOldTarg )
{
self thread explicitAbandonMiniTarget();
return;
}
}
wait( .05 );
}
wait( .25 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: From the entity_list, return the one that is closest to the entity
find_closest_spidernode ( target, entity_list )
{
//tagJC<NOTE>: Use an arbitrary distance as the base for comparision
closest_distance = distance( target.origin , entity_list[0].origin );
closest_entity = entity_list[0];
for ( i = 1; i < entity_list.size; i++ )
{
//tagJC<NOTE>: If another entity on the list results in a shorter distance, update the results accordingly
if ( distance( target.origin , entity_list[i].origin ) < closest_distance )
{
closest_distance = distance( target.origin , entity_list[i].origin );
closest_entity = entity_list[i];
}
}
return closest_entity;
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: If a vehicle is dropped more than 2048 units, kill it.
deleteOnZ()
{
self endon ( "death" );
originalZ = self.origin[2];
for ( ;; )
{
if ( originalZ - self.origin[2] > 2048 )
{
self.health = 0;
self notify( "death" );
return;
}
wait ( 1.0 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: This function tracks player's movement and put the closest node to the player into a queue
TrackingPlayers( owner )
{
self.PlayerLocations = [];
while ( 1 )
{
close_node = find_closest_spidernode( owner, level._spiderNodes );
if ( self.PlayerLocations.size == 0 )
{
self.PlayerLocations[0] = close_node;
}
else
{
size = self.PlayerLocations.size;
Player_last_location = self.PlayerLocations[ size - 1 ];
if ( close_node != Player_last_location )
{
self.PlayerLocations[ size ] = close_node;
//println ( "========== This is inside Tracking Player ============" );
//println ( "The location of the node being added is: " + self.PlayerLocations[ size ].origin);
//println ( "The size of PlayerLocations is: " + self.PlayerLocations.size );
//println ( "======================================================" );
}
}
wait( 0.5 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
//tagJC<NOTE>: Remove the first item in the list by shifting entities in the list forward by one slot in the list
RemoveFirstItem ( list )
{
if ( list.size > 0 )
{
for ( i = 0 ; i < list.size - 1 ; i ++ )
{
list[ i ] = list[ i + 1 ];
}
list[ list.size - 1 ] = undefined;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// tagJC<NOTE>: This script is running on the global level object, it monitors players connecting to the game.
// Its main purpose is to apply the onPlayerSpawned script to each player as they connect to the game.
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
}
}
//*******************************************************************
// *
// *
//*******************************************************************
// tagJC<NOTE>: This script is running on each player in the game, it recieves a notification each time the player it is running on spawns in the game
// Its main purpose is to initialize any per player data, as well as update the player subject to any global killstreak data when that player spawns.
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill( "spawned_player" );
println( "player spwaned" );
// init/manage any per player killstreak data here
}
}
main ( vehicle, model )
{
}
//*******************************************************************
// *
// *
//*******************************************************************
/*
QUAKED script_vehicle_nx_proto_roboturret (1 0 0) (-16 -16 -24) (16 16 32) USABLE SPAWNER
maps\mp\killstreaks\_spider::main( "nx_vehicle_roboturret_legs_vehicle", "proto_nx_vehicle_roboturret_legs_vehicle" );
include,prototype_nx_vehicle_roboturret
defaultmdl="nx_vehicle_roboturret_legs_vehicle"
default:"vehicletype" "proto_nx_vehicle_roboturret_legs_vehicle"
default:"script_team" "allies"
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,881 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
precacheString( &"MP_WAR_RADAR_ACQUIRED" );
precacheString( &"MP_WAR_RADAR_ACQUIRED_ENEMY" );
precacheString( &"MP_WAR_RADAR_EXPIRED" );
precacheString( &"MP_WAR_RADAR_EXPIRED_ENEMY" );
precacheString( &"MP_WAR_COUNTER_RADAR_ACQUIRED" );
precacheString( &"MP_WAR_COUNTER_RADAR_ACQUIRED_ENEMY" );
precacheString( &"MP_WAR_COUNTER_RADAR_EXPIRED" );
precacheString( &"MP_WAR_COUNTER_RADAR_EXPIRED_ENEMY" );
precacheString( &"MP_LASE_TARGET_FOR_PREDATOR_STRIKE" );
precacheModel( "vehicle_uav_static_mp" );
precacheItem( "uavstrikebinoculars_mp" );
precacheItem( "uav_strike_projectile_mp" );
level._radarViewTime = 30; // time radar remains active
level._uavBlockTime = 30; // this only seems to be used for the FFA version.
assert( level._radarViewTime > 7 );
assert( level._uavBlockTime > 7 );
level._uav_fx[ "explode" ] = loadFx( "explosions/helicopter_explosion_cobra_low" );
level._killStreakFuncs["uav"] = ::tryUseUAV;
level._killStreakFuncs["double_uav"] = ::tryUseDoubleUAV;
level._killStreakFuncs["counter_uav"] = ::tryUseCounterUAV;
level._killstreakFuncs["uav_strike"] = ::tryUseUAVStrike;
level._killstreakSetupFuncs["uav_strike"] = ::UAVStrikeSetup;
level._effect[ "laserTarget" ] = loadfx("nx/misc/nx_laser_glow");
minimapOrigins = getEntArray( "minimap_corner", "targetname" );
if ( miniMapOrigins.size )
uavOrigin = maps\mp\gametypes\_spawnlogic::findBoxCenter( miniMapOrigins[0].origin, miniMapOrigins[1].origin );
else
uavOrigin = (0,0,0);
level._UAVRig = spawn( "script_model", uavOrigin );
level._UAVRig setModel( "c130_zoomrig" );
level._UAVRig.angles = (0,115,0);
level._UAVRig hide();
level._UAVRig thread rotateUAVRig();
if ( level._teamBased )
{
level._radarMode["allies"] = "normal_radar";
level._radarMode["axis"] = "normal_radar";
level._activeUAVs["allies"] = 0;
level._activeUAVs["axis"] = 0;
level._activeCounterUAVs["allies"] = 0;
level._activeCounterUAVs["axis"] = 0;
level._uavModels["allies"] = [];
level._uavModels["axis"] = [];
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
level._radarMode[level._teamNameList[i]] = "normal_radar";
level._activeUAVs[level._teamNameList[i]] = 0;
level._activeCounterUAVs[level._teamNameList[i]] = 0;
level._uavModels[level._teamNameList[i]] = [];
}
}
}
else
{
level._radarMode = [];
level._activeUAVs = [];
level._activeCounterUAVs = [];
level._uavModels = [];
level thread onPlayerConnect();
}
level thread UAVTracker();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
level._activeUAVs[ player.guid ] = 0;
level._activeCounterUAVs[ player.guid ] = 0;
level._radarMode[ player.guid ] = "normal_radar";
}
}
rotateUAVRig()
{
for (;;)
{
self rotateyaw( -360, 60 );
wait ( 60 );
}
}
launchUAV( owner, team, duration, isCounter )
{
UAVModel = spawn( "script_model", level._UAVRig getTagOrigin( "tag_origin" ) );
UAVModel setModel( "vehicle_uav_static_mp" );
UAVModel thread damageTracker( isCounter );
UAVModel.team = team;
UAVModel.owner = owner;
UAVModel thread handleIncomingStinger();
addUAVModel( UAVModel );
zOffset = randomIntRange( 3000, 5000 );
angle = randomInt( 360 );
radiusOffset = randomInt( 2000 ) + 5000;
xOffset = cos( angle ) * radiusOffset;
yOffset = sin( angle ) * radiusOffset;
angleVector = vectorNormalize( (xOffset,yOffset,zOffset) );
angleVector = vector_multiply( angleVector, randomIntRange( 6000, 7000 ) );
UAVModel linkTo( level._UAVRig, "tag_origin", angleVector, (0,angle - 90,0) );
UAVModel thread updateUAVModelVisibility();
if ( isCounter )
UAVModel addActiveCounterUAV();
else
UAVModel addActiveUAV();
level notify ( "uav_update" );
UAVModel waittill_notify_or_timeout_hostmigration_pause( "death", duration - 7 );
if ( UAVModel.health <= 0 )
{
forward = vector_multiply( anglesToRight( UAVModel.angles ), 200 );
playFx ( level._uav_fx[ "explode" ], UAVModel.origin, forward );
}
else
{
UAVModel unlink();
destPoint = UAVModel.origin + vector_multiply( anglestoforward( UAVModel.angles ), 20000 );
UAVModel moveTo( destPoint, 60 );
PlayFXOnTag( level._effect[ "ac130_engineeffect" ] , UAVModel, "tag_origin" );
UAVModel waittill_notify_or_timeout_hostmigration_pause( "death", 3 );
UAVModel moveTo( destPoint, 4, 4, 0.0 );
UAVModel waittill_notify_or_timeout_hostmigration_pause( "death", 4 );
}
if ( isCounter )
UAVModel removeActiveCounterUAV();
else
UAVModel removeActiveUAV();
UAVModel delete();
removeUAVModel( UAVModel );
level notify ( "uav_update" );
}
monitorUAVStrike()
{
level endon( "game_ended" );
for ( ;; )
{
msg = self waittill_any_return( "death", "uav_strike_cancel", "uav_strike_successful" );
if ( msg == "uav_strike_successful" )
return true;
else
return false;
}
}
showLazeMessage()
{
msg = self maps\mp\gametypes\_hud_util::createFontString( "bigfixed", 0.75 );
msg maps\mp\gametypes\_hud_util::setPoint( "CENTER", "CENTER", 0 , 150 );
msg setText( &"MP_LASE_TARGET_FOR_PREDATOR_STRIKE" );
self waittill_any_timeout( 4.0, "death", "uav_strike_cancel", "uav_strike_successful" );
msg destroyElem();
}
waitForLazeDiscard()
{
level endon( "game_ended" );
self endon( "death" );
self endon( "uav_strike_used" );
for ( ;; )
{
self waittill ( "weapon_change", newWeapon );
if ( newWeapon != "uavstrikebinoculars_mp" )
{
self notify( "uav_strike_cancel" );
break;
}
else
wait( 0.05 );
}
}
waitForLazedTarget()
{
level endon( "game_ended" );
self endon( "death" );
self thread showLazeMessage();
self thread waitForLazeDiscard();
weapon = self getLastWeapon();
secondaryWeapon = undefined;
primaryWeapons = self GetWeaponsListPrimaries();
foreach ( primaryWeapon in primaryWeapons )
{
if ( primaryWeapon != weapon )
{
secondaryWeapon = primaryWeapon;
self takeWeapon( secondaryWeapon );
break;
}
}
self _giveWeapon("uavstrikebinoculars_mp");
self switchToWeapon( "uavstrikebinoculars_mp" );
traceData = undefined;
for(;;)
{
msg = self waittill_any_return( "weapon_fired", "uav_strike_cancel" );
if ( msg == "uav_strike_cancel" )
break;
origin = self GetEye();
forward = AnglesToForward( self GetPlayerAngles() );
endpoint = origin + forward * 15000;
traceData = BulletTrace( origin, endpoint, true, self );
if ( isDefined(traceData["position"]) )
break;
}
if ( isDefined( traceData ) )
{
targetPosition = traceData["position"];
fxEnt = SpawnFx( level._effect[ "laserTarget" ], targetPosition);
TriggerFx( fxEnt );
fxEnt thread waitFxEntDie();
magicBullet( "uav_strike_projectile_mp", targetPosition + (0,0,4000) , targetPosition, self );
self notify( "uav_strike_used" );
}
self takeWeapon( "uavstrikebinoculars_mp" );
if ( msg != "uav_strike_cancel" )
self switchToWeapon( weapon );
if ( isDefined( secondaryWeapon ) )
self _giveWeapon( secondaryWeapon );
if ( isDefined( traceData ) )
self notify( "uav_strike_successful" );
}
waitFxEntDie()
{
wait( 2 );
self delete();
}
waittill_notify_or_timeout_hostmigration_pause( msg, timer )
{
self endon( msg );
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( timer );
}
updateUAVModelVisibility()
{
self endon ( "death" );
for ( ;; )
{
level waittill_either ( "joined_team", "uav_update" );
self hide();
foreach ( player in level._players )
{
if ( level._teamBased )
{
if ( player.team != self.team )
self showToPlayer( player );
}
else
{
if ( isDefined( self.owner ) && player == self.owner )
continue;
self showToPlayer( player );
}
}
}
}
damageTracker( isCounterUAV )
{
level endon ( "game_ended" );
self setCanDamage( true );
self.maxhealth = 700;
self.health = self.maxhealth;
for ( ;; )
{
self waittill ( "damage", damage, attacker, direction_vec, point, sMeansOfDeath );
if ( !isPlayer( attacker ) )
{
if ( !isDefined( self ) )
return;
continue;
}
attacker maps\mp\gametypes\_damagefeedback::updateDamageFeedback( "" );
if ( attacker _hasPerk( "specialty_armorpiercing" ) && isDefined( self ) )
{
damageAdd = damage*level._armorPiercingMod;
self.health -= int(damageAdd);
}
if ( !isDefined( self ) )
{
if ( isPlayer( attacker ) && (!isDefined(self.owner) || attacker != self.owner) )
{
if ( isCounterUAV )
thread teamPlayerCardSplash( "callout_destroyed_counter_uav", attacker );
else
thread teamPlayerCardSplash( "callout_destroyed_uav", attacker );
thread maps\mp\gametypes\_missions::vehicleKilled( self.owner, self, undefined, attacker, damage, sMeansOfDeath );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "kill", 50 );
attacker notify( "destroyed_killstreak" );
}
return;
}
}
}
tryUseUAV( lifeId )
{
return useUAV( "uav" );
}
tryUseDoubleUAV( lifeId )
{
return useUAV( "double_uav" );
}
tryUseCounterUAV( lifeId )
{
return useUAV( "counter_uav" );
}
UAVStrikeSetup()
{
self.usedStrikeUAV = 0;
}
tryUseUAVStrike( lifeId )
{
if ( self.usedStrikeUAV == 0 )
{
self.usedStrikeUAV = 1;
//useUAV( "uav_strike" );
}
self thread waitForLazedTarget();
return monitorUAVStrike();
}
useUAV( uavType )
{
self maps\mp\_matchdata::logKillstreakEvent( uavType, self.origin );
team = self.pers["team"];
useTime = level._radarViewTime;
level thread launchUAV( self, team, useTime, uavType == "counter_uav" );
if ( uavType == "counter_uav" )
self notify( "used_counter_uav" );
else
self notify( "used_uav" );
return true;
}
UAVTracker()
{
level endon ( "game_ended" );
for ( ;; )
{
level waittill ( "uav_update" );
if ( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
updateTeamUAVStatus( level._teamNameList[i] );
}
}
else if ( level._teamBased )
{
updateTeamUAVStatus( "allies" );
updateTeamUAVStatus( "axis" );
}
else
{
updatePlayersUAVStatus();
}
}
}
updateTeamUAVStatus( team )
{
activeUAVs = level._activeUAVs[team];
activeCounterUAVs = 0;
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
if( team != level._teamNameList[i] )
{
activeCounterUAVs += level._activeCounterUAVs[level._teamNameList[i]];
}
}
}
else
{
activeCounterUAVs = level._activeCounterUAVs[level._otherTeam[team]];
}
if ( !activeCounterUAVs )
unblockTeamRadar( team );
else
blockTeamRadar( team );
if ( !activeUAVs )
{
setTeamRadarWrapper( team, 0 );
return;
}
if ( activeUAVs > 1 )
level._radarMode[team] = "fast_radar";
else
level._radarMode[team] = "normal_radar";
updateTeamUAVType();
setTeamRadarWrapper( team, 1 );
}
updatePlayersUAVStatus()
{
totalActiveCounterUAVs = 0;
counterUAVPlayer = undefined;
foreach ( player in level._players )
{
activeUAVs = level._activeUAVs[ player.guid ];
activeCounterUAVs = level._activeCounterUAVs[ player.guid ];
if ( activeCounterUAVs )
{
totalActiveCounterUAVs++;
counterUAVPlayer = player;
}
if ( !activeUAVs )
{
player.hasRadar = false;
if( player.radarMode != "directional_radar" )
{
player.radarMode = "normal_radar";
player.nextRadarMode = "normal_radar";
}
else
{
player.nextRadarMode = "normal_radar";
}
continue;
}
if ( activeUAVs > 1 )
if( player.radarMode != "directional_radar" )
{
player.radarMode = "fast_radar";
}
else
{
player.nextRadarMode = "fast_radar";
}
else
{
if( player.radarMode != "directional_radar" )
{
player.radarMode = "normal_radar";
player.nextRadarMode = "normal_radar";
}
else
{
player.nextRadarMode = "normal_radar";
}
}
player.hasRadar = true;
}
foreach ( player in level._players )
{
if ( !totalActiveCounterUAVs )
{
player.isRadarBlocked = false;
continue;
}
if ( totalActiveCounterUAVs == 1 && player == counterUAVPlayer )
player.isRadarBlocked = false;
else
player.isRadarBlocked = true;
}
}
blockPlayerUAV()
{
self endon ( "disconnect" );
self notify ( "blockPlayerUAV" );
self endon ( "blockPlayerUAV" );
self.isRadarBlocked = true;
wait ( level._uavBlockTime );
self.isRadarBlocked = false;
//self iPrintLn( &"MP_WAR_COUNTER_RADAR_EXPIRED" );
}
updateTeamUAVType()
{
foreach ( player in level._players )
{
if ( player.team == "spectator" )
continue;
if( player.radarMode != "directional_radar" )
{
player.radarMode = level._radarMode[player.team];
}
else
{
player.nextRadarMode = level._radarMode[player.team];
}
}
}
usePlayerUAV( doubleUAV, useTime )
{
level endon("game_ended");
self endon("disconnect");
self notify ( "usePlayerUAV" );
self endon ( "usePlayerUAV" );
if ( doubleUAV )
{
if( self.radarMode != "directional_radar" )
{
self.radarMode = "fast_radar";
}
else
{
self.nextRadarMode = "fast_radar";
}
}
else
{
if( self.radarMode != "directional_radar" )
{
self.radarMode = "normal_radar";
self.nextRadarMode = "normal_radar";
}
else
{
self.nextRadarMode = "normal_radar";
}
}
self.hasRadar = true;
wait ( useTime );
if( self.radarMode != "directional_radar" )
{
self.hasRadar = false;
}
//self iPrintLn( &"MP_WAR_RADAR_EXPIRED" );
}
setTeamRadarWrapper( team, value )
{
setTeamRadar( team, value );
level notify( "radar_status_change", team );
}
handleIncomingStinger()
{
level endon ( "game_ended" );
self endon ( "death" );
for ( ;; )
{
level waittill ( "stinger_fired", player, missile, lockTarget );
if ( !IsDefined( lockTarget ) || (lockTarget != self) )
continue;
missile thread stingerProximityDetonate( lockTarget, player );
}
}
stingerProximityDetonate( targetEnt, player )
{
self endon ( "death" );
minDist = distance( self.origin, targetEnt GetPointInBounds( 0, 0, 0 ) );
lastCenter = targetEnt GetPointInBounds( 0, 0, 0 );
for ( ;; )
{
// UAV already destroyed
if ( !isDefined( targetEnt ) )
center = lastCenter;
else
center = targetEnt GetPointInBounds( 0, 0, 0 );
lastCenter = center;
curDist = distance( self.origin, center );
if ( curDist < minDist )
minDist = curDist;
if ( curDist > minDist )
{
if ( curDist > 1536 )
return;
radiusDamage( self.origin, 1536, 600, 600, player );
playFx( level._stingerFXid, self.origin );
//self playSound( "remotemissile_explode" );
self hide();
self notify("deleted");
wait ( 0.05 );
self delete();
player notify( "killstreak_destroyed" );
}
wait ( 0.05 );
}
}
addUAVModel( UAVModel )
{
if ( level._teamBased )
level._UAVModels[UAVModel.team][level._UAVModels[UAVModel.team].size] = UAVModel;
else
level._UAVModels[UAVModel.owner.guid + "_" + getTime()] = UAVModel;
}
removeUAVModel( UAVModel )
{
UAVModels = [];
if ( level._teamBased )
{
team = UAVModel.team;
foreach ( uavModel in level._UAVModels[team] )
{
if ( !isDefined( uavModel ) )
continue;
UAVModels[UAVModels.size] = uavModel;
}
level._UAVModels[team] = UAVModels;
}
else
{
foreach ( uavModel in level._UAVModels )
{
if ( !isDefined( uavModel ) )
continue;
UAVModels[UAVModels.size] = uavModel;
}
level._UAVModels = UAVModels;
}
}
addActiveUAV()
{
if ( level._teamBased )
level._activeUAVs[self.team]++;
else
level._activeUAVs[self.owner.guid]++;
/*
if ( level._teamBased )
{
foreach ( player in level._players )
{
if ( player.team == self.team )
player iPrintLn( &"MP_WAR_RADAR_ACQUIRED", self.owner, level._radarViewTime );
else if ( player.team == level._otherTeam[self.team] )
player iPrintLn( &"MP_WAR_RADAR_ACQUIRED_ENEMY", level._radarViewTime );
}
}
else
{
foreach ( player in level._players )
{
if ( player == self.owner )
player iPrintLn( &"MP_WAR_RADAR_ACQUIRED", self.owner, level._radarViewTime );
else
player iPrintLn( &"MP_WAR_RADAR_ACQUIRED_ENEMY", level._radarViewTime );
}
}
*/
}
addActiveCounterUAV()
{
if ( level._teamBased )
level._activeCounterUAVs[self.team]++;
else
level._activeCounterUAVs[self.owner.guid]++;
/*
if ( level._teamBased )
{
foreach ( player in level._players )
{
if ( player.team == self.team )
player iPrintLn( &"MP_WAR_COUNTER_RADAR_ACQUIRED", self.owner, level._uavBlockTime );
else if ( player.team == level._otherTeam[self.team] )
player iPrintLn( &"MP_WAR_COUNTER_RADAR_ACQUIRED_ENEMY", level._uavBlockTime );
}
}
else
{
foreach ( player in level._players )
{
if ( player == self.owner )
player iPrintLn( &"MP_WAR_COUNTER_RADAR_ACQUIRED", self.owner, level._uavBlockTime );
else
player iPrintLn( &"MP_WAR_COUNTER_RADAR_ACQUIRED_ENEMY", level._uavBlockTime );
}
}
*/
}
removeActiveUAV()
{
if ( level._teamBased )
{
level._activeUAVs[self.team]--;
if ( !level._activeUAVs[self.team] )
{
//printOnTeam( &"MP_WAR_RADAR_EXPIRED", self.team );
//printOnTeam( &"MP_WAR_RADAR_EXPIRED_ENEMY", level._otherTeam[self.team] );
}
}
else if ( isDefined( self.owner ) )
{
level._activeUAVs[self.owner.guid]--;
}
}
removeActiveCounterUAV()
{
if ( level._teamBased )
{
level._activeCounterUAVs[self.team]--;
if ( !level._activeCounterUAVs[self.team] )
{
//printOnTeam( &"MP_WAR_COUNTER_RADAR_EXPIRED", self.team );
//printOnTeam( &"MP_WAR_COUNTER_RADAR_EXPIRED_ENEMY", level._otherTeam[self.team] );
}
}
else if ( isDefined( self.owner ) )
{
level._activeCounterUAVs[self.owner.guid]--;
}
}
MeleeUAV()
{
level endon ( "game_ended" );
self endon ( "disconnect" );
self.radarMode = "directional_radar";
// self.hasRadar = true;
wait ( 5 );
// self.hasRadar = false;
if( isDefined( self.nextRadarMode ))
{
self.radarMode = self.nextRadarMode;
}
else
{
self.radarMode = "normal_radar";
}
}

View File

@ -0,0 +1,204 @@
#include maps\mp\_utility;
#include common_scripts\utility;
// Each Killstreak has its own initialization function. This Script has two main purposes.
// (1). All global data and assets used by this killstreak should be initialized here.
// (2). The callback that executes when a player activates this killstreak should be set here.
// TODO: A call to this script must be added to the script init() in the file c:\trees\nx1\game\share\raw\maps\mp\killstreaks\_killstreaks.gsc,
// this is were each individual killstreak is initialized.
init()
{
//This is a good place to precache assets, load up fx, or setup any global data that might be needed, NOTE: Everything defined in killstreakTable.csv
//will be precached automatically ( see initKillstreakData() in _killstreaks.gsc if interested ) so you do not need to worry about initializing the
//strings/weapons/materials/sounds defined there. If, for example, you were going to manually script up a plane flyiing over when this killstreak was
//activated you would want to precache that model here.
//generally any global data that is needed would be stored in the level object, here is an example
//level._effect[ "emp_flash" ] = loadfx( "explosions/emp_flash_mp" );
//This is were the killstreak activation callback is set
//TODO: Replace "killstreak_template" with the name of the new killstreak as defined in killstreakTable.csv
//Most killstreaks use a try fuction ( which i recommend, even if it is not necessary for this particualr killstreak it is nice to have a consistent model )
//the try script will make sure it is ok to fire the killstreak before the actual killstreak script is called.
precacheString ( &"MP_AIR_SPACE_TOO_CROWDED" );
precacheString ( &"MP_HOLD_USERELOAD_TO_THROWAWAY" );
level._killstreakFuncs["weapdrop"] = ::try_use_weapdrop;
//Use this script to update/initialize players as they connect to the game
level thread onPlayerConnect();
}
// This script is running on the global level object, it monitors players connecting to the game.
// Its main purpose is to apply the onPlayerSpawned script to each player as they connect to the game.
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
}
}
// This script is running on each player in the game, it recieves a notification each time the player it is running on spawns in the game
// Its main purpose is to initialize any per player data, as well as update the player subject to any global killstreak data when that player spawns.
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill( "spawned_player" );
println( "player spwaned" );
// init/manage any per player killstreak data here
}
}
//Many of the killstreaks have a try block that will test level conditions to make sure it is ok to fire the killstreak now. A good example of this is for the air killstreaks.
//Only a certain number of vehicles are allowed in the air at any given time, so if the airspace is full and the killstreak cannot be fired this try should return false.
//If there are any preconditions that must be met in order to fire this killstreak they should be checked in this script.
//NOTE: If this script returns true the killstreak system will consider this killstreak usage complete and the dpad icon will be removed, if this script returns false nothing will
//change and the system will just continue to wait for the the player to activate the killstreak by pressing right on the dpad.
try_use_weapdrop()
{
is_ok_to_use_killstreak = true;
if( is_ok_to_use_killstreak )
{
weapdrop_use();
return true;
}
return false;
}
// This is the callback that executes when the killstreak is activated by a player pressing on the dpad. This is called from the script killstreakUsePressed()
// located in the file _killstreaks.gsc
weapdrop_use()
{
assert( isDefined( self ) );
//println( "Killstreak Template Fired!!" );
/*
// don't allow use if theres 3 or more little birds up in the air already. this is consistent with the care package drop ks.
if ( level._littleBirds >= 3 )
{
self iPrintLnBold( &"MP_AIR_SPACE_TOO_CROWDED" );
return false;
}
*/
weapdrop_weapon = undefined;
// randomInt is confusing. 0 based and the number passed is how many ints it can return. 4 = 0-3.
switch( randomInt( 4 ) )
{
case 0:
weapdrop_weapon = "augks_mp";
break;
case 1:
weapdrop_weapon = "xm25ks_mp";
break;
case 2:
weapdrop_weapon = "aa12_akimbo_mp";
break;
case 3:
weapdrop_weapon = "javelinks_mp";
break;
}
// spawn a new script to give and switch to the weapdrop weapon
// the drop ks's need to return true asap otherwise you're still holding the trigger in your hand
self thread weapdrop_equip( weapdrop_weapon );
return true;
}
weapdrop_equip( weapdrop_weapon )
{
self endon( "death" );
self endon( "disconnect" );
assert( isDefined( weapdrop_weapon ) );
// hack. sometimes getCurrentWeapon will return none but getWeaponsListPrimaries wont...hmm...
/*
initial_weapon = self getCurrentWeapon();
if ( initial_weapon == "none" )
{
weapList = self GetWeaponsListPrimaries();
initial_weapon = weapList[0];
}
//printLn( initial_weapon );
*/
// make sure the script that spawned this one has returned true before I switch your weapon. this is probably unnecessary.
wait .1;
// akimbo weapons must be given a specific way.
if ( weapdrop_weapon == "aa12_akimbo_mp" )
{
self giveWeapon( weapdrop_weapon, 0 , true );
}
else
{
self giveWeapon( weapdrop_weapon );
}
self switchToWeapon( weapdrop_weapon );
for( ;; )
{
// when you run out of ammo, switch back to your first primary and take the weapdrop weapon
if ( self hasWeapon ( weapdrop_weapon ) )
{
if ( self getAmmoCount( weapdrop_weapon ) == 0 )
{
//self switchToWeapon( initial_weapon );
self takeWeapon ( weapdrop_weapon );
break;
}
}
else
{
break;
}
wait 0.05;
}
//printLn( "NO LONGER HAS KS WEAPON" );
}
weapdrop_hud()
{
hudelem = newClientHudElem( self );
// put something on screen that tells you, you can throw away this weapon
hudelem.x = -30;
hudelem.y = -20;
hudelem.alignX = "left";
hudelem.alignY = "bottom";
hudelem.horzAlign = "center";
hudelem.vertAlign = "bottom";
hudelem.sort = 1;// force to draw after the background
hudelem.foreground = true;
hudelem SetText( &"MP_HOLD_USERELOAD_TO_THROWAWAY" );
hudelem.alpha = 0;
hudelem FadeOverTime( 0.2 );
hudelem.alpha = 1;
hudelem.hidewheninmenu = true;
hudelem.fontScale = 1.25;
hudelem.font = "fwmed";
//hudelem.color = ( getdvarfloat( "color_neutral_r" ), getdvarfloat( "color_neutral_g" ), getdvarfloat( "color_neutral_b" ) );
//hudelem SetPulseFX( 30, duration, 700 );// something, decay start, decay duration
self waittill_any( "death", "disconnect", "weapdrop_done" );
hudelem Destroy();
}

67
maps/mp/mp_nx_fallout.gsc Normal file
View File

@ -0,0 +1,67 @@
//****************************************************************************
// **
// Confidential - (C) Activision Publishing, Inc. 2010 **
// **
//****************************************************************************
// **
// Module: MISSION DESCRIPTION **
// **
// Created: DATE - CREATOR **
// **
//****************************************************************************
//#include maps\_utility;
//#include common_scripts\utility;
//#include maps\_anim;
//#include maps\_vehicle;
//*******************************************************************
// *
// *
//*******************************************************************
/*
main()
{
// External Initialization
maps\mp_nx_fallout_precache::main();
//maps\mp_nx_fallout_anim::main();
maps\mp_nx_fallout_fx::main();
maps\_load::main();
// Internal Initialization
mission_flag_inits();
mission_precache();
}
*/
main()
{
maps\mp\mp_nx_fallout_precache::main();
maps\createart\mp_nx_fallout_art::main();
maps\mp\mp_nx_fallout_fx::main();
maps\mp\_load::main();
maps\mp\_compass::setupMiniMap("compass_map_mp_nx_fallout");
ambientPlay( "ambient_mp_default" );
game["attackers"] = "allies";
game["defenders"] = "axis";
}
// All mission specific PreCache calls
mission_precache()
{
}
// All mission specific flag_init() calls
mission_flag_inits()
{
}
//*******************************************************************
// *
// *
//*******************************************************************

View File

@ -0,0 +1,30 @@
//****************************************************************************
// **
// Confidential - (C) Activision Publishing, Inc. 2010 **
// **
//****************************************************************************
// **
// Module: FX Support **
// **
// Created: DATE - CREATOR **
// **
//****************************************************************************
main()
{
//level._effect[ "ash_aftermath_ugv_mp" ] = loadfx( "weather/ash_aftermath_ugv_mp" );
level._effect[ "tank_fire_hatch" ] = loadfx( "fire/tank_fire_hatch" );
level._effect[ "nx_mp_fallout_steam_jet" ] = loadfx( "nx/mp/steam/nx_mp_fallout_steam_jet" );
level._effect[ "nx_mp_fallout_steam_filler" ] = loadfx( "nx/mp/steam/nx_mp_fallout_steam_filler" );
level._effect[ "nx_mp_ash_aftermath_fallout" ] = loadfx( "nx/mp/weather/nx_mp_ash_aftermath_fallout" );
level._effect[ "battlefield_smokebank_S_warm_thick" ] = loadfx( "smoke/battlefield_smokebank_S_warm_thick" );
if ( !getdvarint( "r_reflectionProbeGenerate" ) )
maps\createfx\mp_nx_fallout_fx::main();
}
//*******************************************************************
// *
// *
//*******************************************************************

View File

@ -0,0 +1,8 @@
// this file is autogenerated, modifying parameters is ok, other lines will be removed.
main()
{
maps\animated_models\foliage_tree_palm_bushy_1::main();
maps\animated_models\foliage_tree_palm_bushy_3::main();
maps\animated_models\highrise_fencetarp_01::main();
maps\animated_models\highrise_fencetarp_09::main();
}

View File

@ -0,0 +1,68 @@
//****************************************************************************
// **
// Confidential - (C) Activision Publishing, Inc. 2010 **
// **
//****************************************************************************
// **
// Module: MISSION DESCRIPTION **
// **
// Created: DATE - CREATOR **
// **
//****************************************************************************
//#include maps\_utility;
//#include common_scripts\utility;
//#include maps\_anim;
//#include maps\_vehicle;
//*******************************************************************
// *
// *
//*******************************************************************
/*
main()
{
// External Initialization
maps\mp_nx_galleria_precache::main();
//maps\mp_nx_galleria_anim::main();
maps\mp_nx_galleria_fx::main();
maps\_load::main();
// Internal Initialization
mission_flag_inits();
mission_precache();
}
*/
main()
{
maps\mp\mp_nx_galleria_precache::main();
maps\createart\mp_nx_galleria_art::main();
maps\mp\mp_nx_galleria_fx::main();
maps\mp\_load::main();
maps\mp\_compass::setupMiniMap("compass_map_mp_nx_galleria");
ambientPlay( "ambient_mp_galleria_front" );
game["attackers"] = "allies";
game["defenders"] = "axis";
}
// All mission specific PreCache calls
mission_precache()
{
}
// All mission specific flag_init() calls
mission_flag_inits()
{
}
//*******************************************************************
// *
// *
//*******************************************************************
 $

View File

@ -0,0 +1,70 @@
//****************************************************************************
// **
// Confidential - (C) Activision Publishing, Inc. 2010 **
// **
//****************************************************************************
// **
// Module: FX Support **
// **
// Created: DATE - CREATOR **
// **
//****************************************************************************
//#include common_scripts\utility;
main()
{
level._effect[ "drips_fast" ] = loadfx( "misc/drips_fast" );
level._effect[ "nx_smoke_plume_huge" ] = loadfx( "nx/smoke/nx_smoke_plume_huge" );
level._effect[ "nx_ash_cloud_heavy" ] = loadfx( "nx/misc/nx_ash_cloud_heavy" );
level._effect[ "nx_smoke_plume_huge_periph_preseed" ] = loadfx( "nx/smoke/nx_smoke_plume_huge_periph_preseed" );
level._effect[ "nx_smoke_plume_huge_periph_dark_preseed" ] = loadfx( "nx/smoke/nx_smoke_plume_huge_periph_dark_preseed" );
level._effect[ "nx_fire_building_large" ] = loadfx( "nx/fire/nx_fire_building_large" );
level._effect[ "nx_debri_paper_falling_building" ] = loadfx( "nx/misc/nx_debri_paper_falling_building" );
//level._effect[ "nx_ash_cloud_heavy_runner" ] = loadfx( "nx/misc/nx_ash_cloud_heavy_runner" );
//level._effect[ "nx_godray_medium" ] = loadfx( "nx/misc/nx_godray_medium" );
//level._effect[ "nx_ash_cloud_heavy_parkinglot" ] = loadfx( "nx/misc/nx_ash_cloud_heavy_parkinglot" );
level._effect[ "nx_big_orange_glows" ] = loadfx( "nx/misc/nx_big_orange_glows" );
level._effect[ "nx_fire_building_distant" ] = loadfx( "nx/fire/nx_fire_building_distant" );
//level._effect[ "dust_outdoor_large" ] = loadfx( "dust/dust_outdoor_large" );
level._effect[ "dust_wind_fast_paper" ] = loadfx( "dust/dust_wind_fast_paper" );
level._effect[ "paper_falling_burning" ] = loadfx( "misc/paper_falling_burning" );
//level._effect[ "ground_fog" ] = loadfx( "dust/ground_fog" );
level._effect[ "ground_smoke_dcburning1200x1200" ] = loadfx( "smoke/ground_smoke1200x1200_dcburning" );
level._effect[ "trash_spiral_runner" ] = loadfx( "misc/trash_spiral_runner" );
level._effect[ "paper_blowing_trash" ] = loadfx( "misc/paper_blowing_trash" );
level._effect[ "room_smoke_400" ] = loadfx( "smoke/room_smoke_400" );
level._effect[ "nx_light_emergency_red" ] = loadfx( "nx/misc/nx_light_emergency_red" );
level._effect[ "nx_sparks_falling_runner" ] = loadfx( "nx/explosions/nx_sparks_falling_runner" );
level._effect[ "crawling_death_blood_smear" ] = loadfx( "impacts/blood_smear_decal" );
level._effect[ "blood_pool" ] = loadfx( "impacts/deathfx_bloodpool_generic" );
level._effect[ "nx_flesh_hit_splat_large" ] = loadfx( "impacts/nx_flesh_hit_splat_large" );
level._effect[ "nx_flesh_hit_splat" ] = loadfx( "impacts/nx_flesh_hit_splat" );
//level._effect[ "nx_gfx_godray_side" ] = loadfx( "nx/misc/nx_gfx_godray_side" );
//level._effect[ "nx_gfx_godray_side_small" ] = loadfx( "nx/misc/nx_gfx_godray_side_small" );
//level._effect[ "nx_gfx_godray_down" ] = loadfx( "nx/misc/nx_gfx_godray_down" );
level._effect[ "amb_smoke_add" ] = loadfx( "smoke/amb_smoke_add" );
level._effect[ "amb_smoke_blend" ] = loadfx( "smoke/amb_smoke_blend" );
level._effect[ "nx_godray_150" ] = loadfx( "nx/misc/nx_godray_150" );
level._effect[ "nx_godray_225_soft" ] = loadfx( "nx/misc/nx_godray_225_soft" );
level._effect[ "nx_godray_75" ] = loadfx( "nx/misc/nx_godray_75" );
level._effect[ "police_lights" ] = loadfx( "nx/misc/nx_light_police_lights" );
level._effect[ "nx_ash_cloud_light" ] = loadfx( "nx/misc/nx_ash_cloud_light" );
level._effect[ "nx_smoke_mid_bldg_preseed" ] = loadfx( "nx/smoke/nx_smoke_mid_bldg_preseed" );
level._effect[ "nx_trash_runner_1024" ] = loadfx( "nx/misc/nx_trash_runner_1024" );
if ( getdvar( "clientsideeffects" ) != "1" )
{
maps\createfx\mp_nx_galleria_fx::main();
}
}
//*******************************************************************
// *
// *
//*******************************************************************

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