Pushed raw files
This commit is contained in:
1 parent
22d0d4d39f
commit
79f967ecc9
5854 files changed
+2989978
No files matched your search
@@ -0,0 +1,202 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
init()
|
||||
{
|
||||
level.isTeamSpeaking["allies"] = false;
|
||||
level.isTeamSpeaking["axis"] = false;
|
||||
|
||||
level.speakers["allies"] = [];
|
||||
level.speakers["axis"] = [];
|
||||
|
||||
level.bcSounds = [];
|
||||
level.bcSounds["reload"] = "inform_reloading_generic";
|
||||
level.bcSounds["frag_out"] = "inform_attack_grenade";
|
||||
level.bcSounds["flash_out"] = "inform_attack_flashbang";
|
||||
level.bcSounds["smoke_out"] = "inform_attack_smoke";
|
||||
level.bcSounds["conc_out"] = "inform_attack_stun";
|
||||
level.bcSounds["c4_plant"] = "inform_attack_thwc4";
|
||||
level.bcSounds["claymore_plant"] = "inform_plant_claymore";
|
||||
level.bcSounds["kill"] = "inform_killfirm_infantry";
|
||||
level.bcSounds["casualty"] = "inform_casualty_generic";
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill ( "connected", player );
|
||||
|
||||
player thread onPlayerSpawned();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
// help players be stealthy in splitscreen by not announcing their intentions
|
||||
if ( level.splitscreen )
|
||||
continue;
|
||||
|
||||
self thread claymoreTracking();
|
||||
self thread reloadTracking();
|
||||
self thread grenadeTracking();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
claymoreTracking()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
while(1)
|
||||
{
|
||||
self waittill( "begin_firing" );
|
||||
weaponName = self getCurrentWeapon();
|
||||
if ( weaponName == "claymore_mp" )
|
||||
level thread sayLocalSound( self, "claymore_plant" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
reloadTracking()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
self waittill ( "reload_start" );
|
||||
level thread sayLocalSound( self, "reload" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
grenadeTracking()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
self waittill ( "grenade_fire", grenade, weaponName );
|
||||
|
||||
if ( weaponName == "frag_grenade_mp" )
|
||||
level thread sayLocalSound( self, "frag_out" );
|
||||
else if ( weaponName == "flash_grenade_mp" )
|
||||
level thread sayLocalSound( self, "flash_out" );
|
||||
else if ( weaponName == "concussion_grenade_mp" )
|
||||
level thread sayLocalSound( self, "conc_out" );
|
||||
else if ( weaponName == "smoke_grenade_mp" )
|
||||
level thread sayLocalSound( self, "smoke_out" );
|
||||
else if ( weaponName == "c4_mp" )
|
||||
level thread sayLocalSound( self, "c4_plant" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sayLocalSoundDelayed( player, soundType, delay )
|
||||
{
|
||||
player endon ( "death" );
|
||||
player endon ( "disconnect" );
|
||||
|
||||
wait ( delay );
|
||||
|
||||
sayLocalSound( player, soundType );
|
||||
}
|
||||
|
||||
|
||||
sayLocalSound( player, soundType )
|
||||
{
|
||||
player endon ( "death" );
|
||||
player endon ( "disconnect" );
|
||||
|
||||
if ( isSpeakerInRange( player ) )
|
||||
return;
|
||||
|
||||
if( player.team != "spectator" )
|
||||
{
|
||||
prefix = maps\mp\gametypes\_teams::getTeamVoicePrefix( player.team ) + "1_";
|
||||
soundAlias = prefix + level.bcSounds[soundType];
|
||||
player thread doSound( soundAlias );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
doSound( soundAlias )
|
||||
{
|
||||
team = self.pers["team"];
|
||||
level addSpeaker( self, team );
|
||||
self playSoundToTeam( soundAlias, team, self );
|
||||
self thread timeHack( soundAlias ); // workaround because soundalias notify isn't happening
|
||||
self waittill_any( soundAlias, "death", "disconnect" );
|
||||
level removeSpeaker( self, team );
|
||||
}
|
||||
|
||||
|
||||
timeHack( soundAlias )
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
wait ( 2.0 );
|
||||
self notify ( soundAlias );
|
||||
}
|
||||
|
||||
|
||||
isSpeakerInRange( player )
|
||||
{
|
||||
player endon ( "death" );
|
||||
player endon ( "disconnect" );
|
||||
|
||||
distSq = 1000 * 1000;
|
||||
|
||||
// to prevent player switch to spectator after throwing a granade causing damage to someone and result in attacker.pers["team"] = "spectator"
|
||||
if( isdefined( player ) && isdefined( player.pers["team"] ) && player.pers["team"] != "spectator" )
|
||||
{
|
||||
for ( index = 0; index < level.speakers[player.pers["team"]].size; index++ )
|
||||
{
|
||||
teammate = level.speakers[player.pers["team"]][index];
|
||||
if ( teammate == player )
|
||||
return true;
|
||||
|
||||
if ( distancesquared( teammate.origin, player.origin ) < distSq )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
addSpeaker( player, team )
|
||||
{
|
||||
level.speakers[team][level.speakers[team].size] = player;
|
||||
}
|
||||
|
||||
|
||||
// this is lazy... fix up later by tracking ID's and doing array slot swapping
|
||||
removeSpeaker( player, team )
|
||||
{
|
||||
newSpeakers = [];
|
||||
for ( index = 0; index < level.speakers[team].size; index++ )
|
||||
{
|
||||
if ( level.speakers[team][index] == player )
|
||||
continue;
|
||||
|
||||
newSpeakers[newSpeakers.size] = level.speakers[team][index];
|
||||
}
|
||||
|
||||
level.speakers[team] = newSpeakers;
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
// Callback Setup
|
||||
// This script provides the hooks from code into script for the gametype callback functions.
|
||||
|
||||
//=============================================================================
|
||||
// Code Callback functions
|
||||
|
||||
/*================
|
||||
Called by code after the level's main script function has run.
|
||||
================*/
|
||||
CodeCallback_StartGameType()
|
||||
{
|
||||
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
|
||||
level waittill( "eternity" );
|
||||
|
||||
// If the gametype has not beed started, run the startup
|
||||
if(!isDefined(level.gametypestarted) || !level.gametypestarted)
|
||||
{
|
||||
[[level.callbackStartGameType]]();
|
||||
|
||||
level.gametypestarted = true; // so we know that the gametype has been started up
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a player begins connecting to the server.
|
||||
Called again for every map change or tournement restart.
|
||||
|
||||
Return undefined if the client should be allowed, otherwise return
|
||||
a string with the reason for denial.
|
||||
|
||||
Otherwise, the client will be sent the current gamestate
|
||||
and will eventually get to ClientBegin.
|
||||
|
||||
firstTime will be qtrue the very first time a client connects
|
||||
to the server machine, but qfalse on map changes and tournement
|
||||
restarts.
|
||||
================*/
|
||||
CodeCallback_PlayerConnect()
|
||||
{
|
||||
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
|
||||
level waittill( "eternity" );
|
||||
|
||||
self endon("disconnect");
|
||||
[[level.callbackPlayerConnect]]();
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player drops from the server.
|
||||
Will not be called between levels.
|
||||
self is the player that is disconnecting.
|
||||
================*/
|
||||
CodeCallback_PlayerDisconnect()
|
||||
{
|
||||
self notify("disconnect");
|
||||
[[level.callbackPlayerDisconnect]]();
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player has taken damage.
|
||||
self is the player that took damage.
|
||||
================*/
|
||||
CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level.callbackPlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player has been killed.
|
||||
self is the player that was killed.
|
||||
================*/
|
||||
CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level.callbackPlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a vehicle has taken damage.
|
||||
self is the vehicle that took damage.
|
||||
================*/
|
||||
CodeCallback_VehicleDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName )
|
||||
{
|
||||
if ( isDefined( self.damageCallback ) )
|
||||
self [[self.damageCallback]]( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
|
||||
else
|
||||
self Vehicle_FinishDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when code is forcibly ending the game.
|
||||
e.g. we suck as host.
|
||||
================*/
|
||||
CodeCallback_CodeEndGame()
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level.callbackCodeEndGame]]();
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a player has been killed, but has last stand perk.
|
||||
self is the player that was killed.
|
||||
================*/
|
||||
CodeCallback_PlayerLastStand(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level.callbackPlayerLastStand]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a player reconnects to the server
|
||||
following a host migration.
|
||||
================*/
|
||||
CodeCallback_PlayerMigrated()
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level.callbackPlayerMigrated]]();
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called once when a host migration has occured.
|
||||
================*/
|
||||
CodeCallback_HostMigration()
|
||||
{
|
||||
[[level.callbackHostMigration]]();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
// Damage flags used in the playerDamage callback
|
||||
SetupDamageFlags()
|
||||
{
|
||||
// code-defined:
|
||||
level.iDFLAGS_RADIUS = 1; // damage was indirect
|
||||
level.iDFLAGS_NO_ARMOR = 2; // armor does not protect from this damage
|
||||
level.iDFLAGS_NO_KNOCKBACK = 4; // do not affect velocity, just view angles
|
||||
level.iDFLAGS_PENETRATION = 8; // damage occurred after one or more penetrations
|
||||
level.iDFLAGS_STUN = 16; // non-lethal
|
||||
level.iDFLAGS_SHIELD_EXPLOSIVE_IMPACT = 32; // missile impacted on the front of the victim's shield
|
||||
level.iDFLAGS_SHIELD_EXPLOSIVE_IMPACT_HUGE = 64; // ...and was from a projectile with "Big Explosion" checked on.
|
||||
level.iDFLAGS_SHIELD_EXPLOSIVE_SPLASH = 128; // explosive splash, somewhat deflected by the victim's shield
|
||||
|
||||
// script-defined:
|
||||
level.iDFLAGS_NO_TEAM_PROTECTION = 256;
|
||||
level.iDFLAGS_NO_PROTECTION = 512;
|
||||
level.iDFLAGS_PASSTHRU = 1024;
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Setup any misc callbacks stuff like defines and default callbacks
|
||||
================*/
|
||||
SetupCallbacks()
|
||||
{
|
||||
SetDefaultCallbacks();
|
||||
SetupDamageFlags();
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called from the gametype script to store off the default callback functions.
|
||||
This allows the callbacks to be overridden by level script, but not lost.
|
||||
================*/
|
||||
SetDefaultCallbacks()
|
||||
{
|
||||
level.callbackStartGameType = maps\mp\gametypes\_gamelogic::Callback_StartGameType;
|
||||
level.callbackPlayerConnect = maps\mp\gametypes\_playerlogic::Callback_PlayerConnect;
|
||||
level.callbackPlayerDisconnect = maps\mp\gametypes\_playerlogic::Callback_PlayerDisconnect;
|
||||
level.callbackPlayerDamage = maps\mp\gametypes\_damage::Callback_PlayerDamage;
|
||||
level.callbackPlayerKilled = maps\mp\gametypes\_damage::Callback_PlayerKilled;
|
||||
level.callbackCodeEndGame = maps\mp\gametypes\_gamelogic::Callback_CodeEndGame;
|
||||
level.callbackPlayerLastStand = maps\mp\gametypes\_damage::Callback_PlayerLastStand;
|
||||
level.callbackPlayerMigrated = maps\mp\gametypes\_playerlogic::Callback_PlayerMigrated;
|
||||
level.callbackHostMigration = maps\mp\gametypes\_hostmigration::Callback_HostMigration;
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a gametype is not supported.
|
||||
================*/
|
||||
AbortLevel()
|
||||
{
|
||||
println("Aborting level - gametype is not supported");
|
||||
|
||||
level.callbackStartGameType = ::callbackVoid;
|
||||
level.callbackPlayerConnect = ::callbackVoid;
|
||||
level.callbackPlayerDisconnect = ::callbackVoid;
|
||||
level.callbackPlayerDamage = ::callbackVoid;
|
||||
level.callbackPlayerKilled = ::callbackVoid;
|
||||
level.callbackCodeEndGame = ::callbackVoid;
|
||||
level.callbackPlayerLastStand = ::callbackVoid;
|
||||
level.callbackPlayerMigrated = ::callbackVoid;
|
||||
level.callbackHostMigration = ::callbackVoid;
|
||||
|
||||
setdvar("g_gametype", "dm");
|
||||
|
||||
exitLevel(false);
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
================*/
|
||||
callbackVoid()
|
||||
{
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,828 @@
|
||||
init()
|
||||
{
|
||||
level.coptermodel = "vehicle_cobra_helicopter_fly";
|
||||
precacheModel(level.coptermodel);
|
||||
|
||||
level.copter_maxaccel = 200;
|
||||
level.copter_maxvel = 700;
|
||||
level.copter_rotspeed = 90; // degrees per second
|
||||
level.copter_accellookahead = 2; // seconds
|
||||
|
||||
level.copterCenterOffset = (0,0,72);
|
||||
level.copterTargetOffset = (0,0,45);
|
||||
|
||||
level.copterexplosion = loadfx("explosions/default_explosion");
|
||||
level.copterfinalexplosion = loadfx("explosions/large_vehicle_explosion");
|
||||
}
|
||||
|
||||
getAboveBuildingsLocation(location)
|
||||
{
|
||||
trace = bullettrace(location + (0,0,10000), location, false, undefined);
|
||||
startorigin = trace["position"] + (0,0,-514);
|
||||
|
||||
zpos = 0;
|
||||
|
||||
maxxpos = 13; maxypos = 13;
|
||||
for (xpos = 0; xpos < maxxpos; xpos++) {
|
||||
for (ypos = 0; ypos < maxypos; ypos++) {
|
||||
thisstartorigin = startorigin + ((xpos/(maxxpos-1) - .5) * 1024, (ypos/(maxypos-1) - .5) * 1024, 0);
|
||||
thisorigin = bullettrace(thisstartorigin, thisstartorigin + (0,0,-10000), false, undefined);
|
||||
zpos += thisorigin["position"][2];
|
||||
}
|
||||
}
|
||||
zpos = zpos / (maxxpos*maxypos);
|
||||
|
||||
zpos = zpos + 850;
|
||||
|
||||
return (location[0], location[1], zpos);
|
||||
}
|
||||
|
||||
vectorAngle(v1, v2)
|
||||
{
|
||||
dot = vectordot(v1, v2);
|
||||
if (dot >= 1)
|
||||
return 0;
|
||||
else if (dot <= -1)
|
||||
return 180;
|
||||
return acos(dot);
|
||||
}
|
||||
vectorTowardsOtherVector(v1, v2, angle)
|
||||
{
|
||||
dot = vectordot(v1, v2);
|
||||
if (dot <= -1)
|
||||
{
|
||||
return v1; // eh
|
||||
}
|
||||
v3 = vectornormalize(v2 - vecscale(v1, dot));
|
||||
|
||||
return vecscale(v1, cos(angle)) + vecscale(v3, sin(angle));
|
||||
}
|
||||
veclength(v)
|
||||
{
|
||||
return distance((0,0,0), v);
|
||||
}
|
||||
|
||||
createCopter(location, team, damagetrig)
|
||||
{
|
||||
location = getAboveBuildingsLocation(location);
|
||||
|
||||
scriptorigin = spawn("script_origin", location);
|
||||
scriptorigin.angles = vectorToAngles((1, 0, 0));
|
||||
|
||||
copter = spawn("script_model", location);
|
||||
copter.angles = vectorToAngles((0, 1, 0));
|
||||
|
||||
copter linkto(scriptorigin);
|
||||
scriptorigin.copter = copter;
|
||||
copter setModel(level.coptermodel);
|
||||
copter playLoopSound("mp_copter_ambience");
|
||||
|
||||
damagetrig.origin = scriptorigin.origin;
|
||||
damagetrig thread mylinkto(scriptorigin);
|
||||
scriptorigin.damagetrig = damagetrig;
|
||||
|
||||
scriptorigin.finalDest = location;
|
||||
scriptorigin.finalZDest = location[2];
|
||||
scriptorigin.desiredDir = (1,0,0);
|
||||
scriptorigin.desiredDirEntity = undefined;
|
||||
scriptorigin.desiredDirEntityOffset = (0,0,0);
|
||||
scriptorigin.vel = (0,0,0);
|
||||
scriptorigin.dontascend = false;
|
||||
|
||||
scriptorigin.health = 2000;
|
||||
if (getdvar("scr_copter_health") != "")
|
||||
scriptorigin.health = getdvarfloat("scr_copter_health");
|
||||
|
||||
scriptorigin.team = team;
|
||||
|
||||
scriptorigin thread copterAI();
|
||||
scriptorigin thread copterDamage(damagetrig);
|
||||
|
||||
return scriptorigin;
|
||||
}
|
||||
|
||||
makeCopterPassive()
|
||||
{
|
||||
self.damagetrig notify("unlink");
|
||||
self.damagetrig = undefined;
|
||||
|
||||
self notify("passive");
|
||||
|
||||
self.desiredDirEntity = undefined;
|
||||
self.desiredDir = undefined;
|
||||
}
|
||||
makeCopterActive(damagetrig)
|
||||
{
|
||||
damagetrig.origin = self.origin;
|
||||
damagetrig thread mylinkto(self);
|
||||
self.damagetrig = damagetrig;
|
||||
|
||||
self thread copterAI();
|
||||
self thread copterDamage(damagetrig);
|
||||
}
|
||||
|
||||
mylinkto(obj)
|
||||
{
|
||||
self endon("unlink");
|
||||
while(1)
|
||||
{
|
||||
self.angles = obj.angles;
|
||||
self.origin = obj.origin;
|
||||
wait .1;
|
||||
}
|
||||
}
|
||||
|
||||
setCopterDefenseArea(areaEnt)
|
||||
{
|
||||
self.areaEnt = areaEnt;
|
||||
self.areaDescentPoints = [];
|
||||
if (isdefined(areaEnt.target)) {
|
||||
self.areaDescentPoints = getentarray(areaEnt.target, "targetname");
|
||||
}
|
||||
for (i = 0; i < self.areaDescentPoints.size; i++)
|
||||
{
|
||||
self.areaDescentPoints[i].targetEnt = getent(self.areaDescentPoints[i].target, "targetname");
|
||||
}
|
||||
}
|
||||
|
||||
copterAI()
|
||||
{
|
||||
self thread copterMove();
|
||||
self thread copterShoot();
|
||||
|
||||
self endon("death");
|
||||
self endon("passive");
|
||||
|
||||
flying = true;
|
||||
descendingEnt = undefined;
|
||||
reachedDescendingEnt = false;
|
||||
returningToArea = false;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (!isdefined(self.areaEnt)) {
|
||||
wait(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
players = level.players;
|
||||
enemyTargets = [];
|
||||
if (self.team != "neutral") {
|
||||
for (i = 0; i < players.size; i++) {
|
||||
if (isalive(players[i]) && isdefined(players[i].pers["team"]) && players[i].pers["team"] != self.team && !isdefined(players[i].usingObj)) {
|
||||
playerorigin = players[i].origin;
|
||||
playerorigin = (playerorigin[0], playerorigin[1], self.areaEnt.origin[2]);
|
||||
if (distance(playerorigin, self.areaEnt.origin) < self.areaEnt.radius)
|
||||
enemyTargets[enemyTargets.size] = players[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
insideTargets = [];
|
||||
outsideTargets = [];
|
||||
|
||||
skyheight = bullettrace(self.origin, self.origin + (0,0,10000), false, undefined)["position"][2] - 10;
|
||||
|
||||
bestTarget = undefined;
|
||||
bestWeight = 0;
|
||||
for (i = 0; i < enemyTargets.size; i++) {
|
||||
inside = false;
|
||||
trace = bulletTrace(enemyTargets[i].origin + (0,0,10), enemyTargets[i].origin + (0,0,10000), false, undefined);
|
||||
if (trace["position"][2] >= skyheight)
|
||||
// outside.
|
||||
outsideTargets[outsideTargets.size] = enemyTargets[i];
|
||||
else
|
||||
// inside.
|
||||
insideTargets[insideTargets.size] = enemyTargets[i];
|
||||
}
|
||||
|
||||
goToPos = undefined;
|
||||
calcedGoToPos = false;
|
||||
|
||||
oldDescendingEnt = undefined;
|
||||
|
||||
// determine if we should change states
|
||||
if (flying) {
|
||||
if (outsideTargets.size == 0 && insideTargets.size > 0 && self.areaDescentPoints.size > 0) {
|
||||
flying = false;
|
||||
|
||||
result = determineBestEnt(insideTargets, self.areaDescentPoints, self.origin);
|
||||
descendingEnt = result["descendEnt"];
|
||||
if (isdefined(descendingEnt))
|
||||
goToPos = result["position"];
|
||||
else
|
||||
flying = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
oldDescendingEnt = descendingEnt;
|
||||
if (insideTargets.size == 0) {
|
||||
flying = true;
|
||||
}
|
||||
else {
|
||||
// if we can't get a good target, and there are outside targets, give up and fly
|
||||
if (outsideTargets.size > 0) {
|
||||
if (!isdefined(descendingEnt))
|
||||
flying = true;
|
||||
else
|
||||
{
|
||||
calcedGoToPos = true;
|
||||
goToPos = determineBestPos(insideTargets, descendingEnt, self.origin);
|
||||
if (!isdefined(goToPos))
|
||||
flying = true;
|
||||
}
|
||||
}
|
||||
// determine where to go.
|
||||
if (isdefined(descendingEnt)) {
|
||||
// we're already descended. try to find a good place to shoot into the door/window from.
|
||||
if (!calcedGoToPos)
|
||||
goToPos = determineBestPos(insideTargets, descendingEnt, self.origin);
|
||||
}
|
||||
if (!isdefined(goToPos)) {
|
||||
result = determineBestEnt(insideTargets, self.areaDescentPoints, self.origin);
|
||||
if (isdefined(result["descendEnt"])) {
|
||||
descendingEnt = result["descendEnt"];
|
||||
goToPos = result["position"];
|
||||
reachedDescendingEnt = false;
|
||||
}
|
||||
else {
|
||||
if (isdefined(descendingEnt)) {
|
||||
if (isdefined(self.finalDest))
|
||||
goToPos = self.finalDest;
|
||||
else
|
||||
goToPos = descendingEnt.origin;
|
||||
}
|
||||
else
|
||||
goToPos = undefined;
|
||||
}
|
||||
}
|
||||
// couldn't find a place to descend?
|
||||
if (!isdefined(goToPos))
|
||||
flying = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (flying)
|
||||
{
|
||||
// determine best target to shoot outside.
|
||||
|
||||
desireddist = 1024*2.5;
|
||||
|
||||
distToArea = distance((self.origin[0], self.origin[1], self.areaEnt.origin[2]), self.areaEnt.origin);
|
||||
if (outsideTargets.size == 0 && distToArea > self.areaEnt.radius + desireddist*.25)
|
||||
returningToArea = true;
|
||||
else if (distToArea < self.areaEnt.radius*.5)
|
||||
returningToArea = false;
|
||||
if (outsideTargets.size == 0 && !returningToArea)
|
||||
{
|
||||
// no outside targets? look again for any enemies outside the radius we're defending - just so
|
||||
// we don't look stupid when we could be making ourself useful.
|
||||
if (self.team != "neutral") {
|
||||
for (i = 0; i < players.size; i++) {
|
||||
if (isalive(players[i]) && isdefined(players[i].pers["team"]) && players[i].pers["team"] != self.team && !isdefined(players[i].usingObj)) {
|
||||
playerorigin = players[i].origin;
|
||||
playerorigin = (playerorigin[0], playerorigin[1], self.areaEnt.origin[2]);
|
||||
if (distance(players[i].origin, self.areaEnt.origin) > self.areaEnt.radius)
|
||||
outsideTargets[outsideTargets.size] = players[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
best = undefined;
|
||||
bestdist = 0;
|
||||
for (i = 0; i < outsideTargets.size; i++)
|
||||
{
|
||||
dist = abs(distance(outsideTargets[i].origin, self.origin) - desireddist);
|
||||
if (!isdefined(best) || dist < bestdist) {
|
||||
best = outsideTargets[i];
|
||||
bestdist = dist;
|
||||
}
|
||||
}
|
||||
|
||||
if (isdefined(best)) {
|
||||
// determine best position to go to to get target.
|
||||
attackpos = best.origin + level.copterTargetOffset;
|
||||
goToPos = determineBestAttackPos(attackpos, self.origin, desireddist);
|
||||
|
||||
//iprintln("going to flying attack pos");
|
||||
|
||||
self setCopterDest(goToPos, false);
|
||||
|
||||
self.desiredDir = vectornormalize(attackpos - goToPos);
|
||||
self.desiredDirEntity = best;
|
||||
self.desiredDirEntityOffset = level.copterTargetOffset;
|
||||
|
||||
wait(1);
|
||||
}
|
||||
else {
|
||||
goToPos = getRandomPos(self.areaEnt.origin, self.areaEnt.radius);
|
||||
self setCopterDest(goToPos, false);
|
||||
|
||||
//iprintln("going to random pos");
|
||||
|
||||
self.desiredDir = undefined;
|
||||
self.desiredDirEntity = undefined;
|
||||
|
||||
wait(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (distance(self.origin, descendingEnt.origin) < descendingEnt.radius)
|
||||
reachedDescendingEnt = true;
|
||||
|
||||
//iprintln("going to descent pos");
|
||||
|
||||
goDirectly = (isdefined(oldDescendingEnt) && oldDescendingEnt == descendingEnt);
|
||||
goDirectly = goDirectly && reachedDescendingEnt;
|
||||
|
||||
self.desiredDir = vectornormalize(descendingEnt.targetEnt.origin - (goToPos - level.copterCenterOffset));
|
||||
self.desiredDirEntity = descendingEnt.targetEnt;
|
||||
self.desiredDirEntityOffset = (0,0,0);
|
||||
|
||||
if (goToPos != self.origin) {
|
||||
self setCopterDest(goToPos - level.copterCenterOffset, true, goDirectly);
|
||||
wait(.3);
|
||||
}
|
||||
else
|
||||
wait(.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// determines the best position to go to within descendEnt
|
||||
// from where a target is visible. if no such positions,
|
||||
// returns undefined.
|
||||
determineBestPos(targets, descendEnt, startorigin)
|
||||
{
|
||||
targetpos = descendEnt.targetEnt.origin;
|
||||
circleradius = distance(targetpos, descendEnt.origin);
|
||||
|
||||
|
||||
bestpoint = undefined;
|
||||
bestdist = 0;
|
||||
for (i = 0; i < targets.size; i++)
|
||||
{
|
||||
enemypos = targets[i].origin + level.copterTargetOffset;
|
||||
passed = bullettracepassed(enemypos, targetpos, false, undefined);
|
||||
if (passed) {
|
||||
dir = targetpos - enemypos;
|
||||
dir = (dir[0], dir[1], 0);
|
||||
isect = vecscale(vectornormalize(dir),circleradius) + targetpos;
|
||||
isect = (isect[0], isect[1], descendEnt.origin[2]);
|
||||
|
||||
dist = distance(isect, descendEnt.origin);
|
||||
if (dist <= descendEnt.radius) {
|
||||
dist = distance(isect, startorigin);
|
||||
if (!isdefined(bestpoint) || dist < bestdist) {
|
||||
bestdist = dist;
|
||||
bestpoint = isect;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestpoint;
|
||||
}
|
||||
// determines the best entity out of descendEnts to go to
|
||||
// in order to get at one of targets.
|
||||
// result["descendEnt"] is the winning entity,
|
||||
// result["position"] is the position to go to.
|
||||
determineBestEnt(targets, descendEnts, startorigin)
|
||||
{
|
||||
result = [];
|
||||
|
||||
bestpos = undefined;
|
||||
bestent = 0;
|
||||
bestdist = 0;
|
||||
for (i = 0; i < descendEnts.size; i++)
|
||||
{
|
||||
thispos = determineBestPos(targets, descendEnts[i], startorigin);
|
||||
if (isdefined(thispos)) {
|
||||
thisdist = distance(thispos, startorigin);
|
||||
if (!isdefined(bestpos) || thisdist < bestdist) {
|
||||
bestpos = thispos;
|
||||
bestent = i;
|
||||
bestdist = thisdist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isdefined(bestpos)) {
|
||||
result["descendEnt"] = descendEnts[bestent];
|
||||
result["position"] = bestpos;
|
||||
return result;
|
||||
}
|
||||
|
||||
result["descendEnt"] = undefined;
|
||||
return result;
|
||||
}
|
||||
|
||||
determineBestAttackPos(targetpos, curpos, desireddist)
|
||||
{
|
||||
targetposcopterheight = (targetpos[0], targetpos[1], curpos[2]);
|
||||
attackdirx = curpos - targetposcopterheight;
|
||||
attackdirx = vectornormalize(attackdirx);
|
||||
attackdiry = (0-attackdirx[1], attackdirx[0], 0);
|
||||
|
||||
bestpos = undefined;
|
||||
bestdist = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
theta = (i/8.0) * 360;
|
||||
thisdir = vecscale(attackdirx, cos(theta)) + vecscale(attackdiry, sin(theta));
|
||||
traceend = targetposcopterheight + vecscale(thisdir, desireddist);
|
||||
|
||||
losexists = bullettracepassed(targetpos, traceend, false, undefined);
|
||||
if (losexists) {
|
||||
thisdist = distance(traceend, curpos);
|
||||
if (!isdefined(bestpos) || thisdist < bestdist) {
|
||||
bestpos = traceend;
|
||||
bestdist = thisdist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goToPos = undefined;
|
||||
if (isdefined(bestpos)) {
|
||||
goToPos = bestpos;
|
||||
}
|
||||
else {
|
||||
dist = distance(targetposcopterheight, curpos);
|
||||
if (dist > desireddist)
|
||||
goToPos = self.origin + vecscale(vectornormalize(attackdirx), 0-(dist - desireddist));
|
||||
else
|
||||
goToPos = self.origin;
|
||||
}
|
||||
return goToPos;
|
||||
}
|
||||
|
||||
getRandomPos(origin, radius)
|
||||
{
|
||||
// no sqrt so have to do this the guess and check way.
|
||||
|
||||
pos = origin + ((randomfloat(2)-1)*radius, (randomfloat(2)-1)*radius, 0);
|
||||
while(distanceSquared(pos, origin) > radius*radius)
|
||||
pos = origin + ((randomfloat(2)-1)*radius, (randomfloat(2)-1)*radius, 0);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
copterShoot()
|
||||
{
|
||||
self endon("death");
|
||||
self endon("passive");
|
||||
|
||||
cosThreshold = cos(10);
|
||||
while(1)
|
||||
{
|
||||
if (isdefined(self.desiredDirEntity) && isdefined(self.desiredDirEntity.origin)) {
|
||||
mypos = self.origin + level.copterCenterOffset;
|
||||
enemypos = self.desiredDirEntity.origin + self.desiredDirEntityOffset;
|
||||
curdir = anglesToForward(self.angles);
|
||||
enemydirraw = enemypos - mypos;
|
||||
enemydir = vectornormalize(enemydirraw);
|
||||
|
||||
if (vectordot(curdir, enemydir) > cosThreshold)
|
||||
{
|
||||
canseetarget = bullettracepassed(mypos, enemypos, false, undefined);
|
||||
if (!canseetarget && isplayer(self.desiredDirEntity) && isalive(self.desiredDirEntity))
|
||||
canseetarget = bullettracepassed(mypos, self.desiredDirEntity getEye(), false, undefined);
|
||||
if (canseetarget) {
|
||||
// shoot.
|
||||
self playSound("mp_copter_shoot");
|
||||
numshots = 20;
|
||||
for (i = 0; i < numshots; i++)
|
||||
{
|
||||
mypos = self.origin + level.copterCenterOffset;
|
||||
/*if (isdefined(self.desiredDirEntity)) {
|
||||
enemypos = self.desiredDirEntity.origin + self.desiredDirEntityOffset;
|
||||
enemydirraw = enemypos - mypos;
|
||||
enemydir = vectornormalize(enemydirraw);
|
||||
dir = enemydir;
|
||||
}
|
||||
else*/
|
||||
dir = anglesToForward(self.angles);
|
||||
|
||||
dir = dir + ((randomfloat(2)-1)*.015, (randomfloat(2)-1)*.015, (randomfloat(2)-1)*.015);
|
||||
dir = vectornormalize(dir);
|
||||
self myMagicBullet(mypos, dir);
|
||||
wait(.075);
|
||||
}
|
||||
wait(.25);
|
||||
}
|
||||
//else
|
||||
//iprintln("can't see");
|
||||
}
|
||||
//else
|
||||
//iprintln("below cosThreshold: ", vectordot(curdir, enemydir), " < ", cosThreshold);
|
||||
}
|
||||
//else
|
||||
//iprintln("no target");
|
||||
wait(.25);
|
||||
}
|
||||
}
|
||||
myMagicBullet(pos, dir)
|
||||
{
|
||||
damage = 20;
|
||||
if (getdvar("scr_copter_damage") != "")
|
||||
damage = getdvarint("scr_copter_damage");
|
||||
|
||||
// for now just shoot from origin
|
||||
trace = bullettrace(pos, pos + vecscale(dir, 10000), true, undefined);
|
||||
if (isdefined(trace["entity"]) && isplayer(trace["entity"]) && isalive(trace["entity"])) {
|
||||
// hurt entity shot at
|
||||
trace["entity"] thread [[level.callbackPlayerDamage]](
|
||||
self, // eInflictor The entity that causes the damage.(e.g. a turret)
|
||||
self, // eAttacker The entity that is attacking.
|
||||
damage, // iDamage Integer specifying the amount of damage done
|
||||
0, // iDFlags Integer specifying flags that are to be applied to the damage
|
||||
"MOD_RIFLE_BULLET", // sMeansOfDeath Integer specifying the method of death
|
||||
"copter", // sWeapon The weapon number of the weapon used to inflict the damage
|
||||
self.origin, // vPoint The point the damage is from?
|
||||
dir, // vDir The direction of the damage
|
||||
"none", // sHitLoc The location of the hit
|
||||
0 // psOffsetTime The time offset for the damage
|
||||
);
|
||||
}
|
||||
//line(pos, trace["position"], (1,1,1));
|
||||
}
|
||||
|
||||
setCopterDest(newlocation, descend, dontascend)
|
||||
{
|
||||
self.finalDest = getAboveBuildingsLocation(newlocation);
|
||||
if (isdefined(descend) && descend)
|
||||
self.finalZDest = newlocation[2];
|
||||
else
|
||||
self.finalZDest = self.finalDest[2];
|
||||
|
||||
self.intransit = true;
|
||||
self.dontascend = false;
|
||||
if (isdefined(dontascend))
|
||||
self.dontascend = dontascend;
|
||||
}
|
||||
notifyArrived()
|
||||
{
|
||||
wait .05;
|
||||
self notify("arrived");
|
||||
}
|
||||
|
||||
vecscale(vec, scalar)
|
||||
{
|
||||
return (vec[0]*scalar, vec[1]*scalar, vec[2]*scalar);
|
||||
}
|
||||
|
||||
abs(x)
|
||||
{
|
||||
if (x < 0)
|
||||
return 0-x;
|
||||
return x;
|
||||
}
|
||||
|
||||
copterMove()
|
||||
{
|
||||
self endon("death");
|
||||
|
||||
if (isdefined(self.copterMoveRunning))
|
||||
return;
|
||||
self.copterMoveRunning = true;
|
||||
|
||||
self.intransit = false;
|
||||
interval = .15;
|
||||
zinterp = .1;
|
||||
tiltamnt = 0;
|
||||
while(1)
|
||||
{
|
||||
horizDistSquared = distanceSquared((self.origin[0], self.origin[1], 0), (self.finalDest[0], self.finalDest[1], 0));
|
||||
|
||||
doneMoving = horizDistSquared < 10*10;
|
||||
|
||||
//if (!doneMoving)
|
||||
{
|
||||
nearDest = (horizDistSquared < 256*256);
|
||||
|
||||
self.intransit = true;
|
||||
|
||||
desiredZ = 0;
|
||||
|
||||
// movement
|
||||
movingHorizontally = true;
|
||||
movingVertically = false;
|
||||
if (self.dontascend)
|
||||
movingVertically = true;
|
||||
else {
|
||||
// if we're not near our horizontal goal position
|
||||
if (!nearDest) {
|
||||
// get the z position we *want* to have before moving horizontally
|
||||
desiredZ = getAboveBuildingsLocation(self.origin)[2];
|
||||
movingHorizontally = (abs(self.origin[2] - desiredZ) <= 256); // we're moving horizontally if we're up high enough to do so
|
||||
movingVertically = !movingHorizontally; // we're moving vertically if we aren't
|
||||
}
|
||||
// if we are near our horizontal goal position
|
||||
else
|
||||
movingVertically = true;
|
||||
}
|
||||
|
||||
// determine our destination
|
||||
if (movingHorizontally) {
|
||||
if (movingVertically)
|
||||
thisDest = (self.finalDest[0], self.finalDest[1], self.finalZDest);
|
||||
else
|
||||
thisDest = self.finalDest;
|
||||
}
|
||||
else {
|
||||
assert(movingVertically);
|
||||
thisDest = (self.origin[0], self.origin[1], desiredZ);
|
||||
}
|
||||
|
||||
movevec = thisDest - self.origin;
|
||||
|
||||
idealAccel = vecscale(thisDest - (self.origin + vecscale(self.vel, level.copter_accellookahead)), interval);
|
||||
vlen = veclength(idealAccel);
|
||||
if (vlen > level.copter_maxaccel) {
|
||||
idealAccel = vecscale(idealAccel, level.copter_maxaccel / vlen);
|
||||
}
|
||||
|
||||
self.vel = self.vel + idealAccel;
|
||||
vlen = veclength(self.vel);
|
||||
if (vlen > level.copter_maxvel) {
|
||||
self.vel = vecscale(self.vel, level.copter_maxvel / vlen);
|
||||
}
|
||||
|
||||
thisDest = self.origin + vecscale(self.vel, interval);
|
||||
|
||||
self moveto(thisDest, interval*.999);
|
||||
|
||||
speed = veclength(self.vel);
|
||||
|
||||
if (isdefined(self.desiredDirEntity) && isdefined(self.desiredDirEntity.origin)) {
|
||||
self.destDir = vectornormalize((self.desiredDirEntity.origin + self.desiredDirEntityOffset) - (self.origin + level.copterCenterOffset));
|
||||
}
|
||||
else if (isdefined(self.desiredDir)) {
|
||||
self.destDir = self.desiredDir;
|
||||
}
|
||||
else if (movingVertically) {
|
||||
self.destDir = anglesToForward(self.angles);
|
||||
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], 0));
|
||||
}
|
||||
else {
|
||||
tiltamnt = speed / level.copter_maxvel;
|
||||
tiltamnt = (tiltamnt - .1) / .9; if (tiltamnt < 0) tiltamnt = 0;
|
||||
|
||||
self.destDir = movevec;
|
||||
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], 0)); // remove z component
|
||||
tiltamnt = tiltamnt * (1 - (vectorAngle(anglesToForward(self.angles), self.destDir) / 180));
|
||||
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], tiltamnt * -.4)); // tilt forward while moving
|
||||
}
|
||||
}
|
||||
/*else {
|
||||
if (self.intransit) {
|
||||
self.intransit = false;
|
||||
self.dontascend = false;
|
||||
|
||||
// if we descended to get to this point, we'll be ascending to get out
|
||||
if (self.finalZDest != self.finalDest[2])
|
||||
self.ascending = true;
|
||||
|
||||
self notify("arrived");
|
||||
}
|
||||
|
||||
if (isdefined(self.desiredDir))
|
||||
self.destDir = self.desiredDir;
|
||||
else {
|
||||
self.destDir = anglesToForward(self.angles);
|
||||
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], 0));
|
||||
}
|
||||
}*/
|
||||
|
||||
// rotation
|
||||
newdir = self.destDir;
|
||||
//line(self.origin + level.copterCenterOffset, self.origin + level.copterCenterOffset + vecscale(self.destDir,10000), (1,0,0));
|
||||
if (newdir[2] < -.4) {// *never* look too far down
|
||||
newdir = vectornormalize((newdir[0], newdir[1], -.4));
|
||||
}
|
||||
//line(self.origin + level.copterCenterOffset, self.origin + level.copterCenterOffset + vecscale(newdir,10000), (1,1,0));
|
||||
|
||||
copterangles = self.angles;
|
||||
copterangles = combineangles(copterangles, (0,90,0));
|
||||
olddir = anglesToForward(copterangles);
|
||||
|
||||
thisRotSpeed = level.copter_rotspeed;
|
||||
//if (movelen < 256)
|
||||
// thisRotSpeed = thisRotSpeed * movelen / 256;
|
||||
|
||||
olddir2d = vectornormalize((olddir[0], olddir[1], 0));
|
||||
newdir2d = vectornormalize((newdir[0], newdir[1], 0));
|
||||
|
||||
angle = vectorAngle(olddir2d, newdir2d);
|
||||
angle3d = vectorAngle(olddir, newdir);
|
||||
|
||||
if (angle > .001 && thisRotSpeed > .001) {
|
||||
thisangle = thisRotSpeed * interval;
|
||||
if (thisangle > angle)
|
||||
thisangle = angle;
|
||||
|
||||
newdir2d = vectorTowardsOtherVector(olddir2d, newdir2d, thisangle);
|
||||
oldz = olddir[2]/veclength((olddir[0], olddir[1], 0));
|
||||
newz = newdir[2]/veclength((newdir[0], newdir[1], 0));
|
||||
interpz = oldz + (newz - oldz) * (thisangle / angle);
|
||||
newdir = vectornormalize((newdir2d[0], newdir2d[1], interpz));
|
||||
|
||||
copterangles = vectorToAngles(newdir);
|
||||
copterangles = combineangles(copterangles, (0,-90,0));
|
||||
self rotateto(copterangles, interval*.999);
|
||||
}
|
||||
else if (angle3d > .001 && thisRotSpeed > .001) {
|
||||
// need to rotate vertically
|
||||
thisangle = thisRotSpeed * interval;
|
||||
if (thisangle > angle3d)
|
||||
thisangle = angle3d;
|
||||
|
||||
newdir = vectorTowardsOtherVector(olddir, newdir, thisangle);
|
||||
newdir = vectornormalize(newdir);
|
||||
|
||||
copterangles = vectorToAngles(newdir);
|
||||
copterangles = combineangles(copterangles, (0,-90,0));
|
||||
self rotateto(copterangles, interval*.999);
|
||||
}
|
||||
|
||||
wait interval;
|
||||
}
|
||||
}
|
||||
|
||||
copterDamage(damagetrig)
|
||||
{
|
||||
self endon("passive");
|
||||
|
||||
while(1)
|
||||
{
|
||||
damagetrig waittill("damage", amount, attacker);
|
||||
|
||||
// disallow friendly fire
|
||||
if (isdefined(attacker) && isplayer(attacker) && isdefined(attacker.pers["team"]) && attacker.pers["team"] == self.team)
|
||||
continue;
|
||||
|
||||
self.health -= amount;
|
||||
if (self.health <= 0) {
|
||||
self thread copterDie();
|
||||
return;
|
||||
}
|
||||
//iprintln("OW ", amount);
|
||||
}
|
||||
}
|
||||
|
||||
copterDie()
|
||||
{
|
||||
self endon("passive");
|
||||
|
||||
self notify("death");
|
||||
self.dead = true;
|
||||
|
||||
self thread copterExplodeFX();
|
||||
|
||||
// crash.
|
||||
interval = .2;
|
||||
rottime = 15;
|
||||
self rotateyaw(360 + randomfloat(360), rottime);
|
||||
self rotatepitch(360 + randomfloat(360), rottime);
|
||||
self rotateroll(360 + randomfloat(360), rottime);
|
||||
while(1)
|
||||
{
|
||||
self.vel = self.vel + vecscale((0,0,-200), interval);
|
||||
newpos = self.origin + vecscale(self.vel, interval);
|
||||
|
||||
// check for collision with ground
|
||||
pathclear = bullettracepassed(self.origin, newpos, false, undefined);
|
||||
if (!pathclear)
|
||||
break;
|
||||
|
||||
self moveto(newpos, interval*.999);
|
||||
|
||||
wait (interval);
|
||||
}
|
||||
|
||||
playfx (level.copterfinalexplosion, self.origin);
|
||||
playsoundatpos( self.origin, "mp_copter_explosion" );
|
||||
self notify("finaldeath");
|
||||
|
||||
deleteCopter();
|
||||
}
|
||||
deleteCopter()
|
||||
{
|
||||
if (isdefined(self.damagetrig)) {
|
||||
self.damagetrig notify("unlink");
|
||||
self.damagetrig = undefined;
|
||||
}
|
||||
self.copter delete();
|
||||
self delete();
|
||||
}
|
||||
copterExplodeFX()
|
||||
{
|
||||
self endon("finaldeath");
|
||||
|
||||
while(1)
|
||||
{
|
||||
playfx (level.copterexplosion, self.origin);
|
||||
self playsound("mp_copter_explosion");
|
||||
wait .5 + randomfloat(1);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,93 @@
|
||||
init()
|
||||
{
|
||||
precacheShader("damage_feedback");
|
||||
precacheShader("damage_feedback_j");
|
||||
precacheShader("damage_feedback_endgame");
|
||||
precacheShader("scavenger_pickup");
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player.hud_damagefeedback = newClientHudElem(player);
|
||||
player.hud_damagefeedback.horzAlign = "center";
|
||||
player.hud_damagefeedback.vertAlign = "middle";
|
||||
player.hud_damagefeedback.x = -12;
|
||||
player.hud_damagefeedback.y = -12;
|
||||
player.hud_damagefeedback.alpha = 0;
|
||||
player.hud_damagefeedback.archived = true;
|
||||
player.hud_damagefeedback setShader("damage_feedback", 24, 48);
|
||||
}
|
||||
}
|
||||
|
||||
updateDamageFeedback( typeHit )
|
||||
{
|
||||
if ( !isPlayer( self ) )
|
||||
return;
|
||||
|
||||
x = -12;
|
||||
y = -12;
|
||||
|
||||
if ( getDvarInt( "camera_thirdPerson" ) )
|
||||
yOffset = self GetThirdPersonCrosshairOffset() * 240;
|
||||
else
|
||||
yOffset = getdvarfloat( "cg_crosshairVerticalOffset" ) * 240;
|
||||
|
||||
if ( level.splitscreen )
|
||||
yOffset *= 0.5;
|
||||
|
||||
feedbackDurationOverride = 0;
|
||||
startAlpha = 1;
|
||||
|
||||
if ( typeHit == "hitBodyArmor" )
|
||||
{
|
||||
self.hud_damagefeedback setShader("damage_feedback_j", 24, 48);
|
||||
self playlocalsound("MP_hit_alert"); // TODO: change sound?
|
||||
}
|
||||
else if ( typeHit == "hitEndGame" )
|
||||
{
|
||||
self.hud_damagefeedback setShader("damage_feedback_endgame", 24, 48);
|
||||
self playlocalsound("MP_hit_alert");
|
||||
}
|
||||
else if ( typeHit == "stun" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if ( typeHit == "none" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if ( typeHit == "scavenger" && !level.hardcoreMode )
|
||||
{
|
||||
x = -36;
|
||||
y = 32;
|
||||
self.hud_damagefeedback setShader("scavenger_pickup", 64, 32);
|
||||
feedbackDurationOverride = 2.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.hud_damagefeedback setShader("damage_feedback", 24, 48);
|
||||
self playlocalsound("MP_hit_alert");
|
||||
}
|
||||
|
||||
self.hud_damagefeedback.alpha = startAlpha;
|
||||
if ( feedBackDurationOverride != 0 )
|
||||
self.hud_damagefeedback fadeOverTime(feedbackDurationOverride);
|
||||
else
|
||||
self.hud_damagefeedback fadeOverTime(1);
|
||||
|
||||
self.hud_damagefeedback.alpha = 0;
|
||||
|
||||
// only update hudelem positioning when necessary
|
||||
if ( self.hud_damagefeedback.x != x )
|
||||
self.hud_damagefeedback.x = x;
|
||||
|
||||
y = y - int( yOffset );
|
||||
if ( self.hud_damagefeedback.y != y )
|
||||
self.hud_damagefeedback.y = y;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
if (!level.teambased)
|
||||
return;
|
||||
|
||||
precacheShader("headicon_dead");
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player.selfDeathIcons = []; // icons that other people see which point to this player when he's dead
|
||||
}
|
||||
}
|
||||
|
||||
updateDeathIconsEnabled()
|
||||
{
|
||||
//if (!self.enableDeathIcons)
|
||||
// self removeOtherDeathIcons();
|
||||
}
|
||||
|
||||
addDeathIcon( entity, dyingplayer, team, timeout )
|
||||
{
|
||||
if ( !level.teambased )
|
||||
return;
|
||||
|
||||
iconOrg = entity.origin;
|
||||
|
||||
dyingplayer endon("spawned_player");
|
||||
dyingplayer endon("disconnect");
|
||||
|
||||
wait .05;
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
assert(team == "allies" || team == "axis");
|
||||
|
||||
if ( getDvar( "ui_hud_showdeathicons" ) == "0" )
|
||||
return;
|
||||
if ( level.hardcoreMode )
|
||||
return;
|
||||
|
||||
if ( isdefined( self.lastDeathIcon ) )
|
||||
self.lastDeathIcon destroy();
|
||||
|
||||
newdeathicon = newTeamHudElem( team );
|
||||
newdeathicon.x = iconOrg[0];
|
||||
newdeathicon.y = iconOrg[1];
|
||||
newdeathicon.z = iconOrg[2] + 54;
|
||||
newdeathicon.alpha = .61;
|
||||
newdeathicon.archived = true;
|
||||
if ( level.splitscreen )
|
||||
newdeathicon setShader("headicon_dead", 14, 14);
|
||||
else
|
||||
newdeathicon setShader("headicon_dead", 7, 7);
|
||||
newdeathicon setwaypoint( true, false );
|
||||
|
||||
self.lastDeathIcon = newdeathicon;
|
||||
|
||||
newdeathicon thread destroySlowly ( timeout );
|
||||
}
|
||||
|
||||
destroySlowly( timeout )
|
||||
{
|
||||
self endon("death");
|
||||
|
||||
wait timeout;
|
||||
|
||||
self fadeOverTime(1.0);
|
||||
self.alpha = 0;
|
||||
|
||||
wait 1.0;
|
||||
self destroy();
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,120 @@
|
||||
init()
|
||||
{
|
||||
// Draws a team icon over teammates
|
||||
level.drawfriend = 0;
|
||||
|
||||
game["headicon_allies"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "allies" );
|
||||
game["headicon_axis"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "axis" );
|
||||
|
||||
precacheHeadIcon( game["headicon_allies"] );
|
||||
precacheHeadIcon( game["headicon_axis"] );
|
||||
|
||||
precacheShader( "waypoint_revive" );
|
||||
|
||||
level thread onPlayerConnect();
|
||||
|
||||
for(;;)
|
||||
{
|
||||
updateFriendIconSettings();
|
||||
wait 5;
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player thread onPlayerSpawned();
|
||||
player thread onPlayerKilled();
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("spawned_player");
|
||||
|
||||
self thread showFriendIcon();
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerKilled()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("killed_player");
|
||||
self.headicon = "";
|
||||
}
|
||||
}
|
||||
|
||||
showFriendIcon()
|
||||
{
|
||||
if(level.drawfriend)
|
||||
{
|
||||
if(self.pers["team"] == "allies")
|
||||
{
|
||||
self.headicon = game["headicon_allies"];
|
||||
self.headiconteam = "allies";
|
||||
}
|
||||
else
|
||||
{
|
||||
self.headicon = game["headicon_axis"];
|
||||
self.headiconteam = "axis";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateFriendIconSettings()
|
||||
{
|
||||
drawfriend = maps\mp\_utility::getIntProperty("scr_drawfriend", level.drawfriend);
|
||||
if(level.drawfriend != drawfriend)
|
||||
{
|
||||
level.drawfriend = drawfriend;
|
||||
updateFriendIcons();
|
||||
}
|
||||
}
|
||||
|
||||
updateFriendIcons()
|
||||
{
|
||||
// for all living players, show the appropriate headicon
|
||||
players = level.players;
|
||||
for(i = 0; i < players.size; i++)
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
|
||||
{
|
||||
if(level.drawfriend)
|
||||
{
|
||||
if(player.pers["team"] == "allies")
|
||||
{
|
||||
player.headicon = game["headicon_allies"];
|
||||
player.headiconteam = "allies";
|
||||
}
|
||||
else
|
||||
{
|
||||
player.headicon = game["headicon_axis"];
|
||||
player.headiconteam = "axis";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
players = level.players;
|
||||
for(i = 0; i < players.size; i++)
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
|
||||
player.headicon = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,414 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
|
||||
|
||||
|
||||
getHighestScoringPlayer()
|
||||
{
|
||||
updatePlacement();
|
||||
|
||||
if ( !level.placement["all"].size )
|
||||
return ( undefined );
|
||||
else
|
||||
return ( level.placement["all"][0] );
|
||||
}
|
||||
|
||||
|
||||
getLosingPlayers()
|
||||
{
|
||||
updatePlacement();
|
||||
|
||||
players = level.placement["all"];
|
||||
losingPlayers = [];
|
||||
|
||||
foreach ( player in players )
|
||||
{
|
||||
if ( player == level.placement["all"][0] )
|
||||
continue;
|
||||
|
||||
losingPlayers[losingPlayers.size] = player;
|
||||
}
|
||||
|
||||
return losingPlayers;
|
||||
}
|
||||
|
||||
|
||||
givePlayerScore( event, player, victim )
|
||||
{
|
||||
if ( isDefined( level.nukeIncoming ) )
|
||||
return;
|
||||
|
||||
score = player.pers["score"];
|
||||
onPlayerScore( event, player, victim );
|
||||
|
||||
if ( score == player.pers["score"] )
|
||||
return;
|
||||
|
||||
if ( !player rankingEnabled() && !level.hardcoreMode )
|
||||
player thread maps\mp\gametypes\_rank::scorePopup( (player.pers["score"] - score), false, (0.85,0.85,0.85), 0 );
|
||||
|
||||
player maps\mp\gametypes\_persistence::statAdd( "score", (player.pers["score"] - score) );
|
||||
|
||||
player.score = player.pers["score"];
|
||||
player maps\mp\gametypes\_persistence::statSetChild( "round", "score", player.score );
|
||||
|
||||
if ( !level.teambased )
|
||||
thread sendUpdatedDMScores();
|
||||
|
||||
player maps\mp\gametypes\_gamelogic::checkPlayerScoreLimitSoon();
|
||||
scoreEndedMatch = player maps\mp\gametypes\_gamelogic::checkScoreLimit();
|
||||
|
||||
if ( scoreEndedMatch && event == "kill" )
|
||||
player.finalKill = true;
|
||||
}
|
||||
|
||||
|
||||
onPlayerScore( event, player, victim )
|
||||
{
|
||||
score = maps\mp\gametypes\_rank::getScoreInfoValue( event );
|
||||
|
||||
assert( isDefined( score ) );
|
||||
|
||||
player.pers["score"] += score * level.objectivePointsMod;
|
||||
}
|
||||
|
||||
|
||||
// Seems to only be used for reducing a player's score due to suicide
|
||||
_setPlayerScore( player, score )
|
||||
{
|
||||
if ( score == player.pers["score"] )
|
||||
return;
|
||||
|
||||
player.pers["score"] = score;
|
||||
player.score = player.pers["score"];
|
||||
|
||||
player thread maps\mp\gametypes\_gamelogic::checkScoreLimit();
|
||||
}
|
||||
|
||||
|
||||
_getPlayerScore( player )
|
||||
{
|
||||
return player.pers["score"];
|
||||
}
|
||||
|
||||
|
||||
giveTeamScoreForObjective( team, score )
|
||||
{
|
||||
if ( isDefined( level.nukeIncoming ) )
|
||||
return;
|
||||
|
||||
score *= level.objectivePointsMod;
|
||||
|
||||
teamScore = game["teamScores"][team];
|
||||
|
||||
otherTeam = level.otherTeam[team];
|
||||
|
||||
if ( game["teamScores"][team] > game["teamScores"][otherTeam] )
|
||||
level.wasWinning = team;
|
||||
else if ( game["teamScores"][otherTeam] > game["teamScores"][team] )
|
||||
level.wasWinning = otherTeam;
|
||||
|
||||
_setTeamScore( team, _getTeamScore( team ) + score );
|
||||
|
||||
isWinning = "none";
|
||||
if ( game["teamScores"][team] > game["teamScores"][otherTeam] )
|
||||
isWinning = team;
|
||||
else if ( game["teamScores"][otherTeam] > game["teamScores"][team] )
|
||||
isWinning = otherTeam;
|
||||
|
||||
if ( !level.splitScreen && isWinning != "none" && isWinning != level.wasWinning && getTime() - level.lastStatusTime > 5000 && getScoreLimit() != 1 )
|
||||
{
|
||||
level.lastStatusTime = getTime();
|
||||
leaderDialog( "lead_taken", isWinning, "status" );
|
||||
if ( level.wasWinning != "none")
|
||||
leaderDialog( "lead_lost", level.wasWinning, "status" );
|
||||
}
|
||||
|
||||
if ( isWinning != "none" )
|
||||
level.wasWinning = isWinning;
|
||||
}
|
||||
|
||||
|
||||
getWinningTeam()
|
||||
{
|
||||
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
|
||||
return ( "allies" );
|
||||
else if ( game["teamScores"]["allies"] < game["teamScores"]["axis"] )
|
||||
return ( "axis" );
|
||||
|
||||
return ( "none" );
|
||||
}
|
||||
|
||||
_setTeamScore( team, teamScore )
|
||||
{
|
||||
if ( teamScore == game["teamScores"][team] )
|
||||
return;
|
||||
|
||||
if ( isDefined( level.nukeIncoming ) )
|
||||
return;
|
||||
|
||||
game["teamScores"][team] = teamScore;
|
||||
|
||||
updateTeamScore( team );
|
||||
|
||||
if ( game["status"] == "overtime" )
|
||||
thread maps\mp\gametypes\_gamelogic::onScoreLimit();
|
||||
else
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::checkTeamScoreLimitSoon( team );
|
||||
thread maps\mp\gametypes\_gamelogic::checkScoreLimit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateTeamScore( team )
|
||||
{
|
||||
assert( level.teamBased );
|
||||
|
||||
teamScore = 0;
|
||||
if ( !isRoundBased() || !isObjectiveBased() )
|
||||
teamScore = _getTeamScore( team );
|
||||
else
|
||||
teamScore = game["roundsWon"][team];
|
||||
|
||||
setTeamScore( team, teamScore );
|
||||
|
||||
//thread sendUpdatedTeamScores();
|
||||
}
|
||||
|
||||
|
||||
_getTeamScore( team )
|
||||
{
|
||||
return game["teamScores"][team];
|
||||
}
|
||||
|
||||
|
||||
sendUpdatedTeamScores()
|
||||
{
|
||||
level notify("updating_scores");
|
||||
level endon("updating_scores");
|
||||
wait .05;
|
||||
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
foreach ( player in level.players )
|
||||
player updateScores();
|
||||
}
|
||||
|
||||
sendUpdatedDMScores()
|
||||
{
|
||||
level notify("updating_dm_scores");
|
||||
level endon("updating_dm_scores");
|
||||
wait .05;
|
||||
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
for ( i = 0; i < level.players.size; i++ )
|
||||
{
|
||||
level.players[i] updateDMScores();
|
||||
level.players[i].updatedDMScores = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
removeDisconnectedPlayerFromPlacement()
|
||||
{
|
||||
offset = 0;
|
||||
numPlayers = level.placement["all"].size;
|
||||
found = false;
|
||||
for ( i = 0; i < numPlayers; i++ )
|
||||
{
|
||||
if ( level.placement["all"][i] == self )
|
||||
found = true;
|
||||
|
||||
if ( found )
|
||||
level.placement["all"][i] = level.placement["all"][ i + 1 ];
|
||||
}
|
||||
if ( !found )
|
||||
return;
|
||||
|
||||
level.placement["all"][ numPlayers - 1 ] = undefined;
|
||||
assert( level.placement["all"].size == numPlayers - 1 );
|
||||
|
||||
if ( level.teamBased )
|
||||
{
|
||||
updateTeamPlacement();
|
||||
return;
|
||||
}
|
||||
|
||||
numPlayers = level.placement["all"].size;
|
||||
for ( i = 0; i < numPlayers; i++ )
|
||||
{
|
||||
player = level.placement["all"][i];
|
||||
player notify( "update_outcome" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updatePlacement()
|
||||
{
|
||||
prof_begin("updatePlacement");
|
||||
|
||||
placementAll = [];
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( isDefined( player.connectedPostGame ) || (player.pers["team"] != "allies" && player.pers["team"] != "axis") )
|
||||
continue;
|
||||
|
||||
placementAll[placementAll.size] = player;
|
||||
}
|
||||
|
||||
for ( i = 1; i < placementAll.size; i++ )
|
||||
{
|
||||
player = placementAll[i];
|
||||
playerScore = player.score;
|
||||
// for ( j = i - 1; j >= 0 && (player.score > placementAll[j].score || (player.score == placementAll[j].score && player.deaths < placementAll[j].deaths)); j-- )
|
||||
for ( j = i - 1; j >= 0 && getBetterPlayer( player, placementAll[j] ) == player; j-- )
|
||||
placementAll[j + 1] = placementAll[j];
|
||||
placementAll[j + 1] = player;
|
||||
}
|
||||
|
||||
level.placement["all"] = placementAll;
|
||||
|
||||
if ( level.teamBased )
|
||||
updateTeamPlacement();
|
||||
|
||||
prof_end("updatePlacement");
|
||||
}
|
||||
|
||||
|
||||
getBetterPlayer( playerA, playerB )
|
||||
{
|
||||
if ( playerA.score > playerB.score )
|
||||
return playerA;
|
||||
|
||||
if ( playerB.score > playerA.score )
|
||||
return playerB;
|
||||
|
||||
if ( playerA.deaths < playerB.deaths )
|
||||
return playerA;
|
||||
|
||||
if ( playerB.deaths < playerA.deaths )
|
||||
return playerB;
|
||||
|
||||
// TODO: more metrics for getting the better player
|
||||
|
||||
if ( cointoss() )
|
||||
return playerA;
|
||||
else
|
||||
return playerB;
|
||||
}
|
||||
|
||||
|
||||
updateTeamPlacement()
|
||||
{
|
||||
placement["allies"] = [];
|
||||
placement["axis"] = [];
|
||||
placement["spectator"] = [];
|
||||
|
||||
assert( level.teamBased );
|
||||
|
||||
placementAll = level.placement["all"];
|
||||
placementAllSize = placementAll.size;
|
||||
|
||||
for ( i = 0; i < placementAllSize; i++ )
|
||||
{
|
||||
player = placementAll[i];
|
||||
team = player.pers["team"];
|
||||
|
||||
placement[team][ placement[team].size ] = player;
|
||||
}
|
||||
|
||||
level.placement["allies"] = placement["allies"];
|
||||
level.placement["axis"] = placement["axis"];
|
||||
}
|
||||
|
||||
|
||||
initialDMScoreUpdate()
|
||||
{
|
||||
// the first time we call updateDMScores on a player, we have to send them the whole scoreboard.
|
||||
// by calling updateDMScores on each player one at a time,
|
||||
// we can avoid having to send the entire scoreboard to every single player
|
||||
// the first time someone kills someone else.
|
||||
wait .2;
|
||||
numSent = 0;
|
||||
while(1)
|
||||
{
|
||||
didAny = false;
|
||||
|
||||
players = level.players;
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if ( !isdefined( player ) )
|
||||
continue;
|
||||
|
||||
if ( isdefined( player.updatedDMScores ) )
|
||||
continue;
|
||||
|
||||
player.updatedDMScores = true;
|
||||
player updateDMScores();
|
||||
|
||||
didAny = true;
|
||||
wait .5;
|
||||
}
|
||||
|
||||
if ( !didAny )
|
||||
wait 3; // let more players connect
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
processAssist( killedplayer )
|
||||
{
|
||||
self endon("disconnect");
|
||||
killedplayer endon("disconnect");
|
||||
|
||||
wait .05; // don't ever run on the same frame as the playerkilled callback.
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
|
||||
return;
|
||||
|
||||
if ( self.pers["team"] == killedplayer.pers["team"] )
|
||||
return;
|
||||
|
||||
self thread [[level.onXPEvent]]( "assist" );
|
||||
self incPersStat( "assists", 1 );
|
||||
self.assists = self getPersStat( "assists" );
|
||||
self incPlayerStat( "assists", 1 );
|
||||
|
||||
givePlayerScore( "assist", self, killedplayer );
|
||||
self thread giveAdrenaline( "assist" );
|
||||
|
||||
self thread maps\mp\gametypes\_missions::playerAssist();
|
||||
}
|
||||
|
||||
processShieldAssist( killedPlayer )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
killedPlayer endon( "disconnect" );
|
||||
|
||||
wait .05; // don't ever run on the same frame as the playerkilled callback.
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
|
||||
return;
|
||||
|
||||
if ( self.pers["team"] == killedplayer.pers["team"] )
|
||||
return;
|
||||
|
||||
self thread [[level.onXPEvent]]( "assist" );
|
||||
self thread [[level.onXPEvent]]( "assist" );
|
||||
self incPersStat( "assists", 1 );
|
||||
self.assists = self getPersStat( "assists" );
|
||||
self incPlayerStat( "assists", 1 );
|
||||
|
||||
givePlayerScore( "assist", self, killedplayer );
|
||||
|
||||
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "shield_assist" );
|
||||
|
||||
self thread maps\mp\gametypes\_missions::playerAssist();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/*QUAKED mp_global_intermission (1.0 0.0 1.0) (-16 -16 -16) (16 16 16)
|
||||
Intermission is randomly viewed from one of these positions.
|
||||
Spectators spawn randomly at one of these positions.
|
||||
*/
|
||||
@@ -0,0 +1,255 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.splitscreen = isSplitScreen();
|
||||
level.ps3 = (getDvar( "ps3Game" ) == "true");
|
||||
level.xenon = (getDvar( "xenonGame" ) == "true");
|
||||
level.console = (level.ps3 || level.xenon);
|
||||
|
||||
level.onlineGame = getDvarInt( "onlinegame" );
|
||||
level.rankedMatch = ( !level.onlineGame || !getDvarInt( "xblive_privatematch" ) );
|
||||
|
||||
/#
|
||||
if ( getdvarint( "scr_forcerankedmatch" ) == 1 )
|
||||
{
|
||||
level.onlineGame = true;
|
||||
level.rankedMatch = true;
|
||||
}
|
||||
#/
|
||||
|
||||
level.script = toLower( getDvar( "mapname" ) );
|
||||
level.gametype = toLower( getDvar( "g_gametype" ) );
|
||||
|
||||
level.otherTeam["allies"] = "axis";
|
||||
level.otherTeam["axis"] = "allies";
|
||||
|
||||
level.teamBased = false;
|
||||
|
||||
level.objectiveBased = false;
|
||||
|
||||
level.endGameOnTimeLimit = true;
|
||||
|
||||
level.showingFinalKillcam = false;
|
||||
|
||||
level.tiSpawnDelay = getDvarInt( "scr_tispawndelay" );
|
||||
|
||||
// hack to allow maps with no scripts to run correctly
|
||||
if ( !isDefined( level.tweakablesInitialized ) )
|
||||
maps\mp\gametypes\_tweakables::init();
|
||||
|
||||
precacheString( &"MP_HALFTIME" );
|
||||
precacheString( &"MP_OVERTIME" );
|
||||
precacheString( &"MP_ROUNDEND" );
|
||||
precacheString( &"MP_INTERMISSION" );
|
||||
precacheString( &"MP_SWITCHING_SIDES" );
|
||||
precacheString( &"MP_FRIENDLY_FIRE_WILL_NOT" );
|
||||
precacheString( &"PLATFORM_REVIVE" );
|
||||
|
||||
precacheString( &"MP_OBITUARY_NEUTRAL" );
|
||||
precacheString( &"MP_OBITUARY_FRIENDLY" );
|
||||
precacheString( &"MP_OBITUARY_ENEMY" );
|
||||
|
||||
if ( level.splitScreen )
|
||||
precacheString( &"MP_ENDED_GAME" );
|
||||
else
|
||||
precacheString( &"MP_HOST_ENDED_GAME" );
|
||||
|
||||
level.halftimeType = "halftime";
|
||||
level.halftimeSubCaption = &"MP_SWITCHING_SIDES";
|
||||
|
||||
level.lastStatusTime = 0;
|
||||
level.wasWinning = "none";
|
||||
|
||||
level.lastSlowProcessFrame = 0;
|
||||
|
||||
level.placement["allies"] = [];
|
||||
level.placement["axis"] = [];
|
||||
level.placement["all"] = [];
|
||||
|
||||
level.postRoundTime = 5.0;
|
||||
|
||||
level.playersLookingForSafeSpawn = [];
|
||||
|
||||
registerDvars();
|
||||
|
||||
precacheModel( "vehicle_mig29_desert" );
|
||||
precacheModel( "projectile_cbu97_clusterbomb" );
|
||||
precacheModel( "tag_origin" );
|
||||
|
||||
level.fx_airstrike_afterburner = loadfx ("fire/jet_afterburner");
|
||||
level.fx_airstrike_contrail = loadfx ("smoke/jet_contrail");
|
||||
|
||||
if ( level.console )
|
||||
precacheLeaderboards( "LB_KILLS LB_WINS LB_TOTALXP LB_ACCURACY" );
|
||||
|
||||
level.teamCount["allies"] = 0;
|
||||
level.teamCount["axis"] = 0;
|
||||
level.teamCount["spectator"] = 0;
|
||||
|
||||
level.aliveCount["allies"] = 0;
|
||||
level.aliveCount["axis"] = 0;
|
||||
level.aliveCount["spectator"] = 0;
|
||||
|
||||
level.livesCount["allies"] = 0;
|
||||
level.livesCount["axis"] = 0;
|
||||
|
||||
level.oneLeftTime = [];
|
||||
|
||||
level.hasSpawned["allies"] = 0;
|
||||
level.hasSpawned["axis"] = 0;
|
||||
|
||||
/#
|
||||
if ( getdvarint( "scr_runlevelandquit" ) == 1 )
|
||||
{
|
||||
thread runLevelAndQuit();
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
|
||||
/#
|
||||
runLevelAndQuit()
|
||||
{
|
||||
wait 1;
|
||||
while ( level.players.size < 1 )
|
||||
{
|
||||
wait 0.5;
|
||||
}
|
||||
wait 0.5;
|
||||
level notify( "game_ended" );
|
||||
exitLevel();
|
||||
}
|
||||
#/
|
||||
|
||||
|
||||
registerDvars()
|
||||
{
|
||||
makeDvarServerInfo( "ui_bomb_timer", 0 );
|
||||
makeDvarServerInfo( "ui_danger_team", "" );
|
||||
|
||||
makeDvarServerInfo( "camera_thirdPerson", getDvarInt( "scr_thirdPerson" ) );
|
||||
}
|
||||
|
||||
SetupCallbacks()
|
||||
{
|
||||
level.onXPEvent = ::onXPEvent;
|
||||
|
||||
level.getSpawnPoint = ::blank;
|
||||
level.onSpawnPlayer = ::blank;
|
||||
level.onRespawnDelay = ::blank;
|
||||
|
||||
level.onTimeLimit = maps\mp\gametypes\_gamelogic::default_onTimeLimit;
|
||||
level.onHalfTime = maps\mp\gametypes\_gamelogic::default_onHalfTime;
|
||||
level.onDeadEvent = maps\mp\gametypes\_gamelogic::default_onDeadEvent;
|
||||
level.onOneLeftEvent = maps\mp\gametypes\_gamelogic::default_onOneLeftEvent;
|
||||
|
||||
level.onPrecacheGametype = ::blank;
|
||||
level.onStartGameType = ::blank;
|
||||
level.onPlayerKilled = ::blank;
|
||||
|
||||
level.autoassign = maps\mp\gametypes\_menus::menuAutoAssign;
|
||||
level.spectator = maps\mp\gametypes\_menus::menuSpectator;
|
||||
level.class = maps\mp\gametypes\_menus::menuClass;
|
||||
level.allies = maps\mp\gametypes\_menus::menuAllies;
|
||||
level.axis = maps\mp\gametypes\_menus::menuAxis;
|
||||
}
|
||||
|
||||
|
||||
|
||||
blank( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/#
|
||||
xpRateThread()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
gameFlagWait( "prematch_done" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( 5.0 );
|
||||
if ( level.players[0].pers["team"] == "allies" || level.players[0].pers["team"] == "axis" )
|
||||
self maps\mp\gametypes\_rank::giveRankXP( "kill", int(min( getDvarInt( "scr_xprate" ), 50 )) );
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
testMenu()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( 10.0 );
|
||||
|
||||
notifyData = spawnStruct();
|
||||
notifyData.titleText = &"MP_CHALLENGE_COMPLETED";
|
||||
notifyData.notifyText = "wheee";
|
||||
notifyData.sound = "mp_challenge_complete";
|
||||
|
||||
self thread maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
|
||||
}
|
||||
}
|
||||
|
||||
testShock()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( 3.0 );
|
||||
|
||||
numShots = randomInt( 6 );
|
||||
|
||||
for ( i = 0; i < numShots; i++ )
|
||||
{
|
||||
iPrintLnBold( numShots );
|
||||
self shellShock( "frag_grenade_mp", 0.2 );
|
||||
wait ( 0.1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onXPEvent( event )
|
||||
{
|
||||
//self thread maps\mp\_loot::giveMoney( event, 10 );
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( event );
|
||||
}
|
||||
|
||||
|
||||
|
||||
fakeLag()
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
self.fakeLag = randomIntRange( 50, 150 );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self setClientDvar( "fakelag_target", self.fakeLag );
|
||||
wait ( randomFloatRange( 5.0, 15.0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
debugLine( start, end )
|
||||
{
|
||||
for ( i = 0; i < 50; i++ )
|
||||
{
|
||||
line( start, end );
|
||||
wait .05;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.healthOverlayCutoff = 0.55;
|
||||
|
||||
regenTime = 5;
|
||||
regenTime = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "healthregentime" );
|
||||
|
||||
level.playerHealth_RegularRegenDelay = regenTime * 1000;
|
||||
|
||||
level.healthRegenDisabled = (level.playerHealth_RegularRegenDelay <= 0);
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player thread onPlayerSpawned();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("spawned_player");
|
||||
self thread playerHealthRegen();
|
||||
|
||||
self thread showTempDamage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
showTempDamage()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
/#
|
||||
setDevDvar( "scr_damage_wait", 0 );
|
||||
setDevDvar( "scr_damage_fadein", 0.25 );
|
||||
setDevDvar( "scr_damage_fadeout", 0.5 );
|
||||
setDevDvar( "scr_damage_holdtime", 0.5 );
|
||||
setDevDvar( "scr_damage_numfades", 5 );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
while ( getDvarFloat( "scr_damage_wait" ) <= 0 )
|
||||
wait ( 1.0 );
|
||||
|
||||
wait ( getDvarFloat( "scr_damage_wait" ) );
|
||||
|
||||
for ( i = 0; i < getDvarInt( "scr_damage_numfades" ); i++ )
|
||||
{
|
||||
self VisionSetNakedForPlayer( "mp_crash_damage", getDvarFloat( "scr_damage_fadein" ) * (getDvarInt( "scr_damage_numfades" ) - i) );
|
||||
wait ( getDvarFloat( "scr_damage_fadein" ) + getDvarFloat( "scr_damage_holdtime" ) );
|
||||
self VisionSetNakedForPlayer( "mp_crash", getDvarFloat( "scr_damage_fadeout" ) * getDvarInt( "scr_damage_numfades" ) );
|
||||
wait ( getDvarFloat( "scr_damage_fadeout" ) );
|
||||
}
|
||||
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
playerHealthRegen()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
self endon ( "joined_team" );
|
||||
self endon ( "joined_spectators" );
|
||||
|
||||
if ( self.health <= 0 )
|
||||
{
|
||||
assert( !isalive( self ) );
|
||||
return;
|
||||
}
|
||||
|
||||
oldhealth = self.maxhealth;
|
||||
|
||||
regenRate = 0.1;
|
||||
veryHurt = false;
|
||||
|
||||
self.breathingStopTime = -10000;
|
||||
|
||||
thread playerBreathingSound( self.maxhealth * 0.35 );
|
||||
|
||||
lastSoundTime_Recover = 0;
|
||||
hurtTime = 0;
|
||||
newHealth = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wait ( 0.05 );
|
||||
if ( isDefined( level.hostMigrationTimer ) )
|
||||
{
|
||||
timePassed = maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
|
||||
|
||||
hurtTime += timePassed;
|
||||
lastSoundTime_Recover += timePassed;
|
||||
}
|
||||
|
||||
if ( self.health == self.maxhealth || ( level.dieHardMode && isDefined( self.healthClamped ) && self.health >= self.healthClamped ) ) // runs every frame
|
||||
{
|
||||
oldHealth = self.maxhealth;
|
||||
veryHurt = false;
|
||||
self.atBrinkOfDeath = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self.health <= 0 ) // player dead
|
||||
return;
|
||||
|
||||
curTime = getTime();
|
||||
|
||||
ratio = self.health / self.maxHealth;
|
||||
|
||||
if ( ratio <= level.healthOverlayCutoff )
|
||||
{
|
||||
if ( !veryHurt )
|
||||
hurtTime = curTime;
|
||||
|
||||
veryHurt = true;
|
||||
self.atBrinkOfDeath = true;
|
||||
}
|
||||
|
||||
if ( self.health >= oldhealth )
|
||||
{
|
||||
if ( curTime - hurtTime < level.playerHealth_RegularRegenDelay )
|
||||
continue;
|
||||
|
||||
if ( level.healthRegenDisabled )
|
||||
{
|
||||
wait ( 3.0 );
|
||||
self.maxHealth = int( max( self.health, 2 ) );
|
||||
self.health = self.maxHealth;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( curTime - lastSoundTime_Recover > level.playerHealth_RegularRegenDelay )
|
||||
{
|
||||
lastSoundTime_Recover = curTime;
|
||||
if ( !level.gameEnded )
|
||||
self playLocalSound("breathing_better");
|
||||
}
|
||||
|
||||
if ( veryHurt )
|
||||
{
|
||||
newHealth = ratio;
|
||||
if ( curTime > hurtTime + 3000 )
|
||||
newHealth += regenRate;
|
||||
}
|
||||
else
|
||||
{
|
||||
newHealth = 1;
|
||||
}
|
||||
|
||||
if ( newHealth >= 1.0 )
|
||||
{
|
||||
if ( veryHurt )
|
||||
self maps\mp\gametypes\_missions::healthRegenerated();
|
||||
|
||||
self maps\mp\gametypes\_damage::resetAttackerList();
|
||||
newHealth = 1.0;
|
||||
}
|
||||
|
||||
if (newHealth <= 0)
|
||||
{
|
||||
// Player is dead
|
||||
return;
|
||||
}
|
||||
|
||||
self setNormalHealth (newHealth);
|
||||
oldHealth = self.health;
|
||||
continue;
|
||||
}
|
||||
|
||||
// first time damaged
|
||||
oldHealth = self.health;
|
||||
hurtTime = curTime;
|
||||
self.breathingStopTime = hurtTime + 6000;
|
||||
}
|
||||
}
|
||||
|
||||
playerBreathingSound( healthcap )
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
self endon ( "joined_team" );
|
||||
self endon ( "joined_spectators" );
|
||||
|
||||
wait ( 2 );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wait ( 0.2 );
|
||||
|
||||
if ( self.health <= 0 )
|
||||
return;
|
||||
|
||||
// Player still has a lot of health so no breathing sound
|
||||
if ( self.health >= healthcap )
|
||||
continue;
|
||||
|
||||
if ( level.healthRegenDisabled && gettime() > self.breathingStopTime )
|
||||
continue;
|
||||
|
||||
self playLocalSound( "breathing_hurt" );
|
||||
|
||||
wait ( .784 );
|
||||
wait ( 0.1 + randomfloat (0.8) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
Callback_HostMigration()
|
||||
{
|
||||
level.hostMigrationReturnedPlayerCount = 0;
|
||||
|
||||
if ( level.gameEnded )
|
||||
{
|
||||
println( "Migration starting at time " + gettime() + ", but game has ended, so no countdown." );
|
||||
return;
|
||||
}
|
||||
|
||||
println( "Migration starting at time " + gettime() );
|
||||
|
||||
level.hostMigrationTimer = true;
|
||||
|
||||
level notify( "host_migration_begin" );
|
||||
maps\mp\gametypes\_gamelogic::UpdateTimerPausedness();
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
player thread hostMigrationTimerThink();
|
||||
}
|
||||
|
||||
level endon( "host_migration_begin" );
|
||||
hostMigrationWait();
|
||||
|
||||
|
||||
level.hostMigrationTimer = undefined;
|
||||
println( "Migration finished at time " + gettime() );
|
||||
|
||||
level notify( "host_migration_end" );
|
||||
maps\mp\gametypes\_gamelogic::UpdateTimerPausedness();
|
||||
}
|
||||
|
||||
hostMigrationWait()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
level endon( "nuke_death" );
|
||||
|
||||
// start with a 20 second wait.
|
||||
// once we get enough players, or the first 15 seconds pass, switch to a 5 second timer.
|
||||
|
||||
thread maps\mp\gametypes\_gamelogic::matchStartTimer( "waiting_for_players", 20.0 );
|
||||
hostMigrationWaitForPlayers();
|
||||
|
||||
thread maps\mp\gametypes\_gamelogic::matchStartTimer( "match_resuming_in", 5.0 );
|
||||
wait 5;
|
||||
}
|
||||
|
||||
hostMigrationWaitForPlayers()
|
||||
{
|
||||
level endon( "hostmigration_enoughplayers" );
|
||||
wait 15;
|
||||
}
|
||||
|
||||
hostMigrationTimerThink_Internal()
|
||||
{
|
||||
level endon( "host_migration_begin" );
|
||||
level endon( "host_migration_end" );
|
||||
|
||||
self.hostMigrationControlsFrozen = false;
|
||||
|
||||
while ( !isReallyAlive( self ) )
|
||||
{
|
||||
self waittill( "spawned" );
|
||||
}
|
||||
|
||||
self.hostMigrationControlsFrozen = true;
|
||||
self freezeControlsWrapper( true );
|
||||
|
||||
level waittill( "host_migration_end" );
|
||||
}
|
||||
|
||||
hostMigrationTimerThink()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self setClientDvar( "cg_scoreboardPingGraph", "0" );
|
||||
|
||||
hostMigrationTimerThink_Internal();
|
||||
|
||||
if ( self.hostMigrationControlsFrozen )
|
||||
self freezeControlsWrapper( false );
|
||||
|
||||
self setClientDvar( "cg_scoreboardPingGraph", "1" );
|
||||
}
|
||||
|
||||
waitTillHostMigrationDone()
|
||||
{
|
||||
if ( !isDefined( level.hostMigrationTimer ) )
|
||||
return 0;
|
||||
|
||||
starttime = gettime();
|
||||
level waittill( "host_migration_end" );
|
||||
return gettime() - starttime;
|
||||
}
|
||||
|
||||
waitTillHostMigrationStarts( duration )
|
||||
{
|
||||
if ( isDefined( level.hostMigrationTimer ) )
|
||||
return;
|
||||
|
||||
level endon( "host_migration_begin" );
|
||||
wait duration;
|
||||
}
|
||||
|
||||
waitLongDurationWithHostMigrationPause( duration )
|
||||
{
|
||||
if ( duration == 0 )
|
||||
return;
|
||||
assert( duration > 0 );
|
||||
|
||||
starttime = gettime();
|
||||
|
||||
endtime = gettime() + duration * 1000;
|
||||
|
||||
while ( gettime() < endtime )
|
||||
{
|
||||
waitTillHostMigrationStarts( (endtime - gettime()) / 1000 );
|
||||
|
||||
if ( isDefined( level.hostMigrationTimer ) )
|
||||
{
|
||||
timePassed = waitTillHostMigrationDone();
|
||||
endtime += timePassed;
|
||||
}
|
||||
}
|
||||
|
||||
assert( gettime() == endtime );
|
||||
waitTillHostMigrationDone();
|
||||
|
||||
return gettime() - starttime;
|
||||
}
|
||||
|
||||
waitLongDurationWithGameEndTimeUpdate( duration )
|
||||
{
|
||||
if ( duration == 0 )
|
||||
return;
|
||||
assert( duration > 0 );
|
||||
|
||||
starttime = gettime();
|
||||
|
||||
endtime = gettime() + duration * 1000;
|
||||
|
||||
while ( gettime() < endtime )
|
||||
{
|
||||
waitTillHostMigrationStarts( (endtime - gettime()) / 1000 );
|
||||
|
||||
while ( isDefined( level.hostMigrationTimer ) )
|
||||
{
|
||||
endTime += 1000;
|
||||
setGameEndTime( int( endTime ) );
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
assert( gettime() == endtime );
|
||||
while ( isDefined( level.hostMigrationTimer ) )
|
||||
{
|
||||
endTime += 1000;
|
||||
setGameEndTime( int( endTime ) );
|
||||
wait 1;
|
||||
}
|
||||
|
||||
return gettime() - starttime;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
|
||||
// Edge relative placement values for rect->h_align and rect->v_align
|
||||
#define HORIZONTAL_ALIGN_SUBLEFT 0 // left edge of a 4:3 screen (safe area not included)
|
||||
#define HORIZONTAL_ALIGN_LEFT 1 // left viewable (safe area) edge
|
||||
#define HORIZONTAL_ALIGN_CENTER 2 // center of the screen (reticle)
|
||||
#define HORIZONTAL_ALIGN_RIGHT 3 // right viewable (safe area) edge
|
||||
#define HORIZONTAL_ALIGN_FULLSCREEN 4 // disregards safe area
|
||||
#define HORIZONTAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
|
||||
#define HORIZONTAL_ALIGN_TO640 6 // scales a real-screen resolution x down into the 0 - 640 range
|
||||
#define HORIZONTAL_ALIGN_CENTER_SAFEAREA 7 // center of the safearea
|
||||
#define HORIZONTAL_ALIGN_MAX HORIZONTAL_ALIGN_CENTER_SAFEAREA
|
||||
#define HORIZONTAL_ALIGN_DEFAULT HORIZONTAL_ALIGN_SUBLEFT
|
||||
|
||||
#define VERTICAL_ALIGN_SUBTOP 0 // top edge of the 4:3 screen (safe area not included)
|
||||
#define VERTICAL_ALIGN_TOP 1 // top viewable (safe area) edge
|
||||
#define VERTICAL_ALIGN_CENTER 2 // center of the screen (reticle)
|
||||
#define VERTICAL_ALIGN_BOTTOM 3 // bottom viewable (safe area) edge
|
||||
#define VERTICAL_ALIGN_FULLSCREEN 4 // disregards safe area
|
||||
#define VERTICAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
|
||||
#define VERTICAL_ALIGN_TO480 6 // scales a real-screen resolution y down into the 0 - 480 range
|
||||
#define VERTICAL_ALIGN_CENTER_SAFEAREA 7 // center of the save area
|
||||
#define VERTICAL_ALIGN_MAX VERTICAL_ALIGN_CENTER_SAFEAREA
|
||||
#define VERTICAL_ALIGN_DEFAULT VERTICAL_ALIGN_SUBTOP
|
||||
|
||||
static const char *g_he_font[] =
|
||||
{
|
||||
"default", // HE_FONT_DEFAULT
|
||||
"bigfixed", // HE_FONT_BIGFIXED
|
||||
"smallfixed", // HE_FONT_SMALLFIXED
|
||||
"objective", // HE_FONT_OBJECTIVE
|
||||
};
|
||||
|
||||
|
||||
// These values correspond to the defines in q_shared.h
|
||||
static const char *g_he_alignx[] =
|
||||
{
|
||||
"left", // HE_ALIGN_LEFT
|
||||
"center", // HE_ALIGN_CENTER
|
||||
"right", // HE_ALIGN_RIGHT
|
||||
};
|
||||
|
||||
|
||||
static const char *g_he_aligny[] =
|
||||
{
|
||||
"top", // HE_ALIGN_TOP
|
||||
"middle", // HE_ALIGN_MIDDLE
|
||||
"bottom", // HE_ALIGN_BOTTOM
|
||||
};
|
||||
|
||||
|
||||
// These values correspond to the defines in menudefinition.h
|
||||
static const char *g_he_horzalign[] =
|
||||
{
|
||||
"subleft", // HORIZONTAL_ALIGN_SUBLEFT
|
||||
"left", // HORIZONTAL_ALIGN_LEFT
|
||||
"center", // HORIZONTAL_ALIGN_CENTER
|
||||
"right", // HORIZONTAL_ALIGN_RIGHT
|
||||
"fullscreen", // HORIZONTAL_ALIGN_FULLSCREEN
|
||||
"noscale", // HORIZONTAL_ALIGN_NOSCALE
|
||||
"alignto640", // HORIZONTAL_ALIGN_TO640
|
||||
"center_safearea", // HORIZONTAL_ALIGN_CENTER_SAFEAREA
|
||||
};
|
||||
cassert( ARRAY_COUNT( g_he_horzalign ) == HORIZONTAL_ALIGN_MAX + 1 );
|
||||
|
||||
|
||||
static const char *g_he_vertalign[] =
|
||||
{
|
||||
"subtop", // VERTICAL_ALIGN_SUBTOP
|
||||
"top", // VERTICAL_ALIGN_TOP
|
||||
"middle", // VERTICAL_ALIGN_CENTER
|
||||
"bottom", // VERTICAL_ALIGN_BOTTOM
|
||||
"fullscreen", // VERTICAL_ALIGN_FULLSCREEN
|
||||
"noscale", // VERTICAL_ALIGN_NOSCALE
|
||||
"alignto480", // VERTICAL_ALIGN_TO480
|
||||
"center_safearea", // VERTICAL_ALIGN_CENTER_SAFEAREA
|
||||
};
|
||||
cassert( ARRAY_COUNT( g_he_vertalign ) == VERTICAL_ALIGN_MAX + 1 );
|
||||
*/
|
||||
|
||||
init()
|
||||
{
|
||||
precacheShader( "progress_bar_bg" );
|
||||
precacheShader( "progress_bar_fg" );
|
||||
precacheShader( "progress_bar_fill" );
|
||||
|
||||
level.uiParent = spawnstruct();
|
||||
level.uiParent.horzAlign = "left";
|
||||
level.uiParent.vertAlign = "top";
|
||||
level.uiParent.alignX = "left";
|
||||
level.uiParent.alignY = "top";
|
||||
level.uiParent.x = 0;
|
||||
level.uiParent.y = 0;
|
||||
level.uiParent.width = 0;
|
||||
level.uiParent.height = 0;
|
||||
level.uiParent.children = [];
|
||||
|
||||
level.fontHeight = 12;
|
||||
|
||||
level.hud["allies"] = spawnstruct();
|
||||
level.hud["axis"] = spawnstruct();
|
||||
|
||||
// we can, of course, separate out the following constants for splitscreen.
|
||||
// primary progress bars are for things like capturing flags or planting bombs - big, important things that happen as you play a gametype
|
||||
level.primaryProgressBarY = -61; // from center
|
||||
level.primaryProgressBarX = 0;
|
||||
level.primaryProgressBarHeight = 9; //28; // this is the height and width of the whole progress bar, including the outline. the part that actually moves is 2 pixels smaller.
|
||||
level.primaryProgressBarWidth = 120;
|
||||
level.primaryProgressBarTextY = -75;
|
||||
level.primaryProgressBarTextX = 0;
|
||||
level.primaryProgressBarFontSize = .6; // 1.4 before font change from "objective"
|
||||
|
||||
level.teamProgressBarY = 32; // 205;
|
||||
level.teamProgressBarHeight = 14;
|
||||
level.teamProgressBarWidth = 192;
|
||||
level.teamProgressBarTextY = 8; // 155;
|
||||
level.teamProgressBarFontSize = 1.65;
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
level.lowerTextYAlign = "BOTTOM";
|
||||
level.lowerTextY = -76;
|
||||
level.lowerTextFontSize = 1.14;
|
||||
}
|
||||
else
|
||||
{
|
||||
level.lowerTextYAlign = "CENTER";
|
||||
level.lowerTextY = 70;
|
||||
level.lowerTextFontSize = 1.6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fontPulseInit( maxFontScale )
|
||||
{
|
||||
self.baseFontScale = self.fontScale;
|
||||
if ( isDefined( maxFontScale ) )
|
||||
self.maxFontScale = min( maxFontScale, 6.3 );
|
||||
else
|
||||
self.maxFontScale = min( self.fontScale * 2, 6.3 );
|
||||
self.inFrames = 2;
|
||||
self.outFrames = 4;
|
||||
}
|
||||
|
||||
|
||||
fontPulse(player)
|
||||
{
|
||||
self notify ( "fontPulse" );
|
||||
self endon ( "fontPulse" );
|
||||
self endon( "death" );
|
||||
|
||||
player endon("disconnect");
|
||||
player endon("joined_team");
|
||||
player endon("joined_spectators");
|
||||
|
||||
self ChangeFontScaleOverTime( self.inFrames * 0.05 );
|
||||
self.fontScale = self.maxFontScale;
|
||||
wait self.inFrames * 0.05;
|
||||
|
||||
self ChangeFontScaleOverTime( self.outFrames * 0.05 );
|
||||
self.fontScale = self.baseFontScale;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,793 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
setParent( element )
|
||||
{
|
||||
if ( isDefined( self.parent ) && self.parent == element )
|
||||
return;
|
||||
|
||||
if ( isDefined( self.parent ) )
|
||||
self.parent removeChild( self );
|
||||
|
||||
self.parent = element;
|
||||
self.parent addChild( self );
|
||||
|
||||
if ( isDefined( self.point ) )
|
||||
self setPoint( self.point, self.relativePoint, self.xOffset, self.yOffset );
|
||||
else
|
||||
self setPoint( "TOPLEFT" );
|
||||
}
|
||||
|
||||
getParent()
|
||||
{
|
||||
return self.parent;
|
||||
}
|
||||
|
||||
addChild( element )
|
||||
{
|
||||
element.index = self.children.size;
|
||||
self.children[self.children.size] = element;
|
||||
}
|
||||
|
||||
removeChild( element )
|
||||
{
|
||||
element.parent = undefined;
|
||||
|
||||
if ( self.children[self.children.size-1] != element )
|
||||
{
|
||||
self.children[element.index] = self.children[self.children.size-1];
|
||||
self.children[element.index].index = element.index;
|
||||
}
|
||||
self.children[self.children.size-1] = undefined;
|
||||
|
||||
element.index = undefined;
|
||||
}
|
||||
|
||||
|
||||
setPoint( point, relativePoint, xOffset, yOffset, moveTime )
|
||||
{
|
||||
if ( !isDefined( moveTime ) )
|
||||
moveTime = 0;
|
||||
|
||||
element = self getParent();
|
||||
|
||||
if ( moveTime )
|
||||
self moveOverTime( moveTime );
|
||||
|
||||
if ( !isDefined( xOffset ) )
|
||||
xOffset = 0;
|
||||
self.xOffset = xOffset;
|
||||
|
||||
if ( !isDefined( yOffset ) )
|
||||
yOffset = 0;
|
||||
self.yOffset = yOffset;
|
||||
|
||||
self.point = point;
|
||||
|
||||
self.alignX = "center";
|
||||
self.alignY = "middle";
|
||||
|
||||
if ( isSubStr( point, "TOP" ) )
|
||||
self.alignY = "top";
|
||||
if ( isSubStr( point, "BOTTOM" ) )
|
||||
self.alignY = "bottom";
|
||||
if ( isSubStr( point, "LEFT" ) )
|
||||
self.alignX = "left";
|
||||
if ( isSubStr( point, "RIGHT" ) )
|
||||
self.alignX = "right";
|
||||
|
||||
if ( !isDefined( relativePoint ) )
|
||||
relativePoint = point;
|
||||
|
||||
self.relativePoint = relativePoint;
|
||||
|
||||
relativeX = "center_adjustable";
|
||||
relativeY = "middle";
|
||||
|
||||
if ( isSubStr( relativePoint, "TOP" ) )
|
||||
relativeY = "top_adjustable";
|
||||
if ( isSubStr( relativePoint, "BOTTOM" ) )
|
||||
relativeY = "bottom_adjustable";
|
||||
if ( isSubStr( relativePoint, "LEFT" ) )
|
||||
relativeX = "left_adjustable";
|
||||
if ( isSubStr( relativePoint, "RIGHT" ) )
|
||||
relativeX = "right_adjustable";
|
||||
|
||||
if ( element == level.uiParent )
|
||||
{
|
||||
self.horzAlign = relativeX;
|
||||
self.vertAlign = relativeY;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.horzAlign = element.horzAlign;
|
||||
self.vertAlign = element.vertAlign;
|
||||
}
|
||||
|
||||
|
||||
if ( strip_suffix( relativeX, "_adjustable" ) == element.alignX )
|
||||
{
|
||||
offsetX = 0;
|
||||
xFactor = 0;
|
||||
}
|
||||
else if ( relativeX == "center" || element.alignX == "center" )
|
||||
{
|
||||
offsetX = int(element.width / 2);
|
||||
if ( relativeX == "left_adjustable" || element.alignX == "right" )
|
||||
xFactor = -1;
|
||||
else
|
||||
xFactor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
offsetX = element.width;
|
||||
if ( relativeX == "left_adjustable" )
|
||||
xFactor = -1;
|
||||
else
|
||||
xFactor = 1;
|
||||
}
|
||||
self.x = element.x + (offsetX * xFactor);
|
||||
|
||||
if ( strip_suffix( relativeY, "_adjustable" ) == element.alignY )
|
||||
{
|
||||
offsetY = 0;
|
||||
yFactor = 0;
|
||||
}
|
||||
else if ( relativeY == "middle" || element.alignY == "middle" )
|
||||
{
|
||||
offsetY = int(element.height / 2);
|
||||
if ( relativeY == "top_adjustable" || element.alignY == "bottom" )
|
||||
yFactor = -1;
|
||||
else
|
||||
yFactor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
offsetY = element.height;
|
||||
if ( relativeY == "top_adjustable" )
|
||||
yFactor = -1;
|
||||
else
|
||||
yFactor = 1;
|
||||
}
|
||||
self.y = element.y + (offsetY * yFactor);
|
||||
|
||||
self.x += self.xOffset;
|
||||
self.y += self.yOffset;
|
||||
|
||||
switch ( self.elemType )
|
||||
{
|
||||
case "bar":
|
||||
setPointBar( point, relativePoint, xOffset, yOffset );
|
||||
break;
|
||||
}
|
||||
|
||||
self updateChildren();
|
||||
}
|
||||
|
||||
|
||||
setPointBar( point, relativePoint, xOffset, yOffset )
|
||||
{
|
||||
self.bar.horzAlign = self.horzAlign;
|
||||
self.bar.vertAlign = self.vertAlign;
|
||||
|
||||
self.bar.alignX = "left";
|
||||
self.bar.alignY = self.alignY;
|
||||
self.bar.y = self.y;
|
||||
|
||||
if ( self.alignX == "left" )
|
||||
self.bar.x = self.x;
|
||||
else if ( self.alignX == "right" )
|
||||
self.bar.x = self.x - self.width;
|
||||
else
|
||||
self.bar.x = self.x - int(self.width / 2);
|
||||
|
||||
if ( self.alignY == "top" )
|
||||
self.bar.y = self.y;
|
||||
else if ( self.alignY == "bottom" )
|
||||
self.bar.y = self.y;
|
||||
|
||||
self updateBar( self.bar.frac );
|
||||
}
|
||||
|
||||
|
||||
updateBar( barFrac, rateOfChange )
|
||||
{
|
||||
if ( self.elemType == "bar" )
|
||||
updateBarScale( barFrac, rateOfChange );
|
||||
}
|
||||
|
||||
|
||||
updateBarScale( barFrac, rateOfChange ) // rateOfChange is optional and is in "(entire bar lengths) per second"
|
||||
{
|
||||
barWidth = int(self.width * barFrac + 0.5); // (+ 0.5 rounds)
|
||||
|
||||
if ( !barWidth )
|
||||
barWidth = 1;
|
||||
|
||||
self.bar.frac = barFrac;
|
||||
self.bar setShader( self.bar.shader, barWidth, self.height );
|
||||
|
||||
assertEx( barWidth <= self.width, "barWidth <= self.width: " + barWidth + " <= " + self.width + " - barFrac was " + barFrac );
|
||||
|
||||
//if barWidth is bigger than self.width then we are drawing more than 100%
|
||||
if ( isDefined( rateOfChange ) && barWidth < self.width )
|
||||
{
|
||||
if ( rateOfChange > 0 )
|
||||
{
|
||||
//printLn( "scaling from: " + barWidth + " to " + self.width + " at " + ((1 - barFrac) / rateOfChange) );
|
||||
assertex( ((1 - barFrac) / rateOfChange) > 0, "barFrac: " + barFrac + "rateOfChange: " + rateOfChange );
|
||||
self.bar scaleOverTime( (1 - barFrac) / rateOfChange, self.width, self.height );
|
||||
}
|
||||
else if ( rateOfChange < 0 )
|
||||
{
|
||||
//printLn( "scaling from: " + barWidth + " to " + 0 + " at " + (barFrac / (-1 * rateOfChange)) );
|
||||
assertex( (barFrac / (-1 * rateOfChange)) > 0, "barFrac: " + barFrac + "rateOfChange: " + rateOfChange );
|
||||
self.bar scaleOverTime( barFrac / (-1 * rateOfChange), 1, self.height );
|
||||
}
|
||||
}
|
||||
self.bar.rateOfChange = rateOfChange;
|
||||
self.bar.lastUpdateTime = getTime();
|
||||
}
|
||||
|
||||
|
||||
createFontString( font, fontScale )
|
||||
{
|
||||
fontElem = newClientHudElem( self );
|
||||
fontElem.elemType = "font";
|
||||
fontElem.font = font;
|
||||
fontElem.fontscale = fontScale;
|
||||
fontElem.baseFontScale = fontScale;
|
||||
fontElem.x = 0;
|
||||
fontElem.y = 0;
|
||||
fontElem.width = 0;
|
||||
fontElem.height = int(level.fontHeight * fontScale);
|
||||
fontElem.xOffset = 0;
|
||||
fontElem.yOffset = 0;
|
||||
fontElem.children = [];
|
||||
fontElem setParent( level.uiParent );
|
||||
fontElem.hidden = false;
|
||||
return fontElem;
|
||||
}
|
||||
|
||||
|
||||
createServerFontString( font, fontScale, team )
|
||||
{
|
||||
if ( isDefined( team ) )
|
||||
fontElem = newTeamHudElem( team );
|
||||
else
|
||||
fontElem = newHudElem();
|
||||
|
||||
fontElem.elemType = "font";
|
||||
fontElem.font = font;
|
||||
fontElem.fontscale = fontScale;
|
||||
fontElem.baseFontScale = fontScale;
|
||||
fontElem.x = 0;
|
||||
fontElem.y = 0;
|
||||
fontElem.width = 0;
|
||||
fontElem.height = int(level.fontHeight * fontScale);
|
||||
fontElem.xOffset = 0;
|
||||
fontElem.yOffset = 0;
|
||||
fontElem.children = [];
|
||||
fontElem setParent( level.uiParent );
|
||||
fontElem.hidden = false;
|
||||
|
||||
return fontElem;
|
||||
}
|
||||
|
||||
createServerTimer( font, fontScale, team )
|
||||
{
|
||||
if ( isDefined( team ) )
|
||||
timerElem = newTeamHudElem( team );
|
||||
else
|
||||
timerElem = newHudElem();
|
||||
timerElem.elemType = "timer";
|
||||
timerElem.font = font;
|
||||
timerElem.fontScale = fontScale;
|
||||
timerElem.baseFontScale = fontScale;
|
||||
timerElem.x = 0;
|
||||
timerElem.y = 0;
|
||||
timerElem.width = 0;
|
||||
timerElem.height = int(level.fontHeight * fontScale);
|
||||
timerElem.xOffset = 0;
|
||||
timerElem.yOffset = 0;
|
||||
timerElem.children = [];
|
||||
timerElem setParent( level.uiParent );
|
||||
timerElem.hidden = false;
|
||||
|
||||
return timerElem;
|
||||
}
|
||||
|
||||
|
||||
createTimer( font, fontScale )
|
||||
{
|
||||
timerElem = newClientHudElem( self );
|
||||
timerElem.elemType = "timer";
|
||||
timerElem.font = font;
|
||||
timerElem.fontScale = fontScale;
|
||||
timerElem.baseFontScale = fontScale;
|
||||
timerElem.x = 0;
|
||||
timerElem.y = 0;
|
||||
timerElem.width = 0;
|
||||
timerElem.height = int(level.fontHeight * fontScale);
|
||||
timerElem.xOffset = 0;
|
||||
timerElem.yOffset = 0;
|
||||
timerElem.children = [];
|
||||
timerElem setParent( level.uiParent );
|
||||
timerElem.hidden = false;
|
||||
|
||||
return timerElem;
|
||||
}
|
||||
|
||||
|
||||
createIcon( shader, width, height )
|
||||
{
|
||||
iconElem = newClientHudElem( self );
|
||||
iconElem.elemType = "icon";
|
||||
iconElem.x = 0;
|
||||
iconElem.y = 0;
|
||||
iconElem.width = width;
|
||||
iconElem.height = height;
|
||||
iconElem.baseWidth = iconElem.width;
|
||||
iconElem.baseHeight = iconElem.height;
|
||||
iconElem.xOffset = 0;
|
||||
iconElem.yOffset = 0;
|
||||
iconElem.children = [];
|
||||
iconElem setParent( level.uiParent );
|
||||
iconElem.hidden = false;
|
||||
|
||||
if ( isDefined( shader ) )
|
||||
{
|
||||
iconElem setShader( shader, width, height );
|
||||
iconElem.shader = shader;
|
||||
}
|
||||
|
||||
return iconElem;
|
||||
}
|
||||
|
||||
|
||||
createServerIcon( shader, width, height, team )
|
||||
{
|
||||
if ( isDefined( team ) )
|
||||
iconElem = newTeamHudElem( team );
|
||||
else
|
||||
iconElem = newHudElem();
|
||||
iconElem.elemType = "icon";
|
||||
iconElem.x = 0;
|
||||
iconElem.y = 0;
|
||||
iconElem.width = width;
|
||||
iconElem.height = height;
|
||||
iconElem.baseWidth = iconElem.width;
|
||||
iconElem.baseHeight = iconElem.height;
|
||||
iconElem.xOffset = 0;
|
||||
iconElem.yOffset = 0;
|
||||
iconElem.children = [];
|
||||
iconElem setParent( level.uiParent );
|
||||
iconElem.hidden = false;
|
||||
|
||||
if ( isDefined( shader ) )
|
||||
{
|
||||
iconElem setShader( shader, width, height );
|
||||
iconElem.shader = shader;
|
||||
}
|
||||
|
||||
return iconElem;
|
||||
}
|
||||
|
||||
|
||||
createServerBar( color, width, height, flashFrac, team, selected )
|
||||
{
|
||||
if ( isDefined( team ) )
|
||||
barElem = newTeamHudElem( team );
|
||||
else
|
||||
barElem = newHudElem();
|
||||
barElem.x = 0;
|
||||
barElem.y = 0;
|
||||
barElem.frac = 0;
|
||||
barElem.color = color;
|
||||
barElem.sort = -2;
|
||||
barElem.shader = "progress_bar_fill";
|
||||
barElem setShader( "progress_bar_fill", width, height );
|
||||
barElem.hidden = false;
|
||||
if ( isDefined( flashFrac ) )
|
||||
{
|
||||
barElem.flashFrac = flashFrac;
|
||||
// barElem thread flashThread();
|
||||
}
|
||||
|
||||
if ( isDefined( team ) )
|
||||
barElemBG = newTeamHudElem( team );
|
||||
else
|
||||
barElemBG = newHudElem();
|
||||
barElemBG.elemType = "bar";
|
||||
barElemBG.x = 0;
|
||||
barElemBG.y = 0;
|
||||
barElemBG.width = width;
|
||||
barElemBG.height = height;
|
||||
barElemBG.xOffset = 0;
|
||||
barElemBG.yOffset = 0;
|
||||
barElemBG.bar = barElem;
|
||||
barElemBG.children = [];
|
||||
barElemBG.sort = -3;
|
||||
barElemBG.color = (0,0,0);
|
||||
barElemBG.alpha = 0.5;
|
||||
barElemBG setParent( level.uiParent );
|
||||
barElemBG setShader( "progress_bar_bg", width, height );
|
||||
barElemBG.hidden = false;
|
||||
|
||||
return barElemBG;
|
||||
}
|
||||
|
||||
createBar( color, width, height, flashFrac )
|
||||
{
|
||||
barElem = newClientHudElem( self );
|
||||
barElem.x = 0 ;
|
||||
barElem.y = 0;
|
||||
barElem.frac = 0;
|
||||
barElem.color = color;
|
||||
barElem.sort = -2;
|
||||
barElem.shader = "progress_bar_fill";
|
||||
barElem setShader( "progress_bar_fill", width, height );
|
||||
barElem.hidden = false;
|
||||
if ( isDefined( flashFrac ) )
|
||||
{
|
||||
barElem.flashFrac = flashFrac;
|
||||
// barElem thread flashThread();
|
||||
}
|
||||
|
||||
barElemBG = newClientHudElem( self );
|
||||
barElemBG.elemType = "bar";
|
||||
barElemBG.width = width;
|
||||
barElemBG.height = height;
|
||||
barElemBG.xOffset = 0;
|
||||
barElemBG.yOffset = 0;
|
||||
barElemBG.bar = barElem;
|
||||
barElemBG.children = [];
|
||||
barElemBG.sort = -3;
|
||||
barElemBG.color = (0,0,0);
|
||||
barElemBG.alpha = 0.5;
|
||||
barElemBG setParent( level.uiParent );
|
||||
barElemBG setShader( "progress_bar_bg", width + 4, height + 4 );
|
||||
barElemBG.hidden = false;
|
||||
|
||||
return barElemBG;
|
||||
}
|
||||
|
||||
getCurrentFraction()
|
||||
{
|
||||
frac = self.bar.frac;
|
||||
if (isdefined(self.bar.rateOfChange))
|
||||
{
|
||||
frac += (getTime() - self.bar.lastUpdateTime) * self.bar.rateOfChange;
|
||||
if (frac > 1) frac = 1;
|
||||
if (frac < 0) frac = 0;
|
||||
}
|
||||
return frac;
|
||||
}
|
||||
|
||||
createPrimaryProgressBar( yOffset )
|
||||
{
|
||||
if ( !isDefined( yOffset ) )
|
||||
yOffset = 0;
|
||||
|
||||
bar = createBar( (1, 1, 1), level.primaryProgressBarWidth, level.primaryProgressBarHeight );
|
||||
bar setPoint("CENTER", undefined, level.primaryProgressBarX, level.primaryProgressBarY - yOffset );
|
||||
|
||||
return bar;
|
||||
}
|
||||
createPrimaryProgressBarText( yOffset )
|
||||
{
|
||||
if ( !isDefined( yOffset ) )
|
||||
yOffset = 0;
|
||||
|
||||
text = createFontString( "hudbig", level.primaryProgressBarFontSize );
|
||||
text setPoint("CENTER", undefined, level.primaryProgressBarTextX, level.primaryProgressBarTextY - yOffset );
|
||||
text.sort = -1;
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
createTeamProgressBar( team )
|
||||
{
|
||||
bar = createServerBar( (1,0,0), level.teamProgressBarWidth, level.teamProgressBarHeight, undefined, team );
|
||||
bar setPoint("TOP", undefined, 0, level.teamProgressBarY);
|
||||
return bar;
|
||||
}
|
||||
createTeamProgressBarText( team )
|
||||
{
|
||||
text = createServerFontString( "default", level.teamProgressBarFontSize, team );
|
||||
text setPoint("TOP", undefined, 0, level.teamProgressBarTextY);
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
setFlashFrac( flashFrac )
|
||||
{
|
||||
self.bar.flashFrac = flashFrac;
|
||||
}
|
||||
|
||||
hideElem()
|
||||
{
|
||||
if ( self.hidden )
|
||||
return;
|
||||
|
||||
self.hidden = true;
|
||||
|
||||
if ( self.alpha != 0 )
|
||||
self.alpha = 0;
|
||||
|
||||
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
|
||||
{
|
||||
self.bar.hidden = true;
|
||||
if ( self.bar.alpha != 0 )
|
||||
self.bar.alpha = 0;
|
||||
}
|
||||
}
|
||||
|
||||
showElem()
|
||||
{
|
||||
if ( !self.hidden )
|
||||
return;
|
||||
|
||||
self.hidden = false;
|
||||
|
||||
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
|
||||
{
|
||||
if ( self.alpha != .5 )
|
||||
self.alpha = .5;
|
||||
|
||||
self.bar.hidden = false;
|
||||
if ( self.bar.alpha != 1 )
|
||||
self.bar.alpha = 1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self.alpha != 1 )
|
||||
self.alpha = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
flashThread()
|
||||
{
|
||||
self endon ( "death" );
|
||||
|
||||
if ( !self.hidden )
|
||||
self.alpha = 1;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if ( self.frac >= self.flashFrac )
|
||||
{
|
||||
if ( !self.hidden )
|
||||
{
|
||||
self fadeOverTime(0.3);
|
||||
self.alpha = .2;
|
||||
wait(0.35);
|
||||
self fadeOverTime(0.3);
|
||||
self.alpha = 1;
|
||||
}
|
||||
wait(0.7);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !self.hidden && self.alpha != 1 )
|
||||
self.alpha = 1;
|
||||
|
||||
wait ( 0.05 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
destroyElem()
|
||||
{
|
||||
tempChildren = [];
|
||||
|
||||
for ( index = 0; index < self.children.size; index++ )
|
||||
{
|
||||
if ( isDefined( self.children[index] ) )
|
||||
tempChildren[tempChildren.size] = self.children[index];
|
||||
}
|
||||
|
||||
for ( index = 0; index < tempChildren.size; index++ )
|
||||
tempChildren[index] setParent( self getParent() );
|
||||
|
||||
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
|
||||
{
|
||||
self.bar destroy();
|
||||
}
|
||||
|
||||
self destroy();
|
||||
}
|
||||
|
||||
setIconShader( shader )
|
||||
{
|
||||
self setShader( shader );
|
||||
self.shader = shader;
|
||||
}
|
||||
|
||||
|
||||
getIconShader( shader )
|
||||
{
|
||||
return self.shader;
|
||||
}
|
||||
|
||||
|
||||
setIconSize( width, height )
|
||||
{
|
||||
assert( isDefined( self.shader ) );
|
||||
|
||||
self setShader( self.shader, width, height );
|
||||
}
|
||||
|
||||
|
||||
setWidth( width )
|
||||
{
|
||||
self.width = width;
|
||||
}
|
||||
|
||||
|
||||
setHeight( height )
|
||||
{
|
||||
self.height = height;
|
||||
}
|
||||
|
||||
setSize( width, height )
|
||||
{
|
||||
self.width = width;
|
||||
self.height = height;
|
||||
}
|
||||
|
||||
updateChildren()
|
||||
{
|
||||
for ( index = 0; index < self.children.size; index++ )
|
||||
{
|
||||
child = self.children[index];
|
||||
child setPoint( child.point, child.relativePoint, child.xOffset, child.yOffset );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
transitionReset()
|
||||
{
|
||||
self.x = self.xOffset;
|
||||
self.y = self.yOffset;
|
||||
if ( self.elemType == "font" )
|
||||
{
|
||||
self.fontScale = self.baseFontScale;
|
||||
self.label = &"";
|
||||
}
|
||||
else if ( self.elemType == "icon" )
|
||||
{
|
||||
//self scaleOverTime( 0.001, self.width, self.height );
|
||||
self setShader( self.shader, self.width, self.height );
|
||||
}
|
||||
self.alpha = 0;
|
||||
}
|
||||
|
||||
|
||||
transitionZoomIn( duration )
|
||||
{
|
||||
switch ( self.elemType )
|
||||
{
|
||||
case "font":
|
||||
case "timer":
|
||||
self.fontScale = 6.3;
|
||||
self changeFontScaleOverTime( duration );
|
||||
self.fontScale = self.baseFontScale;
|
||||
break;
|
||||
case "icon":
|
||||
self setShader( self.shader, self.width * 6, self.height * 6 );
|
||||
self scaleOverTime( duration, self.width, self.height );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transitionPulseFXIn( inTime, duration )
|
||||
{
|
||||
transTime = int(inTime)*1000;
|
||||
showTime = int(duration)*1000;
|
||||
|
||||
switch ( self.elemType )
|
||||
{
|
||||
case "font":
|
||||
case "timer":
|
||||
self setPulseFX( transTime+250, showTime+transTime, transTime+250 );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transitionSlideIn( duration, direction )
|
||||
{
|
||||
if ( !isDefined( direction ) )
|
||||
direction = "left";
|
||||
|
||||
switch ( direction )
|
||||
{
|
||||
case "left":
|
||||
self.x += 1000;
|
||||
break;
|
||||
case "right":
|
||||
self.x -= 1000;
|
||||
break;
|
||||
case "up":
|
||||
self.y -= 1000;
|
||||
break;
|
||||
case "down":
|
||||
self.y += 1000;
|
||||
break;
|
||||
}
|
||||
self moveOverTime( duration );
|
||||
self.x = self.xOffset;
|
||||
self.y = self.yOffset;
|
||||
}
|
||||
|
||||
|
||||
transitionSlideOut( duration, direction )
|
||||
{
|
||||
if ( !isDefined( direction ) )
|
||||
direction = "left";
|
||||
|
||||
gotoX = self.xOffset;
|
||||
gotoY = self.yOffset;
|
||||
|
||||
switch ( direction )
|
||||
{
|
||||
case "left":
|
||||
gotoX += 1000;
|
||||
break;
|
||||
case "right":
|
||||
gotoX -= 1000;
|
||||
break;
|
||||
case "up":
|
||||
gotoY -= 1000;
|
||||
break;
|
||||
case "down":
|
||||
gotoY += 1000;
|
||||
break;
|
||||
}
|
||||
|
||||
self.alpha = 1;
|
||||
|
||||
self moveOverTime( duration );
|
||||
self.x = gotoX;
|
||||
self.y = gotoY;
|
||||
}
|
||||
|
||||
|
||||
transitionZoomOut( duration )
|
||||
{
|
||||
switch ( self.elemType )
|
||||
{
|
||||
case "font":
|
||||
case "timer":
|
||||
self changeFontScaleOverTime( duration );
|
||||
self.fontScale = 6.3;
|
||||
case "icon":
|
||||
self scaleOverTime( duration, self.width * 6, self.height * 6 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transitionFadeIn( duration )
|
||||
{
|
||||
self fadeOverTime( duration );
|
||||
if ( isDefined( self.maxAlpha ) )
|
||||
self.alpha = self.maxAlpha;
|
||||
else
|
||||
self.alpha = 1;
|
||||
}
|
||||
|
||||
|
||||
transitionFadeOut( duration )
|
||||
{
|
||||
self fadeOverTime( 0.15 );
|
||||
self.alpha = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,594 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
init()
|
||||
{
|
||||
precacheString(&"PLATFORM_PRESS_TO_SKIP");
|
||||
precacheString(&"PLATFORM_PRESS_TO_RESPAWN");
|
||||
precacheString(&"PLATFORM_PRESS_TO_COPYCAT");
|
||||
precacheShader("specialty_copycat");
|
||||
|
||||
level.killcam = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "allowkillcam" );
|
||||
}
|
||||
|
||||
killcam(
|
||||
attackerNum, // entity number of the attacker
|
||||
killcamentityindex, // entity number of the entity to view (grenade, airstrike, etc)
|
||||
killcamentitystarttime, // time at which the killcamentity came into being
|
||||
sWeapon, // killing weapon
|
||||
predelay, // time between player death and beginning of killcam
|
||||
offsetTime, // something to do with how far back in time the killer was seeing the world when he made the kill; latency related, sorta
|
||||
timeUntilRespawn, // will the player be allowed to respawn after the killcam?
|
||||
maxtime, // time remaining until map ends; the killcam will never last longer than this. undefined = no limit
|
||||
attacker, // entity object of attacker
|
||||
victim // entity object of the victim
|
||||
)
|
||||
{
|
||||
// monitors killcam and hides HUD elements during killcam session
|
||||
//if ( !level.splitscreen )
|
||||
// self thread killcam_HUD_off();
|
||||
|
||||
self endon("disconnect");
|
||||
self endon("spawned");
|
||||
level endon("game_ended");
|
||||
|
||||
if ( attackerNum < 0 )
|
||||
return;
|
||||
|
||||
// length from killcam start to killcam end
|
||||
if (getdvar("scr_killcam_time") == "") {
|
||||
if ( sWeapon == "artillery_mp" || sWeapon == "stealth_bomb_mp" )
|
||||
camtime = (gettime() - killcamentitystarttime) / 1000 - predelay - .1;
|
||||
else if ( level.showingFinalKillcam )
|
||||
camtime = 4.0;
|
||||
else if ( sWeapon == "javelin_mp" )
|
||||
camtime = 8;
|
||||
else if ( issubstr( sWeapon, "remotemissile_" ) )
|
||||
camtime = 5;
|
||||
else if ( !timeUntilRespawn || timeUntilRespawn > 5.0 ) // if we're not going to respawn, we can take more time to watch what happened
|
||||
camtime = 5.0;
|
||||
else if ( sWeapon == "frag_grenade_mp" || sWeapon == "frag_grenade_short_mp" || sWeapon == "semtex_mp" )
|
||||
camtime = 4.25; // show long enough to see grenade thrown
|
||||
else
|
||||
camtime = 2.5;
|
||||
}
|
||||
else
|
||||
camtime = getdvarfloat("scr_killcam_time");
|
||||
|
||||
if (isdefined(maxtime)) {
|
||||
if (camtime > maxtime)
|
||||
camtime = maxtime;
|
||||
if (camtime < .05)
|
||||
camtime = .05;
|
||||
}
|
||||
|
||||
// time after player death that killcam continues for
|
||||
if (getdvar("scr_killcam_posttime") == "")
|
||||
postdelay = 2;
|
||||
else {
|
||||
postdelay = getdvarfloat("scr_killcam_posttime");
|
||||
if (postdelay < 0.05)
|
||||
postdelay = 0.05;
|
||||
}
|
||||
|
||||
/* timeline:
|
||||
|
||||
| camtime | postdelay |
|
||||
| | predelay |
|
||||
|
||||
^ killcam start ^ player death ^ killcam end
|
||||
^ player starts watching killcam
|
||||
|
||||
*/
|
||||
|
||||
killcamlength = camtime + postdelay;
|
||||
|
||||
// don't let the killcam last past the end of the round.
|
||||
if (isdefined(maxtime) && killcamlength > maxtime)
|
||||
{
|
||||
// first trim postdelay down to a minimum of 1 second.
|
||||
// if that doesn't make it short enough, trim camtime down to a minimum of 1 second.
|
||||
// if that's still not short enough, cancel the killcam.
|
||||
if ( maxtime < 2 )
|
||||
return;
|
||||
|
||||
if (maxtime - camtime >= 1) {
|
||||
// reduce postdelay so killcam ends at end of match
|
||||
postdelay = maxtime - camtime;
|
||||
}
|
||||
else {
|
||||
// distribute remaining time over postdelay and camtime
|
||||
postdelay = 1;
|
||||
camtime = maxtime - 1;
|
||||
}
|
||||
|
||||
// recalc killcamlength
|
||||
killcamlength = camtime + postdelay;
|
||||
}
|
||||
|
||||
killcamoffset = camtime + predelay;
|
||||
|
||||
startTime = getTime();
|
||||
self notify ( "begin_killcam", startTime );
|
||||
|
||||
self.sessionstate = "spectator";
|
||||
self.forcespectatorclient = attackerNum;
|
||||
self.killcamentity = -1;
|
||||
if ( killcamentityindex >= 0 )
|
||||
self thread setKillCamEntity( killcamentityindex, killcamoffset, killcamentitystarttime );
|
||||
self.archivetime = killcamoffset;
|
||||
self.killcamlength = killcamlength;
|
||||
self.psoffsettime = offsetTime;
|
||||
|
||||
// ignore spectate permissions
|
||||
self allowSpectateTeam("allies", true);
|
||||
self allowSpectateTeam("axis", true);
|
||||
self allowSpectateTeam("freelook", true);
|
||||
self allowSpectateTeam("none", true);
|
||||
|
||||
if ( isDefined( attacker ) && level.showingFinalKillcam ) // attacker may have disconnected
|
||||
{
|
||||
self openMenu( "killedby_card_display" );
|
||||
self SetCardDisplaySlot( attacker, 7 );
|
||||
}
|
||||
|
||||
self thread endedKillcamCleanup();
|
||||
|
||||
// wait till the next server frame to allow code a chance to update archivetime if it needs trimming
|
||||
wait 0.05;
|
||||
|
||||
assertex( self.archivetime <= killcamoffset + 0.0001, "archivetime: " + self.archivetime + ", killcamoffset: " + killcamoffset );
|
||||
if ( self.archivetime < killcamoffset )
|
||||
println( "WARNING: Code trimmed killcam time by " + (killcamoffset - self.archivetime) + " seconds because it doesn't have enough game time recorded!" );
|
||||
|
||||
camtime = self.archivetime - .05 - predelay;
|
||||
killcamlength = camtime + postdelay;
|
||||
self.killcamlength = killcamlength;
|
||||
|
||||
if ( camtime <= 0 ) // if we're not looking back in time far enough to even see the death, cancel
|
||||
{
|
||||
println( "Cancelling killcam because we don't even have enough recorded to show the death." );
|
||||
|
||||
self.sessionstate = "dead";
|
||||
self.forcespectatorclient = -1;
|
||||
self.killcamentity = -1;
|
||||
self.archivetime = 0;
|
||||
self.psoffsettime = 0;
|
||||
|
||||
self notify ( "killcam_ended" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( level.showingFinalKillcam )
|
||||
thread doFinalKillCamFX( camtime );
|
||||
|
||||
self.killcam = true;
|
||||
|
||||
self initKCElements();
|
||||
|
||||
if ( !level.splitscreen )
|
||||
{
|
||||
self.kc_timer.alpha = 1;
|
||||
self.kc_timer setTenthsTimer(camtime);
|
||||
}
|
||||
|
||||
if ( timeUntilRespawn && !level.gameEnded )
|
||||
{
|
||||
if ( timeUntilRespawn > 0 )
|
||||
setLowerMessage( "kc_info", game["strings"]["waiting_to_spawn"], timeUntilRespawn );
|
||||
else
|
||||
setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_SKIP" );
|
||||
}
|
||||
else if ( !level.gameEnded )
|
||||
{
|
||||
setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_RESPAWN" );
|
||||
}
|
||||
|
||||
if ( !level.showingFinalKillcam )
|
||||
self.kc_skiptext.alpha = 1;
|
||||
else
|
||||
self.kc_skiptext.alpha = 0;
|
||||
|
||||
self.kc_othertext.alpha = 0;
|
||||
self.kc_icon.alpha = 0;
|
||||
|
||||
self thread spawnedKillcamCleanup();
|
||||
|
||||
if ( self == victim && victim _hasPerk( "specialty_copycat" ) && isDefined( victim.pers["copyCatLoadout"] ) )
|
||||
self thread waitKCCopyCatButton( attacker );
|
||||
|
||||
if ( !level.showingFinalKillcam )
|
||||
self thread waitSkipKillcamButton( timeUntilRespawn );
|
||||
else
|
||||
self notify ( "showing_final_killcam" );
|
||||
|
||||
self thread endKillcamIfNothingToShow();
|
||||
|
||||
self waittillKillcamOver();
|
||||
|
||||
if ( level.showingFinalKillcam )
|
||||
{
|
||||
self thread maps\mp\gametypes\_playerlogic::spawnEndOfGame();
|
||||
return;
|
||||
}
|
||||
|
||||
self thread calculateKillCamTime( startTime );
|
||||
|
||||
self thread killcamCleanup( true );
|
||||
}
|
||||
|
||||
|
||||
doFinalKillCamFX( camTime )
|
||||
{
|
||||
if ( isDefined( level.doingFinalKillcamFx ) )
|
||||
return;
|
||||
level.doingFinalKillcamFx = true;
|
||||
|
||||
intoSlowMoTime = camTime;
|
||||
if ( intoSlowMoTime > 1.0 )
|
||||
{
|
||||
intoSlowMoTime = 1.0;
|
||||
wait( camTime - 1.0 );
|
||||
}
|
||||
|
||||
setSlowMotion( 1.0, 0.25, intoSlowMoTime ); // start timescale, end timescale, lerp duration
|
||||
wait( intoSlowMoTime + .5 );
|
||||
setSlowMotion( 0.25, 1, 1.0 );
|
||||
|
||||
level.doingFinalKillcamFx = undefined;
|
||||
}
|
||||
|
||||
|
||||
calculateKillCamTime( startTime )
|
||||
{
|
||||
watchedTime = int(getTime() - startTime);
|
||||
self incPlayerStat( "killcamtimewatched", watchedTime );
|
||||
}
|
||||
|
||||
waittillKillcamOver()
|
||||
{
|
||||
self endon("abort_killcam");
|
||||
|
||||
wait(self.killcamlength - 0.05);
|
||||
}
|
||||
|
||||
setKillCamEntity( killcamentityindex, killcamoffset, starttime )
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
killcamtime = (gettime() - killcamoffset * 1000);
|
||||
|
||||
if ( starttime > killcamtime )
|
||||
{
|
||||
wait .05;
|
||||
// code may have trimmed archivetime after the first frame if we couldn't go back in time as far as requested.
|
||||
killcamoffset = self.archivetime;
|
||||
killcamtime = (gettime() - killcamoffset * 1000);
|
||||
|
||||
if ( starttime > killcamtime )
|
||||
wait (starttime - killcamtime) / 1000;
|
||||
}
|
||||
self.killcamentity = killcamentityindex;
|
||||
}
|
||||
|
||||
waitSkipKillcamButton( timeUntilRespawn )
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
while(self useButtonPressed())
|
||||
wait .05;
|
||||
|
||||
while(!(self useButtonPressed()))
|
||||
wait .05;
|
||||
|
||||
if ( !matchMakingGame() )
|
||||
self incPlayerStat( "killcamskipped", 1 );
|
||||
|
||||
if ( timeUntilRespawn <= 0 )
|
||||
clearLowerMessage( "kc_info" );
|
||||
|
||||
self notify("abort_killcam");
|
||||
}
|
||||
|
||||
waitKCCopyCatButton( attacker )
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
self waitCopyCatButton( attacker );
|
||||
|
||||
self notify("abort_killcam");
|
||||
}
|
||||
|
||||
waitDeathCopyCatButton( attacker )
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
|
||||
self initKCElements();
|
||||
|
||||
usedCopycat = self waitCopyCatButton( attacker );
|
||||
|
||||
if ( !isDefined( usedCopycat ) )
|
||||
{
|
||||
self.kc_icon.alpha = 0;
|
||||
self.kc_othertext.alpha = 0;
|
||||
}
|
||||
}
|
||||
|
||||
waitCopyCatButton( attacker )
|
||||
{
|
||||
self endon ( "spawned_player" );
|
||||
self endon ( "death_delay_finished" );
|
||||
self.kc_icon setShader( "specialty_copycat", 48, 48 );
|
||||
self.kc_othertext setText( &"PLATFORM_PRESS_TO_COPYCAT" );
|
||||
self.kc_othertext.alpha = 1;
|
||||
self.kc_icon.alpha = 1;
|
||||
|
||||
self notifyOnPlayerCommand( "use_copycat", "weapnext" );
|
||||
|
||||
self waittill( "use_copycat" );
|
||||
|
||||
self.pers["copyCatLoadout"]["inUse"] = true;
|
||||
self.pers["copyCatLoadout"]["owner"] = attacker;
|
||||
|
||||
self.kc_othertext fadeOverTime( 0.5 );
|
||||
self.kc_othertext.alpha = 0;
|
||||
|
||||
self.kc_icon fadeOverTime( 0.25 );
|
||||
self.kc_icon scaleOverTime( 0.25, 512, 512 );
|
||||
self.kc_icon.alpha = 0;
|
||||
|
||||
if ( isDefined( attacker ) )
|
||||
attacker thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "copied", self );
|
||||
|
||||
self playLocalSound( "copycat_steal_class" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
waitSkipKillcamSafeSpawnButton()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
if ( !self maps\mp\gametypes\_playerlogic::maySpawn() )
|
||||
return;
|
||||
|
||||
while(self fragButtonPressed())
|
||||
wait .05;
|
||||
|
||||
while(!(self fragButtonPressed()))
|
||||
wait .05;
|
||||
|
||||
self.wantSafeSpawn = true;
|
||||
|
||||
self notify("abort_killcam");
|
||||
}
|
||||
|
||||
endKillcamIfNothingToShow()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
while(1)
|
||||
{
|
||||
// code may trim our archivetime to zero if there is nothing "recorded" to show.
|
||||
// this can happen when the person we're watching in our killcam goes into killcam himself.
|
||||
// in this case, end the killcam.
|
||||
if ( self.archivetime <= 0 )
|
||||
break;
|
||||
wait .05;
|
||||
}
|
||||
|
||||
self notify("abort_killcam");
|
||||
}
|
||||
|
||||
spawnedKillcamCleanup()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
self waittill("spawned");
|
||||
self thread killcamCleanup( false );
|
||||
}
|
||||
|
||||
endedKillcamCleanup()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("killcam_ended");
|
||||
|
||||
level waittill("game_ended");
|
||||
|
||||
self thread killcamCleanup( true );
|
||||
}
|
||||
|
||||
killcamCleanup( clearState )
|
||||
{
|
||||
if(isDefined(self.kc_skiptext))
|
||||
self.kc_skiptext.alpha = 0;
|
||||
|
||||
if(isDefined(self.kc_timer))
|
||||
self.kc_timer.alpha = 0;
|
||||
|
||||
if(isDefined(self.kc_icon))
|
||||
self.kc_icon.alpha = 0;
|
||||
|
||||
if(isDefined(self.kc_othertext))
|
||||
self.kc_othertext.alpha = 0;
|
||||
|
||||
self.killcam = undefined;
|
||||
|
||||
if ( !level.gameEnded )
|
||||
self clearLowerMessage( "kc_info" );
|
||||
|
||||
self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
|
||||
|
||||
self notify("killcam_ended"); // do this last, in case this function was called from a thread ending on it
|
||||
|
||||
if ( !clearState )
|
||||
return;
|
||||
|
||||
self.sessionstate = "dead";
|
||||
self ClearKillcamState();
|
||||
}
|
||||
|
||||
|
||||
|
||||
cancelKillCamOnUse()
|
||||
{
|
||||
self.cancelKillcam = false;
|
||||
self thread cancelKillCamOnUse_specificButton( ::cancelKillCamUseButton, ::cancelKillCamCallback );
|
||||
//self thread cancelKillCamOnUse_specificButton( ::cancelKillCamSafeSpawnButton, ::cancelKillCamSafeSpawnCallback );
|
||||
}
|
||||
|
||||
cancelKillCamUseButton()
|
||||
{
|
||||
return self useButtonPressed();
|
||||
}
|
||||
cancelKillCamSafeSpawnButton()
|
||||
{
|
||||
return self fragButtonPressed();
|
||||
}
|
||||
cancelKillCamCallback()
|
||||
{
|
||||
self.cancelKillcam = true;
|
||||
}
|
||||
cancelKillCamSafeSpawnCallback()
|
||||
{
|
||||
self.cancelKillcam = true;
|
||||
self.wantSafeSpawn = true;
|
||||
}
|
||||
|
||||
cancelKillCamOnUse_specificButton( pressingButtonFunc, finishedFunc )
|
||||
{
|
||||
self endon ( "death_delay_finished" );
|
||||
self endon ( "disconnect" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( !self [[pressingButtonFunc]]() )
|
||||
{
|
||||
wait ( 0.05 );
|
||||
continue;
|
||||
}
|
||||
|
||||
buttonTime = 0;
|
||||
while( self [[pressingButtonFunc]]() )
|
||||
{
|
||||
buttonTime += 0.05;
|
||||
wait ( 0.05 );
|
||||
}
|
||||
|
||||
if ( buttonTime >= 0.5 )
|
||||
continue;
|
||||
|
||||
buttonTime = 0;
|
||||
|
||||
while ( !self [[pressingButtonFunc]]() && buttonTime < 0.5 )
|
||||
{
|
||||
buttonTime += 0.05;
|
||||
wait ( 0.05 );
|
||||
}
|
||||
|
||||
if ( buttonTime >= 0.5 )
|
||||
continue;
|
||||
|
||||
self [[finishedFunc]]();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
initKCElements()
|
||||
{
|
||||
if ( !isDefined( self.kc_skiptext ) )
|
||||
{
|
||||
self.kc_skiptext = newClientHudElem(self);
|
||||
self.kc_skiptext.archived = false;
|
||||
self.kc_skiptext.x = 0;
|
||||
self.kc_skiptext.alignX = "center";
|
||||
self.kc_skiptext.alignY = "top";
|
||||
self.kc_skiptext.horzAlign = "center_adjustable";
|
||||
self.kc_skiptext.vertAlign = "top_adjustable";
|
||||
self.kc_skiptext.sort = 1; // force to draw after the bars
|
||||
self.kc_skiptext.font = "default";
|
||||
self.kc_skiptext.foreground = true;
|
||||
self.kc_skiptext.hideWhenInMenu = true;
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
self.kc_skiptext.y = 20;
|
||||
self.kc_skiptext.fontscale = 1.2; // 1.8/1.5
|
||||
}
|
||||
else
|
||||
{
|
||||
self.kc_skiptext.y = 32;
|
||||
self.kc_skiptext.fontscale = 1.8;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isDefined( self.kc_othertext ) )
|
||||
{
|
||||
self.kc_othertext = newClientHudElem(self);
|
||||
self.kc_othertext.archived = false;
|
||||
self.kc_othertext.y = 18;
|
||||
self.kc_othertext.alignX = "left";
|
||||
self.kc_othertext.alignY = "top";
|
||||
self.kc_othertext.horzAlign = "center";
|
||||
self.kc_othertext.vertAlign = "middle";
|
||||
self.kc_othertext.sort = 10; // force to draw after the bars
|
||||
self.kc_othertext.font = "small";
|
||||
self.kc_othertext.foreground = true;
|
||||
self.kc_othertext.hideWhenInMenu = true;
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
self.kc_othertext.x = 16;
|
||||
self.kc_othertext.fontscale = 1.2;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.kc_othertext.x = 62;
|
||||
self.kc_othertext.fontscale = 1.6;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isDefined( self.kc_icon ) )
|
||||
{
|
||||
self.kc_icon = newClientHudElem(self);
|
||||
self.kc_icon.archived = false;
|
||||
self.kc_icon.x = 16;
|
||||
self.kc_icon.y = 16;
|
||||
self.kc_icon.alignX = "left";
|
||||
self.kc_icon.alignY = "top";
|
||||
self.kc_icon.horzAlign = "center";
|
||||
self.kc_icon.vertAlign = "middle";
|
||||
self.kc_icon.sort = 1; // force to draw after the bars
|
||||
self.kc_icon.foreground = true;
|
||||
self.kc_icon.hideWhenInMenu = true;
|
||||
}
|
||||
|
||||
if ( !level.splitscreen )
|
||||
{
|
||||
if ( !isdefined( self.kc_timer ) )
|
||||
{
|
||||
self.kc_timer = createFontString( "hudbig", 1.0 );
|
||||
self.kc_timer.archived = false;
|
||||
self.kc_timer.x = 0;
|
||||
self.kc_timer.alignX = "center";
|
||||
self.kc_timer.alignY = "middle";
|
||||
self.kc_timer.horzAlign = "center_safearea";
|
||||
self.kc_timer.vertAlign = "top_adjustable";
|
||||
self.kc_timer.y = 42;
|
||||
self.kc_timer.sort = 1; // force to draw after the bars
|
||||
self.kc_timer.font = "hudbig";
|
||||
self.kc_timer.foreground = true;
|
||||
self.kc_timer.color = (0.85,0.85,0.85);
|
||||
self.kc_timer.hideWhenInMenu = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,555 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
if ( !isDefined( game["gamestarted"] ) )
|
||||
{
|
||||
game["menu_team"] = "team_marinesopfor";
|
||||
game["menu_class_allies"] = "class_marines";
|
||||
game["menu_changeclass_allies"] = "changeclass_marines";
|
||||
game["menu_initteam_allies"] = "initteam_marines";
|
||||
game["menu_class_axis"] = "class_opfor";
|
||||
game["menu_changeclass_axis"] = "changeclass_opfor";
|
||||
game["menu_initteam_axis"] = "initteam_opfor";
|
||||
game["menu_class"] = "class";
|
||||
game["menu_changeclass"] = "changeclass";
|
||||
game["menu_onemanarmy"] = "onemanarmy";
|
||||
game["menu_controls"] = "ingame_controls";
|
||||
|
||||
if ( !level.console )
|
||||
{
|
||||
game["menu_muteplayer"] = "muteplayer";
|
||||
precacheMenu(game["menu_muteplayer"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//game["menu_options"] = "ingame_options";
|
||||
game["menu_leavegame"] = "popup_leavegame";
|
||||
|
||||
if(level.splitscreen)
|
||||
{
|
||||
game["menu_team"] += "_splitscreen";
|
||||
game["menu_class_allies"] += "_splitscreen";
|
||||
game["menu_changeclass_allies"] += "_splitscreen";
|
||||
game["menu_class_axis"] += "_splitscreen";
|
||||
game["menu_changeclass_axis"] += "_splitscreen";
|
||||
game["menu_class"] += "_splitscreen";
|
||||
game["menu_controls"] += "_splitscreen";
|
||||
//game["menu_options"] += "_splitscreen";
|
||||
game["menu_leavegame"] += "_splitscreen";
|
||||
game["menu_onemanarmy"] += "_splitscreen";
|
||||
|
||||
game["menu_changeclass_defaults_splitscreen"] = "changeclass_defaults_splitscreen";
|
||||
game["menu_changeclass_custom_splitscreen"] = "changeclass_custom_splitscreen";
|
||||
game["menu_onemanarmy_defaults_splitscreen"] = "onemanarmy_defaults_splitscreen";
|
||||
game["menu_onemanarmy_custom_splitscreen"] = "onemanarmy_custom_splitscreen";
|
||||
|
||||
precacheMenu(game["menu_changeclass_defaults_splitscreen"]);
|
||||
precacheMenu(game["menu_changeclass_custom_splitscreen"]);
|
||||
precacheMenu(game["menu_onemanarmy_defaults_splitscreen"]);
|
||||
precacheMenu(game["menu_onemanarmy_custom_splitscreen"]);
|
||||
}
|
||||
|
||||
precacheMenu(game["menu_controls"]);
|
||||
//precacheMenu(game["menu_options"]);
|
||||
precacheMenu(game["menu_leavegame"]);
|
||||
|
||||
//precacheMenu("status_update");
|
||||
}
|
||||
|
||||
precacheMenu("scoreboard");
|
||||
precacheMenu(game["menu_team"]);
|
||||
precacheMenu(game["menu_class_allies"]);
|
||||
precacheMenu(game["menu_changeclass_allies"]);
|
||||
precacheMenu(game["menu_initteam_allies"]);
|
||||
precacheMenu(game["menu_class_axis"]);
|
||||
precacheMenu(game["menu_changeclass_axis"]);
|
||||
precacheMenu(game["menu_class"]);
|
||||
precacheMenu(game["menu_changeclass"]);
|
||||
precacheMenu(game["menu_initteam_axis"]);
|
||||
precacheMenu(game["menu_onemanarmy"]);
|
||||
|
||||
precacheString( &"MP_HOST_ENDED_GAME" );
|
||||
precacheString( &"MP_HOST_ENDGAME_RESPONSE" );
|
||||
}
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
|
||||
player thread onMenuResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
isOptionsMenu( menu )
|
||||
{
|
||||
if ( menu == game["menu_changeclass"] )
|
||||
return true;
|
||||
|
||||
if ( menu == game["menu_team"] )
|
||||
return true;
|
||||
|
||||
if ( menu == game["menu_controls"] )
|
||||
return true;
|
||||
|
||||
if ( isSubStr( menu, "pc_options" ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
onMenuResponse()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("menuresponse", menu, response);
|
||||
|
||||
if ( response == "back" )
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
|
||||
if ( isOptionsMenu( menu ) )
|
||||
{
|
||||
if( self.pers["team"] == "allies" )
|
||||
self openpopupMenu( game["menu_class_allies"] );
|
||||
if( self.pers["team"] == "axis" )
|
||||
self openpopupMenu( game["menu_class_axis"] );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(response == "changeteam")
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
self openpopupMenu(game["menu_team"]);
|
||||
}
|
||||
|
||||
if(response == "changeclass_marines" )
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
self openpopupMenu( game["menu_changeclass_allies"] );
|
||||
continue;
|
||||
}
|
||||
|
||||
if(response == "changeclass_opfor" )
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
self openpopupMenu( game["menu_changeclass_axis"] );
|
||||
continue;
|
||||
}
|
||||
|
||||
if(response == "changeclass_marines_splitscreen" )
|
||||
self openpopupMenu( "changeclass_marines_splitscreen" );
|
||||
|
||||
if(response == "changeclass_opfor_splitscreen" )
|
||||
self openpopupMenu( "changeclass_opfor_splitscreen" );
|
||||
|
||||
if(response == "endgame")
|
||||
{
|
||||
if(level.splitscreen)
|
||||
{
|
||||
endparty();
|
||||
|
||||
if ( !level.gameEnded )
|
||||
{
|
||||
level thread maps\mp\gametypes\_gamelogic::forceEnd();
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( response == "endround" )
|
||||
{
|
||||
if ( !level.gameEnded )
|
||||
{
|
||||
level thread maps\mp\gametypes\_gamelogic::forceEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
self iprintln( &"MP_HOST_ENDGAME_RESPONSE" );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(menu == game["menu_team"])
|
||||
{
|
||||
switch(response)
|
||||
{
|
||||
case "allies":
|
||||
self [[level.allies]]();
|
||||
break;
|
||||
|
||||
case "axis":
|
||||
self [[level.axis]]();
|
||||
break;
|
||||
|
||||
case "autoassign":
|
||||
self [[level.autoassign]]();
|
||||
break;
|
||||
|
||||
case "spectator":
|
||||
self [[level.spectator]]();
|
||||
break;
|
||||
}
|
||||
} // the only responses remain are change class events
|
||||
else if ( menu == game["menu_changeclass"] ||
|
||||
( isDefined( game["menu_changeclass_defaults_splitscreen"] ) && menu == game["menu_changeclass_defaults_splitscreen"] ) ||
|
||||
( isDefined( game["menu_changeclass_custom_splitscreen"] ) && menu == game["menu_changeclass_custom_splitscreen"] ) )
|
||||
{
|
||||
self closepopupMenu();
|
||||
self closeInGameMenu();
|
||||
|
||||
self.selectedClass = true;
|
||||
self [[level.class]](response);
|
||||
}
|
||||
else if ( !level.console )
|
||||
{
|
||||
if(menu == game["menu_quickcommands"])
|
||||
maps\mp\gametypes\_quickmessages::quickcommands(response);
|
||||
else if(menu == game["menu_quickstatements"])
|
||||
maps\mp\gametypes\_quickmessages::quickstatements(response);
|
||||
else if(menu == game["menu_quickresponses"])
|
||||
maps\mp\gametypes\_quickmessages::quickresponses(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getTeamAssignment()
|
||||
{
|
||||
teams[0] = "allies";
|
||||
teams[1] = "axis";
|
||||
|
||||
if ( !level.teamBased )
|
||||
return teams[randomInt(2)];
|
||||
|
||||
if ( self.sessionteam != "none" && self.sessionteam != "spectator" && self.sessionstate != "playing" && self.sessionstate != "dead" )
|
||||
{
|
||||
assignment = self.sessionteam;
|
||||
}
|
||||
else
|
||||
{
|
||||
playerCounts = self maps\mp\gametypes\_teams::CountPlayers();
|
||||
|
||||
// if teams are equal return the team with the lowest score
|
||||
if ( playerCounts["allies"] == playerCounts["axis"] )
|
||||
{
|
||||
if( getTeamScore( "allies" ) == getTeamScore( "axis" ) )
|
||||
assignment = teams[randomInt(2)];
|
||||
else if ( getTeamScore( "allies" ) < getTeamScore( "axis" ) )
|
||||
assignment = "allies";
|
||||
else
|
||||
assignment = "axis";
|
||||
}
|
||||
else if( playerCounts["allies"] < playerCounts["axis"] )
|
||||
{
|
||||
assignment = "allies";
|
||||
}
|
||||
else
|
||||
{
|
||||
assignment = "axis";
|
||||
}
|
||||
}
|
||||
|
||||
return assignment;
|
||||
}
|
||||
|
||||
|
||||
menuAutoAssign()
|
||||
{
|
||||
self closeMenus();
|
||||
|
||||
assignment = getTeamAssignment();
|
||||
|
||||
if ( isDefined( self.pers["team"] ) && (self.sessionstate == "playing" || self.sessionstate == "dead") )
|
||||
{
|
||||
if ( assignment == self.pers["team"] )
|
||||
{
|
||||
self beginClassChoice();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.switching_teams = true;
|
||||
self.joining_team = assignment;
|
||||
self.leaving_team = self.pers["team"];
|
||||
self suicide();
|
||||
}
|
||||
}
|
||||
|
||||
self addToTeam( assignment );
|
||||
self.pers["class"] = undefined;
|
||||
self.class = undefined;
|
||||
|
||||
if ( !isAlive( self ) )
|
||||
self.statusicon = "hud_status_dead";
|
||||
|
||||
self notify("end_respawn");
|
||||
|
||||
self beginClassChoice();
|
||||
}
|
||||
|
||||
|
||||
beginClassChoice( forceNewChoice )
|
||||
{
|
||||
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
|
||||
|
||||
team = self.pers["team"];
|
||||
|
||||
// menu_changeclass_team is the one where you choose one of the n classes to play as.
|
||||
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
|
||||
self openpopupMenu( game[ "menu_changeclass_" + team ] );
|
||||
|
||||
if ( !isAlive( self ) )
|
||||
self thread maps\mp\gametypes\_playerlogic::predictAboutToSpawnPlayerOverTime( 0.1 );
|
||||
}
|
||||
|
||||
|
||||
beginTeamChoice()
|
||||
{
|
||||
self openpopupMenu( game["menu_team"] );
|
||||
}
|
||||
|
||||
|
||||
showMainMenuForTeam()
|
||||
{
|
||||
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
|
||||
|
||||
team = self.pers["team"];
|
||||
|
||||
// menu_changeclass_team is the one where you choose one of the n classes to play as.
|
||||
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
|
||||
self openpopupMenu( game[ "menu_class_" + team ] );
|
||||
}
|
||||
|
||||
menuAllies()
|
||||
{
|
||||
self closeMenus();
|
||||
|
||||
if(self.pers["team"] != "allies")
|
||||
{
|
||||
if( level.teamBased && !maps\mp\gametypes\_teams::getJoinTeamPermissions( "allies" ) )
|
||||
{
|
||||
self openpopupMenu(game["menu_team"]);
|
||||
return;
|
||||
}
|
||||
|
||||
// allow respawn when switching teams during grace period.
|
||||
if ( level.inGracePeriod && !self.hasDoneCombat )
|
||||
self.hasSpawned = false;
|
||||
|
||||
if(self.sessionstate == "playing")
|
||||
{
|
||||
self.switching_teams = true;
|
||||
self.joining_team = "allies";
|
||||
self.leaving_team = self.pers["team"];
|
||||
self suicide();
|
||||
}
|
||||
|
||||
self addToTeam( "allies" );
|
||||
self.pers["class"] = undefined;
|
||||
self.class = undefined;
|
||||
|
||||
self notify("end_respawn");
|
||||
}
|
||||
|
||||
self beginClassChoice();
|
||||
}
|
||||
|
||||
|
||||
menuAxis()
|
||||
{
|
||||
self closeMenus();
|
||||
|
||||
if(self.pers["team"] != "axis")
|
||||
{
|
||||
if( level.teamBased && !maps\mp\gametypes\_teams::getJoinTeamPermissions( "axis" ) )
|
||||
{
|
||||
self openpopupMenu(game["menu_team"]);
|
||||
return;
|
||||
}
|
||||
|
||||
// allow respawn when switching teams during grace period.
|
||||
if ( level.inGracePeriod && !self.hasDoneCombat )
|
||||
self.hasSpawned = false;
|
||||
|
||||
if(self.sessionstate == "playing")
|
||||
{
|
||||
self.switching_teams = true;
|
||||
self.joining_team = "axis";
|
||||
self.leaving_team = self.pers["team"];
|
||||
self suicide();
|
||||
}
|
||||
|
||||
self addToTeam( "axis" );
|
||||
self.pers["class"] = undefined;
|
||||
self.class = undefined;
|
||||
|
||||
self notify("end_respawn");
|
||||
}
|
||||
|
||||
self beginClassChoice();
|
||||
}
|
||||
|
||||
|
||||
menuSpectator()
|
||||
{
|
||||
self closeMenus();
|
||||
|
||||
if( isDefined( self.pers["team"] ) && self.pers["team"] == "spectator" )
|
||||
return;
|
||||
|
||||
if( isAlive( self ) )
|
||||
{
|
||||
assert( isDefined( self.pers["team"] ) );
|
||||
self.switching_teams = true;
|
||||
self.joining_team = "spectator";
|
||||
self.leaving_team = self.pers["team"];
|
||||
self suicide();
|
||||
}
|
||||
|
||||
self addToTeam( "spectator" );
|
||||
self.pers["class"] = undefined;
|
||||
self.class = undefined;
|
||||
|
||||
self thread maps\mp\gametypes\_playerlogic::spawnSpectator();
|
||||
}
|
||||
|
||||
|
||||
menuClass( response )
|
||||
{
|
||||
self closeMenus();
|
||||
|
||||
// clear new status of unlocked classes
|
||||
if ( response == "demolitions_mp,0" && self getPlayerData( "featureNew", "demolitions" ) )
|
||||
{
|
||||
self setPlayerData( "featureNew", "demolitions", false );
|
||||
}
|
||||
if ( response == "sniper_mp,0" && self getPlayerData( "featureNew", "sniper" ) )
|
||||
{
|
||||
self setPlayerData( "featureNew", "sniper", false );
|
||||
}
|
||||
|
||||
// this should probably be an assert
|
||||
if(!isDefined(self.pers["team"]) || (self.pers["team"] != "allies" && self.pers["team"] != "axis"))
|
||||
return;
|
||||
|
||||
class = self maps\mp\gametypes\_class::getClassChoice( response );
|
||||
primary = self maps\mp\gametypes\_class::getWeaponChoice( response );
|
||||
|
||||
if ( class == "restricted" )
|
||||
{
|
||||
self beginClassChoice();
|
||||
return;
|
||||
}
|
||||
|
||||
if( (isDefined( self.pers["class"] ) && self.pers["class"] == class) &&
|
||||
(isDefined( self.pers["primary"] ) && self.pers["primary"] == primary) )
|
||||
return;
|
||||
|
||||
if ( self.sessionstate == "playing" )
|
||||
{
|
||||
self.pers["class"] = class;
|
||||
self.class = class;
|
||||
self.pers["primary"] = primary;
|
||||
|
||||
if ( game["state"] == "postgame" )
|
||||
return;
|
||||
|
||||
if ( level.inGracePeriod && !self.hasDoneCombat ) // used weapons check?
|
||||
{
|
||||
self maps\mp\gametypes\_class::setClass( self.pers["class"] );
|
||||
self.tag_stowed_back = undefined;
|
||||
self.tag_stowed_hip = undefined;
|
||||
self maps\mp\gametypes\_class::giveLoadout( self.pers["team"], self.pers["class"] );
|
||||
}
|
||||
else
|
||||
{
|
||||
self iPrintLnBold( game["strings"]["change_class"] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.pers["class"] = class;
|
||||
self.class = class;
|
||||
self.pers["primary"] = primary;
|
||||
|
||||
if ( game["state"] == "postgame" )
|
||||
return;
|
||||
|
||||
if ( game["state"] == "playing" && !isInKillcam() )
|
||||
self thread maps\mp\gametypes\_playerlogic::spawnClient();
|
||||
}
|
||||
|
||||
self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
addToTeam( team, firstConnect )
|
||||
{
|
||||
// UTS update playerCount remove from team
|
||||
if ( isDefined( self.team ) )
|
||||
self maps\mp\gametypes\_playerlogic::removeFromTeamCount();
|
||||
|
||||
self.pers["team"] = team;
|
||||
// this is the only place self.team should ever be set
|
||||
self.team = team;
|
||||
|
||||
// session team is readonly in ranked matches on console
|
||||
if ( !matchMakingGame() || isDefined( self.pers["isBot"] ) )
|
||||
{
|
||||
if ( level.teamBased )
|
||||
{
|
||||
self.sessionteam = team;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( team == "spectator" )
|
||||
self.sessionteam = "spectator";
|
||||
else
|
||||
self.sessionteam = "none";
|
||||
}
|
||||
}
|
||||
|
||||
// UTS update playerCount add to team
|
||||
if ( game["state"] != "postgame" )
|
||||
self maps\mp\gametypes\_playerlogic::addToTeamCount();
|
||||
|
||||
self updateObjectiveText();
|
||||
|
||||
// give "joined_team" and "joined_spectators" handlers a chance to start
|
||||
// these are generally triggered from the "connected" notify, which can happen on the same
|
||||
// frame as these notifies
|
||||
if ( isDefined( firstConnect ) && firstConnect )
|
||||
waittillframeend;
|
||||
|
||||
self updateMainMenu();
|
||||
|
||||
if ( team == "spectator" )
|
||||
{
|
||||
self notify( "joined_spectators" );
|
||||
level notify( "joined_team" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self notify( "joined_team" );
|
||||
level notify( "joined_team" );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,483 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
init()
|
||||
{
|
||||
|
||||
game["music"]["spawn_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "spawn_music";
|
||||
game["music"]["defeat_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "defeat_music";
|
||||
game["music"]["victory_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "victory_music";
|
||||
game["music"]["winning_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "winning_music";
|
||||
game["music"]["losing_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "losing_music";
|
||||
game["voice"]["allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "1mc_";
|
||||
|
||||
game["music"]["spawn_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "spawn_music";
|
||||
game["music"]["defeat_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "defeat_music";
|
||||
game["music"]["victory_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "victory_music";
|
||||
game["music"]["winning_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "winning_music";
|
||||
game["music"]["losing_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "losing_music";
|
||||
game["voice"]["axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "1mc_";
|
||||
|
||||
game["music"]["defeat"] = "mp_defeat";
|
||||
game["music"]["victory_spectator"] = "mp_defeat";
|
||||
game["music"]["winning_time"] = "mp_time_running_out_winning";
|
||||
game["music"]["losing_time"] = "mp_time_running_out_losing";
|
||||
game["music"]["winning_score"] = "mp_time_running_out_winning";
|
||||
game["music"]["losing_score"] = "mp_time_running_out_losing";
|
||||
game["music"]["victory_tie"] = "mp_defeat";
|
||||
|
||||
game["music"]["suspense"] = [];
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_01";
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_02";
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_03";
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_04";
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_05";
|
||||
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_06";
|
||||
|
||||
game["dialog"]["mission_success"] = "mission_success";
|
||||
game["dialog"]["mission_failure"] = "mission_fail";
|
||||
game["dialog"]["mission_draw"] = "draw";
|
||||
|
||||
game["dialog"]["round_success"] = "encourage_win";
|
||||
game["dialog"]["round_failure"] = "encourage_lost";
|
||||
game["dialog"]["round_draw"] = "draw";
|
||||
|
||||
// status
|
||||
game["dialog"]["timesup"] = "timesup";
|
||||
game["dialog"]["winning_time"] = "winning";
|
||||
game["dialog"]["losing_time"] = "losing";
|
||||
game["dialog"]["winning_score"] = "winning_fight";
|
||||
game["dialog"]["losing_score"] = "losing_fight";
|
||||
game["dialog"]["lead_lost"] = "lead_lost";
|
||||
game["dialog"]["lead_tied"] = "tied";
|
||||
game["dialog"]["lead_taken"] = "lead_taken";
|
||||
game["dialog"]["last_alive"] = "lastalive";
|
||||
|
||||
game["dialog"]["boost"] = "boost";
|
||||
|
||||
if ( !isDefined( game["dialog"]["offense_obj"] ) )
|
||||
game["dialog"]["offense_obj"] = "boost";
|
||||
if ( !isDefined( game["dialog"]["defense_obj"] ) )
|
||||
game["dialog"]["defense_obj"] = "boost";
|
||||
|
||||
game["dialog"]["hardcore"] = "hardcore";
|
||||
game["dialog"]["highspeed"] = "highspeed";
|
||||
game["dialog"]["tactical"] = "tactical";
|
||||
|
||||
game["dialog"]["challenge"] = "challengecomplete";
|
||||
game["dialog"]["promotion"] = "promotion";
|
||||
|
||||
game["dialog"]["bomb_taken"] = "acheive_bomb";
|
||||
game["dialog"]["bomb_lost"] = "bomb_taken";
|
||||
game["dialog"]["bomb_defused"] = "bomb_defused";
|
||||
game["dialog"]["bomb_planted"] = "bomb_planted";
|
||||
|
||||
game["dialog"]["obj_taken"] = "securedobj";
|
||||
game["dialog"]["obj_lost"] = "lostobj";
|
||||
|
||||
game["dialog"]["obj_defend"] = "obj_defend";
|
||||
game["dialog"]["obj_destroy"] = "obj_destroy";
|
||||
game["dialog"]["obj_capture"] = "capture_obj";
|
||||
game["dialog"]["objs_capture"] = "capture_objs";
|
||||
|
||||
game["dialog"]["hq_located"] = "hq_located";
|
||||
game["dialog"]["hq_enemy_captured"] = "hq_captured";
|
||||
game["dialog"]["hq_enemy_destroyed"] = "hq_destroyed";
|
||||
game["dialog"]["hq_secured"] = "hq_secured";
|
||||
game["dialog"]["hq_offline"] = "hq_offline";
|
||||
game["dialog"]["hq_online"] = "hq_online";
|
||||
|
||||
game["dialog"]["move_to_new"] = "new_positions";
|
||||
|
||||
game["dialog"]["push_forward"] = "pushforward";
|
||||
|
||||
game["dialog"]["attack"] = "attack";
|
||||
game["dialog"]["defend"] = "defend";
|
||||
game["dialog"]["offense"] = "offense";
|
||||
game["dialog"]["defense"] = "defense";
|
||||
|
||||
game["dialog"]["halftime"] = "halftime";
|
||||
game["dialog"]["overtime"] = "overtime";
|
||||
game["dialog"]["side_switch"] = "switching";
|
||||
|
||||
game["dialog"]["flag_taken"] = "ourflag";
|
||||
game["dialog"]["flag_dropped"] = "ourflag_drop";
|
||||
game["dialog"]["flag_returned"] = "ourflag_return";
|
||||
game["dialog"]["flag_captured"] = "ourflag_capt";
|
||||
game["dialog"]["flag_getback"] = "getback_ourflag";
|
||||
game["dialog"]["enemy_flag_bringhome"] = "enemyflag_tobase";
|
||||
game["dialog"]["enemy_flag_taken"] = "enemyflag";
|
||||
game["dialog"]["enemy_flag_dropped"] = "enemyflag_drop";
|
||||
game["dialog"]["enemy_flag_returned"] = "enemyflag_return";
|
||||
game["dialog"]["enemy_flag_captured"] = "enemyflag_capt";
|
||||
|
||||
game["dialog"]["capturing_a"] = "capturing_a";
|
||||
game["dialog"]["capturing_b"] = "capturing_b";
|
||||
game["dialog"]["capturing_c"] = "capturing_c";
|
||||
game["dialog"]["captured_a"] = "capture_a";
|
||||
game["dialog"]["captured_b"] = "capture_c";
|
||||
game["dialog"]["captured_c"] = "capture_b";
|
||||
|
||||
game["dialog"]["securing_a"] = "securing_a";
|
||||
game["dialog"]["securing_b"] = "securing_b";
|
||||
game["dialog"]["securing_c"] = "securing_c";
|
||||
game["dialog"]["secured_a"] = "secure_a";
|
||||
game["dialog"]["secured_b"] = "secure_b";
|
||||
game["dialog"]["secured_c"] = "secure_c";
|
||||
|
||||
game["dialog"]["losing_a"] = "losing_a";
|
||||
game["dialog"]["losing_b"] = "losing_b";
|
||||
game["dialog"]["losing_c"] = "losing_c";
|
||||
game["dialog"]["lost_a"] = "lost_a";
|
||||
game["dialog"]["lost_b"] = "lost_b";
|
||||
game["dialog"]["lost_c"] = "lost_c";
|
||||
|
||||
game["dialog"]["enemy_taking_a"] = "enemy_take_a";
|
||||
game["dialog"]["enemy_taking_b"] = "enemy_take_b";
|
||||
game["dialog"]["enemy_taking_c"] = "enemy_take_c";
|
||||
game["dialog"]["enemy_has_a"] = "enemy_has_a";
|
||||
game["dialog"]["enemy_has_b"] = "enemy_has_b";
|
||||
game["dialog"]["enemy_has_c"] = "enemy_has_c";
|
||||
|
||||
game["dialog"]["lost_all"] = "take_positions";
|
||||
game["dialog"]["secure_all"] = "positions_lock";
|
||||
|
||||
game["dialog"]["destroy_sentry"] = "dest_sentrygun";
|
||||
game["music"]["nuke_music"] = "nuke_music";
|
||||
|
||||
game["dialog"]["sentry_gone"] = "sentry_gone";
|
||||
game["dialog"]["sentry_destroyed"] = "sentry_gone";
|
||||
game["dialog"]["ti_gone"] = "ti_cancelled";
|
||||
game["dialog"]["ti_destroyed"] = "ti_blocked";
|
||||
|
||||
level thread onPlayerConnect();
|
||||
level thread onLastAlive();
|
||||
level thread musicController();
|
||||
level thread onGameEnded();
|
||||
level thread onRoundSwitch();
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill ( "connected", player );
|
||||
|
||||
player thread onPlayerSpawned();
|
||||
player thread finalKillcamMusic();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
if ( !level.splitscreen || level.splitscreen && !isDefined( level.playedStartingMusic ) )
|
||||
{
|
||||
self playLocalSound( game["music"]["spawn_" + self.team] );
|
||||
|
||||
|
||||
if ( level.splitscreen )
|
||||
level.playedStartingMusic = true;
|
||||
}
|
||||
|
||||
if ( isDefined( game["dialog"]["gametype"] ) && (!level.splitscreen || self == level.players[0]) )
|
||||
self leaderDialogOnPlayer( "gametype" );
|
||||
|
||||
gameFlagWait( "prematch_done" );
|
||||
|
||||
if ( self.team == game["attackers"] )
|
||||
self leaderDialogOnPlayer( "offense_obj", "introboost" );
|
||||
else
|
||||
self leaderDialogOnPlayer( "defense_obj", "introboost" );
|
||||
}
|
||||
|
||||
|
||||
onLastAlive()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
|
||||
level waittill ( "last_alive", player );
|
||||
|
||||
if ( !isAlive( player ) )
|
||||
return;
|
||||
|
||||
player leaderDialogOnPlayer( "last_alive" );
|
||||
}
|
||||
|
||||
|
||||
onRoundSwitch()
|
||||
{
|
||||
level waittill ( "round_switch", switchType );
|
||||
|
||||
switch( switchType )
|
||||
{
|
||||
case "halftime":
|
||||
foreach ( player in level.players )
|
||||
player leaderDialogOnPlayer( "halftime" );
|
||||
break;
|
||||
case "overtime":
|
||||
foreach ( player in level.players )
|
||||
player leaderDialogOnPlayer( "overtime" );
|
||||
break;
|
||||
default:
|
||||
foreach ( player in level.players )
|
||||
player leaderDialogOnPlayer( "side_switch" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onGameEnded()
|
||||
{
|
||||
level thread roundWinnerDialog();
|
||||
level thread gameWinnerDialog();
|
||||
|
||||
level waittill ( "game_win", winner );
|
||||
|
||||
if ( isDefined( level.nukeDetonated ) )
|
||||
{
|
||||
if ( !level.splitScreen )
|
||||
playSoundOnPlayers( game["music"]["nuke_music"] );
|
||||
else
|
||||
level.players[0] playLocalSound( game["music"]["nuke_music"] );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( level.teamBased )
|
||||
{
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
if ( winner == "allies" )
|
||||
playSoundOnPlayers( game["music"]["victory_allies"], "allies" );
|
||||
else if ( winner == "axis" )
|
||||
playSoundOnPlayers( game["music"]["victory_axis"], "axis" );
|
||||
else
|
||||
playSoundOnPlayers( game["music"]["nuke_music"] );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( winner == "allies" )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["victory_allies"], "allies" );
|
||||
playSoundOnPlayers( game["music"]["defeat_axis"], "axis" );
|
||||
}
|
||||
else if ( winner == "axis" )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["victory_axis"], "axis" );
|
||||
playSoundOnPlayers( game["music"]["defeat_allies"], "allies" );
|
||||
}
|
||||
else
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["nuke_music"] );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( player.pers["team"] != "allies" && player.pers["team"] != "axis" )
|
||||
player playLocalSound( game["music"]["nuke_music"] );
|
||||
else if ( isDefined( winner ) && player == winner )
|
||||
player playLocalSound( game["music"]["victory_" + player.pers["team"] ] );
|
||||
else if ( !level.splitScreen )
|
||||
player playLocalSound( game["music"]["defeat_" + player.pers["team"] ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
roundWinnerDialog()
|
||||
{
|
||||
level waittill ( "round_win", winner );
|
||||
|
||||
delay = level.roundEndDelay / 4;
|
||||
if ( delay > 0 )
|
||||
wait ( delay );
|
||||
|
||||
if ( !isDefined( winner ) || isPlayer( winner ) || isDefined( level.nukeDetonated ) )
|
||||
return;
|
||||
|
||||
if ( winner == "allies" )
|
||||
{
|
||||
leaderDialog( "round_success", "allies" );
|
||||
leaderDialog( "round_failure", "axis" );
|
||||
}
|
||||
else if ( winner == "axis" )
|
||||
{
|
||||
leaderDialog( "round_success", "axis" );
|
||||
leaderDialog( "round_failure", "allies" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gameWinnerDialog()
|
||||
{
|
||||
level waittill ( "game_win", winner );
|
||||
|
||||
delay = level.postRoundTime / 2;
|
||||
if ( delay > 0 )
|
||||
wait ( delay );
|
||||
|
||||
if ( !isDefined( winner ) || isPlayer( winner ) || isDefined( level.nukeDetonated ) )
|
||||
return;
|
||||
|
||||
if ( winner == "allies" )
|
||||
{
|
||||
leaderDialog( "mission_success", "allies" );
|
||||
leaderDialog( "mission_failure", "axis" );
|
||||
}
|
||||
else if ( winner == "axis" )
|
||||
{
|
||||
leaderDialog( "mission_success", "axis" );
|
||||
leaderDialog( "mission_failure", "allies" );
|
||||
}
|
||||
else
|
||||
{
|
||||
leaderDialog( "mission_draw" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
musicController()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
|
||||
if ( !level.hardcoreMode )
|
||||
thread suspenseMusic();
|
||||
|
||||
level waittill ( "match_ending_soon", reason );
|
||||
assert( isDefined( reason ) );
|
||||
|
||||
if ( getWatchedDvar( "roundlimit" ) == 1 || game["roundsPlayed"] == (getWatchedDvar( "roundlimit" ) - 1) )
|
||||
{
|
||||
if ( !level.splitScreen )
|
||||
{
|
||||
if ( reason == "time" )
|
||||
{
|
||||
if ( level.teamBased )
|
||||
{
|
||||
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
|
||||
{
|
||||
if ( !level.hardcoreMode )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["winning_allies"], "allies" );
|
||||
playSoundOnPlayers( game["music"]["losing_axis"], "axis" );
|
||||
}
|
||||
|
||||
leaderDialog( "winning_time", "allies" );
|
||||
leaderDialog( "losing_time", "axis" );
|
||||
}
|
||||
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
|
||||
{
|
||||
if ( !level.hardcoreMode )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["winning_axis"], "axis" );
|
||||
playSoundOnPlayers( game["music"]["losing_allies"], "allies" );
|
||||
}
|
||||
|
||||
leaderDialog( "winning_time", "axis" );
|
||||
leaderDialog( "losing_time", "allies" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !level.hardcoreMode )
|
||||
playSoundOnPlayers( game["music"]["losing_time"] );
|
||||
|
||||
leaderDialog( "timesup" );
|
||||
}
|
||||
}
|
||||
else if ( reason == "score" )
|
||||
{
|
||||
if ( level.teamBased )
|
||||
{
|
||||
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
|
||||
{
|
||||
if ( !level.hardcoreMode )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["winning_allies"], "allies" );
|
||||
playSoundOnPlayers( game["music"]["losing_axis"], "axis" );
|
||||
}
|
||||
|
||||
leaderDialog( "winning_score", "allies" );
|
||||
leaderDialog( "losing_score", "axis" );
|
||||
}
|
||||
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
|
||||
{
|
||||
if ( !level.hardcoreMode )
|
||||
{
|
||||
playSoundOnPlayers( game["music"]["winning_axis"], "axis" );
|
||||
playSoundOnPlayers( game["music"]["losing_allies"], "allies" );
|
||||
}
|
||||
|
||||
leaderDialog( "winning_score", "axis" );
|
||||
leaderDialog( "losing_score", "allies" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
winningPlayer = maps\mp\gametypes\_gamescore::getHighestScoringPlayer();
|
||||
losingPlayers = maps\mp\gametypes\_gamescore::getLosingPlayers();
|
||||
excludeList[0] = winningPlayer;
|
||||
|
||||
if ( !level.hardcoreMode )
|
||||
{
|
||||
winningPlayer playLocalSound( game["music"]["winning_" + winningPlayer.pers["team"] ] );
|
||||
|
||||
foreach ( otherPlayer in level.players )
|
||||
{
|
||||
if ( otherPlayer == winningPlayer )
|
||||
continue;
|
||||
|
||||
otherPlayer playLocalSound( game["music"]["losing_" + otherPlayer.pers["team"] ] );
|
||||
}
|
||||
}
|
||||
|
||||
winningPlayer leaderDialogOnPlayer( "winning_score" );
|
||||
leaderDialogOnPlayers( "losing_score", losingPlayers );
|
||||
}
|
||||
}
|
||||
|
||||
level waittill ( "match_ending_very_soon" );
|
||||
leaderDialog( "timesup" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !level.hardcoreMode )
|
||||
playSoundOnPlayers( game["music"]["losing_allies"] );
|
||||
|
||||
leaderDialog( "timesup" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suspenseMusic()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
level endon ( "match_ending_soon" );
|
||||
|
||||
numTracks = game["music"]["suspense"].size;
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( randomFloatRange( 60, 120 ) );
|
||||
|
||||
playSoundOnPlayers( game["music"]["suspense"][randomInt(numTracks)] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finalKillcamMusic()
|
||||
{
|
||||
self waittill ( "showing_final_killcam" );
|
||||
|
||||
// self playLocalSound( game["music"]["winning"] );
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
init()
|
||||
{
|
||||
precacheShader("objpoint_default");
|
||||
|
||||
level.objPointNames = [];
|
||||
level.objPoints = [];
|
||||
|
||||
if ( level.splitscreen )
|
||||
level.objPointSize = 15;
|
||||
else
|
||||
level.objPointSize = 8;
|
||||
|
||||
level.objpoint_alpha_default = .5;
|
||||
level.objPointScale = 1.0;
|
||||
}
|
||||
|
||||
|
||||
createTeamObjpoint( name, origin, team, shader, alpha, scale )
|
||||
{
|
||||
assert( team == "axis" || team == "allies" || team == "all" );
|
||||
|
||||
objPoint = getObjPointByName( name );
|
||||
|
||||
if ( isDefined( objPoint ) )
|
||||
deleteObjPoint( objPoint );
|
||||
|
||||
if ( !isDefined( shader ) )
|
||||
shader = "objpoint_default";
|
||||
|
||||
if ( !isDefined( scale ) )
|
||||
scale = 1.0;
|
||||
|
||||
if ( team != "all" )
|
||||
objPoint = newTeamHudElem( team );
|
||||
else
|
||||
objPoint = newHudElem();
|
||||
|
||||
objPoint.name = name;
|
||||
objPoint.x = origin[0];
|
||||
objPoint.y = origin[1];
|
||||
objPoint.z = origin[2];
|
||||
objPoint.team = team;
|
||||
objPoint.isFlashing = false;
|
||||
objPoint.isShown = true;
|
||||
|
||||
objPoint setShader( shader, level.objPointSize, level.objPointSize );
|
||||
objPoint setWaypoint( true, false );
|
||||
|
||||
if ( isDefined( alpha ) )
|
||||
objPoint.alpha = alpha;
|
||||
else
|
||||
objPoint.alpha = level.objpoint_alpha_default;
|
||||
objPoint.baseAlpha = objPoint.alpha;
|
||||
|
||||
objPoint.index = level.objPointNames.size;
|
||||
level.objPoints[name] = objPoint;
|
||||
level.objPointNames[level.objPointNames.size] = name;
|
||||
|
||||
return objPoint;
|
||||
}
|
||||
|
||||
|
||||
deleteObjPoint( oldObjPoint )
|
||||
{
|
||||
assert( level.objPoints.size == level.objPointNames.size );
|
||||
|
||||
if ( level.objPoints.size == 1 )
|
||||
{
|
||||
assert( level.objPointNames[0] == oldObjPoint.name );
|
||||
assert( isDefined( level.objPoints[oldObjPoint.name] ) );
|
||||
|
||||
level.objPoints = [];
|
||||
level.objPointNames = [];
|
||||
oldObjPoint destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
newIndex = oldObjPoint.index;
|
||||
oldIndex = (level.objPointNames.size - 1);
|
||||
|
||||
objPoint = getObjPointByIndex( oldIndex );
|
||||
level.objPointNames[newIndex] = objPoint.name;
|
||||
objPoint.index = newIndex;
|
||||
|
||||
level.objPointNames[oldIndex] = undefined;
|
||||
level.objPoints[oldObjPoint.name] = undefined;
|
||||
|
||||
oldObjPoint destroy();
|
||||
}
|
||||
|
||||
|
||||
updateOrigin( origin )
|
||||
{
|
||||
if ( self.x != origin[0] )
|
||||
self.x = origin[0];
|
||||
|
||||
if ( self.y != origin[1] )
|
||||
self.y = origin[1];
|
||||
|
||||
if ( self.z != origin[2] )
|
||||
self.z = origin[2];
|
||||
}
|
||||
|
||||
|
||||
setOriginByName( name, origin )
|
||||
{
|
||||
objPoint = getObjPointByName( name );
|
||||
objPoint updateOrigin( origin );
|
||||
}
|
||||
|
||||
|
||||
getObjPointByName( name )
|
||||
{
|
||||
if ( isDefined( level.objPoints[name] ) )
|
||||
return level.objPoints[name];
|
||||
else
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getObjPointByIndex( index )
|
||||
{
|
||||
if ( isDefined( level.objPointNames[index] ) )
|
||||
return level.objPoints[level.objPointNames[index]];
|
||||
else
|
||||
return undefined;
|
||||
}
|
||||
|
||||
startFlashing()
|
||||
{
|
||||
self endon("stop_flashing_thread");
|
||||
|
||||
if ( self.isFlashing )
|
||||
return;
|
||||
|
||||
self.isFlashing = true;
|
||||
|
||||
while ( self.isFlashing )
|
||||
{
|
||||
self fadeOverTime( 0.75 );
|
||||
self.alpha = 0.35 * self.baseAlpha;
|
||||
wait ( 0.75 );
|
||||
|
||||
self fadeOverTime( 0.75 );
|
||||
self.alpha = self.baseAlpha;
|
||||
wait ( 0.75 );
|
||||
}
|
||||
|
||||
self.alpha = self.baseAlpha;
|
||||
}
|
||||
|
||||
stopFlashing()
|
||||
{
|
||||
if ( !self.isFlashing )
|
||||
return;
|
||||
|
||||
self.isFlashing = false;
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.persistentDataInfo = [];
|
||||
|
||||
maps\mp\gametypes\_class::init();
|
||||
maps\mp\gametypes\_rank::init();
|
||||
maps\mp\gametypes\_missions::init();
|
||||
maps\mp\gametypes\_playercards::init();
|
||||
|
||||
level thread updateBufferedStats();
|
||||
}
|
||||
|
||||
|
||||
initBufferedStats()
|
||||
{
|
||||
self.bufferedStats = [];
|
||||
self.bufferedStats[ "totalShots" ] = self getPlayerData( "totalShots" );
|
||||
self.bufferedStats[ "accuracy" ] = self getPlayerData( "accuracy" );
|
||||
self.bufferedStats[ "misses" ] = self getPlayerData( "misses" );
|
||||
self.bufferedStats[ "hits" ] = self getPlayerData( "hits" );
|
||||
self.bufferedStats[ "timePlayedAllies" ] = self getPlayerData( "timePlayedAllies" );
|
||||
self.bufferedStats[ "timePlayedOpfor" ] = self getPlayerData( "timePlayedOpfor" );
|
||||
self.bufferedStats[ "timePlayedOther" ] = self getPlayerData( "timePlayedOther" );
|
||||
self.bufferedStats[ "timePlayedTotal" ] = self getPlayerData( "timePlayedTotal" );
|
||||
|
||||
self.bufferedChildStats = [];
|
||||
self.bufferedChildStats[ "round" ] = [];
|
||||
self.bufferedChildStats[ "round" ][ "timePlayed" ] = self getPlayerData( "round", "timePlayed" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==========================================
|
||||
// Script persistent data functions
|
||||
// These are made for convenience, so persistent data can be tracked by strings.
|
||||
// They make use of code functions which are prototyped below.
|
||||
|
||||
/*
|
||||
=============
|
||||
statGet
|
||||
|
||||
Returns the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statGet( dataName )
|
||||
{
|
||||
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
|
||||
return self GetPlayerData( dataName );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
statSet
|
||||
|
||||
Sets the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statSet( dataName, value )
|
||||
{
|
||||
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
self SetPlayerData( dataName, value );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
statAdd
|
||||
|
||||
Adds the passed value to the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statAdd( dataName, value )
|
||||
{
|
||||
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
curValue = self GetPlayerData( dataName );
|
||||
self SetPlayerData( dataName, value + curValue );
|
||||
}
|
||||
|
||||
|
||||
statGetChild( parent, child )
|
||||
{
|
||||
return self GetPlayerData( parent, child );
|
||||
}
|
||||
|
||||
|
||||
statSetChild( parent, child, value )
|
||||
{
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
self SetPlayerData( parent, child, value );
|
||||
}
|
||||
|
||||
|
||||
statAddChild( parent, child, value )
|
||||
{
|
||||
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
curValue = self GetPlayerData( parent, child );
|
||||
self SetPlayerData( parent, child, curValue + value );
|
||||
}
|
||||
|
||||
|
||||
statGetChildBuffered( parent, child )
|
||||
{
|
||||
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
|
||||
|
||||
return self.bufferedChildStats[ parent ][ child ];
|
||||
}
|
||||
|
||||
|
||||
statSetChildBuffered( parent, child, value )
|
||||
{
|
||||
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
self.bufferedChildStats[ parent ][ child ] = value;
|
||||
}
|
||||
|
||||
|
||||
statAddChildBuffered( parent, child, value )
|
||||
{
|
||||
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
curValue = statGetChildBuffered( parent, child );
|
||||
statSetChildBuffered( parent, child, curValue + value );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
statGetBuffered
|
||||
|
||||
Returns the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statGetBuffered( dataName )
|
||||
{
|
||||
assert( isDefined( self.bufferedStats[ dataName ] ) );
|
||||
|
||||
return self.bufferedStats[ dataName ];
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
statSet
|
||||
|
||||
Sets the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statSetBuffered( dataName, value )
|
||||
{
|
||||
assert( isDefined( self.bufferedStats[ dataName ] ) );
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
self.bufferedStats[ dataName ] = value;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
statAdd
|
||||
|
||||
Adds the passed value to the value of the named stat
|
||||
=============
|
||||
*/
|
||||
statAddBuffered( dataName, value )
|
||||
{
|
||||
assert( isDefined( self.bufferedStats[ dataName ] ) );
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
curValue = statGetBuffered( dataName );
|
||||
statSetBuffered( dataName, curValue + value );
|
||||
}
|
||||
|
||||
|
||||
updateBufferedStats()
|
||||
{
|
||||
// give the first player time to connect
|
||||
wait ( 0.15 );
|
||||
|
||||
nextToUpdate = 0;
|
||||
while ( !level.gameEnded )
|
||||
{
|
||||
nextToUpdate++;
|
||||
if ( nextToUpdate >= level.players.size )
|
||||
nextToUpdate = 0;
|
||||
|
||||
if ( isDefined( level.players[nextToUpdate] ) )
|
||||
level.players[nextToUpdate] writeBufferedStats();
|
||||
|
||||
wait ( 2.0 );
|
||||
}
|
||||
|
||||
foreach ( player in level.players )
|
||||
player writeBufferedStats();
|
||||
}
|
||||
|
||||
|
||||
writeBufferedStats()
|
||||
{
|
||||
foreach ( statName, statVal in self.bufferedStats )
|
||||
{
|
||||
self setPlayerData( statName, statVal );
|
||||
}
|
||||
|
||||
foreach ( statName, statVal in self.bufferedChildStats )
|
||||
{
|
||||
foreach ( childStatName, childStatVal in statVal )
|
||||
self setPlayerData( statName, childStatName, childStatVal );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
|
||||
init()
|
||||
{
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
//@NOTE: Should we make sure they're really unlocked before setting them? Catch cheaters...
|
||||
// e.g. isItemUnlocked( iconHandle )
|
||||
|
||||
iconHandle = player maps\mp\gametypes\_persistence::statGet( "cardIcon" );
|
||||
player SetCardIcon( iconHandle );
|
||||
|
||||
titleHandle = player maps\mp\gametypes\_persistence::statGet( "cardTitle" );
|
||||
player SetCardTitle( titleHandle );
|
||||
|
||||
nameplateHandle = player maps\mp\gametypes\_persistence::statGet( "cardNameplate" );
|
||||
player SetCardNameplate( nameplateHandle );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,686 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
|
||||
init()
|
||||
{
|
||||
level.scoreInfo = [];
|
||||
level.xpScale = getDvarInt( "scr_xpscale" );
|
||||
|
||||
if ( level.xpScale > 4 || level.xpScale < 0)
|
||||
exitLevel( false );
|
||||
|
||||
level.xpScale = min( level.xpScale, 4 );
|
||||
level.xpScale = max( level.xpScale, 0 );
|
||||
|
||||
level.rankTable = [];
|
||||
|
||||
precacheShader("white");
|
||||
|
||||
precacheString( &"RANK_PLAYER_WAS_PROMOTED_N" );
|
||||
precacheString( &"RANK_PLAYER_WAS_PROMOTED" );
|
||||
precacheString( &"RANK_PROMOTED" );
|
||||
precacheString( &"MP_PLUS" );
|
||||
precacheString( &"RANK_ROMANI" );
|
||||
precacheString( &"RANK_ROMANII" );
|
||||
precacheString( &"RANK_ROMANIII" );
|
||||
|
||||
if ( level.teamBased )
|
||||
{
|
||||
registerScoreInfo( "kill", 100 );
|
||||
registerScoreInfo( "headshot", 100 );
|
||||
registerScoreInfo( "assist", 20 );
|
||||
registerScoreInfo( "suicide", 0 );
|
||||
registerScoreInfo( "teamkill", 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
registerScoreInfo( "kill", 50 );
|
||||
registerScoreInfo( "headshot", 50 );
|
||||
registerScoreInfo( "assist", 0 );
|
||||
registerScoreInfo( "suicide", 0 );
|
||||
registerScoreInfo( "teamkill", 0 );
|
||||
}
|
||||
|
||||
registerScoreInfo( "win", 1 );
|
||||
registerScoreInfo( "loss", 0.5 );
|
||||
registerScoreInfo( "tie", 0.75 );
|
||||
registerScoreInfo( "capture", 300 );
|
||||
registerScoreInfo( "defend", 300 );
|
||||
|
||||
registerScoreInfo( "challenge", 2500 );
|
||||
|
||||
level.maxRank = int(tableLookup( "mp/rankTable.csv", 0, "maxrank", 1 ));
|
||||
level.maxPrestige = int(tableLookup( "mp/rankIconTable.csv", 0, "maxprestige", 1 ));
|
||||
|
||||
pId = 0;
|
||||
rId = 0;
|
||||
for ( pId = 0; pId <= level.maxPrestige; pId++ )
|
||||
{
|
||||
for ( rId = 0; rId <= level.maxRank; rId++ )
|
||||
precacheShader( tableLookup( "mp/rankIconTable.csv", 0, rId, pId+1 ) );
|
||||
}
|
||||
|
||||
rankId = 0;
|
||||
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
|
||||
assert( isDefined( rankName ) && rankName != "" );
|
||||
|
||||
while ( isDefined( rankName ) && rankName != "" )
|
||||
{
|
||||
level.rankTable[rankId][1] = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
|
||||
level.rankTable[rankId][2] = tableLookup( "mp/ranktable.csv", 0, rankId, 2 );
|
||||
level.rankTable[rankId][3] = tableLookup( "mp/ranktable.csv", 0, rankId, 3 );
|
||||
level.rankTable[rankId][7] = tableLookup( "mp/ranktable.csv", 0, rankId, 7 );
|
||||
|
||||
precacheString( tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 ) );
|
||||
|
||||
rankId++;
|
||||
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
|
||||
}
|
||||
|
||||
maps\mp\gametypes\_missions::buildChallegeInfo();
|
||||
|
||||
level thread patientZeroWaiter();
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
patientZeroWaiter()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
while ( !isDefined( level.players ) || !level.players.size )
|
||||
wait ( 0.05 );
|
||||
|
||||
if ( !matchMakingGame() )
|
||||
{
|
||||
if ( (getDvar( "mapname" ) == "mp_rust" && randomInt( 1000 ) == 999) )
|
||||
level.patientZeroName = level.players[0].name;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( getDvar( "scr_patientZero" ) != "" )
|
||||
level.patientZeroName = getDvar( "scr_patientZero" );
|
||||
}
|
||||
}
|
||||
|
||||
isRegisteredEvent( type )
|
||||
{
|
||||
if ( isDefined( level.scoreInfo[type] ) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
registerScoreInfo( type, value )
|
||||
{
|
||||
level.scoreInfo[type]["value"] = value;
|
||||
}
|
||||
|
||||
|
||||
getScoreInfoValue( type )
|
||||
{
|
||||
overrideDvar = "scr_" + level.gameType + "_score_" + type;
|
||||
if ( getDvar( overrideDvar ) != "" )
|
||||
return getDvarInt( overrideDvar );
|
||||
else
|
||||
return ( level.scoreInfo[type]["value"] );
|
||||
}
|
||||
|
||||
|
||||
getScoreInfoLabel( type )
|
||||
{
|
||||
return ( level.scoreInfo[type]["label"] );
|
||||
}
|
||||
|
||||
|
||||
getRankInfoMinXP( rankId )
|
||||
{
|
||||
return int(level.rankTable[rankId][2]);
|
||||
}
|
||||
|
||||
|
||||
getRankInfoXPAmt( rankId )
|
||||
{
|
||||
return int(level.rankTable[rankId][3]);
|
||||
}
|
||||
|
||||
|
||||
getRankInfoMaxXp( rankId )
|
||||
{
|
||||
return int(level.rankTable[rankId][7]);
|
||||
}
|
||||
|
||||
|
||||
getRankInfoFull( rankId )
|
||||
{
|
||||
return tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 );
|
||||
}
|
||||
|
||||
|
||||
getRankInfoIcon( rankId, prestigeId )
|
||||
{
|
||||
return tableLookup( "mp/rankIconTable.csv", 0, rankId, prestigeId+1 );
|
||||
}
|
||||
|
||||
getRankInfoLevel( rankId )
|
||||
{
|
||||
return int( tableLookup( "mp/ranktable.csv", 0, rankId, 13 ) );
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
/#
|
||||
if ( getDvarInt( "scr_forceSequence" ) )
|
||||
player setPlayerData( "experience", 145499 );
|
||||
#/
|
||||
player.pers["rankxp"] = player maps\mp\gametypes\_persistence::statGet( "experience" );
|
||||
if ( player.pers["rankxp"] < 0 ) // paranoid defensive
|
||||
player.pers["rankxp"] = 0;
|
||||
|
||||
rankId = player getRankForXp( player getRankXP() );
|
||||
player.pers[ "rank" ] = rankId;
|
||||
player.pers[ "participation" ] = 0;
|
||||
|
||||
player.xpUpdateTotal = 0;
|
||||
player.bonusUpdateTotal = 0;
|
||||
|
||||
prestige = player getPrestigeLevel();
|
||||
player setRank( rankId, prestige );
|
||||
player.pers["prestige"] = prestige;
|
||||
|
||||
player.postGamePromotion = false;
|
||||
if ( !isDefined( player.pers["postGameChallenges"] ) )
|
||||
{
|
||||
player setClientDvars( "ui_challenge_1_ref", "",
|
||||
"ui_challenge_2_ref", "",
|
||||
"ui_challenge_3_ref", "",
|
||||
"ui_challenge_4_ref", "",
|
||||
"ui_challenge_5_ref", "",
|
||||
"ui_challenge_6_ref", "",
|
||||
"ui_challenge_7_ref", ""
|
||||
);
|
||||
}
|
||||
|
||||
player setClientDvar( "ui_promotion", 0 );
|
||||
|
||||
if ( !isDefined( player.pers["summary"] ) )
|
||||
{
|
||||
player.pers["summary"] = [];
|
||||
player.pers["summary"]["xp"] = 0;
|
||||
player.pers["summary"]["score"] = 0;
|
||||
player.pers["summary"]["challenge"] = 0;
|
||||
player.pers["summary"]["match"] = 0;
|
||||
player.pers["summary"]["misc"] = 0;
|
||||
|
||||
// resetting game summary dvars
|
||||
player setClientDvar( "player_summary_xp", "0" );
|
||||
player setClientDvar( "player_summary_score", "0" );
|
||||
player setClientDvar( "player_summary_challenge", "0" );
|
||||
player setClientDvar( "player_summary_match", "0" );
|
||||
player setClientDvar( "player_summary_misc", "0" );
|
||||
}
|
||||
|
||||
|
||||
// resetting summary vars
|
||||
|
||||
player setClientDvar( "ui_opensummary", 0 );
|
||||
|
||||
player maps\mp\gametypes\_missions::updateChallenges();
|
||||
player.explosiveKills[0] = 0;
|
||||
player.xpGains = [];
|
||||
|
||||
player.hud_scorePopup = newClientHudElem( player );
|
||||
player.hud_scorePopup.horzAlign = "center";
|
||||
player.hud_scorePopup.vertAlign = "middle";
|
||||
player.hud_scorePopup.alignX = "center";
|
||||
player.hud_scorePopup.alignY = "middle";
|
||||
player.hud_scorePopup.x = 0;
|
||||
if ( level.splitScreen )
|
||||
player.hud_scorePopup.y = -40;
|
||||
else
|
||||
player.hud_scorePopup.y = -60;
|
||||
player.hud_scorePopup.font = "hudbig";
|
||||
player.hud_scorePopup.fontscale = 0.75;
|
||||
player.hud_scorePopup.archived = false;
|
||||
player.hud_scorePopup.color = (0.5,0.5,0.5);
|
||||
player.hud_scorePopup.sort = 10000;
|
||||
player.hud_scorePopup maps\mp\gametypes\_hud::fontPulseInit( 3.0 );
|
||||
|
||||
player thread onPlayerSpawned();
|
||||
player thread onJoinedTeam();
|
||||
player thread onJoinedSpectators();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onJoinedTeam()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "joined_team" );
|
||||
self thread removeRankHUD();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onJoinedSpectators()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "joined_spectators" );
|
||||
self thread removeRankHUD();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("spawned_player");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
roundUp( floatVal )
|
||||
{
|
||||
if ( int( floatVal ) != floatVal )
|
||||
return int( floatVal+1 );
|
||||
else
|
||||
return int( floatVal );
|
||||
}
|
||||
|
||||
|
||||
giveRankXP( type, value )
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
lootType = "none";
|
||||
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
if ( level.teamBased && (!level.teamCount["allies"] || !level.teamCount["axis"]) )
|
||||
return;
|
||||
else if ( !level.teamBased && (level.teamCount["allies"] + level.teamCount["axis"] < 2) )
|
||||
return;
|
||||
|
||||
if ( !isDefined( value ) )
|
||||
value = getScoreInfoValue( type );
|
||||
|
||||
if ( !isDefined( self.xpGains[type] ) )
|
||||
self.xpGains[type] = 0;
|
||||
|
||||
momentumBonus = 0;
|
||||
gotRestXP = false;
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case "kill":
|
||||
case "headshot":
|
||||
case "shield_damage":
|
||||
value *= self.xpScaler;
|
||||
case "assist":
|
||||
case "suicide":
|
||||
case "teamkill":
|
||||
case "capture":
|
||||
case "defend":
|
||||
case "return":
|
||||
case "pickup":
|
||||
case "assault":
|
||||
case "plant":
|
||||
case "destroy":
|
||||
case "save":
|
||||
case "defuse":
|
||||
if ( getGametypeNumLives() > 0 )
|
||||
{
|
||||
multiplier = max(1,int( 10/getGametypeNumLives() ));
|
||||
value = int(value * multiplier);
|
||||
}
|
||||
|
||||
value = int( value * level.xpScale );
|
||||
|
||||
restXPAwarded = getRestXPAward( value );
|
||||
value += restXPAwarded;
|
||||
if ( restXPAwarded > 0 )
|
||||
{
|
||||
if ( isLastRestXPAward( value ) )
|
||||
thread maps\mp\gametypes\_hud_message::splashNotify( "rested_done" );
|
||||
|
||||
gotRestXP = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !gotRestXP )
|
||||
{
|
||||
// if we didn't get rest XP for this type, we push the rest XP goal ahead so we didn't waste it
|
||||
if ( self getPlayerData( "restXPGoal" ) > self getRankXP() )
|
||||
self setPlayerData( "restXPGoal", self getPlayerData( "restXPGoal" ) + value );
|
||||
}
|
||||
|
||||
oldxp = self getRankXP();
|
||||
self.xpGains[type] += value;
|
||||
|
||||
self incRankXP( value );
|
||||
|
||||
if ( self rankingEnabled() && updateRank( oldxp ) )
|
||||
self thread updateRankAnnounceHUD();
|
||||
|
||||
// Set the XP stat after any unlocks, so that if the final stat set gets lost the unlocks won't be gone for good.
|
||||
self syncXPStat();
|
||||
|
||||
if ( !level.hardcoreMode )
|
||||
{
|
||||
if ( type == "teamkill" )
|
||||
{
|
||||
self thread scorePopup( 0 - getScoreInfoValue( "kill" ), 0, (1,0,0), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
color = (1,1,0.5);
|
||||
if ( gotRestXP )
|
||||
color = (1,.65,0);
|
||||
self thread scorePopup( value, momentumBonus, color, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case "kill":
|
||||
case "headshot":
|
||||
case "suicide":
|
||||
case "teamkill":
|
||||
case "assist":
|
||||
case "capture":
|
||||
case "defend":
|
||||
case "return":
|
||||
case "pickup":
|
||||
case "assault":
|
||||
case "plant":
|
||||
case "defuse":
|
||||
self.pers["summary"]["score"] += value;
|
||||
self.pers["summary"]["xp"] += value;
|
||||
break;
|
||||
|
||||
case "win":
|
||||
case "loss":
|
||||
case "tie":
|
||||
self.pers["summary"]["match"] += value;
|
||||
self.pers["summary"]["xp"] += value;
|
||||
break;
|
||||
|
||||
case "challenge":
|
||||
self.pers["summary"]["challenge"] += value;
|
||||
self.pers["summary"]["xp"] += value;
|
||||
break;
|
||||
|
||||
default:
|
||||
self.pers["summary"]["misc"] += value; //keeps track of ungrouped match xp reward
|
||||
self.pers["summary"]["match"] += value;
|
||||
self.pers["summary"]["xp"] += value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
updateRank( oldxp )
|
||||
{
|
||||
newRankId = self getRank();
|
||||
if ( newRankId == self.pers["rank"] )
|
||||
return false;
|
||||
|
||||
oldRank = self.pers["rank"];
|
||||
rankId = self.pers["rank"];
|
||||
self.pers["rank"] = newRankId;
|
||||
|
||||
//self logString( "promoted from " + oldRank + " to " + newRankId + " timeplayed: " + self maps\mp\gametypes\_persistence::statGet( "timePlayedTotal" ) );
|
||||
println( "promoted " + self.name + " from rank " + oldRank + " to " + newRankId + ". Experience went from " + oldxp + " to " + self getRankXP() + "." );
|
||||
|
||||
self setRank( newRankId );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
updateRankAnnounceHUD()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
self notify("update_rank");
|
||||
self endon("update_rank");
|
||||
|
||||
team = self.pers["team"];
|
||||
if ( !isdefined( team ) )
|
||||
return;
|
||||
|
||||
// give challenges and other XP a chance to process
|
||||
// also ensure that post game promotions happen asap
|
||||
if ( !levelFlag( "game_over" ) )
|
||||
level waittill_notify_or_timeout( "game_over", 0.25 );
|
||||
|
||||
|
||||
newRankName = self getRankInfoFull( self.pers["rank"] );
|
||||
rank_char = level.rankTable[self.pers["rank"]][1];
|
||||
subRank = int(rank_char[rank_char.size-1]);
|
||||
|
||||
thread maps\mp\gametypes\_hud_message::promotionSplashNotify();
|
||||
|
||||
if ( subRank > 1 )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < level.players.size; i++ )
|
||||
{
|
||||
player = level.players[i];
|
||||
playerteam = player.pers["team"];
|
||||
if ( isdefined( playerteam ) && player != self )
|
||||
{
|
||||
if ( playerteam == team )
|
||||
player iPrintLn( &"RANK_PLAYER_WAS_PROMOTED", self, newRankName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
endGameUpdate()
|
||||
{
|
||||
player = self;
|
||||
}
|
||||
|
||||
|
||||
scorePopup( amount, bonus, hudColor, glowAlpha )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "joined_team" );
|
||||
self endon( "joined_spectators" );
|
||||
|
||||
if ( amount == 0 )
|
||||
return;
|
||||
|
||||
self notify( "scorePopup" );
|
||||
self endon( "scorePopup" );
|
||||
|
||||
self.xpUpdateTotal += amount;
|
||||
self.bonusUpdateTotal += bonus;
|
||||
|
||||
wait ( 0.05 );
|
||||
|
||||
if ( self.xpUpdateTotal < 0 )
|
||||
self.hud_scorePopup.label = &"";
|
||||
else
|
||||
self.hud_scorePopup.label = &"MP_PLUS";
|
||||
|
||||
self.hud_scorePopup.color = hudColor;
|
||||
self.hud_scorePopup.glowColor = hudColor;
|
||||
self.hud_scorePopup.glowAlpha = glowAlpha;
|
||||
|
||||
self.hud_scorePopup setValue(self.xpUpdateTotal);
|
||||
self.hud_scorePopup.alpha = 0.85;
|
||||
self.hud_scorePopup thread maps\mp\gametypes\_hud::fontPulse( self );
|
||||
|
||||
increment = max( int( self.bonusUpdateTotal / 20 ), 1 );
|
||||
|
||||
if ( self.bonusUpdateTotal )
|
||||
{
|
||||
while ( self.bonusUpdateTotal > 0 )
|
||||
{
|
||||
self.xpUpdateTotal += min( self.bonusUpdateTotal, increment );
|
||||
self.bonusUpdateTotal -= min( self.bonusUpdateTotal, increment );
|
||||
|
||||
self.hud_scorePopup setValue( self.xpUpdateTotal );
|
||||
|
||||
wait ( 0.05 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wait ( 1.0 );
|
||||
}
|
||||
|
||||
self.hud_scorePopup fadeOverTime( 0.75 );
|
||||
self.hud_scorePopup.alpha = 0;
|
||||
|
||||
self.xpUpdateTotal = 0;
|
||||
}
|
||||
|
||||
removeRankHUD()
|
||||
{
|
||||
self.hud_scorePopup.alpha = 0;
|
||||
}
|
||||
|
||||
getRank()
|
||||
{
|
||||
rankXp = self.pers["rankxp"];
|
||||
rankId = self.pers["rank"];
|
||||
|
||||
if ( rankXp < (getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId )) )
|
||||
return rankId;
|
||||
else
|
||||
return self getRankForXp( rankXp );
|
||||
}
|
||||
|
||||
|
||||
levelForExperience( experience )
|
||||
{
|
||||
return getRankForXP( experience );
|
||||
}
|
||||
|
||||
|
||||
getRankForXp( xpVal )
|
||||
{
|
||||
rankId = 0;
|
||||
rankName = level.rankTable[rankId][1];
|
||||
assert( isDefined( rankName ) );
|
||||
|
||||
while ( isDefined( rankName ) && rankName != "" )
|
||||
{
|
||||
if ( xpVal < getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId ) )
|
||||
return rankId;
|
||||
|
||||
rankId++;
|
||||
if ( isDefined( level.rankTable[rankId] ) )
|
||||
rankName = level.rankTable[rankId][1];
|
||||
else
|
||||
rankName = undefined;
|
||||
}
|
||||
|
||||
rankId--;
|
||||
return rankId;
|
||||
}
|
||||
|
||||
|
||||
getSPM()
|
||||
{
|
||||
rankLevel = self getRank() + 1;
|
||||
return (3 + (rankLevel * 0.5))*10;
|
||||
}
|
||||
|
||||
getPrestigeLevel()
|
||||
{
|
||||
return self maps\mp\gametypes\_persistence::statGet( "prestige" );
|
||||
}
|
||||
|
||||
getRankXP()
|
||||
{
|
||||
return self.pers["rankxp"];
|
||||
}
|
||||
|
||||
incRankXP( amount )
|
||||
{
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
if ( isDefined( self.isCheater ) )
|
||||
return;
|
||||
|
||||
xp = self getRankXP();
|
||||
newXp = (xp + amount);
|
||||
|
||||
if ( self.pers["rank"] == level.maxRank && newXp >= getRankInfoMaxXP( level.maxRank ) )
|
||||
newXp = getRankInfoMaxXP( level.maxRank );
|
||||
|
||||
self.pers["rankxp"] = newXp;
|
||||
}
|
||||
|
||||
getRestXPAward( baseXP )
|
||||
{
|
||||
if ( !getdvarint( "scr_restxp_enable" ) )
|
||||
return 0;
|
||||
|
||||
restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
|
||||
|
||||
wantGiveRestXP = int(baseXP * restXPAwardRate);
|
||||
mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
|
||||
|
||||
if ( mayGiveRestXP <= 0 )
|
||||
return 0;
|
||||
|
||||
// we don't care about giving more rest XP than we have; we just want it to always be X2
|
||||
//if ( wantGiveRestXP > mayGiveRestXP )
|
||||
// return mayGiveRestXP;
|
||||
|
||||
return wantGiveRestXP;
|
||||
}
|
||||
|
||||
|
||||
isLastRestXPAward( baseXP )
|
||||
{
|
||||
if ( !getdvarint( "scr_restxp_enable" ) )
|
||||
return false;
|
||||
|
||||
restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
|
||||
|
||||
wantGiveRestXP = int(baseXP * restXPAwardRate);
|
||||
mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
|
||||
|
||||
if ( mayGiveRestXP <= 0 )
|
||||
return false;
|
||||
|
||||
if ( wantGiveRestXP >= mayGiveRestXP )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
syncXPStat()
|
||||
{
|
||||
if ( level.xpScale > 4 || level.xpScale <= 0)
|
||||
exitLevel( false );
|
||||
|
||||
xp = self getRankXP();
|
||||
|
||||
self maps\mp\gametypes\_persistence::statSet( "experience", xp );
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
precacheShellShock( "frag_grenade_mp" );
|
||||
precacheShellShock( "damage_mp" );
|
||||
precacheRumble( "artillery_rumble" );
|
||||
precacheRumble( "grenade_rumble" );
|
||||
|
||||
precacheMenu( "dirt_effect_center" );
|
||||
precacheMenu( "dirt_effect_left" );
|
||||
precacheMenu( "dirt_effect_right" );
|
||||
}
|
||||
|
||||
shellshockOnDamage( cause, damage )
|
||||
{
|
||||
if ( self maps\mp\_flashgrenades::isFlashbanged() )
|
||||
return; // don't interrupt flashbang shellshock
|
||||
|
||||
if ( self _hasPerk( "specialty_blastshield" ) )
|
||||
return;
|
||||
|
||||
if ( cause == "MOD_EXPLOSIVE" ||
|
||||
cause == "MOD_GRENADE" ||
|
||||
cause == "MOD_GRENADE_SPLASH" ||
|
||||
cause == "MOD_PROJECTILE" ||
|
||||
cause == "MOD_PROJECTILE_SPLASH" )
|
||||
{
|
||||
time = 0;
|
||||
|
||||
if(damage >= 90)
|
||||
time = 4;
|
||||
else if(damage >= 50)
|
||||
time = 3;
|
||||
else if(damage >= 25)
|
||||
time = 2;
|
||||
else if(damage > 10)
|
||||
time = 2;
|
||||
|
||||
if ( time )
|
||||
{
|
||||
self shellshock("frag_grenade_mp", 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endOnDeath()
|
||||
{
|
||||
self waittill( "death" );
|
||||
waittillframeend;
|
||||
self notify ( "end_explode" );
|
||||
}
|
||||
|
||||
grenade_earthQuake()
|
||||
{
|
||||
self thread endOnDeath();
|
||||
self endon( "end_explode" );
|
||||
self waittill( "explode", position );
|
||||
PlayRumbleOnPosition( "grenade_rumble", position );
|
||||
earthquake( 0.5, 0.75, position, 800 );
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( player isUsingRemote() )
|
||||
continue;
|
||||
|
||||
if ( distance( position, player.origin ) > 600 )
|
||||
continue;
|
||||
|
||||
if ( player DamageConeTrace( position ) )
|
||||
player thread dirtEffect( position );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dirtEffect( position )
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
|
||||
forwardVec = vectorNormalize( anglesToForward( self.angles ) );
|
||||
rightVec = vectorNormalize( anglesToRight( self.angles ) );
|
||||
grenadeVec = vectorNormalize( position - self.origin );
|
||||
|
||||
fDot = vectorDot( grenadeVec, forwardVec );
|
||||
rDot = vectorDot( grenadeVec, rightVec );
|
||||
|
||||
printLn( fDot );
|
||||
printLn( rDot );
|
||||
|
||||
effectMenus = [];
|
||||
if ( fDot > 0 && fDot > 0.5 && self getCurrentWeapon() != "riotshield_mp" )
|
||||
effectMenus[effectMenus.size] = "dirt_effect_center";
|
||||
|
||||
if ( abs(fDot) < 0.866 )
|
||||
{
|
||||
if ( rDot > 0 )
|
||||
effectMenus[effectMenus.size] = "dirt_effect_right";
|
||||
else
|
||||
effectMenus[effectMenus.size] = "dirt_effect_left";
|
||||
}
|
||||
|
||||
foreach ( menu in effectMenus )
|
||||
self openMenu( menu );
|
||||
|
||||
if ( isAlive( self ) )
|
||||
self waittill_notify_or_timeout( "death", 2.0 );
|
||||
|
||||
foreach ( menu in effectMenus )
|
||||
self closeMenu( menu );
|
||||
}
|
||||
|
||||
c4_earthQuake()
|
||||
{
|
||||
self thread endOnDeath();
|
||||
self endon( "end_explode" );
|
||||
self waittill( "explode", position );
|
||||
PlayRumbleOnPosition( "grenade_rumble", position );
|
||||
earthquake( 0.4, 0.75, position, 512 );
|
||||
}
|
||||
|
||||
barrel_earthQuake()
|
||||
{
|
||||
PlayRumbleOnPosition( "grenade_rumble", self.origin );
|
||||
earthquake( 0.4, 0.5, self.origin, 512 );
|
||||
}
|
||||
|
||||
|
||||
artillery_earthQuake()
|
||||
{
|
||||
PlayRumbleOnPosition( "artillery_rumble", self.origin );
|
||||
earthquake( 0.7, 0.5, self.origin, 800 );
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,149 @@
|
||||
init()
|
||||
{
|
||||
level.spectateOverride["allies"] = spawnstruct();
|
||||
level.spectateOverride["axis"] = spawnstruct();
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player thread onJoinedTeam();
|
||||
player thread onJoinedSpectators();
|
||||
player thread onSpectatingClient();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onJoinedTeam()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "joined_team" );
|
||||
self setSpectatePermissions();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onJoinedSpectators()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "joined_spectators" );
|
||||
self setSpectatePermissions();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onSpectatingClient()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
self waittill( "spectating_cycle" );
|
||||
|
||||
// show the card for the player we're viewing. Could be undefined if the cyling failed
|
||||
spectatedPlayer = self GetSpectatingPlayer();
|
||||
if ( isDefined( spectatedPlayer ) )
|
||||
{
|
||||
self SetCardDisplaySlot( spectatedPlayer, 6 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateSpectateSettings()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
|
||||
for ( index = 0; index < level.players.size; index++ )
|
||||
level.players[index] setSpectatePermissions();
|
||||
}
|
||||
|
||||
|
||||
getOtherTeam( team )
|
||||
{
|
||||
if ( team == "axis" )
|
||||
return "allies";
|
||||
else if ( team == "allies" )
|
||||
return "axis";
|
||||
else
|
||||
return "none";
|
||||
}
|
||||
|
||||
|
||||
setSpectatePermissions()
|
||||
{
|
||||
team = self.sessionteam;
|
||||
|
||||
if ( level.gameEnded && gettime() - level.gameEndTime >= 2000 )
|
||||
{
|
||||
self allowSpectateTeam( "allies", false );
|
||||
self allowSpectateTeam( "axis", false );
|
||||
self allowSpectateTeam( "freelook", false );
|
||||
self allowSpectateTeam( "none", true );
|
||||
return;
|
||||
}
|
||||
|
||||
spectateType = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "spectatetype" );
|
||||
|
||||
switch( spectateType )
|
||||
{
|
||||
case 0: // disabled
|
||||
self allowSpectateTeam( "allies", false );
|
||||
self allowSpectateTeam( "axis", false );
|
||||
self allowSpectateTeam( "freelook", false );
|
||||
self allowSpectateTeam( "none", false );
|
||||
|
||||
break;
|
||||
case 1: // team/player only
|
||||
if ( !level.teamBased )
|
||||
{
|
||||
self allowSpectateTeam( "allies", true );
|
||||
self allowSpectateTeam( "axis", true );
|
||||
self allowSpectateTeam( "none", true );
|
||||
self allowSpectateTeam( "freelook", false );
|
||||
}
|
||||
else if ( isDefined( team ) && (team == "allies" || team == "axis") )
|
||||
{
|
||||
self allowSpectateTeam( team, true );
|
||||
self allowSpectateTeam( getOtherTeam( team ), false );
|
||||
self allowSpectateTeam( "freelook", false );
|
||||
self allowSpectateTeam( "none", false );
|
||||
}
|
||||
else
|
||||
{
|
||||
self allowSpectateTeam( "allies", false );
|
||||
self allowSpectateTeam( "axis", false );
|
||||
self allowSpectateTeam( "freelook", false );
|
||||
self allowSpectateTeam( "none", false );
|
||||
}
|
||||
break;
|
||||
case 2: // free
|
||||
self allowSpectateTeam( "allies", true );
|
||||
self allowSpectateTeam( "axis", true );
|
||||
self allowSpectateTeam( "freelook", true );
|
||||
self allowSpectateTeam( "none", true );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isDefined( team ) && (team == "axis" || team == "allies") )
|
||||
{
|
||||
if ( isdefined(level.spectateOverride[team].allowFreeSpectate) )
|
||||
self allowSpectateTeam( "freelook", true );
|
||||
|
||||
if (isdefined(level.spectateOverride[team].allowEnemySpectate))
|
||||
self allowSpectateTeam( getOtherTeam( team ), true );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,892 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
FACTION_REF_COL = 0;
|
||||
FACTION_NAME_COL = 1;
|
||||
FACTION_SHORT_NAME_COL = 2;
|
||||
FACTION_ELIMINATED_COL = 3;
|
||||
FACTION_FORFEITED_COL = 4;
|
||||
FACTION_ICON_COL = 5;
|
||||
FACTION_HUD_ICON_COL = 6;
|
||||
FACTION_VOICE_PREFIX_COL = 7;
|
||||
FACTION_SPAWN_MUSIC_COL = 8;
|
||||
FACTION_WIN_MUSIC_COL = 9;
|
||||
FACTION_FLAG_MODEL_COL = 10;
|
||||
FACTION_FLAG_CARRY_MODEL_COL = 11;
|
||||
FACTION_FLAG_ICON_COL = 12;
|
||||
FACTION_FLAG_FX_COL = 13;
|
||||
FACTION_COLOR_R_COL = 14;
|
||||
FACTION_COLOR_G_COL = 15;
|
||||
FACTION_COLOR_B_COL = 16;
|
||||
FACTION_HEAD_ICON_COL = 17;
|
||||
FACTION_CRATE_MODEL_COL = 18;
|
||||
|
||||
init()
|
||||
{
|
||||
initScoreBoard();
|
||||
|
||||
level.teamBalance = getDvarInt("scr_teambalance");
|
||||
level.maxClients = getDvarInt( "sv_maxclients" );
|
||||
|
||||
level._effect["thermal_beacon"] = loadFx("misc/thermal_beacon_inverted");
|
||||
effect = level._effect["thermal_beacon"];
|
||||
PrecacheFxTeamThermal( effect, "J_Spine4" );
|
||||
|
||||
setPlayerModels();
|
||||
|
||||
level.freeplayers = [];
|
||||
|
||||
if( level.teamBased )
|
||||
{
|
||||
level thread onPlayerConnect();
|
||||
level thread updateTeamBalance();
|
||||
|
||||
wait .15;
|
||||
level thread updatePlayerTimes();
|
||||
}
|
||||
else
|
||||
{
|
||||
level thread onFreePlayerConnect();
|
||||
|
||||
wait .15;
|
||||
level thread updateFreePlayerTimes();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
initScoreBoard()
|
||||
{
|
||||
setDvar("g_TeamName_Allies", getTeamShortName( "allies" ));
|
||||
setDvar("g_TeamIcon_Allies", getTeamIcon( "allies" ));
|
||||
setDvar("g_TeamIcon_MyAllies", getTeamIcon( "allies" ));
|
||||
setDvar("g_TeamIcon_EnemyAllies", getTeamIcon( "allies" ));
|
||||
scoreColor = getTeamColor( "allies" );
|
||||
setDvar("g_ScoresColor_Allies", scoreColor[0] + " " + scoreColor[1] + " " + scoreColor[2] );
|
||||
|
||||
setDvar("g_TeamName_Axis", getTeamShortName( "axis" ));
|
||||
setDvar("g_TeamIcon_Axis", getTeamIcon( "axis" ));
|
||||
setDvar("g_TeamIcon_MyAxis", getTeamIcon( "axis" ));
|
||||
setDvar("g_TeamIcon_EnemyAxis", getTeamIcon( "axis" ));
|
||||
scoreColor = getTeamColor( "axis" );
|
||||
setDvar("g_ScoresColor_Axis", scoreColor[0] + " " + scoreColor[1] + " " + scoreColor[2] );
|
||||
|
||||
setdvar("g_ScoresColor_Spectator", ".25 .25 .25");
|
||||
setdvar("g_ScoresColor_Free", ".76 .78 .10");
|
||||
setdvar("g_teamColor_MyTeam", ".6 .8 .6" );
|
||||
setdvar("g_teamColor_EnemyTeam", "1 .45 .5" );
|
||||
setdvar("g_teamTitleColor_MyTeam", ".6 .8 .6" );
|
||||
setdvar("g_teamTitleColor_EnemyTeam", "1 .45 .5" );
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player thread onJoinedTeam();
|
||||
player thread onJoinedSpectators();
|
||||
player thread onPlayerSpawned();
|
||||
|
||||
player thread trackPlayedTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onFreePlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player thread trackFreePlayedTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onJoinedTeam()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "joined_team" );
|
||||
//self logString( "joined team: " + self.pers["team"] );
|
||||
self updateTeamTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onJoinedSpectators()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill("joined_spectators");
|
||||
self.pers["teamTime"] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
trackPlayedTime()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self.timePlayed["allies"] = 0;
|
||||
self.timePlayed["axis"] = 0;
|
||||
self.timePlayed["free"] = 0;
|
||||
self.timePlayed["other"] = 0;
|
||||
self.timePlayed["total"] = 0;
|
||||
|
||||
gameFlagWait( "prematch_done" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( game["state"] == "playing" )
|
||||
{
|
||||
if ( self.sessionteam == "allies" )
|
||||
{
|
||||
self.timePlayed["allies"]++;
|
||||
self.timePlayed["total"]++;
|
||||
}
|
||||
else if ( self.sessionteam == "axis" )
|
||||
{
|
||||
self.timePlayed["axis"]++;
|
||||
self.timePlayed["total"]++;
|
||||
}
|
||||
else if ( self.sessionteam == "spectator" )
|
||||
{
|
||||
self.timePlayed["other"]++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
wait ( 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updatePlayerTimes()
|
||||
{
|
||||
if ( !level.rankedmatch )
|
||||
return;
|
||||
|
||||
level endon( "game_ended" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
foreach ( player in level.players )
|
||||
player updatePlayedTime();
|
||||
|
||||
wait( 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updatePlayedTime()
|
||||
{
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
if ( self.timePlayed["allies"] )
|
||||
{
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedAllies", self.timePlayed["allies"] );
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["allies"] );
|
||||
self maps\mp\gametypes\_persistence::statAddChildBuffered( "round", "timePlayed", self.timePlayed["allies"] );
|
||||
}
|
||||
|
||||
if ( self.timePlayed["axis"] )
|
||||
{
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOpfor", self.timePlayed["axis"] );
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["axis"] );
|
||||
self maps\mp\gametypes\_persistence::statAddChildBuffered( "round", "timePlayed", self.timePlayed["axis"] );
|
||||
}
|
||||
|
||||
if ( self.timePlayed["other"] )
|
||||
{
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOther", self.timePlayed["other"] );
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["other"] );
|
||||
self maps\mp\gametypes\_persistence::statAddChildBuffered( "round", "timePlayed", self.timePlayed["other"] );
|
||||
}
|
||||
|
||||
if ( game["state"] == "postgame" )
|
||||
return;
|
||||
|
||||
self.timePlayed["allies"] = 0;
|
||||
self.timePlayed["axis"] = 0;
|
||||
self.timePlayed["other"] = 0;
|
||||
}
|
||||
|
||||
|
||||
updateTeamTime()
|
||||
{
|
||||
if ( game["state"] != "playing" )
|
||||
return;
|
||||
|
||||
self.pers["teamTime"] = getTime();
|
||||
}
|
||||
|
||||
|
||||
updateTeamBalanceDvar()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
teambalance = getdvarInt("scr_teambalance");
|
||||
if(level.teambalance != teambalance)
|
||||
level.teambalance = getdvarInt("scr_teambalance");
|
||||
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateTeamBalance()
|
||||
{
|
||||
level.teamLimit = level.maxclients / 2;
|
||||
|
||||
level thread updateTeamBalanceDvar();
|
||||
|
||||
wait .15;
|
||||
|
||||
if ( level.teamBalance && isRoundBased() )
|
||||
{
|
||||
if( isDefined( game["BalanceTeamsNextRound"] ) )
|
||||
iPrintLnbold( &"MP_AUTOBALANCE_NEXT_ROUND" );
|
||||
|
||||
// TODO: add or change
|
||||
level waittill( "restarting" );
|
||||
|
||||
if( isDefined( game["BalanceTeamsNextRound"] ) )
|
||||
{
|
||||
level balanceTeams();
|
||||
game["BalanceTeamsNextRound"] = undefined;
|
||||
}
|
||||
else if( !getTeamBalance() )
|
||||
{
|
||||
game["BalanceTeamsNextRound"] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
for( ;; )
|
||||
{
|
||||
if( level.teamBalance )
|
||||
{
|
||||
if( !getTeamBalance() )
|
||||
{
|
||||
iPrintLnBold( &"MP_AUTOBALANCE_SECONDS", 15 );
|
||||
wait 15.0;
|
||||
|
||||
if( !getTeamBalance() )
|
||||
level balanceTeams();
|
||||
}
|
||||
|
||||
wait 59.0;
|
||||
}
|
||||
|
||||
wait 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
getTeamBalance()
|
||||
{
|
||||
level.team["allies"] = 0;
|
||||
level.team["axis"] = 0;
|
||||
|
||||
players = level.players;
|
||||
for(i = 0; i < players.size; i++)
|
||||
{
|
||||
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
|
||||
level.team["allies"]++;
|
||||
else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
|
||||
level.team["axis"]++;
|
||||
}
|
||||
|
||||
if((level.team["allies"] > (level.team["axis"] + level.teamBalance)) || (level.team["axis"] > (level.team["allies"] + level.teamBalance)))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
balanceTeams()
|
||||
{
|
||||
iPrintLnBold( game["strings"]["autobalance"] );
|
||||
//Create/Clear the team arrays
|
||||
AlliedPlayers = [];
|
||||
AxisPlayers = [];
|
||||
|
||||
// Populate the team arrays
|
||||
players = level.players;
|
||||
for(i = 0; i < players.size; i++)
|
||||
{
|
||||
if(!isdefined(players[i].pers["teamTime"]))
|
||||
continue;
|
||||
|
||||
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
|
||||
AlliedPlayers[AlliedPlayers.size] = players[i];
|
||||
else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
|
||||
AxisPlayers[AxisPlayers.size] = players[i];
|
||||
}
|
||||
|
||||
MostRecent = undefined;
|
||||
|
||||
while((AlliedPlayers.size > (AxisPlayers.size + 1)) || (AxisPlayers.size > (AlliedPlayers.size + 1)))
|
||||
{
|
||||
if(AlliedPlayers.size > (AxisPlayers.size + 1))
|
||||
{
|
||||
// Move the player that's been on the team the shortest ammount of time (highest teamTime value)
|
||||
for(j = 0; j < AlliedPlayers.size; j++)
|
||||
{
|
||||
if(isdefined(AlliedPlayers[j].dont_auto_balance))
|
||||
continue;
|
||||
|
||||
if(!isdefined(MostRecent))
|
||||
MostRecent = AlliedPlayers[j];
|
||||
else if(AlliedPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"])
|
||||
MostRecent = AlliedPlayers[j];
|
||||
}
|
||||
|
||||
MostRecent [[level.axis]]();
|
||||
}
|
||||
else if(AxisPlayers.size > (AlliedPlayers.size + 1))
|
||||
{
|
||||
// Move the player that's been on the team the shortest ammount of time (highest teamTime value)
|
||||
for(j = 0; j < AxisPlayers.size; j++)
|
||||
{
|
||||
if(isdefined(AxisPlayers[j].dont_auto_balance))
|
||||
continue;
|
||||
|
||||
if(!isdefined(MostRecent))
|
||||
MostRecent = AxisPlayers[j];
|
||||
else if(AxisPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"])
|
||||
MostRecent = AxisPlayers[j];
|
||||
}
|
||||
|
||||
MostRecent [[level.allies]]();
|
||||
}
|
||||
|
||||
MostRecent = undefined;
|
||||
AlliedPlayers = [];
|
||||
AxisPlayers = [];
|
||||
|
||||
players = level.players;
|
||||
for(i = 0; i < players.size; i++)
|
||||
{
|
||||
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
|
||||
AlliedPlayers[AlliedPlayers.size] = players[i];
|
||||
else if((isdefined(players[i].pers["team"])) &&(players[i].pers["team"] == "axis"))
|
||||
AxisPlayers[AxisPlayers.size] = players[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setGhillieModels( env )
|
||||
{
|
||||
level.environment = env;
|
||||
switch ( env )
|
||||
{
|
||||
case "desert":
|
||||
mptype\mptype_ally_ghillie_desert::precache();
|
||||
mptype\mptype_opforce_ghillie_desert::precache();
|
||||
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_desert::main;
|
||||
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_desert::main;
|
||||
break;
|
||||
case "arctic":
|
||||
mptype\mptype_ally_ghillie_arctic::precache();
|
||||
mptype\mptype_opforce_ghillie_arctic::precache();
|
||||
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_arctic::main;
|
||||
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_arctic::main;
|
||||
break;
|
||||
case "urban":
|
||||
mptype\mptype_ally_ghillie_urban::precache();
|
||||
mptype\mptype_opforce_ghillie_urban::precache();
|
||||
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_urban::main;
|
||||
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_urban::main;
|
||||
break;
|
||||
case "forest":
|
||||
mptype\mptype_ally_ghillie_forest::precache();
|
||||
mptype\mptype_opforce_ghillie_forest::precache();
|
||||
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_forest::main;
|
||||
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_forest::main;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setTeamModels( team, charSet )
|
||||
{
|
||||
switch ( charSet )
|
||||
{
|
||||
case "seals_udt":
|
||||
mptype\mptype_seal_udt_sniper::precache();
|
||||
mptype\mptype_seal_udt_lmg::precache();
|
||||
mptype\mptype_seal_udt_assault::precache();
|
||||
mptype\mptype_seal_udt_shotgun::precache();
|
||||
mptype\mptype_seal_udt_smg::precache();
|
||||
mptype\mptype_seal_udt_riot::precache();
|
||||
|
||||
game[team + "_model"]["SNIPER"] = mptype\mptype_seal_udt_sniper::main;
|
||||
game[team + "_model"]["LMG"] = mptype\mptype_seal_udt_lmg::main;
|
||||
game[team + "_model"]["ASSAULT"] = mptype\mptype_seal_udt_assault::main;
|
||||
game[team + "_model"]["SHOTGUN"] = mptype\mptype_seal_udt_shotgun::main;
|
||||
game[team + "_model"]["SMG"] = mptype\mptype_seal_udt_smg::main;
|
||||
game[team + "_model"]["RIOT"] = mptype\mptype_seal_udt_riot::main;
|
||||
|
||||
break;
|
||||
case "us_army":
|
||||
mptype\mptype_us_army_sniper::precache();
|
||||
mptype\mptype_us_army_lmg::precache();
|
||||
mptype\mptype_us_army_assault::precache();
|
||||
mptype\mptype_us_army_shotgun::precache();
|
||||
mptype\mptype_us_army_smg::precache();
|
||||
mptype\mptype_us_army_riot::precache();
|
||||
|
||||
game[team + "_model"]["SNIPER"] = mptype\mptype_us_army_sniper::main;
|
||||
game[team + "_model"]["LMG"] = mptype\mptype_us_army_lmg::main;
|
||||
game[team + "_model"]["ASSAULT"] = mptype\mptype_us_army_assault::main;
|
||||
game[team + "_model"]["SHOTGUN"] = mptype\mptype_us_army_shotgun::main;
|
||||
game[team + "_model"]["SMG"] = mptype\mptype_us_army_smg::main;
|
||||
game[team + "_model"]["RIOT"] = mptype\mptype_us_army_riot::main;
|
||||
|
||||
break;
|
||||
case "opforce_composite":
|
||||
mptype\mptype_opforce_comp_assault::precache();
|
||||
mptype\mptype_opforce_comp_lmg::precache();
|
||||
mptype\mptype_opforce_comp_shotgun::precache();
|
||||
mptype\mptype_opforce_comp_smg::precache();
|
||||
mptype\mptype_opforce_comp_sniper::precache();
|
||||
mptype\mptype_opforce_comp_riot::precache();
|
||||
|
||||
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_comp_sniper::main;
|
||||
game[team + "_model"]["LMG"] = mptype\mptype_opforce_comp_lmg::main;
|
||||
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_comp_assault::main;
|
||||
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_comp_shotgun::main;
|
||||
game[team + "_model"]["SMG"] = mptype\mptype_opforce_comp_smg::main;
|
||||
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_comp_riot::main;
|
||||
|
||||
break;
|
||||
case "opforce_arctic":
|
||||
mptype\mptype_opforce_arctic_assault::precache();
|
||||
mptype\mptype_opforce_arctic_lmg::precache();
|
||||
mptype\mptype_opforce_arctic_shotgun::precache();
|
||||
mptype\mptype_opforce_arctic_smg::precache();
|
||||
mptype\mptype_opforce_arctic_sniper::precache();
|
||||
mptype\mptype_opforce_arctic_riot::precache();
|
||||
|
||||
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_arctic_sniper::main;
|
||||
game[team + "_model"]["LMG"] = mptype\mptype_opforce_arctic_lmg::main;
|
||||
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_arctic_assault::main;
|
||||
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_arctic_shotgun::main;
|
||||
game[team + "_model"]["SMG"] = mptype\mptype_opforce_arctic_smg::main;
|
||||
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_arctic_riot::main;
|
||||
|
||||
break;
|
||||
case "opforce_airborne":
|
||||
mptype\mptype_opforce_airborne_assault::precache();
|
||||
mptype\mptype_opforce_airborne_lmg::precache();
|
||||
mptype\mptype_opforce_airborne_shotgun::precache();
|
||||
mptype\mptype_opforce_airborne_smg::precache();
|
||||
mptype\mptype_opforce_airborne_sniper::precache();
|
||||
mptype\mptype_opforce_airborne_riot::precache();
|
||||
|
||||
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_airborne_sniper::main;
|
||||
game[team + "_model"]["LMG"] = mptype\mptype_opforce_airborne_lmg::main;
|
||||
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_airborne_assault::main;
|
||||
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_airborne_shotgun::main;
|
||||
game[team + "_model"]["SMG"] = mptype\mptype_opforce_airborne_smg::main;
|
||||
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_airborne_riot::main;
|
||||
|
||||
break;
|
||||
case "militia":
|
||||
mptype\mptype_opforce_militia_assault::precache();
|
||||
mptype\mptype_opforce_militia_lmg::precache();
|
||||
mptype\mptype_opforce_militia_shotgun::precache();
|
||||
mptype\mptype_opforce_militia_smg::precache();
|
||||
mptype\mptype_opforce_militia_sniper::precache();
|
||||
mptype\mptype_opforce_militia_riot::precache();
|
||||
|
||||
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_militia_sniper::main;
|
||||
game[team + "_model"]["LMG"] = mptype\mptype_opforce_militia_lmg::main;
|
||||
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_militia_assault::main;
|
||||
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_militia_shotgun::main;
|
||||
game[team + "_model"]["SMG"] = mptype\mptype_opforce_militia_smg::main;
|
||||
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_militia_riot::main;
|
||||
|
||||
break;
|
||||
case "socom_141":
|
||||
mptype\mptype_socom_assault::precache();
|
||||
mptype\mptype_socom_lmg::precache();
|
||||
mptype\mptype_socom_shotgun::precache();
|
||||
mptype\mptype_socom_smg::precache();
|
||||
mptype\mptype_socom_sniper::precache();
|
||||
|
||||
game[team + "_model"]["SNIPER"] = mptype\mptype_socom_sniper::main;
|
||||
game[team + "_model"]["LMG"] = mptype\mptype_socom_lmg::main;
|
||||
game[team + "_model"]["ASSAULT"] = mptype\mptype_socom_assault::main;
|
||||
game[team + "_model"]["SHOTGUN"] = mptype\mptype_socom_shotgun::main;
|
||||
game[team + "_model"]["SMG"] = mptype\mptype_socom_smg::main;
|
||||
game[team + "_model"]["RIOT"] = mptype\mptype_socom_smg::main;
|
||||
|
||||
break;
|
||||
case "socom_141_desert":
|
||||
mptype\mptype_tf141_desert_assault::precache();
|
||||
mptype\mptype_tf141_desert_lmg::precache();
|
||||
mptype\mptype_tf141_desert_smg::precache();
|
||||
mptype\mptype_tf141_desert_shotgun::precache();
|
||||
mptype\mptype_tf141_desert_sniper::precache();
|
||||
mptype\mptype_tf141_desert_riot::precache();
|
||||
|
||||
game[team + "_model"]["SNIPER"] = mptype\mptype_tf141_desert_sniper::main;
|
||||
game[team + "_model"]["LMG"] = mptype\mptype_tf141_desert_lmg::main;
|
||||
game[team + "_model"]["ASSAULT"] = mptype\mptype_tf141_desert_assault::main;
|
||||
game[team + "_model"]["SHOTGUN"] = mptype\mptype_tf141_desert_shotgun::main;
|
||||
game[team + "_model"]["SMG"] = mptype\mptype_tf141_desert_smg::main;
|
||||
game[team + "_model"]["RIOT"] = mptype\mptype_tf141_desert_riot::main;
|
||||
|
||||
break;
|
||||
case "socom_141_forest":
|
||||
mptype\mptype_tf141_forest_assault::precache();
|
||||
mptype\mptype_tf141_forest_lmg::precache();
|
||||
mptype\mptype_tf141_forest_smg::precache();
|
||||
mptype\mptype_tf141_forest_shotgun::precache();
|
||||
mptype\mptype_tf141_forest_sniper::precache();
|
||||
mptype\mptype_tf141_forest_riot::precache();
|
||||
|
||||
game[team + "_model"]["SNIPER"] = mptype\mptype_tf141_forest_sniper::main;
|
||||
game[team + "_model"]["LMG"] = mptype\mptype_tf141_forest_lmg::main;
|
||||
game[team + "_model"]["ASSAULT"] = mptype\mptype_tf141_forest_assault::main;
|
||||
game[team + "_model"]["SHOTGUN"] = mptype\mptype_tf141_forest_shotgun::main;
|
||||
game[team + "_model"]["SMG"] = mptype\mptype_tf141_forest_smg::main;
|
||||
game[team + "_model"]["RIOT"] = mptype\mptype_tf141_forest_riot::main;
|
||||
|
||||
break;
|
||||
case "socom_141_arctic":
|
||||
mptype\mptype_tf141_arctic_assault::precache();
|
||||
mptype\mptype_tf141_arctic_lmg::precache();
|
||||
mptype\mptype_tf141_arctic_smg::precache();
|
||||
mptype\mptype_tf141_arctic_shotgun::precache();
|
||||
mptype\mptype_tf141_arctic_sniper::precache();
|
||||
mptype\mptype_tf141_arctic_riot::precache();
|
||||
|
||||
game[team + "_model"]["SNIPER"] = mptype\mptype_tf141_arctic_sniper::main;
|
||||
game[team + "_model"]["LMG"] = mptype\mptype_tf141_arctic_lmg::main;
|
||||
game[team + "_model"]["ASSAULT"] = mptype\mptype_tf141_arctic_assault::main;
|
||||
game[team + "_model"]["SHOTGUN"] = mptype\mptype_tf141_arctic_shotgun::main;
|
||||
game[team + "_model"]["SMG"] = mptype\mptype_tf141_arctic_smg::main;
|
||||
game[team + "_model"]["RIOT"] = mptype\mptype_tf141_arctic_riot::main;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setPlayerModels()
|
||||
{
|
||||
//mptype\mptype_us_army_riot::precache();
|
||||
//game["allies_model"]["riotshield"] = mptype\mptype_us_army_riot::main;
|
||||
//game["axis_model"]["riotshield"] = mptype\mptype_us_army_riot::main;
|
||||
|
||||
setTeamModels( "allies", game["allies"] );
|
||||
setTeamModels( "axis", game["axis"] );
|
||||
|
||||
setGhillieModels( getMapCustom( "environment" ) );
|
||||
}
|
||||
|
||||
|
||||
playerModelForWeapon( weapon, secondary )
|
||||
{
|
||||
team = self.team;
|
||||
|
||||
|
||||
if ( isDefined( game[team + "_model"][weapon] ) )
|
||||
{
|
||||
[[game[team+"_model"][weapon]]]();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
weaponClass = tablelookup( "mp/statstable.csv", 4, weapon, 2 );
|
||||
|
||||
switch ( weaponClass )
|
||||
{
|
||||
case "weapon_smg":
|
||||
[[game[team+"_model"]["SMG"]]]();
|
||||
break;
|
||||
case "weapon_assault":
|
||||
weaponClass = tablelookup( "mp/statstable.csv", 4, secondary, 2 );
|
||||
if ( weaponClass == "weapon_shotgun" )
|
||||
[[game[team+"_model"]["SHOTGUN"]]]();
|
||||
else
|
||||
[[game[team+"_model"]["ASSAULT"]]]();
|
||||
break;
|
||||
case "weapon_sniper":
|
||||
if ( level.environment != "" && self isItemUnlocked( "ghillie_" + level.environment ) )
|
||||
[[game[team+"_model"]["GHILLIE"]]]();
|
||||
else
|
||||
[[game[team+"_model"]["SNIPER"]]]();
|
||||
break;
|
||||
case "weapon_lmg":
|
||||
[[game[team+"_model"]["LMG"]]]();
|
||||
break;
|
||||
case "weapon_riot":
|
||||
[[game[team+"_model"]["RIOT"]]]();
|
||||
break;
|
||||
default:
|
||||
[[game[team+"_model"]["ASSAULT"]]]();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CountPlayers()
|
||||
{
|
||||
//chad
|
||||
players = level.players;
|
||||
allies = 0;
|
||||
axis = 0;
|
||||
for(i = 0; i < players.size; i++)
|
||||
{
|
||||
if ( players[i] == self )
|
||||
continue;
|
||||
|
||||
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
|
||||
allies++;
|
||||
else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
|
||||
axis++;
|
||||
}
|
||||
players["allies"] = allies;
|
||||
players["axis"] = axis;
|
||||
return players;
|
||||
}
|
||||
|
||||
|
||||
trackFreePlayedTime()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self.timePlayed["allies"] = 0;
|
||||
self.timePlayed["axis"] = 0;
|
||||
self.timePlayed["other"] = 0;
|
||||
self.timePlayed["total"] = 0;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( game["state"] == "playing" )
|
||||
{
|
||||
if ( isDefined( self.pers["team"] ) && self.pers["team"] == "allies" && self.sessionteam != "spectator" )
|
||||
{
|
||||
self.timePlayed["allies"]++;
|
||||
self.timePlayed["total"]++;
|
||||
}
|
||||
else if ( isDefined( self.pers["team"] ) && self.pers["team"] == "axis" && self.sessionteam != "spectator" )
|
||||
{
|
||||
self.timePlayed["axis"]++;
|
||||
self.timePlayed["total"]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.timePlayed["other"]++;
|
||||
}
|
||||
}
|
||||
|
||||
wait ( 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/#
|
||||
playerConnectedTest()
|
||||
{
|
||||
if ( getdvarint( "scr_runlevelandquit" ) == 1 )
|
||||
return;
|
||||
|
||||
level endon( "exitLevel_called" );
|
||||
|
||||
// every frame, do a getPlayerData on each player in level.players.
|
||||
// this will force a script error if a player in level.players isn't connected.
|
||||
for ( ;; )
|
||||
{
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
player getPlayerData( "experience" );
|
||||
}
|
||||
wait .05;
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
|
||||
updateFreePlayerTimes()
|
||||
{
|
||||
if ( !level.rankedmatch )
|
||||
return;
|
||||
|
||||
/#
|
||||
thread playerConnectedTest();
|
||||
#/
|
||||
|
||||
nextToUpdate = 0;
|
||||
for ( ;; )
|
||||
{
|
||||
nextToUpdate++;
|
||||
if ( nextToUpdate >= level.players.size )
|
||||
nextToUpdate = 0;
|
||||
|
||||
if ( isDefined( level.players[nextToUpdate] ) )
|
||||
level.players[nextToUpdate] updateFreePlayedTime();
|
||||
|
||||
wait ( 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateFreePlayedTime()
|
||||
{
|
||||
if ( !self rankingEnabled() )
|
||||
return;
|
||||
|
||||
if ( self.timePlayed["allies"] )
|
||||
{
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedAllies", self.timePlayed["allies"] );
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["allies"] );
|
||||
}
|
||||
|
||||
if ( self.timePlayed["axis"] )
|
||||
{
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOpfor", self.timePlayed["axis"] );
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["axis"] );
|
||||
}
|
||||
|
||||
if ( self.timePlayed["other"] )
|
||||
{
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOther", self.timePlayed["other"] );
|
||||
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["other"] );
|
||||
}
|
||||
|
||||
if ( game["state"] == "postgame" )
|
||||
return;
|
||||
|
||||
self.timePlayed["allies"] = 0;
|
||||
self.timePlayed["axis"] = 0;
|
||||
self.timePlayed["other"] = 0;
|
||||
}
|
||||
|
||||
|
||||
getJoinTeamPermissions( team )
|
||||
{
|
||||
teamcount = 0;
|
||||
|
||||
players = level.players;
|
||||
for(i = 0; i < players.size; i++)
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if((isdefined(player.pers["team"])) && (player.pers["team"] == team))
|
||||
teamcount++;
|
||||
}
|
||||
|
||||
if( teamCount < level.teamLimit )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill ( "spawned_player" );
|
||||
}
|
||||
}
|
||||
|
||||
getTeamName( teamRef )
|
||||
{
|
||||
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_NAME_COL ) );
|
||||
}
|
||||
|
||||
getTeamShortName( teamRef )
|
||||
{
|
||||
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_SHORT_NAME_COL ) );
|
||||
}
|
||||
|
||||
getTeamForfeitedString( teamRef )
|
||||
{
|
||||
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FORFEITED_COL ) );
|
||||
}
|
||||
|
||||
getTeamEliminatedString( teamRef )
|
||||
{
|
||||
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_ELIMINATED_COL ) );
|
||||
}
|
||||
|
||||
getTeamIcon( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_ICON_COL ) );
|
||||
}
|
||||
|
||||
getTeamHudIcon( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_HUD_ICON_COL ) );
|
||||
}
|
||||
|
||||
getTeamHeadIcon( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_HEAD_ICON_COL ) );
|
||||
}
|
||||
|
||||
getTeamVoicePrefix( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_VOICE_PREFIX_COL ) );
|
||||
}
|
||||
|
||||
getTeamSpawnMusic( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_SPAWN_MUSIC_COL ) );
|
||||
}
|
||||
|
||||
getTeamWinMusic( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_WIN_MUSIC_COL ) );
|
||||
}
|
||||
|
||||
getTeamFlagModel( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_MODEL_COL ) );
|
||||
}
|
||||
|
||||
getTeamFlagCarryModel( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_CARRY_MODEL_COL ) );
|
||||
}
|
||||
|
||||
getTeamFlagIcon( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_ICON_COL ) );
|
||||
}
|
||||
|
||||
getTeamFlagFX( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_FX_COL ) );
|
||||
}
|
||||
|
||||
getTeamColor( teamRef )
|
||||
{
|
||||
return ( (stringToFloat( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_COLOR_R_COL ) ),
|
||||
stringToFloat( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_COLOR_G_COL ) ),
|
||||
stringToFloat( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_COLOR_B_COL ) ))
|
||||
);
|
||||
}
|
||||
|
||||
getTeamCrateModel( teamRef )
|
||||
{
|
||||
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_CRATE_MODEL_COL ) );
|
||||
}
|
||||
@@ -0,0 +1,365 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
getTweakableDVarValue( category, name )
|
||||
{
|
||||
switch( category )
|
||||
{
|
||||
case "rule":
|
||||
dVar = level.rules[name].dVar;
|
||||
break;
|
||||
case "game":
|
||||
dVar = level.gameTweaks[name].dVar;
|
||||
break;
|
||||
case "team":
|
||||
dVar = level.teamTweaks[name].dVar;
|
||||
break;
|
||||
case "player":
|
||||
dVar = level.playerTweaks[name].dVar;
|
||||
break;
|
||||
case "class":
|
||||
dVar = level.classTweaks[name].dVar;
|
||||
break;
|
||||
case "weapon":
|
||||
dVar = level.weaponTweaks[name].dVar;
|
||||
break;
|
||||
case "hardpoint":
|
||||
dVar = level.hardpointTweaks[name].dVar;
|
||||
break;
|
||||
case "hud":
|
||||
dVar = level.hudTweaks[name].dVar;
|
||||
break;
|
||||
default:
|
||||
dVar = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
assert( isDefined( dVar ) );
|
||||
|
||||
value = getDvarInt( dVar );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
getTweakableDVar( category, name )
|
||||
{
|
||||
switch( category )
|
||||
{
|
||||
case "rule":
|
||||
value = level.rules[name].dVar;
|
||||
break;
|
||||
case "game":
|
||||
value = level.gameTweaks[name].dVar;
|
||||
break;
|
||||
case "team":
|
||||
value = level.teamTweaks[name].dVar;
|
||||
break;
|
||||
case "player":
|
||||
value = level.playerTweaks[name].dVar;
|
||||
break;
|
||||
case "class":
|
||||
value = level.classTweaks[name].dVar;
|
||||
break;
|
||||
case "weapon":
|
||||
value = level.weaponTweaks[name].dVar;
|
||||
break;
|
||||
case "hardpoint":
|
||||
value = level.hardpointTweaks[name].dVar;
|
||||
break;
|
||||
case "hud":
|
||||
value = level.hudTweaks[name].dVar;
|
||||
break;
|
||||
default:
|
||||
value = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
assert( isDefined( value ) );
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
getTweakableValue( category, name )
|
||||
{
|
||||
switch( category )
|
||||
{
|
||||
case "rule":
|
||||
value = level.rules[name].value;
|
||||
break;
|
||||
case "game":
|
||||
value = level.gameTweaks[name].value;
|
||||
break;
|
||||
case "team":
|
||||
value = level.teamTweaks[name].value;
|
||||
break;
|
||||
case "player":
|
||||
value = level.playerTweaks[name].value;
|
||||
break;
|
||||
case "class":
|
||||
value = level.classTweaks[name].value;
|
||||
break;
|
||||
case "weapon":
|
||||
value = level.weaponTweaks[name].value;
|
||||
break;
|
||||
case "hardpoint":
|
||||
value = level.hardpointTweaks[name].value;
|
||||
break;
|
||||
case "hud":
|
||||
value = level.hudTweaks[name].value;
|
||||
break;
|
||||
default:
|
||||
value = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
/#
|
||||
overrideDvar = "scr_" + level.gameType + "_" + category + "_" + name;
|
||||
return getDvarInt( overrideDvar, value );
|
||||
#/
|
||||
|
||||
assert( isDefined( value ) );
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
getTweakableLastValue( category, name )
|
||||
{
|
||||
switch( category )
|
||||
{
|
||||
case "rule":
|
||||
value = level.rules[name].lastValue;
|
||||
break;
|
||||
case "game":
|
||||
value = level.gameTweaks[name].lastValue;
|
||||
break;
|
||||
case "team":
|
||||
value = level.teamTweaks[name].lastValue;
|
||||
break;
|
||||
case "player":
|
||||
value = level.playerTweaks[name].lastValue;
|
||||
break;
|
||||
case "class":
|
||||
value = level.classTweaks[name].lastValue;
|
||||
break;
|
||||
case "weapon":
|
||||
value = level.weaponTweaks[name].lastValue;
|
||||
break;
|
||||
case "hardpoint":
|
||||
value = level.hardpointTweaks[name].lastValue;
|
||||
break;
|
||||
case "hud":
|
||||
value = level.hudTweaks[name].lastValue;
|
||||
break;
|
||||
default:
|
||||
value = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
assert( isDefined( value ) );
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
setTweakableValue( category, name, value )
|
||||
{
|
||||
switch( category )
|
||||
{
|
||||
case "rule":
|
||||
dVar = level.rules[name].dVar;
|
||||
break;
|
||||
case "game":
|
||||
dVar = level.gameTweaks[name].dVar;
|
||||
break;
|
||||
case "team":
|
||||
dVar = level.teamTweaks[name].dVar;
|
||||
break;
|
||||
case "player":
|
||||
dVar = level.playerTweaks[name].dVar;
|
||||
break;
|
||||
case "class":
|
||||
dVar = level.classTweaks[name].dVar;
|
||||
break;
|
||||
case "weapon":
|
||||
dVar = level.weaponTweaks[name].dVar;
|
||||
break;
|
||||
case "hardpoint":
|
||||
dVar = level.hardpointTweaks[name].dVar;
|
||||
break;
|
||||
case "hud":
|
||||
dVar = level.hudTweaks[name].dVar;
|
||||
break;
|
||||
default:
|
||||
dVar = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
setDvar( dVar, value );
|
||||
}
|
||||
|
||||
|
||||
setTweakableLastValue( category, name, value )
|
||||
{
|
||||
switch( category )
|
||||
{
|
||||
case "rule":
|
||||
level.rules[name].lastValue = value;
|
||||
break;
|
||||
case "game":
|
||||
level.gameTweaks[name].lastValue = value;
|
||||
break;
|
||||
case "team":
|
||||
level.teamTweaks[name].lastValue = value;
|
||||
break;
|
||||
case "player":
|
||||
level.playerTweaks[name].lastValue = value;
|
||||
break;
|
||||
case "class":
|
||||
level.classTweaks[name].lastValue = value;
|
||||
break;
|
||||
case "weapon":
|
||||
level.weaponTweaks[name].lastValue = value;
|
||||
break;
|
||||
case "hardpoint":
|
||||
level.hardpointTweaks[name].lastValue = value;
|
||||
break;
|
||||
case "hud":
|
||||
level.hudTweaks[name].lastValue = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
registerTweakable( category, name, dvar, value )
|
||||
{
|
||||
if ( isString( value ) )
|
||||
{
|
||||
value = getDvar( dvar, value );
|
||||
}
|
||||
else
|
||||
{
|
||||
value = getDvarInt( dvar, value );
|
||||
}
|
||||
|
||||
switch( category )
|
||||
{
|
||||
case "rule":
|
||||
if ( !isDefined( level.rules[name] ) )
|
||||
level.rules[name] = spawnStruct();
|
||||
level.rules[name].value = value;
|
||||
level.rules[name].lastValue = value;
|
||||
level.rules[name].dVar = dvar;
|
||||
break;
|
||||
case "game":
|
||||
if ( !isDefined( level.gameTweaks[name] ) )
|
||||
level.gameTweaks[name] = spawnStruct();
|
||||
level.gameTweaks[name].value = value;
|
||||
level.gameTweaks[name].lastValue = value;
|
||||
level.gameTweaks[name].dVar = dvar;
|
||||
break;
|
||||
case "team":
|
||||
if ( !isDefined( level.teamTweaks[name] ) )
|
||||
level.teamTweaks[name] = spawnStruct();
|
||||
level.teamTweaks[name].value = value;
|
||||
level.teamTweaks[name].lastValue = value;
|
||||
level.teamTweaks[name].dVar = dvar;
|
||||
break;
|
||||
case "player":
|
||||
if ( !isDefined( level.playerTweaks[name] ) )
|
||||
level.playerTweaks[name] = spawnStruct();
|
||||
level.playerTweaks[name].value = value;
|
||||
level.playerTweaks[name].lastValue = value;
|
||||
level.playerTweaks[name].dVar = dvar;
|
||||
break;
|
||||
case "class":
|
||||
if ( !isDefined( level.classTweaks[name] ) )
|
||||
level.classTweaks[name] = spawnStruct();
|
||||
level.classTweaks[name].value = value;
|
||||
level.classTweaks[name].lastValue = value;
|
||||
level.classTweaks[name].dVar = dvar;
|
||||
break;
|
||||
case "weapon":
|
||||
if ( !isDefined( level.weaponTweaks[name] ) )
|
||||
level.weaponTweaks[name] = spawnStruct();
|
||||
level.weaponTweaks[name].value = value;
|
||||
level.weaponTweaks[name].lastValue = value;
|
||||
level.weaponTweaks[name].dVar = dvar;
|
||||
break;
|
||||
case "hardpoint":
|
||||
if ( !isDefined( level.hardpointTweaks[name] ) )
|
||||
level.hardpointTweaks[name] = spawnStruct();
|
||||
level.hardpointTweaks[name].value = value;
|
||||
level.hardpointTweaks[name].lastValue = value;
|
||||
level.hardpointTweaks[name].dVar = dvar;
|
||||
break;
|
||||
case "hud":
|
||||
if ( !isDefined( level.hudTweaks[name] ) )
|
||||
level.hudTweaks[name] = spawnStruct();
|
||||
level.hudTweaks[name].value = value;
|
||||
level.hudTweaks[name].lastValue = value;
|
||||
level.hudTweaks[name].dVar = dvar;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
init()
|
||||
{
|
||||
level.clientTweakables = [];
|
||||
level.tweakablesInitialized = true;
|
||||
|
||||
level.rules = [];
|
||||
level.gameTweaks = [];
|
||||
level.teamTweaks = [];
|
||||
level.playerTweaks = [];
|
||||
level.classTweaks = [];
|
||||
level.weaponTweaks = [];
|
||||
level.hardpointTweaks = [];
|
||||
level.hudTweaks = [];
|
||||
// commented out tweaks have not yet been implemented
|
||||
|
||||
if ( level.console )
|
||||
{
|
||||
registerTweakable( "game", "graceperiod", "scr_game_graceperiod", 15 ); //*
|
||||
}
|
||||
else
|
||||
{
|
||||
registerTweakable( "game", "playerwaittime", "scr_game_playerwaittime", 15 ); //*
|
||||
registerTweakable( "game", "matchstarttime", "scr_game_matchstarttime", 5 ); //*
|
||||
}
|
||||
registerTweakable( "game", "onlyheadshots", "scr_game_onlyheadshots", 0 ); //*
|
||||
registerTweakable( "game", "allowkillcam", "scr_game_allowkillcam", 1 ); //*
|
||||
registerTweakable( "game", "spectatetype", "scr_game_spectatetype", 2 ); //*
|
||||
|
||||
registerTweakable( "game", "deathpointloss", "scr_game_deathpointloss", 0 ); //*
|
||||
registerTweakable( "game", "suicidepointloss", "scr_game_suicidepointloss", 0 ); //*
|
||||
registerTweakable( "team", "teamkillpointloss", "scr_team_teamkillpointloss", 0 ); //*
|
||||
|
||||
// registerTweakable( "team", "respawntime", "scr_team_respawntime", 0 );
|
||||
registerTweakable( "team", "fftype", "scr_team_fftype", 0 );
|
||||
registerTweakable( "team", "teamkillspawndelay", "scr_team_teamkillspawndelay", 0 );
|
||||
|
||||
// registerTweakable( "player", "respawndelay", "scr_player_respawndelay", 0 ); //*
|
||||
registerTweakable( "player", "maxhealth", "scr_player_maxhealth", 100 ); //*
|
||||
registerTweakable( "player", "healthregentime", "scr_player_healthregentime", 5 ); //*
|
||||
registerTweakable( "player", "forcerespawn", "scr_player_forcerespawn", 1 ); //*
|
||||
|
||||
registerTweakable( "weapon", "allowfrag", "scr_weapon_allowfrags", 1 );
|
||||
registerTweakable( "weapon", "allowsmoke", "scr_weapon_allowsmoke", 1 );
|
||||
registerTweakable( "weapon", "allowflash", "scr_weapon_allowflash", 1 );
|
||||
registerTweakable( "weapon", "allowc4", "scr_weapon_allowc4", 1 );
|
||||
registerTweakable( "weapon", "allowclaymores", "scr_weapon_allowclaymores", 1 );
|
||||
registerTweakable( "weapon", "allowrpgs", "scr_weapon_allowrpgs", 1 );
|
||||
registerTweakable( "weapon", "allowmines", "scr_weapon_allowmines", 1 );
|
||||
|
||||
registerTweakable( "hardpoint", "allowartillery", "scr_hardpoint_allowartillery", 1 );
|
||||
registerTweakable( "hardpoint", "allowuav", "scr_hardpoint_allowuav", 1 );
|
||||
registerTweakable( "hardpoint", "allowsupply", "scr_hardpoint_allowsupply", 1 );
|
||||
registerTweakable( "hardpoint", "allowhelicopter", "scr_hardpoint_allowhelicopter", 1 );
|
||||
|
||||
registerTweakable( "hud", "showobjicons", "ui_hud_showobjicons", 1 ); //*
|
||||
makeDVarServerInfo( "ui_hud_showobjicons", 1 );
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,532 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
/*
|
||||
Arena
|
||||
Objective: Eliminate the enemy team
|
||||
Map ends: When one team eliminates the enemy team, or the flag is reached
|
||||
Respawning: Beginning of next round
|
||||
|
||||
Level requirementss
|
||||
------------------
|
||||
Spawnpoints:
|
||||
classname mp_tdm_spawn
|
||||
All players spawn from these. The spawnpoint chosen is dependent on the current locations of teammates and enemies
|
||||
at the time of spawn. Players generally spawn behind their teammates relative to the direction of enemies.
|
||||
|
||||
Spectator Spawnpoints:
|
||||
classname mp_global_intermission
|
||||
Spectators spawn from these and intermission is viewed from these positions.
|
||||
Atleast one is required, any more and they are randomly chosen between.
|
||||
*/
|
||||
|
||||
/*QUAKED mp_tdm_spawn (0.0 0.0 1.0) (-16 -16 0) (16 16 72)
|
||||
Players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_tdm_spawn_axis_start (0.5 0.0 1.0) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
/*QUAKED mp_tdm_spawn_allies_start (0.0 0.5 1.0) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
main()
|
||||
{
|
||||
if(getdvar("mapname") == "mp_background")
|
||||
return;
|
||||
|
||||
maps\mp\gametypes\_globallogic::init();
|
||||
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
|
||||
maps\mp\gametypes\_globallogic::SetupCallbacks();
|
||||
|
||||
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
|
||||
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
|
||||
registerScoreLimitDvar( level.gameType, 500, 0, 5000 );
|
||||
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
|
||||
registerWinLimitDvar( level.gameType, 1, 0, 10 );
|
||||
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
|
||||
registerNumLivesDvar( level.gameType, 0, 0, 10 );
|
||||
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
|
||||
|
||||
level.teamBased = true;
|
||||
level.objectiveBased = true;
|
||||
|
||||
level.onPrecacheGameType = ::onPrecacheGameType;
|
||||
level.onStartGameType = ::onStartGameType;
|
||||
level.getSpawnPoint = ::getSpawnPoint;
|
||||
level.onSpawnPlayer = ::onSpawnPlayer;
|
||||
level.onNormalDeath = ::onNormalDeath;
|
||||
level.onPlayerKilled = ::onPlayerKilled;
|
||||
level.onDeadEvent = ::onDeadEvent;
|
||||
|
||||
game["dialog"]["gametype"] = "arena";
|
||||
|
||||
if ( getDvarInt( "g_hardcore" ) )
|
||||
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "camera_thirdPerson" ) )
|
||||
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "scr_diehard" ) )
|
||||
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
|
||||
|
||||
game["strings"]["overtime_hint"] = &"MP_FIRST_BLOOD";
|
||||
}
|
||||
|
||||
onPrecacheGameType()
|
||||
{
|
||||
precacheShader( "compass_waypoint_captureneutral" );
|
||||
precacheShader( "compass_waypoint_capture" );
|
||||
precacheShader( "compass_waypoint_defend" );
|
||||
|
||||
precacheShader( "waypoint_captureneutral" );
|
||||
precacheShader( "waypoint_capture" );
|
||||
precacheShader( "waypoint_defend" );
|
||||
|
||||
}
|
||||
|
||||
onStartGameType()
|
||||
{
|
||||
setClientNameMode("auto_change");
|
||||
|
||||
if ( !isdefined( game["switchedsides"] ) )
|
||||
game["switchedsides"] = false;
|
||||
|
||||
if ( game["switchedsides"] )
|
||||
{
|
||||
oldAttackers = game["attackers"];
|
||||
oldDefenders = game["defenders"];
|
||||
game["attackers"] = oldDefenders;
|
||||
game["defenders"] = oldAttackers;
|
||||
}
|
||||
|
||||
setObjectiveText( "allies", &"OBJECTIVES_ARENA" );
|
||||
setObjectiveText( "axis", &"OBJECTIVES_ARENA" );
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
setObjectiveScoreText( "allies", &"OBJECTIVES_ARENA" );
|
||||
setObjectiveScoreText( "axis", &"OBJECTIVES_ARENA" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveScoreText( "allies", &"OBJECTIVES_ARENA_SCORE" );
|
||||
setObjectiveScoreText( "axis", &"OBJECTIVES_ARENA_SCORE" );
|
||||
}
|
||||
setObjectiveHintText( "allies", &"OBJECTIVES_ARENA_HINT" );
|
||||
setObjectiveHintText( "axis", &"OBJECTIVES_ARENA_HINT" );
|
||||
|
||||
level.spawnMins = ( 0, 0, 0 );
|
||||
level.spawnMaxs = ( 0, 0, 0 );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
|
||||
|
||||
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
|
||||
setMapCenter( level.mapCenter );
|
||||
|
||||
allowed[0] = "dom";
|
||||
allowed[1] = "airdrop_pallet";
|
||||
allowed[2] = "arena";
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 200 );
|
||||
|
||||
maps\mp\gametypes\_gameobjects::main(allowed);
|
||||
|
||||
precacheFlag();
|
||||
thread arenaFlagWaiter();
|
||||
thread arenaTimeFlagWaiter();
|
||||
}
|
||||
|
||||
precacheFlag()
|
||||
{
|
||||
game["flagmodels"] = [];
|
||||
game["flagmodels"]["neutral"] = "prop_flag_neutral";
|
||||
|
||||
game["flagmodels"]["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
|
||||
game["flagmodels"]["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
|
||||
|
||||
precacheModel( game["flagmodels"]["neutral"] );
|
||||
precacheModel( game["flagmodels"]["allies"] );
|
||||
precacheModel( game["flagmodels"]["axis"] );
|
||||
|
||||
precacheString( &"MP_CAPTURING_FLAG" );
|
||||
precacheString( &"MP_LOSING_FLAG" );
|
||||
precacheString( &"MP_DOM_YOUR_FLAG_WAS_CAPTURED" );
|
||||
precacheString( &"MP_DOM_ENEMY_FLAG_CAPTURED" );
|
||||
precacheString( &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
|
||||
precacheString( &"MP_ENEMY_FLAG_CAPTURED_BY" );
|
||||
precacheString( &"MP_NEUTRAL_FLAG_CAPTURED_BY" );
|
||||
precacheString( &"MP_FRIENDLY_FLAG_CAPTURED_BY" );
|
||||
|
||||
}
|
||||
|
||||
arenaTimeFlagWaiter()
|
||||
{
|
||||
level endon( "down_to_one" );
|
||||
level endon( "game_end" );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
timeLeft = maps\mp\gametypes\_gamelogic::getTimeRemaining();
|
||||
|
||||
if ( timeLeft < 61000 )
|
||||
break;
|
||||
|
||||
wait ( 1 );
|
||||
}
|
||||
|
||||
level notify( "arena_flag_time" );
|
||||
thread arenaFlag();
|
||||
}
|
||||
|
||||
arenaFlagWaiter()
|
||||
{
|
||||
level endon( "game_end" );
|
||||
level endon( "arena_flag_time" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( level.inGracePeriod == 0 )
|
||||
break;
|
||||
|
||||
wait ( 0.05 );
|
||||
}
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( getTeamPlayersAlive ( "axis" ) == 1 )
|
||||
{
|
||||
thread arenaFlag();
|
||||
level notify( "down_to_one" );
|
||||
break;
|
||||
}
|
||||
if ( getTeamPlayersAlive ( "allies" ) == 1 )
|
||||
{
|
||||
thread arenaFlag();
|
||||
level notify( "down_to_one" );
|
||||
break;
|
||||
}
|
||||
wait( 1 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getSpawnPoint()
|
||||
{
|
||||
spawnteam = self.pers["team"];
|
||||
if ( game["switchedsides"] )
|
||||
spawnteam = getOtherTeam( spawnteam );
|
||||
|
||||
if ( level.inGracePeriod )
|
||||
{
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + spawnteam + "_start" );
|
||||
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
|
||||
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
|
||||
}
|
||||
|
||||
return spawnPoint;
|
||||
}
|
||||
|
||||
onSpawnPlayer()
|
||||
{
|
||||
self.usingObj = undefined;
|
||||
level notify ( "spawned_player" );
|
||||
}
|
||||
|
||||
onNormalDeath( victim, attacker, lifeId )
|
||||
{
|
||||
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
|
||||
assert( isDefined( score ) );
|
||||
|
||||
attacker maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( attacker.pers["team"], score );
|
||||
|
||||
team = victim.team;
|
||||
|
||||
if ( game["state"] == "postgame" )
|
||||
attacker.finalKill = true;
|
||||
}
|
||||
|
||||
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
|
||||
{
|
||||
thread checkAllowSpectating();
|
||||
}
|
||||
|
||||
onTimeLimit()
|
||||
{
|
||||
if ( game["status"] == "overtime" )
|
||||
{
|
||||
winner = "forfeit";
|
||||
}
|
||||
else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
|
||||
{
|
||||
winner = "overtime";
|
||||
}
|
||||
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
|
||||
{
|
||||
winner = "axis";
|
||||
}
|
||||
else
|
||||
{
|
||||
winner = "allies";
|
||||
}
|
||||
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( winner, game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
|
||||
checkAllowSpectating()
|
||||
{
|
||||
wait ( 0.05 );
|
||||
|
||||
update = false;
|
||||
if ( !level.aliveCount[ game["attackers"] ] )
|
||||
{
|
||||
level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
|
||||
update = true;
|
||||
}
|
||||
if ( !level.aliveCount[ game["defenders"] ] )
|
||||
{
|
||||
level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
|
||||
update = true;
|
||||
}
|
||||
if ( update )
|
||||
maps\mp\gametypes\_spectating::updateSpectateSettings();
|
||||
}
|
||||
|
||||
arenaFlag()
|
||||
{
|
||||
level.lastStatus["allies"] = 0;
|
||||
level.lastStatus["axis"] = 0;
|
||||
|
||||
arenaFlag = getEntArray("flag_arena", "targetname");
|
||||
primaryFlags = getEntArray( "flag_primary", "targetname" );
|
||||
secondaryFlags = getEntArray( "flag_secondary", "targetname" );
|
||||
|
||||
// check to see if arena flag is present otherwise throw a warning and use the dom Flag.
|
||||
if ( !isDefined( arenaFlag[0] ) )
|
||||
{
|
||||
println("WARNING: no arena flags specified attempting to use Dom flag_b" );
|
||||
|
||||
if ( (primaryFlags.size + secondaryFlags.size) < 1 )
|
||||
{
|
||||
printLn( "^1Not enough domination flags found in level!" );
|
||||
maps\mp\gametypes\_callbacksetup::AbortLevel();
|
||||
return;
|
||||
}
|
||||
|
||||
self setupDomFlag(primaryFlags, secondaryFlags);
|
||||
}
|
||||
else
|
||||
level.arenaFlag = arenaFlag[0];
|
||||
|
||||
trigger = level.arenaFlag;
|
||||
if ( isDefined( trigger.target ) )
|
||||
{
|
||||
visuals[0] = getEnt( trigger.target, "targetname" );
|
||||
}
|
||||
else
|
||||
{
|
||||
visuals[0] = spawn( "script_model", trigger.origin );
|
||||
visuals[0].angles = trigger.angles;
|
||||
}
|
||||
|
||||
visuals[0] setModel( game["flagmodels"]["neutral"] );
|
||||
|
||||
arenaFlag = maps\mp\gametypes\_gameobjects::createUseObject( "neutral", trigger, visuals, (0,0,100) );
|
||||
arenaFlag maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
|
||||
arenaFlag maps\mp\gametypes\_gameobjects::setUseTime( 20.0 );
|
||||
arenaFlag maps\mp\gametypes\_gameobjects::setUseText( &"MP_CAPTURING_FLAG" );
|
||||
label = arenaFlag maps\mp\gametypes\_gameobjects::getLabel();
|
||||
arenaFlag.label = label;
|
||||
arenaFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
|
||||
arenaFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend");
|
||||
arenaFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral");
|
||||
arenaFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral");
|
||||
arenaFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
arenaFlag.onUse = ::onUse;
|
||||
arenaFlag.onBeginUse = ::onBeginUse;
|
||||
arenaFlag.onUseUpdate = ::onUseUpdate;
|
||||
arenaFlag.onEndUse = ::onEndUse;
|
||||
arenaFlag.isArena = true;
|
||||
|
||||
//play sound to show flag is now available for capture
|
||||
iPrintLnBold( "Arena flag spawned" );
|
||||
|
||||
level.arenaFlag playSound( "flag_spawned" );
|
||||
|
||||
traceStart = visuals[0].origin + (0,0,32);
|
||||
traceEnd = visuals[0].origin + (0,0,-32);
|
||||
trace = bulletTrace( traceStart, traceEnd, false, undefined );
|
||||
|
||||
upangles = vectorToAngles( trace["normal"] );
|
||||
arenaFlag.baseeffectforward = anglesToForward( upangles );
|
||||
arenaFlag.baseeffectright = anglesToRight( upangles );
|
||||
arenaFlag.baseeffectpos = trace["position"];
|
||||
|
||||
arenaFlag.levelFlag = level.arenaFlag;
|
||||
|
||||
level.arenaFlag = arenaFlag;
|
||||
}
|
||||
|
||||
setupDomFlag( primaryFlags, secondaryFlags )
|
||||
{
|
||||
for ( index = 0; index < primaryFlags.size; index++ )
|
||||
{
|
||||
label = primaryFlags[index].script_label;
|
||||
|
||||
if ( label != "_b" )
|
||||
{
|
||||
primaryFlags[index] delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
level.arenaFlag = primaryFlags[index];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDeadEvent( team )
|
||||
{
|
||||
if ( team == game["attackers"] )
|
||||
{
|
||||
level thread arena_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
|
||||
}
|
||||
else if ( team == game["defenders"] )
|
||||
{
|
||||
level thread arena_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
|
||||
}
|
||||
}
|
||||
|
||||
arena_endGame( winningTeam, endReasonText )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
|
||||
}
|
||||
|
||||
giveFlagCaptureXP( touchList )
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
wait .05;
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
players = getArrayKeys( touchList );
|
||||
for ( index = 0; index < players.size; index++ )
|
||||
{
|
||||
player = touchList[players[index]].player;
|
||||
player thread [[level.onXPEvent]]( "capture" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
|
||||
}
|
||||
}
|
||||
|
||||
onUse( player )
|
||||
{
|
||||
team = player.pers["team"];
|
||||
oldTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
label = self maps\mp\gametypes\_gameobjects::getLabel();
|
||||
|
||||
//player logString( "flag captured: " + self.label );
|
||||
|
||||
self.captureTime = getTime();
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::setOwnerTeam( team );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_capture" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_capture" );
|
||||
self.visuals[0] setModel( game["flagmodels"][team] );
|
||||
|
||||
assert( team != "neutral" );
|
||||
|
||||
if ( oldTeam == "neutral" )
|
||||
{
|
||||
otherTeam = getOtherTeam( team );
|
||||
thread printAndSoundOnEveryone( team, otherTeam, &"MP_NEUTRAL_FLAG_CAPTURED_BY", &"MP_NEUTRAL_FLAG_CAPTURED_BY", "mp_war_objective_taken", undefined, player );
|
||||
|
||||
statusDialog( "captured_a", team );
|
||||
statusDialog( "enemy_has_a", otherTeam );
|
||||
}
|
||||
else
|
||||
thread printAndSoundOnEveryone( team, oldTeam, &"MP_ENEMY_FLAG_CAPTURED_BY", &"MP_FRIENDLY_FLAG_CAPTURED_BY", "mp_war_objective_taken", "mp_war_objective_lost", player );
|
||||
|
||||
thread giveFlagCaptureXP( self.touchList[team] );
|
||||
player notify( "objective", "captured" );
|
||||
|
||||
thread flagCaptured( team, &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
|
||||
}
|
||||
|
||||
onBeginUse( player )
|
||||
{
|
||||
ownerTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
self.didStatusNotify = false;
|
||||
|
||||
if ( ownerTeam == "neutral" )
|
||||
{
|
||||
otherTeam = getOtherTeam( player.pers["team"] );
|
||||
|
||||
statusDialog( "securing", player.pers["team"] );
|
||||
self.objPoints[player.pers["team"]] thread maps\mp\gametypes\_objpoints::startFlashing();
|
||||
|
||||
statusDialog( "enemy_taking", otherTeam );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ownerTeam == "allies" )
|
||||
otherTeam = "axis";
|
||||
else
|
||||
otherTeam = "allies";
|
||||
|
||||
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::startFlashing();
|
||||
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::startFlashing();
|
||||
}
|
||||
|
||||
onUseUpdate( team, progress, change )
|
||||
{
|
||||
if ( progress > 0.05 && change && !self.didStatusNotify )
|
||||
{
|
||||
otherTeam = getOtherTeam( team );
|
||||
|
||||
statusDialog( "losing_a", otherTeam );
|
||||
statusDialog( "securing_a", team );
|
||||
|
||||
self.didStatusNotify = true;
|
||||
}
|
||||
}
|
||||
|
||||
onEndUse( team, player, success )
|
||||
{
|
||||
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::stopFlashing();
|
||||
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::stopFlashing();
|
||||
}
|
||||
|
||||
statusDialog( dialog, team )
|
||||
{
|
||||
time = getTime();
|
||||
if ( getTime() < level.lastStatus[team] + 6000 )
|
||||
return;
|
||||
|
||||
thread delayedLeaderDialog( dialog, team );
|
||||
level.lastStatus[team] = getTime();
|
||||
}
|
||||
|
||||
delayedLeaderDialog( sound, team )
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
wait .1;
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
leaderDialog( sound, team );
|
||||
}
|
||||
|
||||
delayedLeaderDialogBothTeams( sound1, team1, sound2, team2 )
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
wait .1;
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
leaderDialogBothTeams( sound1, team1, sound2, team2 );
|
||||
}
|
||||
|
||||
flagCaptured( winningTeam, endReasonText )
|
||||
{
|
||||
maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
|
||||
}
|
||||
@@ -0,0 +1,761 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
/*
|
||||
One Flag CTF
|
||||
*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
main()
|
||||
{
|
||||
maps\mp\gametypes\_globallogic::init();
|
||||
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
|
||||
maps\mp\gametypes\_globallogic::SetupCallbacks();
|
||||
|
||||
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
|
||||
registerScoreLimitDvar( level.gameType, 1, 0, 10000 );
|
||||
registerRoundLimitDvar( level.gameType, 0, 0, 30 );
|
||||
registerWinLimitDvar( level.gameType, 4, 0, 10 );
|
||||
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
|
||||
registerNumLivesDvar( level.gameType, 0, 0, 10 );
|
||||
registerHalfTimeDvar( level.gameType, 1, 0, 1 );
|
||||
|
||||
setOverTimeLimitDvar( 4 );
|
||||
|
||||
level.teamBased = true;
|
||||
level.onPrecacheGameType = ::onPrecacheGameType;
|
||||
level.onStartGameType = ::onStartGameType;
|
||||
level.getSpawnPoint = ::getSpawnPoint;
|
||||
level.onPlayerKilled = ::onPlayerKilled;
|
||||
level.initGametypeAwards = ::initGametypeAwards;
|
||||
level.onTimeLimit = ::onTimeLimit;
|
||||
level.onSpawnPlayer = ::onSpawnPlayer;
|
||||
|
||||
level.flagReturnTime = getIntProperty( "scr_ctf_returntime", 30 );
|
||||
|
||||
game["dialog"]["gametype"] = "captureflag";
|
||||
|
||||
if ( getDvarInt( "g_hardcore" ) )
|
||||
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "camera_thirdPerson" ) )
|
||||
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "scr_diehard" ) )
|
||||
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
|
||||
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
|
||||
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
|
||||
|
||||
game["dialog"]["offense_obj"] = "capture_obj";
|
||||
game["dialog"]["defense_obj"] = "capture_obj";
|
||||
}
|
||||
|
||||
onPrecacheGameType()
|
||||
{
|
||||
precacheString(&"MP_FLAG_TAKEN_BY");
|
||||
precacheString(&"MP_ENEMY_FLAG_TAKEN_BY");
|
||||
precacheString(&"MP_FLAG_CAPTURED_BY");
|
||||
precacheString(&"MP_ENEMY_FLAG_CAPTURED_BY");
|
||||
precacheString(&"MP_FLAG_RETURNED");
|
||||
precacheString(&"MP_ENEMY_FLAG_RETURNED");
|
||||
precacheString(&"MP_YOUR_FLAG_RETURNING_IN");
|
||||
precacheString(&"MP_ENEMY_FLAG_RETURNING_IN");
|
||||
precacheString(&"MP_ENEMY_FLAG_DROPPED_BY");
|
||||
precacheString(&"MP_DOM_NEUTRAL_FLAG_CAPTURED");
|
||||
precacheString(&"MP_GRABBING_FLAG");
|
||||
precacheString(&"MP_RETURNING_FLAG");
|
||||
}
|
||||
|
||||
|
||||
onSpawnPlayer()
|
||||
{
|
||||
if( ( inOvertime() ) && !isDefined( self.otSpawned ) )
|
||||
self thread printOTHint();
|
||||
}
|
||||
|
||||
|
||||
printOTHint()
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
// give the "Overtime!" message time to show
|
||||
wait ( 0.25 );
|
||||
|
||||
self.otSpawned = true;
|
||||
hintMessage = getObjectiveHintText( self.team );
|
||||
self thread maps\mp\gametypes\_hud_message::hintMessage( hintMessage );
|
||||
}
|
||||
|
||||
|
||||
onStartGameType()
|
||||
{
|
||||
if ( !isdefined( game["switchedsides"] ) )
|
||||
game["switchedsides"] = false;
|
||||
|
||||
if ( !isdefined( game["original_defenders"] ) )
|
||||
game["original_defenders"] = game["defenders"];
|
||||
|
||||
if ( game["switchedsides"] )
|
||||
{
|
||||
oldAttackers = game["attackers"];
|
||||
oldDefenders = game["defenders"];
|
||||
game["attackers"] = oldDefenders;
|
||||
game["defenders"] = oldAttackers;
|
||||
}
|
||||
|
||||
setClientNameMode("auto_change");
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
if ( inOvertime() )
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GRAB_FLAG" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GRAB_FLAG" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( inOvertime() )
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GRAB_FLAG_SCORE" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GRAB_FLAG_SCORE" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_SCORE" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_SCORE" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( inOvertime() )
|
||||
{
|
||||
setObjectiveText( game["attackers"], &"OBJECTIVES_OVERTIME_CTF" );
|
||||
setObjectiveText( game["defenders"], &"OBJECTIVES_OVERTIME_CTF" );
|
||||
setObjectiveHintText( game["attackers"], &"OBJECTIVES_GRAB_FLAG_HINT" );
|
||||
setObjectiveHintText( game["defenders"], &"OBJECTIVES_GRAB_FLAG_HINT" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveText( game["attackers"], &"OBJECTIVES_CTF" );
|
||||
setObjectiveText( game["defenders"], &"OBJECTIVES_CTF" );
|
||||
setObjectiveHintText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_HINT" );
|
||||
setObjectiveHintText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_HINT" );
|
||||
}
|
||||
|
||||
level.spawnMins = ( 0, 0, 0 );
|
||||
level.spawnMaxs = ( 0, 0, 0 );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_allies_start" );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_axis_start" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_ctf_spawn_allies" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_ctf_spawn_axis" );
|
||||
|
||||
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
|
||||
setMapCenter( level.mapCenter );
|
||||
|
||||
thread maps\mp\gametypes\_dev::init();
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "pickup", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "return", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 250 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "kill_carrier", 50 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "defend", 100 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "defend_assist", 100 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assault", 200 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assault_assist", 40 );
|
||||
|
||||
allowed[0] = "ctf";
|
||||
maps\mp\gametypes\_gameobjects::main(allowed);
|
||||
|
||||
thread ctf();
|
||||
}
|
||||
|
||||
|
||||
getSpawnPoint()
|
||||
{
|
||||
if ( self.team == "axis" )
|
||||
{
|
||||
spawnTeam = game["attackers"];
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnTeam = game["defenders"];
|
||||
}
|
||||
|
||||
// if ( game["switchedsides"] )
|
||||
// spawnTeam = getOtherTeam( spawnteam );
|
||||
|
||||
if ( level.inGracePeriod )
|
||||
{
|
||||
spawnPoints = getentarray("mp_ctf_spawn_" + spawnteam + "_start", "classname");
|
||||
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
|
||||
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
|
||||
}
|
||||
|
||||
return spawnPoint;
|
||||
}
|
||||
|
||||
|
||||
ctf()
|
||||
{
|
||||
level.flagModel["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
|
||||
level.icon2D["allies"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "allies" );
|
||||
level.carryFlag["allies"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "allies" );
|
||||
|
||||
precacheModel( level.flagModel["allies"] );
|
||||
precacheModel( level.carryFlag["allies"] );
|
||||
|
||||
level.flagModel["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
|
||||
level.icon2D["axis"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "axis" );
|
||||
level.carryFlag["axis"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "axis" );
|
||||
|
||||
precacheModel( level.flagModel["axis"] );
|
||||
precacheModel( level.carryFlag["axis"] );
|
||||
|
||||
level.iconEscort3D = "waypoint_escort";
|
||||
level.iconEscort2D = "waypoint_escort";
|
||||
precacheShader( level.iconEscort3D );
|
||||
precacheShader( level.iconEscort2D );
|
||||
//level.iconEscort2D = level.iconEscort3D; // flags with words on compass
|
||||
|
||||
level.iconKill3D = "waypoint_kill";
|
||||
level.iconKill2D = "waypoint_kill";
|
||||
precacheShader( level.iconKill3D );
|
||||
precacheShader( level.iconKill2D );
|
||||
//level.iconKill2D = level.iconKill3D; // flags with words on compass
|
||||
|
||||
level.iconCaptureFlag3D = "waypoint_capture_flag";
|
||||
level.iconCaptureFlag2D = "waypoint_capture_flag";
|
||||
precacheShader( level.iconCaptureFlag3D );
|
||||
precacheShader( level.iconCaptureFlag2D );
|
||||
//level.iconCaptureFlag2D = level.iconCaptureFlag3D; // flags with words on compass
|
||||
|
||||
level.iconDefendFlag3D = "waypoint_defend_flag";
|
||||
level.iconDefendFlag2D = "waypoint_defend_flag";
|
||||
precacheShader( level.iconDefendFlag3D );
|
||||
precacheShader( level.iconDefendFlag2D );
|
||||
//level.iconDefendFlag2D = level.iconDefendFlag3D; // flags with words on compass
|
||||
|
||||
level.iconReturnFlag3D = "waypoint_return_flag";
|
||||
level.iconReturnFlag2D = "waypoint_return_flag";
|
||||
precacheShader( level.iconReturnFlag3D );
|
||||
precacheShader( level.iconReturnFlag2D );
|
||||
//level.iconReturnFlag2D = level.iconReturnFlag3D; // flags with words on compass
|
||||
|
||||
level.iconWaitForFlag3D = "waypoint_waitfor_flag";
|
||||
level.iconWaitForFlag2D = "waypoint_waitfor_flag";
|
||||
precacheShader( level.iconWaitForFlag3D );
|
||||
precacheShader( level.iconWaitForFlag2D );
|
||||
//level.iconWaitForFlag2D = level.iconWaitForFlag3D; // flags with words on compass
|
||||
|
||||
precacheShader( level.icon2D["axis"] );
|
||||
precacheShader( level.icon2D["allies"] );
|
||||
|
||||
precacheShader( "waypoint_flag_friendly" );
|
||||
precacheShader( "waypoint_flag_enemy" );
|
||||
|
||||
precacheString( &"OBJECTIVES_FLAG_HOME" );
|
||||
precacheString( &"OBJECTIVES_FLAG_NAME" );
|
||||
precacheString( &"OBJECTIVES_FLAG_AWAY" );
|
||||
|
||||
level.teamFlags[game["defenders"]] = createTeamFlag( game["defenders"], "allies" );
|
||||
level.teamFlags[game["attackers"]] = createTeamFlag( game["attackers"], level.otherTeam["allies"] );
|
||||
|
||||
level.capZones[game["defenders"]] = createCapZone( game["defenders"], "allies" );
|
||||
level.capZones[game["attackers"]] = createCapZone( game["attackers"], level.otherTeam["allies"] );
|
||||
|
||||
if ( level.splitScreen )
|
||||
hudElemAlpha = 0;
|
||||
else
|
||||
hudElemAlpha = 0.85;
|
||||
|
||||
level.friendlyFlagStatusIcon["allies"] = createServerIcon( "waypoint_flag_friendly", 32, 32, "allies" );
|
||||
level.friendlyFlagStatusIcon["allies"] setPoint( "TOP LEFT", "TOP LEFT", 132, 0 );
|
||||
level.friendlyFlagStatusIcon["allies"].alpha = hudElemAlpha;
|
||||
level.friendlyFlagStatusIcon["allies"].hideWhenInMenu = true;
|
||||
|
||||
level.friendlyFlagStatusText["allies"] = createServerFontString( "small", 1.6, "allies" );
|
||||
level.friendlyFlagStatusText["allies"] setParent( level.friendlyFlagStatusIcon["allies"] );
|
||||
level.friendlyFlagStatusText["allies"] setPoint( "LEFT", "RIGHT", 4 );
|
||||
level.friendlyFlagStatusText["allies"] setText( &"OBJECTIVES_FLAG_HOME" );
|
||||
level.friendlyFlagStatusText["allies"].alpha = hudElemAlpha;
|
||||
level.friendlyFlagStatusText["allies"].color = (1,1,1);
|
||||
level.friendlyFlagStatusText["allies"].glowAlpha = 1;
|
||||
level.friendlyFlagStatusText["allies"].hideWhenInMenu = true;
|
||||
|
||||
level.enemyFlagStatusIcon["allies"] = createServerIcon( "waypoint_flag_enemy", 24, 24, "allies" );
|
||||
level.enemyFlagStatusIcon["allies"] setPoint( "TOP LEFT", "TOP LEFT", 132, 26 );
|
||||
level.enemyFlagStatusIcon["allies"].alpha = hudElemAlpha;
|
||||
level.enemyFlagStatusIcon["allies"].hideWhenInMenu = true;
|
||||
|
||||
level.enemyFlagStatusText["allies"] = createServerFontString( "small", 1.6, "allies" );
|
||||
level.enemyFlagStatusText["allies"] setParent( level.enemyFlagStatusIcon["allies"] );
|
||||
level.enemyFlagStatusText["allies"] setPoint( "LEFT", "RIGHT", 4 );
|
||||
level.enemyFlagStatusText["allies"] setText( &"OBJECTIVES_FLAG_HOME" );
|
||||
level.enemyFlagStatusText["allies"].alpha = hudElemAlpha;
|
||||
level.enemyFlagStatusText["allies"].color = (1,1,1);
|
||||
level.enemyFlagStatusText["allies"].glowAlpha = 1;
|
||||
level.enemyFlagStatusText["allies"].hideWhenInMenu = true;
|
||||
|
||||
|
||||
level.friendlyFlagStatusIcon["axis"] = createServerIcon( "waypoint_flag_friendly", 32, 32, "axis" );
|
||||
level.friendlyFlagStatusIcon["axis"] setPoint( "TOP LEFT", "TOP LEFT", 132, 0 );
|
||||
level.friendlyFlagStatusIcon["axis"].alpha = hudElemAlpha;
|
||||
level.friendlyFlagStatusIcon["axis"].hideWhenInMenu = true;
|
||||
|
||||
level.friendlyFlagStatusText["axis"] = createServerFontString( "small", 1.6, "axis" );
|
||||
level.friendlyFlagStatusText["axis"] setParent( level.friendlyFlagStatusIcon["axis"] );
|
||||
level.friendlyFlagStatusText["axis"] setPoint( "LEFT", "RIGHT", 4 );
|
||||
level.friendlyFlagStatusText["axis"] setText( &"OBJECTIVES_FLAG_HOME" );
|
||||
level.friendlyFlagStatusText["axis"].alpha = hudElemAlpha;
|
||||
level.friendlyFlagStatusText["axis"].color = (1,1,1);
|
||||
level.friendlyFlagStatusText["axis"].glowAlpha = 1;
|
||||
level.friendlyFlagStatusText["axis"].hideWhenInMenu = true;
|
||||
|
||||
level.enemyFlagStatusIcon["axis"] = createServerIcon( "waypoint_flag_enemy", 24, 24, "axis" );
|
||||
level.enemyFlagStatusIcon["axis"] setPoint( "TOP LEFT", "TOP LEFT", 132, 26 );
|
||||
level.enemyFlagStatusIcon["axis"].alpha = hudElemAlpha;
|
||||
level.enemyFlagStatusIcon["axis"].hideWhenInMenu = true;
|
||||
|
||||
level.enemyFlagStatusText["axis"] = createServerFontString( "small", 1.6, "axis" );
|
||||
level.enemyFlagStatusText["axis"] setParent( level.enemyFlagStatusIcon["axis"] );
|
||||
level.enemyFlagStatusText["axis"] setPoint( "LEFT", "RIGHT", 4 );
|
||||
level.enemyFlagStatusText["axis"] setText( &"OBJECTIVES_FLAG_HOME" );
|
||||
level.enemyFlagStatusText["axis"].alpha = hudElemAlpha;
|
||||
level.enemyFlagStatusText["axis"].color = (1,1,1);
|
||||
level.enemyFlagStatusText["axis"].glowAlpha = 1;
|
||||
level.enemyFlagStatusText["axis"].hideWhenInMenu = true;
|
||||
}
|
||||
|
||||
//sets overtime and associated variables
|
||||
onTimeLimit()
|
||||
{
|
||||
if ( !inOvertime() && game["teamScores"]["allies"] == game["teamScores"]["axis"] && game["switchedsides"] )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "overtime", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
else if( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
else if( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
else if ( inOvertime() )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
}
|
||||
|
||||
spawnFxDelay( fxid, pos, forward, right, delay )
|
||||
{
|
||||
wait delay;
|
||||
effect = spawnFx( fxid, pos, forward, right );
|
||||
triggerFx( effect );
|
||||
}
|
||||
|
||||
createTeamFlag( team, entityTeam )
|
||||
{
|
||||
trigger = getEnt( "ctf_zone_" + entityTeam, "targetname" );
|
||||
if ( !isDefined( trigger ) )
|
||||
{
|
||||
error( "No ctf_zone_" + entityTeam + " trigger found in map." );
|
||||
return;
|
||||
}
|
||||
visuals[0] = getEnt( "ctf_flag_" + entityTeam, "targetname" );
|
||||
if ( !isDefined( visuals[0] ) )
|
||||
{
|
||||
error( "No ctf_flag_" + entityTeam + " script_model found in map." );
|
||||
return;
|
||||
}
|
||||
|
||||
cloneTrigger = spawn( "trigger_radius", trigger.origin, 0, 96, trigger.height );
|
||||
trigger = cloneTrigger;
|
||||
|
||||
visuals[0] setModel( level.flagModel[team] );
|
||||
|
||||
teamFlag = maps\mp\gametypes\_gameobjects::createCarryObject( team, trigger, visuals, (0,0,85) );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "friendly", 0.5 );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "enemy", 0.5 );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "enemy", &"MP_GRABBING_FLAG" );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "friendly", &"MP_RETURNING_FLAG" );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
|
||||
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill2D );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconEscort2D );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconEscort3D );
|
||||
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setCarryIcon( level.icon2D[team] );
|
||||
teamFlag.objIDPingFriendly = true;
|
||||
teamFlag.allowWeapons = true;
|
||||
teamFlag.onPickup = ::onPickup;
|
||||
teamFlag.onPickupFailed = ::onPickup;
|
||||
teamFlag.onDrop = ::onDrop;
|
||||
teamFlag.onReset = ::onReset;
|
||||
|
||||
teamFlag.oldRadius = trigger.radius;
|
||||
|
||||
traceStart = trigger.origin + (0,0,32);
|
||||
traceEnd = trigger.origin + (0,0,-32);
|
||||
trace = bulletTrace( traceStart, traceEnd, false, undefined );
|
||||
|
||||
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
|
||||
fxid = loadfx( fx );
|
||||
|
||||
upangles = vectorToAngles( trace["normal"] );
|
||||
forward = anglesToForward( upangles );
|
||||
right = anglesToRight( upangles );
|
||||
|
||||
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
|
||||
|
||||
return teamFlag;
|
||||
}
|
||||
|
||||
createCapZone( team, entityTeam )
|
||||
{
|
||||
trigger = getEnt( "ctf_zone_" + entityTeam, "targetname" );
|
||||
if ( !isDefined( trigger ) )
|
||||
{
|
||||
error("No ctf_zone_" + entityTeam + " trigger found in map.");
|
||||
return;
|
||||
}
|
||||
|
||||
visuals = [];
|
||||
capZone = maps\mp\gametypes\_gameobjects::createUseObject( team, trigger, visuals, (0,0,85) );
|
||||
capZone maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
|
||||
|
||||
capZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
capZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefendFlag2D );
|
||||
capZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefendFlag3D );
|
||||
capZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCaptureFlag2D );
|
||||
capZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCaptureFlag3D );
|
||||
|
||||
capZone maps\mp\gametypes\_gameobjects::setUseTime( 0 );
|
||||
capZone maps\mp\gametypes\_gameobjects::setKeyObject( level.teamFlags[ getOtherTeam( team ) ] );
|
||||
|
||||
capZone.onUse = ::onUse;
|
||||
capZone.onCantUse = ::onCantUse;
|
||||
|
||||
traceStart = trigger.origin + (0,0,32);
|
||||
traceEnd = trigger.origin + (0,0,-32);
|
||||
trace = bulletTrace( traceStart, traceEnd, false, undefined );
|
||||
|
||||
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
|
||||
fxid = loadfx( fx );
|
||||
|
||||
upangles = vectorToAngles( trace["normal"] );
|
||||
forward = anglesToForward( upangles );
|
||||
right = anglesToRight( upangles );
|
||||
|
||||
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
|
||||
|
||||
return capZone;
|
||||
}
|
||||
|
||||
|
||||
onBeginUse( player )
|
||||
{
|
||||
team = player.pers["team"];
|
||||
|
||||
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
|
||||
self.trigger.radius = 1024;
|
||||
else
|
||||
self.trigger.radius = self.oldRadius;
|
||||
}
|
||||
|
||||
|
||||
onEndUse( player, team, success )
|
||||
{
|
||||
self.trigger.radius = self.oldRadius;
|
||||
}
|
||||
|
||||
|
||||
onPickup( player )
|
||||
{
|
||||
self notify ( "picked_up" );
|
||||
|
||||
team = player.pers["team"];
|
||||
|
||||
if ( team == "allies" )
|
||||
otherTeam = "axis";
|
||||
else
|
||||
otherTeam = "allies";
|
||||
|
||||
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
|
||||
{
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagreturn", maps\mp\gametypes\_rank::getScoreInfoValue( "return" ) );
|
||||
player thread [[level.onXPEvent]]( "return" );
|
||||
self thread returnFlag();
|
||||
player incPlayerStat( "flagsreturned", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "return", player.origin );
|
||||
|
||||
printAndSoundOnEveryone( team, getOtherTeam( team ), &"MP_FLAG_RETURNED", &"MP_ENEMY_FLAG_RETURNED", "mp_obj_returned", "mp_obj_returned", "" );
|
||||
leaderDialog( "enemy_flag_returned", otherteam, "status" );
|
||||
leaderDialog( "flag_returned", team, "status" );
|
||||
|
||||
level.friendlyFlagStatusText[team] setText( &"OBJECTIVES_FLAG_HOME" );
|
||||
level.friendlyFlagStatusText[team].glowColor = (1,1,1);
|
||||
level.friendlyFlagStatusText[team].glowAlpha = 0;
|
||||
level.enemyFlagStatusText[otherTeam] setText( &"OBJECTIVES_FLAG_HOME" );
|
||||
level.enemyFlagStatusText[otherTeam].glowColor = (1,1,1);
|
||||
level.enemyFlagStatusText[otherTeam].glowAlpha = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( inOvertime() )
|
||||
{
|
||||
if ( isDefined( level.flagCaptured ) )
|
||||
{
|
||||
// denied splash!
|
||||
return;
|
||||
}
|
||||
|
||||
level thread teamPlayerCardSplash( "callout_grabbedtheflag", player );
|
||||
|
||||
level.teamFlags[team] maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
level.capZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
|
||||
level.flagCaptured = true;
|
||||
|
||||
//wait ( 1.5 );
|
||||
|
||||
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "winner", game["strings"]["grabbed_flag"] );
|
||||
}
|
||||
|
||||
player attachFlag();
|
||||
|
||||
level.friendlyFlagStatusText[otherTeam] setPlayerNameString( player );
|
||||
level.friendlyFlagStatusText[otherTeam].glowColor = (0.75,0.25,0.25);
|
||||
level.friendlyFlagStatusText[otherTeam].glowAlpha = 1;
|
||||
|
||||
level.enemyFlagStatusText[team] setPlayerNameString( player );
|
||||
level.enemyFlagStatusText[team].glowColor = (0.25,0.75,0.25);
|
||||
level.enemyFlagStatusText[team].glowAlpha = 1;
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill2D );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconEscort2D );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconEscort3D );
|
||||
|
||||
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
//level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
|
||||
//level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill3D );
|
||||
|
||||
if ( !level.teamFlags[ team ] maps\mp\gametypes\_gameobjects::isHome() )
|
||||
{
|
||||
level.capZones[ team ].trigger maps\mp\_entityheadIcons::setHeadIcon( player, level.iconWaitForFlag3D, (0,0,85) );
|
||||
|
||||
if ( isDefined( level.teamFlags[ team ].carrier ) )
|
||||
level.capZones[ otherTeam ].trigger maps\mp\_entityheadIcons::setHeadIcon( level.teamFlags[ team ].carrier, level.iconWaitForFlag3D, (0,0,85) );
|
||||
}
|
||||
|
||||
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_TAKEN_BY", &"MP_FLAG_TAKEN_BY", "mp_obj_taken", "mp_enemy_obj_taken", player );
|
||||
|
||||
leaderDialog( "enemy_flag_taken", team, "status" );
|
||||
leaderDialog( "flag_taken", otherteam, "status" );
|
||||
|
||||
thread teamPlayerCardSplash( "callout_flagpickup", player );
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagpickup", maps\mp\gametypes\_rank::getScoreInfoValue( "pickup" ) );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "pickup", player );
|
||||
player thread [[level.onXPEvent]]( "pickup" );
|
||||
player incPlayerStat( "flagscarried", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
returnFlag()
|
||||
{
|
||||
self maps\mp\gametypes\_gameobjects::returnHome();
|
||||
}
|
||||
|
||||
|
||||
onDrop( player )
|
||||
{
|
||||
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
otherTeam = level.otherTeam[team];
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::allowCarry( "any" );
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconReturnFlag2D );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconReturnFlag3D );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCaptureFlag2D );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCaptureFlag3D );
|
||||
|
||||
level.friendlyFlagStatusText[team] setText( &"OBJECTIVES_FLAG_AWAY" );
|
||||
level.friendlyFlagStatusText[team].glowColor = (1,1,1);
|
||||
level.friendlyFlagStatusText[team].glowAlpha = 0;
|
||||
level.enemyFlagStatusText[otherTeam] setText( &"OBJECTIVES_FLAG_AWAY" );
|
||||
level.enemyFlagStatusText[otherTeam].glowColor = (1,1,1);
|
||||
level.enemyFlagStatusText[otherTeam].glowAlpha = 0;
|
||||
|
||||
level.capZones[otherTeam].trigger maps\mp\_entityheadIcons::setHeadIcon( "none", "", (0,0,0) );
|
||||
|
||||
if ( isDefined( player ) )
|
||||
{
|
||||
if ( isDefined( player.carryFlag ) )
|
||||
player detachFlag();
|
||||
|
||||
printAndSoundOnEveryone( otherTeam, "none", &"MP_ENEMY_FLAG_DROPPED_BY", "", "mp_war_objective_lost", "", player );
|
||||
}
|
||||
else
|
||||
{
|
||||
playSoundOnPlayers( "mp_war_objective_lost", otherTeam );
|
||||
}
|
||||
|
||||
leaderDialog( "enemy_flag_dropped", otherTeam, "status" );
|
||||
leaderDialog( "flag_dropped", team, "status" );
|
||||
|
||||
self thread returnAfterTime();
|
||||
}
|
||||
|
||||
returnAfterTime()
|
||||
{
|
||||
self endon ( "picked_up" );
|
||||
|
||||
wait ( level.flagReturnTime );
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::returnHome();
|
||||
}
|
||||
|
||||
|
||||
onReset()
|
||||
{
|
||||
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
otherTeam = level.otherTeam[team];
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill2D );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconEscort2D );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconEscort3D );
|
||||
|
||||
level.friendlyFlagStatusText[team] setText( &"OBJECTIVES_FLAG_HOME" );
|
||||
level.friendlyFlagStatusText[team].glowColor = (1,1,1);
|
||||
level.friendlyFlagStatusText[team].glowAlpha = 0;
|
||||
|
||||
level.enemyFlagStatusText[otherTeam] setText( &"OBJECTIVES_FLAG_HOME" );
|
||||
level.enemyFlagStatusText[otherTeam].glowColor = (1,1,1);
|
||||
level.enemyFlagStatusText[otherTeam].glowAlpha = 0;
|
||||
|
||||
level.capZones[team] maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
|
||||
level.capZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
level.capZones[team] maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefendFlag2D );
|
||||
level.capZones[team] maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefendFlag3D );
|
||||
level.capZones[team] maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCaptureFlag2D );
|
||||
level.capZones[team] maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCaptureFlag3D );
|
||||
|
||||
level.capZones[team].trigger maps\mp\_entityheadIcons::setHeadIcon( "none", "", (0,0,0) );
|
||||
}
|
||||
|
||||
|
||||
onUse( player )
|
||||
{
|
||||
team = player.pers["team"];
|
||||
if ( team == "allies" )
|
||||
otherTeam = "axis";
|
||||
else
|
||||
otherTeam = "allies";
|
||||
|
||||
leaderDialog( "enemy_flag_captured", team, "status" );
|
||||
leaderDialog( "flag_captured", otherteam, "status" );
|
||||
|
||||
thread teamPlayerCardSplash( "callout_flagcapture", player );
|
||||
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flag_capture", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
|
||||
player thread [[level.onXPEvent]]( "capture" );
|
||||
player incPlayerStat( "flagscaptured", 1 );
|
||||
player notify( "objective", "captured" );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
|
||||
|
||||
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_CAPTURED_BY", &"MP_FLAG_CAPTURED_BY", "mp_obj_captured", "mp_enemy_obj_captured", player );
|
||||
|
||||
if ( isDefined( player.carryFlag ) )
|
||||
player detachFlag();
|
||||
|
||||
level.teamFlags[otherTeam] returnFlag();
|
||||
}
|
||||
|
||||
|
||||
onCantUse( player )
|
||||
{
|
||||
// player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
|
||||
}
|
||||
|
||||
|
||||
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId )
|
||||
{
|
||||
if ( isDefined( attacker ) && isPlayer( attacker ) && attacker.pers["team"] != self.pers["team"] )
|
||||
{
|
||||
if ( isDefined( attacker.carryFlag ) )
|
||||
attacker incPlayerStat( "killsasflagcarrier", 1 );
|
||||
|
||||
if ( isDefined( self.carryFlag ) )
|
||||
{
|
||||
attacker thread [[level.onXPEvent]]( "kill_carrier" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "kill_carrier", attacker );
|
||||
attacker incPlayerStat( "flagcarrierkills", 1 );
|
||||
|
||||
thread maps\mp\_matchdata::logKillEvent( killId, "carrying" );
|
||||
|
||||
self detachFlag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
attachFlag()
|
||||
{
|
||||
otherTeam = level.otherTeam[self.pers["team"]];
|
||||
|
||||
self attach( level.carryFlag[otherTeam], "J_spine4", true );
|
||||
self.carryFlag = level.carryFlag[otherTeam];
|
||||
}
|
||||
|
||||
detachFlag()
|
||||
{
|
||||
self detach( self.carryFlag, "J_spine4" );
|
||||
self.carryFlag = undefined;
|
||||
}
|
||||
|
||||
initGametypeAwards()
|
||||
{
|
||||
maps\mp\_awards::initStatAward( "flagscaptured", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "flagsreturned", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "flagcarrierkills", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "flagscarried", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "killsasflagcarrier", 0, maps\mp\_awards::highestWins );
|
||||
}
|
||||
@@ -0,0 +1,870 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
|
||||
/*
|
||||
Action SAB/SD = DD
|
||||
Attackers objective: Bomb both of 2 positions
|
||||
Defenders objective: Defend these 2 positions / Defuse planted bombs
|
||||
Round ends: When one team defends for duration of match, both sites are destroyed.
|
||||
Map ends: When one team reaches the score limit, or time limit or round limit is reached
|
||||
Respawning: Players respawn indefinetly and immediately
|
||||
|
||||
Level requirements
|
||||
------------------
|
||||
Allied Spawnpoints:
|
||||
classname mp_sd_spawn_attacker
|
||||
Allied players spawn from these. Place at least 16 of these relatively close together.
|
||||
|
||||
Axis Spawnpoints:
|
||||
classname mp_sd_spawn_defender
|
||||
Axis players spawn from these. Place at least 16 of these relatively close together.
|
||||
|
||||
Spectator Spawnpoints:
|
||||
classname mp_global_intermission
|
||||
Spectators spawn from these and intermission is viewed from these positions.
|
||||
Atleast one is required, any more and they are randomly chosen between.
|
||||
|
||||
Bombzones:
|
||||
classname trigger_multiple
|
||||
targetname bombzone
|
||||
script_gameobjectname bombzone
|
||||
script_bombmode_original <if defined this bombzone will be used in the original bomb mode>
|
||||
script_bombmode_single <if defined this bombzone will be used in the single bomb mode>
|
||||
script_bombmode_dual <if defined this bombzone will be used in the dual bomb mode>
|
||||
script_team Set to allies or axis. This is used to set which team a bombzone is used by in dual bomb mode.
|
||||
script_label Set to A or B. This sets the letter shown on the compass in original mode.
|
||||
This is a volume of space in which the bomb can planted. Must contain an origin brush.
|
||||
|
||||
Bomb:
|
||||
classname trigger_lookat
|
||||
targetname bombtrigger
|
||||
script_gameobjectname bombzone
|
||||
This should be a 16x16 unit trigger with an origin brush placed so that it's center lies on the bottom plane of the trigger.
|
||||
Must be in the level somewhere. This is the trigger that is used when defusing a bomb.
|
||||
It gets moved to the position of the planted bomb model.
|
||||
|
||||
Level script requirements
|
||||
-------------------------
|
||||
Team Definitions:
|
||||
game["attackers"] = "allies";
|
||||
game["defenders"] = "axis";
|
||||
This sets which team is attacking and which team is defending. Attackers plant the bombs. Defenders protect the targets.
|
||||
|
||||
Exploder Effects:
|
||||
Setting script_noteworthy on a bombzone trigger to an exploder group can be used to trigger additional effects.
|
||||
|
||||
multiple bombs
|
||||
multiple targets
|
||||
spawning
|
||||
round handling when both sites are destroyed
|
||||
|
||||
*/
|
||||
|
||||
/*QUAKED mp_dd_spawn_attacker_a (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn near bomb a.*/
|
||||
|
||||
/*QUAKED mp_dd_spawn_attacker_b (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn near bomb b.*/
|
||||
|
||||
/*QUAKED mp_dd_spawn_attacker (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_dd_spawn_defender (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_dd_spawn_defender_a (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn near bomb site a.*/
|
||||
|
||||
/*QUAKED mp_dd_spawn_defender_b (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn near bomb site b.*/
|
||||
|
||||
/*QUAKED mp_dd_spawn_attacker_start (0.0 1.0 0.0) (-16 -16 0) (16 16 72)
|
||||
Attacking players spawn randomly at one of these positions at the beginning of a round.*/
|
||||
|
||||
/*QUAKED mp_dd_spawn_defender_start (1.0 0.0 0.0) (-16 -16 0) (16 16 72)
|
||||
Defending players spawn randomly at one of these positions at the beginning of a round.*/
|
||||
|
||||
main()
|
||||
{
|
||||
if(getdvar("mapname") == "mp_background")
|
||||
return;
|
||||
|
||||
maps\mp\gametypes\_globallogic::init();
|
||||
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
|
||||
maps\mp\gametypes\_globallogic::SetupCallbacks();
|
||||
|
||||
registerRoundSwitchDvar( level.gameType, 1, 0, 9 );
|
||||
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
|
||||
registerScoreLimitDvar( level.gameType, 0, 0, 500 );
|
||||
registerRoundLimitDvar( level.gameType, 3, 0, 12 );
|
||||
registerWinLimitDvar( level.gameType, 2, 0, 12 );
|
||||
registerNumLivesDvar( level.gameType, 0, 0, 10 );
|
||||
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
|
||||
|
||||
level.objectiveBased = true;
|
||||
level.teamBased = true;
|
||||
level.onPrecacheGameType = ::onPrecacheGameType;
|
||||
level.onStartGameType = ::onStartGameType;
|
||||
level.getSpawnPoint = ::getSpawnPoint;
|
||||
level.onSpawnPlayer = ::onSpawnPlayer;
|
||||
level.onDeadEvent = ::onDeadEvent;
|
||||
level.onTimeLimit = ::onTimeLimit;
|
||||
level.onNormalDeath = ::onNormalDeath;
|
||||
level.initGametypeAwards = ::initGametypeAwards;
|
||||
level.dd = true;
|
||||
level.bombsPlanted = 0;
|
||||
level.ddBombModel = []
|
||||
|
||||
setBombTimerDvar();
|
||||
|
||||
makeDvarServerInfo( "ui_bombtimer_a", -1 );
|
||||
makeDvarServerInfo( "ui_bombtimer_b", -1 );
|
||||
|
||||
game["dialog"]["gametype"] = "demolition";
|
||||
|
||||
if ( getDvarInt( "g_hardcore" ) )
|
||||
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "camera_thirdPerson" ) )
|
||||
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "scr_diehard" ) )
|
||||
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
|
||||
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
|
||||
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
|
||||
|
||||
game["dialog"]["offense_obj"] = "obj_destroy";
|
||||
game["dialog"]["defense_obj"] = "obj_defend";
|
||||
}
|
||||
|
||||
|
||||
onPrecacheGameType()
|
||||
{
|
||||
game["bomb_dropped_sound"] = "mp_war_objective_lost";
|
||||
game["bomb_recovered_sound"] = "mp_war_objective_taken";
|
||||
|
||||
precacheShader("waypoint_bomb");
|
||||
precacheShader("hud_suitcase_bomb");
|
||||
precacheShader("waypoint_target");
|
||||
precacheShader("waypoint_target_a");
|
||||
precacheShader("waypoint_target_b");
|
||||
precacheShader("waypoint_defend");
|
||||
precacheShader("waypoint_defend_a");
|
||||
precacheShader("waypoint_defend_b");
|
||||
precacheShader("waypoint_defuse_a");
|
||||
precacheShader("waypoint_defuse_b");
|
||||
precacheShader("waypoint_target");
|
||||
precacheShader("waypoint_target_a");
|
||||
precacheShader("waypoint_target_b");
|
||||
precacheShader("waypoint_defend");
|
||||
precacheShader("waypoint_defend_a");
|
||||
precacheShader("waypoint_defend_b");
|
||||
precacheShader("waypoint_defuse");
|
||||
precacheShader("waypoint_defuse_a");
|
||||
precacheShader("waypoint_defuse_b");
|
||||
|
||||
precacheString( &"MP_EXPLOSIVES_RECOVERED_BY" );
|
||||
precacheString( &"MP_EXPLOSIVES_DROPPED_BY" );
|
||||
precacheString( &"MP_EXPLOSIVES_PLANTED_BY" );
|
||||
precacheString( &"MP_EXPLOSIVES_DEFUSED_BY" );
|
||||
precacheString( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
|
||||
precacheString( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
|
||||
precacheString( &"MP_CANT_PLANT_WITHOUT_BOMB" );
|
||||
precacheString( &"MP_PLANTING_EXPLOSIVE" );
|
||||
precacheString( &"MP_DEFUSING_EXPLOSIVE" );
|
||||
precacheString( &"MP_BOMB_A_TIMER" );
|
||||
precacheString( &"MP_BOMB_B_TIMER" );
|
||||
precacheString( &"MP_BOMBSITE_IN_USE" );
|
||||
}
|
||||
|
||||
onStartGameType()
|
||||
{
|
||||
if ( !isDefined( game["switchedsides"] ) )
|
||||
game["switchedsides"] = false;
|
||||
|
||||
if ( game["switchedsides"] )
|
||||
{
|
||||
oldAttackers = game["attackers"];
|
||||
oldDefenders = game["defenders"];
|
||||
game["attackers"] = oldDefenders;
|
||||
game["defenders"] = oldAttackers;
|
||||
}
|
||||
|
||||
level.useStartSpawns = true;
|
||||
|
||||
setClientNameMode( "manual_change" );
|
||||
|
||||
game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
|
||||
game["strings"]["bomb_defused"] = &"MP_BOMB_DEFUSED";
|
||||
|
||||
precacheString( game["strings"]["target_destroyed"] );
|
||||
precacheString( game["strings"]["bomb_defused"] );
|
||||
|
||||
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
|
||||
|
||||
setObjectiveText( game["attackers"], &"OBJECTIVES_DD_ATTACKER" );
|
||||
setObjectiveText( game["defenders"], &"OBJECTIVES_DD_DEFENDER" );
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_DD_ATTACKER" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_DD_DEFENDER" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_DD_ATTACKER_SCORE" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_DD_DEFENDER_SCORE" );
|
||||
}
|
||||
setObjectiveHintText( game["attackers"], &"OBJECTIVES_DD_ATTACKER_HINT" );
|
||||
setObjectiveHintText( game["defenders"], &"OBJECTIVES_DD_DEFENDER_HINT" );
|
||||
|
||||
level.spawnMins = ( 0, 0, 0 );
|
||||
level.spawnMaxs = ( 0, 0, 0 );
|
||||
|
||||
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender_a", true );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender_b", true );
|
||||
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dd_spawn_defender_start" );
|
||||
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker_a", true );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker_b", true );
|
||||
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dd_spawn_attacker_start" );
|
||||
|
||||
level.spawn_defenders = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender" );
|
||||
level.spawn_defenders_a = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_a" );
|
||||
level.spawn_defenders_a = array_combine( level.spawn_defenders, level.spawn_defenders_a );
|
||||
level.spawn_defenders_b = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_b" );
|
||||
level.spawn_defenders_b = array_combine( level.spawn_defenders, level.spawn_defenders_b );
|
||||
|
||||
level.spawn_attackers = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker" );
|
||||
level.spawn_attackers_a = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_a" );
|
||||
level.spawn_attackers_a = array_combine( level.spawn_attackers, level.spawn_attackers_a );
|
||||
level.spawn_attackers_b = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_b" );
|
||||
level.spawn_attackers_b = array_combine( level.spawn_attackers, level.spawn_attackers_b );
|
||||
|
||||
level.spawn_defenders_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_start" );
|
||||
level.spawn_attackers_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_start" );
|
||||
|
||||
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
|
||||
level.aPlanted = false;
|
||||
level.bPlanted = false;
|
||||
|
||||
setMapCenter( level.mapCenter );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "win", 2 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "loss", 1 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "tie", 1.5 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "plant", 100 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 100 );
|
||||
|
||||
thread updateGametypeDvars();
|
||||
thread waitToProcess();
|
||||
|
||||
winlimit = getWatchedDvar("winlimit");
|
||||
|
||||
allowed[0] = "dd";
|
||||
allowed[1] = "bombzone";
|
||||
allowed[2] = "blocker";
|
||||
maps\mp\gametypes\_gameobjects::main(allowed);
|
||||
|
||||
thread bombs();
|
||||
}
|
||||
|
||||
waitToProcess()
|
||||
{
|
||||
level endon( "game_end" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( level.inGracePeriod == 0 )
|
||||
break;
|
||||
|
||||
wait ( 0.05 );
|
||||
}
|
||||
|
||||
level.useStartSpawns = false;
|
||||
|
||||
}
|
||||
|
||||
getSpawnPoint()
|
||||
{
|
||||
spawnteam = self.pers["team"];
|
||||
|
||||
if ( level.useStartSpawns )
|
||||
{
|
||||
if ( spawnteam == game["attackers"] )
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_attackers_start);
|
||||
else
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_defenders_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spawnteam == game["attackers"] )
|
||||
{
|
||||
if ( (!level.aPlanted && !level.bPlanted) )
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
|
||||
else if ( level.aPlanted && !level.bPlanted )
|
||||
spawnPoints = level.spawn_attackers_a;
|
||||
else if ( level.bPlanted && !level.aPlanted )
|
||||
spawnPoints = level.spawn_attackers_b;
|
||||
else
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
|
||||
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (!level.aPlanted && !level.bPlanted) )
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
|
||||
else if ( level.aPlanted && !level.bPlanted )
|
||||
spawnPoints = level.spawn_defenders_a;
|
||||
else if ( level.bPlanted && !level.aPlanted )
|
||||
spawnPoints = level.spawn_defenders_b;
|
||||
else
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
|
||||
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
|
||||
}
|
||||
}
|
||||
|
||||
assert( isDefined(spawnpoint) );
|
||||
|
||||
return spawnpoint;
|
||||
}
|
||||
|
||||
onSpawnPlayer()
|
||||
{
|
||||
|
||||
if ( self.pers["team"] == game["attackers"] )
|
||||
{
|
||||
self.isPlanting = false;
|
||||
self.isDefusing = false;
|
||||
self.isBombCarrier = true;
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
self.carryIcon = createIcon( "hud_suitcase_bomb", 33, 33 );
|
||||
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", 0, -78 );
|
||||
self.carryIcon.alpha = 0.75;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.carryIcon = createIcon( "hud_suitcase_bomb", 50, 50 );
|
||||
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -90, -65 );
|
||||
self.carryIcon.alpha = 0.75;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.isPlanting = false;
|
||||
self.isDefusing = false;
|
||||
self.isBombCarrier = false;
|
||||
|
||||
if ( isDefined( self.carryIcon ) )
|
||||
{
|
||||
self.carryIcon Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
level notify ( "spawned_player" );
|
||||
}
|
||||
|
||||
|
||||
dd_endGame( winningTeam, endReasonText )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
|
||||
}
|
||||
|
||||
|
||||
onDeadEvent( team )
|
||||
{
|
||||
if ( level.bombExploded || level.bombDefused )
|
||||
return;
|
||||
|
||||
if ( team == "all" )
|
||||
{
|
||||
if ( level.bombPlanted )
|
||||
dd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
|
||||
else
|
||||
dd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
|
||||
}
|
||||
else if ( team == game["attackers"] )
|
||||
{
|
||||
if ( level.bombPlanted )
|
||||
return;
|
||||
|
||||
level thread dd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
|
||||
}
|
||||
else if ( team == game["defenders"] )
|
||||
{
|
||||
level thread dd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onNormalDeath( victim, attacker, lifeId )
|
||||
{
|
||||
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
|
||||
assert( isDefined( score ) );
|
||||
|
||||
team = victim.team;
|
||||
|
||||
if ( game["state"] == "postgame" && (victim.team == game["defenders"] || !level.bombPlanted) )
|
||||
attacker.finalKill = true;
|
||||
|
||||
if ( victim.isPlanting )
|
||||
{
|
||||
thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
|
||||
}
|
||||
else if ( victim.isDefusing )
|
||||
{
|
||||
thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onTimeLimit()
|
||||
{
|
||||
dd_endGame( game["defenders"], game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
|
||||
|
||||
updateGametypeDvars()
|
||||
{
|
||||
level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
|
||||
level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
|
||||
level.bombTimer = dvarIntValue( "bombtimer", 45, 1, 300 );
|
||||
level.ddTimeToAdd = dvarFloatValue( "addtime", 2, 0, 5 );; //how much time is added to the match when a target is destroyed
|
||||
}
|
||||
|
||||
|
||||
bombs()
|
||||
{
|
||||
level.bombPlanted = false;
|
||||
level.bombDefused = false;
|
||||
level.bombExploded = 0;
|
||||
|
||||
level.bombZones = [];
|
||||
|
||||
bombZones = getEntArray( "bombzone", "targetname" );
|
||||
|
||||
for ( index = 0; index < bombZones.size; index++ )
|
||||
{
|
||||
trigger = bombZones[index];
|
||||
visuals = getEntArray( bombZones[index].target, "targetname" );
|
||||
|
||||
bombZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,64) );
|
||||
bombZone maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
|
||||
bombZone maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
|
||||
bombZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
|
||||
bombZone maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
|
||||
bombZone maps\mp\gametypes\_gameobjects::setKeyObject( level.ddBomb );
|
||||
|
||||
label = bombZone maps\mp\gametypes\_gameobjects::getLabel();
|
||||
bombZone.label = label;
|
||||
bombZone.index = index;
|
||||
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
|
||||
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
|
||||
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + label );
|
||||
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + label );
|
||||
bombZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
bombZone.onBeginUse = ::onBeginUse;
|
||||
bombZone.onEndUse = ::onEndUse;
|
||||
bombZone.onUse = ::onUseObject;
|
||||
bombZone.onCantUse = ::onCantUse;
|
||||
bombZone.useWeapon = "briefcase_bomb_mp";
|
||||
bombZone.visuals[0].killCamEnt = spawn( "script_model", bombZone.visuals[0].origin + (0,0,128) );
|
||||
|
||||
for ( i = 0; i < visuals.size; i++ )
|
||||
{
|
||||
if ( isDefined( visuals[i].script_exploder ) )
|
||||
{
|
||||
bombZone.exploderIndex = visuals[i].script_exploder;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
level.bombZones[level.bombZones.size] = bombZone;
|
||||
|
||||
bombZone.bombDefuseTrig = getent( visuals[0].target, "targetname" );
|
||||
assert( isdefined( bombZone.bombDefuseTrig ) );
|
||||
bombZone.bombDefuseTrig.origin += (0,0,-10000);
|
||||
bombZone.bombDefuseTrig.label = label;
|
||||
}
|
||||
|
||||
for ( index = 0; index < level.bombZones.size; index++ )
|
||||
{
|
||||
array = [];
|
||||
for ( otherindex = 0; otherindex < level.bombZones.size; otherindex++ )
|
||||
{
|
||||
if ( otherindex != index )
|
||||
array[ array.size ] = level.bombZones[otherindex];
|
||||
}
|
||||
level.bombZones[index].otherBombZones = array;
|
||||
}
|
||||
}
|
||||
|
||||
onUseObject( player )
|
||||
{
|
||||
team = player.pers["team"];
|
||||
otherTeam = level.otherTeam[team];
|
||||
|
||||
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
|
||||
{
|
||||
player notify ( "bomb_planted" );
|
||||
player playSound( "mp_bomb_plant" );
|
||||
|
||||
thread teamPlayerCardSplash( "callout_bombplanted", player );
|
||||
//iPrintLn( &"MP_EXPLOSIVES_PLANTED_BY", player );
|
||||
leaderDialog( "bomb_planted" );
|
||||
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
|
||||
player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
|
||||
player incPlayerStat( "bombsplanted", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
|
||||
player.bombPlantedTime = getTime();
|
||||
|
||||
level thread bombPlanted( self, player );
|
||||
|
||||
level.bombOwner = player;
|
||||
self.useWeapon = "briefcase_bomb_defuse_mp";
|
||||
self setUpForDefusing();
|
||||
}
|
||||
else // defused the bomb
|
||||
{
|
||||
self thread bombHandler( player, "defused" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resetBombZone()
|
||||
{
|
||||
self maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
|
||||
self maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
|
||||
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
|
||||
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
|
||||
self maps\mp\gametypes\_gameobjects::setKeyObject( level.ddBomb );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + self.label );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + self.label );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + self.label );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + self.label );
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
self.useWeapon = "briefcase_bomb_mp";
|
||||
}
|
||||
|
||||
setUpForDefusing()
|
||||
{
|
||||
self maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
|
||||
self maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
|
||||
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
|
||||
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
|
||||
self maps\mp\gametypes\_gameobjects::setKeyObject( undefined );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" + self.label );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" + self.label );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" + self.label );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" + self.label );
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
}
|
||||
|
||||
onBeginUse( player )
|
||||
{
|
||||
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
|
||||
{
|
||||
player playSound( "mp_bomb_defuse" );
|
||||
player.isDefusing = true;
|
||||
|
||||
bestDistance = 9000000;
|
||||
closestBomb = undefined;
|
||||
|
||||
if ( isDefined( level.ddBombModel ) )
|
||||
{
|
||||
foreach ( bomb in level.ddBombModel )
|
||||
{
|
||||
if ( !isDefined( bomb ) )
|
||||
continue;
|
||||
|
||||
dist = distanceSquared( player.origin, bomb.origin );
|
||||
|
||||
if ( dist < bestDistance )
|
||||
{
|
||||
bestDistance = dist;
|
||||
closestBomb = bomb;
|
||||
}
|
||||
}
|
||||
|
||||
assert( isDefined(closestBomb) );
|
||||
player.defusing = closestBomb;
|
||||
closestBomb hide();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.isPlanting = true;
|
||||
}
|
||||
}
|
||||
|
||||
onEndUse( team, player, result )
|
||||
{
|
||||
if ( !isDefined( player ) )
|
||||
return;
|
||||
|
||||
if ( isAlive( player ) )
|
||||
{
|
||||
player.isDefusing = false;
|
||||
player.isPlanting = false;
|
||||
}
|
||||
|
||||
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
|
||||
{
|
||||
if ( isDefined( player.defusing ) && !result )
|
||||
{
|
||||
player.defusing show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onCantUse( player )
|
||||
{
|
||||
player iPrintLnBold( &"MP_BOMBSITE_IN_USE" );
|
||||
}
|
||||
|
||||
onReset()
|
||||
{
|
||||
}
|
||||
|
||||
bombPlanted( destroyedObj, player )
|
||||
{
|
||||
destroyedObj endon( "defused" );
|
||||
|
||||
level.bombsPlanted += 1;
|
||||
self setBombTimerDvar();
|
||||
maps\mp\gametypes\_gamelogic::pauseTimer();
|
||||
level.timePauseStart = getTime();
|
||||
level.timeLimitOverride = true;
|
||||
|
||||
level.bombPlanted = true;
|
||||
level.destroyedObject = destroyedObj;
|
||||
|
||||
if ( level.destroyedObject.label == "_a" )
|
||||
level.aPlanted = true;
|
||||
else
|
||||
level.bPlanted = true;
|
||||
|
||||
level.destroyedObject.bombPlanted = true;
|
||||
|
||||
destroyedObj.visuals[0] thread playDemolitionTickingSound(destroyedObj);
|
||||
level.tickingObject = destroyedObj.visuals[0];
|
||||
|
||||
self dropBombModel( player, destroyedObj.label );
|
||||
destroyedObj.bombDefused = false;
|
||||
destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
destroyedObj setUpForDefusing();
|
||||
|
||||
destroyedObj BombTimerWait(destroyedObj); //waits for bomb to explode!
|
||||
|
||||
destroyedObj thread bombHandler( player ,"explode" );
|
||||
|
||||
}
|
||||
|
||||
bombHandler( player, destType )
|
||||
{
|
||||
self.visuals[0] notify( "stopTicking" );
|
||||
level.bombsPlanted -= 1;
|
||||
|
||||
if ( self.label == "_a" )
|
||||
level.aPlanted = false;
|
||||
else
|
||||
level.bPlanted = false;
|
||||
|
||||
self.bombPlanted = 0;
|
||||
|
||||
self restartTimer();
|
||||
self setBombTimerDvar();
|
||||
|
||||
setDvar( "ui_bombtimer" + self.label, -1 );
|
||||
//self maps\mp\gametypes\_gameobjects::updateTimer( 0, false );
|
||||
|
||||
if ( level.gameEnded )
|
||||
return;
|
||||
|
||||
if ( destType == "explode" )
|
||||
{
|
||||
level.bombExploded += 1;
|
||||
|
||||
explosionOrigin = self.curorigin;
|
||||
level.ddBombModel[ self.label ] Delete();
|
||||
|
||||
if ( isdefined( player ) )
|
||||
{
|
||||
self.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player );
|
||||
player incPlayerStat( "targetsdestroyed", 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
self.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
|
||||
}
|
||||
|
||||
rot = randomfloat(360);
|
||||
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
|
||||
triggerFx( explosionEffect );
|
||||
|
||||
PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
|
||||
earthquake( 0.75, 2.0, explosionOrigin, 2000 );
|
||||
|
||||
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
|
||||
|
||||
if ( isDefined( self.exploderIndex ) )
|
||||
exploder( self.exploderIndex );
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::disableObject();
|
||||
|
||||
if ( level.bombExploded < 2 )
|
||||
{
|
||||
foreach ( splashPlayer in level.players )
|
||||
splashPlayer thread maps\mp\gametypes\_hud_message::SplashNotify( "time_added" );
|
||||
}
|
||||
|
||||
wait 2;
|
||||
|
||||
if ( level.bombExploded > 1 )
|
||||
dd_endGame( game["attackers"], game["strings"]["target_destroyed"] );
|
||||
else
|
||||
level thread teamPlayerCardSplash( "callout_time_added", player );
|
||||
}
|
||||
else //defused
|
||||
{
|
||||
player notify ( "bomb_defused" );
|
||||
self notify( "defused" );
|
||||
|
||||
// if ( !level.hardcoreMode )
|
||||
// iPrintLn( &"MP_EXPLOSIVES_DEFUSED_BY", player );
|
||||
|
||||
leaderDialog( "bomb_defused" );
|
||||
|
||||
level thread teamPlayerCardSplash( "callout_bombdefused", player );
|
||||
|
||||
level thread bombDefused( self );
|
||||
self resetBombzone();
|
||||
|
||||
if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 4000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
|
||||
else
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
|
||||
|
||||
player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
|
||||
player incPlayerStat( "bombsdefused", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origIn );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
playDemolitionTickingSound( site )
|
||||
{
|
||||
self endon("death");
|
||||
self endon("stopTicking");
|
||||
level endon("game_ended");
|
||||
|
||||
while(1)
|
||||
{
|
||||
self playSound( "ui_mp_suitcasebomb_timer" );
|
||||
|
||||
if ( !isDefined( site.waitTime ) || site.waitTime > 10 )
|
||||
wait 1.0;
|
||||
else if ( isDefined( site.waitTime ) && site.waitTime > 5 )
|
||||
wait 0.5;
|
||||
else
|
||||
wait 0.25;
|
||||
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
|
||||
}
|
||||
}
|
||||
|
||||
setBombTimerDvar()
|
||||
{
|
||||
println( "BOMBS PLANTED: " + level.bombsPlanted );
|
||||
|
||||
if ( level.bombsPlanted == 1 )
|
||||
setDvar( "ui_bomb_timer", 2 );
|
||||
else if ( level.bombsPlanted == 2 )
|
||||
setDvar( "ui_bomb_timer", 3 );
|
||||
else
|
||||
setDvar( "ui_bomb_timer", 0 );
|
||||
}
|
||||
|
||||
|
||||
dropBombModel( player, site )
|
||||
{
|
||||
trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000), false, player );
|
||||
|
||||
tempAngle = randomfloat( 360 );
|
||||
forward = (cos( tempAngle ), sin( tempAngle ), 0);
|
||||
forward = vectornormalize( forward - common_scripts\utility::vector_multiply( trace["normal"], vectordot( forward, trace["normal"] ) ) );
|
||||
dropAngles = vectortoangles( forward );
|
||||
|
||||
level.ddBombModel[ site ] = spawn( "script_model", trace["position"] );
|
||||
level.ddBombModel[ site ].angles = dropAngles;
|
||||
level.ddBombModel[ site ] setModel( "prop_suitcase_bomb" );
|
||||
}
|
||||
|
||||
|
||||
restartTimer()
|
||||
{
|
||||
if ( level.bombsPlanted <= 0 )
|
||||
{
|
||||
maps\mp\gametypes\_gamelogic::resumeTimer();
|
||||
level.timePaused = ( getTime() - level.timePauseStart ) ;
|
||||
level.timeLimitOverride = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BombTimerWait(siteLoc)
|
||||
{
|
||||
level endon("game_ended");
|
||||
level endon("bomb_defused" + siteLoc.label );
|
||||
|
||||
siteLoc.waitTime = level.bombTimer;
|
||||
|
||||
while ( siteLoc.waitTime >= 0 )
|
||||
{
|
||||
siteLoc.waitTime--;
|
||||
setDvar( "ui_bombtimer" + siteLoc.label, siteLoc.waitTime );
|
||||
|
||||
//self maps\mp\gametypes\_gameobjects::updateTimer( waitTime, true );
|
||||
|
||||
if ( siteLoc.waitTime >= 0 )
|
||||
wait( 1 );
|
||||
|
||||
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
|
||||
}
|
||||
}
|
||||
|
||||
bombDefused( siteDefused )
|
||||
{
|
||||
level.tickingObject maps\mp\gametypes\_gamelogic::stopTickingSound();
|
||||
siteDefused.bombDefused = true;
|
||||
self setBombTimerDvar();
|
||||
|
||||
setDvar( "ui_bombtimer" + siteDefused.label, -1 );
|
||||
|
||||
level notify("bomb_defused" + siteDefused.label);
|
||||
}
|
||||
|
||||
initGametypeAwards()
|
||||
{
|
||||
maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,968 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
/*
|
||||
Domination
|
||||
Objective: Capture all the flags by touching them
|
||||
Map ends: When one team captures all the flags, or time limit is reached
|
||||
Respawning: No wait / Near teammates
|
||||
|
||||
Level requirements
|
||||
------------------
|
||||
Spawnpoints:
|
||||
classname mp_tdm_spawn
|
||||
All players spawn from these. The spawnpoint chosen is dependent on the current locations of owned flags, teammates and
|
||||
enemies at the time of spawn. Players generally spawn behind their teammates relative to the direction of enemies.
|
||||
Optionally, give a spawnpoint a script_linkto to specify which flag it "belongs" to (see Flag Descriptors).
|
||||
|
||||
Spectator Spawnpoints:
|
||||
classname mp_global_intermission
|
||||
Spectators spawn from these and intermission is viewed from these positions.
|
||||
Atleast one is required, any more and they are randomly chosen between.
|
||||
|
||||
Flags:
|
||||
classname trigger_radius
|
||||
targetname flag_primary or flag_secondary
|
||||
Flags that need to be captured to win. Primary flags take time to capture; secondary flags are instant.
|
||||
|
||||
Flag Descriptors:
|
||||
classname script_origin
|
||||
targetname flag_descriptor
|
||||
Place one flag descriptor close to each flag. Use the script_linkname and script_linkto properties to say which flags
|
||||
it can be considered "adjacent" to in the level. For instance, if players have a primary path from flag1 to flag2, and
|
||||
from flag2 to flag3, flag2 would have a flag_descriptor with these properties:
|
||||
script_linkname flag2
|
||||
script_linkto flag1 flag3
|
||||
|
||||
Set scr_domdebug to 1 to see flag connections and what spawnpoints are considered connected to each flag.
|
||||
*/
|
||||
|
||||
/*QUAKED mp_dom_spawn (0.5 0.5 1.0) (-16 -16 0) (16 16 72)
|
||||
Players spawn near their flags at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_dom_spawn_axis_start (1.0 0.0 1.0) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
/*QUAKED mp_dom_spawn_allies_start (0.0 1.0 1.0) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
main()
|
||||
{
|
||||
if(getdvar("mapname") == "mp_background")
|
||||
return;
|
||||
|
||||
maps\mp\gametypes\_globallogic::init();
|
||||
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
|
||||
maps\mp\gametypes\_globallogic::SetupCallbacks();
|
||||
|
||||
registerTimeLimitDvar( level.gameType, 30, 0, 1440 );
|
||||
registerScoreLimitDvar( level.gameType, 300, 0, 1000 );
|
||||
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
|
||||
registerWinLimitDvar( level.gameType, 1, 0, 10 );
|
||||
registerNumLivesDvar( level.gameType, 0, 0, 10 );
|
||||
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
|
||||
|
||||
level.teamBased = true;
|
||||
level.onStartGameType = ::onStartGameType;
|
||||
level.getSpawnPoint = ::getSpawnPoint;
|
||||
level.onPlayerKilled = ::onPlayerKilled;
|
||||
level.onPrecacheGameType = ::onPrecacheGameType;
|
||||
level.initGametypeAwards = ::initGametypeAwards;
|
||||
level.onSpawnPlayer = ::onSpawnPlayer;
|
||||
|
||||
game["dialog"]["gametype"] = "domination";
|
||||
|
||||
if ( getDvarInt( "g_hardcore" ) )
|
||||
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "camera_thirdPerson" ) )
|
||||
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "scr_diehard" ) )
|
||||
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
|
||||
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
|
||||
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
|
||||
|
||||
game["dialog"]["offense_obj"] = "capture_objs";
|
||||
game["dialog"]["defense_obj"] = "capture_objs";
|
||||
}
|
||||
|
||||
|
||||
onPrecacheGameType()
|
||||
{
|
||||
precacheShader( "waypoint_captureneutral" );
|
||||
precacheShader( "waypoint_capture" );
|
||||
precacheShader( "waypoint_defend" );
|
||||
precacheShader( "waypoint_captureneutral_a" );
|
||||
precacheShader( "waypoint_capture_a" );
|
||||
precacheShader( "waypoint_defend_a" );
|
||||
precacheShader( "waypoint_captureneutral_b" );
|
||||
precacheShader( "waypoint_capture_b" );
|
||||
precacheShader( "waypoint_defend_b" );
|
||||
precacheShader( "waypoint_captureneutral_c" );
|
||||
precacheShader( "waypoint_capture_c" );
|
||||
precacheShader( "waypoint_defend_c" );
|
||||
|
||||
precacheShader( "waypoint_captureneutral" );
|
||||
precacheShader( "waypoint_capture" );
|
||||
precacheShader( "waypoint_defend" );
|
||||
precacheShader( "waypoint_captureneutral_a" );
|
||||
precacheShader( "waypoint_capture_a" );
|
||||
precacheShader( "waypoint_defend_a" );
|
||||
precacheShader( "waypoint_captureneutral_b" );
|
||||
precacheShader( "waypoint_capture_b" );
|
||||
precacheShader( "waypoint_defend_b" );
|
||||
precacheShader( "waypoint_captureneutral_c" );
|
||||
precacheShader( "waypoint_capture_c" );
|
||||
precacheShader( "waypoint_defend_c" );
|
||||
}
|
||||
|
||||
|
||||
onStartGameType()
|
||||
{
|
||||
setObjectiveText( "allies", &"OBJECTIVES_DOM" );
|
||||
setObjectiveText( "axis", &"OBJECTIVES_DOM" );
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
setObjectiveScoreText( "allies", &"OBJECTIVES_DOM" );
|
||||
setObjectiveScoreText( "axis", &"OBJECTIVES_DOM" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveScoreText( "allies", &"OBJECTIVES_DOM_SCORE" );
|
||||
setObjectiveScoreText( "axis", &"OBJECTIVES_DOM_SCORE" );
|
||||
}
|
||||
setObjectiveHintText( "allies", &"OBJECTIVES_DOM_HINT" );
|
||||
setObjectiveHintText( "axis", &"OBJECTIVES_DOM_HINT" );
|
||||
|
||||
setClientNameMode("auto_change");
|
||||
|
||||
level.spawnMins = ( 0, 0, 0 );
|
||||
level.spawnMaxs = ( 0, 0, 0 );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dom_spawn_allies_start" );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dom_spawn_axis_start" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_dom_spawn" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_dom_spawn" );
|
||||
|
||||
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
|
||||
setMapCenter( level.mapCenter );
|
||||
|
||||
level.spawn_all = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn" );
|
||||
level.spawn_axis_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn_axis_start" );
|
||||
level.spawn_allies_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn_allies_start" );
|
||||
|
||||
level.startPos["allies"] = level.spawn_allies_start[0].origin;
|
||||
level.startPos["axis"] = level.spawn_axis_start[0].origin;
|
||||
|
||||
level.flagBaseFXid[ "allies" ] = loadfx( maps\mp\gametypes\_teams::getTeamFlagFX( "allies" ) );
|
||||
level.flagBaseFXid[ "axis" ] = loadfx( maps\mp\gametypes\_teams::getTeamFlagFX( "axis" ) );
|
||||
|
||||
allowed[0] = "dom";
|
||||
// allowed[1] = "hardpoint";
|
||||
maps\mp\gametypes\_gameobjects::main(allowed);
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 10 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 150 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "defend", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "defend_assist", 10 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assault", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assault_assist", 10 );
|
||||
|
||||
thread domFlags();
|
||||
thread updateDomScores();
|
||||
}
|
||||
|
||||
|
||||
getSpawnPoint()
|
||||
{
|
||||
spawnpoint = undefined;
|
||||
|
||||
if ( !level.useStartSpawns )
|
||||
{
|
||||
flagsOwned = 0;
|
||||
enemyFlagsOwned = 0;
|
||||
myTeam = self.pers["team"];
|
||||
enemyTeam = getOtherTeam( myTeam );
|
||||
for ( i = 0; i < level.flags.size; i++ )
|
||||
{
|
||||
team = level.flags[i] getFlagTeam();
|
||||
if ( team == myTeam )
|
||||
flagsOwned++;
|
||||
else if ( team == enemyTeam )
|
||||
enemyFlagsOwned++;
|
||||
}
|
||||
|
||||
if ( flagsOwned == level.flags.size )
|
||||
{
|
||||
// own all flags! pretend we don't own the last one we got, so enemies can spawn there
|
||||
enemyBestSpawnFlag = level.bestSpawnFlag[ getOtherTeam( self.pers["team"] ) ];
|
||||
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all, getSpawnsBoundingFlag( enemyBestSpawnFlag ) );
|
||||
}
|
||||
else if ( flagsOwned > 0 )
|
||||
{
|
||||
// spawn near any flag we own that's nearish something we can capture
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all, getBoundaryFlagSpawns( myTeam ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// own no flags!
|
||||
bestFlag = undefined;
|
||||
if ( enemyFlagsOwned > 0 && enemyFlagsOwned < level.flags.size )
|
||||
{
|
||||
// there should be an unowned one to use
|
||||
bestFlag = getUnownedFlagNearestStart( myTeam );
|
||||
}
|
||||
if ( !isdefined( bestFlag ) )
|
||||
{
|
||||
// pretend we still own the last one we lost
|
||||
bestFlag = level.bestSpawnFlag[ self.pers["team"] ];
|
||||
}
|
||||
level.bestSpawnFlag[ self.pers["team"] ] = bestFlag;
|
||||
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all, bestFlag.nearbyspawns );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isdefined( spawnpoint ) )
|
||||
{
|
||||
if (self.pers["team"] == "axis")
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_axis_start);
|
||||
else
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_allies_start);
|
||||
}
|
||||
|
||||
//spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all );
|
||||
|
||||
assert( isDefined(spawnpoint) );
|
||||
|
||||
return spawnpoint;
|
||||
}
|
||||
|
||||
|
||||
domFlags()
|
||||
{
|
||||
level.lastStatus["allies"] = 0;
|
||||
level.lastStatus["axis"] = 0;
|
||||
|
||||
game["flagmodels"] = [];
|
||||
game["flagmodels"]["neutral"] = "prop_flag_neutral";
|
||||
|
||||
game["flagmodels"]["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
|
||||
game["flagmodels"]["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
|
||||
|
||||
precacheModel( game["flagmodels"]["neutral"] );
|
||||
precacheModel( game["flagmodels"]["allies"] );
|
||||
precacheModel( game["flagmodels"]["axis"] );
|
||||
|
||||
precacheString( &"MP_SECURING_POSITION" );
|
||||
|
||||
primaryFlags = getEntArray( "flag_primary", "targetname" );
|
||||
secondaryFlags = getEntArray( "flag_secondary", "targetname" );
|
||||
|
||||
if ( (primaryFlags.size + secondaryFlags.size) < 2 )
|
||||
{
|
||||
printLn( "^1Not enough domination flags found in level!" );
|
||||
maps\mp\gametypes\_callbacksetup::AbortLevel();
|
||||
return;
|
||||
}
|
||||
|
||||
level.flags = [];
|
||||
for ( index = 0; index < primaryFlags.size; index++ )
|
||||
level.flags[level.flags.size] = primaryFlags[index];
|
||||
|
||||
for ( index = 0; index < secondaryFlags.size; index++ )
|
||||
level.flags[level.flags.size] = secondaryFlags[index];
|
||||
|
||||
level.domFlags = [];
|
||||
for ( index = 0; index < level.flags.size; index++ )
|
||||
{
|
||||
trigger = level.flags[index];
|
||||
if ( isDefined( trigger.target ) )
|
||||
{
|
||||
visuals[0] = getEnt( trigger.target, "targetname" );
|
||||
}
|
||||
else
|
||||
{
|
||||
visuals[0] = spawn( "script_model", trigger.origin );
|
||||
visuals[0].angles = trigger.angles;
|
||||
}
|
||||
|
||||
visuals[0] setModel( game["flagmodels"]["neutral"] );
|
||||
|
||||
domFlag = maps\mp\gametypes\_gameobjects::createUseObject( "neutral", trigger, visuals, (0,0,100) );
|
||||
domFlag maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
|
||||
domFlag maps\mp\gametypes\_gameobjects::setUseTime( 10.0 );
|
||||
domFlag maps\mp\gametypes\_gameobjects::setUseText( &"MP_SECURING_POSITION" );
|
||||
label = domFlag maps\mp\gametypes\_gameobjects::getLabel();
|
||||
domFlag.label = label;
|
||||
domFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
|
||||
domFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
|
||||
domFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_captureneutral" + label );
|
||||
domFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" + label );
|
||||
domFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
domFlag.onUse = ::onUse;
|
||||
domFlag.onBeginUse = ::onBeginUse;
|
||||
domFlag.onUseUpdate = ::onUseUpdate;
|
||||
domFlag.onEndUse = ::onEndUse;
|
||||
|
||||
|
||||
traceStart = visuals[0].origin + (0,0,32);
|
||||
traceEnd = visuals[0].origin + (0,0,-32);
|
||||
trace = bulletTrace( traceStart, traceEnd, false, undefined );
|
||||
|
||||
upangles = vectorToAngles( trace["normal"] );
|
||||
domFlag.baseeffectforward = anglesToForward( upangles );
|
||||
domFlag.baseeffectright = anglesToRight( upangles );
|
||||
|
||||
domFlag.baseeffectpos = trace["position"];
|
||||
|
||||
// legacy spawn code support
|
||||
level.flags[index].useObj = domFlag;
|
||||
level.flags[index].adjflags = [];
|
||||
level.flags[index].nearbyspawns = [];
|
||||
|
||||
domFlag.levelFlag = level.flags[index];
|
||||
|
||||
level.domFlags[level.domFlags.size] = domFlag;
|
||||
}
|
||||
|
||||
// level.bestSpawnFlag is used as a last resort when the enemy holds all flags.
|
||||
level.bestSpawnFlag = [];
|
||||
level.bestSpawnFlag[ "allies" ] = getUnownedFlagNearestStart( "allies", undefined );
|
||||
level.bestSpawnFlag[ "axis" ] = getUnownedFlagNearestStart( "axis", level.bestSpawnFlag[ "allies" ] );
|
||||
|
||||
flagSetup();
|
||||
|
||||
/#
|
||||
thread domDebug();
|
||||
#/
|
||||
}
|
||||
|
||||
getUnownedFlagNearestStart( team, excludeFlag )
|
||||
{
|
||||
best = undefined;
|
||||
bestdistsq = undefined;
|
||||
for ( i = 0; i < level.flags.size; i++ )
|
||||
{
|
||||
flag = level.flags[i];
|
||||
|
||||
if ( flag getFlagTeam() != "neutral" )
|
||||
continue;
|
||||
|
||||
distsq = distanceSquared( flag.origin, level.startPos[team] );
|
||||
if ( (!isDefined( excludeFlag ) || flag != excludeFlag) && (!isdefined( best ) || distsq < bestdistsq) )
|
||||
{
|
||||
bestdistsq = distsq;
|
||||
best = flag;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
/#
|
||||
domDebug()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if (getdvar("scr_domdebug") != "1") {
|
||||
wait 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (getdvar("scr_domdebug") != "1")
|
||||
break;
|
||||
// show flag connections and each flag's spawnpoints
|
||||
for (i = 0; i < level.flags.size; i++) {
|
||||
for (j = 0; j < level.flags[i].adjflags.size; j++) {
|
||||
line(level.flags[i].origin, level.flags[i].adjflags[j].origin, (1,1,1));
|
||||
}
|
||||
|
||||
for (j = 0; j < level.flags[i].nearbyspawns.size; j++) {
|
||||
line(level.flags[i].origin, level.flags[i].nearbyspawns[j].origin, (.2,.2,.6));
|
||||
}
|
||||
|
||||
if ( level.flags[i] == level.bestSpawnFlag["allies"] )
|
||||
print3d( level.flags[i].origin, "allies best spawn flag" );
|
||||
if ( level.flags[i] == level.bestSpawnFlag["axis"] )
|
||||
print3d( level.flags[i].origin, "axis best spawn flag" );
|
||||
}
|
||||
wait .05;
|
||||
}
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
onBeginUse( player )
|
||||
{
|
||||
ownerTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
self.didStatusNotify = false;
|
||||
|
||||
if ( ownerTeam == "neutral" )
|
||||
{
|
||||
statusDialog( "securing"+self.label, player.pers["team"] );
|
||||
self.objPoints[player.pers["team"]] thread maps\mp\gametypes\_objpoints::startFlashing();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ownerTeam == "allies" )
|
||||
otherTeam = "axis";
|
||||
else
|
||||
otherTeam = "allies";
|
||||
|
||||
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::startFlashing();
|
||||
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::startFlashing();
|
||||
}
|
||||
|
||||
|
||||
onUseUpdate( team, progress, change )
|
||||
{
|
||||
if ( progress > 0.05 && change && !self.didStatusNotify )
|
||||
{
|
||||
ownerTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
if ( ownerTeam == "neutral" )
|
||||
{
|
||||
statusDialog( "securing"+self.label, team );
|
||||
}
|
||||
else
|
||||
{
|
||||
statusDialog( "losing"+self.label, ownerTeam );
|
||||
statusDialog( "securing"+self.label, team );
|
||||
}
|
||||
|
||||
self.didStatusNotify = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
statusDialog( dialog, team, forceDialog )
|
||||
{
|
||||
time = getTime();
|
||||
|
||||
if ( getTime() < level.lastStatus[team] + 5000 && (!isDefined( forceDialog ) || !forceDialog) )
|
||||
return;
|
||||
|
||||
thread delayedLeaderDialog( dialog, team );
|
||||
level.lastStatus[team] = getTime();
|
||||
}
|
||||
|
||||
|
||||
onEndUse( team, player, success )
|
||||
{
|
||||
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::stopFlashing();
|
||||
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::stopFlashing();
|
||||
}
|
||||
|
||||
|
||||
resetFlagBaseEffect()
|
||||
{
|
||||
if ( isdefined( self.baseeffect ) )
|
||||
self.baseeffect delete();
|
||||
|
||||
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
|
||||
if ( team != "axis" && team != "allies" )
|
||||
return;
|
||||
|
||||
fxid = level.flagBaseFXid[ team ];
|
||||
|
||||
self.baseeffect = spawnFx( fxid, self.baseeffectpos, self.baseeffectforward, self.baseeffectright );
|
||||
triggerFx( self.baseeffect );
|
||||
}
|
||||
|
||||
onUse( player )
|
||||
{
|
||||
team = player.pers["team"];
|
||||
oldTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
label = self maps\mp\gametypes\_gameobjects::getLabel();
|
||||
|
||||
//player logString( "flag captured: " + self.label );
|
||||
|
||||
self.captureTime = getTime();
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::setOwnerTeam( team );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_capture" + label );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_capture" + label );
|
||||
self.visuals[0] setModel( game["flagmodels"][team] );
|
||||
|
||||
self resetFlagBaseEffect();
|
||||
|
||||
level.useStartSpawns = false;
|
||||
|
||||
assert( team != "neutral" );
|
||||
|
||||
if ( oldTeam == "neutral" )
|
||||
{
|
||||
otherTeam = getOtherTeam( team );
|
||||
thread printAndSoundOnEveryone( team, otherTeam, undefined, undefined, "mp_war_objective_taken", undefined, player );
|
||||
|
||||
statusDialog( "secured"+self.label, team, true );
|
||||
statusDialog( "enemy_has"+self.label, otherTeam, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
thread printAndSoundOnEveryone( team, oldTeam, undefined, undefined, "mp_war_objective_taken", "mp_war_objective_lost", player );
|
||||
|
||||
// thread delayedLeaderDialogBothTeams( "obj_lost", oldTeam, "obj_taken", team );
|
||||
|
||||
if ( getTeamFlagCount( team ) == level.flags.size )
|
||||
{
|
||||
statusDialog( "secure_all", team );
|
||||
statusDialog( "lost_all", oldTeam );
|
||||
}
|
||||
else
|
||||
{
|
||||
statusDialog( "secured"+self.label, team, true );
|
||||
statusDialog( "lost"+self.label, oldTeam, true );
|
||||
}
|
||||
|
||||
level.bestSpawnFlag[ oldTeam ] = self.levelFlag;
|
||||
}
|
||||
|
||||
player notify( "objective", "captured" );
|
||||
self thread giveFlagCaptureXP( self.touchList[team] );
|
||||
}
|
||||
|
||||
giveFlagCaptureXP( touchList )
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
|
||||
players = getArrayKeys( touchList );
|
||||
for ( index = 0; index < players.size; index++ )
|
||||
{
|
||||
player = touchList[players[index]].player;
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "capture", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) );
|
||||
player thread updateCPM();
|
||||
player thread maps\mp\gametypes\_rank::giveRankXP( "capture", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) * player getCapXPScale() );
|
||||
printLn( maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) * player getCapXPScale() );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
|
||||
player incPlayerStat( "pointscaptured", 1 );
|
||||
}
|
||||
|
||||
player = self maps\mp\gametypes\_gameobjects::getEarliestClaimPlayer();
|
||||
|
||||
level thread teamPlayerCardSplash( "callout_securedposition" + self.label, player );
|
||||
|
||||
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
|
||||
}
|
||||
|
||||
delayedLeaderDialog( sound, team )
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
wait .1;
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
leaderDialog( sound, team );
|
||||
}
|
||||
delayedLeaderDialogBothTeams( sound1, team1, sound2, team2 )
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
wait .1;
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
leaderDialogBothTeams( sound1, team1, sound2, team2 );
|
||||
}
|
||||
|
||||
|
||||
updateDomScores()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
|
||||
while ( !level.gameEnded )
|
||||
{
|
||||
domFlags = getOwnedDomFlags();
|
||||
|
||||
if ( domFlags.size )
|
||||
{
|
||||
for ( i = 1; i < domFlags.size; i++ )
|
||||
{
|
||||
domFlag = domFlags[i];
|
||||
flagScore = getTime() - domFlag.captureTime;
|
||||
for ( j = i - 1; j >= 0 && flagScore > (getTime() - domFlags[j].captureTime); j-- )
|
||||
domFlags[j + 1] = domFlags[j];
|
||||
domFlags[j + 1] = domFlag;
|
||||
}
|
||||
|
||||
foreach( domFlag in domFlags )
|
||||
{
|
||||
team = domFlag maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
assert( team == "allies" || team == "axis" );
|
||||
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// end the game if people aren't playing
|
||||
if ( (((getTimePassed() / 1000) > 120 && domFlags.size < 2) || ((getTimePassed() / 1000) > 300 && domFlags.size < 3)) && matchMakingGame() )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "none", game["strings"]["time_limit_reached"] );
|
||||
return;
|
||||
}
|
||||
|
||||
wait ( 5.0 );
|
||||
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId )
|
||||
{
|
||||
if ( !isPlayer( attacker ) || (!self.touchTriggers.size && !attacker.touchTriggers.size) || attacker.pers["team"] == self.pers["team"] )
|
||||
return;
|
||||
|
||||
awardedAssault = false;
|
||||
awardedDefend = false;
|
||||
|
||||
foreach ( trigger in self.touchTriggers )
|
||||
{
|
||||
// TODO: way to check for dom specific triggers
|
||||
if ( !isDefined( trigger.useObj ) )
|
||||
continue;
|
||||
|
||||
ownerTeam = trigger.useObj.ownerTeam;
|
||||
team = self.pers["team"];
|
||||
|
||||
if ( ownerTeam == "neutral" )
|
||||
continue;
|
||||
|
||||
if ( team == ownerTeam )
|
||||
{
|
||||
awardedAssault = true;
|
||||
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "assault", maps\mp\gametypes\_rank::getScoreInfoValue( "assault" ) );
|
||||
attacker thread maps\mp\gametypes\_rank::giveRankXP( "assault" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "assault", attacker );
|
||||
|
||||
thread maps\mp\_matchdata::logKillEvent( killId, "defending" );
|
||||
}
|
||||
else
|
||||
{
|
||||
awardedDefend = true;
|
||||
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "defend", maps\mp\gametypes\_rank::getScoreInfoValue( "defend" ) );
|
||||
attacker thread maps\mp\gametypes\_rank::giveRankXP( "defend" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "defend", attacker );
|
||||
|
||||
thread maps\mp\_matchdata::logKillEvent( killId, "assaulting" );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( trigger in attacker.touchTriggers )
|
||||
{
|
||||
// TODO: way to check for dom specific triggers
|
||||
if ( !isDefined( trigger.useObj ) )
|
||||
continue;
|
||||
|
||||
ownerTeam = trigger.useObj.ownerTeam;
|
||||
team = attacker.pers["team"];
|
||||
|
||||
if ( ownerTeam == "neutral" )
|
||||
continue;
|
||||
|
||||
if ( team == ownerTeam )
|
||||
{
|
||||
if ( !awardedDefend )
|
||||
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "defend", maps\mp\gametypes\_rank::getScoreInfoValue( "defend" ) );
|
||||
attacker thread maps\mp\gametypes\_rank::giveRankXP( "defend" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "defend", attacker );
|
||||
|
||||
thread maps\mp\_matchdata::logKillEvent( killId, "assaulting" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !awardedAssault )
|
||||
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "assault", maps\mp\gametypes\_rank::getScoreInfoValue( "assault" ) );
|
||||
attacker thread maps\mp\gametypes\_rank::giveRankXP( "assault" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "assault", attacker );
|
||||
|
||||
thread maps\mp\_matchdata::logKillEvent( killId, "defending" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getOwnedDomFlags()
|
||||
{
|
||||
domFlags = [];
|
||||
foreach ( domFlag in level.domFlags )
|
||||
{
|
||||
if ( domFlag maps\mp\gametypes\_gameobjects::getOwnerTeam() != "neutral" && isDefined( domFlag.captureTime ) )
|
||||
domFlags[domFlags.size] = domFlag;
|
||||
}
|
||||
|
||||
return domFlags;
|
||||
}
|
||||
|
||||
|
||||
getTeamFlagCount( team )
|
||||
{
|
||||
score = 0;
|
||||
for (i = 0; i < level.flags.size; i++)
|
||||
{
|
||||
if ( level.domFlags[i] maps\mp\gametypes\_gameobjects::getOwnerTeam() == team )
|
||||
score++;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
getFlagTeam()
|
||||
{
|
||||
return self.useObj maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
}
|
||||
|
||||
getBoundaryFlags()
|
||||
{
|
||||
// get all flags which are adjacent to flags that aren't owned by the same team
|
||||
bflags = [];
|
||||
for (i = 0; i < level.flags.size; i++)
|
||||
{
|
||||
for (j = 0; j < level.flags[i].adjflags.size; j++)
|
||||
{
|
||||
if (level.flags[i].useObj maps\mp\gametypes\_gameobjects::getOwnerTeam() != level.flags[i].adjflags[j].useObj maps\mp\gametypes\_gameobjects::getOwnerTeam() )
|
||||
{
|
||||
bflags[bflags.size] = level.flags[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bflags;
|
||||
}
|
||||
|
||||
getBoundaryFlagSpawns(team)
|
||||
{
|
||||
spawns = [];
|
||||
|
||||
bflags = getBoundaryFlags();
|
||||
for (i = 0; i < bflags.size; i++)
|
||||
{
|
||||
if (isdefined(team) && bflags[i] getFlagTeam() != team)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < bflags[i].nearbyspawns.size; j++)
|
||||
spawns[spawns.size] = bflags[i].nearbyspawns[j];
|
||||
}
|
||||
|
||||
return spawns;
|
||||
}
|
||||
|
||||
getSpawnsBoundingFlag( avoidflag )
|
||||
{
|
||||
spawns = [];
|
||||
|
||||
for (i = 0; i < level.flags.size; i++)
|
||||
{
|
||||
flag = level.flags[i];
|
||||
if ( flag == avoidflag )
|
||||
continue;
|
||||
|
||||
isbounding = false;
|
||||
for (j = 0; j < flag.adjflags.size; j++)
|
||||
{
|
||||
if ( flag.adjflags[j] == avoidflag )
|
||||
{
|
||||
isbounding = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isbounding )
|
||||
continue;
|
||||
|
||||
for (j = 0; j < flag.nearbyspawns.size; j++)
|
||||
spawns[spawns.size] = flag.nearbyspawns[j];
|
||||
}
|
||||
|
||||
return spawns;
|
||||
}
|
||||
|
||||
// gets an array of all spawnpoints which are near flags that are
|
||||
// owned by the given team, or that are adjacent to flags owned by the given team.
|
||||
getOwnedAndBoundingFlagSpawns(team)
|
||||
{
|
||||
spawns = [];
|
||||
|
||||
for (i = 0; i < level.flags.size; i++)
|
||||
{
|
||||
if ( level.flags[i] getFlagTeam() == team )
|
||||
{
|
||||
// add spawns near this flag
|
||||
for (s = 0; s < level.flags[i].nearbyspawns.size; s++)
|
||||
spawns[spawns.size] = level.flags[i].nearbyspawns[s];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < level.flags[i].adjflags.size; j++)
|
||||
{
|
||||
if ( level.flags[i].adjflags[j] getFlagTeam() == team )
|
||||
{
|
||||
// add spawns near this flag
|
||||
for (s = 0; s < level.flags[i].nearbyspawns.size; s++)
|
||||
spawns[spawns.size] = level.flags[i].nearbyspawns[s];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return spawns;
|
||||
}
|
||||
|
||||
// gets an array of all spawnpoints which are near flags that are
|
||||
// owned by the given team
|
||||
getOwnedFlagSpawns(team)
|
||||
{
|
||||
spawns = [];
|
||||
|
||||
for (i = 0; i < level.flags.size; i++)
|
||||
{
|
||||
if ( level.flags[i] getFlagTeam() == team )
|
||||
{
|
||||
// add spawns near this flag
|
||||
for (s = 0; s < level.flags[i].nearbyspawns.size; s++)
|
||||
spawns[spawns.size] = level.flags[i].nearbyspawns[s];
|
||||
}
|
||||
}
|
||||
|
||||
return spawns;
|
||||
}
|
||||
|
||||
flagSetup()
|
||||
{
|
||||
maperrors = [];
|
||||
descriptorsByLinkname = [];
|
||||
|
||||
// (find each flag_descriptor object)
|
||||
descriptors = getentarray("flag_descriptor", "targetname");
|
||||
|
||||
flags = level.flags;
|
||||
|
||||
for (i = 0; i < level.domFlags.size; i++)
|
||||
{
|
||||
closestdist = undefined;
|
||||
closestdesc = undefined;
|
||||
for (j = 0; j < descriptors.size; j++)
|
||||
{
|
||||
dist = distance(flags[i].origin, descriptors[j].origin);
|
||||
if (!isdefined(closestdist) || dist < closestdist) {
|
||||
closestdist = dist;
|
||||
closestdesc = descriptors[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (!isdefined(closestdesc)) {
|
||||
maperrors[maperrors.size] = "there is no flag_descriptor in the map! see explanation in dom.gsc";
|
||||
break;
|
||||
}
|
||||
if (isdefined(closestdesc.flag)) {
|
||||
maperrors[maperrors.size] = "flag_descriptor with script_linkname \"" + closestdesc.script_linkname + "\" is nearby more than one flag; is there a unique descriptor near each flag?";
|
||||
continue;
|
||||
}
|
||||
flags[i].descriptor = closestdesc;
|
||||
closestdesc.flag = flags[i];
|
||||
descriptorsByLinkname[closestdesc.script_linkname] = closestdesc;
|
||||
}
|
||||
|
||||
if (maperrors.size == 0)
|
||||
{
|
||||
// find adjacent flags
|
||||
for (i = 0; i < flags.size; i++)
|
||||
{
|
||||
if (isdefined(flags[i].descriptor.script_linkto))
|
||||
adjdescs = strtok(flags[i].descriptor.script_linkto, " ");
|
||||
else
|
||||
adjdescs = [];
|
||||
for (j = 0; j < adjdescs.size; j++)
|
||||
{
|
||||
otherdesc = descriptorsByLinkname[adjdescs[j]];
|
||||
if (!isdefined(otherdesc) || otherdesc.targetname != "flag_descriptor") {
|
||||
maperrors[maperrors.size] = "flag_descriptor with script_linkname \"" + flags[i].descriptor.script_linkname + "\" linked to \"" + adjdescs[j] + "\" which does not exist as a script_linkname of any other entity with a targetname of flag_descriptor (or, if it does, that flag_descriptor has not been assigned to a flag)";
|
||||
continue;
|
||||
}
|
||||
adjflag = otherdesc.flag;
|
||||
if (adjflag == flags[i]) {
|
||||
maperrors[maperrors.size] = "flag_descriptor with script_linkname \"" + flags[i].descriptor.script_linkname + "\" linked to itself";
|
||||
continue;
|
||||
}
|
||||
flags[i].adjflags[flags[i].adjflags.size] = adjflag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// assign each spawnpoint to nearest flag
|
||||
spawnpoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn" );
|
||||
for (i = 0; i < spawnpoints.size; i++)
|
||||
{
|
||||
if (isdefined(spawnpoints[i].script_linkto)) {
|
||||
desc = descriptorsByLinkname[spawnpoints[i].script_linkto];
|
||||
if (!isdefined(desc) || desc.targetname != "flag_descriptor") {
|
||||
maperrors[maperrors.size] = "Spawnpoint at " + spawnpoints[i].origin + "\" linked to \"" + spawnpoints[i].script_linkto + "\" which does not exist as a script_linkname of any entity with a targetname of flag_descriptor (or, if it does, that flag_descriptor has not been assigned to a flag)";
|
||||
continue;
|
||||
}
|
||||
nearestflag = desc.flag;
|
||||
}
|
||||
else {
|
||||
nearestflag = undefined;
|
||||
nearestdist = undefined;
|
||||
for (j = 0; j < flags.size; j++)
|
||||
{
|
||||
dist = distancesquared(flags[j].origin, spawnpoints[i].origin);
|
||||
if (!isdefined(nearestflag) || dist < nearestdist)
|
||||
{
|
||||
nearestflag = flags[j];
|
||||
nearestdist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
nearestflag.nearbyspawns[nearestflag.nearbyspawns.size] = spawnpoints[i];
|
||||
}
|
||||
|
||||
if (maperrors.size > 0)
|
||||
{
|
||||
println("^1------------ Map Errors ------------");
|
||||
for(i = 0; i < maperrors.size; i++)
|
||||
println(maperrors[i]);
|
||||
println("^1------------------------------------");
|
||||
|
||||
error("Map errors. See above");
|
||||
maps\mp\gametypes\_callbacksetup::AbortLevel();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
initGametypeAwards()
|
||||
{
|
||||
maps\mp\_awards::initStatAward( "pointscaptured", 0, maps\mp\_awards::highestWins );
|
||||
}
|
||||
|
||||
onSpawnPlayer()
|
||||
{
|
||||
}
|
||||
|
||||
updateCPM()
|
||||
{
|
||||
if ( !isDefined( self.CPM ) )
|
||||
{
|
||||
self.numCaps = 0;
|
||||
self.CPM = 0;
|
||||
}
|
||||
|
||||
self.numCaps++;
|
||||
|
||||
if ( getMinutesPassed() < 1 )
|
||||
return;
|
||||
|
||||
self.CPM = self.numCaps / getMinutesPassed();
|
||||
}
|
||||
|
||||
getCapXPScale()
|
||||
{
|
||||
if ( self.CPM < 4 )
|
||||
return 1;
|
||||
else
|
||||
return 0.25;
|
||||
}
|
||||
@@ -0,0 +1,498 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
/*
|
||||
Global Thermal Nuclear War
|
||||
*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
main()
|
||||
{
|
||||
maps\mp\gametypes\_globallogic::init();
|
||||
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
|
||||
maps\mp\gametypes\_globallogic::SetupCallbacks();
|
||||
|
||||
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
|
||||
registerScoreLimitDvar( level.gameType, 101, 0, 10000 );
|
||||
registerRoundLimitDvar( level.gameType, 1, 0, 30 );
|
||||
registerWinLimitDvar( level.gameType, 1, 0, 10 );
|
||||
registerRoundSwitchDvar( level.gameType, 0, 0, 30 );
|
||||
registerNumLivesDvar( level.gameType, 0, 0, 10 );
|
||||
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
|
||||
|
||||
level.teamBased = true;
|
||||
level.onPrecacheGameType = ::onPrecacheGameType;
|
||||
level.onStartGameType = ::onStartGameType;
|
||||
level.getSpawnPoint = ::getSpawnPoint;
|
||||
level.onDeadEvent = ::onDeadEvent;
|
||||
level.initGametypeAwards = ::initGametypeAwards;
|
||||
level.onTimeLimit = ::onTimeLimit;
|
||||
level.onNormalDeath = ::onNormalDeath;
|
||||
level.gtnw = true;
|
||||
|
||||
game["dialog"]["gametype"] = "gtw";
|
||||
|
||||
if ( getDvarInt( "g_hardcore" ) )
|
||||
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "camera_thirdPerson" ) )
|
||||
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "scr_diehard" ) )
|
||||
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
|
||||
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
|
||||
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
|
||||
|
||||
game["dialog"]["offense_obj"] = "obj_destroy";
|
||||
game["dialog"]["defense_obj"] = "obj_defend";
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
gtnw_endGame( winningTeam, endReasonText )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
|
||||
}
|
||||
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
useBar = player createPrimaryProgressBar();
|
||||
useBarText = player createPrimaryProgressBarText();
|
||||
useBarText setText( &"MP_CAPTURING_NUKE" );
|
||||
|
||||
useBar.useTime = 100;
|
||||
player.useBar = useBar;
|
||||
player.useBar hideElem();
|
||||
player.useBarText = useBarText;
|
||||
player.useBarText hideElem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onStartGameType()
|
||||
{
|
||||
if ( !isdefined( game["switchedsides"] ) )
|
||||
game["switchedsides"] = false;
|
||||
|
||||
if ( !isdefined( game["original_defenders"] ) )
|
||||
game["original_defenders"] = game["defenders"];
|
||||
|
||||
if ( game["switchedsides"] )
|
||||
{
|
||||
oldAttackers = game["attackers"];
|
||||
oldDefenders = game["defenders"];
|
||||
game["attackers"] = oldDefenders;
|
||||
game["defenders"] = oldAttackers;
|
||||
}
|
||||
|
||||
setClientNameMode("auto_change");
|
||||
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GTNW" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GTNW" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GTNW_SCORE" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GTNW_SCORE" );
|
||||
}
|
||||
|
||||
setObjectiveText( game["attackers"], &"OBJECTIVES_GTNW" );
|
||||
setObjectiveText( game["defenders"], &"OBJECTIVES_GTNW" );
|
||||
|
||||
setObjectiveHintText( game["attackers"], &"OBJECTIVES_GTNW_HINT" );
|
||||
setObjectiveHintText( game["defenders"], &"OBJECTIVES_GTNW_HINT" );
|
||||
|
||||
level.spawnMins = ( 0, 0, 0 );
|
||||
level.spawnMaxs = ( 0, 0, 0 );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_allies_start" );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_axis_start" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_ctf_spawn_allies" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_ctf_spawn_axis" );
|
||||
|
||||
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
|
||||
setMapCenter( level.mapCenter );
|
||||
|
||||
thread maps\mp\gametypes\_dev::init();
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 100 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 500 );
|
||||
|
||||
allowed[0] = "airdrop_pallet";
|
||||
allowed[1] = "gtnw";
|
||||
allowed[2] = "gtnw_zone";
|
||||
maps\mp\gametypes\_gameobjects::main(allowed);
|
||||
|
||||
thread setupNukeSite();
|
||||
|
||||
}
|
||||
|
||||
onPrecacheGameType()
|
||||
{
|
||||
precacheShader("waypoint_defend");
|
||||
precacheShader("waypoint_target");
|
||||
precacheShader("waypoint_capture");
|
||||
precacheShader("compass_waypoint_target");
|
||||
precacheShader("compass_waypoint_defend");
|
||||
precacheShader("compass_waypoint_capture");
|
||||
|
||||
precacheString( &"MP_CAPTURING_NUKE" );
|
||||
return;
|
||||
}
|
||||
|
||||
setupNukeSite()
|
||||
{
|
||||
level.lastStatus["allies"] = 0;
|
||||
level.lastStatus["axis"] = 0;
|
||||
|
||||
nukeZone = getEnt( "gtnw_zone", "targetname" );
|
||||
assertEx( isDefined( nukeZone ), "GTNW Zone prefab doesn't exist in this map" );
|
||||
visuals = [];
|
||||
|
||||
nukeSite = maps\mp\gametypes\_gameobjects::createUseObject( "neutral", nukeZone, visuals, (0,0,100) );
|
||||
|
||||
nukeSite maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
|
||||
nukeSite maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" );
|
||||
|
||||
nukeSite maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral" );
|
||||
nukeSite maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" );
|
||||
|
||||
nukeSite maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
|
||||
nukeSite.noUseBar = true;
|
||||
nukeSite maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
|
||||
nukeSite.onBeginUse = ::onBeginUse;
|
||||
nukeSite.onEndUse = ::onEndUse;
|
||||
|
||||
level.nukeSite = nukeSite;
|
||||
nukeSite thread scoreCounter();
|
||||
}
|
||||
|
||||
|
||||
getSpawnPoint()
|
||||
{
|
||||
if ( self.team == "axis" )
|
||||
{
|
||||
spawnTeam = game["attackers"];
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnTeam = game["defenders"];
|
||||
}
|
||||
|
||||
if ( level.inGracePeriod )
|
||||
{
|
||||
spawnPoints = getentarray("mp_ctf_spawn_" + spawnteam + "_start", "classname");
|
||||
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
|
||||
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
|
||||
}
|
||||
|
||||
return spawnPoint;
|
||||
}
|
||||
|
||||
|
||||
spawnFxDelay( fxid, pos, forward, right, delay )
|
||||
{
|
||||
wait delay;
|
||||
effect = spawnFx( fxid, pos, forward, right );
|
||||
triggerFx( effect );
|
||||
}
|
||||
|
||||
|
||||
onDeadEvent( team )
|
||||
{
|
||||
if ( ( isDefined( level.nukeIncoming ) && level.nukeIncoming ) || ( isDefined( level.nukeDetonated ) && level.nukeDetonated ) )
|
||||
return;
|
||||
|
||||
if ( team == game["attackers"] )
|
||||
{
|
||||
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
|
||||
level thread gtnw_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
|
||||
}
|
||||
else if ( team == game["defenders"] )
|
||||
{
|
||||
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
|
||||
level thread gtnw_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
|
||||
}
|
||||
}
|
||||
|
||||
initGametypeAwards()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
onTimeLimit()
|
||||
{
|
||||
if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
|
||||
{
|
||||
level thread overtimeThread();
|
||||
}
|
||||
else if( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
else if( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
}
|
||||
|
||||
overtimeThread( time )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
level.inOvertime = true;
|
||||
level thread disableSpawning( 5 );
|
||||
|
||||
level.endGameTime = 120;
|
||||
|
||||
time = level.endGameTime;
|
||||
|
||||
foreach ( player in level.players )
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "gtnw_overtime" );
|
||||
|
||||
maps\mp\gametypes\_gamelogic::pauseTimer();
|
||||
level.timeLimitOverride = true;
|
||||
setGameEndTime( int( getTime() + ( level.endGameTime * 1000 ) ) );
|
||||
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( time );
|
||||
|
||||
if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
else if ( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
else
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
disableSpawning( waitTime )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
wait ( 5 );
|
||||
level.disableSpawning = true;
|
||||
}
|
||||
|
||||
|
||||
onBeginUse( player )
|
||||
{
|
||||
player.useBar showElem();
|
||||
player.useBarText showElem();
|
||||
return;
|
||||
}
|
||||
|
||||
onEndUse( team, player, success )
|
||||
{
|
||||
player.useBar hideElem();
|
||||
player.useBarText hideElem();
|
||||
return;
|
||||
}
|
||||
|
||||
scoreCounter()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self endon( "stop_counting" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
|
||||
if ( !self.touchList["axis"].size && !self.touchlist["allies"].size )
|
||||
{
|
||||
setDvar( "ui_danger_team", "none" );
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" );
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "none" );
|
||||
self updateHudElems();
|
||||
wait 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_capture" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_capture" );
|
||||
|
||||
if ( self.touchList["axis"].size > self.touchList["allies"].size )
|
||||
{
|
||||
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "axis" ) < 100 )
|
||||
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( "axis", 1 );
|
||||
|
||||
self thread setUseBarScore( "axis" );
|
||||
setDvar( "ui_danger_team", "allies" );
|
||||
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "axis" );
|
||||
|
||||
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "axis" ) >= 100 )
|
||||
{
|
||||
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
activateNuke( "axis" );
|
||||
self notify( "stop_counting" );
|
||||
}
|
||||
}
|
||||
else if ( self.touchList["axis"].size < self.touchList["allies"].size )
|
||||
{
|
||||
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "allies" ) < 100 )
|
||||
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( "allies", 1 );
|
||||
|
||||
self thread setUseBarScore( "allies" );
|
||||
setDvar( "ui_danger_team", "axis" );
|
||||
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "allies" );
|
||||
|
||||
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "allies" ) >= 100 )
|
||||
{
|
||||
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
activateNuke( "allies" );
|
||||
self notify( "stop_counting" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" );
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "none" );
|
||||
setDvar( "ui_danger_team", "contested" );
|
||||
}
|
||||
updateHudElems();
|
||||
|
||||
wait( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
activateNuke( team )
|
||||
{
|
||||
self giveFlagCaptureXP( self.touchList[team] );
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
|
||||
|
||||
bestTime = 99999999;
|
||||
nukeOwner = undefined;
|
||||
|
||||
foreach( player in level.players )
|
||||
{
|
||||
if ( !isDefined( player ) )
|
||||
continue;
|
||||
|
||||
player.useBar hideElem();
|
||||
player.useBarText hideElem();
|
||||
|
||||
if ( player.team != team )
|
||||
continue;
|
||||
|
||||
if ( !isDefined( self.touchlist[team][player.guid] ) )
|
||||
continue;
|
||||
|
||||
timeStarted = self.touchlist[team][player.guid].startTime;
|
||||
|
||||
if ( timeStarted < bestTime )
|
||||
{
|
||||
nukeOwner = player;
|
||||
bestTime = timeStarted;
|
||||
}
|
||||
}
|
||||
assert( isDefined( nukeOwner ) );
|
||||
|
||||
nukeOwner maps\mp\killstreaks\_nuke::tryUseNuke( 1 );
|
||||
}
|
||||
|
||||
|
||||
giveFlagCaptureXP( touchList )
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
wait .05;
|
||||
WaitTillSlowProcessAllowed();
|
||||
|
||||
players = getArrayKeys( touchList );
|
||||
for ( index = 0; index < players.size; index++ )
|
||||
{
|
||||
player = touchList[players[index]].player;
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "captured_nuke", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) );
|
||||
player thread [[level.onXPEvent]]( "capture" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
|
||||
}
|
||||
}
|
||||
|
||||
setUseBarScore( team )
|
||||
{
|
||||
teamScore = getTeamScore( team );
|
||||
|
||||
foreach( player in level.players )
|
||||
{
|
||||
if ( !isDefined( player ) )
|
||||
continue;
|
||||
|
||||
if ( player.team != team )
|
||||
continue;
|
||||
|
||||
if ( !isDefined( self.touchlist[team][player.guid] ) )
|
||||
continue;
|
||||
|
||||
//player thread maps\mp\gametypes\_rank::giveRankXP( "challenge",50 );
|
||||
|
||||
player.useBar updateBar( teamScore/100, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
updateHudElems()
|
||||
{
|
||||
foreach( player in level.players )
|
||||
{
|
||||
if ( !isDefined( player ) )
|
||||
continue;
|
||||
|
||||
if ( !isDefined( self.touchlist["axis"][player.guid] ) && !isDefined( self.touchlist["allies"][player.guid] ) )
|
||||
{
|
||||
player.useBar hideElem();
|
||||
player.useBarText hideElem();
|
||||
}
|
||||
|
||||
if ( isDefined( self.touchlist["axis"][player.guid] ) || isDefined( self.touchlist["allies"][player.guid] ) )
|
||||
{
|
||||
player.useBar showElem();
|
||||
player.useBarText showElem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onNormalDeath( victim, attacker, lifeId )
|
||||
{
|
||||
if ( !isDefined( level.inOvertime ) || !level.inOvertime )
|
||||
return;
|
||||
|
||||
team = victim.team;
|
||||
|
||||
if ( game["state"] == "postgame" )
|
||||
attacker.finalKill = true;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,558 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
/*
|
||||
One Flag CTF
|
||||
*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
/*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
main()
|
||||
{
|
||||
maps\mp\gametypes\_globallogic::init();
|
||||
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
|
||||
maps\mp\gametypes\_globallogic::SetupCallbacks();
|
||||
|
||||
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
|
||||
registerScoreLimitDvar( level.gameType, 1, 0, 10000 );
|
||||
registerRoundLimitDvar( level.gameType, 0, 0, 30 );
|
||||
registerWinLimitDvar( level.gameType, 4, 0, 10 );
|
||||
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
|
||||
registerNumLivesDvar( level.gameType, 0, 0, 10 );
|
||||
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
|
||||
|
||||
level.objectiveBased = true;
|
||||
level.teamBased = true;
|
||||
level.onPrecacheGameType = ::onPrecacheGameType;
|
||||
level.onStartGameType = ::onStartGameType;
|
||||
level.getSpawnPoint = ::getSpawnPoint;
|
||||
level.onSpawnPlayer = ::onSpawnPlayer;
|
||||
level.onPlayerKilled = ::onPlayerKilled;
|
||||
level.onTimeLimit = ::onTimeLimit;
|
||||
level.initGametypeAwards = ::initGametypeAwards;
|
||||
|
||||
game["dialog"]["gametype"] = "oneflag";
|
||||
|
||||
if ( getDvarInt( "g_hardcore" ) )
|
||||
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "camera_thirdPerson" ) )
|
||||
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "scr_diehard" ) )
|
||||
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
|
||||
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
|
||||
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
|
||||
|
||||
if ( getdvar("scr_oneflag_returntime") == "" )
|
||||
setdvar("scr_oneflag_returntime", "15");
|
||||
level.flagReturnTime = getdvarint( "scr_oneflag_returntime" );
|
||||
}
|
||||
|
||||
onPrecacheGameType()
|
||||
{
|
||||
precacheString(&"MP_FLAG_TAKEN_BY");
|
||||
precacheString(&"MP_ENEMY_FLAG_TAKEN_BY");
|
||||
precacheString(&"MP_FLAG_CAPTURED_BY");
|
||||
precacheString(&"MP_ENEMY_FLAG_CAPTURED_BY");
|
||||
//precacheString(&"MP_FLAG_RETURNED_BY");
|
||||
precacheString(&"MP_FLAG_RETURNED");
|
||||
precacheString(&"MP_ENEMY_FLAG_RETURNED");
|
||||
precacheString(&"MP_YOUR_FLAG_RETURNING_IN");
|
||||
precacheString(&"MP_ENEMY_FLAG_RETURNING_IN");
|
||||
precacheString(&"MP_ENEMY_FLAG_DROPPED_BY");
|
||||
precacheString( &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
|
||||
}
|
||||
|
||||
|
||||
onStartGameType()
|
||||
{
|
||||
if ( !isdefined( game["switchedsides"] ) )
|
||||
game["switchedsides"] = false;
|
||||
|
||||
if ( !isdefined( game["original_defenders"] ) )
|
||||
game["original_defenders"] = game["defenders"];
|
||||
|
||||
if ( game["switchedsides"] )
|
||||
{
|
||||
oldAttackers = game["attackers"];
|
||||
oldDefenders = game["defenders"];
|
||||
game["attackers"] = oldDefenders;
|
||||
game["defenders"] = oldAttackers;
|
||||
}
|
||||
|
||||
|
||||
setClientNameMode("auto_change");
|
||||
|
||||
setObjectiveText( game["attackers"], &"OBJECTIVES_CTF" );
|
||||
setObjectiveText( game["defenders"], &"OBJECTIVES_CTF" );
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_SCORE" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_SCORE" );
|
||||
}
|
||||
setObjectiveHintText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_HINT" );
|
||||
setObjectiveHintText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_HINT" );
|
||||
|
||||
|
||||
level.spawnMins = ( 0, 0, 0 );
|
||||
level.spawnMaxs = ( 0, 0, 0 );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_allies_start" );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_axis_start" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_ctf_spawn_allies" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_ctf_spawn_axis" );
|
||||
|
||||
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
|
||||
setMapCenter( level.mapCenter );
|
||||
|
||||
thread maps\mp\gametypes\_dev::init();
|
||||
|
||||
allowed[0] = "ctf";
|
||||
maps\mp\gametypes\_gameobjects::main(allowed);
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 100 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 100 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "pickup", 100 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "return", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 500 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "kill_carrier", 100 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "defend", 100 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "defend_assist", 100 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assault", 200 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assault_assist", 40 );
|
||||
|
||||
thread oneflag_ctf();
|
||||
}
|
||||
|
||||
|
||||
getSpawnPoint()
|
||||
{
|
||||
spawnteam = self.pers["team"];
|
||||
if ( game["switchedsides"] )
|
||||
spawnteam = getOtherTeam( spawnteam );
|
||||
|
||||
if ( level.inGracePeriod )
|
||||
{
|
||||
spawnPoints = getentarray("mp_ctf_spawn_" + spawnteam + "_start", "classname");
|
||||
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
|
||||
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
|
||||
}
|
||||
|
||||
return spawnPoint;
|
||||
}
|
||||
|
||||
|
||||
onSpawnPlayer()
|
||||
{
|
||||
self.usingObj = undefined;
|
||||
}
|
||||
|
||||
|
||||
oneflag_ctf()
|
||||
{
|
||||
|
||||
level.flagModel["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
|
||||
level.icon2D["allies"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "allies" );
|
||||
level.carryFlag["allies"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "allies" );
|
||||
|
||||
precacheModel( level.flagModel["allies"] );
|
||||
precacheModel( level.carryFlag["allies"] );
|
||||
|
||||
level.flagModel["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
|
||||
level.icon2D["axis"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "axis" );
|
||||
level.carryFlag["axis"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "axis" );
|
||||
|
||||
precacheModel( level.flagModel["axis"] );
|
||||
precacheModel( level.carryFlag["axis"] );
|
||||
|
||||
level.iconCapture3D = "waypoint_capture";
|
||||
level.iconCapture2D = "compass_waypoint_capture";
|
||||
level.iconDefend3D = "waypoint_defend";
|
||||
level.iconDefend2D = "compass_waypoint_defend";
|
||||
level.iconTarget3D = "waypoint_target";
|
||||
level.iconTarget2D = "compass_waypoint_target";
|
||||
|
||||
precacheShader( level.icon2D["axis"] );
|
||||
precacheShader( level.icon2D["allies"] );
|
||||
|
||||
precacheShader( level.iconCapture3D );
|
||||
precacheShader( level.iconDefend3D );
|
||||
|
||||
precacheShader( level.iconCapture2D );
|
||||
precacheShader( level.iconDefend2D );
|
||||
|
||||
precacheShader( level.iconTarget3D );
|
||||
precacheShader( level.iconTarget2D );
|
||||
|
||||
precacheShader( "waypoint_kill" );
|
||||
|
||||
level.teamFlags[game["defenders"]] = createTeamFlag( game["defenders"] );
|
||||
level.capZones[game["attackers"]] = createCapZone( game["attackers"] );
|
||||
level.flagCaptured = false;
|
||||
}
|
||||
|
||||
|
||||
spawnFxDelay( fxid, pos, forward, right, delay )
|
||||
{
|
||||
wait delay;
|
||||
effect = spawnFx( fxid, pos, forward, right );
|
||||
triggerFx( effect );
|
||||
}
|
||||
|
||||
createTeamFlag( team )
|
||||
{
|
||||
entityTeam = game["original_defenders"];
|
||||
|
||||
trigger = getEnt( "ctf_trig_" + entityTeam, "targetname" );
|
||||
if ( !isDefined( trigger ) )
|
||||
{
|
||||
error( "No ctf_trig_" + entityTeam + " trigger found in map." );
|
||||
return;
|
||||
}
|
||||
visuals[0] = getEnt( "ctf_flag_" + entityTeam, "targetname" );
|
||||
if ( !isDefined( visuals[0] ) )
|
||||
{
|
||||
error( "No ctf_flag_" + entityTeam + " script_model found in map." );
|
||||
return;
|
||||
}
|
||||
|
||||
cloneTrigger = spawn( "trigger_radius", trigger.origin, 0, 96, trigger.height );
|
||||
trigger delete();
|
||||
trigger = cloneTrigger;
|
||||
|
||||
visuals[0] setModel( level.flagModel[team] );
|
||||
|
||||
teamFlag = maps\mp\gametypes\_gameobjects::createCarryObject( team, trigger, visuals, (0,0,85) );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "friendly", 15.0 );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "enemy", 0 );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "enemy", &"MP_CAPTURING_FLAG" );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "friendly", &"MP_RETURNING_FLAG" );
|
||||
|
||||
teamFlag maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefend2D );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefend3D );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCapture2D );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCapture3D );
|
||||
teamFlag maps\mp\gametypes\_gameobjects::setCarryIcon( level.icon2D[team] );
|
||||
teamFlag.allowWeapons = true;
|
||||
teamFlag.onPickup = ::onPickup;
|
||||
teamFlag.onPickupFailed = ::onPickup;
|
||||
teamFlag.onDrop = ::onDrop;
|
||||
teamFlag.onReset = ::onReset;
|
||||
//teamFlag.onBeginUse = ::onBeginUse;
|
||||
//teamFlag.onEndUse = ::onEndUse;
|
||||
|
||||
teamFlag.oldRadius = trigger.radius;
|
||||
|
||||
traceStart = trigger.origin + (0,0,32);
|
||||
traceEnd = trigger.origin + (0,0,-32);
|
||||
trace = bulletTrace( traceStart, traceEnd, false, undefined );
|
||||
|
||||
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
|
||||
fxid = loadfx( fx );
|
||||
|
||||
upangles = vectorToAngles( trace["normal"] );
|
||||
forward = anglesToForward( upangles );
|
||||
right = anglesToRight( upangles );
|
||||
|
||||
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
|
||||
|
||||
return teamFlag;
|
||||
}
|
||||
|
||||
createCapZone( team )
|
||||
{
|
||||
entityTeam = level.otherTeam[game["original_defenders"]];
|
||||
|
||||
trigger = getEnt( "ctf_zone_" + entityTeam, "targetname" );
|
||||
if ( !isDefined( trigger ) )
|
||||
{
|
||||
error("No ctf_zone_" + entityTeam + " trigger found in map.");
|
||||
return;
|
||||
}
|
||||
|
||||
visuals[0] = getEnt( "ctf_flag_" + entityTeam, "targetname" );
|
||||
if ( !isDefined( visuals[0] ) )
|
||||
{
|
||||
error( "No ctf_flag_" + entityTeam + " script_model found in map." );
|
||||
return;
|
||||
}
|
||||
|
||||
visuals[0] hide();
|
||||
|
||||
visuals = [];
|
||||
capZone = maps\mp\gametypes\_gameobjects::createUseObject( team, trigger, visuals, (0,0,85) );
|
||||
capZone maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
|
||||
capZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
capZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconTarget2D );
|
||||
capZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconTarget3D );
|
||||
|
||||
capZone maps\mp\gametypes\_gameobjects::setUseTime( 0 );
|
||||
capZone maps\mp\gametypes\_gameobjects::setKeyObject( level.teamFlags[ getOtherTeam( team ) ] );
|
||||
|
||||
capZone.onUse = ::onUse;
|
||||
capZone.onCantUse = ::onCantUse;
|
||||
|
||||
traceStart = trigger.origin + (0,0,32);
|
||||
traceEnd = trigger.origin + (0,0,-32);
|
||||
trace = bulletTrace( traceStart, traceEnd, false, undefined );
|
||||
|
||||
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
|
||||
fxid = loadfx( fx );
|
||||
|
||||
upangles = vectorToAngles( trace["normal"] );
|
||||
forward = anglesToForward( upangles );
|
||||
right = anglesToRight( upangles );
|
||||
|
||||
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
|
||||
|
||||
return capZone;
|
||||
}
|
||||
|
||||
|
||||
onBeginUse( player )
|
||||
{
|
||||
team = player.pers["team"];
|
||||
|
||||
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
|
||||
self.trigger.radius = 1024;
|
||||
else
|
||||
self.trigger.radius = self.oldRadius;
|
||||
}
|
||||
|
||||
|
||||
onEndUse( player, team, success )
|
||||
{
|
||||
self.trigger.radius = self.oldRadius;
|
||||
}
|
||||
|
||||
|
||||
onPickup( player )
|
||||
{
|
||||
team = player.pers["team"];
|
||||
|
||||
if ( team == "allies" )
|
||||
otherTeam = "axis";
|
||||
else
|
||||
otherTeam = "allies";
|
||||
|
||||
|
||||
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
|
||||
{
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagreturn", maps\mp\gametypes\_rank::getScoreInfoValue( "pickup" ) );
|
||||
player thread [[level.onXPEvent]]( "pickup" );
|
||||
self thread returnFlag();
|
||||
player incPlayerStat( "flagsreturned", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "return", player.origin );
|
||||
}
|
||||
else
|
||||
{
|
||||
player attachFlag();
|
||||
|
||||
level.capZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
|
||||
//self maps\mp\gametypes\_gameobjects::setVisibleTeam( "enemy" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_kill" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconTarget2D );
|
||||
|
||||
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_TAKEN_BY", &"MP_FLAG_TAKEN_BY", "mp_obj_taken", "mp_enemy_obj_taken", player );
|
||||
|
||||
leaderDialog( "enemy_flag_taken", team, "status" );
|
||||
leaderDialog( "flag_taken", otherteam, "status" );
|
||||
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagpickup", maps\mp\gametypes\_rank::getScoreInfoValue( "pickup" ) );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "pickup", player );
|
||||
player thread [[level.onXPEvent]]( "pickup" );
|
||||
player incPlayerStat( "flagscarried", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
returnFlag()
|
||||
{
|
||||
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
otherTeam = level.otherTeam[team];
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::returnHome();
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
self maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
|
||||
|
||||
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
|
||||
printAndSoundOnEveryone( team, getOtherTeam( team ), &"MP_FLAG_RETURNED", &"MP_ENEMY_FLAG_RETURNED", "mp_obj_returned", "mp_obj_returned", "" );
|
||||
leaderDialog( "enemy_flag_returned", otherteam, "status" );
|
||||
leaderDialog( "flag_returned", team, "status" );
|
||||
}
|
||||
|
||||
|
||||
onDrop( player )
|
||||
{
|
||||
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
otherTeam = level.otherTeam[team];
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefend3D );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefend2D );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCapture3D );
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
self maps\mp\gametypes\_gameobjects::allowCarry( "any" );
|
||||
|
||||
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
|
||||
if ( isDefined( player ) )
|
||||
{
|
||||
if ( isDefined( player.carryFlag ) )
|
||||
player detachFlag();
|
||||
|
||||
printAndSoundOnEveryone( otherTeam, "none", &"MP_ENEMY_FLAG_DROPPED_BY", "", "mp_war_objective_lost", "", player );
|
||||
}
|
||||
else
|
||||
{
|
||||
playSoundOnPlayers( "mp_war_objective_lost", otherTeam );
|
||||
}
|
||||
|
||||
leaderDialog( "enemy_flag_dropped", otherTeam, "status" );
|
||||
leaderDialog( "flag_dropped", team, "status" );
|
||||
}
|
||||
|
||||
|
||||
onReset()
|
||||
{
|
||||
self notify ( "flag_reset" );
|
||||
|
||||
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
otherTeam = level.otherTeam[team];
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefend3D );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefend2D );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCapture3D );
|
||||
|
||||
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
}
|
||||
|
||||
|
||||
onUse( player )
|
||||
{
|
||||
team = player.pers["team"];
|
||||
if ( team == "allies" )
|
||||
otherTeam = "axis";
|
||||
else
|
||||
otherTeam = "allies";
|
||||
|
||||
leaderDialog( "enemy_flag_captured", team, "status" );
|
||||
leaderDialog( "flag_captured", otherteam, "status" );
|
||||
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
|
||||
player thread [[level.onXPEvent]]( "capture" );
|
||||
player incPlayerStat( "flagscaptured", 1 );
|
||||
player notify( "objective", "captured" );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
|
||||
|
||||
// round win here, no reset necessary
|
||||
|
||||
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_CAPTURED_BY", &"MP_FLAG_CAPTURED_BY", "mp_obj_captured", "mp_enemy_obj_captured", player );
|
||||
|
||||
thread flagCaptured( team, &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
|
||||
|
||||
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::allowCarry( "none" );
|
||||
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::disableObject();
|
||||
level.capZones[team] maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
|
||||
if ( isDefined( player.carryFlag ) )
|
||||
player detachFlag();
|
||||
}
|
||||
|
||||
|
||||
flagCaptured( winningTeam, endReasonText )
|
||||
{
|
||||
maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
|
||||
level.flagCaptured = true;
|
||||
}
|
||||
|
||||
|
||||
onTimeLimit()
|
||||
{
|
||||
if ( level.flagCaptured )
|
||||
return;
|
||||
|
||||
// TODO: change to "Flag Defended" or some such
|
||||
maps\mp\gametypes\_gamelogic::endGame( game["defenders"], game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
|
||||
|
||||
onCantUse( player )
|
||||
{
|
||||
// player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
|
||||
}
|
||||
|
||||
|
||||
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId )
|
||||
{
|
||||
if ( isDefined( attacker ) && isPlayer( attacker ) && attacker.pers["team"] != self.pers["team"] )
|
||||
{
|
||||
if ( isDefined( attacker.carryFlag ) )
|
||||
attacker incPlayerStat( "killsasflagcarrier", 1 );
|
||||
|
||||
if ( isDefined( self.carryFlag ) )
|
||||
{
|
||||
attacker thread [[level.onXPEvent]]( "kill_carrier" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "kill_carrier", attacker );
|
||||
attacker incPlayerStat( "flagcarrierkills", 1 );
|
||||
|
||||
thread maps\mp\_matchdata::logKillEvent( killId, "carrying" );
|
||||
|
||||
self detachFlag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
attachFlag()
|
||||
{
|
||||
otherTeam = level.otherTeam[self.pers["team"]];
|
||||
|
||||
self attach( level.carryFlag[otherTeam], "J_spine4", true );
|
||||
self.carryFlag = level.carryFlag[otherTeam];
|
||||
}
|
||||
|
||||
detachFlag()
|
||||
{
|
||||
self detach( self.carryFlag, "J_spine4" );
|
||||
self.carryFlag = undefined;
|
||||
}
|
||||
|
||||
initGametypeAwards()
|
||||
{
|
||||
maps\mp\_awards::initStatAward( "flagscaptured", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "flagsreturned", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "flagcarrierkills", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "flagscarried", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "killsasflagcarrier", 0, maps\mp\_awards::highestWins );
|
||||
}
|
||||
@@ -0,0 +1,907 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
/*
|
||||
Sabotage
|
||||
|
||||
// ...etc...
|
||||
*/
|
||||
|
||||
/*QUAKED mp_sab_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_sab_spawn_axis_planted (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_sab_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_sab_spawn_allies_planted (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions.*/
|
||||
|
||||
/*QUAKED mp_sab_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
/*QUAKED mp_sab_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
|
||||
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
|
||||
|
||||
main()
|
||||
{
|
||||
if ( getdvar("mapname") == "mp_background" )
|
||||
return;
|
||||
|
||||
maps\mp\gametypes\_globallogic::init();
|
||||
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
|
||||
maps\mp\gametypes\_globallogic::SetupCallbacks();
|
||||
|
||||
//level.objectiveBased = true;
|
||||
level.teamBased = true;
|
||||
|
||||
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
|
||||
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
|
||||
registerScoreLimitDvar( level.gameType, 0, 0, 500 );
|
||||
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
|
||||
registerWinLimitDvar( level.gameType, 1, 0, 10 );
|
||||
registerNumLivesDvar( level.gameType, 0, 0, 10 );
|
||||
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
|
||||
|
||||
setOverTimeLimitDvar( 2 );
|
||||
|
||||
level.onPrecacheGameType = ::onPrecacheGameType;
|
||||
level.onStartGameType = ::onStartGameType;
|
||||
level.getSpawnPoint = ::getSpawnPoint;
|
||||
level.onSpawnPlayer = ::onSpawnPlayer;
|
||||
level.onOneLeftEvent = ::onOneLeftEvent;
|
||||
level.onTimeLimit = ::onTimeLimit;
|
||||
level.onNormalDeath = ::onNormalDeath;
|
||||
level.initGametypeAwards = ::initGametypeAwards;
|
||||
|
||||
game["dialog"]["gametype"] = "sabotage";
|
||||
|
||||
if ( getDvarInt( "g_hardcore" ) )
|
||||
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "camera_thirdPerson" ) )
|
||||
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "scr_diehard" ) )
|
||||
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
|
||||
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
|
||||
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
|
||||
|
||||
game["dialog"]["offense_obj"] = "capture_obj";
|
||||
game["dialog"]["defense_obj"] = "capture_obj";
|
||||
|
||||
badtrig = getent( "sab_bomb_defuse_allies", "targetname" );
|
||||
if ( isdefined( badtrig ) )
|
||||
badtrig delete();
|
||||
|
||||
badtrig = getent( "sab_bomb_defuse_axis", "targetname" );
|
||||
if ( isdefined( badtrig ) )
|
||||
badtrig delete();
|
||||
}
|
||||
|
||||
onPrecacheGameType()
|
||||
{
|
||||
game["bomb_dropped_sound"] = "mp_war_objective_lost";
|
||||
game["bomb_recovered_sound"] = "mp_war_objective_taken";
|
||||
|
||||
precacheShader("waypoint_bomb");
|
||||
precacheShader("waypoint_kill");
|
||||
precacheShader("waypoint_bomb_enemy");
|
||||
precacheShader("waypoint_defend");
|
||||
precacheShader("waypoint_defuse");
|
||||
precacheShader("waypoint_target");
|
||||
precacheShader("waypoint_escort");
|
||||
precacheShader("waypoint_bomb");
|
||||
precacheShader("waypoint_defend");
|
||||
precacheShader("waypoint_defuse");
|
||||
precacheShader("waypoint_target");
|
||||
precacheShader("hud_suitcase_bomb");
|
||||
|
||||
precacheString(&"MP_EXPLOSIVES_RECOVERED_BY");
|
||||
precacheString(&"MP_EXPLOSIVES_DROPPED_BY");
|
||||
precacheString(&"MP_EXPLOSIVES_PLANTED_BY");
|
||||
precacheString(&"MP_EXPLOSIVES_DEFUSED_BY");
|
||||
precacheString(&"MP_YOU_HAVE_RECOVERED_THE_BOMB");
|
||||
precacheString(&"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES");
|
||||
precacheString(&"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES");
|
||||
precacheString(&"MP_PLANTING_EXPLOSIVE");
|
||||
precacheString(&"MP_DEFUSING_EXPLOSIVE");
|
||||
precacheString(&"MP_TARGET_DESTROYED");
|
||||
precacheString(&"MP_NO_RESPAWN");
|
||||
precacheString(&"MP_TIE_BREAKER");
|
||||
precacheString(&"MP_NO_RESPAWN");
|
||||
precacheString(&"MP_SUDDEN_DEATH");
|
||||
}
|
||||
|
||||
|
||||
onStartGameType()
|
||||
{
|
||||
if ( !isdefined( game["switchedsides"] ) )
|
||||
game["switchedsides"] = false;
|
||||
|
||||
setClientNameMode("auto_change");
|
||||
|
||||
game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
|
||||
game["strings"]["target_defended"] = &"MP_TARGET_DEDEFEND";
|
||||
|
||||
setObjectiveText( "allies", &"OBJECTIVES_SAB" );
|
||||
setObjectiveText( "axis", &"OBJECTIVES_SAB" );
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
setObjectiveScoreText( "allies", &"OBJECTIVES_SAB" );
|
||||
setObjectiveScoreText( "axis", &"OBJECTIVES_SAB" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveScoreText( "allies", &"OBJECTIVES_SAB_SCORE" );
|
||||
setObjectiveScoreText( "axis", &"OBJECTIVES_SAB_SCORE" );
|
||||
}
|
||||
setObjectiveHintText( "allies", &"OBJECTIVES_SAB_HINT" );
|
||||
setObjectiveHintText( "axis", &"OBJECTIVES_SAB_HINT" );
|
||||
|
||||
level.spawnMins = ( 0, 0, 0 );
|
||||
level.spawnMaxs = ( 0, 0, 0 );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sab_spawn_allies_start" );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sab_spawn_axis_start" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_sab_spawn_allies" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_sab_spawn_axis" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints("allies", "mp_sab_spawn_allies_planted", true );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints("axis", "mp_sab_spawn_axis_planted", true );
|
||||
|
||||
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
|
||||
setMapCenter( level.mapCenter );
|
||||
|
||||
level.spawn_axis = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_axis" );
|
||||
level.spawn_axis_planted = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_axis_planted" );
|
||||
level.spawn_axis_planted = array_combine( level.spawn_axis_planted, level.spawn_axis );
|
||||
|
||||
level.spawn_allies = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_allies" );
|
||||
level.spawn_allies_planted = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_allies_planted" );
|
||||
level.spawn_allies_planted = array_combine( level.spawn_allies_planted, level.spawn_allies );
|
||||
|
||||
level.spawn_axis_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_axis_start" );
|
||||
level.spawn_allies_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_allies_start" );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "plant", 200 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "destroy", 1000 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 150 );
|
||||
|
||||
allowed[0] = "sab";
|
||||
maps\mp\gametypes\_gameobjects::main(allowed);
|
||||
|
||||
thread updateGametypeDvars();
|
||||
|
||||
thread sabotage();
|
||||
}
|
||||
|
||||
|
||||
getSpawnPoint()
|
||||
{
|
||||
spawnteam = self.pers["team"];
|
||||
if ( game["switchedsides"] )
|
||||
spawnteam = getOtherTeam( spawnteam );
|
||||
|
||||
if ( level.useStartSpawns )
|
||||
{
|
||||
if (spawnteam == "axis")
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_axis_start);
|
||||
else
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_allies_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( level.bombplanted ) && level.bombplanted && ( isDefined( level.bombOwner ) && spawnTeam == level.bombOwner.team ) )
|
||||
{
|
||||
if (spawnteam == "axis")
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_axis_planted );
|
||||
else
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_allies_planted );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spawnteam == "axis")
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam(level.spawn_axis);
|
||||
else
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam(level.spawn_allies);
|
||||
}
|
||||
}
|
||||
|
||||
assert( isDefined(spawnpoint) );
|
||||
|
||||
return spawnpoint;
|
||||
}
|
||||
|
||||
|
||||
onSpawnPlayer()
|
||||
{
|
||||
self.isPlanting = false;
|
||||
self.isDefusing = false;
|
||||
self.isBombCarrier = false;
|
||||
|
||||
if( ( inOvertime() ) && !isDefined( self.otSpawned ) )
|
||||
self thread printOTHint();
|
||||
}
|
||||
|
||||
|
||||
printOTHint()
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
|
||||
// give the "Overtime!" message time to show
|
||||
wait ( 0.25 );
|
||||
|
||||
self thread maps\mp\gametypes\_hud_message::SplashNotify( "sudden_death" );
|
||||
self.otSpawned = true;
|
||||
|
||||
}
|
||||
|
||||
updateGametypeDvars()
|
||||
{
|
||||
level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
|
||||
level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
|
||||
level.bombTimer = dvarFloatValue( "bombtimer", 45, 1, 300 );
|
||||
level.hotPotato = dvarIntValue( "hotpotato", 1, 0, 1 );
|
||||
level.scoreMode = getWatchedDvar( "scorelimit" );
|
||||
}
|
||||
|
||||
|
||||
sabotage()
|
||||
{
|
||||
level.bombPlanted = false;
|
||||
level.bombExploded = false;
|
||||
|
||||
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
|
||||
|
||||
trigger = getEnt( "sab_bomb_pickup_trig", "targetname" );
|
||||
if ( !isDefined( trigger ) )
|
||||
{
|
||||
error( "No sab_bomb_pickup_trig trigger found in map." );
|
||||
return;
|
||||
}
|
||||
|
||||
visuals[0] = getEnt( "sab_bomb", "targetname" );
|
||||
if ( !isDefined( visuals[0] ) )
|
||||
{
|
||||
error( "No sab_bomb script_model found in map." );
|
||||
return;
|
||||
}
|
||||
|
||||
precacheModel( "prop_suitcase_bomb" );
|
||||
visuals[0] setModel( "prop_suitcase_bomb" );
|
||||
level.sabBomb = maps\mp\gametypes\_gameobjects::createCarryObject( "neutral", trigger, visuals, (0,0,32) );
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::allowCarry( "any" );
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_bomb" );
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_bomb" );
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::setCarryIcon( "hud_suitcase_bomb" );
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
level.sabBomb.objIDPingEnemy = true;
|
||||
level.sabBomb.onPickup = ::onPickup;
|
||||
level.sabBomb.onDrop = ::onDrop;
|
||||
level.sabBomb.allowWeapons = true;
|
||||
level.sabBomb.objPoints["allies"].archived = true;
|
||||
level.sabBomb.objPoints["axis"].archived = true;
|
||||
level.sabBomb.autoResetTime = 60.0;
|
||||
|
||||
if ( !isDefined( getEnt( "sab_bomb_axis", "targetname" ) ) )
|
||||
{
|
||||
error("No sab_bomb_axis trigger found in map.");
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( getEnt( "sab_bomb_allies", "targetname" ) ) )
|
||||
{
|
||||
error("No sab_bomb_allies trigger found in map.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( game["switchedsides"] )
|
||||
{
|
||||
level.bombZones["allies"] = createBombZone( "allies", getEnt( "sab_bomb_axis", "targetname" ) );
|
||||
level.bombZones["axis"] = createBombZone( "axis", getEnt( "sab_bomb_allies", "targetname" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
level.bombZones["allies"] = createBombZone( "allies", getEnt( "sab_bomb_allies", "targetname" ) );
|
||||
level.bombZones["axis"] = createBombZone( "axis", getEnt( "sab_bomb_axis", "targetname" ) );
|
||||
}
|
||||
|
||||
if ( level.scoreMode )
|
||||
level thread scoreThread();
|
||||
|
||||
if ( inOvertime() )
|
||||
level thread overtimeThread();
|
||||
}
|
||||
|
||||
|
||||
getClosestSite()
|
||||
{
|
||||
if ( distance2d( self.origin, level.bombZones["allies"].trigger.origin ) < distance2d( self.origin, level.bombZones["axis"].trigger.origin ) )
|
||||
return ( "allies" );
|
||||
else
|
||||
return ( "axis" );
|
||||
}
|
||||
|
||||
distanceToSite( team )
|
||||
{
|
||||
return ( distance2d( self.origin, level.bombZones[team].trigger.origin ) );
|
||||
}
|
||||
|
||||
scoreThread()
|
||||
{
|
||||
level.bombDistance = distance2d( getEnt( "sab_bomb_axis", "targetname" ) getOrigin(), getEnt( "sab_bomb_allies", "targetname" ) getOrigin() );
|
||||
|
||||
threatDistance = (level.bombDistance/2) - 384;
|
||||
|
||||
bombEnt = level.sabBomb.trigger;
|
||||
|
||||
// failsafe for bad bomb placement
|
||||
if ( threatDistance > bombEnt distanceToSite( "allies" ) || threatDistance > bombEnt distanceToSite( "axis" ) )
|
||||
threatDistance = bombEnt distanceToSite( bombEnt getClosestSite() ) - 128;
|
||||
|
||||
dangerTeam = "";
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( isDefined( level.sabBomb.carrier ) )
|
||||
bombEnt = level.sabBomb.carrier;
|
||||
else
|
||||
bombEnt = level.sabBomb.trigger;
|
||||
|
||||
lastDangerTeam = dangerTeam;
|
||||
dangerTeam = "none";
|
||||
|
||||
if ( bombEnt distanceToSite( "allies" ) < threatDistance )
|
||||
dangerTeam = level.bombZones["allies"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
else if ( bombEnt distanceToSite( "axis" ) < threatDistance )
|
||||
dangerTeam = level.bombZones["axis"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
else if ( bombEnt distanceToSite( "allies" ) > level.bombDistance && bombEnt getClosestSite() != "allies" )
|
||||
dangerTeam = level.bombZones["axis"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
else if ( bombEnt distanceToSite( "axis" ) > level.bombDistance && bombEnt getClosestSite() != "axis" )
|
||||
dangerTeam = level.bombZones["allies"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
|
||||
|
||||
if ( dangerTeam != "none" )
|
||||
{
|
||||
if ( !level.bombPlanted || !getWatchedDvar( "scorelimit" ) || (level.bombPlanted && (maps\mp\gametypes\_gamescore::_getTeamScore( level.otherTeam[dangerTeam] ) < getWatchedDvar( "scorelimit" ) - 1)) )
|
||||
{
|
||||
maps\mp\gametypes\_gamescore::_setTeamScore( level.otherTeam[dangerTeam], maps\mp\gametypes\_gamescore::_getTeamScore( level.otherTeam[dangerTeam] ) + 1 );
|
||||
maps\mp\gametypes\_gamescore::updateTeamScore( level.otherTeam[dangerTeam] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( dangerTeam != lastDangerTeam && !level.bombExploded )
|
||||
{
|
||||
setDvar( "ui_danger_team", dangerTeam );
|
||||
}
|
||||
|
||||
wait ( 2.5 );
|
||||
}
|
||||
}
|
||||
|
||||
createBombZone( team, trigger )
|
||||
{
|
||||
visuals = getEntArray( trigger.target, "targetname" );
|
||||
|
||||
bombZone = maps\mp\gametypes\_gameobjects::createUseObject( team, trigger, visuals, (0,0,64) );
|
||||
bombZone resetBombsite();
|
||||
bombZone.onUse = ::onUse;
|
||||
bombZone.onBeginUse = ::onBeginUse;
|
||||
bombZone.onEndUse = ::onEndUse;
|
||||
bombZone.onCantUse = ::onCantUse;
|
||||
bombZone.useWeapon = "briefcase_bomb_mp";
|
||||
|
||||
for ( i = 0; i < visuals.size; i++ )
|
||||
{
|
||||
if ( isDefined( visuals[i].script_exploder ) )
|
||||
{
|
||||
bombZone.exploderIndex = visuals[i].script_exploder;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return bombZone;
|
||||
}
|
||||
|
||||
|
||||
onBeginUse( player )
|
||||
{
|
||||
// planted the bomb
|
||||
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
|
||||
player.isPlanting = true;
|
||||
else
|
||||
player.isDefusing = true;
|
||||
}
|
||||
|
||||
onEndUse( team, player, result )
|
||||
{
|
||||
if ( !isAlive( player ) )
|
||||
return;
|
||||
|
||||
player.isPlanting = false;
|
||||
player.isDefusing = false;
|
||||
}
|
||||
|
||||
|
||||
onPickup( player )
|
||||
{
|
||||
level notify ( "bomb_picked_up" );
|
||||
|
||||
self.autoResetTime = 60.0;
|
||||
|
||||
level.useStartSpawns = false;
|
||||
|
||||
team = player.pers["team"];
|
||||
|
||||
if ( team == "allies" )
|
||||
otherTeam = "axis";
|
||||
else
|
||||
otherTeam = "allies";
|
||||
|
||||
player playLocalSound( "mp_suitcase_pickup" );
|
||||
|
||||
player leaderDialogOnPlayer( "obj_destroy", "bomb" );
|
||||
excludeList[0] = player;
|
||||
leaderDialog( "bomb_taken", team, "bomb", excludeList );
|
||||
|
||||
if ( !level.splitscreen )
|
||||
{
|
||||
leaderDialog( "bomb_lost", otherTeam, "bomb" );
|
||||
leaderDialog( "obj_defend", otherTeam, "bomb" );
|
||||
}
|
||||
player.isBombCarrier = true;
|
||||
|
||||
// recovered the bomb before abandonment timer elapsed
|
||||
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
|
||||
{
|
||||
//printOnTeamArg( &"MP_EXPLOSIVES_RECOVERED_BY", team, player );
|
||||
playSoundOnPlayers( game["bomb_recovered_sound"], team );
|
||||
}
|
||||
else
|
||||
{
|
||||
//printOnTeamArg( &"MP_EXPLOSIVES_RECOVERED_BY", team, player );
|
||||
playSoundOnPlayers( game["bomb_recovered_sound"] );
|
||||
}
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::setOwnerTeam( team );
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_kill" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_escort" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_escort" );
|
||||
|
||||
level.bombZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
level.bombZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
|
||||
player incPlayerStat( "bombscarried", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
|
||||
}
|
||||
|
||||
|
||||
onDrop( player )
|
||||
{
|
||||
if ( level.bombPlanted )
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( player ) )
|
||||
printOnTeamArg( &"MP_EXPLOSIVES_DROPPED_BY", self maps\mp\gametypes\_gameobjects::getOwnerTeam(), player );
|
||||
|
||||
playSoundOnPlayers( game["bomb_dropped_sound"], self maps\mp\gametypes\_gameobjects::getOwnerTeam() );
|
||||
|
||||
thread abandonmentThink( 0.0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abandonmentThink( delay )
|
||||
{
|
||||
level endon ( "bomb_picked_up" );
|
||||
|
||||
wait ( delay );
|
||||
|
||||
if ( isDefined( self.carrier ) )
|
||||
return;
|
||||
|
||||
if ( self maps\mp\gametypes\_gameobjects::getOwnerTeam() == "allies" )
|
||||
otherTeam = "axis";
|
||||
else
|
||||
otherTeam = "allies";
|
||||
|
||||
// printOnTeamArg( &"MP_EXPLOSIVES_DROPPED_BY", otherTeam, &"MP_THE_ENEMY" );
|
||||
playSoundOnPlayers( game["bomb_dropped_sound"], otherTeam );
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "neutral" );
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_bomb" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_bomb" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
|
||||
|
||||
level.bombZones["allies"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
level.bombZones["axis"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
}
|
||||
|
||||
|
||||
onUse( player )
|
||||
{
|
||||
team = player.pers["team"];
|
||||
otherTeam = level.otherTeam[team];
|
||||
// planted the bomb
|
||||
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
|
||||
{
|
||||
player notify ( "bomb_planted" );
|
||||
|
||||
player playSound( "mp_bomb_plant" );
|
||||
|
||||
level thread teamPlayerCardSplash( "callout_bombplanted", player );
|
||||
|
||||
leaderDialog( "bomb_planted" );
|
||||
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
|
||||
player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
|
||||
player incPlayerStat( "bombsplanted", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
|
||||
player.bombPlantedTime = getTime();
|
||||
|
||||
//if ( !inOvertime() )
|
||||
level thread bombPlanted( self, player.pers["team"] );
|
||||
|
||||
level.bombOwner = player;
|
||||
|
||||
level.sabBomb.autoResetTime = undefined;
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::allowCarry( "none" );
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::setDropped();
|
||||
self.useWeapon = "briefcase_bomb_defuse_mp";
|
||||
|
||||
self setUpForDefusing();
|
||||
}
|
||||
else // defused the bomb
|
||||
{
|
||||
player notify ( "bomb_defused" );
|
||||
|
||||
leaderDialog( "bomb_defused" );
|
||||
|
||||
level thread teamPlayerCardSplash( "callout_bombdefused", player );
|
||||
|
||||
if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 3000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
|
||||
else
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
|
||||
|
||||
player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
|
||||
player incPlayerStat( "bombsdefused", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origin );
|
||||
|
||||
if ( inOvertime() )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( team, game["strings"]["target_destroyed"] );
|
||||
return;
|
||||
}
|
||||
|
||||
level thread bombDefused( self );
|
||||
|
||||
self resetBombsite();
|
||||
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::allowCarry( "any" );
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::setPickedUp( player );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onCantUse( player )
|
||||
{
|
||||
player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
|
||||
}
|
||||
|
||||
|
||||
bombPlanted( destroyedObj, team )
|
||||
{
|
||||
level endon ( "overtime" );
|
||||
|
||||
maps\mp\gametypes\_gamelogic::pauseTimer();
|
||||
level.bombPlanted = true;
|
||||
level.timeLimitOverride = true;
|
||||
level.scoreLimitOverride = true;
|
||||
setDvar( "ui_bomb_timer", 1 );
|
||||
|
||||
// communicate timer information to menus
|
||||
setGameEndTime( int( getTime() + (level.bombTimer * 1000) ) );
|
||||
|
||||
destroyedObj.visuals[0] thread maps\mp\gametypes\_gamelogic::playTickingSound();
|
||||
|
||||
starttime = gettime();
|
||||
bombTimerWait();
|
||||
|
||||
setDvar( "ui_bomb_timer", 0 );
|
||||
destroyedObj.visuals[0] maps\mp\gametypes\_gamelogic::stopTickingSound();
|
||||
|
||||
if ( !level.bombPlanted )
|
||||
{
|
||||
if ( level.hotPotato )
|
||||
{
|
||||
timePassed = (gettime() - starttime) / 1000;
|
||||
level.bombTimer -= timePassed;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
explosionOrigin = level.sabBomb.visuals[0].origin;
|
||||
level.bombExploded = true;
|
||||
setDvar( "ui_danger_team", "BombExploded" );
|
||||
|
||||
if ( isdefined( level.bombowner ) )
|
||||
{
|
||||
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, level.bombowner );
|
||||
level.bombowner incPlayerStat( "targetsdestroyed", 1 );
|
||||
}
|
||||
else
|
||||
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
|
||||
|
||||
rot = randomfloat(360);
|
||||
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
|
||||
triggerFx( explosionEffect );
|
||||
|
||||
PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
|
||||
earthquake( 0.75, 2.0, explosionOrigin, 2000 );
|
||||
|
||||
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
|
||||
|
||||
if ( isDefined( destroyedObj.exploderIndex ) )
|
||||
exploder( destroyedObj.exploderIndex );
|
||||
|
||||
level.sabBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
level.bombZones["allies"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
level.bombZones["axis"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
|
||||
setGameEndTime( 0 );
|
||||
|
||||
level.scoreLimitOverride = true;
|
||||
|
||||
if ( level.scoreMode )
|
||||
maps\mp\gametypes\_gamescore::_setTeamScore( team, int( max( getWatchedDvar( "scorelimit" ), maps\mp\gametypes\_gamescore::_getTeamScore( level.otherTeam[team] ) + 1 ) ) );
|
||||
else
|
||||
maps\mp\gametypes\_gamescore::_setTeamScore( team, 1 );
|
||||
maps\mp\gametypes\_gamescore::updateTeamScore( team );
|
||||
|
||||
if ( isDefined( level.bombOwner ) )
|
||||
{
|
||||
level.bombOwner thread maps\mp\gametypes\_rank::giveRankXP( "destroy" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "destroy", level.bombOwner );
|
||||
level thread teamPlayerCardSplash( "callout_destroyed_objective", level.bombOwner );
|
||||
}
|
||||
|
||||
wait 3;
|
||||
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( team, game["strings"]["target_destroyed"] );
|
||||
}
|
||||
|
||||
|
||||
bombTimerWait()
|
||||
{
|
||||
level endon("bomb_defused");
|
||||
level endon("overtime_ended");
|
||||
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( level.bombTimer );
|
||||
}
|
||||
|
||||
|
||||
giveLastOnTeamWarning()
|
||||
{
|
||||
self endon("death");
|
||||
self endon("disconnect");
|
||||
level endon( "game_ended" );
|
||||
|
||||
self waitTillRecoveredHealth( 3 );
|
||||
|
||||
otherTeam = getOtherTeam( self.pers["team"] );
|
||||
level thread teamPlayerCardSplash( "callout_lastteammemberalive", self, self.pers["team"] );
|
||||
level thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
|
||||
level notify ( "last_alive", self );
|
||||
//self maps\mp\gametypes\_missions::lastManSD();
|
||||
}
|
||||
|
||||
|
||||
onTimeLimit()
|
||||
{
|
||||
if ( level.bombExploded )
|
||||
return;
|
||||
|
||||
if( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
else if( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
else if( game["teamScores"]["axis"] == game["teamScores"]["allies"] )
|
||||
{
|
||||
if ( inOvertime() )
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game["strings"]["time_limit_reached"] );
|
||||
else
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( "overtime", game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
overtimeThread( time )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
level.inOvertime = true;
|
||||
|
||||
wait ( 5.0 );
|
||||
level.disableSpawning = true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
overtimeThread()
|
||||
{
|
||||
level.inOvertime = getTime();
|
||||
level notify ( "overtime" );
|
||||
|
||||
thread bombDistanceThread();
|
||||
|
||||
foreach ( player in level.players )
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "sab_overtime" );
|
||||
|
||||
maps\mp\gametypes\_gamelogic::pauseTimer();
|
||||
level.bombPlanted = true;
|
||||
level.timeLimitOverride = true;
|
||||
setDvar( "ui_bomb_timer", 1 );
|
||||
|
||||
// communicate timer information to menus
|
||||
setGameEndTime( int( getTime() + (level.bombTimer * 1000) ) );
|
||||
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( level.bombTimer );
|
||||
|
||||
setDvar( "ui_bomb_timer", 0 );
|
||||
|
||||
if ( isDefined( level.sabBomb.carrier ) )
|
||||
{
|
||||
explosionEnt = level.sabBomb.carrier;
|
||||
}
|
||||
else
|
||||
{
|
||||
explosionEnt = level.sabBomb.visuals[0];
|
||||
}
|
||||
|
||||
level.bombExploded = true;
|
||||
|
||||
if ( isdefined( level.bombowner ) )
|
||||
explosionEnt radiusDamage( explosionEnt.origin, 512, 200, 20, level.bombowner );
|
||||
else
|
||||
explosionEnt radiusDamage( explosionEnt.origin, 512, 200, 20 );
|
||||
|
||||
rot = randomfloat(360);
|
||||
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionEnt.origin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
|
||||
triggerFx( explosionEffect );
|
||||
|
||||
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionEnt.origin );
|
||||
|
||||
setGameEndTime( 0 );
|
||||
|
||||
team = getOtherTeam( level.dangerTeam );
|
||||
|
||||
wait 3;
|
||||
|
||||
//maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
|
||||
maps\mp\gametypes\_gamelogic::endGame( team, game["strings"]["target_destroyed"] );
|
||||
}
|
||||
*/
|
||||
|
||||
bombDistanceThread()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
|
||||
if ( cointoss() )
|
||||
level.dangerTeam = "allies";
|
||||
else
|
||||
level.dangerTeam = "axis";
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( isDefined( level.sabBomb.carrier ) )
|
||||
bombEnt = level.sabBomb.carrier;
|
||||
else
|
||||
bombEnt = level.sabBomb.visuals[0];
|
||||
|
||||
if ( distance( bombEnt.origin, level.bombZones[getOtherTeam(level.dangerTeam)].visuals[0].origin ) < distance( bombEnt.origin, level.bombZones[level.dangerTeam].visuals[0].origin ) )
|
||||
level.dangerTeam = getOtherTeam( level.dangerTeam );
|
||||
|
||||
wait ( 0.05 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resetBombsite()
|
||||
{
|
||||
self maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
|
||||
self maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
|
||||
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
|
||||
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
|
||||
self maps\mp\gametypes\_gameobjects::setKeyObject( level.sabBomb );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" );
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
self.useWeapon = "briefcase_bomb_mp";
|
||||
}
|
||||
|
||||
|
||||
setUpForDefusing()
|
||||
{
|
||||
self maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
|
||||
self maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
|
||||
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
|
||||
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
|
||||
self maps\mp\gametypes\_gameobjects::setKeyObject( undefined );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" );
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" );
|
||||
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
}
|
||||
|
||||
|
||||
bombDefused( object )
|
||||
{
|
||||
setDvar( "ui_bomb_timer", 0 );
|
||||
maps\mp\gametypes\_gamelogic::resumeTimer();
|
||||
level.bombPlanted = false;
|
||||
level.timeLimitOverride = false;
|
||||
level.scoreLimitOverride = false;
|
||||
|
||||
level notify("bomb_defused");
|
||||
}
|
||||
|
||||
|
||||
onOneLeftEvent( team )
|
||||
{
|
||||
if ( level.bombExploded )
|
||||
return;
|
||||
|
||||
lastPlayer = getLastLivingPlayer( team );
|
||||
|
||||
lastPlayer thread giveLastOnTeamWarning();
|
||||
}
|
||||
|
||||
|
||||
onNormalDeath( victim, attacker, lifeId, lifeId )
|
||||
{
|
||||
if ( victim.isPlanting )
|
||||
{
|
||||
thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
|
||||
}
|
||||
else if ( victim.isBombCarrier )
|
||||
{
|
||||
attacker incPlayerStat( "bombcarrierkills", 1 );
|
||||
thread maps\mp\_matchdata::logKillEvent( lifeId, "carrying" );
|
||||
}
|
||||
else if ( victim.isDefusing )
|
||||
{
|
||||
thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
|
||||
}
|
||||
|
||||
if ( attacker.isBombCarrier )
|
||||
attacker incPlayerStat( "killsasbombcarrier", 1 );
|
||||
}
|
||||
|
||||
initGametypeAwards()
|
||||
{
|
||||
maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
|
||||
}
|
||||
@@ -0,0 +1,794 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
// Rallypoints should be destroyed on leaving your team/getting killed
|
||||
// Compass icons need to be looked at
|
||||
// Doesn't seem to be setting angle on spawn so that you are facing your rallypoint
|
||||
|
||||
/*
|
||||
Search and Destroy
|
||||
Attackers objective: Bomb one of 2 positions
|
||||
Defenders objective: Defend these 2 positions / Defuse planted bombs
|
||||
Round ends: When one team is eliminated, bomb explodes, bomb is defused, or roundlength time is reached
|
||||
Map ends: When one team reaches the score limit, or time limit or round limit is reached
|
||||
Respawning: Players remain dead for the round and will respawn at the beginning of the next round
|
||||
|
||||
Level requirements
|
||||
------------------
|
||||
Allied Spawnpoints:
|
||||
classname mp_sd_spawn_attacker
|
||||
Allied players spawn from these. Place at least 16 of these relatively close together.
|
||||
|
||||
Axis Spawnpoints:
|
||||
classname mp_sd_spawn_defender
|
||||
Axis players spawn from these. Place at least 16 of these relatively close together.
|
||||
|
||||
Spectator Spawnpoints:
|
||||
classname mp_global_intermission
|
||||
Spectators spawn from these and intermission is viewed from these positions.
|
||||
Atleast one is required, any more and they are randomly chosen between.
|
||||
|
||||
Bombzones:
|
||||
classname trigger_multiple
|
||||
targetname bombzone
|
||||
script_gameobjectname bombzone
|
||||
script_bombmode_original <if defined this bombzone will be used in the original bomb mode>
|
||||
script_bombmode_single <if defined this bombzone will be used in the single bomb mode>
|
||||
script_bombmode_dual <if defined this bombzone will be used in the dual bomb mode>
|
||||
script_team Set to allies or axis. This is used to set which team a bombzone is used by in dual bomb mode.
|
||||
script_label Set to A or B. This sets the letter shown on the compass in original mode.
|
||||
This is a volume of space in which the bomb can planted. Must contain an origin brush.
|
||||
|
||||
Bomb:
|
||||
classname trigger_lookat
|
||||
targetname bombtrigger
|
||||
script_gameobjectname bombzone
|
||||
This should be a 16x16 unit trigger with an origin brush placed so that it's center lies on the bottom plane of the trigger.
|
||||
Must be in the level somewhere. This is the trigger that is used when defusing a bomb.
|
||||
It gets moved to the position of the planted bomb model.
|
||||
|
||||
Level script requirements
|
||||
-------------------------
|
||||
Team Definitions:
|
||||
game["attackers"] = "allies";
|
||||
game["defenders"] = "axis";
|
||||
This sets which team is attacking and which team is defending. Attackers plant the bombs. Defenders protect the targets.
|
||||
|
||||
Exploder Effects:
|
||||
Setting script_noteworthy on a bombzone trigger to an exploder group can be used to trigger additional effects.
|
||||
*/
|
||||
|
||||
/*QUAKED mp_sd_spawn_attacker (0.0 1.0 0.0) (-16 -16 0) (16 16 72)
|
||||
Attacking players spawn randomly at one of these positions at the beginning of a round.*/
|
||||
|
||||
/*QUAKED mp_sd_spawn_defender (1.0 0.0 0.0) (-16 -16 0) (16 16 72)
|
||||
Defending players spawn randomly at one of these positions at the beginning of a round.*/
|
||||
|
||||
main()
|
||||
{
|
||||
if(getdvar("mapname") == "mp_background")
|
||||
return;
|
||||
|
||||
maps\mp\gametypes\_globallogic::init();
|
||||
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
|
||||
maps\mp\gametypes\_globallogic::SetupCallbacks();
|
||||
|
||||
registerRoundSwitchDvar( level.gameType, 3, 0, 9 );
|
||||
registerTimeLimitDvar( level.gameType, 2.5, 0, 1440 );
|
||||
registerScoreLimitDvar( level.gameType, 1, 0, 500 );
|
||||
registerRoundLimitDvar( level.gameType, 0, 0, 12 );
|
||||
registerWinLimitDvar( level.gameType, 4, 0, 12 );
|
||||
registerNumLivesDvar( level.gameType, 1, 0, 10 );
|
||||
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
|
||||
|
||||
level.objectiveBased = true;
|
||||
level.teamBased = true;
|
||||
level.onPrecacheGameType = ::onPrecacheGameType;
|
||||
level.onStartGameType = ::onStartGameType;
|
||||
level.getSpawnPoint = ::getSpawnPoint;
|
||||
level.onSpawnPlayer = ::onSpawnPlayer;
|
||||
level.onPlayerKilled = ::onPlayerKilled;
|
||||
level.onDeadEvent = ::onDeadEvent;
|
||||
level.onOneLeftEvent = ::onOneLeftEvent;
|
||||
level.onTimeLimit = ::onTimeLimit;
|
||||
level.onNormalDeath = ::onNormalDeath;
|
||||
level.initGametypeAwards = ::initGametypeAwards;
|
||||
|
||||
game["dialog"]["gametype"] = "searchdestroy";
|
||||
|
||||
if ( getDvarInt( "g_hardcore" ) )
|
||||
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "camera_thirdPerson" ) )
|
||||
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
|
||||
else if ( getDvarInt( "scr_diehard" ) )
|
||||
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
|
||||
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
|
||||
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
|
||||
|
||||
game["dialog"]["offense_obj"] = "obj_destroy";
|
||||
game["dialog"]["defense_obj"] = "obj_defend";
|
||||
}
|
||||
|
||||
|
||||
onPrecacheGameType()
|
||||
{
|
||||
game["bomb_dropped_sound"] = "mp_war_objective_lost";
|
||||
game["bomb_recovered_sound"] = "mp_war_objective_taken";
|
||||
|
||||
precacheShader("waypoint_bomb");
|
||||
precacheShader("hud_suitcase_bomb");
|
||||
precacheShader("waypoint_target");
|
||||
precacheShader("waypoint_target_a");
|
||||
precacheShader("waypoint_target_b");
|
||||
precacheShader("waypoint_defend");
|
||||
precacheShader("waypoint_defend_a");
|
||||
precacheShader("waypoint_defend_b");
|
||||
precacheShader("waypoint_defuse");
|
||||
precacheShader("waypoint_defuse_a");
|
||||
precacheShader("waypoint_defuse_b");
|
||||
precacheShader("waypoint_escort");
|
||||
/*
|
||||
precacheShader("waypoint_target");
|
||||
precacheShader("waypoint_target_a");
|
||||
precacheShader("waypoint_target_b");
|
||||
precacheShader("waypoint_defend");
|
||||
precacheShader("waypoint_defend_a");
|
||||
precacheShader("waypoint_defend_b");
|
||||
precacheShader("waypoint_defuse");
|
||||
precacheShader("waypoint_defuse_a");
|
||||
precacheShader("waypoint_defuse_b");
|
||||
*/
|
||||
precacheString( &"MP_EXPLOSIVES_RECOVERED_BY" );
|
||||
precacheString( &"MP_EXPLOSIVES_DROPPED_BY" );
|
||||
precacheString( &"MP_EXPLOSIVES_PLANTED_BY" );
|
||||
precacheString( &"MP_EXPLOSIVES_DEFUSED_BY" );
|
||||
precacheString( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
|
||||
precacheString( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
|
||||
precacheString( &"MP_CANT_PLANT_WITHOUT_BOMB" );
|
||||
precacheString( &"MP_PLANTING_EXPLOSIVE" );
|
||||
precacheString( &"MP_DEFUSING_EXPLOSIVE" );
|
||||
}
|
||||
|
||||
|
||||
onStartGameType()
|
||||
{
|
||||
if ( !isDefined( game["switchedsides"] ) )
|
||||
game["switchedsides"] = false;
|
||||
|
||||
if ( game["switchedsides"] )
|
||||
{
|
||||
oldAttackers = game["attackers"];
|
||||
oldDefenders = game["defenders"];
|
||||
game["attackers"] = oldDefenders;
|
||||
game["defenders"] = oldAttackers;
|
||||
}
|
||||
|
||||
setClientNameMode( "manual_change" );
|
||||
|
||||
game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
|
||||
game["strings"]["bomb_defused"] = &"MP_BOMB_DEFUSED";
|
||||
|
||||
precacheString( game["strings"]["target_destroyed"] );
|
||||
precacheString( game["strings"]["bomb_defused"] );
|
||||
|
||||
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
|
||||
|
||||
setObjectiveText( game["attackers"], &"OBJECTIVES_SD_ATTACKER" );
|
||||
setObjectiveText( game["defenders"], &"OBJECTIVES_SD_DEFENDER" );
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_SD_ATTACKER" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_SD_DEFENDER" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_SD_ATTACKER_SCORE" );
|
||||
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_SD_DEFENDER_SCORE" );
|
||||
}
|
||||
setObjectiveHintText( game["attackers"], &"OBJECTIVES_SD_ATTACKER_HINT" );
|
||||
setObjectiveHintText( game["defenders"], &"OBJECTIVES_SD_DEFENDER_HINT" );
|
||||
|
||||
level.spawnMins = ( 0, 0, 0 );
|
||||
level.spawnMaxs = ( 0, 0, 0 );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sd_spawn_attacker" );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sd_spawn_defender" );
|
||||
|
||||
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
|
||||
setMapCenter( level.mapCenter );
|
||||
|
||||
allowed[0] = "sd";
|
||||
allowed[1] = "bombzone";
|
||||
allowed[2] = "blocker";
|
||||
maps\mp\gametypes\_gameobjects::main(allowed);
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "win", 2 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "loss", 1 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "tie", 1.5 );
|
||||
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "plant", 100 );
|
||||
maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 100 );
|
||||
|
||||
thread updateGametypeDvars();
|
||||
|
||||
thread bombs();
|
||||
}
|
||||
|
||||
|
||||
getSpawnPoint()
|
||||
{
|
||||
if(self.pers["team"] == game["attackers"])
|
||||
spawnPointName = "mp_sd_spawn_attacker";
|
||||
else
|
||||
spawnPointName = "mp_sd_spawn_defender";
|
||||
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( spawnPointName );
|
||||
assert( spawnPoints.size );
|
||||
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
|
||||
|
||||
return spawnpoint;
|
||||
}
|
||||
|
||||
onSpawnPlayer()
|
||||
{
|
||||
self.isPlanting = false;
|
||||
self.isDefusing = false;
|
||||
self.isBombCarrier = false;
|
||||
|
||||
if ( level.multiBomb && !isDefined( self.carryIcon ) && self.pers["team"] == game["attackers"] && !level.bombPlanted )
|
||||
{
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
self.carryIcon = createIcon( "hud_suitcase_bomb", 33, 33 );
|
||||
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", 0, -78 );
|
||||
self.carryIcon.alpha = 0.75;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.carryIcon = createIcon( "hud_suitcase_bomb", 50, 50 );
|
||||
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -90, -65 );
|
||||
self.carryIcon.alpha = 0.75;
|
||||
}
|
||||
}
|
||||
|
||||
level notify ( "spawned_player" );
|
||||
}
|
||||
|
||||
|
||||
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
|
||||
{
|
||||
thread checkAllowSpectating();
|
||||
}
|
||||
|
||||
|
||||
checkAllowSpectating()
|
||||
{
|
||||
wait ( 0.05 );
|
||||
|
||||
update = false;
|
||||
if ( !level.aliveCount[ game["attackers"] ] )
|
||||
{
|
||||
level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
|
||||
update = true;
|
||||
}
|
||||
if ( !level.aliveCount[ game["defenders"] ] )
|
||||
{
|
||||
level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
|
||||
update = true;
|
||||
}
|
||||
if ( update )
|
||||
maps\mp\gametypes\_spectating::updateSpectateSettings();
|
||||
}
|
||||
|
||||
|
||||
sd_endGame( winningTeam, endReasonText )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
|
||||
}
|
||||
|
||||
|
||||
onDeadEvent( team )
|
||||
{
|
||||
if ( level.bombExploded || level.bombDefused )
|
||||
return;
|
||||
|
||||
if ( team == "all" )
|
||||
{
|
||||
if ( level.bombPlanted )
|
||||
sd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
|
||||
else
|
||||
sd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
|
||||
}
|
||||
else if ( team == game["attackers"] )
|
||||
{
|
||||
if ( level.bombPlanted )
|
||||
return;
|
||||
|
||||
level thread sd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
|
||||
}
|
||||
else if ( team == game["defenders"] )
|
||||
{
|
||||
level thread sd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onOneLeftEvent( team )
|
||||
{
|
||||
if ( level.bombExploded || level.bombDefused )
|
||||
return;
|
||||
|
||||
lastPlayer = getLastLivingPlayer( team );
|
||||
|
||||
lastPlayer thread giveLastOnTeamWarning();
|
||||
}
|
||||
|
||||
|
||||
onNormalDeath( victim, attacker, lifeId )
|
||||
{
|
||||
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
|
||||
assert( isDefined( score ) );
|
||||
|
||||
team = victim.team;
|
||||
|
||||
if ( game["state"] == "postgame" && (victim.team == game["defenders"] || !level.bombPlanted) )
|
||||
attacker.finalKill = true;
|
||||
|
||||
if ( victim.isPlanting )
|
||||
{
|
||||
thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
|
||||
}
|
||||
else if ( victim.isBombCarrier )
|
||||
{
|
||||
attacker incPlayerStat( "bombcarrierkills", 1 );
|
||||
thread maps\mp\_matchdata::logKillEvent( lifeId, "carrying" );
|
||||
}
|
||||
else if ( victim.isDefusing )
|
||||
{
|
||||
thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
|
||||
}
|
||||
|
||||
if ( attacker.isBombCarrier )
|
||||
attacker incPlayerStat( "killsasbombcarrier", 1 );
|
||||
}
|
||||
|
||||
|
||||
giveLastOnTeamWarning()
|
||||
{
|
||||
self endon("death");
|
||||
self endon("disconnect");
|
||||
level endon( "game_ended" );
|
||||
|
||||
self waitTillRecoveredHealth( 3 );
|
||||
|
||||
otherTeam = getOtherTeam( self.pers["team"] );
|
||||
level thread teamPlayerCardSplash( "callout_lastteammemberalive", self, self.pers["team"] );
|
||||
level thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
|
||||
level notify ( "last_alive", self );
|
||||
self maps\mp\gametypes\_missions::lastManSD();
|
||||
}
|
||||
|
||||
|
||||
onTimeLimit()
|
||||
{
|
||||
sd_endGame( game["defenders"], game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
|
||||
|
||||
updateGametypeDvars()
|
||||
{
|
||||
level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
|
||||
level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
|
||||
level.bombTimer = dvarFloatValue( "bombtimer", 45, 1, 300 );
|
||||
level.multiBomb = dvarIntValue( "multibomb", 0, 0, 1 );
|
||||
}
|
||||
|
||||
|
||||
bombs()
|
||||
{
|
||||
level.bombPlanted = false;
|
||||
level.bombDefused = false;
|
||||
level.bombExploded = false;
|
||||
|
||||
trigger = getEnt( "sd_bomb_pickup_trig", "targetname" );
|
||||
if ( !isDefined( trigger ) )
|
||||
{
|
||||
error("No sd_bomb_pickup_trig trigger found in map.");
|
||||
return;
|
||||
}
|
||||
|
||||
visuals[0] = getEnt( "sd_bomb", "targetname" );
|
||||
if ( !isDefined( visuals[0] ) )
|
||||
{
|
||||
error("No sd_bomb script_model found in map.");
|
||||
return;
|
||||
}
|
||||
|
||||
precacheModel( "prop_suitcase_bomb" );
|
||||
visuals[0] setModel( "prop_suitcase_bomb" );
|
||||
|
||||
if ( !level.multiBomb )
|
||||
{
|
||||
level.sdBomb = maps\mp\gametypes\_gameobjects::createCarryObject( game["attackers"], trigger, visuals, (0,0,32) );
|
||||
level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "friendly" );
|
||||
level.sdBomb maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
|
||||
level.sdBomb maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
|
||||
level.sdBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
|
||||
level.sdBomb maps\mp\gametypes\_gameobjects::setCarryIcon( "hud_suitcase_bomb" );
|
||||
level.sdBomb.allowWeapons = true;
|
||||
level.sdBomb.onPickup = ::onPickup;
|
||||
level.sdBomb.onDrop = ::onDrop;
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger delete();
|
||||
visuals[0] delete();
|
||||
}
|
||||
|
||||
|
||||
level.bombZones = [];
|
||||
|
||||
bombZones = getEntArray( "bombzone", "targetname" );
|
||||
|
||||
for ( index = 0; index < bombZones.size; index++ )
|
||||
{
|
||||
trigger = bombZones[index];
|
||||
visuals = getEntArray( bombZones[index].target, "targetname" );
|
||||
|
||||
bombZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,64) );
|
||||
bombZone maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
|
||||
bombZone maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
|
||||
bombZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
|
||||
bombZone maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
|
||||
if ( !level.multiBomb )
|
||||
bombZone maps\mp\gametypes\_gameobjects::setKeyObject( level.sdBomb );
|
||||
label = bombZone maps\mp\gametypes\_gameobjects::getLabel();
|
||||
bombZone.label = label;
|
||||
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
|
||||
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
|
||||
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + label );
|
||||
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + label );
|
||||
bombZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
bombZone.onBeginUse = ::onBeginUse;
|
||||
bombZone.onEndUse = ::onEndUse;
|
||||
bombZone.onUse = ::onUsePlantObject;
|
||||
bombZone.onCantUse = ::onCantUse;
|
||||
bombZone.useWeapon = "briefcase_bomb_mp";
|
||||
|
||||
for ( i = 0; i < visuals.size; i++ )
|
||||
{
|
||||
if ( isDefined( visuals[i].script_exploder ) )
|
||||
{
|
||||
bombZone.exploderIndex = visuals[i].script_exploder;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
level.bombZones[level.bombZones.size] = bombZone;
|
||||
|
||||
bombZone.bombDefuseTrig = getent( visuals[0].target, "targetname" );
|
||||
assert( isdefined( bombZone.bombDefuseTrig ) );
|
||||
bombZone.bombDefuseTrig.origin += (0,0,-10000);
|
||||
bombZone.bombDefuseTrig.label = label;
|
||||
}
|
||||
|
||||
for ( index = 0; index < level.bombZones.size; index++ )
|
||||
{
|
||||
array = [];
|
||||
for ( otherindex = 0; otherindex < level.bombZones.size; otherindex++ )
|
||||
{
|
||||
if ( otherindex != index )
|
||||
array[ array.size ] = level.bombZones[otherindex];
|
||||
}
|
||||
level.bombZones[index].otherBombZones = array;
|
||||
}
|
||||
}
|
||||
|
||||
onBeginUse( player )
|
||||
{
|
||||
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
|
||||
{
|
||||
player playSound( "mp_bomb_defuse" );
|
||||
player.isDefusing = true;
|
||||
|
||||
if ( isDefined( level.sdBombModel ) )
|
||||
level.sdBombModel hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
player.isPlanting = true;
|
||||
|
||||
if ( level.multibomb )
|
||||
{
|
||||
for ( i = 0; i < self.otherBombZones.size; i++ )
|
||||
{
|
||||
//self.otherBombZones[i] maps\mp\gametypes\_gameobjects::disableObject();
|
||||
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onEndUse( team, player, result )
|
||||
{
|
||||
if ( !isDefined( player ) )
|
||||
return;
|
||||
|
||||
if ( isAlive( player ) )
|
||||
{
|
||||
player.isDefusing = false;
|
||||
player.isPlanting = false;
|
||||
}
|
||||
|
||||
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
|
||||
{
|
||||
if ( isDefined( level.sdBombModel ) && !result )
|
||||
{
|
||||
level.sdBombModel show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.multibomb && !result )
|
||||
{
|
||||
for ( i = 0; i < self.otherBombZones.size; i++ )
|
||||
{
|
||||
//self.otherBombZones[i] maps\mp\gametypes\_gameobjects::enableObject();
|
||||
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
|
||||
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onCantUse( player )
|
||||
{
|
||||
player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
|
||||
}
|
||||
|
||||
onUsePlantObject( player )
|
||||
{
|
||||
// planted the bomb
|
||||
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
|
||||
{
|
||||
level thread bombPlanted( self, player );
|
||||
//player logString( "bomb planted: " + self.label );
|
||||
|
||||
// disable all bomb zones except this one
|
||||
for ( index = 0; index < level.bombZones.size; index++ )
|
||||
{
|
||||
if ( level.bombZones[index] == self )
|
||||
continue;
|
||||
|
||||
level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
|
||||
}
|
||||
|
||||
player playSound( "mp_bomb_plant" );
|
||||
player notify ( "bomb_planted" );
|
||||
|
||||
//if ( !level.hardcoreMode )
|
||||
// iPrintLn( &"MP_EXPLOSIVES_PLANTED_BY", player );
|
||||
|
||||
leaderDialog( "bomb_planted" );
|
||||
|
||||
level thread teamPlayerCardSplash( "callout_bombplanted", player );
|
||||
|
||||
level.bombOwner = player;
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
|
||||
player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
|
||||
player.bombPlantedTime = getTime();
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
|
||||
player incPlayerStat( "bombsplanted", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
|
||||
}
|
||||
}
|
||||
|
||||
onUseDefuseObject( player )
|
||||
{
|
||||
player notify ( "bomb_defused" );
|
||||
//player logString( "bomb defused: " + self.label );
|
||||
level thread bombDefused();
|
||||
|
||||
// disable this bomb zone
|
||||
self maps\mp\gametypes\_gameobjects::disableObject();
|
||||
|
||||
//if ( !level.hardcoreMode )
|
||||
// iPrintLn( &"MP_EXPLOSIVES_DEFUSED_BY", player );
|
||||
leaderDialog( "bomb_defused" );
|
||||
|
||||
level thread teamPlayerCardSplash( "callout_bombdefused", player );
|
||||
|
||||
if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 3000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
|
||||
else
|
||||
player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
|
||||
|
||||
player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
|
||||
maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
|
||||
player incPlayerStat( "bombsdefused", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origin );
|
||||
}
|
||||
|
||||
|
||||
onDrop( player )
|
||||
{
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
|
||||
|
||||
maps\mp\_utility::playSoundOnPlayers( game["bomb_dropped_sound"], game["attackers"] );
|
||||
}
|
||||
|
||||
|
||||
onPickup( player )
|
||||
{
|
||||
player.isBombCarrier = true;
|
||||
player incPlayerStat( "bombscarried", 1 );
|
||||
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
|
||||
|
||||
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_escort" );
|
||||
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_escort" );
|
||||
|
||||
if ( !level.bombDefused )
|
||||
{
|
||||
teamPlayerCardSplash( "callout_bombtaken", player, player.team );
|
||||
leaderDialog( "bomb_taken", player.pers["team"] );
|
||||
}
|
||||
maps\mp\_utility::playSoundOnPlayers( game["bomb_recovered_sound"], game["attackers"] );
|
||||
}
|
||||
|
||||
|
||||
onReset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bombPlanted( destroyedObj, player )
|
||||
{
|
||||
maps\mp\gametypes\_gamelogic::pauseTimer();
|
||||
level.bombPlanted = true;
|
||||
|
||||
destroyedObj.visuals[0] thread maps\mp\gametypes\_gamelogic::playTickingSound();
|
||||
level.tickingObject = destroyedObj.visuals[0];
|
||||
|
||||
level.timeLimitOverride = true;
|
||||
setGameEndTime( int( gettime() + (level.bombTimer * 1000) ) );
|
||||
setDvar( "ui_bomb_timer", 1 );
|
||||
|
||||
if ( !level.multiBomb )
|
||||
{
|
||||
level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "none" );
|
||||
level.sdBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
level.sdBomb maps\mp\gametypes\_gameobjects::setDropped();
|
||||
level.sdBombModel = level.sdBomb.visuals[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
for ( index = 0; index < level.players.size; index++ )
|
||||
{
|
||||
if ( isDefined( level.players[index].carryIcon ) )
|
||||
level.players[index].carryIcon destroyElem();
|
||||
}
|
||||
|
||||
trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000), false, player );
|
||||
|
||||
tempAngle = randomfloat( 360 );
|
||||
forward = (cos( tempAngle ), sin( tempAngle ), 0);
|
||||
forward = vectornormalize( forward - common_scripts\utility::vector_multiply( trace["normal"], vectordot( forward, trace["normal"] ) ) );
|
||||
dropAngles = vectortoangles( forward );
|
||||
|
||||
level.sdBombModel = spawn( "script_model", trace["position"] );
|
||||
level.sdBombModel.angles = dropAngles;
|
||||
level.sdBombModel setModel( "prop_suitcase_bomb" );
|
||||
}
|
||||
destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" );
|
||||
destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
/*
|
||||
destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", undefined );
|
||||
destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", undefined );
|
||||
destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", undefined );
|
||||
destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", undefined );
|
||||
*/
|
||||
label = destroyedObj maps\mp\gametypes\_gameobjects::getLabel();
|
||||
|
||||
// create a new object to defuse with.
|
||||
trigger = destroyedObj.bombDefuseTrig;
|
||||
trigger.origin = level.sdBombModel.origin;
|
||||
visuals = [];
|
||||
defuseObject = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,32) );
|
||||
defuseObject maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
|
||||
defuseObject maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
|
||||
defuseObject maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
|
||||
defuseObject maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
|
||||
defuseObject maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
|
||||
defuseObject maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" + label );
|
||||
defuseObject maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" + label );
|
||||
defuseObject maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" + label );
|
||||
defuseObject maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" + label );
|
||||
defuseObject.label = label;
|
||||
defuseObject.onBeginUse = ::onBeginUse;
|
||||
defuseObject.onEndUse = ::onEndUse;
|
||||
defuseObject.onUse = ::onUseDefuseObject;
|
||||
defuseObject.useWeapon = "briefcase_bomb_defuse_mp";
|
||||
|
||||
BombTimerWait();
|
||||
setDvar( "ui_bomb_timer", 0 );
|
||||
|
||||
destroyedObj.visuals[0] maps\mp\gametypes\_gamelogic::stopTickingSound();
|
||||
|
||||
if ( level.gameEnded || level.bombDefused )
|
||||
return;
|
||||
|
||||
level.bombExploded = true;
|
||||
|
||||
explosionOrigin = level.sdBombModel.origin;
|
||||
level.sdBombModel hide();
|
||||
|
||||
if ( isdefined( player ) )
|
||||
{
|
||||
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player );
|
||||
player incPlayerStat( "targetsdestroyed", 1 );
|
||||
}
|
||||
else
|
||||
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
|
||||
|
||||
rot = randomfloat(360);
|
||||
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
|
||||
triggerFx( explosionEffect );
|
||||
|
||||
PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
|
||||
earthquake( 0.75, 2.0, explosionOrigin, 2000 );
|
||||
|
||||
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
|
||||
|
||||
if ( isDefined( destroyedObj.exploderIndex ) )
|
||||
exploder( destroyedObj.exploderIndex );
|
||||
|
||||
for ( index = 0; index < level.bombZones.size; index++ )
|
||||
level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
|
||||
defuseObject maps\mp\gametypes\_gameobjects::disableObject();
|
||||
|
||||
setGameEndTime( 0 );
|
||||
|
||||
wait 3;
|
||||
|
||||
sd_endGame( game["attackers"], game["strings"]["target_destroyed"] );
|
||||
}
|
||||
|
||||
BombTimerWait()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
level endon( "bomb_defused" );
|
||||
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( level.bombTimer );
|
||||
}
|
||||
|
||||
|
||||
bombDefused()
|
||||
{
|
||||
level.tickingObject maps\mp\gametypes\_gamelogic::stopTickingSound();
|
||||
level.bombDefused = true;
|
||||
setDvar( "ui_bomb_timer", 0 );
|
||||
|
||||
level notify("bomb_defused");
|
||||
|
||||
wait 1.5;
|
||||
|
||||
setGameEndTime( 0 );
|
||||
|
||||
sd_endGame( game["defenders"], game["strings"]["bomb_defused"] );
|
||||
}
|
||||
|
||||
initGametypeAwards()
|
||||
{
|
||||
maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
|
||||
maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
|
||||
}
|
||||
@@ -0,0 +1,447 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
/*
|
||||
VIP
|
||||
Objective: Escort the VIP to safety, or eliminate the VIP beofore he reaches extraction
|
||||
Map ends: When one team eliminates the enemy team, or the flag is reached
|
||||
Respawning: Beginning of next round
|
||||
|
||||
Level requirementss
|
||||
------------------
|
||||
Spawnpoints:
|
||||
classname mp_tdm_spawn
|
||||
|
||||
|
||||
Spectator Spawnpoints:
|
||||
classname mp_global_intermission
|
||||
*/
|
||||
|
||||
main()
|
||||
{
|
||||
if(getdvar("mapname") == "mp_background")
|
||||
return;
|
||||
|
||||
maps\mp\gametypes\_globallogic::init();
|
||||
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
|
||||
maps\mp\gametypes\_globallogic::SetupCallbacks();
|
||||
|
||||
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
|
||||
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
|
||||
registerScoreLimitDvar( level.gameType, 500, 0, 5000 );
|
||||
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
|
||||
registerWinLimitDvar( level.gameType, 1, 0, 10 );
|
||||
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
|
||||
registerNumLivesDvar( level.gameType, 1, 0, 10 );
|
||||
registerWatchDvarInt( "halftime", 0 );
|
||||
|
||||
level.teamBased = true;
|
||||
level.objectiveBased = true;
|
||||
|
||||
level.onPrecacheGameType = ::onPrecacheGameType;
|
||||
level.onStartGameType = ::onStartGameType;
|
||||
level.getSpawnPoint = ::getSpawnPoint;
|
||||
level.onSpawnPlayer = ::onSpawnPlayer;
|
||||
level.onNormalDeath = ::onNormalDeath;
|
||||
level.onPlayerKilled = ::onPlayerKilled;
|
||||
level.onDeadEvent = ::onDeadEvent;
|
||||
|
||||
game["dialog"]["gametype"] = "VIP";
|
||||
}
|
||||
|
||||
onPrecacheGameType()
|
||||
{
|
||||
precacheShader( "compass_waypoint_captureneutral" );
|
||||
precacheShader( "compass_waypoint_capture" );
|
||||
precacheShader( "compass_waypoint_defend" );
|
||||
|
||||
precacheShader( "waypoint_captureneutral" );
|
||||
precacheShader( "waypoint_capture" );
|
||||
precacheShader( "waypoint_defend" );
|
||||
|
||||
precacheString( &"MP_ELIMINATED_VIP" );
|
||||
precacheString( &"MP_DEFENDED_VIP" );
|
||||
precacheString( &"SPLASHES_VIP" );
|
||||
|
||||
game["flagmodels"] = [];
|
||||
game["flagmodels"]["neutral"] = "prop_flag_neutral";
|
||||
|
||||
game["flagmodels"]["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
|
||||
game["flagmodels"]["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
|
||||
|
||||
precacheModel( game["flagmodels"]["neutral"] );
|
||||
precacheModel( game["flagmodels"]["allies"] );
|
||||
precacheModel( game["flagmodels"]["axis"] );
|
||||
|
||||
}
|
||||
|
||||
onStartGameType()
|
||||
{
|
||||
setClientNameMode("auto_change");
|
||||
|
||||
if ( !isdefined( game["switchedsides"] ) )
|
||||
game["switchedsides"] = false;
|
||||
|
||||
if ( game["switchedsides"] )
|
||||
{
|
||||
oldAttackers = game["attackers"];
|
||||
oldDefenders = game["defenders"];
|
||||
game["attackers"] = oldDefenders;
|
||||
game["defenders"] = oldAttackers;
|
||||
}
|
||||
|
||||
setObjectiveText( "allies", &"OBJECTIVES_VIP" );
|
||||
setObjectiveText( "axis", &"OBJECTIVES_VIP" );
|
||||
|
||||
if ( level.splitscreen )
|
||||
{
|
||||
setObjectiveScoreText( "allies", &"OBJECTIVES_VIP" );
|
||||
setObjectiveScoreText( "axis", &"OBJECTIVES_VIP" );
|
||||
}
|
||||
else
|
||||
{
|
||||
setObjectiveScoreText( "allies", &"OBJECTIVES_VIP_SCORE" );
|
||||
setObjectiveScoreText( "axis", &"OBJECTIVES_VIP_SCORE" );
|
||||
}
|
||||
setObjectiveHintText( "allies", &"OBJECTIVES_VIP_HINT" );
|
||||
setObjectiveHintText( "axis", &"OBJECTIVES_VIP_HINT" );
|
||||
|
||||
level.spawnMins = ( 0, 0, 0 );
|
||||
level.spawnMaxs = ( 0, 0, 0 );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
|
||||
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
|
||||
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
|
||||
|
||||
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
|
||||
setMapCenter( level.mapCenter );
|
||||
|
||||
allowed[0] = "vip";
|
||||
allowed[1] = "sd";
|
||||
//maps\mp\gametypes\_rank::registerScoreInfo( "capture", 200 );
|
||||
|
||||
maps\mp\gametypes\_gameobjects::main(allowed);
|
||||
|
||||
self thread waitToProcess();
|
||||
}
|
||||
|
||||
waitToProcess()
|
||||
{
|
||||
level endon( "game_end" );
|
||||
level endon( "waitSkipped" );
|
||||
|
||||
self thread extractionZone();
|
||||
self thread skipWait();
|
||||
|
||||
gameFlagWait( "prematch_done" );
|
||||
gameFlagWait( "graceperiod_done" );
|
||||
self notify( "graceComplete" );
|
||||
|
||||
self thread vipSelection();
|
||||
}
|
||||
|
||||
skipWait()
|
||||
{
|
||||
self endon( "graceComplete" );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if( level.players.size > 2 )
|
||||
break;
|
||||
|
||||
wait( .5 );
|
||||
}
|
||||
|
||||
self notify( "waitSkipped" );
|
||||
self thread vipSelection();
|
||||
|
||||
}
|
||||
|
||||
getSpawnPoint()
|
||||
{
|
||||
spawnteam = self.pers["team"];
|
||||
if ( game["switchedsides"] )
|
||||
spawnteam = getOtherTeam( spawnteam );
|
||||
|
||||
if ( level.inGracePeriod )
|
||||
{
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + spawnteam + "_start" );
|
||||
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
|
||||
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
|
||||
}
|
||||
|
||||
return spawnPoint;
|
||||
}
|
||||
|
||||
onSpawnPlayer()
|
||||
{
|
||||
self.isVip = false;
|
||||
self.usingObj = undefined;
|
||||
level notify ( "spawned_player" );
|
||||
}
|
||||
|
||||
onNormalDeath( victim, attacker, lifeId )
|
||||
{
|
||||
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
|
||||
assert( isDefined( score ) );
|
||||
|
||||
attacker maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( attacker.pers["team"], score );
|
||||
|
||||
team = victim.team;
|
||||
|
||||
if ( isDefined( victim.isVip ) && victim.isVip )
|
||||
{
|
||||
level thread vip_endGame( game["attackers"], &"MP_ELIMINATED_VIP" );
|
||||
attacker.finalKill = true;
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
|
||||
{
|
||||
thread checkAllowSpectating();
|
||||
}
|
||||
|
||||
onTimeLimit()
|
||||
{
|
||||
if ( game["status"] == "overtime" )
|
||||
{
|
||||
winner = "forfeit";
|
||||
}
|
||||
else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
|
||||
{
|
||||
winner = "overtime";
|
||||
}
|
||||
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
|
||||
{
|
||||
winner = "axis";
|
||||
}
|
||||
else
|
||||
{
|
||||
winner = "allies";
|
||||
}
|
||||
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( winner, game["strings"]["time_limit_reached"] );
|
||||
}
|
||||
|
||||
checkAllowSpectating()
|
||||
{
|
||||
wait ( 0.05 );
|
||||
|
||||
update = false;
|
||||
if ( !level.aliveCount[ game["attackers"] ] )
|
||||
{
|
||||
level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
|
||||
update = true;
|
||||
}
|
||||
if ( !level.aliveCount[ game["defenders"] ] )
|
||||
{
|
||||
level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
|
||||
update = true;
|
||||
}
|
||||
if ( update )
|
||||
maps\mp\gametypes\_spectating::updateSpectateSettings();
|
||||
}
|
||||
|
||||
onDeadEvent( team )
|
||||
{
|
||||
if ( team == game["attackers"] )
|
||||
{
|
||||
level thread vip_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
|
||||
}
|
||||
else if ( team == game["defenders"] )
|
||||
{
|
||||
level thread vip_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
|
||||
}
|
||||
}
|
||||
|
||||
vip_endGame( winningTeam, endReasonText )
|
||||
{
|
||||
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
|
||||
}
|
||||
|
||||
vipSelection()
|
||||
{
|
||||
println( "SELECTION" );
|
||||
potentialVIPs = [];
|
||||
abortTime = 0;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if ( level.players.size >= 2 )
|
||||
break;
|
||||
|
||||
if ( abortTime >= 100 )
|
||||
{
|
||||
iPrintlnBold( "Game mode only playable with 2 or more players" );
|
||||
wait( 2 );
|
||||
maps\mp\gametypes\_callbacksetup::AbortLevel();
|
||||
}
|
||||
|
||||
abortTime++;
|
||||
wait( .1 );
|
||||
}
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( player.team == game["defenders"] )
|
||||
potentialVIPs[ potentialVIPs.size ] = player;
|
||||
}
|
||||
|
||||
selectedVIPNum = RandomIntRange( 0, potentialVIPs.size );
|
||||
selectedPlayer = potentialVIPs[ selectedVIPNum ];
|
||||
|
||||
if ( !isAlive(selectedPlayer ) && !isSubStr( selectedPlayer.guid, "bot" ) )
|
||||
selectedPlayer forceVIPSpawn();
|
||||
|
||||
setupVip( selectedPlayer );
|
||||
}
|
||||
|
||||
setupVip ( vipPlayer )
|
||||
{
|
||||
vipPlayer TakeAllWeapons();
|
||||
vipPlayer _clearPerks();
|
||||
|
||||
vipPlayer.isVip = true;
|
||||
|
||||
vipPlayer giveWeapon( "deserteagle_fmj_mp" );
|
||||
vipPlayer giveStartAmmo( "deserteagle_fmj_mp" );
|
||||
|
||||
vipPlayer giveWeapon( "riotshield_mp" );
|
||||
vipPlayer switchToWeapon( "riotshield_mp" );
|
||||
|
||||
vipPlayer _setPerk( "specialty_armorvest" );
|
||||
vipPlayer _setPerk( "specialty_finalstand" );
|
||||
|
||||
vipPlayer iPrintlnBold( "You Are the VIP" );
|
||||
//TO DO: add defend icon on the VIP
|
||||
}
|
||||
|
||||
extractionZone()
|
||||
{
|
||||
extractionZone = getEntArray("extraction_vip", "targetname");
|
||||
|
||||
// check to see if zone is available.
|
||||
if ( !isDefined( extractionZone ) )
|
||||
{
|
||||
println("WARNING: no extraction zone specified" );
|
||||
|
||||
printLn( "^1Not enough extraction zones found in level!" );
|
||||
maps\mp\gametypes\_callbacksetup::AbortLevel();
|
||||
return;
|
||||
}
|
||||
else
|
||||
level.extractionZone = extractionZone;
|
||||
|
||||
trigger = level.extractionZone[0];
|
||||
if ( isDefined( trigger.target ) )
|
||||
{
|
||||
visuals[0] = getEnt( trigger.target, "targetname" );
|
||||
}
|
||||
else
|
||||
{
|
||||
visuals[0] = spawn( "script_model", trigger.origin );
|
||||
visuals[0].angles = trigger.angles;
|
||||
}
|
||||
|
||||
extractionZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,100) );
|
||||
extractionZone maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
|
||||
extractionZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
|
||||
extractionZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_CALLING_EXTRACTION" );
|
||||
extractionZone maps\mp\gametypes\_gameobjects::setUseTime( 0 );
|
||||
|
||||
extractionZone.onUse = ::onUse;
|
||||
extractionZone.onCantUse = ::onCantUse;
|
||||
|
||||
traceStart = trigger.origin + (0,0,32);
|
||||
traceEnd = trigger.origin + (0,0,-32);
|
||||
trace = bulletTrace( traceStart, traceEnd, false, undefined );
|
||||
|
||||
fx = maps\mp\gametypes\_teams::getTeamFlagFX( game["defenders"] );
|
||||
fxid = loadfx( fx );
|
||||
|
||||
upangles = vectorToAngles( trace["normal"] );
|
||||
forward = anglesToForward( upangles );
|
||||
right = anglesToRight( upangles );
|
||||
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
|
||||
|
||||
extractionZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
|
||||
extractionZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend");
|
||||
extractionZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
|
||||
|
||||
level.extractionZone = extractionZone;
|
||||
}
|
||||
|
||||
setVIPUse()
|
||||
{
|
||||
foreach (player in level.players)
|
||||
{
|
||||
if ( ! player.isVip )
|
||||
self.trigger disablePlayerUse(player);
|
||||
}
|
||||
}
|
||||
|
||||
onUse( player )
|
||||
{
|
||||
if ( !isDefined( player.isVip ) || ! player.isVip )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
iPrintlnBold( "Extraction on its way" );
|
||||
self handleTimer( player );
|
||||
}
|
||||
|
||||
handleTimer( player )
|
||||
{
|
||||
player endon( "death" );
|
||||
level endon( "game_end" );
|
||||
|
||||
level.extractionTime = 45;
|
||||
maps\mp\gametypes\_gamelogic::pauseTimer();
|
||||
level.timeLimitOverride = true;
|
||||
setGameEndTime( int( getTime() + (level.extractionTime * 1000) ) );
|
||||
wait level.extractionTime;
|
||||
|
||||
//call the sentry airdrops
|
||||
level thread vip_endGame( game["defenders"], &"MP_DEFENDED_VIP" );
|
||||
}
|
||||
|
||||
onEndUse( team, player, success )
|
||||
{
|
||||
println( "End Use" );
|
||||
}
|
||||
|
||||
onCantUse( player )
|
||||
{
|
||||
// player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
|
||||
}
|
||||
|
||||
spawnFxDelay( fxid, pos, forward, right, delay )
|
||||
{
|
||||
wait delay;
|
||||
effect = spawnFx( fxid, pos, forward, right );
|
||||
triggerFx( effect );
|
||||
}
|
||||
|
||||
forceVIPSpawn()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
self endon ( "spawned" );
|
||||
|
||||
if ( self.hasSpawned )
|
||||
return;
|
||||
|
||||
if ( !isValidClass( self.pers["class"] ) )
|
||||
{
|
||||
self.pers["class"] = "CLASS_CUSTOM1";
|
||||
|
||||
self.class = self.pers["class"];
|
||||
}
|
||||
|
||||
self closeMenus();
|
||||
self thread maps\mp\gametypes\_playerlogic::spawnClient();
|
||||
}
|
||||
@@ -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