mirror of
https://github.com/reaaLx/nx1-gsc-dump.git
synced 2025-06-28 07:11:50 +00:00
Init
This commit is contained in:
211
maps/mp/gametypes/_battlechatter_mp.gsc
Normal file
211
maps/mp/gametypes/_battlechatter_mp.gsc
Normal file
@ -0,0 +1,211 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
init()
|
||||
{
|
||||
if( level._multiTeamBased == true )
|
||||
{
|
||||
for( i = 0; i < level._teamNameList.size; i++ )
|
||||
{
|
||||
level._isTeamSpeaking[level._teamNameList[i]] = false;
|
||||
level._speakers[level._teamNameList[i]] = [];
|
||||
}
|
||||
}
|
||||
|
||||
level._isTeamSpeaking["allies"] = false;
|
||||
level._isTeamSpeaking["axis"] = false;
|
||||
|
||||
level._speakers["allies"] = [];
|
||||
level._speakers["axis"] = [];
|
||||
|
||||
level._bcSounds = [];
|
||||
level._bcSounds["reload"] = "inform_reloading_generic";
|
||||
level._bcSounds["frag_out"] = "inform_attack_grenade";
|
||||
level._bcSounds["flash_out"] = "inform_attack_flashbang";
|
||||
level._bcSounds["smoke_out"] = "inform_attack_smoke";
|
||||
level._bcSounds["conc_out"] = "inform_attack_stun";
|
||||
level._bcSounds["c4_plant"] = "inform_attack_thwc4";
|
||||
level._bcSounds["claymore_plant"] = "inform_plant_claymore";
|
||||
level._bcSounds["kill"] = "inform_killfirm_infantry";
|
||||
level._bcSounds["casualty"] = "inform_casualty_generic";
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill ( "connected", player );
|
||||
|
||||
player thread onPlayerSpawned();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
// help players be stealthy in splitscreen by not announcing their intentions
|
||||
if ( level._splitscreen )
|
||||
continue;
|
||||
|
||||
self thread claymoreTracking();
|
||||
self thread reloadTracking();
|
||||
self thread grenadeTracking();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
claymoreTracking()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
while(1)
|
||||
{
|
||||
self waittill( "begin_firing" );
|
||||
weaponName = self getCurrentWeapon();
|
||||
if ( weaponName == "claymore_mp" )
|
||||
level thread sayLocalSound( self, "claymore_plant" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
reloadTracking()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
self waittill ( "reload_start" );
|
||||
level thread sayLocalSound( self, "reload" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
grenadeTracking()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
self waittill ( "grenade_fire", grenade, weaponName );
|
||||
|
||||
if ( weaponName == "frag_grenade_mp" )
|
||||
level thread sayLocalSound( self, "frag_out" );
|
||||
else if ( weaponName == "flash_grenade_mp" )
|
||||
level thread sayLocalSound( self, "flash_out" );
|
||||
else if ( weaponName == "concussion_grenade_mp" )
|
||||
level thread sayLocalSound( self, "conc_out" );
|
||||
else if ( weaponName == "smoke_grenade_mp" )
|
||||
level thread sayLocalSound( self, "smoke_out" );
|
||||
else if ( weaponName == "c4_mp" )
|
||||
level thread sayLocalSound( self, "c4_plant" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sayLocalSoundDelayed( player, soundType, delay )
|
||||
{
|
||||
player endon ( "death" );
|
||||
player endon ( "disconnect" );
|
||||
|
||||
wait ( delay );
|
||||
|
||||
sayLocalSound( player, soundType );
|
||||
}
|
||||
|
||||
|
||||
sayLocalSound( player, soundType )
|
||||
{
|
||||
player endon ( "death" );
|
||||
player endon ( "disconnect" );
|
||||
|
||||
if ( isSpeakerInRange( player ) )
|
||||
return;
|
||||
|
||||
if( player.team != "spectator" )
|
||||
{
|
||||
prefix = maps\mp\gametypes\_teams::getTeamVoicePrefix( player.team ) + "1_";
|
||||
soundAlias = prefix + level._bcSounds[soundType];
|
||||
player thread doSound( soundAlias );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
doSound( soundAlias )
|
||||
{
|
||||
team = self.pers["team"];
|
||||
level addSpeaker( self, team );
|
||||
self playSoundToTeam( soundAlias, team, self );
|
||||
self thread timeHack( soundAlias ); // workaround because soundalias notify isn't happening
|
||||
self waittill_any( soundAlias, "death", "disconnect" );
|
||||
level removeSpeaker( self, team );
|
||||
}
|
||||
|
||||
|
||||
timeHack( soundAlias )
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
wait ( 2.0 );
|
||||
self notify ( soundAlias );
|
||||
}
|
||||
|
||||
|
||||
isSpeakerInRange( player )
|
||||
{
|
||||
player endon ( "death" );
|
||||
player endon ( "disconnect" );
|
||||
|
||||
distSq = 1000 * 1000;
|
||||
|
||||
// to prevent player switch to spectator after throwing a granade causing damage to someone and result in attacker.pers["team"] = "spectator"
|
||||
if( isdefined( player ) && isdefined( player.pers["team"] ) && player.pers["team"] != "spectator" )
|
||||
{
|
||||
for ( index = 0; index < level._speakers[player.pers["team"]].size; index++ )
|
||||
{
|
||||
teammate = level._speakers[player.pers["team"]][index];
|
||||
if ( teammate == player )
|
||||
return true;
|
||||
|
||||
if ( distancesquared( teammate.origin, player.origin ) < distSq )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
addSpeaker( player, team )
|
||||
{
|
||||
level._speakers[team][level._speakers[team].size] = player;
|
||||
}
|
||||
|
||||
|
||||
// this is lazy... fix up later by tracking ID's and doing array slot swapping
|
||||
removeSpeaker( player, team )
|
||||
{
|
||||
newSpeakers = [];
|
||||
for ( index = 0; index < level._speakers[team].size; index++ )
|
||||
{
|
||||
if ( level._speakers[team][index] == player )
|
||||
continue;
|
||||
|
||||
newSpeakers[newSpeakers.size] = level._speakers[team][index];
|
||||
}
|
||||
|
||||
level._speakers[team] = newSpeakers;
|
||||
}
|
274
maps/mp/gametypes/_callbacksetup.gsc
Normal file
274
maps/mp/gametypes/_callbacksetup.gsc
Normal file
@ -0,0 +1,274 @@
|
||||
// Callback Setup
|
||||
// This script provides the hooks from code into script for the gametype callback functions.
|
||||
|
||||
//=============================================================================
|
||||
// Code Callback functions
|
||||
|
||||
/*================
|
||||
Called by code after the level's main script function has run.
|
||||
================*/
|
||||
CodeCallback_StartGameType()
|
||||
{
|
||||
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
|
||||
level waittill( "eternity" );
|
||||
|
||||
// If the gametype has not beed started, run the startup
|
||||
if(!isDefined(level._gametypestarted) || !level._gametypestarted)
|
||||
{
|
||||
[[level._callbackStartGameType]]();
|
||||
|
||||
level._gametypestarted = true; // so we know that the gametype has been started up
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a player begins connecting to the server.
|
||||
Called again for every map change or tournement restart.
|
||||
|
||||
Return undefined if the client should be allowed, otherwise return
|
||||
a string with the reason for denial.
|
||||
|
||||
Otherwise, the client will be sent the current gamestate
|
||||
and will eventually get to ClientBegin.
|
||||
|
||||
firstTime will be qtrue the very first time a client connects
|
||||
to the server machine, but qfalse on map changes and tournement
|
||||
restarts.
|
||||
================*/
|
||||
CodeCallback_PlayerConnect()
|
||||
{
|
||||
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
|
||||
level waittill( "eternity" );
|
||||
|
||||
self endon("disconnect");
|
||||
[[level._callbackPlayerConnect]]();
|
||||
|
||||
// tagGHS< BB adds >
|
||||
lpselfnum = self getEntityNumber();
|
||||
bbPrint( "mpjoins: name %s client %s", self.name, lpselfnum );
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player drops from the server.
|
||||
Will not be called between levels.
|
||||
self is the player that is disconnecting.
|
||||
================*/
|
||||
CodeCallback_PlayerDisconnect()
|
||||
{
|
||||
self maps\mp\gametypes\_gamelogic::dump_score_board_to_black_box_for_player_bailed_early();
|
||||
|
||||
self notify("disconnect");
|
||||
|
||||
[[level._callbackPlayerDisconnect]]();
|
||||
|
||||
lpselfnum = self getEntityNumber();
|
||||
bbPrint( "mpquits: name %s client %d", self.name, lpselfnum );
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player has taken damage.
|
||||
self is the player that took damage.
|
||||
================*/
|
||||
CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level._callbackPlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player has been killed.
|
||||
self is the player that was killed.
|
||||
================*/
|
||||
CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
//println( "mpattacks: victimxuid='" + self GetXUID() + "', victimweapon='" + self GetCurrentWeapon() + "'\n" );
|
||||
//bbPrint( "breakpoint:" );
|
||||
|
||||
if(self.sessionstate != "dead")
|
||||
{
|
||||
attackerweaponiskillstreak = 0;
|
||||
if ( maps\mp\_utility::isKillstreakWeapon( sWeapon ) )
|
||||
{
|
||||
attackerweaponiskillstreak = 1;
|
||||
}
|
||||
attackerweaponisequipment = 0;
|
||||
if( maps\mp\gametypes\_weapons::isEquipment( sWeapon ) )
|
||||
{
|
||||
attackerweaponisequipment = 1;
|
||||
}
|
||||
attackerweaponisnormal = 1; // assume weapon is normal unless it's a killstreak or equipment weapon.
|
||||
if( ( attackerweaponiskillstreak != 0 ) || ( attackerweaponisequipment != 0 ) )
|
||||
{
|
||||
attackerweaponisnormal = 0;
|
||||
}
|
||||
|
||||
lpattackerorigin = ( 0, 0, 0 );
|
||||
if(isPlayer(eAttacker))
|
||||
{
|
||||
lpattacknum = eAttacker getEntityNumber();
|
||||
lpattackGuid = eAttacker getGuid();
|
||||
lpattackname = eAttacker.name;
|
||||
lpattackerteam = eAttacker.pers["team"];
|
||||
lpattackerorigin = eAttacker.origin;
|
||||
|
||||
//println( "mpattacks: victimxuid='" + self GetXUID() + "', attackerxuid='" + eAttacker GetXUID() + "'\n" );
|
||||
//bbPrint( "breakpoint:" );
|
||||
|
||||
bbPrint( "mpattacks: gametime %d attackerspawnid %d attackerxuid %llu attackerweapon %s attackerx %f attackery %f attackerz %f victimspawnid %d victimxuid %llu victimweapon %s victimx %f victimy %f victimz %f damage %d damagetype %s damagelocation %s death 0 attackerweaponisnormal %d attackerweaponiskillstreak %d attackerweaponisequipment %d attackersuit %s victimsuit %s",
|
||||
gettime(), eAttacker getplayerspawnid(), eAttacker GetXUID(), sWeapon, lpattackerorigin, self getplayerspawnid(), self GetXUID(), self GetCurrentWeapon(), self.origin, iDamage, sMeansOfDeath, sHitLoc, attackerweaponisnormal, attackerweaponiskillstreak, attackerweaponisequipment, eAttacker.currentSuit, self.currentSuit );
|
||||
}
|
||||
else
|
||||
{
|
||||
//println( "mpattacks: victimxuid='" + self GetXUID() + "'\n" );
|
||||
|
||||
lpattacknum = -1;
|
||||
lpattackGuid = "";
|
||||
lpattackname = "";
|
||||
lpattackerteam = "world";
|
||||
bbPrint( "mpattacks: gametime %d attackerweapon %s victimspawnid %d victimxuid %llu victimweapon %s victimx %f victimy %f victimz %f damage %d damagetype %s damagelocation %s death 0 attackerweaponisnormal %d attackerweaponiskillstreak %d attackerweaponisequipment %d",
|
||||
gettime(), sWeapon, self getplayerspawnid(), self GetXUID(), self GetCurrentWeapon(), self.origin, iDamage, sMeansOfDeath, sHitLoc, attackerweaponisnormal, attackerweaponiskillstreak, attackerweaponisequipment );
|
||||
}
|
||||
//bbPrint( "breakpoint:" );
|
||||
}
|
||||
// We need to do the bbprint before here since the level callbacks will respawn the player by the time this next line returns
|
||||
[[level._callbackPlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a vehicle has taken damage.
|
||||
self is the vehicle that took damage.
|
||||
================*/
|
||||
CodeCallback_VehicleDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName )
|
||||
{
|
||||
if ( isDefined( self.damageCallback ) )
|
||||
self [[self.damageCallback]]( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
|
||||
else
|
||||
self Vehicle_FinishDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when code is forcibly ending the game.
|
||||
e.g. we suck as host.
|
||||
================*/
|
||||
CodeCallback_CodeEndGame()
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level._callbackCodeEndGame]]();
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a player has been killed, but has last stand perk.
|
||||
self is the player that was killed.
|
||||
================*/
|
||||
CodeCallback_PlayerLastStand(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level._callbackPlayerLastStand]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a player reconnects to the server
|
||||
following a host migration.
|
||||
================*/
|
||||
CodeCallback_PlayerMigrated()
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level._callbackPlayerMigrated]]();
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called once when a host migration has occured.
|
||||
================*/
|
||||
CodeCallback_HostMigration()
|
||||
{
|
||||
[[level._callbackHostMigration]]();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
// Damage flags used in the playerDamage callback
|
||||
SetupDamageFlags()
|
||||
{
|
||||
// code-defined:
|
||||
level._iDFLAGS_RADIUS = 1; // damage was indirect
|
||||
level._iDFLAGS_NO_ARMOR = 2; // armor does not protect from this damage
|
||||
level._iDFLAGS_NO_KNOCKBACK = 4; // do not affect velocity, just view angles
|
||||
level._iDFLAGS_PENETRATION = 8; // damage occurred after one or more penetrations
|
||||
level._iDFLAGS_STUN = 16; // non-lethal
|
||||
level._iDFLAGS_SHIELD_EXPLOSIVE_IMPACT = 32; // missile impacted on the front of the victim's shield
|
||||
level._iDFLAGS_SHIELD_EXPLOSIVE_IMPACT_HUGE = 64; // ...and was from a projectile with "Big Explosion" checked on.
|
||||
level._iDFLAGS_SHIELD_EXPLOSIVE_SPLASH = 128; // explosive splash, somewhat deflected by the victim's shield
|
||||
|
||||
// script-defined:
|
||||
level._iDFLAGS_NO_TEAM_PROTECTION = 256;
|
||||
level._iDFLAGS_NO_PROTECTION = 512;
|
||||
level._iDFLAGS_PASSTHRU = 1024;
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Setup any misc callbacks stuff like defines and default callbacks
|
||||
================*/
|
||||
SetupCallbacks()
|
||||
{
|
||||
SetDefaultCallbacks();
|
||||
SetupDamageFlags();
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called from the gametype script to store off the default callback functions.
|
||||
This allows the callbacks to be overridden by level script, but not lost.
|
||||
================*/
|
||||
SetDefaultCallbacks()
|
||||
{
|
||||
level._callbackStartGameType = maps\mp\gametypes\_gamelogic::Callback_StartGameType;
|
||||
level._callbackPlayerConnect = maps\mp\gametypes\_playerlogic::Callback_PlayerConnect;
|
||||
level._callbackPlayerDisconnect = maps\mp\gametypes\_playerlogic::Callback_PlayerDisconnect;
|
||||
level._callbackPlayerDamage = maps\mp\gametypes\_damage::Callback_PlayerDamage;
|
||||
level._callbackPlayerKilled = maps\mp\gametypes\_damage::Callback_PlayerKilled;
|
||||
level._callbackCodeEndGame = maps\mp\gametypes\_gamelogic::Callback_CodeEndGame;
|
||||
level._callbackPlayerLastStand = maps\mp\gametypes\_damage::Callback_PlayerLastStand;
|
||||
level._callbackPlayerMigrated = maps\mp\gametypes\_playerlogic::Callback_PlayerMigrated;
|
||||
level._callbackHostMigration = maps\mp\gametypes\_hostmigration::Callback_HostMigration;
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a gametype is not supported.
|
||||
================*/
|
||||
AbortLevel()
|
||||
{
|
||||
println("Aborting level - gametype is not supported");
|
||||
|
||||
level._callbackStartGameType = ::callbackVoid;
|
||||
level._callbackPlayerConnect = ::callbackVoid;
|
||||
level._callbackPlayerDisconnect = ::callbackVoid;
|
||||
level._callbackPlayerDamage = ::callbackVoid;
|
||||
level._callbackPlayerKilled = ::callbackVoid;
|
||||
level._callbackCodeEndGame = ::callbackVoid;
|
||||
level._callbackPlayerLastStand = ::callbackVoid;
|
||||
level._callbackPlayerMigrated = ::callbackVoid;
|
||||
level._callbackHostMigration = ::callbackVoid;
|
||||
|
||||
setdvar("g_gametype", "dm");
|
||||
|
||||
exitLevel(false);
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
================*/
|
||||
callbackVoid()
|
||||
{
|
||||
}
|
2896
maps/mp/gametypes/_class.gsc
Normal file
2896
maps/mp/gametypes/_class.gsc
Normal file
File diff suppressed because it is too large
Load Diff
2558
maps/mp/gametypes/_damage.gsc
Normal file
2558
maps/mp/gametypes/_damage.gsc
Normal file
File diff suppressed because it is too large
Load Diff
94
maps/mp/gametypes/_damagefeedback.gsc
Normal file
94
maps/mp/gametypes/_damagefeedback.gsc
Normal file
@ -0,0 +1,94 @@
|
||||
init()
|
||||
{
|
||||
precacheShader("damage_feedback");
|
||||
precacheShader("damage_feedback_j");
|
||||
precacheShader("damage_feedback_trophy");
|
||||
precacheShader("damage_feedback_endgame");
|
||||
precacheShader("scavenger_pickup");
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player.hud_damagefeedback = newClientHudElem(player);
|
||||
player.hud_damagefeedback.horzAlign = "center";
|
||||
player.hud_damagefeedback.vertAlign = "middle";
|
||||
player.hud_damagefeedback.x = -12;
|
||||
player.hud_damagefeedback.y = -12;
|
||||
player.hud_damagefeedback.alpha = 0;
|
||||
player.hud_damagefeedback.archived = true;
|
||||
player.hud_damagefeedback setShader("damage_feedback", 24, 48);
|
||||
}
|
||||
}
|
||||
|
||||
updateDamageFeedback( typeHit )
|
||||
{
|
||||
if ( !isPlayer( self ) )
|
||||
return;
|
||||
|
||||
x = -12;
|
||||
y = -12;
|
||||
|
||||
if ( getDvarInt( "camera_thirdPerson" ) )
|
||||
yOffset = self GetThirdPersonCrosshairOffset() * 240;
|
||||
else
|
||||
yOffset = getdvarfloat( "cg_crosshairVerticalOffset" ) * 240;
|
||||
|
||||
if ( level._splitscreen )
|
||||
yOffset *= 0.5;
|
||||
|
||||
feedbackDurationOverride = 0;
|
||||
startAlpha = 1;
|
||||
|
||||
if ( typeHit == "hitBodyArmor" )
|
||||
{
|
||||
self.hud_damagefeedback setShader("damage_feedback_trophy", 24, 48);
|
||||
self playlocalsound("MP_hit_alert"); // TODO: change sound?
|
||||
}
|
||||
else if ( typeHit == "hitEndGame" )
|
||||
{
|
||||
self.hud_damagefeedback setShader("damage_feedback_endgame", 24, 48);
|
||||
self playlocalsound("MP_hit_alert");
|
||||
}
|
||||
else if ( typeHit == "stun" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if ( typeHit == "none" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if ( typeHit == "scavenger" && !level._hardcoreMode )
|
||||
{
|
||||
x = -36;
|
||||
y = 32;
|
||||
self.hud_damagefeedback setShader("scavenger_pickup", 64, 32);
|
||||
feedbackDurationOverride = 2.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.hud_damagefeedback setShader("damage_feedback", 24, 48);
|
||||
self playlocalsound("MP_hit_alert");
|
||||
}
|
||||
|
||||
self.hud_damagefeedback.alpha = startAlpha;
|
||||
if ( feedBackDurationOverride != 0 )
|
||||
self.hud_damagefeedback fadeOverTime(feedbackDurationOverride);
|
||||
else
|
||||
self.hud_damagefeedback fadeOverTime(1);
|
||||
|
||||
self.hud_damagefeedback.alpha = 0;
|
||||
|
||||
// only update hudelem positioning when necessary
|
||||
if ( self.hud_damagefeedback.x != x )
|
||||
self.hud_damagefeedback.x = x;
|
||||
|
||||
y = y - int( yOffset );
|
||||
if ( self.hud_damagefeedback.y != y )
|
||||
self.hud_damagefeedback.y = y;
|
||||
}
|
87
maps/mp/gametypes/_deathicons.gsc
Normal file
87
maps/mp/gametypes/_deathicons.gsc
Normal file
@ -0,0 +1,87 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
if (!level._teambased)
|
||||
return;
|
||||
|
||||
precacheShader("headicon_dead");
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player.selfDeathIcons = []; // icons that other people see which point to this player when he's dead
|
||||
}
|
||||
}
|
||||
|
||||
updateDeathIconsEnabled()
|
||||
{
|
||||
//if (!self.enableDeathIcons)
|
||||
// self removeOtherDeathIcons();
|
||||
}
|
||||
|
||||
addDeathIcon( entity, dyingplayer, team, timeout )
|
||||
{
|
||||
if ( !level._teambased )
|
||||
return;
|
||||
|
||||
//tagZP<TODO> fix death icons in MTDM
|
||||
if( level._multiTeamBased )
|
||||
{
|
||||
println( "tagZP<TODO> Fix death icons in MTMD" );
|
||||
return;
|
||||
}
|
||||
|
||||
iconOrg = entity.origin;
|
||||
|
||||
dyingplayer endon("spawned_player");
|
||||
dyingplayer endon("disconnect");
|
||||
|
||||
wait .05;
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
assert(team == "allies" || team == "axis");
|
||||
|
||||
if ( getDvar( "ui_hud_showdeathicons" ) == "0" )
|
||||
return;
|
||||
if ( level._hardcoreMode )
|
||||
return;
|
||||
|
||||
if ( isdefined( self.lastDeathIcon ) )
|
||||
self.lastDeathIcon destroy();
|
||||
|
||||
newdeathicon = newTeamHudElem( team );
|
||||
newdeathicon.x = iconOrg[0];
|
||||
newdeathicon.y = iconOrg[1];
|
||||
newdeathicon.z = iconOrg[2] + 54;
|
||||
newdeathicon.alpha = .61;
|
||||
newdeathicon.archived = true;
|
||||
if ( level._splitscreen )
|
||||
newdeathicon setShader("headicon_dead", 14, 14);
|
||||
else
|
||||
newdeathicon setShader("headicon_dead", 7, 7);
|
||||
newdeathicon setwaypoint( true, false );
|
||||
|
||||
self.lastDeathIcon = newdeathicon;
|
||||
|
||||
newdeathicon thread destroySlowly ( timeout );
|
||||
}
|
||||
|
||||
destroySlowly( timeout )
|
||||
{
|
||||
self endon("death");
|
||||
|
||||
wait timeout;
|
||||
|
||||
self fadeOverTime(1.0);
|
||||
self.alpha = 0;
|
||||
|
||||
wait 1.0;
|
||||
self destroy();
|
||||
}
|
1661
maps/mp/gametypes/_dev.gsc
Normal file
1661
maps/mp/gametypes/_dev.gsc
Normal file
File diff suppressed because it is too large
Load Diff
120
maps/mp/gametypes/_friendicons.gsc
Normal file
120
maps/mp/gametypes/_friendicons.gsc
Normal file
@ -0,0 +1,120 @@
|
||||
init()
|
||||
{
|
||||
// Draws a team icon over teammates
|
||||
level._drawfriend = 0;
|
||||
|
||||
game["headicon_allies"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "allies" );
|
||||
game["headicon_axis"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "axis" );
|
||||
|
||||
precacheHeadIcon( game["headicon_allies"] );
|
||||
precacheHeadIcon( game["headicon_axis"] );
|
||||
|
||||
precacheShader( "waypoint_revive" );
|
||||
|
||||
level thread onPlayerConnect();
|
||||
|
||||
for(;;)
|
||||
{
|
||||
updateFriendIconSettings();
|
||||
wait 5;
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player thread onPlayerSpawned();
|
||||
player thread onPlayerKilled();
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("spawned_player");
|
||||
|
||||
self thread showFriendIcon();
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerKilled()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("killed_player");
|
||||
self.headicon = "";
|
||||
}
|
||||
}
|
||||
|
||||
showFriendIcon()
|
||||
{
|
||||
if(level._drawfriend)
|
||||
{
|
||||
if(self.pers["team"] == "allies")
|
||||
{
|
||||
self.headicon = game["headicon_allies"];
|
||||
self.headiconteam = "allies";
|
||||
}
|
||||
else
|
||||
{
|
||||
self.headicon = game["headicon_axis"];
|
||||
self.headiconteam = "axis";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateFriendIconSettings()
|
||||
{
|
||||
drawfriend = maps\mp\_utility::getIntProperty("scr_drawfriend", level._drawfriend);
|
||||
if(level._drawfriend != drawfriend)
|
||||
{
|
||||
level._drawfriend = drawfriend;
|
||||
updateFriendIcons();
|
||||
}
|
||||
}
|
||||
|
||||
updateFriendIcons()
|
||||
{
|
||||
// for all living players, show the appropriate headicon
|
||||
players = level._players;
|
||||
for(i = 0; i < players.size; i++)
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
|
||||
{
|
||||
if(level._drawfriend)
|
||||
{
|
||||
if(player.pers["team"] == "allies")
|
||||
{
|
||||
player.headicon = game["headicon_allies"];
|
||||
player.headiconteam = "allies";
|
||||
}
|
||||
else
|
||||
{
|
||||
player.headicon = game["headicon_axis"];
|
||||
player.headiconteam = "axis";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
players = level._players;
|
||||
for(i = 0; i < players.size; i++)
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
|
||||
player.headicon = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2782
maps/mp/gametypes/_gamelogic.gsc
Normal file
2782
maps/mp/gametypes/_gamelogic.gsc
Normal file
File diff suppressed because it is too large
Load Diff
2373
maps/mp/gametypes/_gameobjects.gsc
Normal file
2373
maps/mp/gametypes/_gameobjects.gsc
Normal file
File diff suppressed because it is too large
Load Diff
529
maps/mp/gametypes/_gamescore.gsc
Normal file
529
maps/mp/gametypes/_gamescore.gsc
Normal file
@ -0,0 +1,529 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
|
||||
|
||||
|
||||
getHighestScoringPlayer()
|
||||
{
|
||||
updatePlacement();
|
||||
|
||||
if ( !level._placement["all"].size )
|
||||
return ( undefined );
|
||||
else
|
||||
return ( level._placement["all"][0] );
|
||||
}
|
||||
|
||||
|
||||
getLosingPlayers()
|
||||
{
|
||||
updatePlacement();
|
||||
|
||||
players = level._placement["all"];
|
||||
losingPlayers = [];
|
||||
|
||||
foreach ( player in players )
|
||||
{
|
||||
if ( player == level._placement["all"][0] )
|
||||
continue;
|
||||
|
||||
losingPlayers[losingPlayers.size] = player;
|
||||
}
|
||||
|
||||
return losingPlayers;
|
||||
}
|
||||
|
||||
|
||||
givePlayerScore( event, player, victim, overrideCheckPlayerScoreLimitSoon )
|
||||
{
|
||||
if ( isDefined( level._nukeIncoming ) )
|
||||
return;
|
||||
|
||||
score = player.pers["score"];
|
||||
onPlayerScore( event, player, victim );
|
||||
|
||||
if ( score == player.pers["score"] )
|
||||
return;
|
||||
|
||||
if ( !player rankingEnabled() && !level._hardcoreMode )
|
||||
player thread maps\mp\gametypes\_rank::scorePopup( (player.pers["score"] - score), false, (0.85,0.85,0.85), 0 );
|
||||
|
||||
player maps\mp\gametypes\_persistence::statAdd( "score", (player.pers["score"] - score) );
|
||||
|
||||
if( getDvarInt( "prototype_adrenaline_enabled" ) == 1 )
|
||||
{
|
||||
player maps\mp\_adrenaline::adrenalineAddScore( (player.pers["score"] - score) );
|
||||
}
|
||||
|
||||
player.score = player.pers["score"];
|
||||
player maps\mp\gametypes\_persistence::statSetChild( "round", "score", player.score );
|
||||
|
||||
if ( !level._teambased )
|
||||
thread sendUpdatedDMScores();
|
||||
|
||||
// tagJC<NOTE>: In game mode where winning is not dependent on players' or team's score, it is unnecessary to check whether
|
||||
// the score limit will be reached soon.
|
||||
if ( !isDefined( overrideCheckPlayerScoreLimitSoon ) || !overrideCheckPlayerScoreLimitSoon )
|
||||
player maps\mp\gametypes\_gamelogic::checkPlayerScoreLimitSoon();
|
||||
|
||||
scoreEndedMatch = player maps\mp\gametypes\_gamelogic::checkScoreLimit();
|
||||
|
||||
if ( scoreEndedMatch && event == "kill" )
|
||||
player.finalKill = true;
|
||||
}
|
||||
|
||||
|
||||
onPlayerScore( event, player, victim )
|
||||
{
|
||||
score = maps\mp\gametypes\_rank::getScoreInfoValue( event );
|
||||
|
||||
assert( isDefined( score ) );
|
||||
|
||||
player.pers["score"] += score * level._objectivePointsMod;
|
||||
}
|
||||
|
||||
|
||||
// Seems to only be used for reducing a player's score due to suicide
|
||||
_setPlayerScore( player, score )
|
||||
{
|
||||
if ( score == player.pers["score"] )
|
||||
return;
|
||||
|
||||
player.pers["score"] = score;
|
||||
player.score = player.pers["score"];
|
||||
|
||||
player thread maps\mp\gametypes\_gamelogic::checkScoreLimit();
|
||||
}
|
||||
|
||||
|
||||
_getPlayerScore( player )
|
||||
{
|
||||
return player.pers["score"];
|
||||
}
|
||||
|
||||
|
||||
giveTeamScoreForObjective( team, score )
|
||||
{
|
||||
if ( isDefined( level._nukeIncoming ) )
|
||||
return;
|
||||
|
||||
score *= level._objectivePointsMod;
|
||||
|
||||
teamScore = game["teamScores"][team];
|
||||
|
||||
/*
|
||||
otherTeam = level._otherTeam[team];
|
||||
if ( game["teamScores"][team] > game["teamScores"][otherTeam] )
|
||||
level._wasWinning = team;
|
||||
else if ( game["teamScores"][otherTeam] > game["teamScores"][team] )
|
||||
level._wasWinning = otherTeam;
|
||||
*/
|
||||
|
||||
level._wasWinning = getWinningTeam();
|
||||
|
||||
_setTeamScore( team, _getTeamScore( team ) + score );
|
||||
|
||||
isWinning = getWinningTeam();
|
||||
/*
|
||||
isWinning = "none";
|
||||
if ( game["teamScores"][team] > game["teamScores"][otherTeam] )
|
||||
isWinning = team;
|
||||
else if ( game["teamScores"][otherTeam] > game["teamScores"][team] )
|
||||
isWinning = otherTeam;
|
||||
*/
|
||||
|
||||
if ( !level._splitScreen && isWinning != "none" && isWinning != level._wasWinning && getTime() - level._lastStatusTime > 5000 && getScoreLimit() != 1 )
|
||||
{
|
||||
level._lastStatusTime = getTime();
|
||||
leaderDialog( "lead_taken", isWinning, "status" );
|
||||
if ( level._wasWinning != "none")
|
||||
leaderDialog( "lead_lost", level._wasWinning, "status" );
|
||||
}
|
||||
|
||||
if ( isWinning != "none" )
|
||||
level._wasWinning = isWinning;
|
||||
}
|
||||
|
||||
|
||||
getWinningTeam()
|
||||
{
|
||||
//if( level._multiTeamBased == true )
|
||||
//{
|
||||
winning_team = level._teamNameList[0];
|
||||
winning_score = game["teamScores"][level._teamNameList[0]];
|
||||
num_teams_tied_for_winning = 1;
|
||||
for( i = 1; i < level._teamNameList.size; i++ )
|
||||
{
|
||||
if( game["teamScores"][level._teamNameList[i]] > winning_score )
|
||||
{
|
||||
//new winning team found
|
||||
winning_team = level._teamNameList[i];
|
||||
winning_score = game["teamScores"][level._teamNameList[i]];
|
||||
num_teams_tied_for_winning = 1;
|
||||
}
|
||||
else if( game["teamScores"][level._teamNameList[i]] == winning_score )
|
||||
{
|
||||
num_teams_tied_for_winning = num_teams_tied_for_winning + 1;
|
||||
winning_team = "none";
|
||||
}
|
||||
}
|
||||
return( winning_team );
|
||||
//}
|
||||
/*
|
||||
|
||||
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
|
||||
return ( "allies" );
|
||||
else if ( game["teamScores"]["allies"] < game["teamScores"]["axis"] )
|
||||
return ( "axis" );
|
||||
*/
|
||||
return ( "none" );
|
||||
}
|
||||
|
||||
_setTeamScore( team, teamScore )
|
||||
{
|
||||
if ( teamScore == game["teamScores"][team] )
|
||||
return;
|
||||
|
||||
if ( isDefined( level._nukeIncoming ) )
|
||||
return;
|
||||
|
||||
game["teamScores"][team] = teamScore;
|
||||
|
||||
updateTeamScore( team );
|
||||
|
||||
if ( game["status"] == "overtime" )
|
||||
thread [[level._onScoreLimit]]();
|
||||
else
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::checkTeamScoreLimitSoon( team );
|
||||
thread maps\mp\gametypes\_gamelogic::checkScoreLimit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateTeamScore( team )
|
||||
{
|
||||
assert( level._teamBased );
|
||||
|
||||
teamScore = 0;
|
||||
if ( !isRoundBased() || !isObjectiveBased() )
|
||||
teamScore = _getTeamScore( team );
|
||||
else
|
||||
teamScore = game["roundsWon"][team];
|
||||
|
||||
setTeamScore( team, teamScore );
|
||||
|
||||
//thread sendUpdatedTeamScores();
|
||||
}
|
||||
|
||||
|
||||
_getTeamScore( team )
|
||||
{
|
||||
return game["teamScores"][team];
|
||||
}
|
||||
|
||||
|
||||
sendUpdatedTeamScores()
|
||||
{
|
||||
level notify("updating_scores");
|
||||
level endon("updating_scores");
|
||||
wait .05;
|
||||
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
foreach ( player in level._players )
|
||||
player updateScores();
|
||||
}
|
||||
|
||||
sendUpdatedDMScores()
|
||||
{
|
||||
level notify("updating_dm_scores");
|
||||
level endon("updating_dm_scores");
|
||||
wait .05;
|
||||
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
for ( i = 0; i < level._players.size; i++ )
|
||||
{
|
||||
level._players[i] updateDMScores();
|
||||
level._players[i].updatedDMScores = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
removeDisconnectedPlayerFromPlacement()
|
||||
{
|
||||
offset = 0;
|
||||
numPlayers = level._placement["all"].size;
|
||||
found = false;
|
||||
for ( i = 0; i < numPlayers; i++ )
|
||||
{
|
||||
if ( level._placement["all"][i] == self )
|
||||
found = true;
|
||||
|
||||
if ( found )
|
||||
level._placement["all"][i] = level._placement["all"][ i + 1 ];
|
||||
}
|
||||
if ( !found )
|
||||
return;
|
||||
|
||||
level._placement["all"][ numPlayers - 1 ] = undefined;
|
||||
assert( level._placement["all"].size == numPlayers - 1 );
|
||||
|
||||
if( level._multiTeamBased )
|
||||
{
|
||||
MTDM_updateTeamPlacement();
|
||||
}
|
||||
else if ( level._teamBased )
|
||||
{
|
||||
updateTeamPlacement();
|
||||
return;
|
||||
}
|
||||
|
||||
numPlayers = level._placement["all"].size;
|
||||
for ( i = 0; i < numPlayers; i++ )
|
||||
{
|
||||
player = level._placement["all"][i];
|
||||
player notify( "update_outcome" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updatePlacement()
|
||||
{
|
||||
prof_begin("updatePlacement");
|
||||
|
||||
placementAll = [];
|
||||
foreach ( player in level._players )
|
||||
{
|
||||
if ( isDefined( player.connectedPostGame ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( player.pers["team"] == "spectator" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( player.pers["team"] == "none" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
placementAll[placementAll.size] = player;
|
||||
}
|
||||
|
||||
for ( i = 1; i < placementAll.size; i++ )
|
||||
{
|
||||
player = placementAll[i];
|
||||
playerScore = player.score;
|
||||
// for ( j = i - 1; j >= 0 && (player.score > placementAll[j].score || (player.score == placementAll[j].score && player.deaths < placementAll[j].deaths)); j-- )
|
||||
for ( j = i - 1; j >= 0 && getBetterPlayer( player, placementAll[j] ) == player; j-- )
|
||||
placementAll[j + 1] = placementAll[j];
|
||||
placementAll[j + 1] = player;
|
||||
}
|
||||
|
||||
level._placement["all"] = placementAll;
|
||||
|
||||
if( level._multiTeamBased )
|
||||
{
|
||||
MTDM_updateTeamPlacement();
|
||||
}
|
||||
else if ( level._teamBased )
|
||||
{
|
||||
updateTeamPlacement();
|
||||
}
|
||||
|
||||
prof_end("updatePlacement");
|
||||
}
|
||||
|
||||
|
||||
getBetterPlayer( playerA, playerB )
|
||||
{
|
||||
if ( playerA.score > playerB.score )
|
||||
return playerA;
|
||||
|
||||
if ( playerB.score > playerA.score )
|
||||
return playerB;
|
||||
|
||||
if ( playerA.deaths < playerB.deaths )
|
||||
return playerA;
|
||||
|
||||
if ( playerB.deaths < playerA.deaths )
|
||||
return playerB;
|
||||
|
||||
// TODO: more metrics for getting the better player
|
||||
|
||||
if ( cointoss() )
|
||||
return playerA;
|
||||
else
|
||||
return playerB;
|
||||
}
|
||||
|
||||
|
||||
updateTeamPlacement()
|
||||
{
|
||||
placement["allies"] = [];
|
||||
placement["axis"] = [];
|
||||
placement["spectator"] = [];
|
||||
|
||||
assert( level._teamBased );
|
||||
|
||||
placementAll = level._placement["all"];
|
||||
placementAllSize = placementAll.size;
|
||||
|
||||
for ( i = 0; i < placementAllSize; i++ )
|
||||
{
|
||||
player = placementAll[i];
|
||||
team = player.pers["team"];
|
||||
|
||||
placement[team][ placement[team].size ] = player;
|
||||
}
|
||||
|
||||
level._placement["allies"] = placement["allies"];
|
||||
level._placement["axis"] = placement["axis"];
|
||||
}
|
||||
|
||||
//TagZP<TODO> consolidate with updateTeamPlacement()
|
||||
MTDM_updateTeamPlacement()
|
||||
{
|
||||
placement["spectator"] = [];
|
||||
|
||||
foreach( teamname in level._teamNameList )
|
||||
{
|
||||
placement[teamname] = [];
|
||||
}
|
||||
|
||||
assert( level._multiTeamBased );
|
||||
|
||||
placementAll = level._placement["all"];
|
||||
placementAllSize = placementAll.size;
|
||||
|
||||
for ( i = 0; i < placementAllSize; i++ )
|
||||
{
|
||||
player = placementAll[i];
|
||||
team = player.pers["team"];
|
||||
|
||||
placement[team][ placement[team].size ] = player;
|
||||
}
|
||||
|
||||
foreach( teamname in level._teamNameList )
|
||||
{
|
||||
level._placement[teamname] = placement[teamname];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
initialDMScoreUpdate()
|
||||
{
|
||||
// the first time we call updateDMScores on a player, we have to send them the whole scoreboard.
|
||||
// by calling updateDMScores on each player one at a time,
|
||||
// we can avoid having to send the entire scoreboard to every single player
|
||||
// the first time someone kills someone else.
|
||||
wait .2;
|
||||
numSent = 0;
|
||||
while(1)
|
||||
{
|
||||
didAny = false;
|
||||
|
||||
players = level._players;
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if ( !isdefined( player ) )
|
||||
continue;
|
||||
|
||||
if ( isdefined( player.updatedDMScores ) )
|
||||
continue;
|
||||
|
||||
player.updatedDMScores = true;
|
||||
player updateDMScores();
|
||||
|
||||
didAny = true;
|
||||
wait .5;
|
||||
}
|
||||
|
||||
if ( !didAny )
|
||||
wait 3; // let more players connect
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
processAssist( killedplayer )
|
||||
{
|
||||
self endon("disconnect");
|
||||
killedplayer endon("disconnect");
|
||||
|
||||
wait .05; // don't ever run on the same frame as the playerkilled callback.
|
||||
WaitTillSlowProcessAllowed();
|
||||
if( !level._multiteambased )
|
||||
{
|
||||
if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( self.pers["team"] == killedplayer.pers["team"] )
|
||||
return;
|
||||
|
||||
damagedone = killedplayer.attackerData[self.guid].damage;
|
||||
|
||||
// If the attacker has conducted some damages using any grenades with lasting effect, the player should receive a minimum reward that is not porpotional to the damages done
|
||||
playerMaxHealth = getDvarInt ( "scr_player_maxhealth" );
|
||||
//Assuming there are four levels for assist rewards, divide player's max health by 4 to get the amount of damage per assist level
|
||||
damagePerAssistLevel = playerMaxHealth / 4;
|
||||
if ( isDefined ( killedplayer.attackerData[self.guid].isGrenadeWithLastingEffect ) && killedplayer.attackerData[self.guid].isGrenadeWithLastingEffect == true )
|
||||
{
|
||||
if ( damagedone <= 50 )
|
||||
{
|
||||
assist_event = "assist_grenade";
|
||||
}
|
||||
else
|
||||
{
|
||||
assist_event = "assist_level_" + int( ceil( damagedone / damagePerAssistLevel ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assist_event = "assist_level_" + int( ceil( damagedone / damagePerAssistLevel ) );
|
||||
}
|
||||
self thread [[level._onXPEvent]]( assist_event );
|
||||
self incPersStat( "assists", 1 );
|
||||
self.assists = self getPersStat( "assists" );
|
||||
self incPlayerStat( "assists", 1 );
|
||||
|
||||
givePlayerScore( assist_event, self, killedplayer );
|
||||
self thread giveAdrenaline( "assist" );
|
||||
|
||||
self thread maps\mp\gametypes\_missions::playerAssist();
|
||||
}
|
||||
|
||||
processShieldAssist( killedPlayer )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
killedPlayer endon( "disconnect" );
|
||||
|
||||
wait .05; // don't ever run on the same frame as the playerkilled callback.
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
|
||||
return;
|
||||
|
||||
if ( self.pers["team"] == killedplayer.pers["team"] )
|
||||
return;
|
||||
|
||||
self thread [[level._onXPEvent]]( "assist" );
|
||||
self thread [[level._onXPEvent]]( "assist" );
|
||||
self incPersStat( "assists", 1 );
|
||||
self.assists = self getPersStat( "assists" );
|
||||
self incPlayerStat( "assists", 1 );
|
||||
|
||||
givePlayerScore( "assist", self, killedplayer );
|
||||
|
||||
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "shield_assist" );
|
||||
|
||||
self thread maps\mp\gametypes\_missions::playerAssist();
|
||||
}
|
279
maps/mp/gametypes/_globallogic.gsc
Normal file
279
maps/mp/gametypes/_globallogic.gsc
Normal file
@ -0,0 +1,279 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level._splitscreen = isSplitScreen();
|
||||
level._ps3 = (getDvar( "ps3Game" ) == "true");
|
||||
level._xenon = (getDvar( "xenonGame" ) == "true");
|
||||
level._console = (level._ps3 || level._xenon);
|
||||
|
||||
level._onlineGame = getDvarInt( "onlinegame" );
|
||||
level._rankedMatch = ( !level._onlineGame || !getDvarInt( "xblive_privatematch" ) );
|
||||
|
||||
if ( !level._console )
|
||||
{
|
||||
if ( !getDvarInt( "sv_pure" ) )
|
||||
{
|
||||
oldvalue = level._rankedMatch;
|
||||
level._rankedMatch = false;
|
||||
/#
|
||||
level._rankedMatch = oldvalue;
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
/#
|
||||
if ( getdvarint( "scr_forcerankedmatch" ) == 1 )
|
||||
{
|
||||
level._onlineGame = true;
|
||||
level._rankedMatch = true;
|
||||
}
|
||||
#/
|
||||
|
||||
level._script = toLower( getDvar( "mapname" ) );
|
||||
level._gametype = toLower( getDvar( "g_gametype" ) );
|
||||
|
||||
//TagZP<NOTE>blocking this out in MTDM will force crashes/asserts where these are used. So nothing slips by.
|
||||
if( level._gametype != "mtdm" )
|
||||
{
|
||||
level._otherTeam["allies"] = "axis";
|
||||
level._otherTeam["axis"] = "allies";
|
||||
}
|
||||
|
||||
level._maxNumTeams = 2;
|
||||
|
||||
level._teamNameList = ["allies", "axis"];
|
||||
|
||||
level._teamBased = false;
|
||||
|
||||
level._multiTeamBased = false;
|
||||
|
||||
level._objectiveBased = false;
|
||||
|
||||
level._endGameOnTimeLimit = true;
|
||||
|
||||
level._showingFinalKillcam = false;
|
||||
|
||||
level._tiSpawnDelay = getDvarInt( "scr_tispawndelay" );
|
||||
|
||||
// hack to allow maps with no scripts to run correctly
|
||||
if ( !isDefined( level._tweakablesInitialized ) )
|
||||
maps\mp\gametypes\_tweakables::init();
|
||||
|
||||
precacheString( &"MP_HALFTIME" );
|
||||
precacheString( &"MP_OVERTIME" );
|
||||
precacheString( &"MP_ROUNDEND" );
|
||||
precacheString( &"MP_INTERMISSION" );
|
||||
precacheString( &"MP_SWITCHING_SIDES" );
|
||||
precacheString( &"MP_FRIENDLY_FIRE_WILL_NOT" );
|
||||
precacheString( &"PLATFORM_REVIVE" );
|
||||
|
||||
precacheString( &"MP_OBITUARY_NEUTRAL" );
|
||||
precacheString( &"MP_OBITUARY_FRIENDLY" );
|
||||
precacheString( &"MP_OBITUARY_ENEMY" );
|
||||
|
||||
if ( level._splitScreen )
|
||||
precacheString( &"MP_ENDED_GAME" );
|
||||
else
|
||||
precacheString( &"MP_HOST_ENDED_GAME" );
|
||||
|
||||
level._halftimeType = "halftime";
|
||||
level._halftimeSubCaption = &"MP_SWITCHING_SIDES";
|
||||
|
||||
level._lastStatusTime = 0;
|
||||
level._wasWinning = "none";
|
||||
|
||||
level._lastSlowProcessFrame = 0;
|
||||
|
||||
for( i = 0; i < level._teamNameList.size; i++ )
|
||||
{
|
||||
level._placement[level._teamNameList[i]] = [];
|
||||
}
|
||||
level._placement["all"] = [];
|
||||
|
||||
/*
|
||||
level._placement["allies"] = [];
|
||||
level._placement["axis"] = [];
|
||||
level._placement["all"] = [];
|
||||
*/
|
||||
|
||||
level._postRoundTime = 5.0;
|
||||
|
||||
level._playersLookingForSafeSpawn = [];
|
||||
|
||||
registerDvars();
|
||||
|
||||
precacheModel( "vehicle_mig29_desert" );
|
||||
precacheModel( "projectile_cbu97_clusterbomb" );
|
||||
precacheModel( "tag_origin" );
|
||||
|
||||
level._fx_airstrike_afterburner = loadfx ("fire/jet_afterburner");
|
||||
level._fx_airstrike_contrail = loadfx ("smoke/jet_contrail");
|
||||
|
||||
if ( level._console )
|
||||
precacheLeaderboards( "LB_KILLS LB_WINS LB_TOTALXP LB_ACCURACY" );
|
||||
|
||||
for( i = 0; i < level._teamNameList.size; i++ )
|
||||
{
|
||||
level._teamCount[level._teamNameList[i]] = 0;
|
||||
level._aliveCount[level._teamNameList[i]] = 0;
|
||||
level._livesCount[level._teamNameList[i]] = 0;
|
||||
level._hasSpawned[level._teamNameList[i]] = 0;
|
||||
}
|
||||
level._teamCount["spectator"] = 0;
|
||||
level._aliveCount["spectator"] = 0;
|
||||
|
||||
level._oneLeftTime = [];
|
||||
|
||||
/#
|
||||
if ( getdvarint( "scr_runlevelandquit" ) == 1 )
|
||||
{
|
||||
thread runLevelAndQuit();
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
|
||||
/#
|
||||
runLevelAndQuit()
|
||||
{
|
||||
wait 1;
|
||||
while ( level._players.size < 1 )
|
||||
{
|
||||
wait 0.5;
|
||||
}
|
||||
wait 0.5;
|
||||
level notify( "game_ended" );
|
||||
exitLevel();
|
||||
}
|
||||
#/
|
||||
|
||||
|
||||
registerDvars()
|
||||
{
|
||||
makeDvarServerInfo( "ui_bomb_timer", 0 );
|
||||
makeDvarServerInfo( "ui_danger_team", "" );
|
||||
}
|
||||
|
||||
SetupCallbacks()
|
||||
{
|
||||
level._onXPEvent = ::onXPEvent;
|
||||
|
||||
level._getSpawnPoint = ::blank;
|
||||
level._onSpawnPlayer = ::blank;
|
||||
level._onRespawnDelay = ::blank;
|
||||
|
||||
level._onTimeLimit = maps\mp\gametypes\_gamelogic::default_onTimeLimit;
|
||||
level._onScoreLimit = maps\mp\gametypes\_gamelogic::default_onScoreLimit;
|
||||
level._onHalfTime = maps\mp\gametypes\_gamelogic::default_onHalfTime;
|
||||
level._onDeadEvent = maps\mp\gametypes\_gamelogic::default_onDeadEvent;
|
||||
level._onOneLeftEvent = maps\mp\gametypes\_gamelogic::default_onOneLeftEvent;
|
||||
|
||||
level._onPrecacheGametype = ::blank;
|
||||
level._onStartGameType = ::blank;
|
||||
level._onPlayerKilled = ::blank;
|
||||
|
||||
level._autoassign = maps\mp\gametypes\_menus::menuAutoAssign;
|
||||
level._spectator = maps\mp\gametypes\_menus::menuSpectator;
|
||||
level._class = maps\mp\gametypes\_menus::menuClass;
|
||||
level._onTeamSelection = maps\mp\gametypes\_menus::onMenuTeamSelect;
|
||||
}
|
||||
|
||||
|
||||
|
||||
blank( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/#
|
||||
xpRateThread()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
gameFlagWait( "prematch_done" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( 5.0 );
|
||||
if ( level._players[0].pers["team"] == "allies" || level._players[0].pers["team"] == "axis" )
|
||||
self maps\mp\gametypes\_rank::giveRankXP( "kill", int(min( getDvarInt( "scr_xprate" ), 50 )) );
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
testMenu()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( 10.0 );
|
||||
|
||||
notifyData = spawnStruct();
|
||||
notifyData.titleText = &"MP_CHALLENGE_COMPLETED";
|
||||
notifyData.notifyText = "wheee";
|
||||
notifyData.sound = "mp_challenge_complete";
|
||||
|
||||
self thread maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
|
||||
}
|
||||
}
|
||||
|
||||
testShock()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( 3.0 );
|
||||
|
||||
numShots = randomInt( 6 );
|
||||
|
||||
for ( i = 0; i < numShots; i++ )
|
||||
{
|
||||
iPrintLnBold( numShots );
|
||||
self shellShock( "frag_grenade_mp", 0.2 );
|
||||
wait ( 0.1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onXPEvent( event )
|
||||
{
|
||||
//self thread maps\mp\_loot::giveMoney( event, 10 );
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( event );
|
||||
}
|
||||
|
||||
|
||||
|
||||
fakeLag()
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
self.fakeLag = randomIntRange( 50, 150 );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self setClientDvar( "fakelag_target", self.fakeLag );
|
||||
wait ( randomFloatRange( 5.0, 15.0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
debugLine( start, end )
|
||||
{
|
||||
for ( i = 0; i < 50; i++ )
|
||||
{
|
||||
line( start, end );
|
||||
wait .05;
|
||||
}
|
||||
}
|
235
maps/mp/gametypes/_healthoverlay.gsc
Normal file
235
maps/mp/gametypes/_healthoverlay.gsc
Normal file
@ -0,0 +1,235 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level._healthOverlayCutoff = 0.55;
|
||||
|
||||
regenTime = 5;
|
||||
regenTime = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "healthregentime" );
|
||||
|
||||
regenRatePercent = 10;
|
||||
regenRatePercent = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "healthregenratepercent" );
|
||||
|
||||
level._playerHealth_RegularRegenDelay = regenTime * 1000;
|
||||
level._playerHealth_RegenRate = 1.0 / regenRatePercent;
|
||||
|
||||
level._healthRegenDisabled = (level._playerHealth_RegularRegenDelay <= 0);
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player thread onPlayerSpawned();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
self.healthRegenDelay = level._playerHealth_RegularRegenDelay;
|
||||
self.healthRegenRate = level._playerHealth_RegenRate;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("spawned_player");
|
||||
self thread playerHealthRegen();
|
||||
|
||||
self thread showTempDamage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
showTempDamage()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
/#
|
||||
setDevDvar( "scr_damage_wait", 0 );
|
||||
setDevDvar( "scr_damage_fadein", 0.25 );
|
||||
setDevDvar( "scr_damage_fadeout", 0.5 );
|
||||
setDevDvar( "scr_damage_holdtime", 0.5 );
|
||||
setDevDvar( "scr_damage_numfades", 5 );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
while ( getDvarFloat( "scr_damage_wait" ) <= 0 )
|
||||
wait ( 1.0 );
|
||||
|
||||
wait ( getDvarFloat( "scr_damage_wait" ) );
|
||||
|
||||
for ( i = 0; i < getDvarInt( "scr_damage_numfades" ); i++ )
|
||||
{
|
||||
self VisionSetNakedForPlayer( "mp_crash_damage", getDvarFloat( "scr_damage_fadein" ) * (getDvarInt( "scr_damage_numfades" ) - i) );
|
||||
wait ( getDvarFloat( "scr_damage_fadein" ) + getDvarFloat( "scr_damage_holdtime" ) );
|
||||
self VisionSetNakedForPlayer( "mp_crash", getDvarFloat( "scr_damage_fadeout" ) * getDvarInt( "scr_damage_numfades" ) );
|
||||
wait ( getDvarFloat( "scr_damage_fadeout" ) );
|
||||
}
|
||||
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
playerHealthRegen()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
self endon ( "joined_team" );
|
||||
self endon ( "joined_spectators" );
|
||||
|
||||
if ( self.health <= 0 )
|
||||
{
|
||||
assert( !isalive( self ) );
|
||||
return;
|
||||
}
|
||||
|
||||
oldhealth = self.maxhealth;
|
||||
|
||||
regenRate = 0.1;
|
||||
veryHurt = false;
|
||||
|
||||
self.breathingStopTime = -10000;
|
||||
|
||||
thread playerBreathingSound( self.maxhealth * 0.35 );
|
||||
|
||||
lastSoundTime_Recover = 0;
|
||||
hurtTime = 0;
|
||||
newHealth = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wait ( 0.05 );
|
||||
if ( isDefined( level._hostMigrationTimer ) )
|
||||
{
|
||||
timePassed = maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
|
||||
|
||||
hurtTime += timePassed;
|
||||
lastSoundTime_Recover += timePassed;
|
||||
}
|
||||
|
||||
if ( self.health == self.maxhealth || ( level._dieHardMode && isDefined( self.healthClamped ) && self.health >= self.healthClamped ) ) // runs every frame
|
||||
{
|
||||
oldHealth = self.maxhealth;
|
||||
veryHurt = false;
|
||||
self.atBrinkOfDeath = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self.health <= 0 ) // player dead
|
||||
return;
|
||||
|
||||
curTime = getTime();
|
||||
|
||||
ratio = self.health / self.maxHealth;
|
||||
|
||||
if ( ratio <= level._healthOverlayCutoff )
|
||||
{
|
||||
if ( !veryHurt )
|
||||
hurtTime = curTime;
|
||||
|
||||
veryHurt = true;
|
||||
self.atBrinkOfDeath = true;
|
||||
}
|
||||
|
||||
if ( self.health >= oldhealth )
|
||||
{
|
||||
if ( curTime - hurtTime < self.healthRegenDelay )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if ( level._healthRegenDisabled )
|
||||
{
|
||||
wait ( 3.0 );
|
||||
self.maxHealth = int( max( self.health, 2 ) );
|
||||
self.health = self.maxHealth;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( curTime - lastSoundTime_Recover > self.healthRegenDelay )
|
||||
{
|
||||
lastSoundTime_Recover = curTime;
|
||||
if ( !level._gameEnded )
|
||||
self playLocalSound("breathing_better");
|
||||
}
|
||||
|
||||
if ( veryHurt )
|
||||
{
|
||||
newHealth = ratio;
|
||||
if ( curTime > hurtTime + 3000 )
|
||||
{
|
||||
newHealth += self.healthRegenRate;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newHealth = 1;
|
||||
}
|
||||
|
||||
if ( newHealth >= 1.0 )
|
||||
{
|
||||
if ( veryHurt )
|
||||
{
|
||||
self maps\mp\gametypes\_missions::healthRegenerated();
|
||||
}
|
||||
|
||||
self maps\mp\gametypes\_damage::resetAttackerList();
|
||||
newHealth = 1.0;
|
||||
}
|
||||
|
||||
if (newHealth <= 0)
|
||||
{
|
||||
// Player is dead
|
||||
return;
|
||||
}
|
||||
|
||||
self setNormalHealth (newHealth);
|
||||
oldHealth = self.health;
|
||||
continue;
|
||||
}
|
||||
|
||||
// first time damaged
|
||||
oldHealth = self.health;
|
||||
hurtTime = curTime;
|
||||
self.breathingStopTime = hurtTime + 6000;
|
||||
}
|
||||
}
|
||||
|
||||
playerBreathingSound( healthcap )
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
self endon ( "joined_team" );
|
||||
self endon ( "joined_spectators" );
|
||||
|
||||
wait ( 2 );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wait ( 0.2 );
|
||||
|
||||
if ( self.health <= 0 )
|
||||
return;
|
||||
|
||||
// Player still has a lot of health so no breathing sound
|
||||
if ( self.health >= healthcap )
|
||||
continue;
|
||||
|
||||
if ( level._healthRegenDisabled && gettime() > self.breathingStopTime )
|
||||
continue;
|
||||
|
||||
self playLocalSound( "breathing_hurt" );
|
||||
|
||||
wait ( .784 );
|
||||
wait ( 0.1 + randomfloat (0.8) );
|
||||
}
|
||||
}
|
167
maps/mp/gametypes/_hostmigration.gsc
Normal file
167
maps/mp/gametypes/_hostmigration.gsc
Normal file
@ -0,0 +1,167 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
Callback_HostMigration()
|
||||
{
|
||||
level._hostMigrationReturnedPlayerCount = 0;
|
||||
|
||||
if ( level._gameEnded )
|
||||
{
|
||||
println( "Migration starting at time " + gettime() + ", but game has ended, so no countdown." );
|
||||
return;
|
||||
}
|
||||
|
||||
println( "Migration starting at time " + gettime() );
|
||||
|
||||
level._hostMigrationTimer = true;
|
||||
|
||||
level notify( "host_migration_begin" );
|
||||
maps\mp\gametypes\_gamelogic::UpdateTimerPausedness();
|
||||
|
||||
foreach ( player in level._players )
|
||||
{
|
||||
player thread hostMigrationTimerThink();
|
||||
}
|
||||
|
||||
level endon( "host_migration_begin" );
|
||||
hostMigrationWait();
|
||||
|
||||
|
||||
level._hostMigrationTimer = undefined;
|
||||
println( "Migration finished at time " + gettime() );
|
||||
|
||||
level notify( "host_migration_end" );
|
||||
maps\mp\gametypes\_gamelogic::UpdateTimerPausedness();
|
||||
}
|
||||
|
||||
hostMigrationWait()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
level endon( "nuke_death" );
|
||||
|
||||
// start with a 20 second wait.
|
||||
// once we get enough players, or the first 15 seconds pass, switch to a 5 second timer.
|
||||
|
||||
thread maps\mp\gametypes\_gamelogic::matchStartTimerConsole( "waiting_for_players", 20.0 );
|
||||
hostMigrationWaitForPlayers();
|
||||
|
||||
thread maps\mp\gametypes\_gamelogic::matchStartTimerConsole( "match_resuming_in", 5.0 );
|
||||
wait 5;
|
||||
}
|
||||
|
||||
hostMigrationWaitForPlayers()
|
||||
{
|
||||
level endon( "hostmigration_enoughplayers" );
|
||||
wait 15;
|
||||
}
|
||||
|
||||
hostMigrationTimerThink_Internal()
|
||||
{
|
||||
level endon( "host_migration_begin" );
|
||||
level endon( "host_migration_end" );
|
||||
|
||||
self.hostMigrationControlsFrozen = false;
|
||||
|
||||
while ( !isReallyAlive( self ) )
|
||||
{
|
||||
self waittill( "spawned" );
|
||||
}
|
||||
|
||||
self.hostMigrationControlsFrozen = true;
|
||||
self freezeControlsWrapper( true );
|
||||
|
||||
level waittill( "host_migration_end" );
|
||||
}
|
||||
|
||||
hostMigrationTimerThink()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self setClientDvar( "cg_scoreboardPingGraph", "0" );
|
||||
|
||||
hostMigrationTimerThink_Internal();
|
||||
|
||||
if ( self.hostMigrationControlsFrozen )
|
||||
self freezeControlsWrapper( false );
|
||||
|
||||
self setClientDvar( "cg_scoreboardPingGraph", "1" );
|
||||
}
|
||||
|
||||
waitTillHostMigrationDone()
|
||||
{
|
||||
if ( !isDefined( level._hostMigrationTimer ) )
|
||||
return 0;
|
||||
|
||||
starttime = gettime();
|
||||
level waittill( "host_migration_end" );
|
||||
return gettime() - starttime;
|
||||
}
|
||||
|
||||
waitTillHostMigrationStarts( duration )
|
||||
{
|
||||
if ( isDefined( level._hostMigrationTimer ) )
|
||||
return;
|
||||
|
||||
level endon( "host_migration_begin" );
|
||||
wait duration;
|
||||
}
|
||||
|
||||
waitLongDurationWithHostMigrationPause( duration )
|
||||
{
|
||||
if ( duration == 0 )
|
||||
return;
|
||||
assert( duration > 0 );
|
||||
|
||||
starttime = gettime();
|
||||
|
||||
endtime = gettime() + duration * 1000;
|
||||
|
||||
while ( gettime() < endtime )
|
||||
{
|
||||
waitTillHostMigrationStarts( (endtime - gettime()) / 1000 );
|
||||
|
||||
if ( isDefined( level._hostMigrationTimer ) )
|
||||
{
|
||||
timePassed = waitTillHostMigrationDone();
|
||||
endtime += timePassed;
|
||||
}
|
||||
}
|
||||
|
||||
assert( gettime() == endtime );
|
||||
waitTillHostMigrationDone();
|
||||
|
||||
return gettime() - starttime;
|
||||
}
|
||||
|
||||
waitLongDurationWithGameEndTimeUpdate( duration )
|
||||
{
|
||||
if ( duration == 0 )
|
||||
return;
|
||||
assert( duration > 0 );
|
||||
|
||||
starttime = gettime();
|
||||
|
||||
endtime = gettime() + duration * 1000;
|
||||
|
||||
while ( gettime() < endtime )
|
||||
{
|
||||
waitTillHostMigrationStarts( (endtime - gettime()) / 1000 );
|
||||
|
||||
while ( isDefined( level._hostMigrationTimer ) )
|
||||
{
|
||||
endTime += 1000;
|
||||
setGameEndTime( int( endTime ) );
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
assert( gettime() == endtime );
|
||||
while ( isDefined( level._hostMigrationTimer ) )
|
||||
{
|
||||
endTime += 1000;
|
||||
setGameEndTime( int( endTime ) );
|
||||
wait 1;
|
||||
}
|
||||
|
||||
return gettime() - starttime;
|
||||
}
|
160
maps/mp/gametypes/_hud.gsc
Normal file
160
maps/mp/gametypes/_hud.gsc
Normal file
@ -0,0 +1,160 @@
|
||||
// Edge relative placement values for rect->h_align and rect->v_align
|
||||
#define HORIZONTAL_ALIGN_SUBLEFT 0 // left edge of a 4:3 screen (safe area not included)
|
||||
#define HORIZONTAL_ALIGN_LEFT 1 // left viewable (safe area) edge
|
||||
#define HORIZONTAL_ALIGN_CENTER 2 // center of the screen (reticle)
|
||||
#define HORIZONTAL_ALIGN_RIGHT 3 // right viewable (safe area) edge
|
||||
#define HORIZONTAL_ALIGN_FULLSCREEN 4 // disregards safe area
|
||||
#define HORIZONTAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
|
||||
#define HORIZONTAL_ALIGN_TO640 6 // scales a real-screen resolution x down into the 0 - 640 range
|
||||
#define HORIZONTAL_ALIGN_CENTER_SAFEAREA 7 // center of the safearea
|
||||
#define HORIZONTAL_ALIGN_MAX HORIZONTAL_ALIGN_CENTER_SAFEAREA
|
||||
#define HORIZONTAL_ALIGN_DEFAULT HORIZONTAL_ALIGN_SUBLEFT
|
||||
|
||||
#define VERTICAL_ALIGN_SUBTOP 0 // top edge of the 4:3 screen (safe area not included)
|
||||
#define VERTICAL_ALIGN_TOP 1 // top viewable (safe area) edge
|
||||
#define VERTICAL_ALIGN_CENTER 2 // center of the screen (reticle)
|
||||
#define VERTICAL_ALIGN_BOTTOM 3 // bottom viewable (safe area) edge
|
||||
#define VERTICAL_ALIGN_FULLSCREEN 4 // disregards safe area
|
||||
#define VERTICAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
|
||||
#define VERTICAL_ALIGN_TO480 6 // scales a real-screen resolution y down into the 0 - 480 range
|
||||
#define VERTICAL_ALIGN_CENTER_SAFEAREA 7 // center of the save area
|
||||
#define VERTICAL_ALIGN_MAX VERTICAL_ALIGN_CENTER_SAFEAREA
|
||||
#define VERTICAL_ALIGN_DEFAULT VERTICAL_ALIGN_SUBTOP
|
||||
|
||||
static const char *g_he_font[] =
|
||||
{
|
||||
"default", // HE_FONT_DEFAULT
|
||||
"bigfixed", // HE_FONT_BIGFIXED
|
||||
"smallfixed", // HE_FONT_SMALLFIXED
|
||||
"objective", // HE_FONT_OBJECTIVE
|
||||
};
|
||||
|
||||
|
||||
// These values correspond to the defines in q_shared.h
|
||||
static const char *g_he_alignx[] =
|
||||
{
|
||||
"left", // HE_ALIGN_LEFT
|
||||
"center", // HE_ALIGN_CENTER
|
||||
"right", // HE_ALIGN_RIGHT
|
||||
};
|
||||
|
||||
|
||||
static const char *g_he_aligny[] =
|
||||
{
|
||||
"top", // HE_ALIGN_TOP
|
||||
"middle", // HE_ALIGN_MIDDLE
|
||||
"bottom", // HE_ALIGN_BOTTOM
|
||||
};
|
||||
|
||||
|
||||
// These values correspond to the defines in menudefinition.h
|
||||
static const char *g_he_horzalign[] =
|
||||
{
|
||||
"subleft", // HORIZONTAL_ALIGN_SUBLEFT
|
||||
"left", // HORIZONTAL_ALIGN_LEFT
|
||||
"center", // HORIZONTAL_ALIGN_CENTER
|
||||
"right", // HORIZONTAL_ALIGN_RIGHT
|
||||
"fullscreen", // HORIZONTAL_ALIGN_FULLSCREEN
|
||||
"noscale", // HORIZONTAL_ALIGN_NOSCALE
|
||||
"alignto640", // HORIZONTAL_ALIGN_TO640
|
||||
"center_safearea", // HORIZONTAL_ALIGN_CENTER_SAFEAREA
|
||||
};
|
||||
cassert( ARRAY_COUNT( g_he_horzalign ) == HORIZONTAL_ALIGN_MAX + 1 );
|
||||
|
||||
|
||||
static const char *g_he_vertalign[] =
|
||||
{
|
||||
"subtop", // VERTICAL_ALIGN_SUBTOP
|
||||
"top", // VERTICAL_ALIGN_TOP
|
||||
"middle", // VERTICAL_ALIGN_CENTER
|
||||
"bottom", // VERTICAL_ALIGN_BOTTOM
|
||||
"fullscreen", // VERTICAL_ALIGN_FULLSCREEN
|
||||
"noscale", // VERTICAL_ALIGN_NOSCALE
|
||||
"alignto480", // VERTICAL_ALIGN_TO480
|
||||
"center_safearea", // VERTICAL_ALIGN_CENTER_SAFEAREA
|
||||
};
|
||||
cassert( ARRAY_COUNT( g_he_vertalign ) == VERTICAL_ALIGN_MAX + 1 );
|
||||
*/
|
||||
|
||||
init()
|
||||
{
|
||||
precacheShader( "progress_bar_bg" );
|
||||
precacheShader( "progress_bar_fg" );
|
||||
precacheShader( "progress_bar_fill" );
|
||||
|
||||
level._uiParent = spawnstruct();
|
||||
level._uiParent.horzAlign = "left";
|
||||
level._uiParent.vertAlign = "top";
|
||||
level._uiParent.alignX = "left";
|
||||
level._uiParent.alignY = "top";
|
||||
level._uiParent.x = 0;
|
||||
level._uiParent.y = 0;
|
||||
level._uiParent.width = 0;
|
||||
level._uiParent.height = 0;
|
||||
level._uiParent.children = [];
|
||||
|
||||
level._fontHeight = 12;
|
||||
|
||||
level._hud["allies"] = spawnstruct();
|
||||
level._hud["axis"] = spawnstruct();
|
||||
|
||||
// we can, of course, separate out the following constants for splitscreen.
|
||||
// primary progress bars are for things like capturing flags or planting bombs - big, important things that happen as you play a gametype
|
||||
level._primaryProgressBarY = -61; // from center
|
||||
level._primaryProgressBarX = 0;
|
||||
level._primaryProgressBarHeight = 9; //28; // this is the height and width of the whole progress bar, including the outline. the part that actually moves is 2 pixels smaller.
|
||||
level._primaryProgressBarWidth = 120;
|
||||
level._primaryProgressBarTextY = -75;
|
||||
level._primaryProgressBarTextX = 0;
|
||||
level._primaryProgressBarFontSize = .6; // 1.4 before font change from "objective"
|
||||
|
||||
level._teamProgressBarY = 32; // 205;
|
||||
level._teamProgressBarHeight = 14;
|
||||
level._teamProgressBarWidth = 192;
|
||||
level._teamProgressBarTextY = 8; // 155;
|
||||
level._teamProgressBarFontSize = 1.65;
|
||||
|
||||
if ( level._splitscreen )
|
||||
{
|
||||
level._lowerTextYAlign = "BOTTOM";
|
||||
level._lowerTextY = -76;
|
||||
level._lowerTextFontSize = 1.14;
|
||||
}
|
||||
else
|
||||
{
|
||||
level._lowerTextYAlign = "CENTER";
|
||||
level._lowerTextY = 70;
|
||||
level._lowerTextFontSize = 1.6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fontPulseInit( maxFontScale )
|
||||
{
|
||||
self.baseFontScale = self.fontScale;
|
||||
if ( isDefined( maxFontScale ) )
|
||||
self.maxFontScale = min( maxFontScale, 6.3 );
|
||||
else
|
||||
self.maxFontScale = min( self.fontScale * 2, 6.3 );
|
||||
self.inFrames = 2;
|
||||
self.outFrames = 4;
|
||||
}
|
||||
|
||||
|
||||
fontPulse(player)
|
||||
{
|
||||
self notify ( "fontPulse" );
|
||||
self endon ( "fontPulse" );
|
||||
self endon( "death" );
|
||||
|
||||
player endon("disconnect");
|
||||
player endon("joined_team");
|
||||
player endon("joined_spectators");
|
||||
|
||||
self ChangeFontScaleOverTime( self.inFrames * 0.05 );
|
||||
self.fontScale = self.maxFontScale;
|
||||
wait self.inFrames * 0.05;
|
||||
|
||||
self ChangeFontScaleOverTime( self.outFrames * 0.05 );
|
||||
self.fontScale = self.baseFontScale;
|
||||
}
|
1427
maps/mp/gametypes/_hud_message.gsc
Normal file
1427
maps/mp/gametypes/_hud_message.gsc
Normal file
File diff suppressed because it is too large
Load Diff
792
maps/mp/gametypes/_hud_util.gsc
Normal file
792
maps/mp/gametypes/_hud_util.gsc
Normal file
@ -0,0 +1,792 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
setParent( element )
|
||||
{
|
||||
if ( isDefined( self.parent ) && self.parent == element )
|
||||
return;
|
||||
|
||||
if ( isDefined( self.parent ) )
|
||||
self.parent removeChild( self );
|
||||
|
||||
self.parent = element;
|
||||
self.parent addChild( self );
|
||||
|
||||
if ( isDefined( self.point ) )
|
||||
self setPoint( self.point, self.relativePoint, self.xOffset, self.yOffset );
|
||||
else
|
||||
self setPoint( "TOPLEFT" );
|
||||
}
|
||||
|
||||
getParent()
|
||||
{
|
||||
return self.parent;
|
||||
}
|
||||
|
||||
addChild( element )
|
||||
{
|
||||
element.index = self.children.size;
|
||||
self.children[self.children.size] = element;
|
||||
}
|
||||
|
||||
removeChild( element )
|
||||
{
|
||||
element.parent = undefined;
|
||||
|
||||
if ( self.children[self.children.size-1] != element )
|
||||
{
|
||||
self.children[element.index] = self.children[self.children.size-1];
|
||||
self.children[element.index].index = element.index;
|
||||
}
|
||||
self.children[self.children.size-1] = undefined;
|
||||
|
||||
element.index = undefined;
|
||||
}
|
||||
|
||||
|
||||
setPoint( point, relativePoint, xOffset, yOffset, moveTime )
|
||||
{
|
||||
if ( !isDefined( moveTime ) )
|
||||
moveTime = 0;
|
||||
|
||||
element = self getParent();
|
||||
|
||||
if ( moveTime )
|
||||
self moveOverTime( moveTime );
|
||||
|
||||
if ( !isDefined( xOffset ) )
|
||||
xOffset = 0;
|
||||
self.xOffset = xOffset;
|
||||
|
||||
if ( !isDefined( yOffset ) )
|
||||
yOffset = 0;
|
||||
self.yOffset = yOffset;
|
||||
|
||||
self.point = point;
|
||||
|
||||
self.alignX = "center";
|
||||
self.alignY = "middle";
|
||||
|
||||
if ( isSubStr( point, "TOP" ) )
|
||||
self.alignY = "top";
|
||||
if ( isSubStr( point, "BOTTOM" ) )
|
||||
self.alignY = "bottom";
|
||||
if ( isSubStr( point, "LEFT" ) )
|
||||
self.alignX = "left";
|
||||
if ( isSubStr( point, "RIGHT" ) )
|
||||
self.alignX = "right";
|
||||
|
||||
if ( !isDefined( relativePoint ) )
|
||||
relativePoint = point;
|
||||
|
||||
self.relativePoint = relativePoint;
|
||||
|
||||
relativeX = "center_adjustable";
|
||||
relativeY = "middle";
|
||||
|
||||
if ( isSubStr( relativePoint, "TOP" ) )
|
||||
relativeY = "top_adjustable";
|
||||
if ( isSubStr( relativePoint, "BOTTOM" ) )
|
||||
relativeY = "bottom_adjustable";
|
||||
if ( isSubStr( relativePoint, "LEFT" ) )
|
||||
relativeX = "left_adjustable";
|
||||
if ( isSubStr( relativePoint, "RIGHT" ) )
|
||||
relativeX = "right_adjustable";
|
||||
|
||||
if ( element == level._uiParent )
|
||||
{
|
||||
self.horzAlign = relativeX;
|
||||
self.vertAlign = relativeY;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.horzAlign = element.horzAlign;
|
||||
self.vertAlign = element.vertAlign;
|
||||
}
|
||||
|
||||
|
||||
if ( strip_suffix( relativeX, "_adjustable" ) == element.alignX )
|
||||
{
|
||||
offsetX = 0;
|
||||
xFactor = 0;
|
||||
}
|
||||
else if ( relativeX == "center" || element.alignX == "center" )
|
||||
{
|
||||
offsetX = int(element.width / 2);
|
||||
if ( relativeX == "left_adjustable" || element.alignX == "right" )
|
||||
xFactor = -1;
|
||||
else
|
||||
xFactor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
offsetX = element.width;
|
||||
if ( relativeX == "left_adjustable" )
|
||||
xFactor = -1;
|
||||
else
|
||||
xFactor = 1;
|
||||
}
|
||||
self.x = element.x + (offsetX * xFactor);
|
||||
|
||||
if ( strip_suffix( relativeY, "_adjustable" ) == element.alignY )
|
||||
{
|
||||
offsetY = 0;
|
||||
yFactor = 0;
|
||||
}
|
||||
else if ( relativeY == "middle" || element.alignY == "middle" )
|
||||
{
|
||||
offsetY = int(element.height / 2);
|
||||
if ( relativeY == "top_adjustable" || element.alignY == "bottom" )
|
||||
yFactor = -1;
|
||||
else
|
||||
yFactor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
offsetY = element.height;
|
||||
if ( relativeY == "top_adjustable" )
|
||||
yFactor = -1;
|
||||
else
|
||||
yFactor = 1;
|
||||
}
|
||||
self.y = element.y + (offsetY * yFactor);
|
||||
|
||||
self.x += self.xOffset;
|
||||
self.y += self.yOffset;
|
||||
|
||||
switch ( self.elemType )
|
||||
{
|
||||
case "bar":
|
||||
setPointBar( point, relativePoint, xOffset, yOffset );
|
||||
break;
|
||||
}
|
||||
|
||||
self updateChildren();
|
||||
}
|
||||
|
||||
|
||||
setPointBar( point, relativePoint, xOffset, yOffset )
|
||||
{
|
||||
self.bar.horzAlign = self.horzAlign;
|
||||
self.bar.vertAlign = self.vertAlign;
|
||||
|
||||
self.bar.alignX = "left";
|
||||
self.bar.alignY = self.alignY;
|
||||
self.bar.y = self.y;
|
||||
|
||||
if ( self.alignX == "left" )
|
||||
self.bar.x = self.x;
|
||||
else if ( self.alignX == "right" )
|
||||
self.bar.x = self.x - self.width;
|
||||
else
|
||||
self.bar.x = self.x - int(self.width / 2);
|
||||
|
||||
if ( self.alignY == "top" )
|
||||
self.bar.y = self.y;
|
||||
else if ( self.alignY == "bottom" )
|
||||
self.bar.y = self.y;
|
||||
|
||||
self updateBar( self.bar.frac );
|
||||
}
|
||||
|
||||
|
||||
updateBar( barFrac, rateOfChange )
|
||||
{
|
||||
if ( self.elemType == "bar" )
|
||||
updateBarScale( barFrac, rateOfChange );
|
||||
}
|
||||
|
||||
|
||||
updateBarScale( barFrac, rateOfChange ) // rateOfChange is optional and is in "(entire bar lengths) per second"
|
||||
{
|
||||
barWidth = int(self.width * barFrac + 0.5); // (+ 0.5 rounds)
|
||||
|
||||
if ( !barWidth )
|
||||
barWidth = 1;
|
||||
|
||||
self.bar.frac = barFrac;
|
||||
self.bar setShader( self.bar.shader, barWidth, self.height );
|
||||
|
||||
assertEx( barWidth <= self.width, "barWidth <= self.width: " + barWidth + " <= " + self.width + " - barFrac was " + barFrac );
|
||||
|
||||
//if barWidth is bigger than self.width then we are drawing more than 100%
|
||||
if ( isDefined( rateOfChange ) && barWidth < self.width )
|
||||
{
|
||||
if ( rateOfChange > 0 )
|
||||
{
|
||||
//printLn( "scaling from: " + barWidth + " to " + self.width + " at " + ((1 - barFrac) / rateOfChange) );
|
||||
assertex( ((1 - barFrac) / rateOfChange) > 0, "barFrac: " + barFrac + "rateOfChange: " + rateOfChange );
|
||||
self.bar scaleOverTime( (1 - barFrac) / rateOfChange, self.width, self.height );
|
||||
}
|
||||
else if ( rateOfChange < 0 )
|
||||
{
|
||||
//printLn( "scaling from: " + barWidth + " to " + 0 + " at " + (barFrac / (-1 * rateOfChange)) );
|
||||
assertex( (barFrac / (-1 * rateOfChange)) > 0, "barFrac: " + barFrac + "rateOfChange: " + rateOfChange );
|
||||
self.bar scaleOverTime( barFrac / (-1 * rateOfChange), 1, self.height );
|
||||
}
|
||||
}
|
||||
self.bar.rateOfChange = rateOfChange;
|
||||
self.bar.lastUpdateTime = getTime();
|
||||
}
|
||||
|
||||
|
||||
createFontString( font, fontScale )
|
||||
{
|
||||
fontElem = newClientHudElem( self );
|
||||
fontElem.elemType = "font";
|
||||
fontElem.font = font;
|
||||
fontElem.fontscale = fontScale;
|
||||
fontElem.baseFontScale = fontScale;
|
||||
fontElem.x = 0;
|
||||
fontElem.y = 0;
|
||||
fontElem.width = 0;
|
||||
fontElem.height = int(level._fontHeight * fontScale);
|
||||
fontElem.xOffset = 0;
|
||||
fontElem.yOffset = 0;
|
||||
fontElem.children = [];
|
||||
fontElem setParent( level._uiParent );
|
||||
fontElem.hidden = false;
|
||||
return fontElem;
|
||||
}
|
||||
|
||||
|
||||
createServerFontString( font, fontScale, team )
|
||||
{
|
||||
if ( isDefined( team ) )
|
||||
fontElem = newTeamHudElem( team );
|
||||
else
|
||||
fontElem = newHudElem();
|
||||
|
||||
fontElem.elemType = "font";
|
||||
fontElem.font = font;
|
||||
fontElem.fontscale = fontScale;
|
||||
fontElem.baseFontScale = fontScale;
|
||||
fontElem.x = 0;
|
||||
fontElem.y = 0;
|
||||
fontElem.width = 0;
|
||||
fontElem.height = int(level._fontHeight * fontScale);
|
||||
fontElem.xOffset = 0;
|
||||
fontElem.yOffset = 0;
|
||||
fontElem.children = [];
|
||||
fontElem setParent( level._uiParent );
|
||||
fontElem.hidden = false;
|
||||
|
||||
return fontElem;
|
||||
}
|
||||
|
||||
createServerTimer( font, fontScale, team )
|
||||
{
|
||||
if ( isDefined( team ) )
|
||||
timerElem = newTeamHudElem( team );
|
||||
else
|
||||
timerElem = newHudElem();
|
||||
timerElem.elemType = "timer";
|
||||
timerElem.font = font;
|
||||
timerElem.fontScale = fontScale;
|
||||
timerElem.baseFontScale = fontScale;
|
||||
timerElem.x = 0;
|
||||
timerElem.y = 0;
|
||||
timerElem.width = 0;
|
||||
timerElem.height = int(level._fontHeight * fontScale);
|
||||
timerElem.xOffset = 0;
|
||||
timerElem.yOffset = 0;
|
||||
timerElem.children = [];
|
||||
timerElem setParent( level._uiParent );
|
||||
timerElem.hidden = false;
|
||||
|
||||
return timerElem;
|
||||
}
|
||||
|
||||
|
||||
createTimer( font, fontScale )
|
||||
{
|
||||
timerElem = newClientHudElem( self );
|
||||
timerElem.elemType = "timer";
|
||||
timerElem.font = font;
|
||||
timerElem.fontScale = fontScale;
|
||||
timerElem.baseFontScale = fontScale;
|
||||
timerElem.x = 0;
|
||||
timerElem.y = 0;
|
||||
timerElem.width = 0;
|
||||
timerElem.height = int(level._fontHeight * fontScale);
|
||||
timerElem.xOffset = 0;
|
||||
timerElem.yOffset = 0;
|
||||
timerElem.children = [];
|
||||
timerElem setParent( level._uiParent );
|
||||
timerElem.hidden = false;
|
||||
|
||||
return timerElem;
|
||||
}
|
||||
|
||||
|
||||
createIcon( shader, width, height )
|
||||
{
|
||||
iconElem = newClientHudElem( self );
|
||||
iconElem.elemType = "icon";
|
||||
iconElem.x = 0;
|
||||
iconElem.y = 0;
|
||||
iconElem.width = width;
|
||||
iconElem.height = height;
|
||||
iconElem.baseWidth = iconElem.width;
|
||||
iconElem.baseHeight = iconElem.height;
|
||||
iconElem.xOffset = 0;
|
||||
iconElem.yOffset = 0;
|
||||
iconElem.children = [];
|
||||
iconElem setParent( level._uiParent );
|
||||
iconElem.hidden = false;
|
||||
|
||||
if ( isDefined( shader ) )
|
||||
{
|
||||
iconElem setShader( shader, width, height );
|
||||
iconElem.shader = shader;
|
||||
}
|
||||
|
||||
return iconElem;
|
||||
}
|
||||
|
||||
|
||||
createServerIcon( shader, width, height, team )
|
||||
{
|
||||
if ( isDefined( team ) )
|
||||
iconElem = newTeamHudElem( team );
|
||||
else
|
||||
iconElem = newHudElem();
|
||||
iconElem.elemType = "icon";
|
||||
iconElem.x = 0;
|
||||
iconElem.y = 0;
|
||||
iconElem.width = width;
|
||||
iconElem.height = height;
|
||||
iconElem.baseWidth = iconElem.width;
|
||||
iconElem.baseHeight = iconElem.height;
|
||||
iconElem.xOffset = 0;
|
||||
iconElem.yOffset = 0;
|
||||
iconElem.children = [];
|
||||
iconElem setParent( level._uiParent );
|
||||
iconElem.hidden = false;
|
||||
|
||||
if ( isDefined( shader ) )
|
||||
{
|
||||
iconElem setShader( shader, width, height );
|
||||
iconElem.shader = shader;
|
||||
}
|
||||
|
||||
return iconElem;
|
||||
}
|
||||
|
||||
|
||||
createServerBar( color, width, height, flashFrac, team, selected )
|
||||
{
|
||||
if ( isDefined( team ) )
|
||||
barElem = newTeamHudElem( team );
|
||||
else
|
||||
barElem = newHudElem();
|
||||
barElem.x = 0;
|
||||
barElem.y = 0;
|
||||
barElem.frac = 0;
|
||||
barElem.color = color;
|
||||
barElem.sort = -2;
|
||||
barElem.shader = "progress_bar_fill";
|
||||
barElem setShader( "progress_bar_fill", width, height );
|
||||
barElem.hidden = false;
|
||||
if ( isDefined( flashFrac ) )
|
||||
{
|
||||
barElem.flashFrac = flashFrac;
|
||||
// barElem thread flashThread();
|
||||
}
|
||||
|
||||
if ( isDefined( team ) )
|
||||
barElemBG = newTeamHudElem( team );
|
||||
else
|
||||
barElemBG = newHudElem();
|
||||
barElemBG.elemType = "bar";
|
||||
barElemBG.x = 0;
|
||||
barElemBG.y = 0;
|
||||
barElemBG.width = width;
|
||||
barElemBG.height = height;
|
||||
barElemBG.xOffset = 0;
|
||||
barElemBG.yOffset = 0;
|
||||
barElemBG.bar = barElem;
|
||||
barElemBG.children = [];
|
||||
barElemBG.sort = -3;
|
||||
barElemBG.color = (0,0,0);
|
||||
barElemBG.alpha = 0.5;
|
||||
barElemBG setParent( level._uiParent );
|
||||
barElemBG setShader( "progress_bar_bg", width, height );
|
||||
barElemBG.hidden = false;
|
||||
|
||||
return barElemBG;
|
||||
}
|
||||
|
||||
createBar( color, width, height, flashFrac )
|
||||
{
|
||||
barElem = newClientHudElem( self );
|
||||
barElem.x = 0 ;
|
||||
barElem.y = 0;
|
||||
barElem.frac = 0;
|
||||
barElem.color = color;
|
||||
barElem.sort = -2;
|
||||
barElem.shader = "progress_bar_fill";
|
||||
barElem setShader( "progress_bar_fill", width, height );
|
||||
barElem.hidden = false;
|
||||
if ( isDefined( flashFrac ) )
|
||||
{
|
||||
barElem.flashFrac = flashFrac;
|
||||
// barElem thread flashThread();
|
||||
}
|
||||
|
||||
barElemBG = newClientHudElem( self );
|
||||
barElemBG.elemType = "bar";
|
||||
barElemBG.width = width;
|
||||
barElemBG.height = height;
|
||||
barElemBG.xOffset = 0;
|
||||
barElemBG.yOffset = 0;
|
||||
barElemBG.bar = barElem;
|
||||
barElemBG.children = [];
|
||||
barElemBG.sort = -3;
|
||||
barElemBG.color = (0,0,0);
|
||||
barElemBG.alpha = 0.5;
|
||||
barElemBG setParent( level._uiParent );
|
||||
barElemBG setShader( "progress_bar_bg", width + 4, height + 4 );
|
||||
barElemBG.hidden = false;
|
||||
|
||||
return barElemBG;
|
||||
}
|
||||
|
||||
getCurrentFraction()
|
||||
{
|
||||
frac = self.bar.frac;
|
||||
if (isdefined(self.bar.rateOfChange))
|
||||
{
|
||||
frac += (getTime() - self.bar.lastUpdateTime) * self.bar.rateOfChange;
|
||||
if (frac > 1) frac = 1;
|
||||
if (frac < 0) frac = 0;
|
||||
}
|
||||
return frac;
|
||||
}
|
||||
|
||||
createPrimaryProgressBar( yOffset )
|
||||
{
|
||||
if ( !isDefined( yOffset ) )
|
||||
yOffset = 0;
|
||||
|
||||
bar = createBar( (1, 1, 1), level._primaryProgressBarWidth, level._primaryProgressBarHeight );
|
||||
bar setPoint("CENTER", undefined, level._primaryProgressBarX, level._primaryProgressBarY - yOffset );
|
||||
|
||||
return bar;
|
||||
}
|
||||
createPrimaryProgressBarText( yOffset )
|
||||
{
|
||||
if ( !isDefined( yOffset ) )
|
||||
yOffset = 0;
|
||||
|
||||
text = createFontString( "hudbig", level._primaryProgressBarFontSize );
|
||||
text setPoint("CENTER", undefined, level._primaryProgressBarTextX, level._primaryProgressBarTextY - yOffset );
|
||||
text.sort = -1;
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
createTeamProgressBar( team )
|
||||
{
|
||||
bar = createServerBar( (1,0,0), level._teamProgressBarWidth, level._teamProgressBarHeight, undefined, team );
|
||||
bar setPoint("TOP", undefined, 0, level._teamProgressBarY);
|
||||
return bar;
|
||||
}
|
||||
createTeamProgressBarText( team )
|
||||
{
|
||||
text = createServerFontString( "default", level._teamProgressBarFontSize, team );
|
||||
text setPoint("TOP", undefined, 0, level._teamProgressBarTextY);
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
setFlashFrac( flashFrac )
|
||||
{
|
||||
self.bar.flashFrac = flashFrac;
|
||||
}
|
||||
|
||||
hideElem()
|
||||
{
|
||||
if ( self.hidden )
|
||||
return;
|
||||
|
||||
self.hidden = true;
|
||||
|
||||
if ( self.alpha != 0 )
|
||||
self.alpha = 0;
|
||||
|
||||
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
|
||||
{
|
||||
self.bar.hidden = true;
|
||||
if ( self.bar.alpha != 0 )
|
||||
self.bar.alpha = 0;
|
||||
}
|
||||
}
|
||||
|
||||
showElem()
|
||||
{
|
||||
if ( !self.hidden )
|
||||
return;
|
||||
|
||||
self.hidden = false;
|
||||
|
||||
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
|
||||
{
|
||||
if ( self.alpha != .5 )
|
||||
self.alpha = .5;
|
||||
|
||||
self.bar.hidden = false;
|
||||
if ( self.bar.alpha != 1 )
|
||||
self.bar.alpha = 1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self.alpha != 1 )
|
||||
self.alpha = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
flashThread()
|
||||
{
|
||||
self endon ( "death" );
|
||||
|
||||
if ( !self.hidden )
|
||||
self.alpha = 1;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if ( self.frac >= self.flashFrac )
|
||||
{
|
||||
if ( !self.hidden )
|
||||
{
|
||||
self fadeOverTime(0.3);
|
||||
self.alpha = .2;
|
||||
wait(0.35);
|
||||
self fadeOverTime(0.3);
|
||||
self.alpha = 1;
|
||||
}
|
||||
wait(0.7);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !self.hidden && self.alpha != 1 )
|
||||
self.alpha = 1;
|
||||
|
||||
wait ( 0.05 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
destroyElem()
|
||||
{
|
||||
tempChildren = [];
|
||||
|
||||
for ( index = 0; index < self.children.size; index++ )
|
||||
{
|
||||
if ( isDefined( self.children[index] ) )
|
||||
tempChildren[tempChildren.size] = self.children[index];
|
||||
}
|
||||
|
||||
for ( index = 0; index < tempChildren.size; index++ )
|
||||
tempChildren[index] setParent( self getParent() );
|
||||
|
||||
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
|
||||
{
|
||||
self.bar destroy();
|
||||
}
|
||||
|
||||
self destroy();
|
||||
}
|
||||
|
||||
setIconShader( shader )
|
||||
{
|
||||
self setShader( shader );
|
||||
self.shader = shader;
|
||||
}
|
||||
|
||||
|
||||
getIconShader( shader )
|
||||
{
|
||||
return self.shader;
|
||||
}
|
||||
|
||||
|
||||
setIconSize( width, height )
|
||||
{
|
||||
assert( isDefined( self.shader ) );
|
||||
|
||||
self setShader( self.shader, width, height );
|
||||
}
|
||||
|
||||
|
||||
setWidth( width )
|
||||
{
|
||||
self.width = width;
|
||||
}
|
||||
|
||||
|
||||
setHeight( height )
|
||||
{
|
||||
self.height = height;
|
||||
}
|
||||
|
||||
setSize( width, height )
|
||||
{
|
||||
self.width = width;
|
||||
self.height = height;
|
||||
}
|
||||
|
||||
updateChildren()
|
||||
{
|
||||
for ( index = 0; index < self.children.size; index++ )
|
||||
{
|
||||
child = self.children[index];
|
||||
child setPoint( child.point, child.relativePoint, child.xOffset, child.yOffset );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
transitionReset()
|
||||
{
|
||||
self.x = self.xOffset;
|
||||
self.y = self.yOffset;
|
||||
if ( self.elemType == "font" )
|
||||
{
|
||||
self.fontScale = self.baseFontScale;
|
||||
self.label = &"";
|
||||
}
|
||||
else if ( self.elemType == "icon" )
|
||||
{
|
||||
//self scaleOverTime( 0.001, self.width, self.height );
|
||||
self setShader( self.shader, self.width, self.height );
|
||||
}
|
||||
self.alpha = 0;
|
||||
}
|
||||
|
||||
|
||||
transitionZoomIn( duration )
|
||||
{
|
||||
switch ( self.elemType )
|
||||
{
|
||||
case "font":
|
||||
case "timer":
|
||||
self.fontScale = 6.3;
|
||||
self changeFontScaleOverTime( duration );
|
||||
self.fontScale = self.baseFontScale;
|
||||
break;
|
||||
case "icon":
|
||||
self setShader( self.shader, self.width * 6, self.height * 6 );
|
||||
self scaleOverTime( duration, self.width, self.height );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transitionPulseFXIn( inTime, duration )
|
||||
{
|
||||
transTime = int(inTime)*1000;
|
||||
showTime = int(duration)*1000;
|
||||
|
||||
switch ( self.elemType )
|
||||
{
|
||||
case "font":
|
||||
case "timer":
|
||||
self setPulseFX( transTime+250, showTime+transTime, transTime+250 );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transitionSlideIn( duration, direction )
|
||||
{
|
||||
if ( !isDefined( direction ) )
|
||||
direction = "left";
|
||||
|
||||
switch ( direction )
|
||||
{
|
||||
case "left":
|
||||
self.x += 1000;
|
||||
break;
|
||||
case "right":
|
||||
self.x -= 1000;
|
||||
break;
|
||||
case "up":
|
||||
self.y -= 1000;
|
||||
break;
|
||||
case "down":
|
||||
self.y += 1000;
|
||||
break;
|
||||
}
|
||||
self moveOverTime( duration );
|
||||
self.x = self.xOffset;
|
||||
self.y = self.yOffset;
|
||||
}
|
||||
|
||||
|
||||
transitionSlideOut( duration, direction )
|
||||
{
|
||||
if ( !isDefined( direction ) )
|
||||
direction = "left";
|
||||
|
||||
gotoX = self.xOffset;
|
||||
gotoY = self.yOffset;
|
||||
|
||||
switch ( direction )
|
||||
{
|
||||
case "left":
|
||||
gotoX += 1000;
|
||||
break;
|
||||
case "right":
|
||||
gotoX -= 1000;
|
||||
break;
|
||||
case "up":
|
||||
gotoY -= 1000;
|
||||
break;
|
||||
case "down":
|
||||
gotoY += 1000;
|
||||
break;
|
||||
}
|
||||
|
||||
self.alpha = 1;
|
||||
|
||||
self moveOverTime( duration );
|
||||
self.x = gotoX;
|
||||
self.y = gotoY;
|
||||
}
|
||||
|
||||
|
||||
transitionZoomOut( duration )
|
||||
{
|
||||
switch ( self.elemType )
|
||||
{
|
||||
case "font":
|
||||
case "timer":
|
||||
self changeFontScaleOverTime( duration );
|
||||
self.fontScale = 6.3;
|
||||
case "icon":
|
||||
self scaleOverTime( duration, self.width * 6, self.height * 6 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transitionFadeIn( duration )
|
||||
{
|
||||
self fadeOverTime( duration );
|
||||
if ( isDefined( self.maxAlpha ) )
|
||||
self.alpha = self.maxAlpha;
|
||||
else
|
||||
self.alpha = 1;
|
||||
}
|
||||
|
||||
|
||||
transitionFadeOut( duration )
|
||||
{
|
||||
self fadeOverTime( 0.15 );
|
||||
self.alpha = 0;
|
||||
}
|
691
maps/mp/gametypes/_killcam.gsc
Normal file
691
maps/mp/gametypes/_killcam.gsc
Normal file
@ -0,0 +1,691 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
init()
|
||||
{
|
||||
precacheString(&"PLATFORM_PRESS_TO_SKIP");
|
||||
precacheString(&"PLATFORM_PRESS_TO_RESPAWN");
|
||||
precacheString(&"PLATFORM_PRESS_TO_COPYCAT");
|
||||
precacheShader("specialty_copycat");
|
||||
|
||||
level._killcam = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "allowkillcam" );
|
||||
}
|
||||
|
||||
killcam(
|
||||
attackerNum, // entity number of the attacker
|
||||
killcamentityindex, // entity number of the entity to view (grenade, airstrike, etc)
|
||||
killcamentitystarttime, // time at which the killcamentity came into being
|
||||
sWeapon, // killing weapon
|
||||
predelay, // time between player death and beginning of killcam
|
||||
offsetTime, // something to do with how far back in time the killer was seeing the world when he made the kill; latency related, sorta
|
||||
timeUntilRespawn, // will the player be allowed to respawn after the killcam?
|
||||
maxtime, // time remaining until map ends; the killcam will never last longer than this. undefined = no limit
|
||||
attacker, // entity object of attacker
|
||||
victim // entity object of the victim
|
||||
)
|
||||
{
|
||||
// monitors killcam and hides HUD elements during killcam session
|
||||
//if ( !level.splitscreen )
|
||||
// self thread killcam_HUD_off();
|
||||
|
||||
self endon("disconnect");
|
||||
self endon("spawned");
|
||||
level endon("game_ended");
|
||||
|
||||
if ( attackerNum < 0 )
|
||||
return;
|
||||
|
||||
// length from killcam start to killcam end
|
||||
if (getdvar("scr_killcam_time") == "")
|
||||
{
|
||||
if ( sWeapon == "artillery_mp" || sWeapon == "stealth_bomb_mp" )
|
||||
camtime = (gettime() - killcamentitystarttime) / 1000 - predelay - .1;
|
||||
else if ( level._showingFinalKillcam )
|
||||
camtime = 4.0;
|
||||
else if ( sWeapon == "javelin_mp" )
|
||||
camtime = 8;
|
||||
else if ( issubstr( sWeapon, "remotemissile_" ) )
|
||||
camtime = 5;
|
||||
else if ( !timeUntilRespawn || timeUntilRespawn > 5.0 ) // if we're not going to respawn, we can take more time to watch what happened
|
||||
camtime = 5.0;
|
||||
else if ( sWeapon == "frag_grenade_mp" || sWeapon == "frag_grenade_short_mp" || sWeapon == "semtex_mp" )
|
||||
camtime = 4.25; // show long enough to see grenade thrown
|
||||
else
|
||||
camtime = 2.5;
|
||||
}
|
||||
else
|
||||
camtime = getdvarfloat("scr_killcam_time");
|
||||
|
||||
if (isdefined(maxtime)) {
|
||||
if (camtime > maxtime)
|
||||
camtime = maxtime;
|
||||
if (camtime < .05)
|
||||
camtime = .05;
|
||||
}
|
||||
|
||||
// time after player death that killcam continues for
|
||||
if (getdvar("scr_killcam_posttime") == "")
|
||||
postdelay = 2;
|
||||
else {
|
||||
postdelay = getdvarfloat("scr_killcam_posttime");
|
||||
if (postdelay < 0.05)
|
||||
postdelay = 0.05;
|
||||
}
|
||||
|
||||
/* timeline:
|
||||
|
||||
| camtime | postdelay |
|
||||
| | predelay |
|
||||
|
||||
^ killcam start ^ player death ^ killcam end
|
||||
^ player starts watching killcam
|
||||
|
||||
*/
|
||||
|
||||
killcamlength = camtime + postdelay;
|
||||
|
||||
// don't let the killcam last past the end of the round.
|
||||
if (isdefined(maxtime) && killcamlength > maxtime)
|
||||
{
|
||||
// first trim postdelay down to a minimum of 1 second.
|
||||
// if that doesn't make it short enough, trim camtime down to a minimum of 1 second.
|
||||
// if that's still not short enough, cancel the killcam.
|
||||
if ( maxtime < 2 )
|
||||
return;
|
||||
|
||||
if (maxtime - camtime >= 1) {
|
||||
// reduce postdelay so killcam ends at end of match
|
||||
postdelay = maxtime - camtime;
|
||||
}
|
||||
else {
|
||||
// distribute remaining time over postdelay and camtime
|
||||
postdelay = 1;
|
||||
camtime = maxtime - 1;
|
||||
}
|
||||
|
||||
// recalc killcamlength
|
||||
killcamlength = camtime + postdelay;
|
||||
}
|
||||
|
||||
killcamoffset = camtime + predelay;
|
||||
|
||||
startTime = getTime();
|
||||
self notify ( "begin_killcam", startTime );
|
||||
|
||||
if ( getDvarInt( "upgradeEnabling" ) == 1 )
|
||||
{
|
||||
// To specifically wait for the button presses for Y or B
|
||||
self thread maps\mp\_upgrade::waitForYButtonPress();
|
||||
self thread maps\mp\_upgrade::waitForBButtonPress();
|
||||
}
|
||||
|
||||
self.sessionstate = "spectator";
|
||||
self.forcespectatorclient = attackerNum;
|
||||
self.killcamentity = -1;
|
||||
if ( killcamentityindex >= 0 )
|
||||
self thread setKillCamEntity( killcamentityindex, killcamoffset, killcamentitystarttime );
|
||||
self.archivetime = killcamoffset;
|
||||
self.killcamlength = killcamlength;
|
||||
self.psoffsettime = offsetTime;
|
||||
|
||||
// ignore spectate permissions
|
||||
self allowSpectateTeam("allies", true);
|
||||
self allowSpectateTeam("axis", true);
|
||||
self allowSpectateTeam("freelook", true);
|
||||
self allowSpectateTeam("none", true);
|
||||
if( level._multiTeamBased )
|
||||
{
|
||||
foreach( teamname in level._teamNameList )
|
||||
{
|
||||
self allowSpectateTeam( teamname, true );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isDefined( attacker ) && level._showingFinalKillcam ) // attacker may have disconnected
|
||||
{
|
||||
self openMenu( "killedby_card_display" );
|
||||
self SetCardDisplaySlot( attacker, 7 );
|
||||
}
|
||||
|
||||
self thread endedKillcamCleanup();
|
||||
|
||||
// wait till the next server frame to allow code a chance to update archivetime if it needs trimming
|
||||
wait 0.05;
|
||||
|
||||
assertex( self.archivetime <= killcamoffset + 0.0001, "archivetime: " + self.archivetime + ", killcamoffset: " + killcamoffset );
|
||||
if ( self.archivetime < killcamoffset )
|
||||
println( "WARNING: Code trimmed killcam time by " + (killcamoffset - self.archivetime) + " seconds because it doesn't have enough game time recorded!" );
|
||||
|
||||
camtime = self.archivetime - .05 - predelay;
|
||||
killcamlength = camtime + postdelay;
|
||||
self.killcamlength = killcamlength;
|
||||
|
||||
if ( camtime <= 0 ) // if we're not looking back in time far enough to even see the death, cancel
|
||||
{
|
||||
println( "Cancelling killcam because we don't even have enough recorded to show the death." );
|
||||
|
||||
self.sessionstate = "dead";
|
||||
self.forcespectatorclient = -1;
|
||||
self.killcamentity = -1;
|
||||
self.archivetime = 0;
|
||||
self.psoffsettime = 0;
|
||||
|
||||
self notify ( "killcam_ended" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( level._showingFinalKillcam )
|
||||
thread doFinalKillCamFX( camtime );
|
||||
|
||||
self.killcam = true;
|
||||
|
||||
self initKCElements();
|
||||
if ( getDvarInt( "upgradeEnabling" ) == 1 )
|
||||
{
|
||||
self maps\mp\_upgrade::initUpgradeElements();
|
||||
}
|
||||
|
||||
if ( !level._splitscreen )
|
||||
{
|
||||
self.kc_timer.alpha = 1;
|
||||
self.kc_timer setTenthsTimer(camtime);
|
||||
}
|
||||
|
||||
if ( timeUntilRespawn && !level._gameEnded )
|
||||
{
|
||||
if ( timeUntilRespawn > 0 )
|
||||
if ( isDefined( level._showSpawnTimer ) && level._showSpawnTimer )
|
||||
{
|
||||
setLowerMessage( "kc_info", game["strings"]["waiting_to_spawn"], timeUntilRespawn, 1, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
setLowerMessage( "kc_info", game["strings"]["waiting_to_spawn"], timeUntilRespawn );
|
||||
}
|
||||
else
|
||||
setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_SKIP" );
|
||||
}
|
||||
else if ( !level._gameEnded )
|
||||
{
|
||||
setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_RESPAWN" );
|
||||
}
|
||||
|
||||
if ( !level._showingFinalKillcam )
|
||||
{
|
||||
self.kc_skiptext.alpha = 1;
|
||||
if ( getDvarInt( "upgradeEnabling" ) == 1 )
|
||||
{
|
||||
self maps\mp\_upgrade::showUpgradeHUDElement();
|
||||
}
|
||||
}
|
||||
else
|
||||
self.kc_skiptext.alpha = 0;
|
||||
|
||||
self.kc_othertext.alpha = 0;
|
||||
self.kc_icon.alpha = 0;
|
||||
|
||||
self thread spawnedKillcamCleanup();
|
||||
|
||||
if ( self == victim && victim _hasPerk( "specialty_copycat" ) && isDefined( victim.pers["copyCatLoadout"] ) )
|
||||
self thread waitKCCopyCatButton( attacker );
|
||||
|
||||
if ( !level._showingFinalKillcam )
|
||||
self thread waitSkipKillcamButton( timeUntilRespawn );
|
||||
else
|
||||
self notify ( "showing_final_killcam" );
|
||||
|
||||
self thread endKillcamIfNothingToShow();
|
||||
|
||||
self waittillKillcamOver();
|
||||
|
||||
if ( level._showingFinalKillcam )
|
||||
{
|
||||
self thread maps\mp\gametypes\_playerlogic::spawnEndOfGame();
|
||||
return;
|
||||
}
|
||||
|
||||
self thread calculateKillCamTime( startTime );
|
||||
|
||||
self thread killcamCleanup( true );
|
||||
}
|
||||
|
||||
|
||||
doFinalKillCamFX( camTime )
|
||||
{
|
||||
if ( isDefined( level._doingFinalKillcamFx ) )
|
||||
return;
|
||||
level._doingFinalKillcamFx = true;
|
||||
|
||||
intoSlowMoTime = camTime;
|
||||
if ( intoSlowMoTime > 1.0 )
|
||||
{
|
||||
intoSlowMoTime = 1.0;
|
||||
wait( camTime - 1.0 );
|
||||
}
|
||||
|
||||
setSlowMotion( 1.0, 0.25, intoSlowMoTime ); // start timescale, end timescale, lerp duration
|
||||
wait( intoSlowMoTime + .5 );
|
||||
setSlowMotion( 0.25, 1, 1.0 );
|
||||
|
||||
level._doingFinalKillcamFx = undefined;
|
||||
}
|
||||
|
||||
|
||||
calculateKillCamTime( startTime )
|
||||
{
|
||||
watchedTime = int(getTime() - startTime);
|
||||
self incPlayerStat( "killcamtimewatched", watchedTime );
|
||||
}
|
||||
|
||||
waittillKillcamOver()
|
||||
{
|
||||
self endon("abort_killcam");
|
||||
|
||||
wait(self.killcamlength - 0.05);
|
||||
}
|
||||
|
||||
setKillCamEntity( killcamentityindex, killcamoffset, starttime )
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
killcamtime = (gettime() - killcamoffset * 1000);
|
||||
|
||||
if ( starttime > killcamtime )
|
||||
{
|
||||
wait .05;
|
||||
// code may have trimmed archivetime after the first frame if we couldn't go back in time as far as requested.
|
||||
killcamoffset = self.archivetime;
|
||||
killcamtime = (gettime() - killcamoffset * 1000);
|
||||
|
||||
if ( starttime > killcamtime )
|
||||
wait (starttime - killcamtime) / 1000;
|
||||
}
|
||||
self.killcamentity = killcamentityindex;
|
||||
}
|
||||
|
||||
waitSkipKillcamButton( timeUntilRespawn )
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
while(self cancelKillCamUseButton())
|
||||
wait .05;
|
||||
|
||||
while(!(self cancelKillCamUseButton()))
|
||||
wait .05;
|
||||
|
||||
if ( !matchMakingGame() )
|
||||
self incPlayerStat( "killcamskipped", 1 );
|
||||
|
||||
if ( timeUntilRespawn <= 0 )
|
||||
clearLowerMessage( "kc_info" );
|
||||
if ( getDvarInt( "upgradeEnabling" ) == 1 )
|
||||
{
|
||||
self maps\mp\_upgrade::processUpgradeSelections();
|
||||
}
|
||||
|
||||
self notify("abort_killcam");
|
||||
}
|
||||
|
||||
waitKCCopyCatButton( attacker )
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
self waitCopyCatButton( attacker );
|
||||
|
||||
self notify("abort_killcam");
|
||||
}
|
||||
|
||||
waitDeathCopyCatButton( attacker )
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
|
||||
self initKCElements();
|
||||
if ( getDvarInt( "upgradeEnabling" ) == 1 )
|
||||
{
|
||||
self maps\mp\_upgrade::initUpgradeElements();
|
||||
}
|
||||
|
||||
usedCopycat = self waitCopyCatButton( attacker );
|
||||
|
||||
if ( !isDefined( usedCopycat ) )
|
||||
{
|
||||
self.kc_icon.alpha = 0;
|
||||
self.kc_othertext.alpha = 0;
|
||||
}
|
||||
}
|
||||
|
||||
waitCopyCatButton( attacker )
|
||||
{
|
||||
self endon ( "spawned_player" );
|
||||
self endon ( "death_delay_finished" );
|
||||
self.kc_icon setShader( "specialty_copycat", 48, 48 );
|
||||
self.kc_othertext setText( &"PLATFORM_PRESS_TO_COPYCAT" );
|
||||
self.kc_othertext.alpha = 1;
|
||||
self.kc_icon.alpha = 1;
|
||||
|
||||
self notifyOnPlayerCommand( "use_copycat", "weapnext" );
|
||||
|
||||
self waittill( "use_copycat" );
|
||||
|
||||
self.pers["copyCatLoadout"]["inUse"] = true;
|
||||
self.pers["copyCatLoadout"]["owner"] = attacker;
|
||||
|
||||
self.kc_othertext fadeOverTime( 0.5 );
|
||||
self.kc_othertext.alpha = 0;
|
||||
|
||||
self.kc_icon fadeOverTime( 0.25 );
|
||||
self.kc_icon scaleOverTime( 0.25, 512, 512 );
|
||||
self.kc_icon.alpha = 0;
|
||||
|
||||
if ( isDefined( attacker ) )
|
||||
attacker thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "copied", self );
|
||||
|
||||
self playLocalSound( "copycat_steal_class" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
waitSkipKillcamSafeSpawnButton()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
if ( !self maps\mp\gametypes\_playerlogic::maySpawn() )
|
||||
return;
|
||||
|
||||
while(self fragButtonPressed())
|
||||
wait .05;
|
||||
|
||||
while(!(self fragButtonPressed()))
|
||||
wait .05;
|
||||
|
||||
self.wantSafeSpawn = true;
|
||||
|
||||
self notify("abort_killcam");
|
||||
}
|
||||
|
||||
endKillcamIfNothingToShow()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
while(1)
|
||||
{
|
||||
// code may trim our archivetime to zero if there is nothing "recorded" to show.
|
||||
// this can happen when the person we're watching in our killcam goes into killcam himself.
|
||||
// in this case, end the killcam.
|
||||
if ( self.archivetime <= 0 )
|
||||
break;
|
||||
wait .05;
|
||||
}
|
||||
|
||||
self notify("abort_killcam");
|
||||
}
|
||||
|
||||
spawnedKillcamCleanup()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
self waittill("spawned");
|
||||
self thread killcamCleanup( false );
|
||||
}
|
||||
|
||||
endedKillcamCleanup()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
level waittill("game_ended");
|
||||
|
||||
self thread killcamCleanup( true );
|
||||
}
|
||||
|
||||
killcamCleanup( clearState )
|
||||
{
|
||||
if(isDefined(self.kc_skiptext))
|
||||
self.kc_skiptext.alpha = 0;
|
||||
|
||||
if(isDefined(self.kc_timer))
|
||||
self.kc_timer.alpha = 0;
|
||||
|
||||
if(isDefined(self.kc_icon))
|
||||
self.kc_icon.alpha = 0;
|
||||
|
||||
if(isDefined(self.kc_othertext))
|
||||
self.kc_othertext.alpha = 0;
|
||||
|
||||
if ( getDvarInt( "upgradeEnabling" ) == 1 )
|
||||
{
|
||||
maps\mp\_upgrade::upgradeHUDCleanUp();
|
||||
}
|
||||
|
||||
self.killcam = undefined;
|
||||
|
||||
if ( !level._gameEnded )
|
||||
self clearLowerMessage( "kc_info" );
|
||||
|
||||
self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
|
||||
|
||||
self notify("killcam_ended"); // do this last, in case this function was called from a thread ending on it
|
||||
|
||||
if ( !clearState )
|
||||
return;
|
||||
|
||||
self.sessionstate = "dead";
|
||||
self ClearKillcamState();
|
||||
}
|
||||
|
||||
|
||||
|
||||
cancelKillCamOnUse()
|
||||
{
|
||||
self.cancelKillcam = false;
|
||||
self thread cancelKillCamOnUse_specificButton( ::cancelKillCamUseButton, ::cancelKillCamCallback );
|
||||
//self thread cancelKillCamOnUse_specificButton( ::cancelKillCamSafeSpawnButton, ::cancelKillCamSafeSpawnCallback );
|
||||
}
|
||||
|
||||
cancelKillCamUseButton()
|
||||
{
|
||||
if ( getDvarInt( "upgradeEnabling" ) == 1 )
|
||||
{
|
||||
if ( self useButtonPressed())
|
||||
{
|
||||
self.killCamButtonPressed = "use";
|
||||
return true;
|
||||
}
|
||||
else if ( self JumpButtonPressed())
|
||||
{
|
||||
self.killCamButtonPressed = "jump";
|
||||
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["jump"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["jump"] )))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( self maps\mp\_upgrade::ReloadButtonPressed())
|
||||
{
|
||||
self.killCamButtonPressed = "switchWeap";
|
||||
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["switchWeap"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["switchWeap"] )))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( self maps\mp\_upgrade::ProneButtonPressed())
|
||||
{
|
||||
self.killCamButtonPressed = "prone";
|
||||
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["prone"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["prone"] )))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return self useButtonPressed();
|
||||
}
|
||||
}
|
||||
cancelKillCamSafeSpawnButton()
|
||||
{
|
||||
return self fragButtonPressed();
|
||||
}
|
||||
cancelKillCamCallback()
|
||||
{
|
||||
self.cancelKillcam = true;
|
||||
}
|
||||
cancelKillCamSafeSpawnCallback()
|
||||
{
|
||||
self.cancelKillcam = true;
|
||||
self.wantSafeSpawn = true;
|
||||
}
|
||||
|
||||
cancelKillCamOnUse_specificButton( pressingButtonFunc, finishedFunc )
|
||||
{
|
||||
self endon ( "death_delay_finished" );
|
||||
self endon ( "disconnect" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( !self [[pressingButtonFunc]]() )
|
||||
{
|
||||
wait ( 0.05 );
|
||||
continue;
|
||||
}
|
||||
|
||||
buttonTime = 0;
|
||||
while( self [[pressingButtonFunc]]() )
|
||||
{
|
||||
buttonTime += 0.05;
|
||||
wait ( 0.05 );
|
||||
}
|
||||
|
||||
if ( buttonTime >= 0.5 )
|
||||
continue;
|
||||
|
||||
buttonTime = 0;
|
||||
|
||||
while ( !self [[pressingButtonFunc]]() && buttonTime < 0.5 )
|
||||
{
|
||||
buttonTime += 0.05;
|
||||
wait ( 0.05 );
|
||||
}
|
||||
|
||||
if ( buttonTime >= 0.5 )
|
||||
continue;
|
||||
|
||||
if ( getDvarInt( "upgradeEnabling" ) == 1 )
|
||||
{
|
||||
self maps\mp\_upgrade::processUpgradeSelections();
|
||||
}
|
||||
|
||||
self [[finishedFunc]]();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
initKCElements()
|
||||
{
|
||||
if ( !isDefined( self.kc_skiptext ) )
|
||||
{
|
||||
self.kc_skiptext = newClientHudElem(self);
|
||||
self.kc_skiptext.archived = false;
|
||||
self.kc_skiptext.x = 0;
|
||||
self.kc_skiptext.alignX = "center";
|
||||
self.kc_skiptext.alignY = "top";
|
||||
self.kc_skiptext.horzAlign = "center_adjustable";
|
||||
self.kc_skiptext.vertAlign = "top_adjustable";
|
||||
self.kc_skiptext.sort = 1; // force to draw after the bars
|
||||
self.kc_skiptext.font = "default";
|
||||
self.kc_skiptext.foreground = true;
|
||||
self.kc_skiptext.hideWhenInMenu = true;
|
||||
|
||||
if ( level._splitscreen )
|
||||
{
|
||||
self.kc_skiptext.y = 20;
|
||||
self.kc_skiptext.fontscale = 1.2; // 1.8/1.5
|
||||
}
|
||||
else
|
||||
{
|
||||
self.kc_skiptext.y = 32;
|
||||
self.kc_skiptext.fontscale = 1.8;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isDefined( self.kc_othertext ) )
|
||||
{
|
||||
self.kc_othertext = newClientHudElem(self);
|
||||
self.kc_othertext.archived = false;
|
||||
self.kc_othertext.y = 48;
|
||||
self.kc_othertext.alignX = "left";
|
||||
self.kc_othertext.alignY = "top";
|
||||
self.kc_othertext.horzAlign = "center";
|
||||
self.kc_othertext.vertAlign = "middle";
|
||||
self.kc_othertext.sort = 10; // force to draw after the bars
|
||||
self.kc_othertext.font = "small";
|
||||
self.kc_othertext.foreground = true;
|
||||
self.kc_othertext.hideWhenInMenu = true;
|
||||
|
||||
if ( level._splitscreen )
|
||||
{
|
||||
self.kc_othertext.x = 16;
|
||||
self.kc_othertext.fontscale = 1.2;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.kc_othertext.x = 32;
|
||||
self.kc_othertext.fontscale = 1.6;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isDefined( self.kc_icon ) )
|
||||
{
|
||||
self.kc_icon = newClientHudElem(self);
|
||||
self.kc_icon.archived = false;
|
||||
self.kc_icon.x = 16;
|
||||
self.kc_icon.y = 16;
|
||||
self.kc_icon.alignX = "left";
|
||||
self.kc_icon.alignY = "top";
|
||||
self.kc_icon.horzAlign = "center";
|
||||
self.kc_icon.vertAlign = "middle";
|
||||
self.kc_icon.sort = 1; // force to draw after the bars
|
||||
self.kc_icon.foreground = true;
|
||||
self.kc_icon.hideWhenInMenu = true;
|
||||
}
|
||||
|
||||
if ( !level._splitscreen )
|
||||
{
|
||||
if ( !isdefined( self.kc_timer ) )
|
||||
{
|
||||
self.kc_timer = createFontString( "hudbig", 1.0 );
|
||||
self.kc_timer.archived = false;
|
||||
self.kc_timer.x = 0;
|
||||
self.kc_timer.alignX = "center";
|
||||
self.kc_timer.alignY = "middle";
|
||||
self.kc_timer.horzAlign = "center_safearea";
|
||||
self.kc_timer.vertAlign = "top_adjustable";
|
||||
self.kc_timer.y = 42;
|
||||
self.kc_timer.sort = 1; // force to draw after the bars
|
||||
self.kc_timer.font = "hudbig";
|
||||
self.kc_timer.foreground = true;
|
||||
self.kc_timer.color = (0.85,0.85,0.85);
|
||||
self.kc_timer.hideWhenInMenu = true;
|
||||
}
|
||||
}
|
||||
}
|
589
maps/mp/gametypes/_menus.gsc
Normal file
589
maps/mp/gametypes/_menus.gsc
Normal file
@ -0,0 +1,589 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
if ( !isDefined( game["gamestarted"] ) )
|
||||
{
|
||||
game["menu_team"] = "team_marinesopfor";
|
||||
|
||||
if( level._multiTeamBased )
|
||||
{
|
||||
game["menu_team"] = "team_mtdm_options";
|
||||
}
|
||||
|
||||
game["menu_class_allies"] = "class_marines";
|
||||
game["menu_changeclass_allies"] = "changeclass_marines";
|
||||
game["menu_initteam_allies"] = "initteam_marines";
|
||||
game["menu_class_axis"] = "class_opfor";
|
||||
game["menu_changeclass_axis"] = "changeclass_opfor";
|
||||
game["menu_initteam_axis"] = "initteam_opfor";
|
||||
game["menu_class"] = "class";
|
||||
game["menu_changeclass"] = "changeclass";
|
||||
game["menu_onemanarmy"] = "onemanarmy";
|
||||
game["menu_exosuit"] = "exosuit";
|
||||
|
||||
if( level._multiTeamBased )
|
||||
{
|
||||
for( i = 0; i < level._teamNameList.size; i++ )
|
||||
{
|
||||
str_menu_class = "menu_class_" + level._teamNameList[i];
|
||||
str_menu_changeclass = "menu_changeclass_" + level._teamNameList[i];
|
||||
str_menu_initteam = "menu_initteam_" + level._teamNameList[i];
|
||||
game[str_menu_class] = "class_marines";
|
||||
game[str_menu_changeclass] = "changeclass_marines";
|
||||
game[str_menu_initteam] = "initteam_marines";
|
||||
}
|
||||
}
|
||||
|
||||
if ( !level._console )
|
||||
{
|
||||
game["menu_callvote"] = "callvote";
|
||||
game["menu_muteplayer"] = "muteplayer";
|
||||
precacheMenu(game["menu_callvote"]);
|
||||
precacheMenu(game["menu_muteplayer"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
game["menu_controls"] = "ingame_controls";
|
||||
//game["menu_options"] = "ingame_options";
|
||||
game["menu_leavegame"] = "popup_leavegame";
|
||||
|
||||
if(level._splitscreen)
|
||||
{
|
||||
if( level._multiTeamBased )
|
||||
{
|
||||
for( i = 0; i < level._teamNameList.size; i++ )
|
||||
{
|
||||
str_menu_class = "menu_class_" + level._teamNameList[i];
|
||||
str_menu_changeclass = "menu_changeclass_" + level._teamNameList[i];
|
||||
game[str_menu_class] += "_splitscreen";
|
||||
game[str_menu_changeclass] += "_splitscreen";
|
||||
}
|
||||
}
|
||||
|
||||
game["menu_team"] += "_splitscreen";
|
||||
game["menu_class_allies"] += "_splitscreen";
|
||||
game["menu_changeclass_allies"] += "_splitscreen";
|
||||
game["menu_class_axis"] += "_splitscreen";
|
||||
game["menu_changeclass_axis"] += "_splitscreen";
|
||||
game["menu_class"] += "_splitscreen";
|
||||
game["menu_controls"] += "_splitscreen";
|
||||
//game["menu_options"] += "_splitscreen";
|
||||
game["menu_leavegame"] += "_splitscreen";
|
||||
game["menu_onemanarmy"] += "_splitscreen";
|
||||
|
||||
game["menu_changeclass_defaults_splitscreen"] = "changeclass_defaults_splitscreen";
|
||||
game["menu_changeclass_custom_splitscreen"] = "changeclass_custom_splitscreen";
|
||||
game["menu_onemanarmy_defaults_splitscreen"] = "onemanarmy_defaults_splitscreen";
|
||||
game["menu_onemanarmy_custom_splitscreen"] = "onemanarmy_custom_splitscreen";
|
||||
|
||||
precacheMenu(game["menu_changeclass_defaults_splitscreen"]);
|
||||
precacheMenu(game["menu_changeclass_custom_splitscreen"]);
|
||||
precacheMenu(game["menu_onemanarmy_defaults_splitscreen"]);
|
||||
precacheMenu(game["menu_onemanarmy_custom_splitscreen"]);
|
||||
}
|
||||
|
||||
precacheMenu(game["menu_controls"]);
|
||||
//precacheMenu(game["menu_options"]);
|
||||
precacheMenu(game["menu_leavegame"]);
|
||||
|
||||
//precacheMenu("status_update");
|
||||
}
|
||||
|
||||
precacheMenu("scoreboard");
|
||||
precacheMenu(game["menu_team"]);
|
||||
precacheMenu(game["menu_class_allies"]);
|
||||
precacheMenu(game["menu_changeclass_allies"]);
|
||||
precacheMenu(game["menu_initteam_allies"]);
|
||||
precacheMenu(game["menu_class_axis"]);
|
||||
precacheMenu(game["menu_changeclass_axis"]);
|
||||
precacheMenu(game["menu_class"]);
|
||||
precacheMenu(game["menu_changeclass"]);
|
||||
precacheMenu(game["menu_initteam_axis"]);
|
||||
precacheMenu(game["menu_onemanarmy"]);
|
||||
precacheMenu(game["menu_exosuit"]);
|
||||
|
||||
precacheString( &"MP_HOST_ENDED_GAME" );
|
||||
precacheString( &"MP_HOST_ENDGAME_RESPONSE" );
|
||||
}
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player thread onMenuResponse();
|
||||
}
|
||||
}
|
||||
|
||||
onMenuResponse()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("menuresponse", menu, response);
|
||||
|
||||
if ( response == "back" )
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
|
||||
if ( level._console )
|
||||
{
|
||||
if ( menu == game["menu_changeclass"] ||
|
||||
menu == game["menu_team"] ||
|
||||
menu == game["menu_controls"] ||
|
||||
( isDefined( game["menu_changeclass_defaults_splitscreen"] ) && menu == game["menu_changeclass_defaults_splitscreen"] ) ||
|
||||
( isDefined( game["menu_changeclass_custom_splitscreen"] ) && menu == game["menu_changeclass_custom_splitscreen"] ) )
|
||||
{
|
||||
if( self.pers["team"] == "allies" )
|
||||
self openpopupMenu( game["menu_class_allies"] );
|
||||
if( self.pers["team"] == "axis" )
|
||||
self openpopupMenu( game["menu_class_axis"] );
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(response == "changeteam")
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
self openpopupMenu(game["menu_team"]);
|
||||
}
|
||||
|
||||
if(response == "changeclass_marines" )
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
self openpopupMenu( game["menu_changeclass_allies"] );
|
||||
continue;
|
||||
}
|
||||
|
||||
if(response == "changeclass_opfor" )
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
self openpopupMenu( game["menu_changeclass_axis"] );
|
||||
continue;
|
||||
}
|
||||
|
||||
if(response == "changeclass_marines_splitscreen" )
|
||||
self openpopupMenu( "changeclass_marines_splitscreen" );
|
||||
|
||||
if(response == "changeclass_opfor_splitscreen" )
|
||||
self openpopupMenu( "changeclass_opfor_splitscreen" );
|
||||
|
||||
if(response == "endgame")
|
||||
{
|
||||
if(level._splitscreen)
|
||||
{
|
||||
endparty();
|
||||
|
||||
if ( !level._gameEnded )
|
||||
{
|
||||
level thread maps\mp\gametypes\_gamelogic::forceEnd();
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( response == "endround" )
|
||||
{
|
||||
if ( !level._gameEnded )
|
||||
{
|
||||
level thread maps\mp\gametypes\_gamelogic::forceEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
self iprintln( &"MP_HOST_ENDGAME_RESPONSE" );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( menu == game["menu_team"] )
|
||||
{
|
||||
switch( response )
|
||||
{
|
||||
case "autoassign":
|
||||
self [[level._autoassign]]();
|
||||
break;
|
||||
|
||||
case "spectator":
|
||||
self [[level._spectator]]();
|
||||
break;
|
||||
|
||||
default:
|
||||
self [[level._onTeamSelection]]( response );
|
||||
}
|
||||
} // the only responses remain are change class events
|
||||
else if ( menu == game["menu_changeclass"] ||
|
||||
( isDefined( game["menu_changeclass_defaults_splitscreen"] ) && menu == game["menu_changeclass_defaults_splitscreen"] ) ||
|
||||
( isDefined( game["menu_changeclass_custom_splitscreen"] ) && menu == game["menu_changeclass_custom_splitscreen"] ) )
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
|
||||
self.selectedClass = true;
|
||||
self [[level._class]](response);
|
||||
}
|
||||
else if ( !level._console )
|
||||
{
|
||||
if(menu == game["menu_quickcommands"])
|
||||
maps\mp\gametypes\_quickmessages::quickcommands(response);
|
||||
else if(menu == game["menu_quickstatements"])
|
||||
maps\mp\gametypes\_quickmessages::quickstatements(response);
|
||||
else if(menu == game["menu_quickresponses"])
|
||||
maps\mp\gametypes\_quickmessages::quickresponses(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMenuTeamSelect( selection )
|
||||
{
|
||||
self closeMenus();
|
||||
|
||||
if(self.pers["team"] != selection)
|
||||
{
|
||||
if( level._teamBased && !maps\mp\gametypes\_teams::getJoinTeamPermissions( selection ) )
|
||||
{
|
||||
self openpopupMenu(game["menu_team"]);
|
||||
return;
|
||||
}
|
||||
|
||||
// allow respawn when switching teams during grace period.
|
||||
if ( level._inGracePeriod && !self.hasDoneCombat )
|
||||
self.hasSpawned = false;
|
||||
|
||||
if(self.sessionstate == "playing")
|
||||
{
|
||||
self.switching_teams = true;
|
||||
self.joining_team = selection;
|
||||
self.leaving_team = self.pers["team"];
|
||||
self suicide();
|
||||
}
|
||||
|
||||
self addToTeam( selection );
|
||||
self.pers["class"] = undefined;
|
||||
self.class = undefined;
|
||||
|
||||
self notify("end_respawn");
|
||||
}
|
||||
|
||||
self beginClassChoice();
|
||||
}
|
||||
|
||||
getTeamAssignment()
|
||||
{
|
||||
teams[0] = "allies";
|
||||
teams[1] = "axis";
|
||||
|
||||
if ( !level._teamBased )
|
||||
return teams[randomInt(2)];
|
||||
|
||||
//If sessionteam is already set, it is probably because you are in a matchmaking game
|
||||
if ( self.sessionteam != "none" && self.sessionteam != "spectator" && self.sessionstate != "playing" && self.sessionstate != "dead" )
|
||||
{
|
||||
assignment = self.sessionteam;
|
||||
}
|
||||
else if( level._multiTeamBased )
|
||||
{
|
||||
/#
|
||||
println( "" );
|
||||
println( "SETTING TEAM ASSIGNMENT" );
|
||||
println( "max num teams = " + level._teamNameList.size );
|
||||
#/
|
||||
|
||||
numTeams = level._teamNameList.size;
|
||||
|
||||
//scan for smallest team, assign new player to that team
|
||||
teamAssignment = level._teamNameList[0];
|
||||
for( i = 0; i < level._teamNameList.size; i++ )
|
||||
{
|
||||
/#
|
||||
println( level._teamNameList[i] + " has " + level._teamCount[level._teamNameList[i]] + " players on it." );
|
||||
#/
|
||||
|
||||
if ( level._teamCount[level._teamNameList[i]] < level._teamCount[teamAssignment] )
|
||||
{
|
||||
teamAssignment = level._teamNameList[i];
|
||||
}
|
||||
}
|
||||
|
||||
/#
|
||||
println( "Team assignment = " + teamAssignment );
|
||||
println( "" );
|
||||
#/
|
||||
|
||||
return teamAssignment;
|
||||
}
|
||||
else
|
||||
{
|
||||
playerCounts = self maps\mp\gametypes\_teams::CountPlayers();
|
||||
|
||||
// if teams are equal return the team with the lowest score
|
||||
if ( playerCounts["allies"] == playerCounts["axis"] )
|
||||
{
|
||||
if( getTeamScore( "allies" ) == getTeamScore( "axis" ) )
|
||||
assignment = teams[randomInt(2)];
|
||||
else if ( getTeamScore( "allies" ) < getTeamScore( "axis" ) )
|
||||
assignment = "allies";
|
||||
else
|
||||
assignment = "axis";
|
||||
}
|
||||
else if( playerCounts["allies"] < playerCounts["axis"] )
|
||||
{
|
||||
assignment = "allies";
|
||||
}
|
||||
else
|
||||
{
|
||||
assignment = "axis";
|
||||
}
|
||||
}
|
||||
|
||||
return assignment;
|
||||
}
|
||||
|
||||
|
||||
menuAutoAssign()
|
||||
{
|
||||
self closeMenus();
|
||||
|
||||
assignment = getTeamAssignment();
|
||||
|
||||
if ( isDefined( self.pers["team"] ) && (self.sessionstate == "playing" || self.sessionstate == "dead") )
|
||||
{
|
||||
if ( assignment == self.pers["team"] )
|
||||
{
|
||||
self beginClassChoice();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.switching_teams = true;
|
||||
self.joining_team = assignment;
|
||||
self.leaving_team = self.pers["team"];
|
||||
self suicide();
|
||||
}
|
||||
}
|
||||
|
||||
self addToTeam( assignment );
|
||||
self.pers["class"] = undefined;
|
||||
self.class = undefined;
|
||||
|
||||
if ( !isAlive( self ) )
|
||||
self.statusicon = "hud_status_dead";
|
||||
|
||||
self notify("end_respawn");
|
||||
|
||||
self beginClassChoice();
|
||||
}
|
||||
|
||||
|
||||
beginClassChoice( forceNewChoice )
|
||||
{
|
||||
if( !level._multiTeamBased )
|
||||
{
|
||||
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
|
||||
}
|
||||
|
||||
team = self.pers["team"];
|
||||
|
||||
// menu_changeclass_team is the one where you choose one of the n classes to play as.
|
||||
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
|
||||
self openpopupMenu( game[ "menu_changeclass_" + team ] );
|
||||
|
||||
if ( !isAlive( self ) )
|
||||
self thread maps\mp\gametypes\_playerlogic::predictAboutToSpawnPlayerOverTime( 0.1 );
|
||||
}
|
||||
|
||||
|
||||
beginTeamChoice()
|
||||
{
|
||||
self openpopupMenu( game["menu_team"] );
|
||||
}
|
||||
|
||||
|
||||
showMainMenuForTeam()
|
||||
{
|
||||
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
|
||||
|
||||
team = self.pers["team"];
|
||||
|
||||
// menu_changeclass_team is the one where you choose one of the n classes to play as.
|
||||
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
|
||||
self openpopupMenu( game[ "menu_class_" + team ] );
|
||||
}
|
||||
|
||||
menuSpectator()
|
||||
{
|
||||
self closeMenus();
|
||||
|
||||
if( isDefined( self.pers["team"] ) && self.pers["team"] == "spectator" )
|
||||
return;
|
||||
|
||||
if( isAlive( self ) )
|
||||
{
|
||||
assert( isDefined( self.pers["team"] ) );
|
||||
self.switching_teams = true;
|
||||
self.joining_team = "spectator";
|
||||
self.leaving_team = self.pers["team"];
|
||||
self suicide();
|
||||
}
|
||||
|
||||
self addToTeam( "spectator" );
|
||||
self.pers["class"] = undefined;
|
||||
self.class = undefined;
|
||||
|
||||
self thread maps\mp\gametypes\_playerlogic::spawnSpectator();
|
||||
}
|
||||
|
||||
|
||||
menuClass( response )
|
||||
{
|
||||
self closeMenus();
|
||||
|
||||
// clear new status of unlocked classes
|
||||
if ( response == "demolitions_mp,0" && self getPlayerData( "featureNew", "demolitions" ) )
|
||||
{
|
||||
self setPlayerData( "featureNew", "demolitions", false );
|
||||
}
|
||||
if ( response == "sniper_mp,0" && self getPlayerData( "featureNew", "sniper" ) )
|
||||
{
|
||||
self setPlayerData( "featureNew", "sniper", false );
|
||||
}
|
||||
|
||||
// this should probably be an assert
|
||||
if( !level._multiTeamBased )
|
||||
{
|
||||
if(!isDefined(self.pers["team"]) || (self.pers["team"] != "allies" && self.pers["team"] != "axis"))
|
||||
return;
|
||||
}
|
||||
|
||||
class = self maps\mp\gametypes\_class::getClassChoice( response );
|
||||
primary = self maps\mp\gametypes\_class::getWeaponChoice( response );
|
||||
|
||||
if ( class == "restricted" )
|
||||
{
|
||||
self beginClassChoice();
|
||||
return;
|
||||
}
|
||||
|
||||
if( (isDefined( self.pers["class"] ) && self.pers["class"] == class) &&
|
||||
(isDefined( self.pers["primary"] ) && self.pers["primary"] == primary) )
|
||||
return;
|
||||
|
||||
if ( self.sessionstate == "playing" )
|
||||
{
|
||||
self.pers["class"] = class;
|
||||
self.class = class;
|
||||
self.pers["primary"] = primary;
|
||||
|
||||
if ( game["state"] == "postgame" )
|
||||
return;
|
||||
|
||||
if ( level._inGracePeriod && !self.hasDoneCombat ) // used weapons check?
|
||||
{
|
||||
if ( !isGameModeBlockingClassChange())
|
||||
{
|
||||
self maps\mp\gametypes\_class::setClass( self.pers["class"] );
|
||||
self.tag_stowed_back = undefined;
|
||||
self.tag_stowed_hip = undefined;
|
||||
self maps\mp\gametypes\_class::giveLoadout( self.pers["team"], self.pers["class"] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isGameModeBlockingClassChange())
|
||||
{
|
||||
self iPrintLnBold( game["strings"]["change_class"] );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.pers["class"] = class;
|
||||
self.class = class;
|
||||
self.pers["primary"] = primary;
|
||||
|
||||
if ( game["state"] == "postgame" )
|
||||
return;
|
||||
|
||||
if ( game["state"] == "playing" && !isInKillcam() )
|
||||
self thread maps\mp\gametypes\_playerlogic::spawnClient();
|
||||
}
|
||||
|
||||
self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
addToTeam( team, firstConnect )
|
||||
{
|
||||
// UTS update playerCount remove from team
|
||||
if ( isDefined( self.team ) )
|
||||
self maps\mp\gametypes\_playerlogic::removeFromTeamCount();
|
||||
|
||||
self.pers["team"] = team;
|
||||
// this is the only place self.team should ever be set
|
||||
self.team = team;
|
||||
|
||||
// session team is readonly in ranked matches on console
|
||||
if ( !matchMakingGame() || isDefined( self.pers["isBot"] ) )
|
||||
{
|
||||
if ( level._teamBased )
|
||||
{
|
||||
self.sessionteam = team;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( team == "spectator" )
|
||||
self.sessionteam = "spectator";
|
||||
else
|
||||
self.sessionteam = "none";
|
||||
}
|
||||
}
|
||||
|
||||
// UTS update playerCount add to team
|
||||
if ( game["state"] != "postgame" )
|
||||
self maps\mp\gametypes\_playerlogic::addToTeamCount();
|
||||
|
||||
self updateObjectiveText();
|
||||
|
||||
// give "joined_team" and "joined_spectators" handlers a chance to start
|
||||
// these are generally triggered from the "connected" notify, which can happen on the same
|
||||
// frame as these notifies
|
||||
if ( isDefined( firstConnect ) && firstConnect )
|
||||
waittillframeend;
|
||||
|
||||
self updateMainMenu();
|
||||
|
||||
if ( team == "spectator" )
|
||||
{
|
||||
self notify( "joined_spectators" );
|
||||
level notify( "joined_team" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self notify( "joined_team" );
|
||||
level notify( "joined_team" );
|
||||
}
|
||||
}
|
||||
|
||||
isGameModeBlockingClassChange()
|
||||
{
|
||||
result = false;
|
||||
if ( isDefined( level._blockClassChange) && level._blockClassChange == true )
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
2368
maps/mp/gametypes/_missions.gsc
Normal file
2368
maps/mp/gametypes/_missions.gsc
Normal file
File diff suppressed because it is too large
Load Diff
512
maps/mp/gametypes/_music_and_dialog.gsc
Normal file
512
maps/mp/gametypes/_music_and_dialog.gsc
Normal file
@ -0,0 +1,512 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
init()
|
||||
{
|
||||
|
||||
if( level._multiTeamBased == true )
|
||||
{
|
||||
for( i = 0; i < level._teamNameList.size; i++ )
|
||||
{
|
||||
str_spawn_team = "spawn_" + level._teamNameList[i];
|
||||
str_defeat_team = "defeat_" + level._teamNameList[i];
|
||||
str_victory_team = "victory_" + level._teamNameList[i];
|
||||
str_winning_team = "winning_" + level._teamNameList[i];
|
||||
str_losing_team = "losing_" + level._teamNameList[i];
|
||||
|
||||
game["music"][str_spawn_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "spawn_music";
|
||||
game["music"][str_defeat_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "defeat_music";
|
||||
game["music"][str_victory_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "victory_music";
|
||||
game["music"][str_winning_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "winning_music";
|
||||
game["music"][str_losing_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "losing_music";
|
||||
game["voice"][level._teamNameList[i]] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "1mc_";
|
||||
}
|
||||
}
|
||||
|
||||
game["music"]["spawn_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "spawn_music";
|
||||
game["music"]["defeat_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "defeat_music";
|
||||
game["music"]["victory_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "victory_music";
|
||||
game["music"]["winning_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "winning_music";
|
||||
game["music"]["losing_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "losing_music";
|
||||
game["voice"]["allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "1mc_";
|
||||
|
||||
game["music"]["spawn_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "spawn_music";
|
||||
game["music"]["defeat_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "defeat_music";
|
||||
game["music"]["victory_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "victory_music";
|
||||
game["music"]["winning_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "winning_music";
|
||||
game["music"]["losing_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "losing_music";
|
||||
game["voice"]["axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "1mc_";
|
||||
|
||||
game["music"]["defeat"] = "mp_defeat";
|
||||
game["music"]["victory_spectator"] = "mp_defeat";
|
||||
game["music"]["winning_time"] = "mp_time_running_out_winning";
|
||||
game["music"]["losing_time"] = "mp_time_running_out_losing";
|
||||
game["music"]["winning_score"] = "mp_time_running_out_winning";
|
||||
game["music"]["losing_score"] = "mp_time_running_out_losing";
|
||||
game["music"]["victory_tie"] = "mp_defeat";
|
||||
|
||||
game["music"]["suspense"] = [];
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_01";
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_02";
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_03";
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_04";
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_05";
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_06";
|
||||
|
||||
game["dialog"]["mission_success"] = "mission_success";
|
||||
game["dialog"]["mission_failure"] = "mission_fail";
|
||||
game["dialog"]["mission_draw"] = "draw";
|
||||
|
||||
game["dialog"]["round_success"] = "encourage_win";
|
||||
game["dialog"]["round_failure"] = "encourage_lost";
|
||||
game["dialog"]["round_draw"] = "draw";
|
||||
|
||||
// status
|
||||
game["dialog"]["timesup"] = "timesup";
|
||||
game["dialog"]["winning_time"] = "winning";
|
||||
game["dialog"]["losing_time"] = "losing";
|
||||
game["dialog"]["winning_score"] = "winning_fight";
|
||||
game["dialog"]["losing_score"] = "losing_fight";
|
||||
game["dialog"]["lead_lost"] = "lead_lost";
|
||||
game["dialog"]["lead_tied"] = "tied";
|
||||
game["dialog"]["lead_taken"] = "lead_taken";
|
||||
game["dialog"]["last_alive"] = "lastalive";
|
||||
|
||||
game["dialog"]["boost"] = "boost";
|
||||
|
||||
if ( !isDefined( game["dialog"]["offense_obj"] ) )
|
||||
game["dialog"]["offense_obj"] = "boost";
|
||||
if ( !isDefined( game["dialog"]["defense_obj"] ) )
|
||||
game["dialog"]["defense_obj"] = "boost";
|
||||
|
||||
game["dialog"]["hardcore"] = "hardcore";
|
||||
game["dialog"]["highspeed"] = "highspeed";
|
||||
game["dialog"]["tactical"] = "tactical";
|
||||
|
||||
game["dialog"]["challenge"] = "challengecomplete";
|
||||
game["dialog"]["promotion"] = "promotion";
|
||||
|
||||
game["dialog"]["bomb_taken"] = "acheive_bomb";
|
||||
game["dialog"]["bomb_lost"] = "bomb_taken";
|
||||
game["dialog"]["bomb_defused"] = "bomb_defused";
|
||||
game["dialog"]["bomb_planted"] = "bomb_planted";
|
||||
|
||||
game["dialog"]["obj_taken"] = "securedobj";
|
||||
game["dialog"]["obj_lost"] = "lostobj";
|
||||
|
||||
game["dialog"]["obj_defend"] = "obj_defend";
|
||||
game["dialog"]["obj_destroy"] = "obj_destroy";
|
||||
game["dialog"]["obj_capture"] = "capture_obj";
|
||||
game["dialog"]["objs_capture"] = "capture_objs";
|
||||
|
||||
game["dialog"]["hq_located"] = "hq_located";
|
||||
game["dialog"]["hq_enemy_captured"] = "hq_captured";
|
||||
game["dialog"]["hq_enemy_destroyed"] = "hq_destroyed";
|
||||
game["dialog"]["hq_secured"] = "hq_secured";
|
||||
game["dialog"]["hq_offline"] = "hq_offline";
|
||||
game["dialog"]["hq_online"] = "hq_online";
|
||||
|
||||
game["dialog"]["move_to_new"] = "new_positions";
|
||||
|
||||
game["dialog"]["push_forward"] = "pushforward";
|
||||
|
||||
game["dialog"]["attack"] = "attack";
|
||||
game["dialog"]["defend"] = "defend";
|
||||
game["dialog"]["offense"] = "offense";
|
||||
game["dialog"]["defense"] = "defense";
|
||||
|
||||
game["dialog"]["halftime"] = "halftime";
|
||||
game["dialog"]["overtime"] = "overtime";
|
||||
game["dialog"]["side_switch"] = "switching";
|
||||
|
||||
game["dialog"]["flag_taken"] = "ourflag";
|
||||
game["dialog"]["flag_dropped"] = "ourflag_drop";
|
||||
game["dialog"]["flag_returned"] = "ourflag_return";
|
||||
game["dialog"]["flag_captured"] = "ourflag_capt";
|
||||
game["dialog"]["flag_getback"] = "getback_ourflag";
|
||||
game["dialog"]["enemy_flag_bringhome"] = "enemyflag_tobase";
|
||||
game["dialog"]["enemy_flag_taken"] = "enemyflag";
|
||||
game["dialog"]["enemy_flag_dropped"] = "enemyflag_drop";
|
||||
game["dialog"]["enemy_flag_returned"] = "enemyflag_return";
|
||||
game["dialog"]["enemy_flag_captured"] = "enemyflag_capt";
|
||||
|
||||
game["dialog"]["capturing_a"] = "capturing_a";
|
||||
game["dialog"]["capturing_b"] = "capturing_b";
|
||||
game["dialog"]["capturing_c"] = "capturing_c";
|
||||
game["dialog"]["captured_a"] = "capture_a";
|
||||
game["dialog"]["captured_b"] = "capture_c";
|
||||
game["dialog"]["captured_c"] = "capture_b";
|
||||
|
||||
game["dialog"]["securing_a"] = "securing_a";
|
||||
game["dialog"]["securing_b"] = "securing_b";
|
||||
game["dialog"]["securing_c"] = "securing_c";
|
||||
game["dialog"]["secured_a"] = "secure_a";
|
||||
game["dialog"]["secured_b"] = "secure_b";
|
||||
game["dialog"]["secured_c"] = "secure_c";
|
||||
|
||||
game["dialog"]["losing_a"] = "losing_a";
|
||||
game["dialog"]["losing_b"] = "losing_b";
|
||||
game["dialog"]["losing_c"] = "losing_c";
|
||||
game["dialog"]["lost_a"] = "lost_a";
|
||||
game["dialog"]["lost_b"] = "lost_b";
|
||||
game["dialog"]["lost_c"] = "lost_c";
|
||||
|
||||
game["dialog"]["enemy_taking_a"] = "enemy_take_a";
|
||||
game["dialog"]["enemy_taking_b"] = "enemy_take_b";
|
||||
game["dialog"]["enemy_taking_c"] = "enemy_take_c";
|
||||
game["dialog"]["enemy_has_a"] = "enemy_has_a";
|
||||
game["dialog"]["enemy_has_b"] = "enemy_has_b";
|
||||
game["dialog"]["enemy_has_c"] = "enemy_has_c";
|
||||
|
||||
game["dialog"]["lost_all"] = "take_positions";
|
||||
game["dialog"]["secure_all"] = "positions_lock";
|
||||
|
||||
game["dialog"]["destroy_sentry"] = "dest_sentrygun";
|
||||
game["music"]["nuke_music"] = "nuke_music";
|
||||
|
||||
game["dialog"]["sentry_gone"] = "sentry_gone";
|
||||
game["dialog"]["sentry_destroyed"] = "sentry_gone";
|
||||
game["dialog"]["ti_gone"] = "ti_cancelled";
|
||||
game["dialog"]["ti_destroyed"] = "ti_blocked";
|
||||
|
||||
level thread onPlayerConnect();
|
||||
level thread onLastAlive();
|
||||
level thread musicController();
|
||||
level thread onGameEnded();
|
||||
level thread onRoundSwitch();
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill ( "connected", player );
|
||||
|
||||
player thread onPlayerSpawned();
|
||||
player thread finalKillcamMusic();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
if ( !level._splitscreen || level._splitscreen && !isDefined( level._playedStartingMusic ) )
|
||||
{
|
||||
self playLocalSound( game["music"]["spawn_" + self.team] );
|
||||
|
||||
|
||||
if ( level._splitscreen )
|
||||
level._playedStartingMusic = true;
|
||||
}
|
||||
|
||||
if ( isDefined( game["dialog"]["gametype"] ) && (!level._splitscreen || self == level._players[0]) )
|
||||
{
|
||||
if ( isDefined( game["dialog"]["allies_gametype"] ) && self.team == "allies" )
|
||||
self leaderDialogOnPlayer( "allies_gametype" );
|
||||
else if ( isDefined( game["dialog"]["axis_gametype"] ) && self.team == "axis" )
|
||||
self leaderDialogOnPlayer( "axis_gametype" );
|
||||
else
|
||||
self leaderDialogOnPlayer( "gametype" );
|
||||
}
|
||||
|
||||
gameFlagWait( "prematch_done" );
|
||||
|
||||
if ( self.team == game["attackers"] )
|
||||
self leaderDialogOnPlayer( "offense_obj", "introboost" );
|
||||
else
|
||||
self leaderDialogOnPlayer( "defense_obj", "introboost" );
|
||||
}
|
||||
|
||||
|
||||
onLastAlive()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
|
||||
level waittill ( "last_alive", player );
|
||||
|
||||
if ( !isAlive( player ) )
|
||||
return;
|
||||
|
||||
player leaderDialogOnPlayer( "last_alive" );
|
||||
}
|
||||
|
||||
|
||||
onRoundSwitch()
|
||||
{
|
||||
level waittill ( "round_switch", switchType );
|
||||
|
||||
if( !isDefined( level._disableRoundSwitchVo ))
|
||||
{
|
||||
switch( switchType )
|
||||
{
|
||||
case "halftime":
|
||||
foreach ( player in level._players )
|
||||
player leaderDialogOnPlayer( "halftime" );
|
||||
break;
|
||||
case "overtime":
|
||||
foreach ( player in level._players )
|
||||
player leaderDialogOnPlayer( "overtime" );
|
||||
break;
|
||||
default:
|
||||
foreach ( player in level._players )
|
||||
player leaderDialogOnPlayer( "side_switch" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onGameEnded()
|
||||
{
|
||||
level thread roundWinnerDialog();
|
||||
level thread gameWinnerDialog();
|
||||
|
||||
level waittill ( "game_win", winner );
|
||||
|
||||
if ( isDefined( level._nukeDetonated ) )
|
||||
{
|
||||
if ( !level._splitScreen )
|
||||
playSoundOnPlayers( game["music"]["nuke_music"] );
|
||||
else
|
||||
level._players[0] playLocalSound( game["music"]["nuke_music"] );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( level._teamBased )
|
||||
{
|
||||
if ( level._splitscreen )
|
||||
{
|
||||
if ( winner == "allies" )
|
||||
playSoundOnPlayers( game["music"]["victory_allies"], "allies" );
|
||||
else if ( winner == "axis" )
|
||||
playSoundOnPlayers( game["music"]["victory_axis"], "axis" );
|
||||
else
|
||||
playSoundOnPlayers( game["music"]["nuke_music"] );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( winner == "allies" )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["victory_allies"], "allies" );
|
||||
playSoundOnPlayers( game["music"]["defeat_axis"], "axis" );
|
||||
}
|
||||
else if ( winner == "axis" )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["victory_axis"], "axis" );
|
||||
playSoundOnPlayers( game["music"]["defeat_allies"], "allies" );
|
||||
}
|
||||
else
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["nuke_music"] );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( player in level._players )
|
||||
{
|
||||
if ( player.pers["team"] != "allies" && player.pers["team"] != "axis" )
|
||||
player playLocalSound( game["music"]["nuke_music"] );
|
||||
else if ( isDefined( winner ) && player == winner )
|
||||
player playLocalSound( game["music"]["victory_" + player.pers["team"] ] );
|
||||
else if ( !level._splitScreen )
|
||||
player playLocalSound( game["music"]["defeat_" + player.pers["team"] ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
roundWinnerDialog()
|
||||
{
|
||||
level waittill ( "round_win", winner );
|
||||
|
||||
delay = level._roundEndDelay / 4;
|
||||
if ( delay > 0 )
|
||||
wait ( delay );
|
||||
|
||||
if ( !isDefined( winner ) || isPlayer( winner ) || isDefined( level._nukeDetonated ) )
|
||||
return;
|
||||
|
||||
if ( winner == "allies" )
|
||||
{
|
||||
leaderDialog( "round_success", "allies" );
|
||||
leaderDialog( "round_failure", "axis" );
|
||||
}
|
||||
else if ( winner == "axis" )
|
||||
{
|
||||
leaderDialog( "round_success", "axis" );
|
||||
leaderDialog( "round_failure", "allies" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gameWinnerDialog()
|
||||
{
|
||||
level waittill ( "game_win", winner );
|
||||
|
||||
delay = level._postRoundTime / 2;
|
||||
if ( delay > 0 )
|
||||
wait ( delay );
|
||||
|
||||
if ( !isDefined( winner ) || isPlayer( winner ) || isDefined( level._nukeDetonated ) )
|
||||
return;
|
||||
|
||||
if ( winner == "allies" )
|
||||
{
|
||||
leaderDialog( "mission_success", "allies" );
|
||||
leaderDialog( "mission_failure", "axis" );
|
||||
}
|
||||
else if ( winner == "axis" )
|
||||
{
|
||||
leaderDialog( "mission_success", "axis" );
|
||||
leaderDialog( "mission_failure", "allies" );
|
||||
}
|
||||
else
|
||||
{
|
||||
leaderDialog( "mission_draw" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
musicController()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
|
||||
if ( !level._hardcoreMode )
|
||||
thread suspenseMusic();
|
||||
|
||||
level waittill ( "match_ending_soon", reason );
|
||||
assert( isDefined( reason ) );
|
||||
|
||||
if ( getWatchedDvar( "roundlimit" ) == 1 || game["roundsPlayed"] == (getWatchedDvar( "roundlimit" ) - 1) )
|
||||
{
|
||||
if ( !level._splitScreen )
|
||||
{
|
||||
if ( reason == "time" )
|
||||
{
|
||||
if ( level._teamBased )
|
||||
{
|
||||
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
|
||||
{
|
||||
if ( !level._hardcoreMode )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["winning_allies"], "allies" );
|
||||
playSoundOnPlayers( game["music"]["losing_axis"], "axis" );
|
||||
}
|
||||
|
||||
leaderDialog( "winning_time", "allies" );
|
||||
leaderDialog( "losing_time", "axis" );
|
||||
}
|
||||
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
|
||||
{
|
||||
if ( !level._hardcoreMode )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["winning_axis"], "axis" );
|
||||
playSoundOnPlayers( game["music"]["losing_allies"], "allies" );
|
||||
}
|
||||
|
||||
leaderDialog( "winning_time", "axis" );
|
||||
leaderDialog( "losing_time", "allies" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !level._hardcoreMode )
|
||||
playSoundOnPlayers( game["music"]["losing_time"] );
|
||||
|
||||
leaderDialog( "timesup" );
|
||||
}
|
||||
}
|
||||
else if ( reason == "score" )
|
||||
{
|
||||
if ( level._teamBased )
|
||||
{
|
||||
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
|
||||
{
|
||||
if ( !level._hardcoreMode )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["winning_allies"], "allies" );
|
||||
playSoundOnPlayers( game["music"]["losing_axis"], "axis" );
|
||||
}
|
||||
|
||||
leaderDialog( "winning_score", "allies" );
|
||||
leaderDialog( "losing_score", "axis" );
|
||||
}
|
||||
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
|
||||
{
|
||||
if ( !level._hardcoreMode )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["winning_axis"], "axis" );
|
||||
playSoundOnPlayers( game["music"]["losing_allies"], "allies" );
|
||||
}
|
||||
|
||||
leaderDialog( "winning_score", "axis" );
|
||||
leaderDialog( "losing_score", "allies" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
winningPlayer = maps\mp\gametypes\_gamescore::getHighestScoringPlayer();
|
||||
losingPlayers = maps\mp\gametypes\_gamescore::getLosingPlayers();
|
||||
excludeList[0] = winningPlayer;
|
||||
|
||||
if ( !level._hardcoreMode )
|
||||
{
|
||||
winningPlayer playLocalSound( game["music"]["winning_" + winningPlayer.pers["team"] ] );
|
||||
|
||||
foreach ( otherPlayer in level._players )
|
||||
{
|
||||
if ( otherPlayer == winningPlayer )
|
||||
continue;
|
||||
|
||||
otherPlayer playLocalSound( game["music"]["losing_" + otherPlayer.pers["team"] ] );
|
||||
}
|
||||
}
|
||||
|
||||
winningPlayer leaderDialogOnPlayer( "winning_score" );
|
||||
leaderDialogOnPlayers( "losing_score", losingPlayers );
|
||||
}
|
||||
}
|
||||
|
||||
level waittill ( "match_ending_very_soon" );
|
||||
leaderDialog( "timesup" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !level._hardcoreMode )
|
||||
playSoundOnPlayers( game["music"]["losing_allies"] );
|
||||
|
||||
leaderDialog( "timesup" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suspenseMusic()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
level endon ( "match_ending_soon" );
|
||||
|
||||
numTracks = game["music"]["suspense"].size;
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( randomFloatRange( 60, 120 ) );
|
||||
|
||||
playSoundOnPlayers( game["music"]["suspense"][randomInt(numTracks)] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finalKillcamMusic()
|
||||
{
|
||||
self waittill ( "showing_final_killcam" );
|
||||
|
||||
//self playLocalSound( game["music"]["winning"] );
|
||||
}
|
163
maps/mp/gametypes/_objpoints.gsc
Normal file
163
maps/mp/gametypes/_objpoints.gsc
Normal file
@ -0,0 +1,163 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
init()
|
||||
{
|
||||
precacheShader("objpoint_default");
|
||||
|
||||
level._objPointNames = [];
|
||||
level._objPoints = [];
|
||||
|
||||
if ( level._splitscreen )
|
||||
level._objPointSize = 15;
|
||||
else
|
||||
level._objPointSize = 8;
|
||||
|
||||
level._objpoint_alpha_default = .5;
|
||||
level._objPointScale = 1.0;
|
||||
}
|
||||
|
||||
|
||||
createTeamObjpoint( name, origin, team, shader, alpha, scale )
|
||||
{
|
||||
if( !level._multiteambased )
|
||||
{
|
||||
assert( team == "axis" || team == "allies" || team == "all" );
|
||||
}
|
||||
|
||||
objPoint = getObjPointByName( name );
|
||||
|
||||
if ( isDefined( objPoint ) )
|
||||
deleteObjPoint( objPoint );
|
||||
|
||||
if ( !isDefined( shader ) )
|
||||
shader = "objpoint_default";
|
||||
|
||||
if ( !isDefined( scale ) )
|
||||
scale = 1.0;
|
||||
|
||||
if ( team != "all" )
|
||||
objPoint = newTeamHudElem( team );
|
||||
else
|
||||
objPoint = newHudElem();
|
||||
|
||||
objPoint.name = name;
|
||||
objPoint.x = origin[0];
|
||||
objPoint.y = origin[1];
|
||||
objPoint.z = origin[2];
|
||||
objPoint.team = team;
|
||||
objPoint.isFlashing = false;
|
||||
objPoint.isShown = true;
|
||||
|
||||
objPoint setShader( shader, level._objPointSize, level._objPointSize );
|
||||
objPoint setWaypoint( true, false );
|
||||
|
||||
if ( isDefined( alpha ) )
|
||||
objPoint.alpha = alpha;
|
||||
else
|
||||
objPoint.alpha = level._objpoint_alpha_default;
|
||||
objPoint.baseAlpha = objPoint.alpha;
|
||||
|
||||
objPoint.index = level._objPointNames.size;
|
||||
level._objPoints[name] = objPoint;
|
||||
level._objPointNames[level._objPointNames.size] = name;
|
||||
|
||||
return objPoint;
|
||||
}
|
||||
|
||||
|
||||
deleteObjPoint( oldObjPoint )
|
||||
{
|
||||
assert( level._objPoints.size == level._objPointNames.size );
|
||||
|
||||
if ( level._objPoints.size == 1 )
|
||||
{
|
||||
assert( level._objPointNames[0] == oldObjPoint.name );
|
||||
assert( isDefined( level._objPoints[oldObjPoint.name] ) );
|
||||
|
||||
level._objPoints = [];
|
||||
level._objPointNames = [];
|
||||
oldObjPoint destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
newIndex = oldObjPoint.index;
|
||||
oldIndex = (level._objPointNames.size - 1);
|
||||
|
||||
objPoint = getObjPointByIndex( oldIndex );
|
||||
level._objPointNames[newIndex] = objPoint.name;
|
||||
objPoint.index = newIndex;
|
||||
|
||||
level._objPointNames[oldIndex] = undefined;
|
||||
level._objPoints[oldObjPoint.name] = undefined;
|
||||
|
||||
oldObjPoint destroy();
|
||||
}
|
||||
|
||||
|
||||
updateOrigin( origin )
|
||||
{
|
||||
if ( self.x != origin[0] )
|
||||
self.x = origin[0];
|
||||
|
||||
if ( self.y != origin[1] )
|
||||
self.y = origin[1];
|
||||
|
||||
if ( self.z != origin[2] )
|
||||
self.z = origin[2];
|
||||
}
|
||||
|
||||
|
||||
setOriginByName( name, origin )
|
||||
{
|
||||
objPoint = getObjPointByName( name );
|
||||
objPoint updateOrigin( origin );
|
||||
}
|
||||
|
||||
|
||||
getObjPointByName( name )
|
||||
{
|
||||
if ( isDefined( level._objPoints[name] ) )
|
||||
return level._objPoints[name];
|
||||
else
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getObjPointByIndex( index )
|
||||
{
|
||||
if ( isDefined( level._objPointNames[index] ) )
|
||||
return level._objPoints[level._objPointNames[index]];
|
||||
else
|
||||
return undefined;
|
||||
}
|
||||
|
||||
startFlashing()
|
||||
{
|
||||
self endon("stop_flashing_thread");
|
||||
|
||||
if ( self.isFlashing )
|
||||
return;
|
||||
|
||||
self.isFlashing = true;
|
||||
|
||||
while ( self.isFlashing )
|
||||
{
|
||||
self fadeOverTime( 0.75 );
|
||||
self.alpha = 0.35 * self.baseAlpha;
|
||||
wait ( 0.75 );
|
||||
|
||||
self fadeOverTime( 0.75 );
|
||||
self.alpha = self.baseAlpha;
|
||||
wait ( 0.75 );
|
||||
}
|
||||
|
||||
self.alpha = self.baseAlpha;
|
||||
}
|
||||
|
||||
stopFlashing()
|
||||
{
|
||||
if ( !self.isFlashing )
|
||||
return;
|
||||
|
||||
self.isFlashing = false;
|
||||
}
|
232
maps/mp/gametypes/_persistence.gsc
Normal file
232
maps/mp/gametypes/_persistence.gsc
Normal file
@ -0,0 +1,232 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level._persistentDataInfo = [];
|
||||
|
||||
maps\mp\gametypes\_class::init();
|
||||
maps\mp\gametypes\_rank::init();
|
||||
maps\mp\gametypes\_missions::init();
|
||||
maps\mp\gametypes\_playercards::init();
|
||||
|
||||
level thread updateBufferedStats();
|
||||
}
|
||||
|
||||
|
||||
initBufferedStats()
|
||||
{
|
||||
self.bufferedStats = [];
|
||||
self.bufferedStats[ "totalShots" ] = self getPlayerData( "totalShots" );
|
||||
self.bufferedStats[ "accuracy" ] = self getPlayerData( "accuracy" );
|
||||
self.bufferedStats[ "misses" ] = self getPlayerData( "misses" );
|
||||
self.bufferedStats[ "hits" ] = self getPlayerData( "hits" );
|
||||
self.bufferedStats[ "timePlayedAllies" ] = self getPlayerData( "timePlayedAllies" );
|
||||
self.bufferedStats[ "timePlayedOpfor" ] = self getPlayerData( "timePlayedOpfor" );
|
||||
self.bufferedStats[ "timePlayedOther" ] = self getPlayerData( "timePlayedOther" );
|
||||
self.bufferedStats[ "timePlayedTotal" ] = self getPlayerData( "timePlayedTotal" );
|
||||
|
||||
self.bufferedChildStats = [];
|
||||
self.bufferedChildStats[ "round" ] = [];
|
||||
self.bufferedChildStats[ "round" ][ "timePlayed" ] = self getPlayerData( "round", "timePlayed" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==========================================
|
||||
// Script persistent data functions
|
||||
// These are made for convenience, so persistent data can be tracked by strings.
|
||||
// They make use of code functions which are prototyped below.
|
||||
|
||||
/*
|
||||
=============
|
||||
statGet
|
||||
|
||||
Returns the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statGet( dataName )
|
||||
{
|
||||
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
|
||||
return self GetPlayerData( dataName );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
statSet
|
||||
|
||||
Sets the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statSet( dataName, value )
|
||||
{
|
||||
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
self SetPlayerData( dataName, value );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
statAdd
|
||||
|
||||
Adds the passed value to the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statAdd( dataName, value )
|
||||
{
|
||||
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
curValue = self GetPlayerData( dataName );
|
||||
self SetPlayerData( dataName, value + curValue );
|
||||
}
|
||||
|
||||
|
||||
statGetChild( parent, child )
|
||||
{
|
||||
return self GetPlayerData( parent, child );
|
||||
}
|
||||
|
||||
|
||||
statSetChild( parent, child, value )
|
||||
{
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
self SetPlayerData( parent, child, value );
|
||||
}
|
||||
|
||||
|
||||
statAddChild( parent, child, value )
|
||||
{
|
||||
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
curValue = self GetPlayerData( parent, child );
|
||||
self SetPlayerData( parent, child, curValue + value );
|
||||
}
|
||||
|
||||
|
||||
statGetChildBuffered( parent, child )
|
||||
{
|
||||
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
|
||||
|
||||
return self.bufferedChildStats[ parent ][ child ];
|
||||
}
|
||||
|
||||
|
||||
statSetChildBuffered( parent, child, value )
|
||||
{
|
||||
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
self.bufferedChildStats[ parent ][ child ] = value;
|
||||
}
|
||||
|
||||
|
||||
statAddChildBuffered( parent, child, value )
|
||||
{
|
||||
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
curValue = statGetChildBuffered( parent, child );
|
||||
statSetChildBuffered( parent, child, curValue + value );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
statGetBuffered
|
||||
|
||||
Returns the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statGetBuffered( dataName )
|
||||
{
|
||||
assert( isDefined( self.bufferedStats[ dataName ] ) );
|
||||
|
||||
return self.bufferedStats[ dataName ];
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
statSet
|
||||
|
||||
Sets the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statSetBuffered( dataName, value )
|
||||
{
|
||||
assert( isDefined( self.bufferedStats[ dataName ] ) );
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
self.bufferedStats[ dataName ] = value;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
statAdd
|
||||
|
||||
Adds the passed value to the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statAddBuffered( dataName, value )
|
||||
{
|
||||
assert( isDefined( self.bufferedStats[ dataName ] ) );
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
curValue = statGetBuffered( dataName );
|
||||
statSetBuffered( dataName, curValue + value );
|
||||
}
|
||||
|
||||
|
||||
updateBufferedStats()
|
||||
{
|
||||
// give the first player time to connect
|
||||
wait ( 0.15 );
|
||||
|
||||
nextToUpdate = 0;
|
||||
while ( !level._gameEnded )
|
||||
{
|
||||
nextToUpdate++;
|
||||
if ( nextToUpdate >= level._players.size )
|
||||
nextToUpdate = 0;
|
||||
|
||||
if ( isDefined( level._players[nextToUpdate] ) )
|
||||
level._players[nextToUpdate] writeBufferedStats();
|
||||
|
||||
wait ( 2.0 );
|
||||
}
|
||||
|
||||
foreach ( player in level._players )
|
||||
player writeBufferedStats();
|
||||
}
|
||||
|
||||
|
||||
writeBufferedStats()
|
||||
{
|
||||
foreach ( statName, statVal in self.bufferedStats )
|
||||
{
|
||||
self setPlayerData( statName, statVal );
|
||||
}
|
||||
|
||||
foreach ( statName, statVal in self.bufferedChildStats )
|
||||
{
|
||||
foreach ( childStatName, childStatVal in statVal )
|
||||
self setPlayerData( statName, childStatName, childStatVal );
|
||||
}
|
||||
}
|
29
maps/mp/gametypes/_playercards.gsc
Normal file
29
maps/mp/gametypes/_playercards.gsc
Normal file
@ -0,0 +1,29 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
|
||||
init()
|
||||
{
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
//@NOTE: Should we make sure they're really unlocked before setting them? Catch cheaters...
|
||||
// e.g. isItemUnlocked( iconHandle )
|
||||
|
||||
iconHandle = player maps\mp\gametypes\_persistence::statGet( "cardIcon" );
|
||||
player SetCardIcon( iconHandle );
|
||||
|
||||
titleHandle = player maps\mp\gametypes\_persistence::statGet( "cardTitle" );
|
||||
player SetCardTitle( titleHandle );
|
||||
|
||||
nameplateHandle = player maps\mp\gametypes\_persistence::statGet( "cardNameplate" );
|
||||
player SetCardNameplate( nameplateHandle );
|
||||
}
|
||||
}
|
1595
maps/mp/gametypes/_playerlogic.gsc
Normal file
1595
maps/mp/gametypes/_playerlogic.gsc
Normal file
File diff suppressed because it is too large
Load Diff
270
maps/mp/gametypes/_quickmessages.gsc
Normal file
270
maps/mp/gametypes/_quickmessages.gsc
Normal file
@ -0,0 +1,270 @@
|
||||
init()
|
||||
{
|
||||
game["menu_quickcommands"] = "quickcommands";
|
||||
game["menu_quickstatements"] = "quickstatements";
|
||||
game["menu_quickresponses"] = "quickresponses";
|
||||
|
||||
precacheMenu(game["menu_quickcommands"]);
|
||||
precacheMenu(game["menu_quickstatements"]);
|
||||
precacheMenu(game["menu_quickresponses"]);
|
||||
precacheHeadIcon("talkingicon");
|
||||
|
||||
precacheString( &"QUICKMESSAGE_FOLLOW_ME" );
|
||||
precacheString( &"QUICKMESSAGE_MOVE_IN" );
|
||||
precacheString( &"QUICKMESSAGE_FALL_BACK" );
|
||||
precacheString( &"QUICKMESSAGE_SUPPRESSING_FIRE" );
|
||||
precacheString( &"QUICKMESSAGE_ATTACK_LEFT_FLANK" );
|
||||
precacheString( &"QUICKMESSAGE_ATTACK_RIGHT_FLANK" );
|
||||
precacheString( &"QUICKMESSAGE_HOLD_THIS_POSITION" );
|
||||
precacheString( &"QUICKMESSAGE_REGROUP" );
|
||||
precacheString( &"QUICKMESSAGE_ENEMY_SPOTTED" );
|
||||
precacheString( &"QUICKMESSAGE_ENEMIES_SPOTTED" );
|
||||
precacheString( &"QUICKMESSAGE_IM_IN_POSITION" );
|
||||
precacheString( &"QUICKMESSAGE_AREA_SECURE" );
|
||||
precacheString( &"QUICKMESSAGE_GRENADE" );
|
||||
precacheString( &"QUICKMESSAGE_SNIPER" );
|
||||
precacheString( &"QUICKMESSAGE_NEED_REINFORCEMENTS" );
|
||||
precacheString( &"QUICKMESSAGE_HOLD_YOUR_FIRE" );
|
||||
precacheString( &"QUICKMESSAGE_YES_SIR" );
|
||||
precacheString( &"QUICKMESSAGE_NO_SIR" );
|
||||
precacheString( &"QUICKMESSAGE_IM_ON_MY_WAY" );
|
||||
precacheString( &"QUICKMESSAGE_SORRY" );
|
||||
precacheString( &"QUICKMESSAGE_GREAT_SHOT" );
|
||||
precacheString( &"QUICKMESSAGE_TOOK_LONG_ENOUGH" );
|
||||
precacheString( &"QUICKMESSAGE_ARE_YOU_CRAZY" );
|
||||
precacheString( &"QUICKMESSAGE_WATCH_SIX" );
|
||||
precacheString( &"QUICKMESSAGE_COME_ON" );
|
||||
}
|
||||
|
||||
quickcommands(response)
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
|
||||
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
|
||||
return;
|
||||
|
||||
self.spamdelay = true;
|
||||
|
||||
switch(response)
|
||||
{
|
||||
case "1":
|
||||
soundalias = "mp_cmd_followme";
|
||||
saytext = &"QUICKMESSAGE_FOLLOW_ME";
|
||||
//saytext = "Follow Me!";
|
||||
break;
|
||||
|
||||
case "2":
|
||||
soundalias = "mp_cmd_movein";
|
||||
saytext = &"QUICKMESSAGE_MOVE_IN";
|
||||
//saytext = "Move in!";
|
||||
break;
|
||||
|
||||
case "3":
|
||||
soundalias = "mp_cmd_fallback";
|
||||
saytext = &"QUICKMESSAGE_FALL_BACK";
|
||||
//saytext = "Fall back!";
|
||||
break;
|
||||
|
||||
case "4":
|
||||
soundalias = "mp_cmd_suppressfire";
|
||||
saytext = &"QUICKMESSAGE_SUPPRESSING_FIRE";
|
||||
//saytext = "Suppressing fire!";
|
||||
break;
|
||||
|
||||
case "5":
|
||||
soundalias = "mp_cmd_attackleftflank";
|
||||
saytext = &"QUICKMESSAGE_ATTACK_LEFT_FLANK";
|
||||
//saytext = "Attack left flank!";
|
||||
break;
|
||||
|
||||
case "6":
|
||||
soundalias = "mp_cmd_attackrightflank";
|
||||
saytext = &"QUICKMESSAGE_ATTACK_RIGHT_FLANK";
|
||||
//saytext = "Attack right flank!";
|
||||
break;
|
||||
|
||||
case "7":
|
||||
soundalias = "mp_cmd_holdposition";
|
||||
saytext = &"QUICKMESSAGE_HOLD_THIS_POSITION";
|
||||
//saytext = "Hold this position!";
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(response == "8");
|
||||
soundalias = "mp_cmd_regroup";
|
||||
saytext = &"QUICKMESSAGE_REGROUP";
|
||||
//saytext = "Regroup!";
|
||||
break;
|
||||
}
|
||||
|
||||
self saveHeadIcon();
|
||||
self doQuickMessage(soundalias, saytext);
|
||||
|
||||
wait 2;
|
||||
self.spamdelay = undefined;
|
||||
self restoreHeadIcon();
|
||||
}
|
||||
|
||||
quickstatements(response)
|
||||
{
|
||||
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
|
||||
return;
|
||||
|
||||
self.spamdelay = true;
|
||||
|
||||
switch(response)
|
||||
{
|
||||
case "1":
|
||||
soundalias = "mp_stm_enemyspotted";
|
||||
saytext = &"QUICKMESSAGE_ENEMY_SPOTTED";
|
||||
//saytext = "Enemy spotted!";
|
||||
break;
|
||||
|
||||
case "2":
|
||||
soundalias = "mp_stm_enemiesspotted";
|
||||
saytext = &"QUICKMESSAGE_ENEMIES_SPOTTED";
|
||||
//saytext = "Enemy down!";
|
||||
break;
|
||||
|
||||
case "3":
|
||||
soundalias = "mp_stm_iminposition";
|
||||
saytext = &"QUICKMESSAGE_IM_IN_POSITION";
|
||||
//saytext = "I'm in position.";
|
||||
break;
|
||||
|
||||
case "4":
|
||||
soundalias = "mp_stm_areasecure";
|
||||
saytext = &"QUICKMESSAGE_AREA_SECURE";
|
||||
//saytext = "Area secure!";
|
||||
break;
|
||||
|
||||
case "5":
|
||||
soundalias = "mp_stm_watchsix";
|
||||
saytext = &"QUICKMESSAGE_WATCH_SIX";
|
||||
//saytext = "Grenade!";
|
||||
break;
|
||||
|
||||
case "6":
|
||||
soundalias = "mp_stm_sniper";
|
||||
saytext = &"QUICKMESSAGE_SNIPER";
|
||||
//saytext = "Sniper!";
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(response == "7");
|
||||
soundalias = "mp_stm_needreinforcements";
|
||||
saytext = &"QUICKMESSAGE_NEED_REINFORCEMENTS";
|
||||
//saytext = "Need reinforcements!";
|
||||
break;
|
||||
}
|
||||
|
||||
self saveHeadIcon();
|
||||
self doQuickMessage(soundalias, saytext);
|
||||
|
||||
wait 2;
|
||||
self.spamdelay = undefined;
|
||||
self restoreHeadIcon();
|
||||
}
|
||||
|
||||
quickresponses(response)
|
||||
{
|
||||
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
|
||||
return;
|
||||
|
||||
self.spamdelay = true;
|
||||
|
||||
switch(response)
|
||||
{
|
||||
case "1":
|
||||
soundalias = "mp_rsp_yessir";
|
||||
saytext = &"QUICKMESSAGE_YES_SIR";
|
||||
//saytext = "Yes Sir!";
|
||||
break;
|
||||
|
||||
case "2":
|
||||
soundalias = "mp_rsp_nosir";
|
||||
saytext = &"QUICKMESSAGE_NO_SIR";
|
||||
//saytext = "No Sir!";
|
||||
break;
|
||||
|
||||
case "3":
|
||||
soundalias = "mp_rsp_onmyway";
|
||||
saytext = &"QUICKMESSAGE_IM_ON_MY_WAY";
|
||||
//saytext = "On my way.";
|
||||
break;
|
||||
|
||||
case "4":
|
||||
soundalias = "mp_rsp_sorry";
|
||||
saytext = &"QUICKMESSAGE_SORRY";
|
||||
//saytext = "Sorry.";
|
||||
break;
|
||||
|
||||
case "5":
|
||||
soundalias = "mp_rsp_greatshot";
|
||||
saytext = &"QUICKMESSAGE_GREAT_SHOT";
|
||||
//saytext = "Great shot!";
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(response == "6");
|
||||
soundalias = "mp_rsp_comeon";
|
||||
saytext = &"QUICKMESSAGE_COME_ON";
|
||||
//saytext = "Took long enough!";
|
||||
break;
|
||||
}
|
||||
|
||||
self saveHeadIcon();
|
||||
self doQuickMessage(soundalias, saytext);
|
||||
|
||||
wait 2;
|
||||
self.spamdelay = undefined;
|
||||
self restoreHeadIcon();
|
||||
}
|
||||
|
||||
doQuickMessage( soundalias, saytext )
|
||||
{
|
||||
if(self.sessionstate != "playing")
|
||||
return;
|
||||
|
||||
prefix = maps\mp\gametypes\_teams::getTeamVoicePrefix( self.team );
|
||||
|
||||
if(isdefined(level._QuickMessageToAll) && level._QuickMessageToAll)
|
||||
{
|
||||
self.headiconteam = "none";
|
||||
self.headicon = "talkingicon";
|
||||
|
||||
self playSound( prefix+soundalias );
|
||||
self sayAll(saytext);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(self.sessionteam == "allies")
|
||||
self.headiconteam = "allies";
|
||||
else if(self.sessionteam == "axis")
|
||||
self.headiconteam = "axis";
|
||||
|
||||
self.headicon = "talkingicon";
|
||||
|
||||
self playSound( prefix+soundalias );
|
||||
self sayTeam( saytext );
|
||||
self pingPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
saveHeadIcon()
|
||||
{
|
||||
if(isdefined(self.headicon))
|
||||
self.oldheadicon = self.headicon;
|
||||
|
||||
if(isdefined(self.headiconteam))
|
||||
self.oldheadiconteam = self.headiconteam;
|
||||
}
|
||||
|
||||
restoreHeadIcon()
|
||||
{
|
||||
if(isdefined(self.oldheadicon))
|
||||
self.headicon = self.oldheadicon;
|
||||
|
||||
if(isdefined(self.oldheadiconteam))
|
||||
self.headiconteam = self.oldheadiconteam;
|
||||
}
|
799
maps/mp/gametypes/_rank.gsc
Normal file
799
maps/mp/gametypes/_rank.gsc
Normal file
@ -0,0 +1,799 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
//Those are the fraction of total possible assist points that is given to the player
|
||||
//For example, with level 1 assist, the player is given 25% of the total possible assist points
|
||||
LEVEL_1_ASSIST = 0.25;
|
||||
LEVEL_2_ASSIST = 0.50;
|
||||
LEVEL_3_ASSIST = 0.75;
|
||||
GRENADE_ASSIST = 0.625;
|
||||
|
||||
init()
|
||||
{
|
||||
level._scoreInfo = [];
|
||||
level._xpScale = getDvarInt( "scr_xpscale" );
|
||||
|
||||
if ( level._xpScale > 4 || level._xpScale < 0)
|
||||
exitLevel( false );
|
||||
|
||||
level._xpScale = min( level._xpScale, 4 );
|
||||
level._xpScale = max( level._xpScale, 0 );
|
||||
|
||||
level._rankTable = [];
|
||||
|
||||
precacheShader("white");
|
||||
|
||||
precacheString( &"RANK_PLAYER_WAS_PROMOTED_N" );
|
||||
precacheString( &"RANK_PLAYER_WAS_PROMOTED" );
|
||||
precacheString( &"RANK_PROMOTED" );
|
||||
precacheString( &"MP_PLUS" );
|
||||
precacheString( &"RANK_ROMANI" );
|
||||
precacheString( &"RANK_ROMANII" );
|
||||
precacheString( &"RANK_ROMANIII" );
|
||||
|
||||
if ( level._teamBased )
|
||||
{
|
||||
registerScoreInfo( "kill", 100 );
|
||||
registerScoreInfo( "headshot", 100 );
|
||||
registerScoreInfo( "assist", 80 );
|
||||
registerScoreInfo( "suicide", 0 );
|
||||
registerScoreInfo( "teamkill", 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
registerScoreInfo( "kill", 50 );
|
||||
registerScoreInfo( "headshot", 50 );
|
||||
registerScoreInfo( "assist", 0 );
|
||||
registerScoreInfo( "suicide", 0 );
|
||||
registerScoreInfo( "teamkill", 0 );
|
||||
}
|
||||
|
||||
registerScoreInfo( "win", 1 );
|
||||
registerScoreInfo( "loss", 0.5 );
|
||||
registerScoreInfo( "tie", 0.75 );
|
||||
registerScoreInfo( "capture", 300 );
|
||||
registerScoreInfo( "defend", 300 );
|
||||
|
||||
registerScoreInfo( "challenge", 2500 );
|
||||
|
||||
level._maxRank = int(tableLookup( "mp/rankTable.csv", 0, "maxrank", 1 ));
|
||||
level._maxPrestige = int(tableLookup( "mp/rankIconTable.csv", 0, "maxprestige", 1 ));
|
||||
|
||||
pId = 0;
|
||||
rId = 0;
|
||||
for ( pId = 0; pId <= level._maxPrestige; pId++ )
|
||||
{
|
||||
for ( rId = 0; rId <= level._maxRank; rId++ )
|
||||
precacheShader( tableLookup( "mp/rankIconTable.csv", 0, rId, pId+1 ) );
|
||||
}
|
||||
|
||||
rankId = 0;
|
||||
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
|
||||
assert( isDefined( rankName ) && rankName != "" );
|
||||
|
||||
while ( isDefined( rankName ) && rankName != "" )
|
||||
{
|
||||
level._rankTable[rankId][1] = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
|
||||
level._rankTable[rankId][2] = tableLookup( "mp/ranktable.csv", 0, rankId, 2 );
|
||||
level._rankTable[rankId][3] = tableLookup( "mp/ranktable.csv", 0, rankId, 3 );
|
||||
level._rankTable[rankId][7] = tableLookup( "mp/ranktable.csv", 0, rankId, 7 );
|
||||
|
||||
precacheString( tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 ) );
|
||||
|
||||
rankId++;
|
||||
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
|
||||
}
|
||||
|
||||
maps\mp\gametypes\_missions::buildChallegeInfo();
|
||||
|
||||
level thread patientZeroWaiter();
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
patientZeroWaiter()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
while ( !isDefined( level._players ) || !level._players.size )
|
||||
wait ( 0.05 );
|
||||
|
||||
if ( !matchMakingGame() )
|
||||
{
|
||||
if ( (getDvar( "mapname" ) == "mp_rust" && randomInt( 1000 ) == 999) )
|
||||
level._patientZeroName = level._players[0].name;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( getDvar( "scr_patientZero" ) != "" )
|
||||
level._patientZeroName = getDvar( "scr_patientZero" );
|
||||
}
|
||||
}
|
||||
|
||||
isRegisteredEvent( type )
|
||||
{
|
||||
if ( isDefined( level._scoreInfo[type] ) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
registerScoreInfo( type, value )
|
||||
{
|
||||
level._scoreInfo[type]["value"] = value;
|
||||
}
|
||||
|
||||
|
||||
getScoreInfoValue( type )
|
||||
{
|
||||
assist_scalar = 1;
|
||||
|
||||
if ( IsSubStr ( type, "assist" ))
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case "assist_level_1":
|
||||
assist_scalar = LEVEL_1_ASSIST;
|
||||
break;
|
||||
case "assist_level_2":
|
||||
assist_scalar = LEVEL_2_ASSIST;
|
||||
break;
|
||||
case "assist_grenade":
|
||||
assist_scalar = GRENADE_ASSIST;
|
||||
break;
|
||||
case "assist_level_3":
|
||||
assist_scalar = LEVEL_3_ASSIST;
|
||||
break;
|
||||
}
|
||||
type = "assist";
|
||||
}
|
||||
|
||||
overrideDvar = "scr_" + level._gameType + "_score_" + type;
|
||||
if ( getDvar( overrideDvar ) != "" )
|
||||
{
|
||||
return getDvarInt( overrideDvar );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( Int ( floor (level._scoreInfo[type]["value"] * assist_scalar )));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getScoreInfoLabel( type )
|
||||
{
|
||||
return ( level._scoreInfo[type]["label"] );
|
||||
}
|
||||
|
||||
|
||||
getRankInfoMinXP( rankId )
|
||||
{
|
||||
return int(level._rankTable[rankId][2]);
|
||||
}
|
||||
|
||||
|
||||
getRankInfoXPAmt( rankId )
|
||||
{
|
||||
return int(level._rankTable[rankId][3]);
|
||||
}
|
||||
|
||||
|
||||
getRankInfoMaxXp( rankId )
|
||||
{
|
||||
return int(level._rankTable[rankId][7]);
|
||||
}
|
||||
|
||||
|
||||
getRankInfoFull( rankId )
|
||||
{
|
||||
return tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 );
|
||||
}
|
||||
|
||||
|
||||
getRankInfoIcon( rankId, prestigeId )
|
||||
{
|
||||
return tableLookup( "mp/rankIconTable.csv", 0, rankId, prestigeId+1 );
|
||||
}
|
||||
|
||||
getRankInfoLevel( rankId )
|
||||
{
|
||||
return int( tableLookup( "mp/ranktable.csv", 0, rankId, 13 ) );
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
/#
|
||||
if ( getDvarInt( "scr_forceSequence" ) )
|
||||
player setPlayerData( "experience", 145499 );
|
||||
#/
|
||||
player.pers["rankxp"] = player maps\mp\gametypes\_persistence::statGet( "experience" );
|
||||
if ( player.pers["rankxp"] < 0 ) // paranoid defensive
|
||||
player.pers["rankxp"] = 0;
|
||||
player.pers["rankxpstart"] = player.pers["rankxp"]; // let's remember what XP we started with.
|
||||
|
||||
rankId = player getRankForXp( player getRankXP() );
|
||||
player.pers[ "rank" ] = rankId;
|
||||
player.pers[ "participation" ] = 0;
|
||||
|
||||
player.xpUpdateTotal = 0;
|
||||
player.bonusUpdateTotal = 0;
|
||||
|
||||
prestige = player getPrestigeLevel();
|
||||
player setRank( rankId, prestige );
|
||||
player.pers["prestige"] = prestige;
|
||||
|
||||
player.postGamePromotion = false;
|
||||
if ( !isDefined( player.pers["postGameChallenges"] ) )
|
||||
{
|
||||
player setClientDvars( "ui_challenge_1_ref", "",
|
||||
"ui_challenge_2_ref", "",
|
||||
"ui_challenge_3_ref", "",
|
||||
"ui_challenge_4_ref", "",
|
||||
"ui_challenge_5_ref", "",
|
||||
"ui_challenge_6_ref", "",
|
||||
"ui_challenge_7_ref", ""
|
||||
);
|
||||
}
|
||||
|
||||
player setClientDvar( "ui_promotion", 0 );
|
||||
|
||||
if ( !isDefined( player.pers["summary"] ) )
|
||||
{
|
||||
player.pers["summary"] = [];
|
||||
player.pers["summary"]["xp"] = 0;
|
||||
player.pers["summary"]["score"] = 0;
|
||||
player.pers["summary"]["challenge"] = 0;
|
||||
player.pers["summary"]["match"] = 0;
|
||||
player.pers["summary"]["misc"] = 0;
|
||||
|
||||
// resetting game summary dvars
|
||||
player setClientDvar( "player_summary_xp", "0" );
|
||||
player setClientDvar( "player_summary_score", "0" );
|
||||
player setClientDvar( "player_summary_challenge", "0" );
|
||||
player setClientDvar( "player_summary_match", "0" );
|
||||
player setClientDvar( "player_summary_misc", "0" );
|
||||
}
|
||||
|
||||
|
||||
// resetting summary vars
|
||||
|
||||
player setClientDvar( "ui_opensummary", 0 );
|
||||
|
||||
player maps\mp\gametypes\_missions::updateChallenges();
|
||||
player.explosiveKills[0] = 0;
|
||||
player.xpGains = [];
|
||||
|
||||
player.hud_xpEventPopup = player createXpEventPopup();
|
||||
|
||||
player.hud_scorePopup = newClientHudElem( player );
|
||||
player.hud_scorePopup.horzAlign = "center";
|
||||
player.hud_scorePopup.vertAlign = "middle";
|
||||
player.hud_scorePopup.alignX = "center";
|
||||
player.hud_scorePopup.alignY = "middle";
|
||||
player.hud_scorePopup.x = 0;
|
||||
if ( level._splitScreen )
|
||||
player.hud_scorePopup.y = -40;
|
||||
else
|
||||
player.hud_scorePopup.y = -60;
|
||||
player.hud_scorePopup.font = "hudbig";
|
||||
player.hud_scorePopup.fontscale = 0.75;
|
||||
player.hud_scorePopup.archived = false;
|
||||
player.hud_scorePopup.color = (0.5,0.5,0.5);
|
||||
player.hud_scorePopup.sort = 10000;
|
||||
player.hud_scorePopup maps\mp\gametypes\_hud::fontPulseInit( 3.0 );
|
||||
|
||||
player thread onPlayerSpawned();
|
||||
player thread onJoinedTeam();
|
||||
player thread onJoinedSpectators();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onJoinedTeam()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "joined_team" );
|
||||
self thread removeRankHUD();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onJoinedSpectators()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "joined_spectators" );
|
||||
self thread removeRankHUD();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("spawned_player");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
roundUp( floatVal )
|
||||
{
|
||||
if ( int( floatVal ) != floatVal )
|
||||
return int( floatVal+1 );
|
||||
else
|
||||
return int( floatVal );
|
||||
}
|
||||
|
||||
|
||||
giveRankXP( type, value )
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
lootType = "none";
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
if( level._multiTeamBased )
|
||||
{
|
||||
numteams = 0;
|
||||
for( i = 0; i < level._teamNameList.size; i++ )
|
||||
{
|
||||
if( level._teamCount[level._teamNameList[i]] )
|
||||
{
|
||||
numteams = numteams + 1;
|
||||
}
|
||||
}
|
||||
if( numteams < 2 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ( level._teamBased && (!level._teamCount["allies"] || !level._teamCount["axis"]) )
|
||||
return;
|
||||
else if ( !level._teamBased && (level._teamCount["allies"] + level._teamCount["axis"] < 2) )
|
||||
return;
|
||||
|
||||
if ( !isDefined( value ) )
|
||||
value = getScoreInfoValue( type );
|
||||
|
||||
if ( !isDefined( self.xpGains[type] ) )
|
||||
self.xpGains[type] = 0;
|
||||
|
||||
momentumBonus = 0;
|
||||
gotRestXP = false;
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case "kill":
|
||||
case "headshot":
|
||||
case "shield_damage":
|
||||
value *= self.xpScaler;
|
||||
case "assist":
|
||||
case "suicide":
|
||||
case "teamkill":
|
||||
case "capture":
|
||||
case "defend":
|
||||
case "return":
|
||||
case "pickup":
|
||||
case "assault":
|
||||
case "plant":
|
||||
case "destroy":
|
||||
case "save":
|
||||
case "defuse":
|
||||
case "escortcheckpoint":
|
||||
if ( getGametypeNumLives() > 0 )
|
||||
{
|
||||
multiplier = max(1,int( 10/getGametypeNumLives() ));
|
||||
value = int(value * multiplier);
|
||||
}
|
||||
|
||||
value = int( value * level._xpScale );
|
||||
|
||||
restXPAwarded = getRestXPAward( value );
|
||||
value += restXPAwarded;
|
||||
if ( restXPAwarded > 0 )
|
||||
{
|
||||
if ( isLastRestXPAward( value ) )
|
||||
thread maps\mp\gametypes\_hud_message::splashNotify( "rested_done" );
|
||||
|
||||
gotRestXP = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !gotRestXP )
|
||||
{
|
||||
// if we didn't get rest XP for this type, we push the rest XP goal ahead so we didn't waste it
|
||||
if ( self getPlayerData( "restXPGoal" ) > self getRankXP() )
|
||||
self setPlayerData( "restXPGoal", self getPlayerData( "restXPGoal" ) + value );
|
||||
}
|
||||
|
||||
if( getDvarInt( "prototype_adrenaline_enabled" ) == 1 )
|
||||
{
|
||||
value *= self maps\mp\_adrenaline::adrenalineGetXPMultiplier();
|
||||
self maps\mp\_adrenaline::adrenalineSetXPEarned();
|
||||
}
|
||||
|
||||
oldxp = self getRankXP();
|
||||
self.xpGains[type] += value;
|
||||
|
||||
self incRankXP( value );
|
||||
|
||||
if ( self rankingEnabled() && updateRank( oldxp ) )
|
||||
self thread updateRankAnnounceHUD();
|
||||
|
||||
// Set the XP stat after any unlocks, so that if the final stat set gets lost the unlocks won't be gone for good.
|
||||
self syncXPStat();
|
||||
|
||||
if ( !level._hardcoreMode )
|
||||
{
|
||||
if ( type == "teamkill" )
|
||||
{
|
||||
self thread scorePopup( 0 - getScoreInfoValue( "kill" ), 0, (1,0,0), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
color = (1,1,0.5);
|
||||
if ( gotRestXP )
|
||||
color = (1,.65,0);
|
||||
self thread scorePopup( value, momentumBonus, color, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case "kill":
|
||||
case "headshot":
|
||||
case "suicide":
|
||||
case "teamkill":
|
||||
case "assist":
|
||||
case "capture":
|
||||
case "defend":
|
||||
case "return":
|
||||
case "pickup":
|
||||
case "assault":
|
||||
case "plant":
|
||||
case "defuse":
|
||||
self.pers["summary"]["score"] += value;
|
||||
self.pers["summary"]["xp"] += value;
|
||||
break;
|
||||
|
||||
case "win":
|
||||
case "loss":
|
||||
case "tie":
|
||||
self.pers["summary"]["match"] += value;
|
||||
self.pers["summary"]["xp"] += value;
|
||||
break;
|
||||
|
||||
case "challenge":
|
||||
self.pers["summary"]["challenge"] += value;
|
||||
self.pers["summary"]["xp"] += value;
|
||||
break;
|
||||
|
||||
default:
|
||||
self.pers["summary"]["misc"] += value; //keeps track of ungrouped match xp reward
|
||||
self.pers["summary"]["match"] += value;
|
||||
self.pers["summary"]["xp"] += value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
updateRank( oldxp )
|
||||
{
|
||||
newRankId = self getRank();
|
||||
if ( newRankId == self.pers["rank"] )
|
||||
return false;
|
||||
|
||||
oldRank = self.pers["rank"];
|
||||
rankId = self.pers["rank"];
|
||||
self.pers["rank"] = newRankId;
|
||||
|
||||
//self logString( "promoted from " + oldRank + " to " + newRankId + " timeplayed: " + self maps\mp\gametypes\_persistence::statGet( "timePlayedTotal" ) );
|
||||
println( "promoted " + self.name + " from rank " + oldRank + " to " + newRankId + ". Experience went from " + oldxp + " to " + self getRankXP() + "." );
|
||||
|
||||
self setRank( newRankId );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
updateRankAnnounceHUD()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
self notify("update_rank");
|
||||
self endon("update_rank");
|
||||
|
||||
team = self.pers["team"];
|
||||
if ( !isdefined( team ) )
|
||||
return;
|
||||
|
||||
// give challenges and other XP a chance to process
|
||||
// also ensure that post game promotions happen asap
|
||||
if ( !levelFlag( "game_over" ) )
|
||||
level waittill_notify_or_timeout( "game_over", 0.25 );
|
||||
|
||||
|
||||
newRankName = self getRankInfoFull( self.pers["rank"] );
|
||||
rank_char = level._rankTable[self.pers["rank"]][1];
|
||||
subRank = int(rank_char[rank_char.size-1]);
|
||||
|
||||
thread maps\mp\gametypes\_hud_message::promotionSplashNotify();
|
||||
|
||||
if ( subRank > 1 )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < level._players.size; i++ )
|
||||
{
|
||||
player = level._players[i];
|
||||
playerteam = player.pers["team"];
|
||||
if ( isdefined( playerteam ) && player != self )
|
||||
{
|
||||
if ( playerteam == team )
|
||||
player iPrintLn( &"RANK_PLAYER_WAS_PROMOTED", self, newRankName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
endGameUpdate()
|
||||
{
|
||||
player = self;
|
||||
}
|
||||
|
||||
|
||||
scorePopup( amount, bonus, hudColor, glowAlpha )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "joined_team" );
|
||||
self endon( "joined_spectators" );
|
||||
|
||||
if ( amount == 0 )
|
||||
return;
|
||||
|
||||
self notify( "scorePopup" );
|
||||
self endon( "scorePopup" );
|
||||
|
||||
self.xpUpdateTotal += amount;
|
||||
self.bonusUpdateTotal += bonus;
|
||||
|
||||
wait ( 0.05 );
|
||||
|
||||
if ( self.xpUpdateTotal < 0 )
|
||||
self.hud_scorePopup.label = &"";
|
||||
else
|
||||
self.hud_scorePopup.label = &"MP_PLUS";
|
||||
|
||||
self.hud_scorePopup.color = hudColor;
|
||||
self.hud_scorePopup.glowColor = hudColor;
|
||||
self.hud_scorePopup.glowAlpha = glowAlpha;
|
||||
|
||||
self.hud_scorePopup setValue(self.xpUpdateTotal);
|
||||
self.hud_scorePopup.alpha = 0.85;
|
||||
self.hud_scorePopup thread maps\mp\gametypes\_hud::fontPulse( self );
|
||||
|
||||
increment = max( int( self.bonusUpdateTotal / 20 ), 1 );
|
||||
|
||||
if ( self.bonusUpdateTotal )
|
||||
{
|
||||
while ( self.bonusUpdateTotal > 0 )
|
||||
{
|
||||
self.xpUpdateTotal += min( self.bonusUpdateTotal, increment );
|
||||
self.bonusUpdateTotal -= min( self.bonusUpdateTotal, increment );
|
||||
|
||||
self.hud_scorePopup setValue( self.xpUpdateTotal );
|
||||
|
||||
wait ( 0.05 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wait ( 1.0 );
|
||||
}
|
||||
|
||||
self.hud_scorePopup fadeOverTime( 0.75 );
|
||||
self.hud_scorePopup.alpha = 0;
|
||||
|
||||
self.xpUpdateTotal = 0;
|
||||
}
|
||||
|
||||
removeRankHUD()
|
||||
{
|
||||
self.hud_scorePopup.alpha = 0;
|
||||
}
|
||||
|
||||
getRank()
|
||||
{
|
||||
rankXp = self.pers["rankxp"];
|
||||
rankId = self.pers["rank"];
|
||||
|
||||
if ( rankXp < (getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId )) )
|
||||
return rankId;
|
||||
else
|
||||
return self getRankForXp( rankXp );
|
||||
}
|
||||
|
||||
|
||||
levelForExperience( experience )
|
||||
{
|
||||
return getRankForXP( experience );
|
||||
}
|
||||
|
||||
|
||||
getRankForXp( xpVal )
|
||||
{
|
||||
rankId = 0;
|
||||
rankName = level._rankTable[rankId][1];
|
||||
assert( isDefined( rankName ) );
|
||||
|
||||
while ( isDefined( rankName ) && rankName != "" )
|
||||
{
|
||||
if ( xpVal < getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId ) )
|
||||
return rankId;
|
||||
|
||||
rankId++;
|
||||
if ( isDefined( level._rankTable[rankId] ) )
|
||||
rankName = level._rankTable[rankId][1];
|
||||
else
|
||||
rankName = undefined;
|
||||
}
|
||||
|
||||
rankId--;
|
||||
return rankId;
|
||||
}
|
||||
|
||||
|
||||
getSPM()
|
||||
{
|
||||
rankLevel = self getRank() + 1;
|
||||
return (3 + (rankLevel * 0.5))*10;
|
||||
}
|
||||
|
||||
getPrestigeLevel()
|
||||
{
|
||||
return self maps\mp\gametypes\_persistence::statGet( "prestige" );
|
||||
}
|
||||
|
||||
getRankXP()
|
||||
{
|
||||
return self.pers["rankxp"];
|
||||
}
|
||||
getRankXPStart()
|
||||
{
|
||||
return self.pers["rankxpstart"];
|
||||
}
|
||||
|
||||
incRankXP( amount )
|
||||
{
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
if ( isDefined( self.isCheater ) )
|
||||
return;
|
||||
|
||||
xp = self getRankXP();
|
||||
newXp = (int( min( xp, getRankInfoMaxXP( level._maxRank ) ) ) + amount);
|
||||
|
||||
if ( self.pers["rank"] == level._maxRank && newXp >= getRankInfoMaxXP( level._maxRank ) )
|
||||
newXp = getRankInfoMaxXP( level._maxRank );
|
||||
|
||||
self.pers["rankxp"] = newXp;
|
||||
}
|
||||
|
||||
getRestXPAward( baseXP )
|
||||
{
|
||||
if ( !getdvarint( "scr_restxp_enable" ) )
|
||||
return 0;
|
||||
|
||||
restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
|
||||
|
||||
wantGiveRestXP = int(baseXP * restXPAwardRate);
|
||||
mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
|
||||
|
||||
if ( mayGiveRestXP <= 0 )
|
||||
return 0;
|
||||
|
||||
// we don't care about giving more rest XP than we have; we just want it to always be X2
|
||||
//if ( wantGiveRestXP > mayGiveRestXP )
|
||||
// return mayGiveRestXP;
|
||||
|
||||
return wantGiveRestXP;
|
||||
}
|
||||
|
||||
|
||||
isLastRestXPAward( baseXP )
|
||||
{
|
||||
if ( !getdvarint( "scr_restxp_enable" ) )
|
||||
return false;
|
||||
|
||||
restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
|
||||
|
||||
wantGiveRestXP = int(baseXP * restXPAwardRate);
|
||||
mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
|
||||
|
||||
if ( mayGiveRestXP <= 0 )
|
||||
return false;
|
||||
|
||||
if ( wantGiveRestXP >= mayGiveRestXP )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
syncXPStat()
|
||||
{
|
||||
if ( level._xpScale > 4 || level._xpScale <= 0)
|
||||
exitLevel( false );
|
||||
|
||||
xp = self getRankXP();
|
||||
|
||||
self maps\mp\gametypes\_persistence::statSet( "experience", xp );
|
||||
}
|
||||
|
||||
createXpEventPopup()
|
||||
{
|
||||
hud_xpEventPopup = newClientHudElem( self );
|
||||
hud_xpEventPopup.children = [];
|
||||
hud_xpEventPopup.horzAlign = "center";
|
||||
hud_xpEventPopup.vertAlign = "middle";
|
||||
hud_xpEventPopup.alignX = "center";
|
||||
hud_xpEventPopup.alignY = "middle";
|
||||
hud_xpEventPopup.x = 55;
|
||||
if ( level._splitScreen )
|
||||
hud_xpEventPopup.y = -20;
|
||||
else
|
||||
hud_xpEventPopup.y = -35;
|
||||
hud_xpEventPopup.font = "hudbig";
|
||||
hud_xpEventPopup.fontscale = 0.65;
|
||||
hud_xpEventPopup.archived = false;
|
||||
hud_xpEventPopup.color = (0.5,0.5,0.5);
|
||||
hud_xpEventPopup.sort = 10000;
|
||||
hud_xpEventPopup.elemType = "msgText";
|
||||
hud_xpEventPopup maps\mp\gametypes\_hud::fontPulseInit( 3.0 );
|
||||
return hud_xpEventPopup;
|
||||
}
|
||||
|
||||
xpEventPopup( event, hudColor, glowAlpha )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "joined_team" );
|
||||
self endon( "joined_spectators" );
|
||||
|
||||
self notify( "xpEventPopup" );
|
||||
self endon( "xpEventPopup" );
|
||||
|
||||
wait ( 0.05 );
|
||||
|
||||
if ( !isDefined( hudColor ) )
|
||||
hudColor = (1,1,0.5);
|
||||
if ( !isDefined( glowAlpha ) )
|
||||
glowAlpha = 0;
|
||||
|
||||
self.hud_xpEventPopup.color = hudColor;
|
||||
self.hud_xpEventPopup.glowColor = hudColor;
|
||||
self.hud_xpEventPopup.glowAlpha = glowAlpha;
|
||||
|
||||
self.hud_xpEventPopup setText(event);
|
||||
self.hud_xpEventPopup.alpha = 0.85;
|
||||
|
||||
wait ( 1.0 );
|
||||
|
||||
self.hud_xpEventPopup fadeOverTime( 0.75 );
|
||||
self.hud_xpEventPopup.alpha = 0;
|
||||
}
|
103
maps/mp/gametypes/_serversettings.gsc
Normal file
103
maps/mp/gametypes/_serversettings.gsc
Normal file
@ -0,0 +1,103 @@
|
||||
init()
|
||||
{
|
||||
level._hostname = getdvar("sv_hostname");
|
||||
if(level._hostname == "")
|
||||
level._hostname = "CoDHost";
|
||||
setdvar("sv_hostname", level._hostname);
|
||||
|
||||
level._allowvote = getdvarint("g_allowvote", 1);
|
||||
SetDvar("g_allowvote", level._allowvote);
|
||||
makedvarserverinfo("ui_allowvote", level._allowvote);
|
||||
|
||||
level._friendlyfire = maps\mp\gametypes\_tweakables::getTweakableValue( "team", "fftype" );
|
||||
makedvarserverinfo("ui_friendlyfire", level._friendlyfire);
|
||||
|
||||
constrainGameType(getdvar("g_gametype"));
|
||||
|
||||
for(;;)
|
||||
{
|
||||
updateServerSettings();
|
||||
wait 5;
|
||||
}
|
||||
}
|
||||
|
||||
updateServerSettings()
|
||||
{
|
||||
sv_hostname = getdvar("sv_hostname");
|
||||
if(level._hostname != sv_hostname)
|
||||
{
|
||||
level._hostname = sv_hostname;
|
||||
}
|
||||
|
||||
g_allowvote = getdvarint("g_allowvote", 1);
|
||||
if(level._allowvote != g_allowvote)
|
||||
{
|
||||
level._allowvote = g_allowvote;
|
||||
setdvar("ui_allowvote", level._allowvote);
|
||||
}
|
||||
|
||||
scr_friendlyfire = maps\mp\gametypes\_tweakables::getTweakableValue( "team", "fftype" );
|
||||
if(level._friendlyfire != scr_friendlyfire)
|
||||
{
|
||||
level._friendlyfire = scr_friendlyfire;
|
||||
setdvar("ui_friendlyfire", level._friendlyfire);
|
||||
}
|
||||
}
|
||||
|
||||
constrainGameType(gametype)
|
||||
{
|
||||
entities = getentarray();
|
||||
for(i = 0; i < entities.size; i++)
|
||||
{
|
||||
entity = entities[i];
|
||||
|
||||
if(gametype == "dm")
|
||||
{
|
||||
if(isdefined(entity.script_gametype_dm) && entity.script_gametype_dm != "1")
|
||||
{
|
||||
//iprintln("DELETED(GameType): ", entity.classname);
|
||||
entity delete();
|
||||
}
|
||||
}
|
||||
else if(gametype == "tdm")
|
||||
{
|
||||
if(isdefined(entity.script_gametype_tdm) && entity.script_gametype_tdm != "1")
|
||||
{
|
||||
//iprintln("DELETED(GameType): ", entity.classname);
|
||||
entity delete();
|
||||
}
|
||||
}
|
||||
else if(gametype == "ctf")
|
||||
{
|
||||
if(isdefined(entity.script_gametype_ctf) && entity.script_gametype_ctf != "1")
|
||||
{
|
||||
//iprintln("DELETED(GameType): ", entity.classname);
|
||||
entity delete();
|
||||
}
|
||||
}
|
||||
else if(gametype == "hq")
|
||||
{
|
||||
if(isdefined(entity.script_gametype_hq) && entity.script_gametype_hq != "1")
|
||||
{
|
||||
//iprintln("DELETED(GameType): ", entity.classname);
|
||||
entity delete();
|
||||
}
|
||||
}
|
||||
else if(gametype == "sd")
|
||||
{
|
||||
if(isdefined(entity.script_gametype_sd) && entity.script_gametype_sd != "1")
|
||||
{
|
||||
//iprintln("DELETED(GameType): ", entity.classname);
|
||||
entity delete();
|
||||
}
|
||||
}
|
||||
else if(gametype == "koth")
|
||||
{
|
||||
if(isdefined(entity.script_gametype_koth) && entity.script_gametype_koth != "1")
|
||||
{
|
||||
//iprintln("DELETED(GameType): ", entity.classname);
|
||||
entity delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
168
maps/mp/gametypes/_shellshock.gsc
Normal file
168
maps/mp/gametypes/_shellshock.gsc
Normal 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 );
|
||||
}
|
||||
}
|
2205
maps/mp/gametypes/_spawnlogic.gsc
Normal file
2205
maps/mp/gametypes/_spawnlogic.gsc
Normal file
File diff suppressed because it is too large
Load Diff
210
maps/mp/gametypes/_spectating.gsc
Normal file
210
maps/mp/gametypes/_spectating.gsc
Normal 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 );
|
||||
}
|
||||
}
|
419
maps/mp/gametypes/_stinger.gsc
Normal file
419
maps/mp/gametypes/_stinger.gsc
Normal file
@ -0,0 +1,419 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
InitStingerUsage()
|
||||
{
|
||||
self.stingerStage = undefined;
|
||||
self.stingerTarget = undefined;
|
||||
self.stingerLockStartTime = undefined;
|
||||
self.stingerLostSightlineTime = undefined;
|
||||
|
||||
self thread ResetStingerLockingOnDeath();
|
||||
level._stingerTargets = [];
|
||||
}
|
||||
|
||||
|
||||
ResetStingerLocking()
|
||||
{
|
||||
if ( !IsDefined( self.stingerUseEntered ) )
|
||||
return;
|
||||
self.stingerUseEntered = undefined;
|
||||
|
||||
self notify( "stop_javelin_locking_feedback" );
|
||||
self notify( "stop_javelin_locked_feedback" );
|
||||
|
||||
self WeaponLockFree();
|
||||
InitStingerUsage();
|
||||
}
|
||||
|
||||
|
||||
ResetStingerLockingOnDeath()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self notify ( "ResetStingerLockingOnDeath" );
|
||||
self endon ( "ResetStingerLockingOnDeath" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "death" );
|
||||
self ResetStingerLocking();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StillValidStingerLock( ent )
|
||||
{
|
||||
assert( IsDefined( self ) );
|
||||
|
||||
if ( !IsDefined( ent ) )
|
||||
return false;
|
||||
if ( !(self WorldPointInReticle_Circle( ent.origin, 65, 85 )) )
|
||||
return false;
|
||||
|
||||
if ( self.stingerTarget == level._ac130.planeModel && !isDefined( level._ac130player ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
LoopStingerLockingFeedback()
|
||||
{
|
||||
self endon( "stop_javelin_locking_feedback" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( isDefined( level._chopper ) && isDefined( level._chopper.gunner ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._chopper.gunner )
|
||||
level._chopper.gunner playLocalSound( "missile_locking" );
|
||||
|
||||
if ( isDefined( level._ac130player ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._ac130.planeModel )
|
||||
level._ac130player playLocalSound( "missile_locking" );
|
||||
|
||||
self playLocalSound( "stinger_locking" );
|
||||
self PlayRumbleOnEntity( "ac130_25mm_fire" );
|
||||
|
||||
wait 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LoopStingerLockedFeedback()
|
||||
{
|
||||
self endon( "stop_javelin_locked_feedback" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( isDefined( level._chopper ) && isDefined( level._chopper.gunner ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._chopper.gunner )
|
||||
level._chopper.gunner playLocalSound( "missile_locking" );
|
||||
|
||||
if ( isDefined( level._ac130player ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._ac130.planeModel )
|
||||
level._ac130player playLocalSound( "missile_locking" );
|
||||
|
||||
self playLocalSound( "stinger_locked" );
|
||||
self PlayRumbleOnEntity( "ac130_25mm_fire" );
|
||||
|
||||
wait 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/#
|
||||
DrawStar( point )
|
||||
{
|
||||
Line( point + (10,0,0), point - (10,0,0) );
|
||||
Line( point + (0,10,0), point - (0,10,0) );
|
||||
Line( point + (0,0,10), point - (0,0,10) );
|
||||
}
|
||||
#/
|
||||
|
||||
|
||||
LockSightTest( target )
|
||||
{
|
||||
eyePos = self GetEye();
|
||||
|
||||
if ( !isDefined( target ) ) //targets can disapear during targeting.
|
||||
return false;
|
||||
|
||||
passed = BulletTracePassed( eyePos, target.origin, false, target );
|
||||
if ( passed )
|
||||
return true;
|
||||
|
||||
front = target GetPointInBounds( 1, 0, 0 );
|
||||
passed = BulletTracePassed( eyePos, front, false, target );
|
||||
if ( passed )
|
||||
return true;
|
||||
|
||||
back = target GetPointInBounds( -1, 0, 0 );
|
||||
passed = BulletTracePassed( eyePos, back, false, target );
|
||||
if ( passed )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
StingerDebugDraw( target )
|
||||
{
|
||||
/#
|
||||
if ( GetDVar( "missileDebugDraw" ) != "1" )
|
||||
return;
|
||||
if ( !IsDefined( target ) )
|
||||
return;
|
||||
|
||||
org = target.origin;
|
||||
DrawStar( org );
|
||||
org = target GetPointInBounds( 1, 0, 0 );
|
||||
DrawStar( org );
|
||||
org = target GetPointInBounds( -1, 0, 0 );
|
||||
DrawStar( org );
|
||||
#/
|
||||
}
|
||||
|
||||
|
||||
SoftSightTest()
|
||||
{
|
||||
LOST_SIGHT_LIMIT = 500;
|
||||
|
||||
if ( self LockSightTest( self.stingerTarget ) )
|
||||
{
|
||||
self.stingerLostSightlineTime = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( self.stingerLostSightlineTime == 0 )
|
||||
self.stingerLostSightlineTime = getTime();
|
||||
|
||||
timePassed = GetTime() - self.stingerLostSightlineTime;
|
||||
//PrintLn( "Losing sight of target [", timePassed, "]..." );
|
||||
|
||||
if ( timePassed >= LOST_SIGHT_LIMIT )
|
||||
{
|
||||
//PrintLn( "Lost sight of target." );
|
||||
ResetStingerLocking();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GetTargetList()
|
||||
{
|
||||
targets = [];
|
||||
|
||||
if ( level._teamBased )
|
||||
{
|
||||
if ( IsDefined( level._chopper ) && ( level._chopper.team != self.team || level._chopper.owner == self ) )
|
||||
targets[targets.size] = level._chopper;
|
||||
|
||||
if ( IsDefined( level._raven ) && ( level._raven.team != self.team || level._raven.owner == self ) )
|
||||
targets[targets.size] = level._raven;
|
||||
|
||||
if ( isDefined( level._ac130player ) && level._ac130player.team != self.team )
|
||||
targets[targets.size] = level._ac130.planemodel;
|
||||
|
||||
if ( isDefined( level._harriers) )
|
||||
{
|
||||
foreach( harrier in level._harriers )
|
||||
{
|
||||
if ( isDefined( harrier ) && ( harrier.team != self.team || ( isDefined( harrier.owner ) && harrier.owner == self ) ) )
|
||||
targets[targets.size] = harrier;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( target_player in level._players )
|
||||
{
|
||||
if (( target_player.team != self.team ) && (target_player _hasPerk("specialty_juggersuit")))
|
||||
{
|
||||
targets[targets.size] = target_player;
|
||||
}
|
||||
}
|
||||
|
||||
if( level._multiTeamBased )
|
||||
{
|
||||
//for all teams
|
||||
for( i = 0; i < level._teamNameList.size; i++ )
|
||||
{
|
||||
//that are not our team
|
||||
if( self.team != level._teamNameList[i] )
|
||||
{
|
||||
//does that team have any uav's
|
||||
if( level._UAVModels[level._teamNameList[i]].size )
|
||||
{
|
||||
//add each uav to the target list
|
||||
foreach ( UAV in level._UAVModels[level._teamNameList[i]] )
|
||||
{
|
||||
targets[targets.size] = UAV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( level._UAVModels[level._otherTeam[self.team]].size )
|
||||
{
|
||||
foreach ( UAV in level._UAVModels[level._otherTeam[self.team]] )
|
||||
targets[targets.size] = UAV;
|
||||
}
|
||||
|
||||
if ( isDefined( level._littleBird ) )
|
||||
{
|
||||
foreach ( bird in level._littleBird )
|
||||
{
|
||||
if ( !isDefined( bird ) )
|
||||
continue;
|
||||
|
||||
if ( self.team != bird.owner.team || self == bird.owner )
|
||||
targets[targets.size] = bird;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( IsDefined( level._chopper ) && ( level._chopper.owner != self ) ) ///check for teams
|
||||
targets[targets.size] = level._chopper;
|
||||
|
||||
if ( isDefined( level._ac130player ) )
|
||||
targets[targets.size] = level._ac130.planemodel;
|
||||
|
||||
if ( isDefined( level._harriers) )
|
||||
{
|
||||
foreach( harrier in level._harriers )
|
||||
{
|
||||
if ( isDefined( harrier ) )
|
||||
targets[targets.size] = harrier;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( target_player in level._players )
|
||||
{
|
||||
if (( target_player != self ) && (target_player _hasPerk("specialty_juggersuit")))
|
||||
{
|
||||
targets[targets.size] = target_player;
|
||||
}
|
||||
}
|
||||
|
||||
if ( level._UAVModels.size )
|
||||
{
|
||||
foreach ( ownerGuid, UAV in level._UAVModels )
|
||||
{
|
||||
if ( isDefined( UAV.owner ) && UAV.owner == self )
|
||||
continue;
|
||||
|
||||
targets[targets.size] = UAV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
|
||||
StingerUsageLoop()
|
||||
{
|
||||
self endon("death");
|
||||
self endon("disconnect");
|
||||
|
||||
LOCK_LENGTH = 1000;
|
||||
|
||||
InitStingerUsage();
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
weapon = self getCurrentWeapon();
|
||||
|
||||
if ( weapon != "stinger_mp" && weapon != "at4_mp" )
|
||||
{
|
||||
ResetStingerLocking();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self PlayerADS() < 0.95 )
|
||||
{
|
||||
ResetStingerLocking();
|
||||
continue;
|
||||
}
|
||||
|
||||
self.stingerUseEntered = true;
|
||||
|
||||
if ( !IsDefined( self.stingerStage ) )
|
||||
self.stingerStage = 0;
|
||||
|
||||
StingerDebugDraw( self.stingerTarget );
|
||||
|
||||
if ( self.stingerStage == 0 ) // searching for target
|
||||
{
|
||||
targets = GetTargetList();
|
||||
if ( targets.size == 0 )
|
||||
continue;
|
||||
|
||||
targetsInReticle = [];
|
||||
foreach ( target in targets )
|
||||
{
|
||||
if ( !isDefined( target ) )
|
||||
continue;
|
||||
|
||||
insideReticle = self WorldPointInReticle_Circle( target.origin, 65, 75 );
|
||||
|
||||
if ( insideReticle )
|
||||
targetsInReticle[targetsInReticle.size] = target;
|
||||
}
|
||||
if ( targetsInReticle.size == 0 )
|
||||
continue;
|
||||
|
||||
sortedTargets = SortByDistance( targetsInReticle, self.origin );
|
||||
if ( !( self LockSightTest( sortedTargets[0] ) ) )
|
||||
continue;
|
||||
|
||||
//PrintLn( "Found a target to lock to..." );
|
||||
thread LoopStingerLockingFeedback();
|
||||
self.stingerTarget = sortedTargets[0];
|
||||
self.stingerLockStartTime = GetTime();
|
||||
self.stingerStage = 1;
|
||||
self.stingerLostSightlineTime = 0;
|
||||
}
|
||||
|
||||
if ( self.stingerStage == 1 ) // locking on to a target
|
||||
{
|
||||
if ( !(self StillValidStingerLock( self.stingerTarget )) )
|
||||
{
|
||||
//PrintLn( "Failed to get lock." );
|
||||
ResetStingerLocking();
|
||||
continue;
|
||||
}
|
||||
|
||||
passed = SoftSightTest();
|
||||
if ( !passed )
|
||||
continue;
|
||||
|
||||
timePassed = getTime() - self.stingerLockStartTime;
|
||||
//PrintLn( "Locking [", timePassed, "]..." );
|
||||
if( self _hasPerk( "specialty_fasterlockon" ))
|
||||
{
|
||||
if( timePassed < ( LOCK_LENGTH * 0.5 ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( timePassed < LOCK_LENGTH )
|
||||
continue;
|
||||
}
|
||||
|
||||
self notify( "stop_javelin_locking_feedback" );
|
||||
thread LoopStingerLockedFeedback();
|
||||
|
||||
//PrintLn( "Locked!");
|
||||
if ( self.stingerTarget.model == "vehicle_av8b_harrier_jet_mp" || self.stingerTarget.model == "vehicle_little_bird_armed" )
|
||||
{
|
||||
self WeaponLockFinalize( self.stingerTarget );
|
||||
}
|
||||
else if ( IsPlayer( self.stingerTarget ) )
|
||||
{
|
||||
self WeaponLockFinalize( self.stingerTarget, (0,0,32) );
|
||||
}
|
||||
else
|
||||
{
|
||||
self WeaponLockFinalize( self.stingerTarget, (100,0,-32) );
|
||||
}
|
||||
|
||||
self.stingerStage = 2;
|
||||
}
|
||||
|
||||
if ( self.stingerStage == 2 ) // target locked
|
||||
{
|
||||
passed = SoftSightTest();
|
||||
if ( !passed )
|
||||
continue;
|
||||
|
||||
if ( !(self StillValidStingerLock( self.stingerTarget )) )
|
||||
{
|
||||
//PrintLn( "Gave up lock." );
|
||||
ResetStingerLocking();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2121
maps/mp/gametypes/_teams.gsc
Normal file
2121
maps/mp/gametypes/_teams.gsc
Normal file
File diff suppressed because one or more lines are too long
364
maps/mp/gametypes/_tweakables.gsc
Normal file
364
maps/mp/gametypes/_tweakables.gsc
Normal 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 );
|
||||
}
|
4201
maps/mp/gametypes/_weapons.gsc
Normal file
4201
maps/mp/gametypes/_weapons.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1885
maps/mp/gametypes/convoy.gsc
Normal file
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
100
maps/mp/gametypes/dm.gsc
Normal 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;
|
||||
}
|
2431
maps/mp/gametypes/escortplus.gsc
Normal file
2431
maps/mp/gametypes/escortplus.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1083
maps/mp/gametypes/hvt.gsc
Normal file
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
171
maps/mp/gametypes/war.gsc
Normal 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"] );
|
||||
}
|
Reference in New Issue
Block a user