Pushed raw files

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

No files matched your search

+202
View File
@@ -0,0 +1,202 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
level.isTeamSpeaking["allies"] = false;
level.isTeamSpeaking["axis"] = false;
level.speakers["allies"] = [];
level.speakers["axis"] = [];
level.bcSounds = [];
level.bcSounds["reload"] = "inform_reloading_generic";
level.bcSounds["frag_out"] = "inform_attack_grenade";
level.bcSounds["flash_out"] = "inform_attack_flashbang";
level.bcSounds["smoke_out"] = "inform_attack_smoke";
level.bcSounds["conc_out"] = "inform_attack_stun";
level.bcSounds["c4_plant"] = "inform_attack_thwc4";
level.bcSounds["claymore_plant"] = "inform_plant_claymore";
level.bcSounds["kill"] = "inform_killfirm_infantry";
level.bcSounds["casualty"] = "inform_casualty_generic";
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill ( "connected", player );
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon( "disconnect" );
for(;;)
{
self waittill( "spawned_player" );
// help players be stealthy in splitscreen by not announcing their intentions
if ( level.splitscreen )
continue;
self thread claymoreTracking();
self thread reloadTracking();
self thread grenadeTracking();
}
}
claymoreTracking()
{
self endon ( "death" );
self endon ( "disconnect" );
while(1)
{
self waittill( "begin_firing" );
weaponName = self getCurrentWeapon();
if ( weaponName == "claymore_mp" )
level thread sayLocalSound( self, "claymore_plant" );
}
}
reloadTracking()
{
self endon ( "death" );
self endon ( "disconnect" );
for( ;; )
{
self waittill ( "reload_start" );
level thread sayLocalSound( self, "reload" );
}
}
grenadeTracking()
{
self endon ( "death" );
self endon ( "disconnect" );
for( ;; )
{
self waittill ( "grenade_fire", grenade, weaponName );
if ( weaponName == "frag_grenade_mp" )
level thread sayLocalSound( self, "frag_out" );
else if ( weaponName == "flash_grenade_mp" )
level thread sayLocalSound( self, "flash_out" );
else if ( weaponName == "concussion_grenade_mp" )
level thread sayLocalSound( self, "conc_out" );
else if ( weaponName == "smoke_grenade_mp" )
level thread sayLocalSound( self, "smoke_out" );
else if ( weaponName == "c4_mp" )
level thread sayLocalSound( self, "c4_plant" );
}
}
sayLocalSoundDelayed( player, soundType, delay )
{
player endon ( "death" );
player endon ( "disconnect" );
wait ( delay );
sayLocalSound( player, soundType );
}
sayLocalSound( player, soundType )
{
player endon ( "death" );
player endon ( "disconnect" );
if ( isSpeakerInRange( player ) )
return;
if( player.team != "spectator" )
{
prefix = maps\mp\gametypes\_teams::getTeamVoicePrefix( player.team ) + "1_";
soundAlias = prefix + level.bcSounds[soundType];
player thread doSound( soundAlias );
}
}
doSound( soundAlias )
{
team = self.pers["team"];
level addSpeaker( self, team );
self playSoundToTeam( soundAlias, team, self );
self thread timeHack( soundAlias ); // workaround because soundalias notify isn't happening
self waittill_any( soundAlias, "death", "disconnect" );
level removeSpeaker( self, team );
}
timeHack( soundAlias )
{
self endon ( "death" );
self endon ( "disconnect" );
wait ( 2.0 );
self notify ( soundAlias );
}
isSpeakerInRange( player )
{
player endon ( "death" );
player endon ( "disconnect" );
distSq = 1000 * 1000;
// to prevent player switch to spectator after throwing a granade causing damage to someone and result in attacker.pers["team"] = "spectator"
if( isdefined( player ) && isdefined( player.pers["team"] ) && player.pers["team"] != "spectator" )
{
for ( index = 0; index < level.speakers[player.pers["team"]].size; index++ )
{
teammate = level.speakers[player.pers["team"]][index];
if ( teammate == player )
return true;
if ( distancesquared( teammate.origin, player.origin ) < distSq )
return true;
}
}
return false;
}
addSpeaker( player, team )
{
level.speakers[team][level.speakers[team].size] = player;
}
// this is lazy... fix up later by tracking ID's and doing array slot swapping
removeSpeaker( player, team )
{
newSpeakers = [];
for ( index = 0; index < level.speakers[team].size; index++ )
{
if ( level.speakers[team][index] == player )
continue;
newSpeakers[newSpeakers.size] = level.speakers[team][index];
}
level.speakers[team] = newSpeakers;
}
+213
View File
@@ -0,0 +1,213 @@
// Callback Setup
// This script provides the hooks from code into script for the gametype callback functions.
//=============================================================================
// Code Callback functions
/*================
Called by code after the level's main script function has run.
================*/
CodeCallback_StartGameType()
{
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
level waittill( "eternity" );
// If the gametype has not beed started, run the startup
if(!isDefined(level.gametypestarted) || !level.gametypestarted)
{
[[level.callbackStartGameType]]();
level.gametypestarted = true; // so we know that the gametype has been started up
}
}
/*================
Called when a player begins connecting to the server.
Called again for every map change or tournement restart.
Return undefined if the client should be allowed, otherwise return
a string with the reason for denial.
Otherwise, the client will be sent the current gamestate
and will eventually get to ClientBegin.
firstTime will be qtrue the very first time a client connects
to the server machine, but qfalse on map changes and tournement
restarts.
================*/
CodeCallback_PlayerConnect()
{
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
level waittill( "eternity" );
self endon("disconnect");
[[level.callbackPlayerConnect]]();
}
/*================
Called when a player drops from the server.
Will not be called between levels.
self is the player that is disconnecting.
================*/
CodeCallback_PlayerDisconnect()
{
self notify("disconnect");
[[level.callbackPlayerDisconnect]]();
}
/*================
Called when a player has taken damage.
self is the player that took damage.
================*/
CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
{
self endon("disconnect");
[[level.callbackPlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
}
/*================
Called when a player has been killed.
self is the player that was killed.
================*/
CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
{
self endon("disconnect");
[[level.callbackPlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
}
/*================
Called when a vehicle has taken damage.
self is the vehicle that took damage.
================*/
CodeCallback_VehicleDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName )
{
if ( isDefined( self.damageCallback ) )
self [[self.damageCallback]]( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
else
self Vehicle_FinishDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
}
/*================
Called when code is forcibly ending the game.
e.g. we suck as host.
================*/
CodeCallback_CodeEndGame()
{
self endon("disconnect");
[[level.callbackCodeEndGame]]();
}
/*================
Called when a player has been killed, but has last stand perk.
self is the player that was killed.
================*/
CodeCallback_PlayerLastStand(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
{
self endon("disconnect");
[[level.callbackPlayerLastStand]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
}
/*================
Called when a player reconnects to the server
following a host migration.
================*/
CodeCallback_PlayerMigrated()
{
self endon("disconnect");
[[level.callbackPlayerMigrated]]();
}
/*================
Called once when a host migration has occured.
================*/
CodeCallback_HostMigration()
{
[[level.callbackHostMigration]]();
}
//=============================================================================
// Damage flags used in the playerDamage callback
SetupDamageFlags()
{
// code-defined:
level.iDFLAGS_RADIUS = 1; // damage was indirect
level.iDFLAGS_NO_ARMOR = 2; // armor does not protect from this damage
level.iDFLAGS_NO_KNOCKBACK = 4; // do not affect velocity, just view angles
level.iDFLAGS_PENETRATION = 8; // damage occurred after one or more penetrations
level.iDFLAGS_STUN = 16; // non-lethal
level.iDFLAGS_SHIELD_EXPLOSIVE_IMPACT = 32; // missile impacted on the front of the victim's shield
level.iDFLAGS_SHIELD_EXPLOSIVE_IMPACT_HUGE = 64; // ...and was from a projectile with "Big Explosion" checked on.
level.iDFLAGS_SHIELD_EXPLOSIVE_SPLASH = 128; // explosive splash, somewhat deflected by the victim's shield
// script-defined:
level.iDFLAGS_NO_TEAM_PROTECTION = 256;
level.iDFLAGS_NO_PROTECTION = 512;
level.iDFLAGS_PASSTHRU = 1024;
}
/*================
Setup any misc callbacks stuff like defines and default callbacks
================*/
SetupCallbacks()
{
SetDefaultCallbacks();
SetupDamageFlags();
}
/*================
Called from the gametype script to store off the default callback functions.
This allows the callbacks to be overridden by level script, but not lost.
================*/
SetDefaultCallbacks()
{
level.callbackStartGameType = maps\mp\gametypes\_gamelogic::Callback_StartGameType;
level.callbackPlayerConnect = maps\mp\gametypes\_playerlogic::Callback_PlayerConnect;
level.callbackPlayerDisconnect = maps\mp\gametypes\_playerlogic::Callback_PlayerDisconnect;
level.callbackPlayerDamage = maps\mp\gametypes\_damage::Callback_PlayerDamage;
level.callbackPlayerKilled = maps\mp\gametypes\_damage::Callback_PlayerKilled;
level.callbackCodeEndGame = maps\mp\gametypes\_gamelogic::Callback_CodeEndGame;
level.callbackPlayerLastStand = maps\mp\gametypes\_damage::Callback_PlayerLastStand;
level.callbackPlayerMigrated = maps\mp\gametypes\_playerlogic::Callback_PlayerMigrated;
level.callbackHostMigration = maps\mp\gametypes\_hostmigration::Callback_HostMigration;
}
/*================
Called when a gametype is not supported.
================*/
AbortLevel()
{
println("Aborting level - gametype is not supported");
level.callbackStartGameType = ::callbackVoid;
level.callbackPlayerConnect = ::callbackVoid;
level.callbackPlayerDisconnect = ::callbackVoid;
level.callbackPlayerDamage = ::callbackVoid;
level.callbackPlayerKilled = ::callbackVoid;
level.callbackCodeEndGame = ::callbackVoid;
level.callbackPlayerLastStand = ::callbackVoid;
level.callbackPlayerMigrated = ::callbackVoid;
level.callbackHostMigration = ::callbackVoid;
setdvar("g_gametype", "dm");
exitLevel(false);
}
/*================
================*/
callbackVoid()
{
}
File diff suppressed because it is too large. Load diff
+828
View File
@@ -0,0 +1,828 @@
init()
{
level.coptermodel = "vehicle_cobra_helicopter_fly";
precacheModel(level.coptermodel);
level.copter_maxaccel = 200;
level.copter_maxvel = 700;
level.copter_rotspeed = 90; // degrees per second
level.copter_accellookahead = 2; // seconds
level.copterCenterOffset = (0,0,72);
level.copterTargetOffset = (0,0,45);
level.copterexplosion = loadfx("explosions/default_explosion");
level.copterfinalexplosion = loadfx("explosions/large_vehicle_explosion");
}
getAboveBuildingsLocation(location)
{
trace = bullettrace(location + (0,0,10000), location, false, undefined);
startorigin = trace["position"] + (0,0,-514);
zpos = 0;
maxxpos = 13; maxypos = 13;
for (xpos = 0; xpos < maxxpos; xpos++) {
for (ypos = 0; ypos < maxypos; ypos++) {
thisstartorigin = startorigin + ((xpos/(maxxpos-1) - .5) * 1024, (ypos/(maxypos-1) - .5) * 1024, 0);
thisorigin = bullettrace(thisstartorigin, thisstartorigin + (0,0,-10000), false, undefined);
zpos += thisorigin["position"][2];
}
}
zpos = zpos / (maxxpos*maxypos);
zpos = zpos + 850;
return (location[0], location[1], zpos);
}
vectorAngle(v1, v2)
{
dot = vectordot(v1, v2);
if (dot >= 1)
return 0;
else if (dot <= -1)
return 180;
return acos(dot);
}
vectorTowardsOtherVector(v1, v2, angle)
{
dot = vectordot(v1, v2);
if (dot <= -1)
{
return v1; // eh
}
v3 = vectornormalize(v2 - vecscale(v1, dot));
return vecscale(v1, cos(angle)) + vecscale(v3, sin(angle));
}
veclength(v)
{
return distance((0,0,0), v);
}
createCopter(location, team, damagetrig)
{
location = getAboveBuildingsLocation(location);
scriptorigin = spawn("script_origin", location);
scriptorigin.angles = vectorToAngles((1, 0, 0));
copter = spawn("script_model", location);
copter.angles = vectorToAngles((0, 1, 0));
copter linkto(scriptorigin);
scriptorigin.copter = copter;
copter setModel(level.coptermodel);
copter playLoopSound("mp_copter_ambience");
damagetrig.origin = scriptorigin.origin;
damagetrig thread mylinkto(scriptorigin);
scriptorigin.damagetrig = damagetrig;
scriptorigin.finalDest = location;
scriptorigin.finalZDest = location[2];
scriptorigin.desiredDir = (1,0,0);
scriptorigin.desiredDirEntity = undefined;
scriptorigin.desiredDirEntityOffset = (0,0,0);
scriptorigin.vel = (0,0,0);
scriptorigin.dontascend = false;
scriptorigin.health = 2000;
if (getdvar("scr_copter_health") != "")
scriptorigin.health = getdvarfloat("scr_copter_health");
scriptorigin.team = team;
scriptorigin thread copterAI();
scriptorigin thread copterDamage(damagetrig);
return scriptorigin;
}
makeCopterPassive()
{
self.damagetrig notify("unlink");
self.damagetrig = undefined;
self notify("passive");
self.desiredDirEntity = undefined;
self.desiredDir = undefined;
}
makeCopterActive(damagetrig)
{
damagetrig.origin = self.origin;
damagetrig thread mylinkto(self);
self.damagetrig = damagetrig;
self thread copterAI();
self thread copterDamage(damagetrig);
}
mylinkto(obj)
{
self endon("unlink");
while(1)
{
self.angles = obj.angles;
self.origin = obj.origin;
wait .1;
}
}
setCopterDefenseArea(areaEnt)
{
self.areaEnt = areaEnt;
self.areaDescentPoints = [];
if (isdefined(areaEnt.target)) {
self.areaDescentPoints = getentarray(areaEnt.target, "targetname");
}
for (i = 0; i < self.areaDescentPoints.size; i++)
{
self.areaDescentPoints[i].targetEnt = getent(self.areaDescentPoints[i].target, "targetname");
}
}
copterAI()
{
self thread copterMove();
self thread copterShoot();
self endon("death");
self endon("passive");
flying = true;
descendingEnt = undefined;
reachedDescendingEnt = false;
returningToArea = false;
while(1)
{
if (!isdefined(self.areaEnt)) {
wait(1);
continue;
}
players = level.players;
enemyTargets = [];
if (self.team != "neutral") {
for (i = 0; i < players.size; i++) {
if (isalive(players[i]) && isdefined(players[i].pers["team"]) && players[i].pers["team"] != self.team && !isdefined(players[i].usingObj)) {
playerorigin = players[i].origin;
playerorigin = (playerorigin[0], playerorigin[1], self.areaEnt.origin[2]);
if (distance(playerorigin, self.areaEnt.origin) < self.areaEnt.radius)
enemyTargets[enemyTargets.size] = players[i];
}
}
}
insideTargets = [];
outsideTargets = [];
skyheight = bullettrace(self.origin, self.origin + (0,0,10000), false, undefined)["position"][2] - 10;
bestTarget = undefined;
bestWeight = 0;
for (i = 0; i < enemyTargets.size; i++) {
inside = false;
trace = bulletTrace(enemyTargets[i].origin + (0,0,10), enemyTargets[i].origin + (0,0,10000), false, undefined);
if (trace["position"][2] >= skyheight)
// outside.
outsideTargets[outsideTargets.size] = enemyTargets[i];
else
// inside.
insideTargets[insideTargets.size] = enemyTargets[i];
}
goToPos = undefined;
calcedGoToPos = false;
oldDescendingEnt = undefined;
// determine if we should change states
if (flying) {
if (outsideTargets.size == 0 && insideTargets.size > 0 && self.areaDescentPoints.size > 0) {
flying = false;
result = determineBestEnt(insideTargets, self.areaDescentPoints, self.origin);
descendingEnt = result["descendEnt"];
if (isdefined(descendingEnt))
goToPos = result["position"];
else
flying = true;
}
}
else {
oldDescendingEnt = descendingEnt;
if (insideTargets.size == 0) {
flying = true;
}
else {
// if we can't get a good target, and there are outside targets, give up and fly
if (outsideTargets.size > 0) {
if (!isdefined(descendingEnt))
flying = true;
else
{
calcedGoToPos = true;
goToPos = determineBestPos(insideTargets, descendingEnt, self.origin);
if (!isdefined(goToPos))
flying = true;
}
}
// determine where to go.
if (isdefined(descendingEnt)) {
// we're already descended. try to find a good place to shoot into the door/window from.
if (!calcedGoToPos)
goToPos = determineBestPos(insideTargets, descendingEnt, self.origin);
}
if (!isdefined(goToPos)) {
result = determineBestEnt(insideTargets, self.areaDescentPoints, self.origin);
if (isdefined(result["descendEnt"])) {
descendingEnt = result["descendEnt"];
goToPos = result["position"];
reachedDescendingEnt = false;
}
else {
if (isdefined(descendingEnt)) {
if (isdefined(self.finalDest))
goToPos = self.finalDest;
else
goToPos = descendingEnt.origin;
}
else
goToPos = undefined;
}
}
// couldn't find a place to descend?
if (!isdefined(goToPos))
flying = true;
}
}
if (flying)
{
// determine best target to shoot outside.
desireddist = 1024*2.5;
distToArea = distance((self.origin[0], self.origin[1], self.areaEnt.origin[2]), self.areaEnt.origin);
if (outsideTargets.size == 0 && distToArea > self.areaEnt.radius + desireddist*.25)
returningToArea = true;
else if (distToArea < self.areaEnt.radius*.5)
returningToArea = false;
if (outsideTargets.size == 0 && !returningToArea)
{
// no outside targets? look again for any enemies outside the radius we're defending - just so
// we don't look stupid when we could be making ourself useful.
if (self.team != "neutral") {
for (i = 0; i < players.size; i++) {
if (isalive(players[i]) && isdefined(players[i].pers["team"]) && players[i].pers["team"] != self.team && !isdefined(players[i].usingObj)) {
playerorigin = players[i].origin;
playerorigin = (playerorigin[0], playerorigin[1], self.areaEnt.origin[2]);
if (distance(players[i].origin, self.areaEnt.origin) > self.areaEnt.radius)
outsideTargets[outsideTargets.size] = players[i];
}
}
}
}
best = undefined;
bestdist = 0;
for (i = 0; i < outsideTargets.size; i++)
{
dist = abs(distance(outsideTargets[i].origin, self.origin) - desireddist);
if (!isdefined(best) || dist < bestdist) {
best = outsideTargets[i];
bestdist = dist;
}
}
if (isdefined(best)) {
// determine best position to go to to get target.
attackpos = best.origin + level.copterTargetOffset;
goToPos = determineBestAttackPos(attackpos, self.origin, desireddist);
//iprintln("going to flying attack pos");
self setCopterDest(goToPos, false);
self.desiredDir = vectornormalize(attackpos - goToPos);
self.desiredDirEntity = best;
self.desiredDirEntityOffset = level.copterTargetOffset;
wait(1);
}
else {
goToPos = getRandomPos(self.areaEnt.origin, self.areaEnt.radius);
self setCopterDest(goToPos, false);
//iprintln("going to random pos");
self.desiredDir = undefined;
self.desiredDirEntity = undefined;
wait(1);
}
}
else
{
if (distance(self.origin, descendingEnt.origin) < descendingEnt.radius)
reachedDescendingEnt = true;
//iprintln("going to descent pos");
goDirectly = (isdefined(oldDescendingEnt) && oldDescendingEnt == descendingEnt);
goDirectly = goDirectly && reachedDescendingEnt;
self.desiredDir = vectornormalize(descendingEnt.targetEnt.origin - (goToPos - level.copterCenterOffset));
self.desiredDirEntity = descendingEnt.targetEnt;
self.desiredDirEntityOffset = (0,0,0);
if (goToPos != self.origin) {
self setCopterDest(goToPos - level.copterCenterOffset, true, goDirectly);
wait(.3);
}
else
wait(.3);
}
}
}
// determines the best position to go to within descendEnt
// from where a target is visible. if no such positions,
// returns undefined.
determineBestPos(targets, descendEnt, startorigin)
{
targetpos = descendEnt.targetEnt.origin;
circleradius = distance(targetpos, descendEnt.origin);
bestpoint = undefined;
bestdist = 0;
for (i = 0; i < targets.size; i++)
{
enemypos = targets[i].origin + level.copterTargetOffset;
passed = bullettracepassed(enemypos, targetpos, false, undefined);
if (passed) {
dir = targetpos - enemypos;
dir = (dir[0], dir[1], 0);
isect = vecscale(vectornormalize(dir),circleradius) + targetpos;
isect = (isect[0], isect[1], descendEnt.origin[2]);
dist = distance(isect, descendEnt.origin);
if (dist <= descendEnt.radius) {
dist = distance(isect, startorigin);
if (!isdefined(bestpoint) || dist < bestdist) {
bestdist = dist;
bestpoint = isect;
}
}
}
}
return bestpoint;
}
// determines the best entity out of descendEnts to go to
// in order to get at one of targets.
// result["descendEnt"] is the winning entity,
// result["position"] is the position to go to.
determineBestEnt(targets, descendEnts, startorigin)
{
result = [];
bestpos = undefined;
bestent = 0;
bestdist = 0;
for (i = 0; i < descendEnts.size; i++)
{
thispos = determineBestPos(targets, descendEnts[i], startorigin);
if (isdefined(thispos)) {
thisdist = distance(thispos, startorigin);
if (!isdefined(bestpos) || thisdist < bestdist) {
bestpos = thispos;
bestent = i;
bestdist = thisdist;
}
}
}
if (isdefined(bestpos)) {
result["descendEnt"] = descendEnts[bestent];
result["position"] = bestpos;
return result;
}
result["descendEnt"] = undefined;
return result;
}
determineBestAttackPos(targetpos, curpos, desireddist)
{
targetposcopterheight = (targetpos[0], targetpos[1], curpos[2]);
attackdirx = curpos - targetposcopterheight;
attackdirx = vectornormalize(attackdirx);
attackdiry = (0-attackdirx[1], attackdirx[0], 0);
bestpos = undefined;
bestdist = 0;
for (i = 0; i < 8; i++) {
theta = (i/8.0) * 360;
thisdir = vecscale(attackdirx, cos(theta)) + vecscale(attackdiry, sin(theta));
traceend = targetposcopterheight + vecscale(thisdir, desireddist);
losexists = bullettracepassed(targetpos, traceend, false, undefined);
if (losexists) {
thisdist = distance(traceend, curpos);
if (!isdefined(bestpos) || thisdist < bestdist) {
bestpos = traceend;
bestdist = thisdist;
}
}
}
goToPos = undefined;
if (isdefined(bestpos)) {
goToPos = bestpos;
}
else {
dist = distance(targetposcopterheight, curpos);
if (dist > desireddist)
goToPos = self.origin + vecscale(vectornormalize(attackdirx), 0-(dist - desireddist));
else
goToPos = self.origin;
}
return goToPos;
}
getRandomPos(origin, radius)
{
// no sqrt so have to do this the guess and check way.
pos = origin + ((randomfloat(2)-1)*radius, (randomfloat(2)-1)*radius, 0);
while(distanceSquared(pos, origin) > radius*radius)
pos = origin + ((randomfloat(2)-1)*radius, (randomfloat(2)-1)*radius, 0);
return pos;
}
copterShoot()
{
self endon("death");
self endon("passive");
cosThreshold = cos(10);
while(1)
{
if (isdefined(self.desiredDirEntity) && isdefined(self.desiredDirEntity.origin)) {
mypos = self.origin + level.copterCenterOffset;
enemypos = self.desiredDirEntity.origin + self.desiredDirEntityOffset;
curdir = anglesToForward(self.angles);
enemydirraw = enemypos - mypos;
enemydir = vectornormalize(enemydirraw);
if (vectordot(curdir, enemydir) > cosThreshold)
{
canseetarget = bullettracepassed(mypos, enemypos, false, undefined);
if (!canseetarget && isplayer(self.desiredDirEntity) && isalive(self.desiredDirEntity))
canseetarget = bullettracepassed(mypos, self.desiredDirEntity getEye(), false, undefined);
if (canseetarget) {
// shoot.
self playSound("mp_copter_shoot");
numshots = 20;
for (i = 0; i < numshots; i++)
{
mypos = self.origin + level.copterCenterOffset;
/*if (isdefined(self.desiredDirEntity)) {
enemypos = self.desiredDirEntity.origin + self.desiredDirEntityOffset;
enemydirraw = enemypos - mypos;
enemydir = vectornormalize(enemydirraw);
dir = enemydir;
}
else*/
dir = anglesToForward(self.angles);
dir = dir + ((randomfloat(2)-1)*.015, (randomfloat(2)-1)*.015, (randomfloat(2)-1)*.015);
dir = vectornormalize(dir);
self myMagicBullet(mypos, dir);
wait(.075);
}
wait(.25);
}
//else
//iprintln("can't see");
}
//else
//iprintln("below cosThreshold: ", vectordot(curdir, enemydir), " < ", cosThreshold);
}
//else
//iprintln("no target");
wait(.25);
}
}
myMagicBullet(pos, dir)
{
damage = 20;
if (getdvar("scr_copter_damage") != "")
damage = getdvarint("scr_copter_damage");
// for now just shoot from origin
trace = bullettrace(pos, pos + vecscale(dir, 10000), true, undefined);
if (isdefined(trace["entity"]) && isplayer(trace["entity"]) && isalive(trace["entity"])) {
// hurt entity shot at
trace["entity"] thread [[level.callbackPlayerDamage]](
self, // eInflictor The entity that causes the damage.(e.g. a turret)
self, // eAttacker The entity that is attacking.
damage, // iDamage Integer specifying the amount of damage done
0, // iDFlags Integer specifying flags that are to be applied to the damage
"MOD_RIFLE_BULLET", // sMeansOfDeath Integer specifying the method of death
"copter", // sWeapon The weapon number of the weapon used to inflict the damage
self.origin, // vPoint The point the damage is from?
dir, // vDir The direction of the damage
"none", // sHitLoc The location of the hit
0 // psOffsetTime The time offset for the damage
);
}
//line(pos, trace["position"], (1,1,1));
}
setCopterDest(newlocation, descend, dontascend)
{
self.finalDest = getAboveBuildingsLocation(newlocation);
if (isdefined(descend) && descend)
self.finalZDest = newlocation[2];
else
self.finalZDest = self.finalDest[2];
self.intransit = true;
self.dontascend = false;
if (isdefined(dontascend))
self.dontascend = dontascend;
}
notifyArrived()
{
wait .05;
self notify("arrived");
}
vecscale(vec, scalar)
{
return (vec[0]*scalar, vec[1]*scalar, vec[2]*scalar);
}
abs(x)
{
if (x < 0)
return 0-x;
return x;
}
copterMove()
{
self endon("death");
if (isdefined(self.copterMoveRunning))
return;
self.copterMoveRunning = true;
self.intransit = false;
interval = .15;
zinterp = .1;
tiltamnt = 0;
while(1)
{
horizDistSquared = distanceSquared((self.origin[0], self.origin[1], 0), (self.finalDest[0], self.finalDest[1], 0));
doneMoving = horizDistSquared < 10*10;
//if (!doneMoving)
{
nearDest = (horizDistSquared < 256*256);
self.intransit = true;
desiredZ = 0;
// movement
movingHorizontally = true;
movingVertically = false;
if (self.dontascend)
movingVertically = true;
else {
// if we're not near our horizontal goal position
if (!nearDest) {
// get the z position we *want* to have before moving horizontally
desiredZ = getAboveBuildingsLocation(self.origin)[2];
movingHorizontally = (abs(self.origin[2] - desiredZ) <= 256); // we're moving horizontally if we're up high enough to do so
movingVertically = !movingHorizontally; // we're moving vertically if we aren't
}
// if we are near our horizontal goal position
else
movingVertically = true;
}
// determine our destination
if (movingHorizontally) {
if (movingVertically)
thisDest = (self.finalDest[0], self.finalDest[1], self.finalZDest);
else
thisDest = self.finalDest;
}
else {
assert(movingVertically);
thisDest = (self.origin[0], self.origin[1], desiredZ);
}
movevec = thisDest - self.origin;
idealAccel = vecscale(thisDest - (self.origin + vecscale(self.vel, level.copter_accellookahead)), interval);
vlen = veclength(idealAccel);
if (vlen > level.copter_maxaccel) {
idealAccel = vecscale(idealAccel, level.copter_maxaccel / vlen);
}
self.vel = self.vel + idealAccel;
vlen = veclength(self.vel);
if (vlen > level.copter_maxvel) {
self.vel = vecscale(self.vel, level.copter_maxvel / vlen);
}
thisDest = self.origin + vecscale(self.vel, interval);
self moveto(thisDest, interval*.999);
speed = veclength(self.vel);
if (isdefined(self.desiredDirEntity) && isdefined(self.desiredDirEntity.origin)) {
self.destDir = vectornormalize((self.desiredDirEntity.origin + self.desiredDirEntityOffset) - (self.origin + level.copterCenterOffset));
}
else if (isdefined(self.desiredDir)) {
self.destDir = self.desiredDir;
}
else if (movingVertically) {
self.destDir = anglesToForward(self.angles);
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], 0));
}
else {
tiltamnt = speed / level.copter_maxvel;
tiltamnt = (tiltamnt - .1) / .9; if (tiltamnt < 0) tiltamnt = 0;
self.destDir = movevec;
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], 0)); // remove z component
tiltamnt = tiltamnt * (1 - (vectorAngle(anglesToForward(self.angles), self.destDir) / 180));
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], tiltamnt * -.4)); // tilt forward while moving
}
}
/*else {
if (self.intransit) {
self.intransit = false;
self.dontascend = false;
// if we descended to get to this point, we'll be ascending to get out
if (self.finalZDest != self.finalDest[2])
self.ascending = true;
self notify("arrived");
}
if (isdefined(self.desiredDir))
self.destDir = self.desiredDir;
else {
self.destDir = anglesToForward(self.angles);
self.destDir = vectornormalize((self.destDir[0], self.destDir[1], 0));
}
}*/
// rotation
newdir = self.destDir;
//line(self.origin + level.copterCenterOffset, self.origin + level.copterCenterOffset + vecscale(self.destDir,10000), (1,0,0));
if (newdir[2] < -.4) {// *never* look too far down
newdir = vectornormalize((newdir[0], newdir[1], -.4));
}
//line(self.origin + level.copterCenterOffset, self.origin + level.copterCenterOffset + vecscale(newdir,10000), (1,1,0));
copterangles = self.angles;
copterangles = combineangles(copterangles, (0,90,0));
olddir = anglesToForward(copterangles);
thisRotSpeed = level.copter_rotspeed;
//if (movelen < 256)
// thisRotSpeed = thisRotSpeed * movelen / 256;
olddir2d = vectornormalize((olddir[0], olddir[1], 0));
newdir2d = vectornormalize((newdir[0], newdir[1], 0));
angle = vectorAngle(olddir2d, newdir2d);
angle3d = vectorAngle(olddir, newdir);
if (angle > .001 && thisRotSpeed > .001) {
thisangle = thisRotSpeed * interval;
if (thisangle > angle)
thisangle = angle;
newdir2d = vectorTowardsOtherVector(olddir2d, newdir2d, thisangle);
oldz = olddir[2]/veclength((olddir[0], olddir[1], 0));
newz = newdir[2]/veclength((newdir[0], newdir[1], 0));
interpz = oldz + (newz - oldz) * (thisangle / angle);
newdir = vectornormalize((newdir2d[0], newdir2d[1], interpz));
copterangles = vectorToAngles(newdir);
copterangles = combineangles(copterangles, (0,-90,0));
self rotateto(copterangles, interval*.999);
}
else if (angle3d > .001 && thisRotSpeed > .001) {
// need to rotate vertically
thisangle = thisRotSpeed * interval;
if (thisangle > angle3d)
thisangle = angle3d;
newdir = vectorTowardsOtherVector(olddir, newdir, thisangle);
newdir = vectornormalize(newdir);
copterangles = vectorToAngles(newdir);
copterangles = combineangles(copterangles, (0,-90,0));
self rotateto(copterangles, interval*.999);
}
wait interval;
}
}
copterDamage(damagetrig)
{
self endon("passive");
while(1)
{
damagetrig waittill("damage", amount, attacker);
// disallow friendly fire
if (isdefined(attacker) && isplayer(attacker) && isdefined(attacker.pers["team"]) && attacker.pers["team"] == self.team)
continue;
self.health -= amount;
if (self.health <= 0) {
self thread copterDie();
return;
}
//iprintln("OW ", amount);
}
}
copterDie()
{
self endon("passive");
self notify("death");
self.dead = true;
self thread copterExplodeFX();
// crash.
interval = .2;
rottime = 15;
self rotateyaw(360 + randomfloat(360), rottime);
self rotatepitch(360 + randomfloat(360), rottime);
self rotateroll(360 + randomfloat(360), rottime);
while(1)
{
self.vel = self.vel + vecscale((0,0,-200), interval);
newpos = self.origin + vecscale(self.vel, interval);
// check for collision with ground
pathclear = bullettracepassed(self.origin, newpos, false, undefined);
if (!pathclear)
break;
self moveto(newpos, interval*.999);
wait (interval);
}
playfx (level.copterfinalexplosion, self.origin);
playsoundatpos( self.origin, "mp_copter_explosion" );
self notify("finaldeath");
deleteCopter();
}
deleteCopter()
{
if (isdefined(self.damagetrig)) {
self.damagetrig notify("unlink");
self.damagetrig = undefined;
}
self.copter delete();
self delete();
}
copterExplodeFX()
{
self endon("finaldeath");
while(1)
{
playfx (level.copterexplosion, self.origin);
self playsound("mp_copter_explosion");
wait .5 + randomfloat(1);
}
}
File diff suppressed because it is too large. Load diff
+93
View File
@@ -0,0 +1,93 @@
init()
{
precacheShader("damage_feedback");
precacheShader("damage_feedback_j");
precacheShader("damage_feedback_endgame");
precacheShader("scavenger_pickup");
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player.hud_damagefeedback = newClientHudElem(player);
player.hud_damagefeedback.horzAlign = "center";
player.hud_damagefeedback.vertAlign = "middle";
player.hud_damagefeedback.x = -12;
player.hud_damagefeedback.y = -12;
player.hud_damagefeedback.alpha = 0;
player.hud_damagefeedback.archived = true;
player.hud_damagefeedback setShader("damage_feedback", 24, 48);
}
}
updateDamageFeedback( typeHit )
{
if ( !isPlayer( self ) )
return;
x = -12;
y = -12;
if ( getDvarInt( "camera_thirdPerson" ) )
yOffset = self GetThirdPersonCrosshairOffset() * 240;
else
yOffset = getdvarfloat( "cg_crosshairVerticalOffset" ) * 240;
if ( level.splitscreen )
yOffset *= 0.5;
feedbackDurationOverride = 0;
startAlpha = 1;
if ( typeHit == "hitBodyArmor" )
{
self.hud_damagefeedback setShader("damage_feedback_j", 24, 48);
self playlocalsound("MP_hit_alert"); // TODO: change sound?
}
else if ( typeHit == "hitEndGame" )
{
self.hud_damagefeedback setShader("damage_feedback_endgame", 24, 48);
self playlocalsound("MP_hit_alert");
}
else if ( typeHit == "stun" )
{
return;
}
else if ( typeHit == "none" )
{
return;
}
else if ( typeHit == "scavenger" && !level.hardcoreMode )
{
x = -36;
y = 32;
self.hud_damagefeedback setShader("scavenger_pickup", 64, 32);
feedbackDurationOverride = 2.5;
}
else
{
self.hud_damagefeedback setShader("damage_feedback", 24, 48);
self playlocalsound("MP_hit_alert");
}
self.hud_damagefeedback.alpha = startAlpha;
if ( feedBackDurationOverride != 0 )
self.hud_damagefeedback fadeOverTime(feedbackDurationOverride);
else
self.hud_damagefeedback fadeOverTime(1);
self.hud_damagefeedback.alpha = 0;
// only update hudelem positioning when necessary
if ( self.hud_damagefeedback.x != x )
self.hud_damagefeedback.x = x;
y = y - int( yOffset );
if ( self.hud_damagefeedback.y != y )
self.hud_damagefeedback.y = y;
}
+80
View File
@@ -0,0 +1,80 @@
#include maps\mp\_utility;
init()
{
if (!level.teambased)
return;
precacheShader("headicon_dead");
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player.selfDeathIcons = []; // icons that other people see which point to this player when he's dead
}
}
updateDeathIconsEnabled()
{
//if (!self.enableDeathIcons)
// self removeOtherDeathIcons();
}
addDeathIcon( entity, dyingplayer, team, timeout )
{
if ( !level.teambased )
return;
iconOrg = entity.origin;
dyingplayer endon("spawned_player");
dyingplayer endon("disconnect");
wait .05;
WaitTillSlowProcessAllowed();
assert(team == "allies" || team == "axis");
if ( getDvar( "ui_hud_showdeathicons" ) == "0" )
return;
if ( level.hardcoreMode )
return;
if ( isdefined( self.lastDeathIcon ) )
self.lastDeathIcon destroy();
newdeathicon = newTeamHudElem( team );
newdeathicon.x = iconOrg[0];
newdeathicon.y = iconOrg[1];
newdeathicon.z = iconOrg[2] + 54;
newdeathicon.alpha = .61;
newdeathicon.archived = true;
if ( level.splitscreen )
newdeathicon setShader("headicon_dead", 14, 14);
else
newdeathicon setShader("headicon_dead", 7, 7);
newdeathicon setwaypoint( true, false );
self.lastDeathIcon = newdeathicon;
newdeathicon thread destroySlowly ( timeout );
}
destroySlowly( timeout )
{
self endon("death");
wait timeout;
self fadeOverTime(1.0);
self.alpha = 0;
wait 1.0;
self destroy();
}
File diff suppressed because it is too large. Load diff
+120
View File
@@ -0,0 +1,120 @@
init()
{
// Draws a team icon over teammates
level.drawfriend = 0;
game["headicon_allies"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "allies" );
game["headicon_axis"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "axis" );
precacheHeadIcon( game["headicon_allies"] );
precacheHeadIcon( game["headicon_axis"] );
precacheShader( "waypoint_revive" );
level thread onPlayerConnect();
for(;;)
{
updateFriendIconSettings();
wait 5;
}
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
player thread onPlayerKilled();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
self thread showFriendIcon();
}
}
onPlayerKilled()
{
self endon("disconnect");
for(;;)
{
self waittill("killed_player");
self.headicon = "";
}
}
showFriendIcon()
{
if(level.drawfriend)
{
if(self.pers["team"] == "allies")
{
self.headicon = game["headicon_allies"];
self.headiconteam = "allies";
}
else
{
self.headicon = game["headicon_axis"];
self.headiconteam = "axis";
}
}
}
updateFriendIconSettings()
{
drawfriend = maps\mp\_utility::getIntProperty("scr_drawfriend", level.drawfriend);
if(level.drawfriend != drawfriend)
{
level.drawfriend = drawfriend;
updateFriendIcons();
}
}
updateFriendIcons()
{
// for all living players, show the appropriate headicon
players = level.players;
for(i = 0; i < players.size; i++)
{
player = players[i];
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
{
if(level.drawfriend)
{
if(player.pers["team"] == "allies")
{
player.headicon = game["headicon_allies"];
player.headiconteam = "allies";
}
else
{
player.headicon = game["headicon_axis"];
player.headiconteam = "axis";
}
}
else
{
players = level.players;
for(i = 0; i < players.size; i++)
{
player = players[i];
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
player.headicon = "";
}
}
}
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+414
View File
@@ -0,0 +1,414 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
getHighestScoringPlayer()
{
updatePlacement();
if ( !level.placement["all"].size )
return ( undefined );
else
return ( level.placement["all"][0] );
}
getLosingPlayers()
{
updatePlacement();
players = level.placement["all"];
losingPlayers = [];
foreach ( player in players )
{
if ( player == level.placement["all"][0] )
continue;
losingPlayers[losingPlayers.size] = player;
}
return losingPlayers;
}
givePlayerScore( event, player, victim )
{
if ( isDefined( level.nukeIncoming ) )
return;
score = player.pers["score"];
onPlayerScore( event, player, victim );
if ( score == player.pers["score"] )
return;
if ( !player rankingEnabled() && !level.hardcoreMode )
player thread maps\mp\gametypes\_rank::scorePopup( (player.pers["score"] - score), false, (0.85,0.85,0.85), 0 );
player maps\mp\gametypes\_persistence::statAdd( "score", (player.pers["score"] - score) );
player.score = player.pers["score"];
player maps\mp\gametypes\_persistence::statSetChild( "round", "score", player.score );
if ( !level.teambased )
thread sendUpdatedDMScores();
player maps\mp\gametypes\_gamelogic::checkPlayerScoreLimitSoon();
scoreEndedMatch = player maps\mp\gametypes\_gamelogic::checkScoreLimit();
if ( scoreEndedMatch && event == "kill" )
player.finalKill = true;
}
onPlayerScore( event, player, victim )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( event );
assert( isDefined( score ) );
player.pers["score"] += score * level.objectivePointsMod;
}
// Seems to only be used for reducing a player's score due to suicide
_setPlayerScore( player, score )
{
if ( score == player.pers["score"] )
return;
player.pers["score"] = score;
player.score = player.pers["score"];
player thread maps\mp\gametypes\_gamelogic::checkScoreLimit();
}
_getPlayerScore( player )
{
return player.pers["score"];
}
giveTeamScoreForObjective( team, score )
{
if ( isDefined( level.nukeIncoming ) )
return;
score *= level.objectivePointsMod;
teamScore = game["teamScores"][team];
otherTeam = level.otherTeam[team];
if ( game["teamScores"][team] > game["teamScores"][otherTeam] )
level.wasWinning = team;
else if ( game["teamScores"][otherTeam] > game["teamScores"][team] )
level.wasWinning = otherTeam;
_setTeamScore( team, _getTeamScore( team ) + score );
isWinning = "none";
if ( game["teamScores"][team] > game["teamScores"][otherTeam] )
isWinning = team;
else if ( game["teamScores"][otherTeam] > game["teamScores"][team] )
isWinning = otherTeam;
if ( !level.splitScreen && isWinning != "none" && isWinning != level.wasWinning && getTime() - level.lastStatusTime > 5000 && getScoreLimit() != 1 )
{
level.lastStatusTime = getTime();
leaderDialog( "lead_taken", isWinning, "status" );
if ( level.wasWinning != "none")
leaderDialog( "lead_lost", level.wasWinning, "status" );
}
if ( isWinning != "none" )
level.wasWinning = isWinning;
}
getWinningTeam()
{
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
return ( "allies" );
else if ( game["teamScores"]["allies"] < game["teamScores"]["axis"] )
return ( "axis" );
return ( "none" );
}
_setTeamScore( team, teamScore )
{
if ( teamScore == game["teamScores"][team] )
return;
if ( isDefined( level.nukeIncoming ) )
return;
game["teamScores"][team] = teamScore;
updateTeamScore( team );
if ( game["status"] == "overtime" )
thread maps\mp\gametypes\_gamelogic::onScoreLimit();
else
{
thread maps\mp\gametypes\_gamelogic::checkTeamScoreLimitSoon( team );
thread maps\mp\gametypes\_gamelogic::checkScoreLimit();
}
}
updateTeamScore( team )
{
assert( level.teamBased );
teamScore = 0;
if ( !isRoundBased() || !isObjectiveBased() )
teamScore = _getTeamScore( team );
else
teamScore = game["roundsWon"][team];
setTeamScore( team, teamScore );
//thread sendUpdatedTeamScores();
}
_getTeamScore( team )
{
return game["teamScores"][team];
}
sendUpdatedTeamScores()
{
level notify("updating_scores");
level endon("updating_scores");
wait .05;
WaitTillSlowProcessAllowed();
foreach ( player in level.players )
player updateScores();
}
sendUpdatedDMScores()
{
level notify("updating_dm_scores");
level endon("updating_dm_scores");
wait .05;
WaitTillSlowProcessAllowed();
for ( i = 0; i < level.players.size; i++ )
{
level.players[i] updateDMScores();
level.players[i].updatedDMScores = true;
}
}
removeDisconnectedPlayerFromPlacement()
{
offset = 0;
numPlayers = level.placement["all"].size;
found = false;
for ( i = 0; i < numPlayers; i++ )
{
if ( level.placement["all"][i] == self )
found = true;
if ( found )
level.placement["all"][i] = level.placement["all"][ i + 1 ];
}
if ( !found )
return;
level.placement["all"][ numPlayers - 1 ] = undefined;
assert( level.placement["all"].size == numPlayers - 1 );
if ( level.teamBased )
{
updateTeamPlacement();
return;
}
numPlayers = level.placement["all"].size;
for ( i = 0; i < numPlayers; i++ )
{
player = level.placement["all"][i];
player notify( "update_outcome" );
}
}
updatePlacement()
{
prof_begin("updatePlacement");
placementAll = [];
foreach ( player in level.players )
{
if ( isDefined( player.connectedPostGame ) || (player.pers["team"] != "allies" && player.pers["team"] != "axis") )
continue;
placementAll[placementAll.size] = player;
}
for ( i = 1; i < placementAll.size; i++ )
{
player = placementAll[i];
playerScore = player.score;
// for ( j = i - 1; j >= 0 && (player.score > placementAll[j].score || (player.score == placementAll[j].score && player.deaths < placementAll[j].deaths)); j-- )
for ( j = i - 1; j >= 0 && getBetterPlayer( player, placementAll[j] ) == player; j-- )
placementAll[j + 1] = placementAll[j];
placementAll[j + 1] = player;
}
level.placement["all"] = placementAll;
if ( level.teamBased )
updateTeamPlacement();
prof_end("updatePlacement");
}
getBetterPlayer( playerA, playerB )
{
if ( playerA.score > playerB.score )
return playerA;
if ( playerB.score > playerA.score )
return playerB;
if ( playerA.deaths < playerB.deaths )
return playerA;
if ( playerB.deaths < playerA.deaths )
return playerB;
// TODO: more metrics for getting the better player
if ( cointoss() )
return playerA;
else
return playerB;
}
updateTeamPlacement()
{
placement["allies"] = [];
placement["axis"] = [];
placement["spectator"] = [];
assert( level.teamBased );
placementAll = level.placement["all"];
placementAllSize = placementAll.size;
for ( i = 0; i < placementAllSize; i++ )
{
player = placementAll[i];
team = player.pers["team"];
placement[team][ placement[team].size ] = player;
}
level.placement["allies"] = placement["allies"];
level.placement["axis"] = placement["axis"];
}
initialDMScoreUpdate()
{
// the first time we call updateDMScores on a player, we have to send them the whole scoreboard.
// by calling updateDMScores on each player one at a time,
// we can avoid having to send the entire scoreboard to every single player
// the first time someone kills someone else.
wait .2;
numSent = 0;
while(1)
{
didAny = false;
players = level.players;
for ( i = 0; i < players.size; i++ )
{
player = players[i];
if ( !isdefined( player ) )
continue;
if ( isdefined( player.updatedDMScores ) )
continue;
player.updatedDMScores = true;
player updateDMScores();
didAny = true;
wait .5;
}
if ( !didAny )
wait 3; // let more players connect
}
}
processAssist( killedplayer )
{
self endon("disconnect");
killedplayer endon("disconnect");
wait .05; // don't ever run on the same frame as the playerkilled callback.
WaitTillSlowProcessAllowed();
if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
return;
if ( self.pers["team"] == killedplayer.pers["team"] )
return;
self thread [[level.onXPEvent]]( "assist" );
self incPersStat( "assists", 1 );
self.assists = self getPersStat( "assists" );
self incPlayerStat( "assists", 1 );
givePlayerScore( "assist", self, killedplayer );
self thread giveAdrenaline( "assist" );
self thread maps\mp\gametypes\_missions::playerAssist();
}
processShieldAssist( killedPlayer )
{
self endon( "disconnect" );
killedPlayer endon( "disconnect" );
wait .05; // don't ever run on the same frame as the playerkilled callback.
WaitTillSlowProcessAllowed();
if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
return;
if ( self.pers["team"] == killedplayer.pers["team"] )
return;
self thread [[level.onXPEvent]]( "assist" );
self thread [[level.onXPEvent]]( "assist" );
self incPersStat( "assists", 1 );
self.assists = self getPersStat( "assists" );
self incPlayerStat( "assists", 1 );
givePlayerScore( "assist", self, killedplayer );
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "shield_assist" );
self thread maps\mp\gametypes\_missions::playerAssist();
}
+4
View File
@@ -0,0 +1,4 @@
/*QUAKED mp_global_intermission (1.0 0.0 1.0) (-16 -16 -16) (16 16 16)
Intermission is randomly viewed from one of these positions.
Spectators spawn randomly at one of these positions.
*/
+255
View File
@@ -0,0 +1,255 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
level.splitscreen = isSplitScreen();
level.ps3 = (getDvar( "ps3Game" ) == "true");
level.xenon = (getDvar( "xenonGame" ) == "true");
level.console = (level.ps3 || level.xenon);
level.onlineGame = getDvarInt( "onlinegame" );
level.rankedMatch = ( !level.onlineGame || !getDvarInt( "xblive_privatematch" ) );
/#
if ( getdvarint( "scr_forcerankedmatch" ) == 1 )
{
level.onlineGame = true;
level.rankedMatch = true;
}
#/
level.script = toLower( getDvar( "mapname" ) );
level.gametype = toLower( getDvar( "g_gametype" ) );
level.otherTeam["allies"] = "axis";
level.otherTeam["axis"] = "allies";
level.teamBased = false;
level.objectiveBased = false;
level.endGameOnTimeLimit = true;
level.showingFinalKillcam = false;
level.tiSpawnDelay = getDvarInt( "scr_tispawndelay" );
// hack to allow maps with no scripts to run correctly
if ( !isDefined( level.tweakablesInitialized ) )
maps\mp\gametypes\_tweakables::init();
precacheString( &"MP_HALFTIME" );
precacheString( &"MP_OVERTIME" );
precacheString( &"MP_ROUNDEND" );
precacheString( &"MP_INTERMISSION" );
precacheString( &"MP_SWITCHING_SIDES" );
precacheString( &"MP_FRIENDLY_FIRE_WILL_NOT" );
precacheString( &"PLATFORM_REVIVE" );
precacheString( &"MP_OBITUARY_NEUTRAL" );
precacheString( &"MP_OBITUARY_FRIENDLY" );
precacheString( &"MP_OBITUARY_ENEMY" );
if ( level.splitScreen )
precacheString( &"MP_ENDED_GAME" );
else
precacheString( &"MP_HOST_ENDED_GAME" );
level.halftimeType = "halftime";
level.halftimeSubCaption = &"MP_SWITCHING_SIDES";
level.lastStatusTime = 0;
level.wasWinning = "none";
level.lastSlowProcessFrame = 0;
level.placement["allies"] = [];
level.placement["axis"] = [];
level.placement["all"] = [];
level.postRoundTime = 5.0;
level.playersLookingForSafeSpawn = [];
registerDvars();
precacheModel( "vehicle_mig29_desert" );
precacheModel( "projectile_cbu97_clusterbomb" );
precacheModel( "tag_origin" );
level.fx_airstrike_afterburner = loadfx ("fire/jet_afterburner");
level.fx_airstrike_contrail = loadfx ("smoke/jet_contrail");
if ( level.console )
precacheLeaderboards( "LB_KILLS LB_WINS LB_TOTALXP LB_ACCURACY" );
level.teamCount["allies"] = 0;
level.teamCount["axis"] = 0;
level.teamCount["spectator"] = 0;
level.aliveCount["allies"] = 0;
level.aliveCount["axis"] = 0;
level.aliveCount["spectator"] = 0;
level.livesCount["allies"] = 0;
level.livesCount["axis"] = 0;
level.oneLeftTime = [];
level.hasSpawned["allies"] = 0;
level.hasSpawned["axis"] = 0;
/#
if ( getdvarint( "scr_runlevelandquit" ) == 1 )
{
thread runLevelAndQuit();
}
#/
}
/#
runLevelAndQuit()
{
wait 1;
while ( level.players.size < 1 )
{
wait 0.5;
}
wait 0.5;
level notify( "game_ended" );
exitLevel();
}
#/
registerDvars()
{
makeDvarServerInfo( "ui_bomb_timer", 0 );
makeDvarServerInfo( "ui_danger_team", "" );
makeDvarServerInfo( "camera_thirdPerson", getDvarInt( "scr_thirdPerson" ) );
}
SetupCallbacks()
{
level.onXPEvent = ::onXPEvent;
level.getSpawnPoint = ::blank;
level.onSpawnPlayer = ::blank;
level.onRespawnDelay = ::blank;
level.onTimeLimit = maps\mp\gametypes\_gamelogic::default_onTimeLimit;
level.onHalfTime = maps\mp\gametypes\_gamelogic::default_onHalfTime;
level.onDeadEvent = maps\mp\gametypes\_gamelogic::default_onDeadEvent;
level.onOneLeftEvent = maps\mp\gametypes\_gamelogic::default_onOneLeftEvent;
level.onPrecacheGametype = ::blank;
level.onStartGameType = ::blank;
level.onPlayerKilled = ::blank;
level.autoassign = maps\mp\gametypes\_menus::menuAutoAssign;
level.spectator = maps\mp\gametypes\_menus::menuSpectator;
level.class = maps\mp\gametypes\_menus::menuClass;
level.allies = maps\mp\gametypes\_menus::menuAllies;
level.axis = maps\mp\gametypes\_menus::menuAxis;
}
blank( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 )
{
}
/#
xpRateThread()
{
self endon ( "death" );
self endon ( "disconnect" );
level endon ( "game_ended" );
gameFlagWait( "prematch_done" );
for ( ;; )
{
wait ( 5.0 );
if ( level.players[0].pers["team"] == "allies" || level.players[0].pers["team"] == "axis" )
self maps\mp\gametypes\_rank::giveRankXP( "kill", int(min( getDvarInt( "scr_xprate" ), 50 )) );
}
}
#/
testMenu()
{
self endon ( "death" );
self endon ( "disconnect" );
for ( ;; )
{
wait ( 10.0 );
notifyData = spawnStruct();
notifyData.titleText = &"MP_CHALLENGE_COMPLETED";
notifyData.notifyText = "wheee";
notifyData.sound = "mp_challenge_complete";
self thread maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
}
}
testShock()
{
self endon ( "death" );
self endon ( "disconnect" );
for ( ;; )
{
wait ( 3.0 );
numShots = randomInt( 6 );
for ( i = 0; i < numShots; i++ )
{
iPrintLnBold( numShots );
self shellShock( "frag_grenade_mp", 0.2 );
wait ( 0.1 );
}
}
}
onXPEvent( event )
{
//self thread maps\mp\_loot::giveMoney( event, 10 );
self thread maps\mp\gametypes\_rank::giveRankXP( event );
}
fakeLag()
{
self endon ( "disconnect" );
self.fakeLag = randomIntRange( 50, 150 );
for ( ;; )
{
self setClientDvar( "fakelag_target", self.fakeLag );
wait ( randomFloatRange( 5.0, 15.0 ) );
}
}
debugLine( start, end )
{
for ( i = 0; i < 50; i++ )
{
line( start, end );
wait .05;
}
}
+221
View File
@@ -0,0 +1,221 @@
#include maps\mp\_utility;
init()
{
level.healthOverlayCutoff = 0.55;
regenTime = 5;
regenTime = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "healthregentime" );
level.playerHealth_RegularRegenDelay = regenTime * 1000;
level.healthRegenDisabled = (level.playerHealth_RegularRegenDelay <= 0);
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
self thread playerHealthRegen();
self thread showTempDamage();
}
}
showTempDamage()
{
self endon ( "death" );
self endon ( "disconnect" );
/#
setDevDvar( "scr_damage_wait", 0 );
setDevDvar( "scr_damage_fadein", 0.25 );
setDevDvar( "scr_damage_fadeout", 0.5 );
setDevDvar( "scr_damage_holdtime", 0.5 );
setDevDvar( "scr_damage_numfades", 5 );
for ( ;; )
{
while ( getDvarFloat( "scr_damage_wait" ) <= 0 )
wait ( 1.0 );
wait ( getDvarFloat( "scr_damage_wait" ) );
for ( i = 0; i < getDvarInt( "scr_damage_numfades" ); i++ )
{
self VisionSetNakedForPlayer( "mp_crash_damage", getDvarFloat( "scr_damage_fadein" ) * (getDvarInt( "scr_damage_numfades" ) - i) );
wait ( getDvarFloat( "scr_damage_fadein" ) + getDvarFloat( "scr_damage_holdtime" ) );
self VisionSetNakedForPlayer( "mp_crash", getDvarFloat( "scr_damage_fadeout" ) * getDvarInt( "scr_damage_numfades" ) );
wait ( getDvarFloat( "scr_damage_fadeout" ) );
}
}
#/
}
playerHealthRegen()
{
self endon ( "death" );
self endon ( "disconnect" );
self endon ( "joined_team" );
self endon ( "joined_spectators" );
if ( self.health <= 0 )
{
assert( !isalive( self ) );
return;
}
oldhealth = self.maxhealth;
regenRate = 0.1;
veryHurt = false;
self.breathingStopTime = -10000;
thread playerBreathingSound( self.maxhealth * 0.35 );
lastSoundTime_Recover = 0;
hurtTime = 0;
newHealth = 0;
for (;;)
{
wait ( 0.05 );
if ( isDefined( level.hostMigrationTimer ) )
{
timePassed = maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
hurtTime += timePassed;
lastSoundTime_Recover += timePassed;
}
if ( self.health == self.maxhealth || ( level.dieHardMode && isDefined( self.healthClamped ) && self.health >= self.healthClamped ) ) // runs every frame
{
oldHealth = self.maxhealth;
veryHurt = false;
self.atBrinkOfDeath = false;
continue;
}
if ( self.health <= 0 ) // player dead
return;
curTime = getTime();
ratio = self.health / self.maxHealth;
if ( ratio <= level.healthOverlayCutoff )
{
if ( !veryHurt )
hurtTime = curTime;
veryHurt = true;
self.atBrinkOfDeath = true;
}
if ( self.health >= oldhealth )
{
if ( curTime - hurtTime < level.playerHealth_RegularRegenDelay )
continue;
if ( level.healthRegenDisabled )
{
wait ( 3.0 );
self.maxHealth = int( max( self.health, 2 ) );
self.health = self.maxHealth;
continue;
}
if ( curTime - lastSoundTime_Recover > level.playerHealth_RegularRegenDelay )
{
lastSoundTime_Recover = curTime;
if ( !level.gameEnded )
self playLocalSound("breathing_better");
}
if ( veryHurt )
{
newHealth = ratio;
if ( curTime > hurtTime + 3000 )
newHealth += regenRate;
}
else
{
newHealth = 1;
}
if ( newHealth >= 1.0 )
{
if ( veryHurt )
self maps\mp\gametypes\_missions::healthRegenerated();
self maps\mp\gametypes\_damage::resetAttackerList();
newHealth = 1.0;
}
if (newHealth <= 0)
{
// Player is dead
return;
}
self setNormalHealth (newHealth);
oldHealth = self.health;
continue;
}
// first time damaged
oldHealth = self.health;
hurtTime = curTime;
self.breathingStopTime = hurtTime + 6000;
}
}
playerBreathingSound( healthcap )
{
level endon ( "game_ended" );
self endon ( "death" );
self endon ( "disconnect" );
self endon ( "joined_team" );
self endon ( "joined_spectators" );
wait ( 2 );
for (;;)
{
wait ( 0.2 );
if ( self.health <= 0 )
return;
// Player still has a lot of health so no breathing sound
if ( self.health >= healthcap )
continue;
if ( level.healthRegenDisabled && gettime() > self.breathingStopTime )
continue;
self playLocalSound( "breathing_hurt" );
wait ( .784 );
wait ( 0.1 + randomfloat (0.8) );
}
}
+168
View File
@@ -0,0 +1,168 @@
#include maps\mp\_utility;
#include common_scripts\utility;
Callback_HostMigration()
{
level.hostMigrationReturnedPlayerCount = 0;
if ( level.gameEnded )
{
println( "Migration starting at time " + gettime() + ", but game has ended, so no countdown." );
return;
}
println( "Migration starting at time " + gettime() );
level.hostMigrationTimer = true;
level notify( "host_migration_begin" );
maps\mp\gametypes\_gamelogic::UpdateTimerPausedness();
foreach ( player in level.players )
{
player thread hostMigrationTimerThink();
}
level endon( "host_migration_begin" );
hostMigrationWait();
level.hostMigrationTimer = undefined;
println( "Migration finished at time " + gettime() );
level notify( "host_migration_end" );
maps\mp\gametypes\_gamelogic::UpdateTimerPausedness();
}
hostMigrationWait()
{
level endon( "game_ended" );
level endon( "nuke_death" );
// start with a 20 second wait.
// once we get enough players, or the first 15 seconds pass, switch to a 5 second timer.
thread maps\mp\gametypes\_gamelogic::matchStartTimer( "waiting_for_players", 20.0 );
hostMigrationWaitForPlayers();
thread maps\mp\gametypes\_gamelogic::matchStartTimer( "match_resuming_in", 5.0 );
wait 5;
}
hostMigrationWaitForPlayers()
{
level endon( "hostmigration_enoughplayers" );
wait 15;
}
hostMigrationTimerThink_Internal()
{
level endon( "host_migration_begin" );
level endon( "host_migration_end" );
self.hostMigrationControlsFrozen = false;
while ( !isReallyAlive( self ) )
{
self waittill( "spawned" );
}
self.hostMigrationControlsFrozen = true;
self freezeControlsWrapper( true );
level waittill( "host_migration_end" );
}
hostMigrationTimerThink()
{
self endon( "disconnect" );
self setClientDvar( "cg_scoreboardPingGraph", "0" );
hostMigrationTimerThink_Internal();
if ( self.hostMigrationControlsFrozen )
self freezeControlsWrapper( false );
self setClientDvar( "cg_scoreboardPingGraph", "1" );
}
waitTillHostMigrationDone()
{
if ( !isDefined( level.hostMigrationTimer ) )
return 0;
starttime = gettime();
level waittill( "host_migration_end" );
return gettime() - starttime;
}
waitTillHostMigrationStarts( duration )
{
if ( isDefined( level.hostMigrationTimer ) )
return;
level endon( "host_migration_begin" );
wait duration;
}
waitLongDurationWithHostMigrationPause( duration )
{
if ( duration == 0 )
return;
assert( duration > 0 );
starttime = gettime();
endtime = gettime() + duration * 1000;
while ( gettime() < endtime )
{
waitTillHostMigrationStarts( (endtime - gettime()) / 1000 );
if ( isDefined( level.hostMigrationTimer ) )
{
timePassed = waitTillHostMigrationDone();
endtime += timePassed;
}
}
assert( gettime() == endtime );
waitTillHostMigrationDone();
return gettime() - starttime;
}
waitLongDurationWithGameEndTimeUpdate( duration )
{
if ( duration == 0 )
return;
assert( duration > 0 );
starttime = gettime();
endtime = gettime() + duration * 1000;
while ( gettime() < endtime )
{
waitTillHostMigrationStarts( (endtime - gettime()) / 1000 );
while ( isDefined( level.hostMigrationTimer ) )
{
endTime += 1000;
setGameEndTime( int( endTime ) );
wait 1;
}
}
assert( gettime() == endtime );
while ( isDefined( level.hostMigrationTimer ) )
{
endTime += 1000;
setGameEndTime( int( endTime ) );
wait 1;
}
return gettime() - starttime;
}
+162
View File
@@ -0,0 +1,162 @@
/*
// Edge relative placement values for rect->h_align and rect->v_align
#define HORIZONTAL_ALIGN_SUBLEFT 0 // left edge of a 4:3 screen (safe area not included)
#define HORIZONTAL_ALIGN_LEFT 1 // left viewable (safe area) edge
#define HORIZONTAL_ALIGN_CENTER 2 // center of the screen (reticle)
#define HORIZONTAL_ALIGN_RIGHT 3 // right viewable (safe area) edge
#define HORIZONTAL_ALIGN_FULLSCREEN 4 // disregards safe area
#define HORIZONTAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
#define HORIZONTAL_ALIGN_TO640 6 // scales a real-screen resolution x down into the 0 - 640 range
#define HORIZONTAL_ALIGN_CENTER_SAFEAREA 7 // center of the safearea
#define HORIZONTAL_ALIGN_MAX HORIZONTAL_ALIGN_CENTER_SAFEAREA
#define HORIZONTAL_ALIGN_DEFAULT HORIZONTAL_ALIGN_SUBLEFT
#define VERTICAL_ALIGN_SUBTOP 0 // top edge of the 4:3 screen (safe area not included)
#define VERTICAL_ALIGN_TOP 1 // top viewable (safe area) edge
#define VERTICAL_ALIGN_CENTER 2 // center of the screen (reticle)
#define VERTICAL_ALIGN_BOTTOM 3 // bottom viewable (safe area) edge
#define VERTICAL_ALIGN_FULLSCREEN 4 // disregards safe area
#define VERTICAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
#define VERTICAL_ALIGN_TO480 6 // scales a real-screen resolution y down into the 0 - 480 range
#define VERTICAL_ALIGN_CENTER_SAFEAREA 7 // center of the save area
#define VERTICAL_ALIGN_MAX VERTICAL_ALIGN_CENTER_SAFEAREA
#define VERTICAL_ALIGN_DEFAULT VERTICAL_ALIGN_SUBTOP
static const char *g_he_font[] =
{
"default", // HE_FONT_DEFAULT
"bigfixed", // HE_FONT_BIGFIXED
"smallfixed", // HE_FONT_SMALLFIXED
"objective", // HE_FONT_OBJECTIVE
};
// These values correspond to the defines in q_shared.h
static const char *g_he_alignx[] =
{
"left", // HE_ALIGN_LEFT
"center", // HE_ALIGN_CENTER
"right", // HE_ALIGN_RIGHT
};
static const char *g_he_aligny[] =
{
"top", // HE_ALIGN_TOP
"middle", // HE_ALIGN_MIDDLE
"bottom", // HE_ALIGN_BOTTOM
};
// These values correspond to the defines in menudefinition.h
static const char *g_he_horzalign[] =
{
"subleft", // HORIZONTAL_ALIGN_SUBLEFT
"left", // HORIZONTAL_ALIGN_LEFT
"center", // HORIZONTAL_ALIGN_CENTER
"right", // HORIZONTAL_ALIGN_RIGHT
"fullscreen", // HORIZONTAL_ALIGN_FULLSCREEN
"noscale", // HORIZONTAL_ALIGN_NOSCALE
"alignto640", // HORIZONTAL_ALIGN_TO640
"center_safearea", // HORIZONTAL_ALIGN_CENTER_SAFEAREA
};
cassert( ARRAY_COUNT( g_he_horzalign ) == HORIZONTAL_ALIGN_MAX + 1 );
static const char *g_he_vertalign[] =
{
"subtop", // VERTICAL_ALIGN_SUBTOP
"top", // VERTICAL_ALIGN_TOP
"middle", // VERTICAL_ALIGN_CENTER
"bottom", // VERTICAL_ALIGN_BOTTOM
"fullscreen", // VERTICAL_ALIGN_FULLSCREEN
"noscale", // VERTICAL_ALIGN_NOSCALE
"alignto480", // VERTICAL_ALIGN_TO480
"center_safearea", // VERTICAL_ALIGN_CENTER_SAFEAREA
};
cassert( ARRAY_COUNT( g_he_vertalign ) == VERTICAL_ALIGN_MAX + 1 );
*/
init()
{
precacheShader( "progress_bar_bg" );
precacheShader( "progress_bar_fg" );
precacheShader( "progress_bar_fill" );
level.uiParent = spawnstruct();
level.uiParent.horzAlign = "left";
level.uiParent.vertAlign = "top";
level.uiParent.alignX = "left";
level.uiParent.alignY = "top";
level.uiParent.x = 0;
level.uiParent.y = 0;
level.uiParent.width = 0;
level.uiParent.height = 0;
level.uiParent.children = [];
level.fontHeight = 12;
level.hud["allies"] = spawnstruct();
level.hud["axis"] = spawnstruct();
// we can, of course, separate out the following constants for splitscreen.
// primary progress bars are for things like capturing flags or planting bombs - big, important things that happen as you play a gametype
level.primaryProgressBarY = -61; // from center
level.primaryProgressBarX = 0;
level.primaryProgressBarHeight = 9; //28; // this is the height and width of the whole progress bar, including the outline. the part that actually moves is 2 pixels smaller.
level.primaryProgressBarWidth = 120;
level.primaryProgressBarTextY = -75;
level.primaryProgressBarTextX = 0;
level.primaryProgressBarFontSize = .6; // 1.4 before font change from "objective"
level.teamProgressBarY = 32; // 205;
level.teamProgressBarHeight = 14;
level.teamProgressBarWidth = 192;
level.teamProgressBarTextY = 8; // 155;
level.teamProgressBarFontSize = 1.65;
if ( level.splitscreen )
{
level.lowerTextYAlign = "BOTTOM";
level.lowerTextY = -76;
level.lowerTextFontSize = 1.14;
}
else
{
level.lowerTextYAlign = "CENTER";
level.lowerTextY = 70;
level.lowerTextFontSize = 1.6;
}
}
fontPulseInit( maxFontScale )
{
self.baseFontScale = self.fontScale;
if ( isDefined( maxFontScale ) )
self.maxFontScale = min( maxFontScale, 6.3 );
else
self.maxFontScale = min( self.fontScale * 2, 6.3 );
self.inFrames = 2;
self.outFrames = 4;
}
fontPulse(player)
{
self notify ( "fontPulse" );
self endon ( "fontPulse" );
self endon( "death" );
player endon("disconnect");
player endon("joined_team");
player endon("joined_spectators");
self ChangeFontScaleOverTime( self.inFrames * 0.05 );
self.fontScale = self.maxFontScale;
wait self.inFrames * 0.05;
self ChangeFontScaleOverTime( self.outFrames * 0.05 );
self.fontScale = self.baseFontScale;
}
File diff suppressed because it is too large. Load diff
+793
View File
@@ -0,0 +1,793 @@
#include maps\mp\_utility;
setParent( element )
{
if ( isDefined( self.parent ) && self.parent == element )
return;
if ( isDefined( self.parent ) )
self.parent removeChild( self );
self.parent = element;
self.parent addChild( self );
if ( isDefined( self.point ) )
self setPoint( self.point, self.relativePoint, self.xOffset, self.yOffset );
else
self setPoint( "TOPLEFT" );
}
getParent()
{
return self.parent;
}
addChild( element )
{
element.index = self.children.size;
self.children[self.children.size] = element;
}
removeChild( element )
{
element.parent = undefined;
if ( self.children[self.children.size-1] != element )
{
self.children[element.index] = self.children[self.children.size-1];
self.children[element.index].index = element.index;
}
self.children[self.children.size-1] = undefined;
element.index = undefined;
}
setPoint( point, relativePoint, xOffset, yOffset, moveTime )
{
if ( !isDefined( moveTime ) )
moveTime = 0;
element = self getParent();
if ( moveTime )
self moveOverTime( moveTime );
if ( !isDefined( xOffset ) )
xOffset = 0;
self.xOffset = xOffset;
if ( !isDefined( yOffset ) )
yOffset = 0;
self.yOffset = yOffset;
self.point = point;
self.alignX = "center";
self.alignY = "middle";
if ( isSubStr( point, "TOP" ) )
self.alignY = "top";
if ( isSubStr( point, "BOTTOM" ) )
self.alignY = "bottom";
if ( isSubStr( point, "LEFT" ) )
self.alignX = "left";
if ( isSubStr( point, "RIGHT" ) )
self.alignX = "right";
if ( !isDefined( relativePoint ) )
relativePoint = point;
self.relativePoint = relativePoint;
relativeX = "center_adjustable";
relativeY = "middle";
if ( isSubStr( relativePoint, "TOP" ) )
relativeY = "top_adjustable";
if ( isSubStr( relativePoint, "BOTTOM" ) )
relativeY = "bottom_adjustable";
if ( isSubStr( relativePoint, "LEFT" ) )
relativeX = "left_adjustable";
if ( isSubStr( relativePoint, "RIGHT" ) )
relativeX = "right_adjustable";
if ( element == level.uiParent )
{
self.horzAlign = relativeX;
self.vertAlign = relativeY;
}
else
{
self.horzAlign = element.horzAlign;
self.vertAlign = element.vertAlign;
}
if ( strip_suffix( relativeX, "_adjustable" ) == element.alignX )
{
offsetX = 0;
xFactor = 0;
}
else if ( relativeX == "center" || element.alignX == "center" )
{
offsetX = int(element.width / 2);
if ( relativeX == "left_adjustable" || element.alignX == "right" )
xFactor = -1;
else
xFactor = 1;
}
else
{
offsetX = element.width;
if ( relativeX == "left_adjustable" )
xFactor = -1;
else
xFactor = 1;
}
self.x = element.x + (offsetX * xFactor);
if ( strip_suffix( relativeY, "_adjustable" ) == element.alignY )
{
offsetY = 0;
yFactor = 0;
}
else if ( relativeY == "middle" || element.alignY == "middle" )
{
offsetY = int(element.height / 2);
if ( relativeY == "top_adjustable" || element.alignY == "bottom" )
yFactor = -1;
else
yFactor = 1;
}
else
{
offsetY = element.height;
if ( relativeY == "top_adjustable" )
yFactor = -1;
else
yFactor = 1;
}
self.y = element.y + (offsetY * yFactor);
self.x += self.xOffset;
self.y += self.yOffset;
switch ( self.elemType )
{
case "bar":
setPointBar( point, relativePoint, xOffset, yOffset );
break;
}
self updateChildren();
}
setPointBar( point, relativePoint, xOffset, yOffset )
{
self.bar.horzAlign = self.horzAlign;
self.bar.vertAlign = self.vertAlign;
self.bar.alignX = "left";
self.bar.alignY = self.alignY;
self.bar.y = self.y;
if ( self.alignX == "left" )
self.bar.x = self.x;
else if ( self.alignX == "right" )
self.bar.x = self.x - self.width;
else
self.bar.x = self.x - int(self.width / 2);
if ( self.alignY == "top" )
self.bar.y = self.y;
else if ( self.alignY == "bottom" )
self.bar.y = self.y;
self updateBar( self.bar.frac );
}
updateBar( barFrac, rateOfChange )
{
if ( self.elemType == "bar" )
updateBarScale( barFrac, rateOfChange );
}
updateBarScale( barFrac, rateOfChange ) // rateOfChange is optional and is in "(entire bar lengths) per second"
{
barWidth = int(self.width * barFrac + 0.5); // (+ 0.5 rounds)
if ( !barWidth )
barWidth = 1;
self.bar.frac = barFrac;
self.bar setShader( self.bar.shader, barWidth, self.height );
assertEx( barWidth <= self.width, "barWidth <= self.width: " + barWidth + " <= " + self.width + " - barFrac was " + barFrac );
//if barWidth is bigger than self.width then we are drawing more than 100%
if ( isDefined( rateOfChange ) && barWidth < self.width )
{
if ( rateOfChange > 0 )
{
//printLn( "scaling from: " + barWidth + " to " + self.width + " at " + ((1 - barFrac) / rateOfChange) );
assertex( ((1 - barFrac) / rateOfChange) > 0, "barFrac: " + barFrac + "rateOfChange: " + rateOfChange );
self.bar scaleOverTime( (1 - barFrac) / rateOfChange, self.width, self.height );
}
else if ( rateOfChange < 0 )
{
//printLn( "scaling from: " + barWidth + " to " + 0 + " at " + (barFrac / (-1 * rateOfChange)) );
assertex( (barFrac / (-1 * rateOfChange)) > 0, "barFrac: " + barFrac + "rateOfChange: " + rateOfChange );
self.bar scaleOverTime( barFrac / (-1 * rateOfChange), 1, self.height );
}
}
self.bar.rateOfChange = rateOfChange;
self.bar.lastUpdateTime = getTime();
}
createFontString( font, fontScale )
{
fontElem = newClientHudElem( self );
fontElem.elemType = "font";
fontElem.font = font;
fontElem.fontscale = fontScale;
fontElem.baseFontScale = fontScale;
fontElem.x = 0;
fontElem.y = 0;
fontElem.width = 0;
fontElem.height = int(level.fontHeight * fontScale);
fontElem.xOffset = 0;
fontElem.yOffset = 0;
fontElem.children = [];
fontElem setParent( level.uiParent );
fontElem.hidden = false;
return fontElem;
}
createServerFontString( font, fontScale, team )
{
if ( isDefined( team ) )
fontElem = newTeamHudElem( team );
else
fontElem = newHudElem();
fontElem.elemType = "font";
fontElem.font = font;
fontElem.fontscale = fontScale;
fontElem.baseFontScale = fontScale;
fontElem.x = 0;
fontElem.y = 0;
fontElem.width = 0;
fontElem.height = int(level.fontHeight * fontScale);
fontElem.xOffset = 0;
fontElem.yOffset = 0;
fontElem.children = [];
fontElem setParent( level.uiParent );
fontElem.hidden = false;
return fontElem;
}
createServerTimer( font, fontScale, team )
{
if ( isDefined( team ) )
timerElem = newTeamHudElem( team );
else
timerElem = newHudElem();
timerElem.elemType = "timer";
timerElem.font = font;
timerElem.fontScale = fontScale;
timerElem.baseFontScale = fontScale;
timerElem.x = 0;
timerElem.y = 0;
timerElem.width = 0;
timerElem.height = int(level.fontHeight * fontScale);
timerElem.xOffset = 0;
timerElem.yOffset = 0;
timerElem.children = [];
timerElem setParent( level.uiParent );
timerElem.hidden = false;
return timerElem;
}
createTimer( font, fontScale )
{
timerElem = newClientHudElem( self );
timerElem.elemType = "timer";
timerElem.font = font;
timerElem.fontScale = fontScale;
timerElem.baseFontScale = fontScale;
timerElem.x = 0;
timerElem.y = 0;
timerElem.width = 0;
timerElem.height = int(level.fontHeight * fontScale);
timerElem.xOffset = 0;
timerElem.yOffset = 0;
timerElem.children = [];
timerElem setParent( level.uiParent );
timerElem.hidden = false;
return timerElem;
}
createIcon( shader, width, height )
{
iconElem = newClientHudElem( self );
iconElem.elemType = "icon";
iconElem.x = 0;
iconElem.y = 0;
iconElem.width = width;
iconElem.height = height;
iconElem.baseWidth = iconElem.width;
iconElem.baseHeight = iconElem.height;
iconElem.xOffset = 0;
iconElem.yOffset = 0;
iconElem.children = [];
iconElem setParent( level.uiParent );
iconElem.hidden = false;
if ( isDefined( shader ) )
{
iconElem setShader( shader, width, height );
iconElem.shader = shader;
}
return iconElem;
}
createServerIcon( shader, width, height, team )
{
if ( isDefined( team ) )
iconElem = newTeamHudElem( team );
else
iconElem = newHudElem();
iconElem.elemType = "icon";
iconElem.x = 0;
iconElem.y = 0;
iconElem.width = width;
iconElem.height = height;
iconElem.baseWidth = iconElem.width;
iconElem.baseHeight = iconElem.height;
iconElem.xOffset = 0;
iconElem.yOffset = 0;
iconElem.children = [];
iconElem setParent( level.uiParent );
iconElem.hidden = false;
if ( isDefined( shader ) )
{
iconElem setShader( shader, width, height );
iconElem.shader = shader;
}
return iconElem;
}
createServerBar( color, width, height, flashFrac, team, selected )
{
if ( isDefined( team ) )
barElem = newTeamHudElem( team );
else
barElem = newHudElem();
barElem.x = 0;
barElem.y = 0;
barElem.frac = 0;
barElem.color = color;
barElem.sort = -2;
barElem.shader = "progress_bar_fill";
barElem setShader( "progress_bar_fill", width, height );
barElem.hidden = false;
if ( isDefined( flashFrac ) )
{
barElem.flashFrac = flashFrac;
// barElem thread flashThread();
}
if ( isDefined( team ) )
barElemBG = newTeamHudElem( team );
else
barElemBG = newHudElem();
barElemBG.elemType = "bar";
barElemBG.x = 0;
barElemBG.y = 0;
barElemBG.width = width;
barElemBG.height = height;
barElemBG.xOffset = 0;
barElemBG.yOffset = 0;
barElemBG.bar = barElem;
barElemBG.children = [];
barElemBG.sort = -3;
barElemBG.color = (0,0,0);
barElemBG.alpha = 0.5;
barElemBG setParent( level.uiParent );
barElemBG setShader( "progress_bar_bg", width, height );
barElemBG.hidden = false;
return barElemBG;
}
createBar( color, width, height, flashFrac )
{
barElem = newClientHudElem( self );
barElem.x = 0 ;
barElem.y = 0;
barElem.frac = 0;
barElem.color = color;
barElem.sort = -2;
barElem.shader = "progress_bar_fill";
barElem setShader( "progress_bar_fill", width, height );
barElem.hidden = false;
if ( isDefined( flashFrac ) )
{
barElem.flashFrac = flashFrac;
// barElem thread flashThread();
}
barElemBG = newClientHudElem( self );
barElemBG.elemType = "bar";
barElemBG.width = width;
barElemBG.height = height;
barElemBG.xOffset = 0;
barElemBG.yOffset = 0;
barElemBG.bar = barElem;
barElemBG.children = [];
barElemBG.sort = -3;
barElemBG.color = (0,0,0);
barElemBG.alpha = 0.5;
barElemBG setParent( level.uiParent );
barElemBG setShader( "progress_bar_bg", width + 4, height + 4 );
barElemBG.hidden = false;
return barElemBG;
}
getCurrentFraction()
{
frac = self.bar.frac;
if (isdefined(self.bar.rateOfChange))
{
frac += (getTime() - self.bar.lastUpdateTime) * self.bar.rateOfChange;
if (frac > 1) frac = 1;
if (frac < 0) frac = 0;
}
return frac;
}
createPrimaryProgressBar( yOffset )
{
if ( !isDefined( yOffset ) )
yOffset = 0;
bar = createBar( (1, 1, 1), level.primaryProgressBarWidth, level.primaryProgressBarHeight );
bar setPoint("CENTER", undefined, level.primaryProgressBarX, level.primaryProgressBarY - yOffset );
return bar;
}
createPrimaryProgressBarText( yOffset )
{
if ( !isDefined( yOffset ) )
yOffset = 0;
text = createFontString( "hudbig", level.primaryProgressBarFontSize );
text setPoint("CENTER", undefined, level.primaryProgressBarTextX, level.primaryProgressBarTextY - yOffset );
text.sort = -1;
return text;
}
createTeamProgressBar( team )
{
bar = createServerBar( (1,0,0), level.teamProgressBarWidth, level.teamProgressBarHeight, undefined, team );
bar setPoint("TOP", undefined, 0, level.teamProgressBarY);
return bar;
}
createTeamProgressBarText( team )
{
text = createServerFontString( "default", level.teamProgressBarFontSize, team );
text setPoint("TOP", undefined, 0, level.teamProgressBarTextY);
return text;
}
setFlashFrac( flashFrac )
{
self.bar.flashFrac = flashFrac;
}
hideElem()
{
if ( self.hidden )
return;
self.hidden = true;
if ( self.alpha != 0 )
self.alpha = 0;
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
{
self.bar.hidden = true;
if ( self.bar.alpha != 0 )
self.bar.alpha = 0;
}
}
showElem()
{
if ( !self.hidden )
return;
self.hidden = false;
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
{
if ( self.alpha != .5 )
self.alpha = .5;
self.bar.hidden = false;
if ( self.bar.alpha != 1 )
self.bar.alpha = 1;
}
else
{
if ( self.alpha != 1 )
self.alpha = 1;
}
}
flashThread()
{
self endon ( "death" );
if ( !self.hidden )
self.alpha = 1;
while(1)
{
if ( self.frac >= self.flashFrac )
{
if ( !self.hidden )
{
self fadeOverTime(0.3);
self.alpha = .2;
wait(0.35);
self fadeOverTime(0.3);
self.alpha = 1;
}
wait(0.7);
}
else
{
if ( !self.hidden && self.alpha != 1 )
self.alpha = 1;
wait ( 0.05 );
}
}
}
destroyElem()
{
tempChildren = [];
for ( index = 0; index < self.children.size; index++ )
{
if ( isDefined( self.children[index] ) )
tempChildren[tempChildren.size] = self.children[index];
}
for ( index = 0; index < tempChildren.size; index++ )
tempChildren[index] setParent( self getParent() );
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
{
self.bar destroy();
}
self destroy();
}
setIconShader( shader )
{
self setShader( shader );
self.shader = shader;
}
getIconShader( shader )
{
return self.shader;
}
setIconSize( width, height )
{
assert( isDefined( self.shader ) );
self setShader( self.shader, width, height );
}
setWidth( width )
{
self.width = width;
}
setHeight( height )
{
self.height = height;
}
setSize( width, height )
{
self.width = width;
self.height = height;
}
updateChildren()
{
for ( index = 0; index < self.children.size; index++ )
{
child = self.children[index];
child setPoint( child.point, child.relativePoint, child.xOffset, child.yOffset );
}
}
transitionReset()
{
self.x = self.xOffset;
self.y = self.yOffset;
if ( self.elemType == "font" )
{
self.fontScale = self.baseFontScale;
self.label = &"";
}
else if ( self.elemType == "icon" )
{
//self scaleOverTime( 0.001, self.width, self.height );
self setShader( self.shader, self.width, self.height );
}
self.alpha = 0;
}
transitionZoomIn( duration )
{
switch ( self.elemType )
{
case "font":
case "timer":
self.fontScale = 6.3;
self changeFontScaleOverTime( duration );
self.fontScale = self.baseFontScale;
break;
case "icon":
self setShader( self.shader, self.width * 6, self.height * 6 );
self scaleOverTime( duration, self.width, self.height );
break;
}
}
transitionPulseFXIn( inTime, duration )
{
transTime = int(inTime)*1000;
showTime = int(duration)*1000;
switch ( self.elemType )
{
case "font":
case "timer":
self setPulseFX( transTime+250, showTime+transTime, transTime+250 );
break;
default:
break;
}
}
transitionSlideIn( duration, direction )
{
if ( !isDefined( direction ) )
direction = "left";
switch ( direction )
{
case "left":
self.x += 1000;
break;
case "right":
self.x -= 1000;
break;
case "up":
self.y -= 1000;
break;
case "down":
self.y += 1000;
break;
}
self moveOverTime( duration );
self.x = self.xOffset;
self.y = self.yOffset;
}
transitionSlideOut( duration, direction )
{
if ( !isDefined( direction ) )
direction = "left";
gotoX = self.xOffset;
gotoY = self.yOffset;
switch ( direction )
{
case "left":
gotoX += 1000;
break;
case "right":
gotoX -= 1000;
break;
case "up":
gotoY -= 1000;
break;
case "down":
gotoY += 1000;
break;
}
self.alpha = 1;
self moveOverTime( duration );
self.x = gotoX;
self.y = gotoY;
}
transitionZoomOut( duration )
{
switch ( self.elemType )
{
case "font":
case "timer":
self changeFontScaleOverTime( duration );
self.fontScale = 6.3;
case "icon":
self scaleOverTime( duration, self.width * 6, self.height * 6 );
break;
}
}
transitionFadeIn( duration )
{
self fadeOverTime( duration );
if ( isDefined( self.maxAlpha ) )
self.alpha = self.maxAlpha;
else
self.alpha = 1;
}
transitionFadeOut( duration )
{
self fadeOverTime( 0.15 );
self.alpha = 0;
}
+594
View File
@@ -0,0 +1,594 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
precacheString(&"PLATFORM_PRESS_TO_SKIP");
precacheString(&"PLATFORM_PRESS_TO_RESPAWN");
precacheString(&"PLATFORM_PRESS_TO_COPYCAT");
precacheShader("specialty_copycat");
level.killcam = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "allowkillcam" );
}
killcam(
attackerNum, // entity number of the attacker
killcamentityindex, // entity number of the entity to view (grenade, airstrike, etc)
killcamentitystarttime, // time at which the killcamentity came into being
sWeapon, // killing weapon
predelay, // time between player death and beginning of killcam
offsetTime, // something to do with how far back in time the killer was seeing the world when he made the kill; latency related, sorta
timeUntilRespawn, // will the player be allowed to respawn after the killcam?
maxtime, // time remaining until map ends; the killcam will never last longer than this. undefined = no limit
attacker, // entity object of attacker
victim // entity object of the victim
)
{
// monitors killcam and hides HUD elements during killcam session
//if ( !level.splitscreen )
// self thread killcam_HUD_off();
self endon("disconnect");
self endon("spawned");
level endon("game_ended");
if ( attackerNum < 0 )
return;
// length from killcam start to killcam end
if (getdvar("scr_killcam_time") == "") {
if ( sWeapon == "artillery_mp" || sWeapon == "stealth_bomb_mp" )
camtime = (gettime() - killcamentitystarttime) / 1000 - predelay - .1;
else if ( level.showingFinalKillcam )
camtime = 4.0;
else if ( sWeapon == "javelin_mp" )
camtime = 8;
else if ( issubstr( sWeapon, "remotemissile_" ) )
camtime = 5;
else if ( !timeUntilRespawn || timeUntilRespawn > 5.0 ) // if we're not going to respawn, we can take more time to watch what happened
camtime = 5.0;
else if ( sWeapon == "frag_grenade_mp" || sWeapon == "frag_grenade_short_mp" || sWeapon == "semtex_mp" )
camtime = 4.25; // show long enough to see grenade thrown
else
camtime = 2.5;
}
else
camtime = getdvarfloat("scr_killcam_time");
if (isdefined(maxtime)) {
if (camtime > maxtime)
camtime = maxtime;
if (camtime < .05)
camtime = .05;
}
// time after player death that killcam continues for
if (getdvar("scr_killcam_posttime") == "")
postdelay = 2;
else {
postdelay = getdvarfloat("scr_killcam_posttime");
if (postdelay < 0.05)
postdelay = 0.05;
}
/* timeline:
| camtime | postdelay |
| | predelay |
^ killcam start ^ player death ^ killcam end
^ player starts watching killcam
*/
killcamlength = camtime + postdelay;
// don't let the killcam last past the end of the round.
if (isdefined(maxtime) && killcamlength > maxtime)
{
// first trim postdelay down to a minimum of 1 second.
// if that doesn't make it short enough, trim camtime down to a minimum of 1 second.
// if that's still not short enough, cancel the killcam.
if ( maxtime < 2 )
return;
if (maxtime - camtime >= 1) {
// reduce postdelay so killcam ends at end of match
postdelay = maxtime - camtime;
}
else {
// distribute remaining time over postdelay and camtime
postdelay = 1;
camtime = maxtime - 1;
}
// recalc killcamlength
killcamlength = camtime + postdelay;
}
killcamoffset = camtime + predelay;
startTime = getTime();
self notify ( "begin_killcam", startTime );
self.sessionstate = "spectator";
self.forcespectatorclient = attackerNum;
self.killcamentity = -1;
if ( killcamentityindex >= 0 )
self thread setKillCamEntity( killcamentityindex, killcamoffset, killcamentitystarttime );
self.archivetime = killcamoffset;
self.killcamlength = killcamlength;
self.psoffsettime = offsetTime;
// ignore spectate permissions
self allowSpectateTeam("allies", true);
self allowSpectateTeam("axis", true);
self allowSpectateTeam("freelook", true);
self allowSpectateTeam("none", true);
if ( isDefined( attacker ) && level.showingFinalKillcam ) // attacker may have disconnected
{
self openMenu( "killedby_card_display" );
self SetCardDisplaySlot( attacker, 7 );
}
self thread endedKillcamCleanup();
// wait till the next server frame to allow code a chance to update archivetime if it needs trimming
wait 0.05;
assertex( self.archivetime <= killcamoffset + 0.0001, "archivetime: " + self.archivetime + ", killcamoffset: " + killcamoffset );
if ( self.archivetime < killcamoffset )
println( "WARNING: Code trimmed killcam time by " + (killcamoffset - self.archivetime) + " seconds because it doesn't have enough game time recorded!" );
camtime = self.archivetime - .05 - predelay;
killcamlength = camtime + postdelay;
self.killcamlength = killcamlength;
if ( camtime <= 0 ) // if we're not looking back in time far enough to even see the death, cancel
{
println( "Cancelling killcam because we don't even have enough recorded to show the death." );
self.sessionstate = "dead";
self.forcespectatorclient = -1;
self.killcamentity = -1;
self.archivetime = 0;
self.psoffsettime = 0;
self notify ( "killcam_ended" );
return;
}
if ( level.showingFinalKillcam )
thread doFinalKillCamFX( camtime );
self.killcam = true;
self initKCElements();
if ( !level.splitscreen )
{
self.kc_timer.alpha = 1;
self.kc_timer setTenthsTimer(camtime);
}
if ( timeUntilRespawn && !level.gameEnded )
{
if ( timeUntilRespawn > 0 )
setLowerMessage( "kc_info", game["strings"]["waiting_to_spawn"], timeUntilRespawn );
else
setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_SKIP" );
}
else if ( !level.gameEnded )
{
setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_RESPAWN" );
}
if ( !level.showingFinalKillcam )
self.kc_skiptext.alpha = 1;
else
self.kc_skiptext.alpha = 0;
self.kc_othertext.alpha = 0;
self.kc_icon.alpha = 0;
self thread spawnedKillcamCleanup();
if ( self == victim && victim _hasPerk( "specialty_copycat" ) && isDefined( victim.pers["copyCatLoadout"] ) )
self thread waitKCCopyCatButton( attacker );
if ( !level.showingFinalKillcam )
self thread waitSkipKillcamButton( timeUntilRespawn );
else
self notify ( "showing_final_killcam" );
self thread endKillcamIfNothingToShow();
self waittillKillcamOver();
if ( level.showingFinalKillcam )
{
self thread maps\mp\gametypes\_playerlogic::spawnEndOfGame();
return;
}
self thread calculateKillCamTime( startTime );
self thread killcamCleanup( true );
}
doFinalKillCamFX( camTime )
{
if ( isDefined( level.doingFinalKillcamFx ) )
return;
level.doingFinalKillcamFx = true;
intoSlowMoTime = camTime;
if ( intoSlowMoTime > 1.0 )
{
intoSlowMoTime = 1.0;
wait( camTime - 1.0 );
}
setSlowMotion( 1.0, 0.25, intoSlowMoTime ); // start timescale, end timescale, lerp duration
wait( intoSlowMoTime + .5 );
setSlowMotion( 0.25, 1, 1.0 );
level.doingFinalKillcamFx = undefined;
}
calculateKillCamTime( startTime )
{
watchedTime = int(getTime() - startTime);
self incPlayerStat( "killcamtimewatched", watchedTime );
}
waittillKillcamOver()
{
self endon("abort_killcam");
wait(self.killcamlength - 0.05);
}
setKillCamEntity( killcamentityindex, killcamoffset, starttime )
{
self endon("disconnect");
self endon("killcam_ended");
killcamtime = (gettime() - killcamoffset * 1000);
if ( starttime > killcamtime )
{
wait .05;
// code may have trimmed archivetime after the first frame if we couldn't go back in time as far as requested.
killcamoffset = self.archivetime;
killcamtime = (gettime() - killcamoffset * 1000);
if ( starttime > killcamtime )
wait (starttime - killcamtime) / 1000;
}
self.killcamentity = killcamentityindex;
}
waitSkipKillcamButton( timeUntilRespawn )
{
self endon("disconnect");
self endon("killcam_ended");
while(self useButtonPressed())
wait .05;
while(!(self useButtonPressed()))
wait .05;
if ( !matchMakingGame() )
self incPlayerStat( "killcamskipped", 1 );
if ( timeUntilRespawn <= 0 )
clearLowerMessage( "kc_info" );
self notify("abort_killcam");
}
waitKCCopyCatButton( attacker )
{
self endon("disconnect");
self endon("killcam_ended");
self waitCopyCatButton( attacker );
self notify("abort_killcam");
}
waitDeathCopyCatButton( attacker )
{
self endon ( "disconnect" );
self initKCElements();
usedCopycat = self waitCopyCatButton( attacker );
if ( !isDefined( usedCopycat ) )
{
self.kc_icon.alpha = 0;
self.kc_othertext.alpha = 0;
}
}
waitCopyCatButton( attacker )
{
self endon ( "spawned_player" );
self endon ( "death_delay_finished" );
self.kc_icon setShader( "specialty_copycat", 48, 48 );
self.kc_othertext setText( &"PLATFORM_PRESS_TO_COPYCAT" );
self.kc_othertext.alpha = 1;
self.kc_icon.alpha = 1;
self notifyOnPlayerCommand( "use_copycat", "weapnext" );
self waittill( "use_copycat" );
self.pers["copyCatLoadout"]["inUse"] = true;
self.pers["copyCatLoadout"]["owner"] = attacker;
self.kc_othertext fadeOverTime( 0.5 );
self.kc_othertext.alpha = 0;
self.kc_icon fadeOverTime( 0.25 );
self.kc_icon scaleOverTime( 0.25, 512, 512 );
self.kc_icon.alpha = 0;
if ( isDefined( attacker ) )
attacker thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "copied", self );
self playLocalSound( "copycat_steal_class" );
return true;
}
waitSkipKillcamSafeSpawnButton()
{
self endon("disconnect");
self endon("killcam_ended");
if ( !self maps\mp\gametypes\_playerlogic::maySpawn() )
return;
while(self fragButtonPressed())
wait .05;
while(!(self fragButtonPressed()))
wait .05;
self.wantSafeSpawn = true;
self notify("abort_killcam");
}
endKillcamIfNothingToShow()
{
self endon("disconnect");
self endon("killcam_ended");
while(1)
{
// code may trim our archivetime to zero if there is nothing "recorded" to show.
// this can happen when the person we're watching in our killcam goes into killcam himself.
// in this case, end the killcam.
if ( self.archivetime <= 0 )
break;
wait .05;
}
self notify("abort_killcam");
}
spawnedKillcamCleanup()
{
self endon("disconnect");
self endon("killcam_ended");
self waittill("spawned");
self thread killcamCleanup( false );
}
endedKillcamCleanup()
{
self endon("disconnect");
self endon("killcam_ended");
level waittill("game_ended");
self thread killcamCleanup( true );
}
killcamCleanup( clearState )
{
if(isDefined(self.kc_skiptext))
self.kc_skiptext.alpha = 0;
if(isDefined(self.kc_timer))
self.kc_timer.alpha = 0;
if(isDefined(self.kc_icon))
self.kc_icon.alpha = 0;
if(isDefined(self.kc_othertext))
self.kc_othertext.alpha = 0;
self.killcam = undefined;
if ( !level.gameEnded )
self clearLowerMessage( "kc_info" );
self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
self notify("killcam_ended"); // do this last, in case this function was called from a thread ending on it
if ( !clearState )
return;
self.sessionstate = "dead";
self ClearKillcamState();
}
cancelKillCamOnUse()
{
self.cancelKillcam = false;
self thread cancelKillCamOnUse_specificButton( ::cancelKillCamUseButton, ::cancelKillCamCallback );
//self thread cancelKillCamOnUse_specificButton( ::cancelKillCamSafeSpawnButton, ::cancelKillCamSafeSpawnCallback );
}
cancelKillCamUseButton()
{
return self useButtonPressed();
}
cancelKillCamSafeSpawnButton()
{
return self fragButtonPressed();
}
cancelKillCamCallback()
{
self.cancelKillcam = true;
}
cancelKillCamSafeSpawnCallback()
{
self.cancelKillcam = true;
self.wantSafeSpawn = true;
}
cancelKillCamOnUse_specificButton( pressingButtonFunc, finishedFunc )
{
self endon ( "death_delay_finished" );
self endon ( "disconnect" );
level endon ( "game_ended" );
for ( ;; )
{
if ( !self [[pressingButtonFunc]]() )
{
wait ( 0.05 );
continue;
}
buttonTime = 0;
while( self [[pressingButtonFunc]]() )
{
buttonTime += 0.05;
wait ( 0.05 );
}
if ( buttonTime >= 0.5 )
continue;
buttonTime = 0;
while ( !self [[pressingButtonFunc]]() && buttonTime < 0.5 )
{
buttonTime += 0.05;
wait ( 0.05 );
}
if ( buttonTime >= 0.5 )
continue;
self [[finishedFunc]]();
return;
}
}
initKCElements()
{
if ( !isDefined( self.kc_skiptext ) )
{
self.kc_skiptext = newClientHudElem(self);
self.kc_skiptext.archived = false;
self.kc_skiptext.x = 0;
self.kc_skiptext.alignX = "center";
self.kc_skiptext.alignY = "top";
self.kc_skiptext.horzAlign = "center_adjustable";
self.kc_skiptext.vertAlign = "top_adjustable";
self.kc_skiptext.sort = 1; // force to draw after the bars
self.kc_skiptext.font = "default";
self.kc_skiptext.foreground = true;
self.kc_skiptext.hideWhenInMenu = true;
if ( level.splitscreen )
{
self.kc_skiptext.y = 20;
self.kc_skiptext.fontscale = 1.2; // 1.8/1.5
}
else
{
self.kc_skiptext.y = 32;
self.kc_skiptext.fontscale = 1.8;
}
}
if ( !isDefined( self.kc_othertext ) )
{
self.kc_othertext = newClientHudElem(self);
self.kc_othertext.archived = false;
self.kc_othertext.y = 18;
self.kc_othertext.alignX = "left";
self.kc_othertext.alignY = "top";
self.kc_othertext.horzAlign = "center";
self.kc_othertext.vertAlign = "middle";
self.kc_othertext.sort = 10; // force to draw after the bars
self.kc_othertext.font = "small";
self.kc_othertext.foreground = true;
self.kc_othertext.hideWhenInMenu = true;
if ( level.splitscreen )
{
self.kc_othertext.x = 16;
self.kc_othertext.fontscale = 1.2;
}
else
{
self.kc_othertext.x = 62;
self.kc_othertext.fontscale = 1.6;
}
}
if ( !isDefined( self.kc_icon ) )
{
self.kc_icon = newClientHudElem(self);
self.kc_icon.archived = false;
self.kc_icon.x = 16;
self.kc_icon.y = 16;
self.kc_icon.alignX = "left";
self.kc_icon.alignY = "top";
self.kc_icon.horzAlign = "center";
self.kc_icon.vertAlign = "middle";
self.kc_icon.sort = 1; // force to draw after the bars
self.kc_icon.foreground = true;
self.kc_icon.hideWhenInMenu = true;
}
if ( !level.splitscreen )
{
if ( !isdefined( self.kc_timer ) )
{
self.kc_timer = createFontString( "hudbig", 1.0 );
self.kc_timer.archived = false;
self.kc_timer.x = 0;
self.kc_timer.alignX = "center";
self.kc_timer.alignY = "middle";
self.kc_timer.horzAlign = "center_safearea";
self.kc_timer.vertAlign = "top_adjustable";
self.kc_timer.y = 42;
self.kc_timer.sort = 1; // force to draw after the bars
self.kc_timer.font = "hudbig";
self.kc_timer.foreground = true;
self.kc_timer.color = (0.85,0.85,0.85);
self.kc_timer.hideWhenInMenu = true;
}
}
}
+555
View File
@@ -0,0 +1,555 @@
#include maps\mp\_utility;
init()
{
if ( !isDefined( game["gamestarted"] ) )
{
game["menu_team"] = "team_marinesopfor";
game["menu_class_allies"] = "class_marines";
game["menu_changeclass_allies"] = "changeclass_marines";
game["menu_initteam_allies"] = "initteam_marines";
game["menu_class_axis"] = "class_opfor";
game["menu_changeclass_axis"] = "changeclass_opfor";
game["menu_initteam_axis"] = "initteam_opfor";
game["menu_class"] = "class";
game["menu_changeclass"] = "changeclass";
game["menu_onemanarmy"] = "onemanarmy";
game["menu_controls"] = "ingame_controls";
if ( !level.console )
{
game["menu_muteplayer"] = "muteplayer";
precacheMenu(game["menu_muteplayer"]);
}
else
{
//game["menu_options"] = "ingame_options";
game["menu_leavegame"] = "popup_leavegame";
if(level.splitscreen)
{
game["menu_team"] += "_splitscreen";
game["menu_class_allies"] += "_splitscreen";
game["menu_changeclass_allies"] += "_splitscreen";
game["menu_class_axis"] += "_splitscreen";
game["menu_changeclass_axis"] += "_splitscreen";
game["menu_class"] += "_splitscreen";
game["menu_controls"] += "_splitscreen";
//game["menu_options"] += "_splitscreen";
game["menu_leavegame"] += "_splitscreen";
game["menu_onemanarmy"] += "_splitscreen";
game["menu_changeclass_defaults_splitscreen"] = "changeclass_defaults_splitscreen";
game["menu_changeclass_custom_splitscreen"] = "changeclass_custom_splitscreen";
game["menu_onemanarmy_defaults_splitscreen"] = "onemanarmy_defaults_splitscreen";
game["menu_onemanarmy_custom_splitscreen"] = "onemanarmy_custom_splitscreen";
precacheMenu(game["menu_changeclass_defaults_splitscreen"]);
precacheMenu(game["menu_changeclass_custom_splitscreen"]);
precacheMenu(game["menu_onemanarmy_defaults_splitscreen"]);
precacheMenu(game["menu_onemanarmy_custom_splitscreen"]);
}
precacheMenu(game["menu_controls"]);
//precacheMenu(game["menu_options"]);
precacheMenu(game["menu_leavegame"]);
//precacheMenu("status_update");
}
precacheMenu("scoreboard");
precacheMenu(game["menu_team"]);
precacheMenu(game["menu_class_allies"]);
precacheMenu(game["menu_changeclass_allies"]);
precacheMenu(game["menu_initteam_allies"]);
precacheMenu(game["menu_class_axis"]);
precacheMenu(game["menu_changeclass_axis"]);
precacheMenu(game["menu_class"]);
precacheMenu(game["menu_changeclass"]);
precacheMenu(game["menu_initteam_axis"]);
precacheMenu(game["menu_onemanarmy"]);
precacheString( &"MP_HOST_ENDED_GAME" );
precacheString( &"MP_HOST_ENDGAME_RESPONSE" );
}
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onMenuResponse();
}
}
isOptionsMenu( menu )
{
if ( menu == game["menu_changeclass"] )
return true;
if ( menu == game["menu_team"] )
return true;
if ( menu == game["menu_controls"] )
return true;
if ( isSubStr( menu, "pc_options" ) )
return true;
return false;
}
onMenuResponse()
{
self endon("disconnect");
for(;;)
{
self waittill("menuresponse", menu, response);
if ( response == "back" )
{
self closepopupMenu();
self closeInGameMenu();
if ( isOptionsMenu( menu ) )
{
if( self.pers["team"] == "allies" )
self openpopupMenu( game["menu_class_allies"] );
if( self.pers["team"] == "axis" )
self openpopupMenu( game["menu_class_axis"] );
}
continue;
}
if(response == "changeteam")
{
self closepopupMenu();
self closeInGameMenu();
self openpopupMenu(game["menu_team"]);
}
if(response == "changeclass_marines" )
{
self closepopupMenu();
self closeInGameMenu();
self openpopupMenu( game["menu_changeclass_allies"] );
continue;
}
if(response == "changeclass_opfor" )
{
self closepopupMenu();
self closeInGameMenu();
self openpopupMenu( game["menu_changeclass_axis"] );
continue;
}
if(response == "changeclass_marines_splitscreen" )
self openpopupMenu( "changeclass_marines_splitscreen" );
if(response == "changeclass_opfor_splitscreen" )
self openpopupMenu( "changeclass_opfor_splitscreen" );
if(response == "endgame")
{
if(level.splitscreen)
{
endparty();
if ( !level.gameEnded )
{
level thread maps\mp\gametypes\_gamelogic::forceEnd();
}
}
continue;
}
if ( response == "endround" )
{
if ( !level.gameEnded )
{
level thread maps\mp\gametypes\_gamelogic::forceEnd();
}
else
{
self closepopupMenu();
self closeInGameMenu();
self iprintln( &"MP_HOST_ENDGAME_RESPONSE" );
}
continue;
}
if(menu == game["menu_team"])
{
switch(response)
{
case "allies":
self [[level.allies]]();
break;
case "axis":
self [[level.axis]]();
break;
case "autoassign":
self [[level.autoassign]]();
break;
case "spectator":
self [[level.spectator]]();
break;
}
} // the only responses remain are change class events
else if ( menu == game["menu_changeclass"] ||
( isDefined( game["menu_changeclass_defaults_splitscreen"] ) && menu == game["menu_changeclass_defaults_splitscreen"] ) ||
( isDefined( game["menu_changeclass_custom_splitscreen"] ) && menu == game["menu_changeclass_custom_splitscreen"] ) )
{
self closepopupMenu();
self closeInGameMenu();
self.selectedClass = true;
self [[level.class]](response);
}
else if ( !level.console )
{
if(menu == game["menu_quickcommands"])
maps\mp\gametypes\_quickmessages::quickcommands(response);
else if(menu == game["menu_quickstatements"])
maps\mp\gametypes\_quickmessages::quickstatements(response);
else if(menu == game["menu_quickresponses"])
maps\mp\gametypes\_quickmessages::quickresponses(response);
}
}
}
getTeamAssignment()
{
teams[0] = "allies";
teams[1] = "axis";
if ( !level.teamBased )
return teams[randomInt(2)];
if ( self.sessionteam != "none" && self.sessionteam != "spectator" && self.sessionstate != "playing" && self.sessionstate != "dead" )
{
assignment = self.sessionteam;
}
else
{
playerCounts = self maps\mp\gametypes\_teams::CountPlayers();
// if teams are equal return the team with the lowest score
if ( playerCounts["allies"] == playerCounts["axis"] )
{
if( getTeamScore( "allies" ) == getTeamScore( "axis" ) )
assignment = teams[randomInt(2)];
else if ( getTeamScore( "allies" ) < getTeamScore( "axis" ) )
assignment = "allies";
else
assignment = "axis";
}
else if( playerCounts["allies"] < playerCounts["axis"] )
{
assignment = "allies";
}
else
{
assignment = "axis";
}
}
return assignment;
}
menuAutoAssign()
{
self closeMenus();
assignment = getTeamAssignment();
if ( isDefined( self.pers["team"] ) && (self.sessionstate == "playing" || self.sessionstate == "dead") )
{
if ( assignment == self.pers["team"] )
{
self beginClassChoice();
return;
}
else
{
self.switching_teams = true;
self.joining_team = assignment;
self.leaving_team = self.pers["team"];
self suicide();
}
}
self addToTeam( assignment );
self.pers["class"] = undefined;
self.class = undefined;
if ( !isAlive( self ) )
self.statusicon = "hud_status_dead";
self notify("end_respawn");
self beginClassChoice();
}
beginClassChoice( forceNewChoice )
{
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
team = self.pers["team"];
// menu_changeclass_team is the one where you choose one of the n classes to play as.
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
self openpopupMenu( game[ "menu_changeclass_" + team ] );
if ( !isAlive( self ) )
self thread maps\mp\gametypes\_playerlogic::predictAboutToSpawnPlayerOverTime( 0.1 );
}
beginTeamChoice()
{
self openpopupMenu( game["menu_team"] );
}
showMainMenuForTeam()
{
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
team = self.pers["team"];
// menu_changeclass_team is the one where you choose one of the n classes to play as.
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
self openpopupMenu( game[ "menu_class_" + team ] );
}
menuAllies()
{
self closeMenus();
if(self.pers["team"] != "allies")
{
if( level.teamBased && !maps\mp\gametypes\_teams::getJoinTeamPermissions( "allies" ) )
{
self openpopupMenu(game["menu_team"]);
return;
}
// allow respawn when switching teams during grace period.
if ( level.inGracePeriod && !self.hasDoneCombat )
self.hasSpawned = false;
if(self.sessionstate == "playing")
{
self.switching_teams = true;
self.joining_team = "allies";
self.leaving_team = self.pers["team"];
self suicide();
}
self addToTeam( "allies" );
self.pers["class"] = undefined;
self.class = undefined;
self notify("end_respawn");
}
self beginClassChoice();
}
menuAxis()
{
self closeMenus();
if(self.pers["team"] != "axis")
{
if( level.teamBased && !maps\mp\gametypes\_teams::getJoinTeamPermissions( "axis" ) )
{
self openpopupMenu(game["menu_team"]);
return;
}
// allow respawn when switching teams during grace period.
if ( level.inGracePeriod && !self.hasDoneCombat )
self.hasSpawned = false;
if(self.sessionstate == "playing")
{
self.switching_teams = true;
self.joining_team = "axis";
self.leaving_team = self.pers["team"];
self suicide();
}
self addToTeam( "axis" );
self.pers["class"] = undefined;
self.class = undefined;
self notify("end_respawn");
}
self beginClassChoice();
}
menuSpectator()
{
self closeMenus();
if( isDefined( self.pers["team"] ) && self.pers["team"] == "spectator" )
return;
if( isAlive( self ) )
{
assert( isDefined( self.pers["team"] ) );
self.switching_teams = true;
self.joining_team = "spectator";
self.leaving_team = self.pers["team"];
self suicide();
}
self addToTeam( "spectator" );
self.pers["class"] = undefined;
self.class = undefined;
self thread maps\mp\gametypes\_playerlogic::spawnSpectator();
}
menuClass( response )
{
self closeMenus();
// clear new status of unlocked classes
if ( response == "demolitions_mp,0" && self getPlayerData( "featureNew", "demolitions" ) )
{
self setPlayerData( "featureNew", "demolitions", false );
}
if ( response == "sniper_mp,0" && self getPlayerData( "featureNew", "sniper" ) )
{
self setPlayerData( "featureNew", "sniper", false );
}
// this should probably be an assert
if(!isDefined(self.pers["team"]) || (self.pers["team"] != "allies" && self.pers["team"] != "axis"))
return;
class = self maps\mp\gametypes\_class::getClassChoice( response );
primary = self maps\mp\gametypes\_class::getWeaponChoice( response );
if ( class == "restricted" )
{
self beginClassChoice();
return;
}
if( (isDefined( self.pers["class"] ) && self.pers["class"] == class) &&
(isDefined( self.pers["primary"] ) && self.pers["primary"] == primary) )
return;
if ( self.sessionstate == "playing" )
{
self.pers["class"] = class;
self.class = class;
self.pers["primary"] = primary;
if ( game["state"] == "postgame" )
return;
if ( level.inGracePeriod && !self.hasDoneCombat ) // used weapons check?
{
self maps\mp\gametypes\_class::setClass( self.pers["class"] );
self.tag_stowed_back = undefined;
self.tag_stowed_hip = undefined;
self maps\mp\gametypes\_class::giveLoadout( self.pers["team"], self.pers["class"] );
}
else
{
self iPrintLnBold( game["strings"]["change_class"] );
}
}
else
{
self.pers["class"] = class;
self.class = class;
self.pers["primary"] = primary;
if ( game["state"] == "postgame" )
return;
if ( game["state"] == "playing" && !isInKillcam() )
self thread maps\mp\gametypes\_playerlogic::spawnClient();
}
self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
}
addToTeam( team, firstConnect )
{
// UTS update playerCount remove from team
if ( isDefined( self.team ) )
self maps\mp\gametypes\_playerlogic::removeFromTeamCount();
self.pers["team"] = team;
// this is the only place self.team should ever be set
self.team = team;
// session team is readonly in ranked matches on console
if ( !matchMakingGame() || isDefined( self.pers["isBot"] ) )
{
if ( level.teamBased )
{
self.sessionteam = team;
}
else
{
if ( team == "spectator" )
self.sessionteam = "spectator";
else
self.sessionteam = "none";
}
}
// UTS update playerCount add to team
if ( game["state"] != "postgame" )
self maps\mp\gametypes\_playerlogic::addToTeamCount();
self updateObjectiveText();
// give "joined_team" and "joined_spectators" handlers a chance to start
// these are generally triggered from the "connected" notify, which can happen on the same
// frame as these notifies
if ( isDefined( firstConnect ) && firstConnect )
waittillframeend;
self updateMainMenu();
if ( team == "spectator" )
{
self notify( "joined_spectators" );
level notify( "joined_team" );
}
else
{
self notify( "joined_team" );
level notify( "joined_team" );
}
}
File diff suppressed because it is too large. Load diff
+483
View File
@@ -0,0 +1,483 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
game["music"]["spawn_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "spawn_music";
game["music"]["defeat_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "defeat_music";
game["music"]["victory_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "victory_music";
game["music"]["winning_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "winning_music";
game["music"]["losing_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "losing_music";
game["voice"]["allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "1mc_";
game["music"]["spawn_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "spawn_music";
game["music"]["defeat_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "defeat_music";
game["music"]["victory_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "victory_music";
game["music"]["winning_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "winning_music";
game["music"]["losing_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "losing_music";
game["voice"]["axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "1mc_";
game["music"]["defeat"] = "mp_defeat";
game["music"]["victory_spectator"] = "mp_defeat";
game["music"]["winning_time"] = "mp_time_running_out_winning";
game["music"]["losing_time"] = "mp_time_running_out_losing";
game["music"]["winning_score"] = "mp_time_running_out_winning";
game["music"]["losing_score"] = "mp_time_running_out_losing";
game["music"]["victory_tie"] = "mp_defeat";
game["music"]["suspense"] = [];
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_01";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_02";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_03";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_04";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_05";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_06";
game["dialog"]["mission_success"] = "mission_success";
game["dialog"]["mission_failure"] = "mission_fail";
game["dialog"]["mission_draw"] = "draw";
game["dialog"]["round_success"] = "encourage_win";
game["dialog"]["round_failure"] = "encourage_lost";
game["dialog"]["round_draw"] = "draw";
// status
game["dialog"]["timesup"] = "timesup";
game["dialog"]["winning_time"] = "winning";
game["dialog"]["losing_time"] = "losing";
game["dialog"]["winning_score"] = "winning_fight";
game["dialog"]["losing_score"] = "losing_fight";
game["dialog"]["lead_lost"] = "lead_lost";
game["dialog"]["lead_tied"] = "tied";
game["dialog"]["lead_taken"] = "lead_taken";
game["dialog"]["last_alive"] = "lastalive";
game["dialog"]["boost"] = "boost";
if ( !isDefined( game["dialog"]["offense_obj"] ) )
game["dialog"]["offense_obj"] = "boost";
if ( !isDefined( game["dialog"]["defense_obj"] ) )
game["dialog"]["defense_obj"] = "boost";
game["dialog"]["hardcore"] = "hardcore";
game["dialog"]["highspeed"] = "highspeed";
game["dialog"]["tactical"] = "tactical";
game["dialog"]["challenge"] = "challengecomplete";
game["dialog"]["promotion"] = "promotion";
game["dialog"]["bomb_taken"] = "acheive_bomb";
game["dialog"]["bomb_lost"] = "bomb_taken";
game["dialog"]["bomb_defused"] = "bomb_defused";
game["dialog"]["bomb_planted"] = "bomb_planted";
game["dialog"]["obj_taken"] = "securedobj";
game["dialog"]["obj_lost"] = "lostobj";
game["dialog"]["obj_defend"] = "obj_defend";
game["dialog"]["obj_destroy"] = "obj_destroy";
game["dialog"]["obj_capture"] = "capture_obj";
game["dialog"]["objs_capture"] = "capture_objs";
game["dialog"]["hq_located"] = "hq_located";
game["dialog"]["hq_enemy_captured"] = "hq_captured";
game["dialog"]["hq_enemy_destroyed"] = "hq_destroyed";
game["dialog"]["hq_secured"] = "hq_secured";
game["dialog"]["hq_offline"] = "hq_offline";
game["dialog"]["hq_online"] = "hq_online";
game["dialog"]["move_to_new"] = "new_positions";
game["dialog"]["push_forward"] = "pushforward";
game["dialog"]["attack"] = "attack";
game["dialog"]["defend"] = "defend";
game["dialog"]["offense"] = "offense";
game["dialog"]["defense"] = "defense";
game["dialog"]["halftime"] = "halftime";
game["dialog"]["overtime"] = "overtime";
game["dialog"]["side_switch"] = "switching";
game["dialog"]["flag_taken"] = "ourflag";
game["dialog"]["flag_dropped"] = "ourflag_drop";
game["dialog"]["flag_returned"] = "ourflag_return";
game["dialog"]["flag_captured"] = "ourflag_capt";
game["dialog"]["flag_getback"] = "getback_ourflag";
game["dialog"]["enemy_flag_bringhome"] = "enemyflag_tobase";
game["dialog"]["enemy_flag_taken"] = "enemyflag";
game["dialog"]["enemy_flag_dropped"] = "enemyflag_drop";
game["dialog"]["enemy_flag_returned"] = "enemyflag_return";
game["dialog"]["enemy_flag_captured"] = "enemyflag_capt";
game["dialog"]["capturing_a"] = "capturing_a";
game["dialog"]["capturing_b"] = "capturing_b";
game["dialog"]["capturing_c"] = "capturing_c";
game["dialog"]["captured_a"] = "capture_a";
game["dialog"]["captured_b"] = "capture_c";
game["dialog"]["captured_c"] = "capture_b";
game["dialog"]["securing_a"] = "securing_a";
game["dialog"]["securing_b"] = "securing_b";
game["dialog"]["securing_c"] = "securing_c";
game["dialog"]["secured_a"] = "secure_a";
game["dialog"]["secured_b"] = "secure_b";
game["dialog"]["secured_c"] = "secure_c";
game["dialog"]["losing_a"] = "losing_a";
game["dialog"]["losing_b"] = "losing_b";
game["dialog"]["losing_c"] = "losing_c";
game["dialog"]["lost_a"] = "lost_a";
game["dialog"]["lost_b"] = "lost_b";
game["dialog"]["lost_c"] = "lost_c";
game["dialog"]["enemy_taking_a"] = "enemy_take_a";
game["dialog"]["enemy_taking_b"] = "enemy_take_b";
game["dialog"]["enemy_taking_c"] = "enemy_take_c";
game["dialog"]["enemy_has_a"] = "enemy_has_a";
game["dialog"]["enemy_has_b"] = "enemy_has_b";
game["dialog"]["enemy_has_c"] = "enemy_has_c";
game["dialog"]["lost_all"] = "take_positions";
game["dialog"]["secure_all"] = "positions_lock";
game["dialog"]["destroy_sentry"] = "dest_sentrygun";
game["music"]["nuke_music"] = "nuke_music";
game["dialog"]["sentry_gone"] = "sentry_gone";
game["dialog"]["sentry_destroyed"] = "sentry_gone";
game["dialog"]["ti_gone"] = "ti_cancelled";
game["dialog"]["ti_destroyed"] = "ti_blocked";
level thread onPlayerConnect();
level thread onLastAlive();
level thread musicController();
level thread onGameEnded();
level thread onRoundSwitch();
}
onPlayerConnect()
{
for(;;)
{
level waittill ( "connected", player );
player thread onPlayerSpawned();
player thread finalKillcamMusic();
}
}
onPlayerSpawned()
{
self endon ( "disconnect" );
self waittill( "spawned_player" );
if ( !level.splitscreen || level.splitscreen && !isDefined( level.playedStartingMusic ) )
{
self playLocalSound( game["music"]["spawn_" + self.team] );
if ( level.splitscreen )
level.playedStartingMusic = true;
}
if ( isDefined( game["dialog"]["gametype"] ) && (!level.splitscreen || self == level.players[0]) )
self leaderDialogOnPlayer( "gametype" );
gameFlagWait( "prematch_done" );
if ( self.team == game["attackers"] )
self leaderDialogOnPlayer( "offense_obj", "introboost" );
else
self leaderDialogOnPlayer( "defense_obj", "introboost" );
}
onLastAlive()
{
level endon ( "game_ended" );
level waittill ( "last_alive", player );
if ( !isAlive( player ) )
return;
player leaderDialogOnPlayer( "last_alive" );
}
onRoundSwitch()
{
level waittill ( "round_switch", switchType );
switch( switchType )
{
case "halftime":
foreach ( player in level.players )
player leaderDialogOnPlayer( "halftime" );
break;
case "overtime":
foreach ( player in level.players )
player leaderDialogOnPlayer( "overtime" );
break;
default:
foreach ( player in level.players )
player leaderDialogOnPlayer( "side_switch" );
break;
}
}
onGameEnded()
{
level thread roundWinnerDialog();
level thread gameWinnerDialog();
level waittill ( "game_win", winner );
if ( isDefined( level.nukeDetonated ) )
{
if ( !level.splitScreen )
playSoundOnPlayers( game["music"]["nuke_music"] );
else
level.players[0] playLocalSound( game["music"]["nuke_music"] );
return;
}
if ( level.teamBased )
{
if ( level.splitscreen )
{
if ( winner == "allies" )
playSoundOnPlayers( game["music"]["victory_allies"], "allies" );
else if ( winner == "axis" )
playSoundOnPlayers( game["music"]["victory_axis"], "axis" );
else
playSoundOnPlayers( game["music"]["nuke_music"] );
}
else
{
if ( winner == "allies" )
{
playSoundOnPlayers( game["music"]["victory_allies"], "allies" );
playSoundOnPlayers( game["music"]["defeat_axis"], "axis" );
}
else if ( winner == "axis" )
{
playSoundOnPlayers( game["music"]["victory_axis"], "axis" );
playSoundOnPlayers( game["music"]["defeat_allies"], "allies" );
}
else
{
playSoundOnPlayers( game["music"]["nuke_music"] );
}
}
}
else
{
foreach ( player in level.players )
{
if ( player.pers["team"] != "allies" && player.pers["team"] != "axis" )
player playLocalSound( game["music"]["nuke_music"] );
else if ( isDefined( winner ) && player == winner )
player playLocalSound( game["music"]["victory_" + player.pers["team"] ] );
else if ( !level.splitScreen )
player playLocalSound( game["music"]["defeat_" + player.pers["team"] ] );
}
}
}
roundWinnerDialog()
{
level waittill ( "round_win", winner );
delay = level.roundEndDelay / 4;
if ( delay > 0 )
wait ( delay );
if ( !isDefined( winner ) || isPlayer( winner ) || isDefined( level.nukeDetonated ) )
return;
if ( winner == "allies" )
{
leaderDialog( "round_success", "allies" );
leaderDialog( "round_failure", "axis" );
}
else if ( winner == "axis" )
{
leaderDialog( "round_success", "axis" );
leaderDialog( "round_failure", "allies" );
}
}
gameWinnerDialog()
{
level waittill ( "game_win", winner );
delay = level.postRoundTime / 2;
if ( delay > 0 )
wait ( delay );
if ( !isDefined( winner ) || isPlayer( winner ) || isDefined( level.nukeDetonated ) )
return;
if ( winner == "allies" )
{
leaderDialog( "mission_success", "allies" );
leaderDialog( "mission_failure", "axis" );
}
else if ( winner == "axis" )
{
leaderDialog( "mission_success", "axis" );
leaderDialog( "mission_failure", "allies" );
}
else
{
leaderDialog( "mission_draw" );
}
}
musicController()
{
level endon ( "game_ended" );
if ( !level.hardcoreMode )
thread suspenseMusic();
level waittill ( "match_ending_soon", reason );
assert( isDefined( reason ) );
if ( getWatchedDvar( "roundlimit" ) == 1 || game["roundsPlayed"] == (getWatchedDvar( "roundlimit" ) - 1) )
{
if ( !level.splitScreen )
{
if ( reason == "time" )
{
if ( level.teamBased )
{
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
{
if ( !level.hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_allies"], "allies" );
playSoundOnPlayers( game["music"]["losing_axis"], "axis" );
}
leaderDialog( "winning_time", "allies" );
leaderDialog( "losing_time", "axis" );
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
if ( !level.hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_axis"], "axis" );
playSoundOnPlayers( game["music"]["losing_allies"], "allies" );
}
leaderDialog( "winning_time", "axis" );
leaderDialog( "losing_time", "allies" );
}
}
else
{
if ( !level.hardcoreMode )
playSoundOnPlayers( game["music"]["losing_time"] );
leaderDialog( "timesup" );
}
}
else if ( reason == "score" )
{
if ( level.teamBased )
{
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
{
if ( !level.hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_allies"], "allies" );
playSoundOnPlayers( game["music"]["losing_axis"], "axis" );
}
leaderDialog( "winning_score", "allies" );
leaderDialog( "losing_score", "axis" );
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
if ( !level.hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_axis"], "axis" );
playSoundOnPlayers( game["music"]["losing_allies"], "allies" );
}
leaderDialog( "winning_score", "axis" );
leaderDialog( "losing_score", "allies" );
}
}
else
{
winningPlayer = maps\mp\gametypes\_gamescore::getHighestScoringPlayer();
losingPlayers = maps\mp\gametypes\_gamescore::getLosingPlayers();
excludeList[0] = winningPlayer;
if ( !level.hardcoreMode )
{
winningPlayer playLocalSound( game["music"]["winning_" + winningPlayer.pers["team"] ] );
foreach ( otherPlayer in level.players )
{
if ( otherPlayer == winningPlayer )
continue;
otherPlayer playLocalSound( game["music"]["losing_" + otherPlayer.pers["team"] ] );
}
}
winningPlayer leaderDialogOnPlayer( "winning_score" );
leaderDialogOnPlayers( "losing_score", losingPlayers );
}
}
level waittill ( "match_ending_very_soon" );
leaderDialog( "timesup" );
}
}
else
{
if ( !level.hardcoreMode )
playSoundOnPlayers( game["music"]["losing_allies"] );
leaderDialog( "timesup" );
}
}
suspenseMusic()
{
level endon ( "game_ended" );
level endon ( "match_ending_soon" );
numTracks = game["music"]["suspense"].size;
for ( ;; )
{
wait ( randomFloatRange( 60, 120 ) );
playSoundOnPlayers( game["music"]["suspense"][randomInt(numTracks)] );
}
}
finalKillcamMusic()
{
self waittill ( "showing_final_killcam" );
// self playLocalSound( game["music"]["winning"] );
}
+160
View File
@@ -0,0 +1,160 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
precacheShader("objpoint_default");
level.objPointNames = [];
level.objPoints = [];
if ( level.splitscreen )
level.objPointSize = 15;
else
level.objPointSize = 8;
level.objpoint_alpha_default = .5;
level.objPointScale = 1.0;
}
createTeamObjpoint( name, origin, team, shader, alpha, scale )
{
assert( team == "axis" || team == "allies" || team == "all" );
objPoint = getObjPointByName( name );
if ( isDefined( objPoint ) )
deleteObjPoint( objPoint );
if ( !isDefined( shader ) )
shader = "objpoint_default";
if ( !isDefined( scale ) )
scale = 1.0;
if ( team != "all" )
objPoint = newTeamHudElem( team );
else
objPoint = newHudElem();
objPoint.name = name;
objPoint.x = origin[0];
objPoint.y = origin[1];
objPoint.z = origin[2];
objPoint.team = team;
objPoint.isFlashing = false;
objPoint.isShown = true;
objPoint setShader( shader, level.objPointSize, level.objPointSize );
objPoint setWaypoint( true, false );
if ( isDefined( alpha ) )
objPoint.alpha = alpha;
else
objPoint.alpha = level.objpoint_alpha_default;
objPoint.baseAlpha = objPoint.alpha;
objPoint.index = level.objPointNames.size;
level.objPoints[name] = objPoint;
level.objPointNames[level.objPointNames.size] = name;
return objPoint;
}
deleteObjPoint( oldObjPoint )
{
assert( level.objPoints.size == level.objPointNames.size );
if ( level.objPoints.size == 1 )
{
assert( level.objPointNames[0] == oldObjPoint.name );
assert( isDefined( level.objPoints[oldObjPoint.name] ) );
level.objPoints = [];
level.objPointNames = [];
oldObjPoint destroy();
return;
}
newIndex = oldObjPoint.index;
oldIndex = (level.objPointNames.size - 1);
objPoint = getObjPointByIndex( oldIndex );
level.objPointNames[newIndex] = objPoint.name;
objPoint.index = newIndex;
level.objPointNames[oldIndex] = undefined;
level.objPoints[oldObjPoint.name] = undefined;
oldObjPoint destroy();
}
updateOrigin( origin )
{
if ( self.x != origin[0] )
self.x = origin[0];
if ( self.y != origin[1] )
self.y = origin[1];
if ( self.z != origin[2] )
self.z = origin[2];
}
setOriginByName( name, origin )
{
objPoint = getObjPointByName( name );
objPoint updateOrigin( origin );
}
getObjPointByName( name )
{
if ( isDefined( level.objPoints[name] ) )
return level.objPoints[name];
else
return undefined;
}
getObjPointByIndex( index )
{
if ( isDefined( level.objPointNames[index] ) )
return level.objPoints[level.objPointNames[index]];
else
return undefined;
}
startFlashing()
{
self endon("stop_flashing_thread");
if ( self.isFlashing )
return;
self.isFlashing = true;
while ( self.isFlashing )
{
self fadeOverTime( 0.75 );
self.alpha = 0.35 * self.baseAlpha;
wait ( 0.75 );
self fadeOverTime( 0.75 );
self.alpha = self.baseAlpha;
wait ( 0.75 );
}
self.alpha = self.baseAlpha;
}
stopFlashing()
{
if ( !self.isFlashing )
return;
self.isFlashing = false;
}
+234
View File
@@ -0,0 +1,234 @@
#include maps\mp\_utility;
init()
{
level.persistentDataInfo = [];
maps\mp\gametypes\_class::init();
maps\mp\gametypes\_rank::init();
maps\mp\gametypes\_missions::init();
maps\mp\gametypes\_playercards::init();
level thread updateBufferedStats();
}
initBufferedStats()
{
self.bufferedStats = [];
self.bufferedStats[ "totalShots" ] = self getPlayerData( "totalShots" );
self.bufferedStats[ "accuracy" ] = self getPlayerData( "accuracy" );
self.bufferedStats[ "misses" ] = self getPlayerData( "misses" );
self.bufferedStats[ "hits" ] = self getPlayerData( "hits" );
self.bufferedStats[ "timePlayedAllies" ] = self getPlayerData( "timePlayedAllies" );
self.bufferedStats[ "timePlayedOpfor" ] = self getPlayerData( "timePlayedOpfor" );
self.bufferedStats[ "timePlayedOther" ] = self getPlayerData( "timePlayedOther" );
self.bufferedStats[ "timePlayedTotal" ] = self getPlayerData( "timePlayedTotal" );
self.bufferedChildStats = [];
self.bufferedChildStats[ "round" ] = [];
self.bufferedChildStats[ "round" ][ "timePlayed" ] = self getPlayerData( "round", "timePlayed" );
}
// ==========================================
// Script persistent data functions
// These are made for convenience, so persistent data can be tracked by strings.
// They make use of code functions which are prototyped below.
/*
=============
statGet
Returns the value of the named stat
=============
*/
statGet( dataName )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
return self GetPlayerData( dataName );
}
/*
=============
statSet
Sets the value of the named stat
=============
*/
statSet( dataName, value )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
if ( !self rankingEnabled() )
return;
self SetPlayerData( dataName, value );
}
/*
=============
statAdd
Adds the passed value to the value of the named stat
=============
*/
statAdd( dataName, value )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
if ( !self rankingEnabled() )
return;
curValue = self GetPlayerData( dataName );
self SetPlayerData( dataName, value + curValue );
}
statGetChild( parent, child )
{
return self GetPlayerData( parent, child );
}
statSetChild( parent, child, value )
{
if ( !self rankingEnabled() )
return;
self SetPlayerData( parent, child, value );
}
statAddChild( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
curValue = self GetPlayerData( parent, child );
self SetPlayerData( parent, child, curValue + value );
}
statGetChildBuffered( parent, child )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
return self.bufferedChildStats[ parent ][ child ];
}
statSetChildBuffered( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
self.bufferedChildStats[ parent ][ child ] = value;
}
statAddChildBuffered( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
curValue = statGetChildBuffered( parent, child );
statSetChildBuffered( parent, child, curValue + value );
}
/*
=============
statGetBuffered
Returns the value of the named stat
=============
*/
statGetBuffered( dataName )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
return self.bufferedStats[ dataName ];
}
/*
=============
statSet
Sets the value of the named stat
=============
*/
statSetBuffered( dataName, value )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
if ( !self rankingEnabled() )
return;
self.bufferedStats[ dataName ] = value;
}
/*
=============
statAdd
Adds the passed value to the value of the named stat
=============
*/
statAddBuffered( dataName, value )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
if ( !self rankingEnabled() )
return;
curValue = statGetBuffered( dataName );
statSetBuffered( dataName, curValue + value );
}
updateBufferedStats()
{
// give the first player time to connect
wait ( 0.15 );
nextToUpdate = 0;
while ( !level.gameEnded )
{
nextToUpdate++;
if ( nextToUpdate >= level.players.size )
nextToUpdate = 0;
if ( isDefined( level.players[nextToUpdate] ) )
level.players[nextToUpdate] writeBufferedStats();
wait ( 2.0 );
}
foreach ( player in level.players )
player writeBufferedStats();
}
writeBufferedStats()
{
foreach ( statName, statVal in self.bufferedStats )
{
self setPlayerData( statName, statVal );
}
foreach ( statName, statVal in self.bufferedChildStats )
{
foreach ( childStatName, childStatVal in statVal )
self setPlayerData( statName, childStatName, childStatVal );
}
}
+29
View File
@@ -0,0 +1,29 @@
#include common_scripts\utility;
#include maps\mp\_utility;
init()
{
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
//@NOTE: Should we make sure they're really unlocked before setting them? Catch cheaters...
// e.g. isItemUnlocked( iconHandle )
iconHandle = player maps\mp\gametypes\_persistence::statGet( "cardIcon" );
player SetCardIcon( iconHandle );
titleHandle = player maps\mp\gametypes\_persistence::statGet( "cardTitle" );
player SetCardTitle( titleHandle );
nameplateHandle = player maps\mp\gametypes\_persistence::statGet( "cardNameplate" );
player SetCardNameplate( nameplateHandle );
}
}
File diff suppressed because it is too large. Load diff
+270
View File
@@ -0,0 +1,270 @@
init()
{
game["menu_quickcommands"] = "quickcommands";
game["menu_quickstatements"] = "quickstatements";
game["menu_quickresponses"] = "quickresponses";
precacheMenu(game["menu_quickcommands"]);
precacheMenu(game["menu_quickstatements"]);
precacheMenu(game["menu_quickresponses"]);
precacheHeadIcon("talkingicon");
precacheString( &"QUICKMESSAGE_FOLLOW_ME" );
precacheString( &"QUICKMESSAGE_MOVE_IN" );
precacheString( &"QUICKMESSAGE_FALL_BACK" );
precacheString( &"QUICKMESSAGE_SUPPRESSING_FIRE" );
precacheString( &"QUICKMESSAGE_ATTACK_LEFT_FLANK" );
precacheString( &"QUICKMESSAGE_ATTACK_RIGHT_FLANK" );
precacheString( &"QUICKMESSAGE_HOLD_THIS_POSITION" );
precacheString( &"QUICKMESSAGE_REGROUP" );
precacheString( &"QUICKMESSAGE_ENEMY_SPOTTED" );
precacheString( &"QUICKMESSAGE_ENEMIES_SPOTTED" );
precacheString( &"QUICKMESSAGE_IM_IN_POSITION" );
precacheString( &"QUICKMESSAGE_AREA_SECURE" );
precacheString( &"QUICKMESSAGE_GRENADE" );
precacheString( &"QUICKMESSAGE_SNIPER" );
precacheString( &"QUICKMESSAGE_NEED_REINFORCEMENTS" );
precacheString( &"QUICKMESSAGE_HOLD_YOUR_FIRE" );
precacheString( &"QUICKMESSAGE_YES_SIR" );
precacheString( &"QUICKMESSAGE_NO_SIR" );
precacheString( &"QUICKMESSAGE_IM_ON_MY_WAY" );
precacheString( &"QUICKMESSAGE_SORRY" );
precacheString( &"QUICKMESSAGE_GREAT_SHOT" );
precacheString( &"QUICKMESSAGE_TOOK_LONG_ENOUGH" );
precacheString( &"QUICKMESSAGE_ARE_YOU_CRAZY" );
precacheString( &"QUICKMESSAGE_WATCH_SIX" );
precacheString( &"QUICKMESSAGE_COME_ON" );
}
quickcommands(response)
{
self endon ( "disconnect" );
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_cmd_followme";
saytext = &"QUICKMESSAGE_FOLLOW_ME";
//saytext = "Follow Me!";
break;
case "2":
soundalias = "mp_cmd_movein";
saytext = &"QUICKMESSAGE_MOVE_IN";
//saytext = "Move in!";
break;
case "3":
soundalias = "mp_cmd_fallback";
saytext = &"QUICKMESSAGE_FALL_BACK";
//saytext = "Fall back!";
break;
case "4":
soundalias = "mp_cmd_suppressfire";
saytext = &"QUICKMESSAGE_SUPPRESSING_FIRE";
//saytext = "Suppressing fire!";
break;
case "5":
soundalias = "mp_cmd_attackleftflank";
saytext = &"QUICKMESSAGE_ATTACK_LEFT_FLANK";
//saytext = "Attack left flank!";
break;
case "6":
soundalias = "mp_cmd_attackrightflank";
saytext = &"QUICKMESSAGE_ATTACK_RIGHT_FLANK";
//saytext = "Attack right flank!";
break;
case "7":
soundalias = "mp_cmd_holdposition";
saytext = &"QUICKMESSAGE_HOLD_THIS_POSITION";
//saytext = "Hold this position!";
break;
default:
assert(response == "8");
soundalias = "mp_cmd_regroup";
saytext = &"QUICKMESSAGE_REGROUP";
//saytext = "Regroup!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
quickstatements(response)
{
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_stm_enemyspotted";
saytext = &"QUICKMESSAGE_ENEMY_SPOTTED";
//saytext = "Enemy spotted!";
break;
case "2":
soundalias = "mp_stm_enemiesspotted";
saytext = &"QUICKMESSAGE_ENEMIES_SPOTTED";
//saytext = "Enemy down!";
break;
case "3":
soundalias = "mp_stm_iminposition";
saytext = &"QUICKMESSAGE_IM_IN_POSITION";
//saytext = "I'm in position.";
break;
case "4":
soundalias = "mp_stm_areasecure";
saytext = &"QUICKMESSAGE_AREA_SECURE";
//saytext = "Area secure!";
break;
case "5":
soundalias = "mp_stm_watchsix";
saytext = &"QUICKMESSAGE_WATCH_SIX";
//saytext = "Grenade!";
break;
case "6":
soundalias = "mp_stm_sniper";
saytext = &"QUICKMESSAGE_SNIPER";
//saytext = "Sniper!";
break;
default:
assert(response == "7");
soundalias = "mp_stm_needreinforcements";
saytext = &"QUICKMESSAGE_NEED_REINFORCEMENTS";
//saytext = "Need reinforcements!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
quickresponses(response)
{
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_rsp_yessir";
saytext = &"QUICKMESSAGE_YES_SIR";
//saytext = "Yes Sir!";
break;
case "2":
soundalias = "mp_rsp_nosir";
saytext = &"QUICKMESSAGE_NO_SIR";
//saytext = "No Sir!";
break;
case "3":
soundalias = "mp_rsp_onmyway";
saytext = &"QUICKMESSAGE_IM_ON_MY_WAY";
//saytext = "On my way.";
break;
case "4":
soundalias = "mp_rsp_sorry";
saytext = &"QUICKMESSAGE_SORRY";
//saytext = "Sorry.";
break;
case "5":
soundalias = "mp_rsp_greatshot";
saytext = &"QUICKMESSAGE_GREAT_SHOT";
//saytext = "Great shot!";
break;
default:
assert(response == "6");
soundalias = "mp_rsp_comeon";
saytext = &"QUICKMESSAGE_COME_ON";
//saytext = "Took long enough!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
doQuickMessage( soundalias, saytext )
{
if(self.sessionstate != "playing")
return;
prefix = maps\mp\gametypes\_teams::getTeamVoicePrefix( self.team );
if(isdefined(level.QuickMessageToAll) && level.QuickMessageToAll)
{
self.headiconteam = "none";
self.headicon = "talkingicon";
self playSound( prefix+soundalias );
self sayAll(saytext);
}
else
{
if(self.sessionteam == "allies")
self.headiconteam = "allies";
else if(self.sessionteam == "axis")
self.headiconteam = "axis";
self.headicon = "talkingicon";
self playSound( prefix+soundalias );
self sayTeam( saytext );
self pingPlayer();
}
}
saveHeadIcon()
{
if(isdefined(self.headicon))
self.oldheadicon = self.headicon;
if(isdefined(self.headiconteam))
self.oldheadiconteam = self.headiconteam;
}
restoreHeadIcon()
{
if(isdefined(self.oldheadicon))
self.headicon = self.oldheadicon;
if(isdefined(self.oldheadiconteam))
self.headiconteam = self.oldheadiconteam;
}
+686
View File
@@ -0,0 +1,686 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
level.scoreInfo = [];
level.xpScale = getDvarInt( "scr_xpscale" );
if ( level.xpScale > 4 || level.xpScale < 0)
exitLevel( false );
level.xpScale = min( level.xpScale, 4 );
level.xpScale = max( level.xpScale, 0 );
level.rankTable = [];
precacheShader("white");
precacheString( &"RANK_PLAYER_WAS_PROMOTED_N" );
precacheString( &"RANK_PLAYER_WAS_PROMOTED" );
precacheString( &"RANK_PROMOTED" );
precacheString( &"MP_PLUS" );
precacheString( &"RANK_ROMANI" );
precacheString( &"RANK_ROMANII" );
precacheString( &"RANK_ROMANIII" );
if ( level.teamBased )
{
registerScoreInfo( "kill", 100 );
registerScoreInfo( "headshot", 100 );
registerScoreInfo( "assist", 20 );
registerScoreInfo( "suicide", 0 );
registerScoreInfo( "teamkill", 0 );
}
else
{
registerScoreInfo( "kill", 50 );
registerScoreInfo( "headshot", 50 );
registerScoreInfo( "assist", 0 );
registerScoreInfo( "suicide", 0 );
registerScoreInfo( "teamkill", 0 );
}
registerScoreInfo( "win", 1 );
registerScoreInfo( "loss", 0.5 );
registerScoreInfo( "tie", 0.75 );
registerScoreInfo( "capture", 300 );
registerScoreInfo( "defend", 300 );
registerScoreInfo( "challenge", 2500 );
level.maxRank = int(tableLookup( "mp/rankTable.csv", 0, "maxrank", 1 ));
level.maxPrestige = int(tableLookup( "mp/rankIconTable.csv", 0, "maxprestige", 1 ));
pId = 0;
rId = 0;
for ( pId = 0; pId <= level.maxPrestige; pId++ )
{
for ( rId = 0; rId <= level.maxRank; rId++ )
precacheShader( tableLookup( "mp/rankIconTable.csv", 0, rId, pId+1 ) );
}
rankId = 0;
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
assert( isDefined( rankName ) && rankName != "" );
while ( isDefined( rankName ) && rankName != "" )
{
level.rankTable[rankId][1] = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
level.rankTable[rankId][2] = tableLookup( "mp/ranktable.csv", 0, rankId, 2 );
level.rankTable[rankId][3] = tableLookup( "mp/ranktable.csv", 0, rankId, 3 );
level.rankTable[rankId][7] = tableLookup( "mp/ranktable.csv", 0, rankId, 7 );
precacheString( tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 ) );
rankId++;
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
}
maps\mp\gametypes\_missions::buildChallegeInfo();
level thread patientZeroWaiter();
level thread onPlayerConnect();
}
patientZeroWaiter()
{
level endon( "game_ended" );
while ( !isDefined( level.players ) || !level.players.size )
wait ( 0.05 );
if ( !matchMakingGame() )
{
if ( (getDvar( "mapname" ) == "mp_rust" && randomInt( 1000 ) == 999) )
level.patientZeroName = level.players[0].name;
}
else
{
if ( getDvar( "scr_patientZero" ) != "" )
level.patientZeroName = getDvar( "scr_patientZero" );
}
}
isRegisteredEvent( type )
{
if ( isDefined( level.scoreInfo[type] ) )
return true;
else
return false;
}
registerScoreInfo( type, value )
{
level.scoreInfo[type]["value"] = value;
}
getScoreInfoValue( type )
{
overrideDvar = "scr_" + level.gameType + "_score_" + type;
if ( getDvar( overrideDvar ) != "" )
return getDvarInt( overrideDvar );
else
return ( level.scoreInfo[type]["value"] );
}
getScoreInfoLabel( type )
{
return ( level.scoreInfo[type]["label"] );
}
getRankInfoMinXP( rankId )
{
return int(level.rankTable[rankId][2]);
}
getRankInfoXPAmt( rankId )
{
return int(level.rankTable[rankId][3]);
}
getRankInfoMaxXp( rankId )
{
return int(level.rankTable[rankId][7]);
}
getRankInfoFull( rankId )
{
return tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 );
}
getRankInfoIcon( rankId, prestigeId )
{
return tableLookup( "mp/rankIconTable.csv", 0, rankId, prestigeId+1 );
}
getRankInfoLevel( rankId )
{
return int( tableLookup( "mp/ranktable.csv", 0, rankId, 13 ) );
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
/#
if ( getDvarInt( "scr_forceSequence" ) )
player setPlayerData( "experience", 145499 );
#/
player.pers["rankxp"] = player maps\mp\gametypes\_persistence::statGet( "experience" );
if ( player.pers["rankxp"] < 0 ) // paranoid defensive
player.pers["rankxp"] = 0;
rankId = player getRankForXp( player getRankXP() );
player.pers[ "rank" ] = rankId;
player.pers[ "participation" ] = 0;
player.xpUpdateTotal = 0;
player.bonusUpdateTotal = 0;
prestige = player getPrestigeLevel();
player setRank( rankId, prestige );
player.pers["prestige"] = prestige;
player.postGamePromotion = false;
if ( !isDefined( player.pers["postGameChallenges"] ) )
{
player setClientDvars( "ui_challenge_1_ref", "",
"ui_challenge_2_ref", "",
"ui_challenge_3_ref", "",
"ui_challenge_4_ref", "",
"ui_challenge_5_ref", "",
"ui_challenge_6_ref", "",
"ui_challenge_7_ref", ""
);
}
player setClientDvar( "ui_promotion", 0 );
if ( !isDefined( player.pers["summary"] ) )
{
player.pers["summary"] = [];
player.pers["summary"]["xp"] = 0;
player.pers["summary"]["score"] = 0;
player.pers["summary"]["challenge"] = 0;
player.pers["summary"]["match"] = 0;
player.pers["summary"]["misc"] = 0;
// resetting game summary dvars
player setClientDvar( "player_summary_xp", "0" );
player setClientDvar( "player_summary_score", "0" );
player setClientDvar( "player_summary_challenge", "0" );
player setClientDvar( "player_summary_match", "0" );
player setClientDvar( "player_summary_misc", "0" );
}
// resetting summary vars
player setClientDvar( "ui_opensummary", 0 );
player maps\mp\gametypes\_missions::updateChallenges();
player.explosiveKills[0] = 0;
player.xpGains = [];
player.hud_scorePopup = newClientHudElem( player );
player.hud_scorePopup.horzAlign = "center";
player.hud_scorePopup.vertAlign = "middle";
player.hud_scorePopup.alignX = "center";
player.hud_scorePopup.alignY = "middle";
player.hud_scorePopup.x = 0;
if ( level.splitScreen )
player.hud_scorePopup.y = -40;
else
player.hud_scorePopup.y = -60;
player.hud_scorePopup.font = "hudbig";
player.hud_scorePopup.fontscale = 0.75;
player.hud_scorePopup.archived = false;
player.hud_scorePopup.color = (0.5,0.5,0.5);
player.hud_scorePopup.sort = 10000;
player.hud_scorePopup maps\mp\gametypes\_hud::fontPulseInit( 3.0 );
player thread onPlayerSpawned();
player thread onJoinedTeam();
player thread onJoinedSpectators();
}
}
onJoinedTeam()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_team" );
self thread removeRankHUD();
}
}
onJoinedSpectators()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_spectators" );
self thread removeRankHUD();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
}
}
roundUp( floatVal )
{
if ( int( floatVal ) != floatVal )
return int( floatVal+1 );
else
return int( floatVal );
}
giveRankXP( type, value )
{
self endon("disconnect");
lootType = "none";
if ( !self rankingEnabled() )
return;
if ( level.teamBased && (!level.teamCount["allies"] || !level.teamCount["axis"]) )
return;
else if ( !level.teamBased && (level.teamCount["allies"] + level.teamCount["axis"] < 2) )
return;
if ( !isDefined( value ) )
value = getScoreInfoValue( type );
if ( !isDefined( self.xpGains[type] ) )
self.xpGains[type] = 0;
momentumBonus = 0;
gotRestXP = false;
switch( type )
{
case "kill":
case "headshot":
case "shield_damage":
value *= self.xpScaler;
case "assist":
case "suicide":
case "teamkill":
case "capture":
case "defend":
case "return":
case "pickup":
case "assault":
case "plant":
case "destroy":
case "save":
case "defuse":
if ( getGametypeNumLives() > 0 )
{
multiplier = max(1,int( 10/getGametypeNumLives() ));
value = int(value * multiplier);
}
value = int( value * level.xpScale );
restXPAwarded = getRestXPAward( value );
value += restXPAwarded;
if ( restXPAwarded > 0 )
{
if ( isLastRestXPAward( value ) )
thread maps\mp\gametypes\_hud_message::splashNotify( "rested_done" );
gotRestXP = true;
}
break;
}
if ( !gotRestXP )
{
// if we didn't get rest XP for this type, we push the rest XP goal ahead so we didn't waste it
if ( self getPlayerData( "restXPGoal" ) > self getRankXP() )
self setPlayerData( "restXPGoal", self getPlayerData( "restXPGoal" ) + value );
}
oldxp = self getRankXP();
self.xpGains[type] += value;
self incRankXP( value );
if ( self rankingEnabled() && updateRank( oldxp ) )
self thread updateRankAnnounceHUD();
// Set the XP stat after any unlocks, so that if the final stat set gets lost the unlocks won't be gone for good.
self syncXPStat();
if ( !level.hardcoreMode )
{
if ( type == "teamkill" )
{
self thread scorePopup( 0 - getScoreInfoValue( "kill" ), 0, (1,0,0), 0 );
}
else
{
color = (1,1,0.5);
if ( gotRestXP )
color = (1,.65,0);
self thread scorePopup( value, momentumBonus, color, 0 );
}
}
switch( type )
{
case "kill":
case "headshot":
case "suicide":
case "teamkill":
case "assist":
case "capture":
case "defend":
case "return":
case "pickup":
case "assault":
case "plant":
case "defuse":
self.pers["summary"]["score"] += value;
self.pers["summary"]["xp"] += value;
break;
case "win":
case "loss":
case "tie":
self.pers["summary"]["match"] += value;
self.pers["summary"]["xp"] += value;
break;
case "challenge":
self.pers["summary"]["challenge"] += value;
self.pers["summary"]["xp"] += value;
break;
default:
self.pers["summary"]["misc"] += value; //keeps track of ungrouped match xp reward
self.pers["summary"]["match"] += value;
self.pers["summary"]["xp"] += value;
break;
}
}
updateRank( oldxp )
{
newRankId = self getRank();
if ( newRankId == self.pers["rank"] )
return false;
oldRank = self.pers["rank"];
rankId = self.pers["rank"];
self.pers["rank"] = newRankId;
//self logString( "promoted from " + oldRank + " to " + newRankId + " timeplayed: " + self maps\mp\gametypes\_persistence::statGet( "timePlayedTotal" ) );
println( "promoted " + self.name + " from rank " + oldRank + " to " + newRankId + ". Experience went from " + oldxp + " to " + self getRankXP() + "." );
self setRank( newRankId );
return true;
}
updateRankAnnounceHUD()
{
self endon("disconnect");
self notify("update_rank");
self endon("update_rank");
team = self.pers["team"];
if ( !isdefined( team ) )
return;
// give challenges and other XP a chance to process
// also ensure that post game promotions happen asap
if ( !levelFlag( "game_over" ) )
level waittill_notify_or_timeout( "game_over", 0.25 );
newRankName = self getRankInfoFull( self.pers["rank"] );
rank_char = level.rankTable[self.pers["rank"]][1];
subRank = int(rank_char[rank_char.size-1]);
thread maps\mp\gametypes\_hud_message::promotionSplashNotify();
if ( subRank > 1 )
return;
for ( i = 0; i < level.players.size; i++ )
{
player = level.players[i];
playerteam = player.pers["team"];
if ( isdefined( playerteam ) && player != self )
{
if ( playerteam == team )
player iPrintLn( &"RANK_PLAYER_WAS_PROMOTED", self, newRankName );
}
}
}
endGameUpdate()
{
player = self;
}
scorePopup( amount, bonus, hudColor, glowAlpha )
{
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "joined_spectators" );
if ( amount == 0 )
return;
self notify( "scorePopup" );
self endon( "scorePopup" );
self.xpUpdateTotal += amount;
self.bonusUpdateTotal += bonus;
wait ( 0.05 );
if ( self.xpUpdateTotal < 0 )
self.hud_scorePopup.label = &"";
else
self.hud_scorePopup.label = &"MP_PLUS";
self.hud_scorePopup.color = hudColor;
self.hud_scorePopup.glowColor = hudColor;
self.hud_scorePopup.glowAlpha = glowAlpha;
self.hud_scorePopup setValue(self.xpUpdateTotal);
self.hud_scorePopup.alpha = 0.85;
self.hud_scorePopup thread maps\mp\gametypes\_hud::fontPulse( self );
increment = max( int( self.bonusUpdateTotal / 20 ), 1 );
if ( self.bonusUpdateTotal )
{
while ( self.bonusUpdateTotal > 0 )
{
self.xpUpdateTotal += min( self.bonusUpdateTotal, increment );
self.bonusUpdateTotal -= min( self.bonusUpdateTotal, increment );
self.hud_scorePopup setValue( self.xpUpdateTotal );
wait ( 0.05 );
}
}
else
{
wait ( 1.0 );
}
self.hud_scorePopup fadeOverTime( 0.75 );
self.hud_scorePopup.alpha = 0;
self.xpUpdateTotal = 0;
}
removeRankHUD()
{
self.hud_scorePopup.alpha = 0;
}
getRank()
{
rankXp = self.pers["rankxp"];
rankId = self.pers["rank"];
if ( rankXp < (getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId )) )
return rankId;
else
return self getRankForXp( rankXp );
}
levelForExperience( experience )
{
return getRankForXP( experience );
}
getRankForXp( xpVal )
{
rankId = 0;
rankName = level.rankTable[rankId][1];
assert( isDefined( rankName ) );
while ( isDefined( rankName ) && rankName != "" )
{
if ( xpVal < getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId ) )
return rankId;
rankId++;
if ( isDefined( level.rankTable[rankId] ) )
rankName = level.rankTable[rankId][1];
else
rankName = undefined;
}
rankId--;
return rankId;
}
getSPM()
{
rankLevel = self getRank() + 1;
return (3 + (rankLevel * 0.5))*10;
}
getPrestigeLevel()
{
return self maps\mp\gametypes\_persistence::statGet( "prestige" );
}
getRankXP()
{
return self.pers["rankxp"];
}
incRankXP( amount )
{
if ( !self rankingEnabled() )
return;
if ( isDefined( self.isCheater ) )
return;
xp = self getRankXP();
newXp = (xp + amount);
if ( self.pers["rank"] == level.maxRank && newXp >= getRankInfoMaxXP( level.maxRank ) )
newXp = getRankInfoMaxXP( level.maxRank );
self.pers["rankxp"] = newXp;
}
getRestXPAward( baseXP )
{
if ( !getdvarint( "scr_restxp_enable" ) )
return 0;
restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
wantGiveRestXP = int(baseXP * restXPAwardRate);
mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
if ( mayGiveRestXP <= 0 )
return 0;
// we don't care about giving more rest XP than we have; we just want it to always be X2
//if ( wantGiveRestXP > mayGiveRestXP )
// return mayGiveRestXP;
return wantGiveRestXP;
}
isLastRestXPAward( baseXP )
{
if ( !getdvarint( "scr_restxp_enable" ) )
return false;
restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
wantGiveRestXP = int(baseXP * restXPAwardRate);
mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
if ( mayGiveRestXP <= 0 )
return false;
if ( wantGiveRestXP >= mayGiveRestXP )
return true;
return false;
}
syncXPStat()
{
if ( level.xpScale > 4 || level.xpScale <= 0)
exitLevel( false );
xp = self getRankXP();
self maps\mp\gametypes\_persistence::statSet( "experience", xp );
}
+103
View File
@@ -0,0 +1,103 @@
init()
{
level.hostname = getdvar("sv_hostname");
if(level.hostname == "")
level.hostname = "CoDHost";
setdvar("sv_hostname", level.hostname);
level.allowvote = getdvarint("g_allowvote", 1);
SetDvar("g_allowvote", level.allowvote);
makedvarserverinfo("ui_allowvote", level.allowvote);
level.friendlyfire = maps\mp\gametypes\_tweakables::getTweakableValue( "team", "fftype" );
makedvarserverinfo("ui_friendlyfire", level.friendlyfire);
constrainGameType(getdvar("g_gametype"));
for(;;)
{
updateServerSettings();
wait 5;
}
}
updateServerSettings()
{
sv_hostname = getdvar("sv_hostname");
if(level.hostname != sv_hostname)
{
level.hostname = sv_hostname;
}
g_allowvote = getdvarint("g_allowvote", 1);
if(level.allowvote != g_allowvote)
{
level.allowvote = g_allowvote;
setdvar("ui_allowvote", level.allowvote);
}
scr_friendlyfire = maps\mp\gametypes\_tweakables::getTweakableValue( "team", "fftype" );
if(level.friendlyfire != scr_friendlyfire)
{
level.friendlyfire = scr_friendlyfire;
setdvar("ui_friendlyfire", level.friendlyfire);
}
}
constrainGameType(gametype)
{
entities = getentarray();
for(i = 0; i < entities.size; i++)
{
entity = entities[i];
if(gametype == "dm")
{
if(isdefined(entity.script_gametype_dm) && entity.script_gametype_dm != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "tdm")
{
if(isdefined(entity.script_gametype_tdm) && entity.script_gametype_tdm != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "ctf")
{
if(isdefined(entity.script_gametype_ctf) && entity.script_gametype_ctf != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "hq")
{
if(isdefined(entity.script_gametype_hq) && entity.script_gametype_hq != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "sd")
{
if(isdefined(entity.script_gametype_sd) && entity.script_gametype_sd != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "koth")
{
if(isdefined(entity.script_gametype_koth) && entity.script_gametype_koth != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
}
}
+133
View File
@@ -0,0 +1,133 @@
#include maps\mp\_utility;
#include common_scripts\utility;
init()
{
precacheShellShock( "frag_grenade_mp" );
precacheShellShock( "damage_mp" );
precacheRumble( "artillery_rumble" );
precacheRumble( "grenade_rumble" );
precacheMenu( "dirt_effect_center" );
precacheMenu( "dirt_effect_left" );
precacheMenu( "dirt_effect_right" );
}
shellshockOnDamage( cause, damage )
{
if ( self maps\mp\_flashgrenades::isFlashbanged() )
return; // don't interrupt flashbang shellshock
if ( self _hasPerk( "specialty_blastshield" ) )
return;
if ( cause == "MOD_EXPLOSIVE" ||
cause == "MOD_GRENADE" ||
cause == "MOD_GRENADE_SPLASH" ||
cause == "MOD_PROJECTILE" ||
cause == "MOD_PROJECTILE_SPLASH" )
{
time = 0;
if(damage >= 90)
time = 4;
else if(damage >= 50)
time = 3;
else if(damage >= 25)
time = 2;
else if(damage > 10)
time = 2;
if ( time )
{
self shellshock("frag_grenade_mp", 0.5);
}
}
}
endOnDeath()
{
self waittill( "death" );
waittillframeend;
self notify ( "end_explode" );
}
grenade_earthQuake()
{
self thread endOnDeath();
self endon( "end_explode" );
self waittill( "explode", position );
PlayRumbleOnPosition( "grenade_rumble", position );
earthquake( 0.5, 0.75, position, 800 );
foreach ( player in level.players )
{
if ( player isUsingRemote() )
continue;
if ( distance( position, player.origin ) > 600 )
continue;
if ( player DamageConeTrace( position ) )
player thread dirtEffect( position );
}
}
dirtEffect( position )
{
self endon ( "disconnect" );
forwardVec = vectorNormalize( anglesToForward( self.angles ) );
rightVec = vectorNormalize( anglesToRight( self.angles ) );
grenadeVec = vectorNormalize( position - self.origin );
fDot = vectorDot( grenadeVec, forwardVec );
rDot = vectorDot( grenadeVec, rightVec );
printLn( fDot );
printLn( rDot );
effectMenus = [];
if ( fDot > 0 && fDot > 0.5 && self getCurrentWeapon() != "riotshield_mp" )
effectMenus[effectMenus.size] = "dirt_effect_center";
if ( abs(fDot) < 0.866 )
{
if ( rDot > 0 )
effectMenus[effectMenus.size] = "dirt_effect_right";
else
effectMenus[effectMenus.size] = "dirt_effect_left";
}
foreach ( menu in effectMenus )
self openMenu( menu );
if ( isAlive( self ) )
self waittill_notify_or_timeout( "death", 2.0 );
foreach ( menu in effectMenus )
self closeMenu( menu );
}
c4_earthQuake()
{
self thread endOnDeath();
self endon( "end_explode" );
self waittill( "explode", position );
PlayRumbleOnPosition( "grenade_rumble", position );
earthquake( 0.4, 0.75, position, 512 );
}
barrel_earthQuake()
{
PlayRumbleOnPosition( "grenade_rumble", self.origin );
earthquake( 0.4, 0.5, self.origin, 512 );
}
artillery_earthQuake()
{
PlayRumbleOnPosition( "artillery_rumble", self.origin );
earthquake( 0.7, 0.5, self.origin, 800 );
}
File diff suppressed because it is too large. Load diff
+149
View File
@@ -0,0 +1,149 @@
init()
{
level.spectateOverride["allies"] = spawnstruct();
level.spectateOverride["axis"] = spawnstruct();
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread onJoinedTeam();
player thread onJoinedSpectators();
player thread onSpectatingClient();
}
}
onJoinedTeam()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_team" );
self setSpectatePermissions();
}
}
onJoinedSpectators()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_spectators" );
self setSpectatePermissions();
}
}
onSpectatingClient()
{
self endon("disconnect");
for( ;; )
{
self waittill( "spectating_cycle" );
// show the card for the player we're viewing. Could be undefined if the cyling failed
spectatedPlayer = self GetSpectatingPlayer();
if ( isDefined( spectatedPlayer ) )
{
self SetCardDisplaySlot( spectatedPlayer, 6 );
}
}
}
updateSpectateSettings()
{
level endon ( "game_ended" );
for ( index = 0; index < level.players.size; index++ )
level.players[index] setSpectatePermissions();
}
getOtherTeam( team )
{
if ( team == "axis" )
return "allies";
else if ( team == "allies" )
return "axis";
else
return "none";
}
setSpectatePermissions()
{
team = self.sessionteam;
if ( level.gameEnded && gettime() - level.gameEndTime >= 2000 )
{
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", true );
return;
}
spectateType = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "spectatetype" );
switch( spectateType )
{
case 0: // disabled
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
break;
case 1: // team/player only
if ( !level.teamBased )
{
self allowSpectateTeam( "allies", true );
self allowSpectateTeam( "axis", true );
self allowSpectateTeam( "none", true );
self allowSpectateTeam( "freelook", false );
}
else if ( isDefined( team ) && (team == "allies" || team == "axis") )
{
self allowSpectateTeam( team, true );
self allowSpectateTeam( getOtherTeam( team ), false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
}
else
{
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
}
break;
case 2: // free
self allowSpectateTeam( "allies", true );
self allowSpectateTeam( "axis", true );
self allowSpectateTeam( "freelook", true );
self allowSpectateTeam( "none", true );
break;
}
if ( isDefined( team ) && (team == "axis" || team == "allies") )
{
if ( isdefined(level.spectateOverride[team].allowFreeSpectate) )
self allowSpectateTeam( "freelook", true );
if (isdefined(level.spectateOverride[team].allowEnemySpectate))
self allowSpectateTeam( getOtherTeam( team ), true );
}
}
+892
View File
@@ -0,0 +1,892 @@
#include maps\mp\_utility;
FACTION_REF_COL = 0;
FACTION_NAME_COL = 1;
FACTION_SHORT_NAME_COL = 2;
FACTION_ELIMINATED_COL = 3;
FACTION_FORFEITED_COL = 4;
FACTION_ICON_COL = 5;
FACTION_HUD_ICON_COL = 6;
FACTION_VOICE_PREFIX_COL = 7;
FACTION_SPAWN_MUSIC_COL = 8;
FACTION_WIN_MUSIC_COL = 9;
FACTION_FLAG_MODEL_COL = 10;
FACTION_FLAG_CARRY_MODEL_COL = 11;
FACTION_FLAG_ICON_COL = 12;
FACTION_FLAG_FX_COL = 13;
FACTION_COLOR_R_COL = 14;
FACTION_COLOR_G_COL = 15;
FACTION_COLOR_B_COL = 16;
FACTION_HEAD_ICON_COL = 17;
FACTION_CRATE_MODEL_COL = 18;
init()
{
initScoreBoard();
level.teamBalance = getDvarInt("scr_teambalance");
level.maxClients = getDvarInt( "sv_maxclients" );
level._effect["thermal_beacon"] = loadFx("misc/thermal_beacon_inverted");
effect = level._effect["thermal_beacon"];
PrecacheFxTeamThermal( effect, "J_Spine4" );
setPlayerModels();
level.freeplayers = [];
if( level.teamBased )
{
level thread onPlayerConnect();
level thread updateTeamBalance();
wait .15;
level thread updatePlayerTimes();
}
else
{
level thread onFreePlayerConnect();
wait .15;
level thread updateFreePlayerTimes();
}
}
initScoreBoard()
{
setDvar("g_TeamName_Allies", getTeamShortName( "allies" ));
setDvar("g_TeamIcon_Allies", getTeamIcon( "allies" ));
setDvar("g_TeamIcon_MyAllies", getTeamIcon( "allies" ));
setDvar("g_TeamIcon_EnemyAllies", getTeamIcon( "allies" ));
scoreColor = getTeamColor( "allies" );
setDvar("g_ScoresColor_Allies", scoreColor[0] + " " + scoreColor[1] + " " + scoreColor[2] );
setDvar("g_TeamName_Axis", getTeamShortName( "axis" ));
setDvar("g_TeamIcon_Axis", getTeamIcon( "axis" ));
setDvar("g_TeamIcon_MyAxis", getTeamIcon( "axis" ));
setDvar("g_TeamIcon_EnemyAxis", getTeamIcon( "axis" ));
scoreColor = getTeamColor( "axis" );
setDvar("g_ScoresColor_Axis", scoreColor[0] + " " + scoreColor[1] + " " + scoreColor[2] );
setdvar("g_ScoresColor_Spectator", ".25 .25 .25");
setdvar("g_ScoresColor_Free", ".76 .78 .10");
setdvar("g_teamColor_MyTeam", ".6 .8 .6" );
setdvar("g_teamColor_EnemyTeam", "1 .45 .5" );
setdvar("g_teamTitleColor_MyTeam", ".6 .8 .6" );
setdvar("g_teamTitleColor_EnemyTeam", "1 .45 .5" );
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread onJoinedTeam();
player thread onJoinedSpectators();
player thread onPlayerSpawned();
player thread trackPlayedTime();
}
}
onFreePlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread trackFreePlayedTime();
}
}
onJoinedTeam()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_team" );
//self logString( "joined team: " + self.pers["team"] );
self updateTeamTime();
}
}
onJoinedSpectators()
{
self endon("disconnect");
for(;;)
{
self waittill("joined_spectators");
self.pers["teamTime"] = undefined;
}
}
trackPlayedTime()
{
self endon( "disconnect" );
self.timePlayed["allies"] = 0;
self.timePlayed["axis"] = 0;
self.timePlayed["free"] = 0;
self.timePlayed["other"] = 0;
self.timePlayed["total"] = 0;
gameFlagWait( "prematch_done" );
for ( ;; )
{
if ( game["state"] == "playing" )
{
if ( self.sessionteam == "allies" )
{
self.timePlayed["allies"]++;
self.timePlayed["total"]++;
}
else if ( self.sessionteam == "axis" )
{
self.timePlayed["axis"]++;
self.timePlayed["total"]++;
}
else if ( self.sessionteam == "spectator" )
{
self.timePlayed["other"]++;
}
}
wait ( 1.0 );
}
}
updatePlayerTimes()
{
if ( !level.rankedmatch )
return;
level endon( "game_ended" );
for ( ;; )
{
foreach ( player in level.players )
player updatePlayedTime();
wait( 1.0 );
}
}
updatePlayedTime()
{
if ( !self rankingEnabled() )
return;
if ( self.timePlayed["allies"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedAllies", self.timePlayed["allies"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["allies"] );
self maps\mp\gametypes\_persistence::statAddChildBuffered( "round", "timePlayed", self.timePlayed["allies"] );
}
if ( self.timePlayed["axis"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOpfor", self.timePlayed["axis"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["axis"] );
self maps\mp\gametypes\_persistence::statAddChildBuffered( "round", "timePlayed", self.timePlayed["axis"] );
}
if ( self.timePlayed["other"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOther", self.timePlayed["other"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["other"] );
self maps\mp\gametypes\_persistence::statAddChildBuffered( "round", "timePlayed", self.timePlayed["other"] );
}
if ( game["state"] == "postgame" )
return;
self.timePlayed["allies"] = 0;
self.timePlayed["axis"] = 0;
self.timePlayed["other"] = 0;
}
updateTeamTime()
{
if ( game["state"] != "playing" )
return;
self.pers["teamTime"] = getTime();
}
updateTeamBalanceDvar()
{
for(;;)
{
teambalance = getdvarInt("scr_teambalance");
if(level.teambalance != teambalance)
level.teambalance = getdvarInt("scr_teambalance");
wait 1;
}
}
updateTeamBalance()
{
level.teamLimit = level.maxclients / 2;
level thread updateTeamBalanceDvar();
wait .15;
if ( level.teamBalance && isRoundBased() )
{
if( isDefined( game["BalanceTeamsNextRound"] ) )
iPrintLnbold( &"MP_AUTOBALANCE_NEXT_ROUND" );
// TODO: add or change
level waittill( "restarting" );
if( isDefined( game["BalanceTeamsNextRound"] ) )
{
level balanceTeams();
game["BalanceTeamsNextRound"] = undefined;
}
else if( !getTeamBalance() )
{
game["BalanceTeamsNextRound"] = true;
}
}
else
{
level endon ( "game_ended" );
for( ;; )
{
if( level.teamBalance )
{
if( !getTeamBalance() )
{
iPrintLnBold( &"MP_AUTOBALANCE_SECONDS", 15 );
wait 15.0;
if( !getTeamBalance() )
level balanceTeams();
}
wait 59.0;
}
wait 1.0;
}
}
}
getTeamBalance()
{
level.team["allies"] = 0;
level.team["axis"] = 0;
players = level.players;
for(i = 0; i < players.size; i++)
{
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
level.team["allies"]++;
else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
level.team["axis"]++;
}
if((level.team["allies"] > (level.team["axis"] + level.teamBalance)) || (level.team["axis"] > (level.team["allies"] + level.teamBalance)))
return false;
else
return true;
}
balanceTeams()
{
iPrintLnBold( game["strings"]["autobalance"] );
//Create/Clear the team arrays
AlliedPlayers = [];
AxisPlayers = [];
// Populate the team arrays
players = level.players;
for(i = 0; i < players.size; i++)
{
if(!isdefined(players[i].pers["teamTime"]))
continue;
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
AlliedPlayers[AlliedPlayers.size] = players[i];
else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
AxisPlayers[AxisPlayers.size] = players[i];
}
MostRecent = undefined;
while((AlliedPlayers.size > (AxisPlayers.size + 1)) || (AxisPlayers.size > (AlliedPlayers.size + 1)))
{
if(AlliedPlayers.size > (AxisPlayers.size + 1))
{
// Move the player that's been on the team the shortest ammount of time (highest teamTime value)
for(j = 0; j < AlliedPlayers.size; j++)
{
if(isdefined(AlliedPlayers[j].dont_auto_balance))
continue;
if(!isdefined(MostRecent))
MostRecent = AlliedPlayers[j];
else if(AlliedPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"])
MostRecent = AlliedPlayers[j];
}
MostRecent [[level.axis]]();
}
else if(AxisPlayers.size > (AlliedPlayers.size + 1))
{
// Move the player that's been on the team the shortest ammount of time (highest teamTime value)
for(j = 0; j < AxisPlayers.size; j++)
{
if(isdefined(AxisPlayers[j].dont_auto_balance))
continue;
if(!isdefined(MostRecent))
MostRecent = AxisPlayers[j];
else if(AxisPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"])
MostRecent = AxisPlayers[j];
}
MostRecent [[level.allies]]();
}
MostRecent = undefined;
AlliedPlayers = [];
AxisPlayers = [];
players = level.players;
for(i = 0; i < players.size; i++)
{
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
AlliedPlayers[AlliedPlayers.size] = players[i];
else if((isdefined(players[i].pers["team"])) &&(players[i].pers["team"] == "axis"))
AxisPlayers[AxisPlayers.size] = players[i];
}
}
}
setGhillieModels( env )
{
level.environment = env;
switch ( env )
{
case "desert":
mptype\mptype_ally_ghillie_desert::precache();
mptype\mptype_opforce_ghillie_desert::precache();
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_desert::main;
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_desert::main;
break;
case "arctic":
mptype\mptype_ally_ghillie_arctic::precache();
mptype\mptype_opforce_ghillie_arctic::precache();
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_arctic::main;
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_arctic::main;
break;
case "urban":
mptype\mptype_ally_ghillie_urban::precache();
mptype\mptype_opforce_ghillie_urban::precache();
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_urban::main;
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_urban::main;
break;
case "forest":
mptype\mptype_ally_ghillie_forest::precache();
mptype\mptype_opforce_ghillie_forest::precache();
game["allies_model"]["GHILLIE"] = mptype\mptype_ally_ghillie_forest::main;
game["axis_model"]["GHILLIE"] = mptype\mptype_opforce_ghillie_forest::main;
break;
default:
break;
}
}
setTeamModels( team, charSet )
{
switch ( charSet )
{
case "seals_udt":
mptype\mptype_seal_udt_sniper::precache();
mptype\mptype_seal_udt_lmg::precache();
mptype\mptype_seal_udt_assault::precache();
mptype\mptype_seal_udt_shotgun::precache();
mptype\mptype_seal_udt_smg::precache();
mptype\mptype_seal_udt_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_seal_udt_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_seal_udt_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_seal_udt_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_seal_udt_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_seal_udt_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_seal_udt_riot::main;
break;
case "us_army":
mptype\mptype_us_army_sniper::precache();
mptype\mptype_us_army_lmg::precache();
mptype\mptype_us_army_assault::precache();
mptype\mptype_us_army_shotgun::precache();
mptype\mptype_us_army_smg::precache();
mptype\mptype_us_army_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_us_army_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_us_army_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_us_army_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_us_army_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_us_army_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_us_army_riot::main;
break;
case "opforce_composite":
mptype\mptype_opforce_comp_assault::precache();
mptype\mptype_opforce_comp_lmg::precache();
mptype\mptype_opforce_comp_shotgun::precache();
mptype\mptype_opforce_comp_smg::precache();
mptype\mptype_opforce_comp_sniper::precache();
mptype\mptype_opforce_comp_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_comp_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_opforce_comp_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_comp_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_comp_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_opforce_comp_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_comp_riot::main;
break;
case "opforce_arctic":
mptype\mptype_opforce_arctic_assault::precache();
mptype\mptype_opforce_arctic_lmg::precache();
mptype\mptype_opforce_arctic_shotgun::precache();
mptype\mptype_opforce_arctic_smg::precache();
mptype\mptype_opforce_arctic_sniper::precache();
mptype\mptype_opforce_arctic_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_arctic_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_opforce_arctic_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_arctic_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_arctic_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_opforce_arctic_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_arctic_riot::main;
break;
case "opforce_airborne":
mptype\mptype_opforce_airborne_assault::precache();
mptype\mptype_opforce_airborne_lmg::precache();
mptype\mptype_opforce_airborne_shotgun::precache();
mptype\mptype_opforce_airborne_smg::precache();
mptype\mptype_opforce_airborne_sniper::precache();
mptype\mptype_opforce_airborne_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_airborne_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_opforce_airborne_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_airborne_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_airborne_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_opforce_airborne_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_airborne_riot::main;
break;
case "militia":
mptype\mptype_opforce_militia_assault::precache();
mptype\mptype_opforce_militia_lmg::precache();
mptype\mptype_opforce_militia_shotgun::precache();
mptype\mptype_opforce_militia_smg::precache();
mptype\mptype_opforce_militia_sniper::precache();
mptype\mptype_opforce_militia_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_opforce_militia_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_opforce_militia_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_opforce_militia_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_opforce_militia_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_opforce_militia_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_opforce_militia_riot::main;
break;
case "socom_141":
mptype\mptype_socom_assault::precache();
mptype\mptype_socom_lmg::precache();
mptype\mptype_socom_shotgun::precache();
mptype\mptype_socom_smg::precache();
mptype\mptype_socom_sniper::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_socom_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_socom_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_socom_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_socom_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_socom_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_socom_smg::main;
break;
case "socom_141_desert":
mptype\mptype_tf141_desert_assault::precache();
mptype\mptype_tf141_desert_lmg::precache();
mptype\mptype_tf141_desert_smg::precache();
mptype\mptype_tf141_desert_shotgun::precache();
mptype\mptype_tf141_desert_sniper::precache();
mptype\mptype_tf141_desert_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_tf141_desert_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_tf141_desert_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_tf141_desert_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_tf141_desert_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_tf141_desert_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_tf141_desert_riot::main;
break;
case "socom_141_forest":
mptype\mptype_tf141_forest_assault::precache();
mptype\mptype_tf141_forest_lmg::precache();
mptype\mptype_tf141_forest_smg::precache();
mptype\mptype_tf141_forest_shotgun::precache();
mptype\mptype_tf141_forest_sniper::precache();
mptype\mptype_tf141_forest_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_tf141_forest_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_tf141_forest_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_tf141_forest_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_tf141_forest_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_tf141_forest_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_tf141_forest_riot::main;
break;
case "socom_141_arctic":
mptype\mptype_tf141_arctic_assault::precache();
mptype\mptype_tf141_arctic_lmg::precache();
mptype\mptype_tf141_arctic_smg::precache();
mptype\mptype_tf141_arctic_shotgun::precache();
mptype\mptype_tf141_arctic_sniper::precache();
mptype\mptype_tf141_arctic_riot::precache();
game[team + "_model"]["SNIPER"] = mptype\mptype_tf141_arctic_sniper::main;
game[team + "_model"]["LMG"] = mptype\mptype_tf141_arctic_lmg::main;
game[team + "_model"]["ASSAULT"] = mptype\mptype_tf141_arctic_assault::main;
game[team + "_model"]["SHOTGUN"] = mptype\mptype_tf141_arctic_shotgun::main;
game[team + "_model"]["SMG"] = mptype\mptype_tf141_arctic_smg::main;
game[team + "_model"]["RIOT"] = mptype\mptype_tf141_arctic_riot::main;
break;
}
}
setPlayerModels()
{
//mptype\mptype_us_army_riot::precache();
//game["allies_model"]["riotshield"] = mptype\mptype_us_army_riot::main;
//game["axis_model"]["riotshield"] = mptype\mptype_us_army_riot::main;
setTeamModels( "allies", game["allies"] );
setTeamModels( "axis", game["axis"] );
setGhillieModels( getMapCustom( "environment" ) );
}
playerModelForWeapon( weapon, secondary )
{
team = self.team;
if ( isDefined( game[team + "_model"][weapon] ) )
{
[[game[team+"_model"][weapon]]]();
return;
}
weaponClass = tablelookup( "mp/statstable.csv", 4, weapon, 2 );
switch ( weaponClass )
{
case "weapon_smg":
[[game[team+"_model"]["SMG"]]]();
break;
case "weapon_assault":
weaponClass = tablelookup( "mp/statstable.csv", 4, secondary, 2 );
if ( weaponClass == "weapon_shotgun" )
[[game[team+"_model"]["SHOTGUN"]]]();
else
[[game[team+"_model"]["ASSAULT"]]]();
break;
case "weapon_sniper":
if ( level.environment != "" && self isItemUnlocked( "ghillie_" + level.environment ) )
[[game[team+"_model"]["GHILLIE"]]]();
else
[[game[team+"_model"]["SNIPER"]]]();
break;
case "weapon_lmg":
[[game[team+"_model"]["LMG"]]]();
break;
case "weapon_riot":
[[game[team+"_model"]["RIOT"]]]();
break;
default:
[[game[team+"_model"]["ASSAULT"]]]();
break;
}
}
CountPlayers()
{
//chad
players = level.players;
allies = 0;
axis = 0;
for(i = 0; i < players.size; i++)
{
if ( players[i] == self )
continue;
if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "allies"))
allies++;
else if((isdefined(players[i].pers["team"])) && (players[i].pers["team"] == "axis"))
axis++;
}
players["allies"] = allies;
players["axis"] = axis;
return players;
}
trackFreePlayedTime()
{
self endon( "disconnect" );
self.timePlayed["allies"] = 0;
self.timePlayed["axis"] = 0;
self.timePlayed["other"] = 0;
self.timePlayed["total"] = 0;
for ( ;; )
{
if ( game["state"] == "playing" )
{
if ( isDefined( self.pers["team"] ) && self.pers["team"] == "allies" && self.sessionteam != "spectator" )
{
self.timePlayed["allies"]++;
self.timePlayed["total"]++;
}
else if ( isDefined( self.pers["team"] ) && self.pers["team"] == "axis" && self.sessionteam != "spectator" )
{
self.timePlayed["axis"]++;
self.timePlayed["total"]++;
}
else
{
self.timePlayed["other"]++;
}
}
wait ( 1.0 );
}
}
/#
playerConnectedTest()
{
if ( getdvarint( "scr_runlevelandquit" ) == 1 )
return;
level endon( "exitLevel_called" );
// every frame, do a getPlayerData on each player in level.players.
// this will force a script error if a player in level.players isn't connected.
for ( ;; )
{
foreach ( player in level.players )
{
player getPlayerData( "experience" );
}
wait .05;
}
}
#/
updateFreePlayerTimes()
{
if ( !level.rankedmatch )
return;
/#
thread playerConnectedTest();
#/
nextToUpdate = 0;
for ( ;; )
{
nextToUpdate++;
if ( nextToUpdate >= level.players.size )
nextToUpdate = 0;
if ( isDefined( level.players[nextToUpdate] ) )
level.players[nextToUpdate] updateFreePlayedTime();
wait ( 1.0 );
}
}
updateFreePlayedTime()
{
if ( !self rankingEnabled() )
return;
if ( self.timePlayed["allies"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedAllies", self.timePlayed["allies"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["allies"] );
}
if ( self.timePlayed["axis"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOpfor", self.timePlayed["axis"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["axis"] );
}
if ( self.timePlayed["other"] )
{
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedOther", self.timePlayed["other"] );
self maps\mp\gametypes\_persistence::statAddBuffered( "timePlayedTotal", self.timePlayed["other"] );
}
if ( game["state"] == "postgame" )
return;
self.timePlayed["allies"] = 0;
self.timePlayed["axis"] = 0;
self.timePlayed["other"] = 0;
}
getJoinTeamPermissions( team )
{
teamcount = 0;
players = level.players;
for(i = 0; i < players.size; i++)
{
player = players[i];
if((isdefined(player.pers["team"])) && (player.pers["team"] == team))
teamcount++;
}
if( teamCount < level.teamLimit )
return true;
else
return false;
}
onPlayerSpawned()
{
level endon ( "game_ended" );
for ( ;; )
{
self waittill ( "spawned_player" );
}
}
getTeamName( teamRef )
{
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_NAME_COL ) );
}
getTeamShortName( teamRef )
{
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_SHORT_NAME_COL ) );
}
getTeamForfeitedString( teamRef )
{
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FORFEITED_COL ) );
}
getTeamEliminatedString( teamRef )
{
return ( tableLookupIString( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_ELIMINATED_COL ) );
}
getTeamIcon( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_ICON_COL ) );
}
getTeamHudIcon( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_HUD_ICON_COL ) );
}
getTeamHeadIcon( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_HEAD_ICON_COL ) );
}
getTeamVoicePrefix( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_VOICE_PREFIX_COL ) );
}
getTeamSpawnMusic( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_SPAWN_MUSIC_COL ) );
}
getTeamWinMusic( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_WIN_MUSIC_COL ) );
}
getTeamFlagModel( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_MODEL_COL ) );
}
getTeamFlagCarryModel( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_CARRY_MODEL_COL ) );
}
getTeamFlagIcon( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_ICON_COL ) );
}
getTeamFlagFX( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_FLAG_FX_COL ) );
}
getTeamColor( teamRef )
{
return ( (stringToFloat( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_COLOR_R_COL ) ),
stringToFloat( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_COLOR_G_COL ) ),
stringToFloat( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_COLOR_B_COL ) ))
);
}
getTeamCrateModel( teamRef )
{
return ( tableLookup( "mp/factionTable.csv", FACTION_REF_COL, game[teamRef], FACTION_CRATE_MODEL_COL ) );
}
+365
View File
@@ -0,0 +1,365 @@
#include maps\mp\_utility;
getTweakableDVarValue( category, name )
{
switch( category )
{
case "rule":
dVar = level.rules[name].dVar;
break;
case "game":
dVar = level.gameTweaks[name].dVar;
break;
case "team":
dVar = level.teamTweaks[name].dVar;
break;
case "player":
dVar = level.playerTweaks[name].dVar;
break;
case "class":
dVar = level.classTweaks[name].dVar;
break;
case "weapon":
dVar = level.weaponTweaks[name].dVar;
break;
case "hardpoint":
dVar = level.hardpointTweaks[name].dVar;
break;
case "hud":
dVar = level.hudTweaks[name].dVar;
break;
default:
dVar = undefined;
break;
}
assert( isDefined( dVar ) );
value = getDvarInt( dVar );
return value;
}
getTweakableDVar( category, name )
{
switch( category )
{
case "rule":
value = level.rules[name].dVar;
break;
case "game":
value = level.gameTweaks[name].dVar;
break;
case "team":
value = level.teamTweaks[name].dVar;
break;
case "player":
value = level.playerTweaks[name].dVar;
break;
case "class":
value = level.classTweaks[name].dVar;
break;
case "weapon":
value = level.weaponTweaks[name].dVar;
break;
case "hardpoint":
value = level.hardpointTweaks[name].dVar;
break;
case "hud":
value = level.hudTweaks[name].dVar;
break;
default:
value = undefined;
break;
}
assert( isDefined( value ) );
return value;
}
getTweakableValue( category, name )
{
switch( category )
{
case "rule":
value = level.rules[name].value;
break;
case "game":
value = level.gameTweaks[name].value;
break;
case "team":
value = level.teamTweaks[name].value;
break;
case "player":
value = level.playerTweaks[name].value;
break;
case "class":
value = level.classTweaks[name].value;
break;
case "weapon":
value = level.weaponTweaks[name].value;
break;
case "hardpoint":
value = level.hardpointTweaks[name].value;
break;
case "hud":
value = level.hudTweaks[name].value;
break;
default:
value = undefined;
break;
}
/#
overrideDvar = "scr_" + level.gameType + "_" + category + "_" + name;
return getDvarInt( overrideDvar, value );
#/
assert( isDefined( value ) );
return value;
}
getTweakableLastValue( category, name )
{
switch( category )
{
case "rule":
value = level.rules[name].lastValue;
break;
case "game":
value = level.gameTweaks[name].lastValue;
break;
case "team":
value = level.teamTweaks[name].lastValue;
break;
case "player":
value = level.playerTweaks[name].lastValue;
break;
case "class":
value = level.classTweaks[name].lastValue;
break;
case "weapon":
value = level.weaponTweaks[name].lastValue;
break;
case "hardpoint":
value = level.hardpointTweaks[name].lastValue;
break;
case "hud":
value = level.hudTweaks[name].lastValue;
break;
default:
value = undefined;
break;
}
assert( isDefined( value ) );
return value;
}
setTweakableValue( category, name, value )
{
switch( category )
{
case "rule":
dVar = level.rules[name].dVar;
break;
case "game":
dVar = level.gameTweaks[name].dVar;
break;
case "team":
dVar = level.teamTweaks[name].dVar;
break;
case "player":
dVar = level.playerTweaks[name].dVar;
break;
case "class":
dVar = level.classTweaks[name].dVar;
break;
case "weapon":
dVar = level.weaponTweaks[name].dVar;
break;
case "hardpoint":
dVar = level.hardpointTweaks[name].dVar;
break;
case "hud":
dVar = level.hudTweaks[name].dVar;
break;
default:
dVar = undefined;
break;
}
setDvar( dVar, value );
}
setTweakableLastValue( category, name, value )
{
switch( category )
{
case "rule":
level.rules[name].lastValue = value;
break;
case "game":
level.gameTweaks[name].lastValue = value;
break;
case "team":
level.teamTweaks[name].lastValue = value;
break;
case "player":
level.playerTweaks[name].lastValue = value;
break;
case "class":
level.classTweaks[name].lastValue = value;
break;
case "weapon":
level.weaponTweaks[name].lastValue = value;
break;
case "hardpoint":
level.hardpointTweaks[name].lastValue = value;
break;
case "hud":
level.hudTweaks[name].lastValue = value;
break;
default:
break;
}
}
registerTweakable( category, name, dvar, value )
{
if ( isString( value ) )
{
value = getDvar( dvar, value );
}
else
{
value = getDvarInt( dvar, value );
}
switch( category )
{
case "rule":
if ( !isDefined( level.rules[name] ) )
level.rules[name] = spawnStruct();
level.rules[name].value = value;
level.rules[name].lastValue = value;
level.rules[name].dVar = dvar;
break;
case "game":
if ( !isDefined( level.gameTweaks[name] ) )
level.gameTweaks[name] = spawnStruct();
level.gameTweaks[name].value = value;
level.gameTweaks[name].lastValue = value;
level.gameTweaks[name].dVar = dvar;
break;
case "team":
if ( !isDefined( level.teamTweaks[name] ) )
level.teamTweaks[name] = spawnStruct();
level.teamTweaks[name].value = value;
level.teamTweaks[name].lastValue = value;
level.teamTweaks[name].dVar = dvar;
break;
case "player":
if ( !isDefined( level.playerTweaks[name] ) )
level.playerTweaks[name] = spawnStruct();
level.playerTweaks[name].value = value;
level.playerTweaks[name].lastValue = value;
level.playerTweaks[name].dVar = dvar;
break;
case "class":
if ( !isDefined( level.classTweaks[name] ) )
level.classTweaks[name] = spawnStruct();
level.classTweaks[name].value = value;
level.classTweaks[name].lastValue = value;
level.classTweaks[name].dVar = dvar;
break;
case "weapon":
if ( !isDefined( level.weaponTweaks[name] ) )
level.weaponTweaks[name] = spawnStruct();
level.weaponTweaks[name].value = value;
level.weaponTweaks[name].lastValue = value;
level.weaponTweaks[name].dVar = dvar;
break;
case "hardpoint":
if ( !isDefined( level.hardpointTweaks[name] ) )
level.hardpointTweaks[name] = spawnStruct();
level.hardpointTweaks[name].value = value;
level.hardpointTweaks[name].lastValue = value;
level.hardpointTweaks[name].dVar = dvar;
break;
case "hud":
if ( !isDefined( level.hudTweaks[name] ) )
level.hudTweaks[name] = spawnStruct();
level.hudTweaks[name].value = value;
level.hudTweaks[name].lastValue = value;
level.hudTweaks[name].dVar = dvar;
break;
}
}
init()
{
level.clientTweakables = [];
level.tweakablesInitialized = true;
level.rules = [];
level.gameTweaks = [];
level.teamTweaks = [];
level.playerTweaks = [];
level.classTweaks = [];
level.weaponTweaks = [];
level.hardpointTweaks = [];
level.hudTweaks = [];
// commented out tweaks have not yet been implemented
if ( level.console )
{
registerTweakable( "game", "graceperiod", "scr_game_graceperiod", 15 ); //*
}
else
{
registerTweakable( "game", "playerwaittime", "scr_game_playerwaittime", 15 ); //*
registerTweakable( "game", "matchstarttime", "scr_game_matchstarttime", 5 ); //*
}
registerTweakable( "game", "onlyheadshots", "scr_game_onlyheadshots", 0 ); //*
registerTweakable( "game", "allowkillcam", "scr_game_allowkillcam", 1 ); //*
registerTweakable( "game", "spectatetype", "scr_game_spectatetype", 2 ); //*
registerTweakable( "game", "deathpointloss", "scr_game_deathpointloss", 0 ); //*
registerTweakable( "game", "suicidepointloss", "scr_game_suicidepointloss", 0 ); //*
registerTweakable( "team", "teamkillpointloss", "scr_team_teamkillpointloss", 0 ); //*
// registerTweakable( "team", "respawntime", "scr_team_respawntime", 0 );
registerTweakable( "team", "fftype", "scr_team_fftype", 0 );
registerTweakable( "team", "teamkillspawndelay", "scr_team_teamkillspawndelay", 0 );
// registerTweakable( "player", "respawndelay", "scr_player_respawndelay", 0 ); //*
registerTweakable( "player", "maxhealth", "scr_player_maxhealth", 100 ); //*
registerTweakable( "player", "healthregentime", "scr_player_healthregentime", 5 ); //*
registerTweakable( "player", "forcerespawn", "scr_player_forcerespawn", 1 ); //*
registerTweakable( "weapon", "allowfrag", "scr_weapon_allowfrags", 1 );
registerTweakable( "weapon", "allowsmoke", "scr_weapon_allowsmoke", 1 );
registerTweakable( "weapon", "allowflash", "scr_weapon_allowflash", 1 );
registerTweakable( "weapon", "allowc4", "scr_weapon_allowc4", 1 );
registerTweakable( "weapon", "allowclaymores", "scr_weapon_allowclaymores", 1 );
registerTweakable( "weapon", "allowrpgs", "scr_weapon_allowrpgs", 1 );
registerTweakable( "weapon", "allowmines", "scr_weapon_allowmines", 1 );
registerTweakable( "hardpoint", "allowartillery", "scr_hardpoint_allowartillery", 1 );
registerTweakable( "hardpoint", "allowuav", "scr_hardpoint_allowuav", 1 );
registerTweakable( "hardpoint", "allowsupply", "scr_hardpoint_allowsupply", 1 );
registerTweakable( "hardpoint", "allowhelicopter", "scr_hardpoint_allowhelicopter", 1 );
registerTweakable( "hud", "showobjicons", "ui_hud_showobjicons", 1 ); //*
makeDVarServerInfo( "ui_hud_showobjicons", 1 );
}
File diff suppressed because it is too large. Load diff
+532
View File
@@ -0,0 +1,532 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Arena
Objective: Eliminate the enemy team
Map ends: When one team eliminates the enemy team, or the flag is reached
Respawning: Beginning of next round
Level requirementss
------------------
Spawnpoints:
classname mp_tdm_spawn
All players spawn from these. The spawnpoint chosen is dependent on the current locations of teammates and enemies
at the time of spawn. Players generally spawn behind their teammates relative to the direction of enemies.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
*/
/*QUAKED mp_tdm_spawn (0.0 0.0 1.0) (-16 -16 0) (16 16 72)
Players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_tdm_spawn_axis_start (0.5 0.0 1.0) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_tdm_spawn_allies_start (0.0 0.5 1.0) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 500, 0, 5000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.teamBased = true;
level.objectiveBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onNormalDeath = ::onNormalDeath;
level.onPlayerKilled = ::onPlayerKilled;
level.onDeadEvent = ::onDeadEvent;
game["dialog"]["gametype"] = "arena";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
game["strings"]["overtime_hint"] = &"MP_FIRST_BLOOD";
}
onPrecacheGameType()
{
precacheShader( "compass_waypoint_captureneutral" );
precacheShader( "compass_waypoint_capture" );
precacheShader( "compass_waypoint_defend" );
precacheShader( "waypoint_captureneutral" );
precacheShader( "waypoint_capture" );
precacheShader( "waypoint_defend" );
}
onStartGameType()
{
setClientNameMode("auto_change");
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setObjectiveText( "allies", &"OBJECTIVES_ARENA" );
setObjectiveText( "axis", &"OBJECTIVES_ARENA" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_ARENA" );
setObjectiveScoreText( "axis", &"OBJECTIVES_ARENA" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_ARENA_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_ARENA_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_ARENA_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_ARENA_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = "dom";
allowed[1] = "airdrop_pallet";
allowed[2] = "arena";
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 200 );
maps\mp\gametypes\_gameobjects::main(allowed);
precacheFlag();
thread arenaFlagWaiter();
thread arenaTimeFlagWaiter();
}
precacheFlag()
{
game["flagmodels"] = [];
game["flagmodels"]["neutral"] = "prop_flag_neutral";
game["flagmodels"]["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
game["flagmodels"]["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
precacheModel( game["flagmodels"]["neutral"] );
precacheModel( game["flagmodels"]["allies"] );
precacheModel( game["flagmodels"]["axis"] );
precacheString( &"MP_CAPTURING_FLAG" );
precacheString( &"MP_LOSING_FLAG" );
precacheString( &"MP_DOM_YOUR_FLAG_WAS_CAPTURED" );
precacheString( &"MP_DOM_ENEMY_FLAG_CAPTURED" );
precacheString( &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
precacheString( &"MP_ENEMY_FLAG_CAPTURED_BY" );
precacheString( &"MP_NEUTRAL_FLAG_CAPTURED_BY" );
precacheString( &"MP_FRIENDLY_FLAG_CAPTURED_BY" );
}
arenaTimeFlagWaiter()
{
level endon( "down_to_one" );
level endon( "game_end" );
for( ;; )
{
timeLeft = maps\mp\gametypes\_gamelogic::getTimeRemaining();
if ( timeLeft < 61000 )
break;
wait ( 1 );
}
level notify( "arena_flag_time" );
thread arenaFlag();
}
arenaFlagWaiter()
{
level endon( "game_end" );
level endon( "arena_flag_time" );
for ( ;; )
{
if ( level.inGracePeriod == 0 )
break;
wait ( 0.05 );
}
for ( ;; )
{
if ( getTeamPlayersAlive ( "axis" ) == 1 )
{
thread arenaFlag();
level notify( "down_to_one" );
break;
}
if ( getTeamPlayersAlive ( "allies" ) == 1 )
{
thread arenaFlag();
level notify( "down_to_one" );
break;
}
wait( 1 );
}
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + spawnteam + "_start" );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onSpawnPlayer()
{
self.usingObj = undefined;
level notify ( "spawned_player" );
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
attacker maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( attacker.pers["team"], score );
team = victim.team;
if ( game["state"] == "postgame" )
attacker.finalKill = true;
}
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
{
thread checkAllowSpectating();
}
onTimeLimit()
{
if ( game["status"] == "overtime" )
{
winner = "forfeit";
}
else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
{
winner = "overtime";
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
winner = "axis";
}
else
{
winner = "allies";
}
thread maps\mp\gametypes\_gamelogic::endGame( winner, game["strings"]["time_limit_reached"] );
}
checkAllowSpectating()
{
wait ( 0.05 );
update = false;
if ( !level.aliveCount[ game["attackers"] ] )
{
level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
update = true;
}
if ( !level.aliveCount[ game["defenders"] ] )
{
level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
update = true;
}
if ( update )
maps\mp\gametypes\_spectating::updateSpectateSettings();
}
arenaFlag()
{
level.lastStatus["allies"] = 0;
level.lastStatus["axis"] = 0;
arenaFlag = getEntArray("flag_arena", "targetname");
primaryFlags = getEntArray( "flag_primary", "targetname" );
secondaryFlags = getEntArray( "flag_secondary", "targetname" );
// check to see if arena flag is present otherwise throw a warning and use the dom Flag.
if ( !isDefined( arenaFlag[0] ) )
{
println("WARNING: no arena flags specified attempting to use Dom flag_b" );
if ( (primaryFlags.size + secondaryFlags.size) < 1 )
{
printLn( "^1Not enough domination flags found in level!" );
maps\mp\gametypes\_callbacksetup::AbortLevel();
return;
}
self setupDomFlag(primaryFlags, secondaryFlags);
}
else
level.arenaFlag = arenaFlag[0];
trigger = level.arenaFlag;
if ( isDefined( trigger.target ) )
{
visuals[0] = getEnt( trigger.target, "targetname" );
}
else
{
visuals[0] = spawn( "script_model", trigger.origin );
visuals[0].angles = trigger.angles;
}
visuals[0] setModel( game["flagmodels"]["neutral"] );
arenaFlag = maps\mp\gametypes\_gameobjects::createUseObject( "neutral", trigger, visuals, (0,0,100) );
arenaFlag maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
arenaFlag maps\mp\gametypes\_gameobjects::setUseTime( 20.0 );
arenaFlag maps\mp\gametypes\_gameobjects::setUseText( &"MP_CAPTURING_FLAG" );
label = arenaFlag maps\mp\gametypes\_gameobjects::getLabel();
arenaFlag.label = label;
arenaFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
arenaFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend");
arenaFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral");
arenaFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral");
arenaFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
arenaFlag.onUse = ::onUse;
arenaFlag.onBeginUse = ::onBeginUse;
arenaFlag.onUseUpdate = ::onUseUpdate;
arenaFlag.onEndUse = ::onEndUse;
arenaFlag.isArena = true;
//play sound to show flag is now available for capture
iPrintLnBold( "Arena flag spawned" );
level.arenaFlag playSound( "flag_spawned" );
traceStart = visuals[0].origin + (0,0,32);
traceEnd = visuals[0].origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
upangles = vectorToAngles( trace["normal"] );
arenaFlag.baseeffectforward = anglesToForward( upangles );
arenaFlag.baseeffectright = anglesToRight( upangles );
arenaFlag.baseeffectpos = trace["position"];
arenaFlag.levelFlag = level.arenaFlag;
level.arenaFlag = arenaFlag;
}
setupDomFlag( primaryFlags, secondaryFlags )
{
for ( index = 0; index < primaryFlags.size; index++ )
{
label = primaryFlags[index].script_label;
if ( label != "_b" )
{
primaryFlags[index] delete();
}
else
{
level.arenaFlag = primaryFlags[index];
return;
}
}
}
onDeadEvent( team )
{
if ( team == game["attackers"] )
{
level thread arena_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
level thread arena_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
arena_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
giveFlagCaptureXP( touchList )
{
level endon ( "game_ended" );
wait .05;
WaitTillSlowProcessAllowed();
players = getArrayKeys( touchList );
for ( index = 0; index < players.size; index++ )
{
player = touchList[players[index]].player;
player thread [[level.onXPEvent]]( "capture" );
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
}
}
onUse( player )
{
team = player.pers["team"];
oldTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
label = self maps\mp\gametypes\_gameobjects::getLabel();
//player logString( "flag captured: " + self.label );
self.captureTime = getTime();
self maps\mp\gametypes\_gameobjects::setOwnerTeam( team );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_capture" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_capture" );
self.visuals[0] setModel( game["flagmodels"][team] );
assert( team != "neutral" );
if ( oldTeam == "neutral" )
{
otherTeam = getOtherTeam( team );
thread printAndSoundOnEveryone( team, otherTeam, &"MP_NEUTRAL_FLAG_CAPTURED_BY", &"MP_NEUTRAL_FLAG_CAPTURED_BY", "mp_war_objective_taken", undefined, player );
statusDialog( "captured_a", team );
statusDialog( "enemy_has_a", otherTeam );
}
else
thread printAndSoundOnEveryone( team, oldTeam, &"MP_ENEMY_FLAG_CAPTURED_BY", &"MP_FRIENDLY_FLAG_CAPTURED_BY", "mp_war_objective_taken", "mp_war_objective_lost", player );
thread giveFlagCaptureXP( self.touchList[team] );
player notify( "objective", "captured" );
thread flagCaptured( team, &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
}
onBeginUse( player )
{
ownerTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
self.didStatusNotify = false;
if ( ownerTeam == "neutral" )
{
otherTeam = getOtherTeam( player.pers["team"] );
statusDialog( "securing", player.pers["team"] );
self.objPoints[player.pers["team"]] thread maps\mp\gametypes\_objpoints::startFlashing();
statusDialog( "enemy_taking", otherTeam );
return;
}
if ( ownerTeam == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::startFlashing();
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::startFlashing();
}
onUseUpdate( team, progress, change )
{
if ( progress > 0.05 && change && !self.didStatusNotify )
{
otherTeam = getOtherTeam( team );
statusDialog( "losing_a", otherTeam );
statusDialog( "securing_a", team );
self.didStatusNotify = true;
}
}
onEndUse( team, player, success )
{
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::stopFlashing();
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::stopFlashing();
}
statusDialog( dialog, team )
{
time = getTime();
if ( getTime() < level.lastStatus[team] + 6000 )
return;
thread delayedLeaderDialog( dialog, team );
level.lastStatus[team] = getTime();
}
delayedLeaderDialog( sound, team )
{
level endon ( "game_ended" );
wait .1;
WaitTillSlowProcessAllowed();
leaderDialog( sound, team );
}
delayedLeaderDialogBothTeams( sound1, team1, sound2, team2 )
{
level endon ( "game_ended" );
wait .1;
WaitTillSlowProcessAllowed();
leaderDialogBothTeams( sound1, team1, sound2, team2 );
}
flagCaptured( winningTeam, endReasonText )
{
maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
+761
View File
@@ -0,0 +1,761 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
One Flag CTF
*/
/*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
registerScoreLimitDvar( level.gameType, 1, 0, 10000 );
registerRoundLimitDvar( level.gameType, 0, 0, 30 );
registerWinLimitDvar( level.gameType, 4, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 1, 0, 1 );
setOverTimeLimitDvar( 4 );
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onPlayerKilled = ::onPlayerKilled;
level.initGametypeAwards = ::initGametypeAwards;
level.onTimeLimit = ::onTimeLimit;
level.onSpawnPlayer = ::onSpawnPlayer;
level.flagReturnTime = getIntProperty( "scr_ctf_returntime", 30 );
game["dialog"]["gametype"] = "captureflag";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "capture_obj";
game["dialog"]["defense_obj"] = "capture_obj";
}
onPrecacheGameType()
{
precacheString(&"MP_FLAG_TAKEN_BY");
precacheString(&"MP_ENEMY_FLAG_TAKEN_BY");
precacheString(&"MP_FLAG_CAPTURED_BY");
precacheString(&"MP_ENEMY_FLAG_CAPTURED_BY");
precacheString(&"MP_FLAG_RETURNED");
precacheString(&"MP_ENEMY_FLAG_RETURNED");
precacheString(&"MP_YOUR_FLAG_RETURNING_IN");
precacheString(&"MP_ENEMY_FLAG_RETURNING_IN");
precacheString(&"MP_ENEMY_FLAG_DROPPED_BY");
precacheString(&"MP_DOM_NEUTRAL_FLAG_CAPTURED");
precacheString(&"MP_GRABBING_FLAG");
precacheString(&"MP_RETURNING_FLAG");
}
onSpawnPlayer()
{
if( ( inOvertime() ) && !isDefined( self.otSpawned ) )
self thread printOTHint();
}
printOTHint()
{
self endon ( "disconnect" );
// give the "Overtime!" message time to show
wait ( 0.25 );
self.otSpawned = true;
hintMessage = getObjectiveHintText( self.team );
self thread maps\mp\gametypes\_hud_message::hintMessage( hintMessage );
}
onStartGameType()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( !isdefined( game["original_defenders"] ) )
game["original_defenders"] = game["defenders"];
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setClientNameMode("auto_change");
if ( level.splitscreen )
{
if ( inOvertime() )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GRAB_FLAG" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GRAB_FLAG" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER" );
}
}
else
{
if ( inOvertime() )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GRAB_FLAG_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GRAB_FLAG_SCORE" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_SCORE" );
}
}
if ( inOvertime() )
{
setObjectiveText( game["attackers"], &"OBJECTIVES_OVERTIME_CTF" );
setObjectiveText( game["defenders"], &"OBJECTIVES_OVERTIME_CTF" );
setObjectiveHintText( game["attackers"], &"OBJECTIVES_GRAB_FLAG_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_GRAB_FLAG_HINT" );
}
else
{
setObjectiveText( game["attackers"], &"OBJECTIVES_CTF" );
setObjectiveText( game["defenders"], &"OBJECTIVES_CTF" );
setObjectiveHintText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_HINT" );
}
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_ctf_spawn_allies" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_ctf_spawn_axis" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
thread maps\mp\gametypes\_dev::init();
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "pickup", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "return", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 250 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill_carrier", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend_assist", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault", 200 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault_assist", 40 );
allowed[0] = "ctf";
maps\mp\gametypes\_gameobjects::main(allowed);
thread ctf();
}
getSpawnPoint()
{
if ( self.team == "axis" )
{
spawnTeam = game["attackers"];
}
else
{
spawnTeam = game["defenders"];
}
// if ( game["switchedsides"] )
// spawnTeam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = getentarray("mp_ctf_spawn_" + spawnteam + "_start", "classname");
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
ctf()
{
level.flagModel["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
level.icon2D["allies"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "allies" );
level.carryFlag["allies"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "allies" );
precacheModel( level.flagModel["allies"] );
precacheModel( level.carryFlag["allies"] );
level.flagModel["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
level.icon2D["axis"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "axis" );
level.carryFlag["axis"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "axis" );
precacheModel( level.flagModel["axis"] );
precacheModel( level.carryFlag["axis"] );
level.iconEscort3D = "waypoint_escort";
level.iconEscort2D = "waypoint_escort";
precacheShader( level.iconEscort3D );
precacheShader( level.iconEscort2D );
//level.iconEscort2D = level.iconEscort3D; // flags with words on compass
level.iconKill3D = "waypoint_kill";
level.iconKill2D = "waypoint_kill";
precacheShader( level.iconKill3D );
precacheShader( level.iconKill2D );
//level.iconKill2D = level.iconKill3D; // flags with words on compass
level.iconCaptureFlag3D = "waypoint_capture_flag";
level.iconCaptureFlag2D = "waypoint_capture_flag";
precacheShader( level.iconCaptureFlag3D );
precacheShader( level.iconCaptureFlag2D );
//level.iconCaptureFlag2D = level.iconCaptureFlag3D; // flags with words on compass
level.iconDefendFlag3D = "waypoint_defend_flag";
level.iconDefendFlag2D = "waypoint_defend_flag";
precacheShader( level.iconDefendFlag3D );
precacheShader( level.iconDefendFlag2D );
//level.iconDefendFlag2D = level.iconDefendFlag3D; // flags with words on compass
level.iconReturnFlag3D = "waypoint_return_flag";
level.iconReturnFlag2D = "waypoint_return_flag";
precacheShader( level.iconReturnFlag3D );
precacheShader( level.iconReturnFlag2D );
//level.iconReturnFlag2D = level.iconReturnFlag3D; // flags with words on compass
level.iconWaitForFlag3D = "waypoint_waitfor_flag";
level.iconWaitForFlag2D = "waypoint_waitfor_flag";
precacheShader( level.iconWaitForFlag3D );
precacheShader( level.iconWaitForFlag2D );
//level.iconWaitForFlag2D = level.iconWaitForFlag3D; // flags with words on compass
precacheShader( level.icon2D["axis"] );
precacheShader( level.icon2D["allies"] );
precacheShader( "waypoint_flag_friendly" );
precacheShader( "waypoint_flag_enemy" );
precacheString( &"OBJECTIVES_FLAG_HOME" );
precacheString( &"OBJECTIVES_FLAG_NAME" );
precacheString( &"OBJECTIVES_FLAG_AWAY" );
level.teamFlags[game["defenders"]] = createTeamFlag( game["defenders"], "allies" );
level.teamFlags[game["attackers"]] = createTeamFlag( game["attackers"], level.otherTeam["allies"] );
level.capZones[game["defenders"]] = createCapZone( game["defenders"], "allies" );
level.capZones[game["attackers"]] = createCapZone( game["attackers"], level.otherTeam["allies"] );
if ( level.splitScreen )
hudElemAlpha = 0;
else
hudElemAlpha = 0.85;
level.friendlyFlagStatusIcon["allies"] = createServerIcon( "waypoint_flag_friendly", 32, 32, "allies" );
level.friendlyFlagStatusIcon["allies"] setPoint( "TOP LEFT", "TOP LEFT", 132, 0 );
level.friendlyFlagStatusIcon["allies"].alpha = hudElemAlpha;
level.friendlyFlagStatusIcon["allies"].hideWhenInMenu = true;
level.friendlyFlagStatusText["allies"] = createServerFontString( "small", 1.6, "allies" );
level.friendlyFlagStatusText["allies"] setParent( level.friendlyFlagStatusIcon["allies"] );
level.friendlyFlagStatusText["allies"] setPoint( "LEFT", "RIGHT", 4 );
level.friendlyFlagStatusText["allies"] setText( &"OBJECTIVES_FLAG_HOME" );
level.friendlyFlagStatusText["allies"].alpha = hudElemAlpha;
level.friendlyFlagStatusText["allies"].color = (1,1,1);
level.friendlyFlagStatusText["allies"].glowAlpha = 1;
level.friendlyFlagStatusText["allies"].hideWhenInMenu = true;
level.enemyFlagStatusIcon["allies"] = createServerIcon( "waypoint_flag_enemy", 24, 24, "allies" );
level.enemyFlagStatusIcon["allies"] setPoint( "TOP LEFT", "TOP LEFT", 132, 26 );
level.enemyFlagStatusIcon["allies"].alpha = hudElemAlpha;
level.enemyFlagStatusIcon["allies"].hideWhenInMenu = true;
level.enemyFlagStatusText["allies"] = createServerFontString( "small", 1.6, "allies" );
level.enemyFlagStatusText["allies"] setParent( level.enemyFlagStatusIcon["allies"] );
level.enemyFlagStatusText["allies"] setPoint( "LEFT", "RIGHT", 4 );
level.enemyFlagStatusText["allies"] setText( &"OBJECTIVES_FLAG_HOME" );
level.enemyFlagStatusText["allies"].alpha = hudElemAlpha;
level.enemyFlagStatusText["allies"].color = (1,1,1);
level.enemyFlagStatusText["allies"].glowAlpha = 1;
level.enemyFlagStatusText["allies"].hideWhenInMenu = true;
level.friendlyFlagStatusIcon["axis"] = createServerIcon( "waypoint_flag_friendly", 32, 32, "axis" );
level.friendlyFlagStatusIcon["axis"] setPoint( "TOP LEFT", "TOP LEFT", 132, 0 );
level.friendlyFlagStatusIcon["axis"].alpha = hudElemAlpha;
level.friendlyFlagStatusIcon["axis"].hideWhenInMenu = true;
level.friendlyFlagStatusText["axis"] = createServerFontString( "small", 1.6, "axis" );
level.friendlyFlagStatusText["axis"] setParent( level.friendlyFlagStatusIcon["axis"] );
level.friendlyFlagStatusText["axis"] setPoint( "LEFT", "RIGHT", 4 );
level.friendlyFlagStatusText["axis"] setText( &"OBJECTIVES_FLAG_HOME" );
level.friendlyFlagStatusText["axis"].alpha = hudElemAlpha;
level.friendlyFlagStatusText["axis"].color = (1,1,1);
level.friendlyFlagStatusText["axis"].glowAlpha = 1;
level.friendlyFlagStatusText["axis"].hideWhenInMenu = true;
level.enemyFlagStatusIcon["axis"] = createServerIcon( "waypoint_flag_enemy", 24, 24, "axis" );
level.enemyFlagStatusIcon["axis"] setPoint( "TOP LEFT", "TOP LEFT", 132, 26 );
level.enemyFlagStatusIcon["axis"].alpha = hudElemAlpha;
level.enemyFlagStatusIcon["axis"].hideWhenInMenu = true;
level.enemyFlagStatusText["axis"] = createServerFontString( "small", 1.6, "axis" );
level.enemyFlagStatusText["axis"] setParent( level.enemyFlagStatusIcon["axis"] );
level.enemyFlagStatusText["axis"] setPoint( "LEFT", "RIGHT", 4 );
level.enemyFlagStatusText["axis"] setText( &"OBJECTIVES_FLAG_HOME" );
level.enemyFlagStatusText["axis"].alpha = hudElemAlpha;
level.enemyFlagStatusText["axis"].color = (1,1,1);
level.enemyFlagStatusText["axis"].glowAlpha = 1;
level.enemyFlagStatusText["axis"].hideWhenInMenu = true;
}
//sets overtime and associated variables
onTimeLimit()
{
if ( !inOvertime() && game["teamScores"]["allies"] == game["teamScores"]["axis"] && game["switchedsides"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "overtime", game["strings"]["time_limit_reached"] );
}
else if( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
}
else if( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
}
else if ( inOvertime() )
{
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game["strings"]["time_limit_reached"] );
}
}
spawnFxDelay( fxid, pos, forward, right, delay )
{
wait delay;
effect = spawnFx( fxid, pos, forward, right );
triggerFx( effect );
}
createTeamFlag( team, entityTeam )
{
trigger = getEnt( "ctf_zone_" + entityTeam, "targetname" );
if ( !isDefined( trigger ) )
{
error( "No ctf_zone_" + entityTeam + " trigger found in map." );
return;
}
visuals[0] = getEnt( "ctf_flag_" + entityTeam, "targetname" );
if ( !isDefined( visuals[0] ) )
{
error( "No ctf_flag_" + entityTeam + " script_model found in map." );
return;
}
cloneTrigger = spawn( "trigger_radius", trigger.origin, 0, 96, trigger.height );
trigger = cloneTrigger;
visuals[0] setModel( level.flagModel[team] );
teamFlag = maps\mp\gametypes\_gameobjects::createCarryObject( team, trigger, visuals, (0,0,85) );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "friendly", 0.5 );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "enemy", 0.5 );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "enemy", &"MP_GRABBING_FLAG" );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "friendly", &"MP_RETURNING_FLAG" );
teamFlag maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
teamFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill2D );
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconEscort2D );
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconEscort3D );
teamFlag maps\mp\gametypes\_gameobjects::setCarryIcon( level.icon2D[team] );
teamFlag.objIDPingFriendly = true;
teamFlag.allowWeapons = true;
teamFlag.onPickup = ::onPickup;
teamFlag.onPickupFailed = ::onPickup;
teamFlag.onDrop = ::onDrop;
teamFlag.onReset = ::onReset;
teamFlag.oldRadius = trigger.radius;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
return teamFlag;
}
createCapZone( team, entityTeam )
{
trigger = getEnt( "ctf_zone_" + entityTeam, "targetname" );
if ( !isDefined( trigger ) )
{
error("No ctf_zone_" + entityTeam + " trigger found in map.");
return;
}
visuals = [];
capZone = maps\mp\gametypes\_gameobjects::createUseObject( team, trigger, visuals, (0,0,85) );
capZone maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
capZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
capZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefendFlag2D );
capZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefendFlag3D );
capZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCaptureFlag2D );
capZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCaptureFlag3D );
capZone maps\mp\gametypes\_gameobjects::setUseTime( 0 );
capZone maps\mp\gametypes\_gameobjects::setKeyObject( level.teamFlags[ getOtherTeam( team ) ] );
capZone.onUse = ::onUse;
capZone.onCantUse = ::onCantUse;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
return capZone;
}
onBeginUse( player )
{
team = player.pers["team"];
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
self.trigger.radius = 1024;
else
self.trigger.radius = self.oldRadius;
}
onEndUse( player, team, success )
{
self.trigger.radius = self.oldRadius;
}
onPickup( player )
{
self notify ( "picked_up" );
team = player.pers["team"];
if ( team == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
{
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagreturn", maps\mp\gametypes\_rank::getScoreInfoValue( "return" ) );
player thread [[level.onXPEvent]]( "return" );
self thread returnFlag();
player incPlayerStat( "flagsreturned", 1 );
player thread maps\mp\_matchdata::logGameEvent( "return", player.origin );
printAndSoundOnEveryone( team, getOtherTeam( team ), &"MP_FLAG_RETURNED", &"MP_ENEMY_FLAG_RETURNED", "mp_obj_returned", "mp_obj_returned", "" );
leaderDialog( "enemy_flag_returned", otherteam, "status" );
leaderDialog( "flag_returned", team, "status" );
level.friendlyFlagStatusText[team] setText( &"OBJECTIVES_FLAG_HOME" );
level.friendlyFlagStatusText[team].glowColor = (1,1,1);
level.friendlyFlagStatusText[team].glowAlpha = 0;
level.enemyFlagStatusText[otherTeam] setText( &"OBJECTIVES_FLAG_HOME" );
level.enemyFlagStatusText[otherTeam].glowColor = (1,1,1);
level.enemyFlagStatusText[otherTeam].glowAlpha = 0;
}
else
{
if ( inOvertime() )
{
if ( isDefined( level.flagCaptured ) )
{
// denied splash!
return;
}
level thread teamPlayerCardSplash( "callout_grabbedtheflag", player );
level.teamFlags[team] maps\mp\gametypes\_gameobjects::allowUse( "none" );
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::allowUse( "none" );
level.capZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.flagCaptured = true;
//wait ( 1.5 );
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
thread maps\mp\gametypes\_gamelogic::endGame( "winner", game["strings"]["grabbed_flag"] );
}
player attachFlag();
level.friendlyFlagStatusText[otherTeam] setPlayerNameString( player );
level.friendlyFlagStatusText[otherTeam].glowColor = (0.75,0.25,0.25);
level.friendlyFlagStatusText[otherTeam].glowAlpha = 1;
level.enemyFlagStatusText[team] setPlayerNameString( player );
level.enemyFlagStatusText[team].glowColor = (0.25,0.75,0.25);
level.enemyFlagStatusText[team].glowAlpha = 1;
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconEscort2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconEscort3D );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::allowUse( "none" );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
//level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
//level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill3D );
if ( !level.teamFlags[ team ] maps\mp\gametypes\_gameobjects::isHome() )
{
level.capZones[ team ].trigger maps\mp\_entityheadIcons::setHeadIcon( player, level.iconWaitForFlag3D, (0,0,85) );
if ( isDefined( level.teamFlags[ team ].carrier ) )
level.capZones[ otherTeam ].trigger maps\mp\_entityheadIcons::setHeadIcon( level.teamFlags[ team ].carrier, level.iconWaitForFlag3D, (0,0,85) );
}
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_TAKEN_BY", &"MP_FLAG_TAKEN_BY", "mp_obj_taken", "mp_enemy_obj_taken", player );
leaderDialog( "enemy_flag_taken", team, "status" );
leaderDialog( "flag_taken", otherteam, "status" );
thread teamPlayerCardSplash( "callout_flagpickup", player );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagpickup", maps\mp\gametypes\_rank::getScoreInfoValue( "pickup" ) );
maps\mp\gametypes\_gamescore::givePlayerScore( "pickup", player );
player thread [[level.onXPEvent]]( "pickup" );
player incPlayerStat( "flagscarried", 1 );
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
}
}
returnFlag()
{
self maps\mp\gametypes\_gameobjects::returnHome();
}
onDrop( player )
{
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
otherTeam = level.otherTeam[team];
self maps\mp\gametypes\_gameobjects::allowCarry( "any" );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconReturnFlag2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconReturnFlag3D );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCaptureFlag2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCaptureFlag3D );
level.friendlyFlagStatusText[team] setText( &"OBJECTIVES_FLAG_AWAY" );
level.friendlyFlagStatusText[team].glowColor = (1,1,1);
level.friendlyFlagStatusText[team].glowAlpha = 0;
level.enemyFlagStatusText[otherTeam] setText( &"OBJECTIVES_FLAG_AWAY" );
level.enemyFlagStatusText[otherTeam].glowColor = (1,1,1);
level.enemyFlagStatusText[otherTeam].glowAlpha = 0;
level.capZones[otherTeam].trigger maps\mp\_entityheadIcons::setHeadIcon( "none", "", (0,0,0) );
if ( isDefined( player ) )
{
if ( isDefined( player.carryFlag ) )
player detachFlag();
printAndSoundOnEveryone( otherTeam, "none", &"MP_ENEMY_FLAG_DROPPED_BY", "", "mp_war_objective_lost", "", player );
}
else
{
playSoundOnPlayers( "mp_war_objective_lost", otherTeam );
}
leaderDialog( "enemy_flag_dropped", otherTeam, "status" );
leaderDialog( "flag_dropped", team, "status" );
self thread returnAfterTime();
}
returnAfterTime()
{
self endon ( "picked_up" );
wait ( level.flagReturnTime );
self maps\mp\gametypes\_gameobjects::returnHome();
}
onReset()
{
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
otherTeam = level.otherTeam[team];
self maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconKill2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconKill3D );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconEscort2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconEscort3D );
level.friendlyFlagStatusText[team] setText( &"OBJECTIVES_FLAG_HOME" );
level.friendlyFlagStatusText[team].glowColor = (1,1,1);
level.friendlyFlagStatusText[team].glowAlpha = 0;
level.enemyFlagStatusText[otherTeam] setText( &"OBJECTIVES_FLAG_HOME" );
level.enemyFlagStatusText[otherTeam].glowColor = (1,1,1);
level.enemyFlagStatusText[otherTeam].glowAlpha = 0;
level.capZones[team] maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
level.capZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
level.capZones[team] maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefendFlag2D );
level.capZones[team] maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefendFlag3D );
level.capZones[team] maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCaptureFlag2D );
level.capZones[team] maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCaptureFlag3D );
level.capZones[team].trigger maps\mp\_entityheadIcons::setHeadIcon( "none", "", (0,0,0) );
}
onUse( player )
{
team = player.pers["team"];
if ( team == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
leaderDialog( "enemy_flag_captured", team, "status" );
leaderDialog( "flag_captured", otherteam, "status" );
thread teamPlayerCardSplash( "callout_flagcapture", player );
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flag_capture", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) );
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
player thread [[level.onXPEvent]]( "capture" );
player incPlayerStat( "flagscaptured", 1 );
player notify( "objective", "captured" );
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_CAPTURED_BY", &"MP_FLAG_CAPTURED_BY", "mp_obj_captured", "mp_enemy_obj_captured", player );
if ( isDefined( player.carryFlag ) )
player detachFlag();
level.teamFlags[otherTeam] returnFlag();
}
onCantUse( player )
{
// player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId )
{
if ( isDefined( attacker ) && isPlayer( attacker ) && attacker.pers["team"] != self.pers["team"] )
{
if ( isDefined( attacker.carryFlag ) )
attacker incPlayerStat( "killsasflagcarrier", 1 );
if ( isDefined( self.carryFlag ) )
{
attacker thread [[level.onXPEvent]]( "kill_carrier" );
maps\mp\gametypes\_gamescore::givePlayerScore( "kill_carrier", attacker );
attacker incPlayerStat( "flagcarrierkills", 1 );
thread maps\mp\_matchdata::logKillEvent( killId, "carrying" );
self detachFlag();
}
}
}
attachFlag()
{
otherTeam = level.otherTeam[self.pers["team"]];
self attach( level.carryFlag[otherTeam], "J_spine4", true );
self.carryFlag = level.carryFlag[otherTeam];
}
detachFlag()
{
self detach( self.carryFlag, "J_spine4" );
self.carryFlag = undefined;
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "flagscaptured", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagsreturned", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasflagcarrier", 0, maps\mp\_awards::highestWins );
}
+870
View File
@@ -0,0 +1,870 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Action SAB/SD = DD
Attackers objective: Bomb both of 2 positions
Defenders objective: Defend these 2 positions / Defuse planted bombs
Round ends: When one team defends for duration of match, both sites are destroyed.
Map ends: When one team reaches the score limit, or time limit or round limit is reached
Respawning: Players respawn indefinetly and immediately
Level requirements
------------------
Allied Spawnpoints:
classname mp_sd_spawn_attacker
Allied players spawn from these. Place at least 16 of these relatively close together.
Axis Spawnpoints:
classname mp_sd_spawn_defender
Axis players spawn from these. Place at least 16 of these relatively close together.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
Bombzones:
classname trigger_multiple
targetname bombzone
script_gameobjectname bombzone
script_bombmode_original <if defined this bombzone will be used in the original bomb mode>
script_bombmode_single <if defined this bombzone will be used in the single bomb mode>
script_bombmode_dual <if defined this bombzone will be used in the dual bomb mode>
script_team Set to allies or axis. This is used to set which team a bombzone is used by in dual bomb mode.
script_label Set to A or B. This sets the letter shown on the compass in original mode.
This is a volume of space in which the bomb can planted. Must contain an origin brush.
Bomb:
classname trigger_lookat
targetname bombtrigger
script_gameobjectname bombzone
This should be a 16x16 unit trigger with an origin brush placed so that it's center lies on the bottom plane of the trigger.
Must be in the level somewhere. This is the trigger that is used when defusing a bomb.
It gets moved to the position of the planted bomb model.
Level script requirements
-------------------------
Team Definitions:
game["attackers"] = "allies";
game["defenders"] = "axis";
This sets which team is attacking and which team is defending. Attackers plant the bombs. Defenders protect the targets.
Exploder Effects:
Setting script_noteworthy on a bombzone trigger to an exploder group can be used to trigger additional effects.
multiple bombs
multiple targets
spawning
round handling when both sites are destroyed
*/
/*QUAKED mp_dd_spawn_attacker_a (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn near bomb a.*/
/*QUAKED mp_dd_spawn_attacker_b (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn near bomb b.*/
/*QUAKED mp_dd_spawn_attacker (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_dd_spawn_defender (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_dd_spawn_defender_a (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn near bomb site a.*/
/*QUAKED mp_dd_spawn_defender_b (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn near bomb site b.*/
/*QUAKED mp_dd_spawn_attacker_start (0.0 1.0 0.0) (-16 -16 0) (16 16 72)
Attacking players spawn randomly at one of these positions at the beginning of a round.*/
/*QUAKED mp_dd_spawn_defender_start (1.0 0.0 0.0) (-16 -16 0) (16 16 72)
Defending players spawn randomly at one of these positions at the beginning of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 1, 0, 9 );
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
registerScoreLimitDvar( level.gameType, 0, 0, 500 );
registerRoundLimitDvar( level.gameType, 3, 0, 12 );
registerWinLimitDvar( level.gameType, 2, 0, 12 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.objectiveBased = true;
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onDeadEvent = ::onDeadEvent;
level.onTimeLimit = ::onTimeLimit;
level.onNormalDeath = ::onNormalDeath;
level.initGametypeAwards = ::initGametypeAwards;
level.dd = true;
level.bombsPlanted = 0;
level.ddBombModel = []
setBombTimerDvar();
makeDvarServerInfo( "ui_bombtimer_a", -1 );
makeDvarServerInfo( "ui_bombtimer_b", -1 );
game["dialog"]["gametype"] = "demolition";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "obj_destroy";
game["dialog"]["defense_obj"] = "obj_defend";
}
onPrecacheGameType()
{
game["bomb_dropped_sound"] = "mp_war_objective_lost";
game["bomb_recovered_sound"] = "mp_war_objective_taken";
precacheShader("waypoint_bomb");
precacheShader("hud_suitcase_bomb");
precacheShader("waypoint_target");
precacheShader("waypoint_target_a");
precacheShader("waypoint_target_b");
precacheShader("waypoint_defend");
precacheShader("waypoint_defend_a");
precacheShader("waypoint_defend_b");
precacheShader("waypoint_defuse_a");
precacheShader("waypoint_defuse_b");
precacheShader("waypoint_target");
precacheShader("waypoint_target_a");
precacheShader("waypoint_target_b");
precacheShader("waypoint_defend");
precacheShader("waypoint_defend_a");
precacheShader("waypoint_defend_b");
precacheShader("waypoint_defuse");
precacheShader("waypoint_defuse_a");
precacheShader("waypoint_defuse_b");
precacheString( &"MP_EXPLOSIVES_RECOVERED_BY" );
precacheString( &"MP_EXPLOSIVES_DROPPED_BY" );
precacheString( &"MP_EXPLOSIVES_PLANTED_BY" );
precacheString( &"MP_EXPLOSIVES_DEFUSED_BY" );
precacheString( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
precacheString( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
precacheString( &"MP_CANT_PLANT_WITHOUT_BOMB" );
precacheString( &"MP_PLANTING_EXPLOSIVE" );
precacheString( &"MP_DEFUSING_EXPLOSIVE" );
precacheString( &"MP_BOMB_A_TIMER" );
precacheString( &"MP_BOMB_B_TIMER" );
precacheString( &"MP_BOMBSITE_IN_USE" );
}
onStartGameType()
{
if ( !isDefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
level.useStartSpawns = true;
setClientNameMode( "manual_change" );
game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
game["strings"]["bomb_defused"] = &"MP_BOMB_DEFUSED";
precacheString( game["strings"]["target_destroyed"] );
precacheString( game["strings"]["bomb_defused"] );
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
setObjectiveText( game["attackers"], &"OBJECTIVES_DD_ATTACKER" );
setObjectiveText( game["defenders"], &"OBJECTIVES_DD_DEFENDER" );
if ( level.splitscreen )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_DD_ATTACKER" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_DD_DEFENDER" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_DD_ATTACKER_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_DD_DEFENDER_SCORE" );
}
setObjectiveHintText( game["attackers"], &"OBJECTIVES_DD_ATTACKER_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_DD_DEFENDER_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender_a", true );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender_b", true );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dd_spawn_defender_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker_a", true );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker_b", true );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dd_spawn_attacker_start" );
level.spawn_defenders = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender" );
level.spawn_defenders_a = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_a" );
level.spawn_defenders_a = array_combine( level.spawn_defenders, level.spawn_defenders_a );
level.spawn_defenders_b = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_b" );
level.spawn_defenders_b = array_combine( level.spawn_defenders, level.spawn_defenders_b );
level.spawn_attackers = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker" );
level.spawn_attackers_a = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_a" );
level.spawn_attackers_a = array_combine( level.spawn_attackers, level.spawn_attackers_a );
level.spawn_attackers_b = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_b" );
level.spawn_attackers_b = array_combine( level.spawn_attackers, level.spawn_attackers_b );
level.spawn_defenders_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_start" );
level.spawn_attackers_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_start" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
level.aPlanted = false;
level.bPlanted = false;
setMapCenter( level.mapCenter );
maps\mp\gametypes\_rank::registerScoreInfo( "win", 2 );
maps\mp\gametypes\_rank::registerScoreInfo( "loss", 1 );
maps\mp\gametypes\_rank::registerScoreInfo( "tie", 1.5 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "plant", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 100 );
thread updateGametypeDvars();
thread waitToProcess();
winlimit = getWatchedDvar("winlimit");
allowed[0] = "dd";
allowed[1] = "bombzone";
allowed[2] = "blocker";
maps\mp\gametypes\_gameobjects::main(allowed);
thread bombs();
}
waitToProcess()
{
level endon( "game_end" );
for ( ;; )
{
if ( level.inGracePeriod == 0 )
break;
wait ( 0.05 );
}
level.useStartSpawns = false;
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( level.useStartSpawns )
{
if ( spawnteam == game["attackers"] )
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_attackers_start);
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_defenders_start);
}
else
{
if (spawnteam == game["attackers"] )
{
if ( (!level.aPlanted && !level.bPlanted) )
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
else if ( level.aPlanted && !level.bPlanted )
spawnPoints = level.spawn_attackers_a;
else if ( level.bPlanted && !level.aPlanted )
spawnPoints = level.spawn_attackers_b;
else
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
else
{
if ( (!level.aPlanted && !level.bPlanted) )
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
else if ( level.aPlanted && !level.bPlanted )
spawnPoints = level.spawn_defenders_a;
else if ( level.bPlanted && !level.aPlanted )
spawnPoints = level.spawn_defenders_b;
else
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
}
assert( isDefined(spawnpoint) );
return spawnpoint;
}
onSpawnPlayer()
{
if ( self.pers["team"] == game["attackers"] )
{
self.isPlanting = false;
self.isDefusing = false;
self.isBombCarrier = true;
if ( level.splitscreen )
{
self.carryIcon = createIcon( "hud_suitcase_bomb", 33, 33 );
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", 0, -78 );
self.carryIcon.alpha = 0.75;
}
else
{
self.carryIcon = createIcon( "hud_suitcase_bomb", 50, 50 );
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -90, -65 );
self.carryIcon.alpha = 0.75;
}
}
else
{
self.isPlanting = false;
self.isDefusing = false;
self.isBombCarrier = false;
if ( isDefined( self.carryIcon ) )
{
self.carryIcon Destroy();
}
}
level notify ( "spawned_player" );
}
dd_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
onDeadEvent( team )
{
if ( level.bombExploded || level.bombDefused )
return;
if ( team == "all" )
{
if ( level.bombPlanted )
dd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
else
dd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["attackers"] )
{
if ( level.bombPlanted )
return;
level thread dd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
level thread dd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
team = victim.team;
if ( game["state"] == "postgame" && (victim.team == game["defenders"] || !level.bombPlanted) )
attacker.finalKill = true;
if ( victim.isPlanting )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
}
else if ( victim.isDefusing )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
}
}
onTimeLimit()
{
dd_endGame( game["defenders"], game["strings"]["time_limit_reached"] );
}
updateGametypeDvars()
{
level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
level.bombTimer = dvarIntValue( "bombtimer", 45, 1, 300 );
level.ddTimeToAdd = dvarFloatValue( "addtime", 2, 0, 5 );; //how much time is added to the match when a target is destroyed
}
bombs()
{
level.bombPlanted = false;
level.bombDefused = false;
level.bombExploded = 0;
level.bombZones = [];
bombZones = getEntArray( "bombzone", "targetname" );
for ( index = 0; index < bombZones.size; index++ )
{
trigger = bombZones[index];
visuals = getEntArray( bombZones[index].target, "targetname" );
bombZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,64) );
bombZone maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
bombZone maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
bombZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
bombZone maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
bombZone maps\mp\gametypes\_gameobjects::setKeyObject( level.ddBomb );
label = bombZone maps\mp\gametypes\_gameobjects::getLabel();
bombZone.label = label;
bombZone.index = index;
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + label );
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + label );
bombZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
bombZone.onBeginUse = ::onBeginUse;
bombZone.onEndUse = ::onEndUse;
bombZone.onUse = ::onUseObject;
bombZone.onCantUse = ::onCantUse;
bombZone.useWeapon = "briefcase_bomb_mp";
bombZone.visuals[0].killCamEnt = spawn( "script_model", bombZone.visuals[0].origin + (0,0,128) );
for ( i = 0; i < visuals.size; i++ )
{
if ( isDefined( visuals[i].script_exploder ) )
{
bombZone.exploderIndex = visuals[i].script_exploder;
break;
}
}
level.bombZones[level.bombZones.size] = bombZone;
bombZone.bombDefuseTrig = getent( visuals[0].target, "targetname" );
assert( isdefined( bombZone.bombDefuseTrig ) );
bombZone.bombDefuseTrig.origin += (0,0,-10000);
bombZone.bombDefuseTrig.label = label;
}
for ( index = 0; index < level.bombZones.size; index++ )
{
array = [];
for ( otherindex = 0; otherindex < level.bombZones.size; otherindex++ )
{
if ( otherindex != index )
array[ array.size ] = level.bombZones[otherindex];
}
level.bombZones[index].otherBombZones = array;
}
}
onUseObject( player )
{
team = player.pers["team"];
otherTeam = level.otherTeam[team];
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
player notify ( "bomb_planted" );
player playSound( "mp_bomb_plant" );
thread teamPlayerCardSplash( "callout_bombplanted", player );
//iPrintLn( &"MP_EXPLOSIVES_PLANTED_BY", player );
leaderDialog( "bomb_planted" );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
player incPlayerStat( "bombsplanted", 1 );
player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
player.bombPlantedTime = getTime();
level thread bombPlanted( self, player );
level.bombOwner = player;
self.useWeapon = "briefcase_bomb_defuse_mp";
self setUpForDefusing();
}
else // defused the bomb
{
self thread bombHandler( player, "defused" );
}
}
resetBombZone()
{
self maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
self maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
self maps\mp\gametypes\_gameobjects::setKeyObject( level.ddBomb );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + self.label );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self.useWeapon = "briefcase_bomb_mp";
}
setUpForDefusing()
{
self maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
self maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
self maps\mp\gametypes\_gameobjects::setKeyObject( undefined );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" + self.label );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
}
onBeginUse( player )
{
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
player playSound( "mp_bomb_defuse" );
player.isDefusing = true;
bestDistance = 9000000;
closestBomb = undefined;
if ( isDefined( level.ddBombModel ) )
{
foreach ( bomb in level.ddBombModel )
{
if ( !isDefined( bomb ) )
continue;
dist = distanceSquared( player.origin, bomb.origin );
if ( dist < bestDistance )
{
bestDistance = dist;
closestBomb = bomb;
}
}
assert( isDefined(closestBomb) );
player.defusing = closestBomb;
closestBomb hide();
}
}
else
{
player.isPlanting = true;
}
}
onEndUse( team, player, result )
{
if ( !isDefined( player ) )
return;
if ( isAlive( player ) )
{
player.isDefusing = false;
player.isPlanting = false;
}
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
if ( isDefined( player.defusing ) && !result )
{
player.defusing show();
}
}
}
onCantUse( player )
{
player iPrintLnBold( &"MP_BOMBSITE_IN_USE" );
}
onReset()
{
}
bombPlanted( destroyedObj, player )
{
destroyedObj endon( "defused" );
level.bombsPlanted += 1;
self setBombTimerDvar();
maps\mp\gametypes\_gamelogic::pauseTimer();
level.timePauseStart = getTime();
level.timeLimitOverride = true;
level.bombPlanted = true;
level.destroyedObject = destroyedObj;
if ( level.destroyedObject.label == "_a" )
level.aPlanted = true;
else
level.bPlanted = true;
level.destroyedObject.bombPlanted = true;
destroyedObj.visuals[0] thread playDemolitionTickingSound(destroyedObj);
level.tickingObject = destroyedObj.visuals[0];
self dropBombModel( player, destroyedObj.label );
destroyedObj.bombDefused = false;
destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" );
destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
destroyedObj setUpForDefusing();
destroyedObj BombTimerWait(destroyedObj); //waits for bomb to explode!
destroyedObj thread bombHandler( player ,"explode" );
}
bombHandler( player, destType )
{
self.visuals[0] notify( "stopTicking" );
level.bombsPlanted -= 1;
if ( self.label == "_a" )
level.aPlanted = false;
else
level.bPlanted = false;
self.bombPlanted = 0;
self restartTimer();
self setBombTimerDvar();
setDvar( "ui_bombtimer" + self.label, -1 );
//self maps\mp\gametypes\_gameobjects::updateTimer( 0, false );
if ( level.gameEnded )
return;
if ( destType == "explode" )
{
level.bombExploded += 1;
explosionOrigin = self.curorigin;
level.ddBombModel[ self.label ] Delete();
if ( isdefined( player ) )
{
self.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player );
player incPlayerStat( "targetsdestroyed", 1 );
}
else
{
self.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
}
rot = randomfloat(360);
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
triggerFx( explosionEffect );
PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
earthquake( 0.75, 2.0, explosionOrigin, 2000 );
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
if ( isDefined( self.exploderIndex ) )
exploder( self.exploderIndex );
self maps\mp\gametypes\_gameobjects::disableObject();
if ( level.bombExploded < 2 )
{
foreach ( splashPlayer in level.players )
splashPlayer thread maps\mp\gametypes\_hud_message::SplashNotify( "time_added" );
}
wait 2;
if ( level.bombExploded > 1 )
dd_endGame( game["attackers"], game["strings"]["target_destroyed"] );
else
level thread teamPlayerCardSplash( "callout_time_added", player );
}
else //defused
{
player notify ( "bomb_defused" );
self notify( "defused" );
// if ( !level.hardcoreMode )
// iPrintLn( &"MP_EXPLOSIVES_DEFUSED_BY", player );
leaderDialog( "bomb_defused" );
level thread teamPlayerCardSplash( "callout_bombdefused", player );
level thread bombDefused( self );
self resetBombzone();
if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 4000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
else
player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
player incPlayerStat( "bombsdefused", 1 );
player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origIn );
}
}
playDemolitionTickingSound( site )
{
self endon("death");
self endon("stopTicking");
level endon("game_ended");
while(1)
{
self playSound( "ui_mp_suitcasebomb_timer" );
if ( !isDefined( site.waitTime ) || site.waitTime > 10 )
wait 1.0;
else if ( isDefined( site.waitTime ) && site.waitTime > 5 )
wait 0.5;
else
wait 0.25;
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
}
}
setBombTimerDvar()
{
println( "BOMBS PLANTED: " + level.bombsPlanted );
if ( level.bombsPlanted == 1 )
setDvar( "ui_bomb_timer", 2 );
else if ( level.bombsPlanted == 2 )
setDvar( "ui_bomb_timer", 3 );
else
setDvar( "ui_bomb_timer", 0 );
}
dropBombModel( player, site )
{
trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000), false, player );
tempAngle = randomfloat( 360 );
forward = (cos( tempAngle ), sin( tempAngle ), 0);
forward = vectornormalize( forward - common_scripts\utility::vector_multiply( trace["normal"], vectordot( forward, trace["normal"] ) ) );
dropAngles = vectortoangles( forward );
level.ddBombModel[ site ] = spawn( "script_model", trace["position"] );
level.ddBombModel[ site ].angles = dropAngles;
level.ddBombModel[ site ] setModel( "prop_suitcase_bomb" );
}
restartTimer()
{
if ( level.bombsPlanted <= 0 )
{
maps\mp\gametypes\_gamelogic::resumeTimer();
level.timePaused = ( getTime() - level.timePauseStart ) ;
level.timeLimitOverride = false;
}
}
BombTimerWait(siteLoc)
{
level endon("game_ended");
level endon("bomb_defused" + siteLoc.label );
siteLoc.waitTime = level.bombTimer;
while ( siteLoc.waitTime >= 0 )
{
siteLoc.waitTime--;
setDvar( "ui_bombtimer" + siteLoc.label, siteLoc.waitTime );
//self maps\mp\gametypes\_gameobjects::updateTimer( waitTime, true );
if ( siteLoc.waitTime >= 0 )
wait( 1 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
}
}
bombDefused( siteDefused )
{
level.tickingObject maps\mp\gametypes\_gamelogic::stopTickingSound();
siteDefused.bombDefused = true;
self setBombTimerDvar();
setDvar( "ui_bombtimer" + siteDefused.label, -1 );
level notify("bomb_defused" + siteDefused.label);
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
}
+100
View File
@@ -0,0 +1,100 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Deathmatch
Objective: Score points by eliminating other players
Map ends: When one player reaches the score limit, or time limit is reached
Respawning: No wait / Away from other players
Level requirements
------------------
Spawnpoints:
classname mp_dm_spawn
All players spawn from these. The spawnpoint chosen is dependent on the current locations of enemies at the time of spawn.
Players generally spawn away from enemies.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
*/
/*QUAKED mp_dm_spawn (1.0 0.5 0.0) (-16 -16 0) (16 16 72)
Players spawn away from enemies at one of these positions.*/
main()
{
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 1000, 0, 5000 );
registerWinLimitDvar( level.gameType, 1, 0, 5000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
game["dialog"]["gametype"] = "freeforall";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
}
onStartGameType()
{
setClientNameMode("auto_change");
setObjectiveText( "allies", &"OBJECTIVES_DM" );
setObjectiveText( "axis", &"OBJECTIVES_DM" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_DM" );
setObjectiveScoreText( "axis", &"OBJECTIVES_DM" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_DM_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_DM_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_DM_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_DM_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_dm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_dm_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = "dm";
maps\mp\gametypes\_gameobjects::main(allowed);
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 10 );
maps\mp\gametypes\_rank::registerScoreInfo( "suicide", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "teamkill", 0 );
level.QuickMessageToAll = true;
}
getSpawnPoint()
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( self.pers["team"] );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_DM( spawnPoints );
return spawnPoint;
}
+968
View File
@@ -0,0 +1,968 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Domination
Objective: Capture all the flags by touching them
Map ends: When one team captures all the flags, or time limit is reached
Respawning: No wait / Near teammates
Level requirements
------------------
Spawnpoints:
classname mp_tdm_spawn
All players spawn from these. The spawnpoint chosen is dependent on the current locations of owned flags, teammates and
enemies at the time of spawn. Players generally spawn behind their teammates relative to the direction of enemies.
Optionally, give a spawnpoint a script_linkto to specify which flag it "belongs" to (see Flag Descriptors).
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
Flags:
classname trigger_radius
targetname flag_primary or flag_secondary
Flags that need to be captured to win. Primary flags take time to capture; secondary flags are instant.
Flag Descriptors:
classname script_origin
targetname flag_descriptor
Place one flag descriptor close to each flag. Use the script_linkname and script_linkto properties to say which flags
it can be considered "adjacent" to in the level. For instance, if players have a primary path from flag1 to flag2, and
from flag2 to flag3, flag2 would have a flag_descriptor with these properties:
script_linkname flag2
script_linkto flag1 flag3
Set scr_domdebug to 1 to see flag connections and what spawnpoints are considered connected to each flag.
*/
/*QUAKED mp_dom_spawn (0.5 0.5 1.0) (-16 -16 0) (16 16 72)
Players spawn near their flags at one of these positions.*/
/*QUAKED mp_dom_spawn_axis_start (1.0 0.0 1.0) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_dom_spawn_allies_start (0.0 1.0 1.0) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 30, 0, 1440 );
registerScoreLimitDvar( level.gameType, 300, 0, 1000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.teamBased = true;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onPlayerKilled = ::onPlayerKilled;
level.onPrecacheGameType = ::onPrecacheGameType;
level.initGametypeAwards = ::initGametypeAwards;
level.onSpawnPlayer = ::onSpawnPlayer;
game["dialog"]["gametype"] = "domination";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "capture_objs";
game["dialog"]["defense_obj"] = "capture_objs";
}
onPrecacheGameType()
{
precacheShader( "waypoint_captureneutral" );
precacheShader( "waypoint_capture" );
precacheShader( "waypoint_defend" );
precacheShader( "waypoint_captureneutral_a" );
precacheShader( "waypoint_capture_a" );
precacheShader( "waypoint_defend_a" );
precacheShader( "waypoint_captureneutral_b" );
precacheShader( "waypoint_capture_b" );
precacheShader( "waypoint_defend_b" );
precacheShader( "waypoint_captureneutral_c" );
precacheShader( "waypoint_capture_c" );
precacheShader( "waypoint_defend_c" );
precacheShader( "waypoint_captureneutral" );
precacheShader( "waypoint_capture" );
precacheShader( "waypoint_defend" );
precacheShader( "waypoint_captureneutral_a" );
precacheShader( "waypoint_capture_a" );
precacheShader( "waypoint_defend_a" );
precacheShader( "waypoint_captureneutral_b" );
precacheShader( "waypoint_capture_b" );
precacheShader( "waypoint_defend_b" );
precacheShader( "waypoint_captureneutral_c" );
precacheShader( "waypoint_capture_c" );
precacheShader( "waypoint_defend_c" );
}
onStartGameType()
{
setObjectiveText( "allies", &"OBJECTIVES_DOM" );
setObjectiveText( "axis", &"OBJECTIVES_DOM" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_DOM" );
setObjectiveScoreText( "axis", &"OBJECTIVES_DOM" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_DOM_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_DOM_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_DOM_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_DOM_HINT" );
setClientNameMode("auto_change");
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dom_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dom_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_dom_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_dom_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
level.spawn_all = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn" );
level.spawn_axis_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn_axis_start" );
level.spawn_allies_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn_allies_start" );
level.startPos["allies"] = level.spawn_allies_start[0].origin;
level.startPos["axis"] = level.spawn_axis_start[0].origin;
level.flagBaseFXid[ "allies" ] = loadfx( maps\mp\gametypes\_teams::getTeamFlagFX( "allies" ) );
level.flagBaseFXid[ "axis" ] = loadfx( maps\mp\gametypes\_teams::getTeamFlagFX( "axis" ) );
allowed[0] = "dom";
// allowed[1] = "hardpoint";
maps\mp\gametypes\_gameobjects::main(allowed);
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 10 );
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 150 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend_assist", 10 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault_assist", 10 );
thread domFlags();
thread updateDomScores();
}
getSpawnPoint()
{
spawnpoint = undefined;
if ( !level.useStartSpawns )
{
flagsOwned = 0;
enemyFlagsOwned = 0;
myTeam = self.pers["team"];
enemyTeam = getOtherTeam( myTeam );
for ( i = 0; i < level.flags.size; i++ )
{
team = level.flags[i] getFlagTeam();
if ( team == myTeam )
flagsOwned++;
else if ( team == enemyTeam )
enemyFlagsOwned++;
}
if ( flagsOwned == level.flags.size )
{
// own all flags! pretend we don't own the last one we got, so enemies can spawn there
enemyBestSpawnFlag = level.bestSpawnFlag[ getOtherTeam( self.pers["team"] ) ];
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all, getSpawnsBoundingFlag( enemyBestSpawnFlag ) );
}
else if ( flagsOwned > 0 )
{
// spawn near any flag we own that's nearish something we can capture
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all, getBoundaryFlagSpawns( myTeam ) );
}
else
{
// own no flags!
bestFlag = undefined;
if ( enemyFlagsOwned > 0 && enemyFlagsOwned < level.flags.size )
{
// there should be an unowned one to use
bestFlag = getUnownedFlagNearestStart( myTeam );
}
if ( !isdefined( bestFlag ) )
{
// pretend we still own the last one we lost
bestFlag = level.bestSpawnFlag[ self.pers["team"] ];
}
level.bestSpawnFlag[ self.pers["team"] ] = bestFlag;
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all, bestFlag.nearbyspawns );
}
}
if ( !isdefined( spawnpoint ) )
{
if (self.pers["team"] == "axis")
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_axis_start);
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_allies_start);
}
//spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_all );
assert( isDefined(spawnpoint) );
return spawnpoint;
}
domFlags()
{
level.lastStatus["allies"] = 0;
level.lastStatus["axis"] = 0;
game["flagmodels"] = [];
game["flagmodels"]["neutral"] = "prop_flag_neutral";
game["flagmodels"]["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
game["flagmodels"]["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
precacheModel( game["flagmodels"]["neutral"] );
precacheModel( game["flagmodels"]["allies"] );
precacheModel( game["flagmodels"]["axis"] );
precacheString( &"MP_SECURING_POSITION" );
primaryFlags = getEntArray( "flag_primary", "targetname" );
secondaryFlags = getEntArray( "flag_secondary", "targetname" );
if ( (primaryFlags.size + secondaryFlags.size) < 2 )
{
printLn( "^1Not enough domination flags found in level!" );
maps\mp\gametypes\_callbacksetup::AbortLevel();
return;
}
level.flags = [];
for ( index = 0; index < primaryFlags.size; index++ )
level.flags[level.flags.size] = primaryFlags[index];
for ( index = 0; index < secondaryFlags.size; index++ )
level.flags[level.flags.size] = secondaryFlags[index];
level.domFlags = [];
for ( index = 0; index < level.flags.size; index++ )
{
trigger = level.flags[index];
if ( isDefined( trigger.target ) )
{
visuals[0] = getEnt( trigger.target, "targetname" );
}
else
{
visuals[0] = spawn( "script_model", trigger.origin );
visuals[0].angles = trigger.angles;
}
visuals[0] setModel( game["flagmodels"]["neutral"] );
domFlag = maps\mp\gametypes\_gameobjects::createUseObject( "neutral", trigger, visuals, (0,0,100) );
domFlag maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
domFlag maps\mp\gametypes\_gameobjects::setUseTime( 10.0 );
domFlag maps\mp\gametypes\_gameobjects::setUseText( &"MP_SECURING_POSITION" );
label = domFlag maps\mp\gametypes\_gameobjects::getLabel();
domFlag.label = label;
domFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
domFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
domFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_captureneutral" + label );
domFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" + label );
domFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
domFlag.onUse = ::onUse;
domFlag.onBeginUse = ::onBeginUse;
domFlag.onUseUpdate = ::onUseUpdate;
domFlag.onEndUse = ::onEndUse;
traceStart = visuals[0].origin + (0,0,32);
traceEnd = visuals[0].origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
upangles = vectorToAngles( trace["normal"] );
domFlag.baseeffectforward = anglesToForward( upangles );
domFlag.baseeffectright = anglesToRight( upangles );
domFlag.baseeffectpos = trace["position"];
// legacy spawn code support
level.flags[index].useObj = domFlag;
level.flags[index].adjflags = [];
level.flags[index].nearbyspawns = [];
domFlag.levelFlag = level.flags[index];
level.domFlags[level.domFlags.size] = domFlag;
}
// level.bestSpawnFlag is used as a last resort when the enemy holds all flags.
level.bestSpawnFlag = [];
level.bestSpawnFlag[ "allies" ] = getUnownedFlagNearestStart( "allies", undefined );
level.bestSpawnFlag[ "axis" ] = getUnownedFlagNearestStart( "axis", level.bestSpawnFlag[ "allies" ] );
flagSetup();
/#
thread domDebug();
#/
}
getUnownedFlagNearestStart( team, excludeFlag )
{
best = undefined;
bestdistsq = undefined;
for ( i = 0; i < level.flags.size; i++ )
{
flag = level.flags[i];
if ( flag getFlagTeam() != "neutral" )
continue;
distsq = distanceSquared( flag.origin, level.startPos[team] );
if ( (!isDefined( excludeFlag ) || flag != excludeFlag) && (!isdefined( best ) || distsq < bestdistsq) )
{
bestdistsq = distsq;
best = flag;
}
}
return best;
}
/#
domDebug()
{
while(1)
{
if (getdvar("scr_domdebug") != "1") {
wait 2;
continue;
}
while(1)
{
if (getdvar("scr_domdebug") != "1")
break;
// show flag connections and each flag's spawnpoints
for (i = 0; i < level.flags.size; i++) {
for (j = 0; j < level.flags[i].adjflags.size; j++) {
line(level.flags[i].origin, level.flags[i].adjflags[j].origin, (1,1,1));
}
for (j = 0; j < level.flags[i].nearbyspawns.size; j++) {
line(level.flags[i].origin, level.flags[i].nearbyspawns[j].origin, (.2,.2,.6));
}
if ( level.flags[i] == level.bestSpawnFlag["allies"] )
print3d( level.flags[i].origin, "allies best spawn flag" );
if ( level.flags[i] == level.bestSpawnFlag["axis"] )
print3d( level.flags[i].origin, "axis best spawn flag" );
}
wait .05;
}
}
}
#/
onBeginUse( player )
{
ownerTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
self.didStatusNotify = false;
if ( ownerTeam == "neutral" )
{
statusDialog( "securing"+self.label, player.pers["team"] );
self.objPoints[player.pers["team"]] thread maps\mp\gametypes\_objpoints::startFlashing();
return;
}
if ( ownerTeam == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::startFlashing();
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::startFlashing();
}
onUseUpdate( team, progress, change )
{
if ( progress > 0.05 && change && !self.didStatusNotify )
{
ownerTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
if ( ownerTeam == "neutral" )
{
statusDialog( "securing"+self.label, team );
}
else
{
statusDialog( "losing"+self.label, ownerTeam );
statusDialog( "securing"+self.label, team );
}
self.didStatusNotify = true;
}
}
statusDialog( dialog, team, forceDialog )
{
time = getTime();
if ( getTime() < level.lastStatus[team] + 5000 && (!isDefined( forceDialog ) || !forceDialog) )
return;
thread delayedLeaderDialog( dialog, team );
level.lastStatus[team] = getTime();
}
onEndUse( team, player, success )
{
self.objPoints["allies"] thread maps\mp\gametypes\_objpoints::stopFlashing();
self.objPoints["axis"] thread maps\mp\gametypes\_objpoints::stopFlashing();
}
resetFlagBaseEffect()
{
if ( isdefined( self.baseeffect ) )
self.baseeffect delete();
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
if ( team != "axis" && team != "allies" )
return;
fxid = level.flagBaseFXid[ team ];
self.baseeffect = spawnFx( fxid, self.baseeffectpos, self.baseeffectforward, self.baseeffectright );
triggerFx( self.baseeffect );
}
onUse( player )
{
team = player.pers["team"];
oldTeam = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
label = self maps\mp\gametypes\_gameobjects::getLabel();
//player logString( "flag captured: " + self.label );
self.captureTime = getTime();
self maps\mp\gametypes\_gameobjects::setOwnerTeam( team );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_capture" + label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_capture" + label );
self.visuals[0] setModel( game["flagmodels"][team] );
self resetFlagBaseEffect();
level.useStartSpawns = false;
assert( team != "neutral" );
if ( oldTeam == "neutral" )
{
otherTeam = getOtherTeam( team );
thread printAndSoundOnEveryone( team, otherTeam, undefined, undefined, "mp_war_objective_taken", undefined, player );
statusDialog( "secured"+self.label, team, true );
statusDialog( "enemy_has"+self.label, otherTeam, true );
}
else
{
thread printAndSoundOnEveryone( team, oldTeam, undefined, undefined, "mp_war_objective_taken", "mp_war_objective_lost", player );
// thread delayedLeaderDialogBothTeams( "obj_lost", oldTeam, "obj_taken", team );
if ( getTeamFlagCount( team ) == level.flags.size )
{
statusDialog( "secure_all", team );
statusDialog( "lost_all", oldTeam );
}
else
{
statusDialog( "secured"+self.label, team, true );
statusDialog( "lost"+self.label, oldTeam, true );
}
level.bestSpawnFlag[ oldTeam ] = self.levelFlag;
}
player notify( "objective", "captured" );
self thread giveFlagCaptureXP( self.touchList[team] );
}
giveFlagCaptureXP( touchList )
{
level endon ( "game_ended" );
players = getArrayKeys( touchList );
for ( index = 0; index < players.size; index++ )
{
player = touchList[players[index]].player;
player thread maps\mp\gametypes\_hud_message::SplashNotify( "capture", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) );
player thread updateCPM();
player thread maps\mp\gametypes\_rank::giveRankXP( "capture", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) * player getCapXPScale() );
printLn( maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) * player getCapXPScale() );
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
player incPlayerStat( "pointscaptured", 1 );
}
player = self maps\mp\gametypes\_gameobjects::getEarliestClaimPlayer();
level thread teamPlayerCardSplash( "callout_securedposition" + self.label, player );
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
}
delayedLeaderDialog( sound, team )
{
level endon ( "game_ended" );
wait .1;
WaitTillSlowProcessAllowed();
leaderDialog( sound, team );
}
delayedLeaderDialogBothTeams( sound1, team1, sound2, team2 )
{
level endon ( "game_ended" );
wait .1;
WaitTillSlowProcessAllowed();
leaderDialogBothTeams( sound1, team1, sound2, team2 );
}
updateDomScores()
{
level endon ( "game_ended" );
while ( !level.gameEnded )
{
domFlags = getOwnedDomFlags();
if ( domFlags.size )
{
for ( i = 1; i < domFlags.size; i++ )
{
domFlag = domFlags[i];
flagScore = getTime() - domFlag.captureTime;
for ( j = i - 1; j >= 0 && flagScore > (getTime() - domFlags[j].captureTime); j-- )
domFlags[j + 1] = domFlags[j];
domFlags[j + 1] = domFlag;
}
foreach( domFlag in domFlags )
{
team = domFlag maps\mp\gametypes\_gameobjects::getOwnerTeam();
assert( team == "allies" || team == "axis" );
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
}
}
// end the game if people aren't playing
if ( (((getTimePassed() / 1000) > 120 && domFlags.size < 2) || ((getTimePassed() / 1000) > 300 && domFlags.size < 3)) && matchMakingGame() )
{
thread maps\mp\gametypes\_gamelogic::endGame( "none", game["strings"]["time_limit_reached"] );
return;
}
wait ( 5.0 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
}
}
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId )
{
if ( !isPlayer( attacker ) || (!self.touchTriggers.size && !attacker.touchTriggers.size) || attacker.pers["team"] == self.pers["team"] )
return;
awardedAssault = false;
awardedDefend = false;
foreach ( trigger in self.touchTriggers )
{
// TODO: way to check for dom specific triggers
if ( !isDefined( trigger.useObj ) )
continue;
ownerTeam = trigger.useObj.ownerTeam;
team = self.pers["team"];
if ( ownerTeam == "neutral" )
continue;
if ( team == ownerTeam )
{
awardedAssault = true;
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "assault", maps\mp\gametypes\_rank::getScoreInfoValue( "assault" ) );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "assault" );
maps\mp\gametypes\_gamescore::givePlayerScore( "assault", attacker );
thread maps\mp\_matchdata::logKillEvent( killId, "defending" );
}
else
{
awardedDefend = true;
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "defend", maps\mp\gametypes\_rank::getScoreInfoValue( "defend" ) );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "defend" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defend", attacker );
thread maps\mp\_matchdata::logKillEvent( killId, "assaulting" );
}
}
foreach ( trigger in attacker.touchTriggers )
{
// TODO: way to check for dom specific triggers
if ( !isDefined( trigger.useObj ) )
continue;
ownerTeam = trigger.useObj.ownerTeam;
team = attacker.pers["team"];
if ( ownerTeam == "neutral" )
continue;
if ( team == ownerTeam )
{
if ( !awardedDefend )
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "defend", maps\mp\gametypes\_rank::getScoreInfoValue( "defend" ) );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "defend" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defend", attacker );
thread maps\mp\_matchdata::logKillEvent( killId, "assaulting" );
}
else
{
if ( !awardedAssault )
attacker thread maps\mp\gametypes\_hud_message::SplashNotify( "assault", maps\mp\gametypes\_rank::getScoreInfoValue( "assault" ) );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "assault" );
maps\mp\gametypes\_gamescore::givePlayerScore( "assault", attacker );
thread maps\mp\_matchdata::logKillEvent( killId, "defending" );
}
}
}
getOwnedDomFlags()
{
domFlags = [];
foreach ( domFlag in level.domFlags )
{
if ( domFlag maps\mp\gametypes\_gameobjects::getOwnerTeam() != "neutral" && isDefined( domFlag.captureTime ) )
domFlags[domFlags.size] = domFlag;
}
return domFlags;
}
getTeamFlagCount( team )
{
score = 0;
for (i = 0; i < level.flags.size; i++)
{
if ( level.domFlags[i] maps\mp\gametypes\_gameobjects::getOwnerTeam() == team )
score++;
}
return score;
}
getFlagTeam()
{
return self.useObj maps\mp\gametypes\_gameobjects::getOwnerTeam();
}
getBoundaryFlags()
{
// get all flags which are adjacent to flags that aren't owned by the same team
bflags = [];
for (i = 0; i < level.flags.size; i++)
{
for (j = 0; j < level.flags[i].adjflags.size; j++)
{
if (level.flags[i].useObj maps\mp\gametypes\_gameobjects::getOwnerTeam() != level.flags[i].adjflags[j].useObj maps\mp\gametypes\_gameobjects::getOwnerTeam() )
{
bflags[bflags.size] = level.flags[i];
break;
}
}
}
return bflags;
}
getBoundaryFlagSpawns(team)
{
spawns = [];
bflags = getBoundaryFlags();
for (i = 0; i < bflags.size; i++)
{
if (isdefined(team) && bflags[i] getFlagTeam() != team)
continue;
for (j = 0; j < bflags[i].nearbyspawns.size; j++)
spawns[spawns.size] = bflags[i].nearbyspawns[j];
}
return spawns;
}
getSpawnsBoundingFlag( avoidflag )
{
spawns = [];
for (i = 0; i < level.flags.size; i++)
{
flag = level.flags[i];
if ( flag == avoidflag )
continue;
isbounding = false;
for (j = 0; j < flag.adjflags.size; j++)
{
if ( flag.adjflags[j] == avoidflag )
{
isbounding = true;
break;
}
}
if ( !isbounding )
continue;
for (j = 0; j < flag.nearbyspawns.size; j++)
spawns[spawns.size] = flag.nearbyspawns[j];
}
return spawns;
}
// gets an array of all spawnpoints which are near flags that are
// owned by the given team, or that are adjacent to flags owned by the given team.
getOwnedAndBoundingFlagSpawns(team)
{
spawns = [];
for (i = 0; i < level.flags.size; i++)
{
if ( level.flags[i] getFlagTeam() == team )
{
// add spawns near this flag
for (s = 0; s < level.flags[i].nearbyspawns.size; s++)
spawns[spawns.size] = level.flags[i].nearbyspawns[s];
}
else
{
for (j = 0; j < level.flags[i].adjflags.size; j++)
{
if ( level.flags[i].adjflags[j] getFlagTeam() == team )
{
// add spawns near this flag
for (s = 0; s < level.flags[i].nearbyspawns.size; s++)
spawns[spawns.size] = level.flags[i].nearbyspawns[s];
break;
}
}
}
}
return spawns;
}
// gets an array of all spawnpoints which are near flags that are
// owned by the given team
getOwnedFlagSpawns(team)
{
spawns = [];
for (i = 0; i < level.flags.size; i++)
{
if ( level.flags[i] getFlagTeam() == team )
{
// add spawns near this flag
for (s = 0; s < level.flags[i].nearbyspawns.size; s++)
spawns[spawns.size] = level.flags[i].nearbyspawns[s];
}
}
return spawns;
}
flagSetup()
{
maperrors = [];
descriptorsByLinkname = [];
// (find each flag_descriptor object)
descriptors = getentarray("flag_descriptor", "targetname");
flags = level.flags;
for (i = 0; i < level.domFlags.size; i++)
{
closestdist = undefined;
closestdesc = undefined;
for (j = 0; j < descriptors.size; j++)
{
dist = distance(flags[i].origin, descriptors[j].origin);
if (!isdefined(closestdist) || dist < closestdist) {
closestdist = dist;
closestdesc = descriptors[j];
}
}
if (!isdefined(closestdesc)) {
maperrors[maperrors.size] = "there is no flag_descriptor in the map! see explanation in dom.gsc";
break;
}
if (isdefined(closestdesc.flag)) {
maperrors[maperrors.size] = "flag_descriptor with script_linkname \"" + closestdesc.script_linkname + "\" is nearby more than one flag; is there a unique descriptor near each flag?";
continue;
}
flags[i].descriptor = closestdesc;
closestdesc.flag = flags[i];
descriptorsByLinkname[closestdesc.script_linkname] = closestdesc;
}
if (maperrors.size == 0)
{
// find adjacent flags
for (i = 0; i < flags.size; i++)
{
if (isdefined(flags[i].descriptor.script_linkto))
adjdescs = strtok(flags[i].descriptor.script_linkto, " ");
else
adjdescs = [];
for (j = 0; j < adjdescs.size; j++)
{
otherdesc = descriptorsByLinkname[adjdescs[j]];
if (!isdefined(otherdesc) || otherdesc.targetname != "flag_descriptor") {
maperrors[maperrors.size] = "flag_descriptor with script_linkname \"" + flags[i].descriptor.script_linkname + "\" linked to \"" + adjdescs[j] + "\" which does not exist as a script_linkname of any other entity with a targetname of flag_descriptor (or, if it does, that flag_descriptor has not been assigned to a flag)";
continue;
}
adjflag = otherdesc.flag;
if (adjflag == flags[i]) {
maperrors[maperrors.size] = "flag_descriptor with script_linkname \"" + flags[i].descriptor.script_linkname + "\" linked to itself";
continue;
}
flags[i].adjflags[flags[i].adjflags.size] = adjflag;
}
}
}
// assign each spawnpoint to nearest flag
spawnpoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dom_spawn" );
for (i = 0; i < spawnpoints.size; i++)
{
if (isdefined(spawnpoints[i].script_linkto)) {
desc = descriptorsByLinkname[spawnpoints[i].script_linkto];
if (!isdefined(desc) || desc.targetname != "flag_descriptor") {
maperrors[maperrors.size] = "Spawnpoint at " + spawnpoints[i].origin + "\" linked to \"" + spawnpoints[i].script_linkto + "\" which does not exist as a script_linkname of any entity with a targetname of flag_descriptor (or, if it does, that flag_descriptor has not been assigned to a flag)";
continue;
}
nearestflag = desc.flag;
}
else {
nearestflag = undefined;
nearestdist = undefined;
for (j = 0; j < flags.size; j++)
{
dist = distancesquared(flags[j].origin, spawnpoints[i].origin);
if (!isdefined(nearestflag) || dist < nearestdist)
{
nearestflag = flags[j];
nearestdist = dist;
}
}
}
nearestflag.nearbyspawns[nearestflag.nearbyspawns.size] = spawnpoints[i];
}
if (maperrors.size > 0)
{
println("^1------------ Map Errors ------------");
for(i = 0; i < maperrors.size; i++)
println(maperrors[i]);
println("^1------------------------------------");
error("Map errors. See above");
maps\mp\gametypes\_callbacksetup::AbortLevel();
return;
}
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "pointscaptured", 0, maps\mp\_awards::highestWins );
}
onSpawnPlayer()
{
}
updateCPM()
{
if ( !isDefined( self.CPM ) )
{
self.numCaps = 0;
self.CPM = 0;
}
self.numCaps++;
if ( getMinutesPassed() < 1 )
return;
self.CPM = self.numCaps / getMinutesPassed();
}
getCapXPScale()
{
if ( self.CPM < 4 )
return 1;
else
return 0.25;
}
+498
View File
@@ -0,0 +1,498 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Global Thermal Nuclear War
*/
/*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
registerScoreLimitDvar( level.gameType, 101, 0, 10000 );
registerRoundLimitDvar( level.gameType, 1, 0, 30 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerRoundSwitchDvar( level.gameType, 0, 0, 30 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onDeadEvent = ::onDeadEvent;
level.initGametypeAwards = ::initGametypeAwards;
level.onTimeLimit = ::onTimeLimit;
level.onNormalDeath = ::onNormalDeath;
level.gtnw = true;
game["dialog"]["gametype"] = "gtw";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "obj_destroy";
game["dialog"]["defense_obj"] = "obj_defend";
level thread onPlayerConnect();
}
gtnw_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
useBar = player createPrimaryProgressBar();
useBarText = player createPrimaryProgressBarText();
useBarText setText( &"MP_CAPTURING_NUKE" );
useBar.useTime = 100;
player.useBar = useBar;
player.useBar hideElem();
player.useBarText = useBarText;
player.useBarText hideElem();
}
}
onStartGameType()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( !isdefined( game["original_defenders"] ) )
game["original_defenders"] = game["defenders"];
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setClientNameMode("auto_change");
if ( level.splitscreen )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GTNW" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GTNW" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_GTNW_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_GTNW_SCORE" );
}
setObjectiveText( game["attackers"], &"OBJECTIVES_GTNW" );
setObjectiveText( game["defenders"], &"OBJECTIVES_GTNW" );
setObjectiveHintText( game["attackers"], &"OBJECTIVES_GTNW_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_GTNW_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_ctf_spawn_allies" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_ctf_spawn_axis" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
thread maps\mp\gametypes\_dev::init();
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 500 );
allowed[0] = "airdrop_pallet";
allowed[1] = "gtnw";
allowed[2] = "gtnw_zone";
maps\mp\gametypes\_gameobjects::main(allowed);
thread setupNukeSite();
}
onPrecacheGameType()
{
precacheShader("waypoint_defend");
precacheShader("waypoint_target");
precacheShader("waypoint_capture");
precacheShader("compass_waypoint_target");
precacheShader("compass_waypoint_defend");
precacheShader("compass_waypoint_capture");
precacheString( &"MP_CAPTURING_NUKE" );
return;
}
setupNukeSite()
{
level.lastStatus["allies"] = 0;
level.lastStatus["axis"] = 0;
nukeZone = getEnt( "gtnw_zone", "targetname" );
assertEx( isDefined( nukeZone ), "GTNW Zone prefab doesn't exist in this map" );
visuals = [];
nukeSite = maps\mp\gametypes\_gameobjects::createUseObject( "neutral", nukeZone, visuals, (0,0,100) );
nukeSite maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
nukeSite maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" );
nukeSite maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral" );
nukeSite maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" );
nukeSite maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
nukeSite.noUseBar = true;
nukeSite maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
nukeSite.onBeginUse = ::onBeginUse;
nukeSite.onEndUse = ::onEndUse;
level.nukeSite = nukeSite;
nukeSite thread scoreCounter();
}
getSpawnPoint()
{
if ( self.team == "axis" )
{
spawnTeam = game["attackers"];
}
else
{
spawnTeam = game["defenders"];
}
if ( level.inGracePeriod )
{
spawnPoints = getentarray("mp_ctf_spawn_" + spawnteam + "_start", "classname");
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
spawnFxDelay( fxid, pos, forward, right, delay )
{
wait delay;
effect = spawnFx( fxid, pos, forward, right );
triggerFx( effect );
}
onDeadEvent( team )
{
if ( ( isDefined( level.nukeIncoming ) && level.nukeIncoming ) || ( isDefined( level.nukeDetonated ) && level.nukeDetonated ) )
return;
if ( team == game["attackers"] )
{
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
level thread gtnw_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
level thread gtnw_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
initGametypeAwards()
{
return;
}
onTimeLimit()
{
if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
{
level thread overtimeThread();
}
else if( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
}
else if( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
}
}
overtimeThread( time )
{
level endon( "game_ended" );
level.inOvertime = true;
level thread disableSpawning( 5 );
level.endGameTime = 120;
time = level.endGameTime;
foreach ( player in level.players )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "gtnw_overtime" );
maps\mp\gametypes\_gamelogic::pauseTimer();
level.timeLimitOverride = true;
setGameEndTime( int( getTime() + ( level.endGameTime * 1000 ) ) );
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( time );
if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
}
else if ( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
}
else
{
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game["strings"]["time_limit_reached"] );
}
}
disableSpawning( waitTime )
{
level endon( "game_ended" );
wait ( 5 );
level.disableSpawning = true;
}
onBeginUse( player )
{
player.useBar showElem();
player.useBarText showElem();
return;
}
onEndUse( team, player, success )
{
player.useBar hideElem();
player.useBarText hideElem();
return;
}
scoreCounter()
{
level endon( "game_ended" );
self endon( "stop_counting" );
for ( ;; )
{
if ( !self.touchList["axis"].size && !self.touchlist["allies"].size )
{
setDvar( "ui_danger_team", "none" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" );
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "none" );
self updateHudElems();
wait 1;
continue;
}
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_capture" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_capture" );
if ( self.touchList["axis"].size > self.touchList["allies"].size )
{
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "axis" ) < 100 )
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( "axis", 1 );
self thread setUseBarScore( "axis" );
setDvar( "ui_danger_team", "allies" );
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "axis" );
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "axis" ) >= 100 )
{
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
activateNuke( "axis" );
self notify( "stop_counting" );
}
}
else if ( self.touchList["axis"].size < self.touchList["allies"].size )
{
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "allies" ) < 100 )
maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( "allies", 1 );
self thread setUseBarScore( "allies" );
setDvar( "ui_danger_team", "axis" );
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "allies" );
if ( maps\mp\gametypes\_gamescore::_getTeamScore( "allies" ) >= 100 )
{
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
activateNuke( "allies" );
self notify( "stop_counting" );
}
}
else
{
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_captureneutral" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_captureneutral" );
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "none" );
setDvar( "ui_danger_team", "contested" );
}
updateHudElems();
wait( 1 );
}
}
activateNuke( team )
{
self giveFlagCaptureXP( self.touchList[team] );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
bestTime = 99999999;
nukeOwner = undefined;
foreach( player in level.players )
{
if ( !isDefined( player ) )
continue;
player.useBar hideElem();
player.useBarText hideElem();
if ( player.team != team )
continue;
if ( !isDefined( self.touchlist[team][player.guid] ) )
continue;
timeStarted = self.touchlist[team][player.guid].startTime;
if ( timeStarted < bestTime )
{
nukeOwner = player;
bestTime = timeStarted;
}
}
assert( isDefined( nukeOwner ) );
nukeOwner maps\mp\killstreaks\_nuke::tryUseNuke( 1 );
}
giveFlagCaptureXP( touchList )
{
level endon ( "game_ended" );
wait .05;
WaitTillSlowProcessAllowed();
players = getArrayKeys( touchList );
for ( index = 0; index < players.size; index++ )
{
player = touchList[players[index]].player;
player thread maps\mp\gametypes\_hud_message::SplashNotify( "captured_nuke", maps\mp\gametypes\_rank::getScoreInfoValue( "capture" ) );
player thread [[level.onXPEvent]]( "capture" );
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
}
}
setUseBarScore( team )
{
teamScore = getTeamScore( team );
foreach( player in level.players )
{
if ( !isDefined( player ) )
continue;
if ( player.team != team )
continue;
if ( !isDefined( self.touchlist[team][player.guid] ) )
continue;
//player thread maps\mp\gametypes\_rank::giveRankXP( "challenge",50 );
player.useBar updateBar( teamScore/100, 0 );
}
}
updateHudElems()
{
foreach( player in level.players )
{
if ( !isDefined( player ) )
continue;
if ( !isDefined( self.touchlist["axis"][player.guid] ) && !isDefined( self.touchlist["allies"][player.guid] ) )
{
player.useBar hideElem();
player.useBarText hideElem();
}
if ( isDefined( self.touchlist["axis"][player.guid] ) || isDefined( self.touchlist["allies"][player.guid] ) )
{
player.useBar showElem();
player.useBarText showElem();
}
}
}
onNormalDeath( victim, attacker, lifeId )
{
if ( !isDefined( level.inOvertime ) || !level.inOvertime )
return;
team = victim.team;
if ( game["state"] == "postgame" )
attacker.finalKill = true;
}
File diff suppressed because it is too large. Load diff
+558
View File
@@ -0,0 +1,558 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
One Flag CTF
*/
/*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
registerScoreLimitDvar( level.gameType, 1, 0, 10000 );
registerRoundLimitDvar( level.gameType, 0, 0, 30 );
registerWinLimitDvar( level.gameType, 4, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.objectiveBased = true;
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onPlayerKilled = ::onPlayerKilled;
level.onTimeLimit = ::onTimeLimit;
level.initGametypeAwards = ::initGametypeAwards;
game["dialog"]["gametype"] = "oneflag";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
if ( getdvar("scr_oneflag_returntime") == "" )
setdvar("scr_oneflag_returntime", "15");
level.flagReturnTime = getdvarint( "scr_oneflag_returntime" );
}
onPrecacheGameType()
{
precacheString(&"MP_FLAG_TAKEN_BY");
precacheString(&"MP_ENEMY_FLAG_TAKEN_BY");
precacheString(&"MP_FLAG_CAPTURED_BY");
precacheString(&"MP_ENEMY_FLAG_CAPTURED_BY");
//precacheString(&"MP_FLAG_RETURNED_BY");
precacheString(&"MP_FLAG_RETURNED");
precacheString(&"MP_ENEMY_FLAG_RETURNED");
precacheString(&"MP_YOUR_FLAG_RETURNING_IN");
precacheString(&"MP_ENEMY_FLAG_RETURNING_IN");
precacheString(&"MP_ENEMY_FLAG_DROPPED_BY");
precacheString( &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
}
onStartGameType()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( !isdefined( game["original_defenders"] ) )
game["original_defenders"] = game["defenders"];
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setClientNameMode("auto_change");
setObjectiveText( game["attackers"], &"OBJECTIVES_CTF" );
setObjectiveText( game["defenders"], &"OBJECTIVES_CTF" );
if ( level.splitscreen )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_SCORE" );
}
setObjectiveHintText( game["attackers"], &"OBJECTIVES_ONE_FLAG_ATTACKER_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_ONE_FLAG_DEFENDER_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_ctf_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_ctf_spawn_allies" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_ctf_spawn_axis" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
thread maps\mp\gametypes\_dev::init();
allowed[0] = "ctf";
maps\mp\gametypes\_gameobjects::main(allowed);
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "pickup", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "return", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "capture", 500 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill_carrier", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defend_assist", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault", 200 );
maps\mp\gametypes\_rank::registerScoreInfo( "assault_assist", 40 );
thread oneflag_ctf();
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = getentarray("mp_ctf_spawn_" + spawnteam + "_start", "classname");
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onSpawnPlayer()
{
self.usingObj = undefined;
}
oneflag_ctf()
{
level.flagModel["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
level.icon2D["allies"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "allies" );
level.carryFlag["allies"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "allies" );
precacheModel( level.flagModel["allies"] );
precacheModel( level.carryFlag["allies"] );
level.flagModel["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
level.icon2D["axis"] = maps\mp\gametypes\_teams::getTeamFlagIcon( "axis" );
level.carryFlag["axis"] = maps\mp\gametypes\_teams::getTeamFlagCarryModel( "axis" );
precacheModel( level.flagModel["axis"] );
precacheModel( level.carryFlag["axis"] );
level.iconCapture3D = "waypoint_capture";
level.iconCapture2D = "compass_waypoint_capture";
level.iconDefend3D = "waypoint_defend";
level.iconDefend2D = "compass_waypoint_defend";
level.iconTarget3D = "waypoint_target";
level.iconTarget2D = "compass_waypoint_target";
precacheShader( level.icon2D["axis"] );
precacheShader( level.icon2D["allies"] );
precacheShader( level.iconCapture3D );
precacheShader( level.iconDefend3D );
precacheShader( level.iconCapture2D );
precacheShader( level.iconDefend2D );
precacheShader( level.iconTarget3D );
precacheShader( level.iconTarget2D );
precacheShader( "waypoint_kill" );
level.teamFlags[game["defenders"]] = createTeamFlag( game["defenders"] );
level.capZones[game["attackers"]] = createCapZone( game["attackers"] );
level.flagCaptured = false;
}
spawnFxDelay( fxid, pos, forward, right, delay )
{
wait delay;
effect = spawnFx( fxid, pos, forward, right );
triggerFx( effect );
}
createTeamFlag( team )
{
entityTeam = game["original_defenders"];
trigger = getEnt( "ctf_trig_" + entityTeam, "targetname" );
if ( !isDefined( trigger ) )
{
error( "No ctf_trig_" + entityTeam + " trigger found in map." );
return;
}
visuals[0] = getEnt( "ctf_flag_" + entityTeam, "targetname" );
if ( !isDefined( visuals[0] ) )
{
error( "No ctf_flag_" + entityTeam + " script_model found in map." );
return;
}
cloneTrigger = spawn( "trigger_radius", trigger.origin, 0, 96, trigger.height );
trigger delete();
trigger = cloneTrigger;
visuals[0] setModel( level.flagModel[team] );
teamFlag = maps\mp\gametypes\_gameobjects::createCarryObject( team, trigger, visuals, (0,0,85) );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "friendly", 15.0 );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseTime( "enemy", 0 );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "enemy", &"MP_CAPTURING_FLAG" );
teamFlag maps\mp\gametypes\_gameobjects::setTeamUseText( "friendly", &"MP_RETURNING_FLAG" );
teamFlag maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
teamFlag maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefend2D );
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefend3D );
teamFlag maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", level.iconCapture2D );
teamFlag maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCapture3D );
teamFlag maps\mp\gametypes\_gameobjects::setCarryIcon( level.icon2D[team] );
teamFlag.allowWeapons = true;
teamFlag.onPickup = ::onPickup;
teamFlag.onPickupFailed = ::onPickup;
teamFlag.onDrop = ::onDrop;
teamFlag.onReset = ::onReset;
//teamFlag.onBeginUse = ::onBeginUse;
//teamFlag.onEndUse = ::onEndUse;
teamFlag.oldRadius = trigger.radius;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
return teamFlag;
}
createCapZone( team )
{
entityTeam = level.otherTeam[game["original_defenders"]];
trigger = getEnt( "ctf_zone_" + entityTeam, "targetname" );
if ( !isDefined( trigger ) )
{
error("No ctf_zone_" + entityTeam + " trigger found in map.");
return;
}
visuals[0] = getEnt( "ctf_flag_" + entityTeam, "targetname" );
if ( !isDefined( visuals[0] ) )
{
error( "No ctf_flag_" + entityTeam + " script_model found in map." );
return;
}
visuals[0] hide();
visuals = [];
capZone = maps\mp\gametypes\_gameobjects::createUseObject( team, trigger, visuals, (0,0,85) );
capZone maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
capZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
capZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconTarget2D );
capZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconTarget3D );
capZone maps\mp\gametypes\_gameobjects::setUseTime( 0 );
capZone maps\mp\gametypes\_gameobjects::setKeyObject( level.teamFlags[ getOtherTeam( team ) ] );
capZone.onUse = ::onUse;
capZone.onCantUse = ::onCantUse;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( team );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
return capZone;
}
onBeginUse( player )
{
team = player.pers["team"];
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
self.trigger.radius = 1024;
else
self.trigger.radius = self.oldRadius;
}
onEndUse( player, team, success )
{
self.trigger.radius = self.oldRadius;
}
onPickup( player )
{
team = player.pers["team"];
if ( team == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
{
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagreturn", maps\mp\gametypes\_rank::getScoreInfoValue( "pickup" ) );
player thread [[level.onXPEvent]]( "pickup" );
self thread returnFlag();
player incPlayerStat( "flagsreturned", 1 );
player thread maps\mp\_matchdata::logGameEvent( "return", player.origin );
}
else
{
player attachFlag();
level.capZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
//self maps\mp\gametypes\_gameobjects::setVisibleTeam( "enemy" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_kill" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconTarget2D );
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_TAKEN_BY", &"MP_FLAG_TAKEN_BY", "mp_obj_taken", "mp_enemy_obj_taken", player );
leaderDialog( "enemy_flag_taken", team, "status" );
leaderDialog( "flag_taken", otherteam, "status" );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "flagpickup", maps\mp\gametypes\_rank::getScoreInfoValue( "pickup" ) );
maps\mp\gametypes\_gamescore::givePlayerScore( "pickup", player );
player thread [[level.onXPEvent]]( "pickup" );
player incPlayerStat( "flagscarried", 1 );
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
}
}
returnFlag()
{
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
otherTeam = level.otherTeam[team];
self maps\mp\gametypes\_gameobjects::returnHome();
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::allowCarry( "enemy" );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
printAndSoundOnEveryone( team, getOtherTeam( team ), &"MP_FLAG_RETURNED", &"MP_ENEMY_FLAG_RETURNED", "mp_obj_returned", "mp_obj_returned", "" );
leaderDialog( "enemy_flag_returned", otherteam, "status" );
leaderDialog( "flag_returned", team, "status" );
}
onDrop( player )
{
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
otherTeam = level.otherTeam[team];
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefend3D );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefend2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCapture3D );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::allowCarry( "any" );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
if ( isDefined( player ) )
{
if ( isDefined( player.carryFlag ) )
player detachFlag();
printAndSoundOnEveryone( otherTeam, "none", &"MP_ENEMY_FLAG_DROPPED_BY", "", "mp_war_objective_lost", "", player );
}
else
{
playSoundOnPlayers( "mp_war_objective_lost", otherTeam );
}
leaderDialog( "enemy_flag_dropped", otherTeam, "status" );
leaderDialog( "flag_dropped", team, "status" );
}
onReset()
{
self notify ( "flag_reset" );
team = self maps\mp\gametypes\_gameobjects::getOwnerTeam();
otherTeam = level.otherTeam[team];
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", level.iconDefend3D );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", level.iconDefend2D );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", level.iconCapture3D );
level.capZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
}
onUse( player )
{
team = player.pers["team"];
if ( team == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
leaderDialog( "enemy_flag_captured", team, "status" );
leaderDialog( "flag_captured", otherteam, "status" );
maps\mp\gametypes\_gamescore::givePlayerScore( "capture", player );
player thread [[level.onXPEvent]]( "capture" );
player incPlayerStat( "flagscaptured", 1 );
player notify( "objective", "captured" );
player thread maps\mp\_matchdata::logGameEvent( "capture", player.origin );
// round win here, no reset necessary
printAndSoundOnEveryone( team, otherteam, &"MP_ENEMY_FLAG_CAPTURED_BY", &"MP_FLAG_CAPTURED_BY", "mp_obj_captured", "mp_enemy_obj_captured", player );
thread flagCaptured( team, &"MP_DOM_NEUTRAL_FLAG_CAPTURED" );
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::allowCarry( "none" );
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.teamFlags[otherTeam] maps\mp\gametypes\_gameobjects::disableObject();
level.capZones[team] maps\mp\gametypes\_gameobjects::allowUse( "none" );
if ( isDefined( player.carryFlag ) )
player detachFlag();
}
flagCaptured( winningTeam, endReasonText )
{
maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
level.flagCaptured = true;
}
onTimeLimit()
{
if ( level.flagCaptured )
return;
// TODO: change to "Flag Defended" or some such
maps\mp\gametypes\_gamelogic::endGame( game["defenders"], game["strings"]["time_limit_reached"] );
}
onCantUse( player )
{
// player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId )
{
if ( isDefined( attacker ) && isPlayer( attacker ) && attacker.pers["team"] != self.pers["team"] )
{
if ( isDefined( attacker.carryFlag ) )
attacker incPlayerStat( "killsasflagcarrier", 1 );
if ( isDefined( self.carryFlag ) )
{
attacker thread [[level.onXPEvent]]( "kill_carrier" );
maps\mp\gametypes\_gamescore::givePlayerScore( "kill_carrier", attacker );
attacker incPlayerStat( "flagcarrierkills", 1 );
thread maps\mp\_matchdata::logKillEvent( killId, "carrying" );
self detachFlag();
}
}
}
attachFlag()
{
otherTeam = level.otherTeam[self.pers["team"]];
self attach( level.carryFlag[otherTeam], "J_spine4", true );
self.carryFlag = level.carryFlag[otherTeam];
}
detachFlag()
{
self detach( self.carryFlag, "J_spine4" );
self.carryFlag = undefined;
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "flagscaptured", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagsreturned", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "flagscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasflagcarrier", 0, maps\mp\_awards::highestWins );
}
+907
View File
@@ -0,0 +1,907 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Sabotage
// ...etc...
*/
/*QUAKED mp_sab_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_sab_spawn_axis_planted (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_sab_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_sab_spawn_allies_planted (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_sab_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_sab_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
if ( getdvar("mapname") == "mp_background" )
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
//level.objectiveBased = true;
level.teamBased = true;
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 0, 0, 500 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
setOverTimeLimitDvar( 2 );
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onOneLeftEvent = ::onOneLeftEvent;
level.onTimeLimit = ::onTimeLimit;
level.onNormalDeath = ::onNormalDeath;
level.initGametypeAwards = ::initGametypeAwards;
game["dialog"]["gametype"] = "sabotage";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "capture_obj";
game["dialog"]["defense_obj"] = "capture_obj";
badtrig = getent( "sab_bomb_defuse_allies", "targetname" );
if ( isdefined( badtrig ) )
badtrig delete();
badtrig = getent( "sab_bomb_defuse_axis", "targetname" );
if ( isdefined( badtrig ) )
badtrig delete();
}
onPrecacheGameType()
{
game["bomb_dropped_sound"] = "mp_war_objective_lost";
game["bomb_recovered_sound"] = "mp_war_objective_taken";
precacheShader("waypoint_bomb");
precacheShader("waypoint_kill");
precacheShader("waypoint_bomb_enemy");
precacheShader("waypoint_defend");
precacheShader("waypoint_defuse");
precacheShader("waypoint_target");
precacheShader("waypoint_escort");
precacheShader("waypoint_bomb");
precacheShader("waypoint_defend");
precacheShader("waypoint_defuse");
precacheShader("waypoint_target");
precacheShader("hud_suitcase_bomb");
precacheString(&"MP_EXPLOSIVES_RECOVERED_BY");
precacheString(&"MP_EXPLOSIVES_DROPPED_BY");
precacheString(&"MP_EXPLOSIVES_PLANTED_BY");
precacheString(&"MP_EXPLOSIVES_DEFUSED_BY");
precacheString(&"MP_YOU_HAVE_RECOVERED_THE_BOMB");
precacheString(&"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES");
precacheString(&"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES");
precacheString(&"MP_PLANTING_EXPLOSIVE");
precacheString(&"MP_DEFUSING_EXPLOSIVE");
precacheString(&"MP_TARGET_DESTROYED");
precacheString(&"MP_NO_RESPAWN");
precacheString(&"MP_TIE_BREAKER");
precacheString(&"MP_NO_RESPAWN");
precacheString(&"MP_SUDDEN_DEATH");
}
onStartGameType()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
setClientNameMode("auto_change");
game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
game["strings"]["target_defended"] = &"MP_TARGET_DEDEFEND";
setObjectiveText( "allies", &"OBJECTIVES_SAB" );
setObjectiveText( "axis", &"OBJECTIVES_SAB" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_SAB" );
setObjectiveScoreText( "axis", &"OBJECTIVES_SAB" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_SAB_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_SAB_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_SAB_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_SAB_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sab_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sab_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_sab_spawn_allies" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_sab_spawn_axis" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints("allies", "mp_sab_spawn_allies_planted", true );
maps\mp\gametypes\_spawnlogic::addSpawnPoints("axis", "mp_sab_spawn_axis_planted", true );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
level.spawn_axis = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_axis" );
level.spawn_axis_planted = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_axis_planted" );
level.spawn_axis_planted = array_combine( level.spawn_axis_planted, level.spawn_axis );
level.spawn_allies = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_allies" );
level.spawn_allies_planted = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_allies_planted" );
level.spawn_allies_planted = array_combine( level.spawn_allies_planted, level.spawn_allies );
level.spawn_axis_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_axis_start" );
level.spawn_allies_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_allies_start" );
maps\mp\gametypes\_rank::registerScoreInfo( "plant", 200 );
maps\mp\gametypes\_rank::registerScoreInfo( "destroy", 1000 );
maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 150 );
allowed[0] = "sab";
maps\mp\gametypes\_gameobjects::main(allowed);
thread updateGametypeDvars();
thread sabotage();
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.useStartSpawns )
{
if (spawnteam == "axis")
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_axis_start);
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_allies_start);
}
else
{
if ( isDefined( level.bombplanted ) && level.bombplanted && ( isDefined( level.bombOwner ) && spawnTeam == level.bombOwner.team ) )
{
if (spawnteam == "axis")
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_axis_planted );
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( level.spawn_allies_planted );
}
else
{
if (spawnteam == "axis")
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam(level.spawn_axis);
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam(level.spawn_allies);
}
}
assert( isDefined(spawnpoint) );
return spawnpoint;
}
onSpawnPlayer()
{
self.isPlanting = false;
self.isDefusing = false;
self.isBombCarrier = false;
if( ( inOvertime() ) && !isDefined( self.otSpawned ) )
self thread printOTHint();
}
printOTHint()
{
self endon ( "disconnect" );
// give the "Overtime!" message time to show
wait ( 0.25 );
self thread maps\mp\gametypes\_hud_message::SplashNotify( "sudden_death" );
self.otSpawned = true;
}
updateGametypeDvars()
{
level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
level.bombTimer = dvarFloatValue( "bombtimer", 45, 1, 300 );
level.hotPotato = dvarIntValue( "hotpotato", 1, 0, 1 );
level.scoreMode = getWatchedDvar( "scorelimit" );
}
sabotage()
{
level.bombPlanted = false;
level.bombExploded = false;
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
trigger = getEnt( "sab_bomb_pickup_trig", "targetname" );
if ( !isDefined( trigger ) )
{
error( "No sab_bomb_pickup_trig trigger found in map." );
return;
}
visuals[0] = getEnt( "sab_bomb", "targetname" );
if ( !isDefined( visuals[0] ) )
{
error( "No sab_bomb script_model found in map." );
return;
}
precacheModel( "prop_suitcase_bomb" );
visuals[0] setModel( "prop_suitcase_bomb" );
level.sabBomb = maps\mp\gametypes\_gameobjects::createCarryObject( "neutral", trigger, visuals, (0,0,32) );
level.sabBomb maps\mp\gametypes\_gameobjects::allowCarry( "any" );
level.sabBomb maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_bomb" );
level.sabBomb maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_bomb" );
level.sabBomb maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
level.sabBomb maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
level.sabBomb maps\mp\gametypes\_gameobjects::setCarryIcon( "hud_suitcase_bomb" );
level.sabBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
level.sabBomb.objIDPingEnemy = true;
level.sabBomb.onPickup = ::onPickup;
level.sabBomb.onDrop = ::onDrop;
level.sabBomb.allowWeapons = true;
level.sabBomb.objPoints["allies"].archived = true;
level.sabBomb.objPoints["axis"].archived = true;
level.sabBomb.autoResetTime = 60.0;
if ( !isDefined( getEnt( "sab_bomb_axis", "targetname" ) ) )
{
error("No sab_bomb_axis trigger found in map.");
return;
}
if ( !isDefined( getEnt( "sab_bomb_allies", "targetname" ) ) )
{
error("No sab_bomb_allies trigger found in map.");
return;
}
if ( game["switchedsides"] )
{
level.bombZones["allies"] = createBombZone( "allies", getEnt( "sab_bomb_axis", "targetname" ) );
level.bombZones["axis"] = createBombZone( "axis", getEnt( "sab_bomb_allies", "targetname" ) );
}
else
{
level.bombZones["allies"] = createBombZone( "allies", getEnt( "sab_bomb_allies", "targetname" ) );
level.bombZones["axis"] = createBombZone( "axis", getEnt( "sab_bomb_axis", "targetname" ) );
}
if ( level.scoreMode )
level thread scoreThread();
if ( inOvertime() )
level thread overtimeThread();
}
getClosestSite()
{
if ( distance2d( self.origin, level.bombZones["allies"].trigger.origin ) < distance2d( self.origin, level.bombZones["axis"].trigger.origin ) )
return ( "allies" );
else
return ( "axis" );
}
distanceToSite( team )
{
return ( distance2d( self.origin, level.bombZones[team].trigger.origin ) );
}
scoreThread()
{
level.bombDistance = distance2d( getEnt( "sab_bomb_axis", "targetname" ) getOrigin(), getEnt( "sab_bomb_allies", "targetname" ) getOrigin() );
threatDistance = (level.bombDistance/2) - 384;
bombEnt = level.sabBomb.trigger;
// failsafe for bad bomb placement
if ( threatDistance > bombEnt distanceToSite( "allies" ) || threatDistance > bombEnt distanceToSite( "axis" ) )
threatDistance = bombEnt distanceToSite( bombEnt getClosestSite() ) - 128;
dangerTeam = "";
for ( ;; )
{
if ( isDefined( level.sabBomb.carrier ) )
bombEnt = level.sabBomb.carrier;
else
bombEnt = level.sabBomb.trigger;
lastDangerTeam = dangerTeam;
dangerTeam = "none";
if ( bombEnt distanceToSite( "allies" ) < threatDistance )
dangerTeam = level.bombZones["allies"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
else if ( bombEnt distanceToSite( "axis" ) < threatDistance )
dangerTeam = level.bombZones["axis"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
else if ( bombEnt distanceToSite( "allies" ) > level.bombDistance && bombEnt getClosestSite() != "allies" )
dangerTeam = level.bombZones["axis"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
else if ( bombEnt distanceToSite( "axis" ) > level.bombDistance && bombEnt getClosestSite() != "axis" )
dangerTeam = level.bombZones["allies"] maps\mp\gametypes\_gameobjects::getOwnerTeam();
if ( dangerTeam != "none" )
{
if ( !level.bombPlanted || !getWatchedDvar( "scorelimit" ) || (level.bombPlanted && (maps\mp\gametypes\_gamescore::_getTeamScore( level.otherTeam[dangerTeam] ) < getWatchedDvar( "scorelimit" ) - 1)) )
{
maps\mp\gametypes\_gamescore::_setTeamScore( level.otherTeam[dangerTeam], maps\mp\gametypes\_gamescore::_getTeamScore( level.otherTeam[dangerTeam] ) + 1 );
maps\mp\gametypes\_gamescore::updateTeamScore( level.otherTeam[dangerTeam] );
}
}
if ( dangerTeam != lastDangerTeam && !level.bombExploded )
{
setDvar( "ui_danger_team", dangerTeam );
}
wait ( 2.5 );
}
}
createBombZone( team, trigger )
{
visuals = getEntArray( trigger.target, "targetname" );
bombZone = maps\mp\gametypes\_gameobjects::createUseObject( team, trigger, visuals, (0,0,64) );
bombZone resetBombsite();
bombZone.onUse = ::onUse;
bombZone.onBeginUse = ::onBeginUse;
bombZone.onEndUse = ::onEndUse;
bombZone.onCantUse = ::onCantUse;
bombZone.useWeapon = "briefcase_bomb_mp";
for ( i = 0; i < visuals.size; i++ )
{
if ( isDefined( visuals[i].script_exploder ) )
{
bombZone.exploderIndex = visuals[i].script_exploder;
break;
}
}
return bombZone;
}
onBeginUse( player )
{
// planted the bomb
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
player.isPlanting = true;
else
player.isDefusing = true;
}
onEndUse( team, player, result )
{
if ( !isAlive( player ) )
return;
player.isPlanting = false;
player.isDefusing = false;
}
onPickup( player )
{
level notify ( "bomb_picked_up" );
self.autoResetTime = 60.0;
level.useStartSpawns = false;
team = player.pers["team"];
if ( team == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
player playLocalSound( "mp_suitcase_pickup" );
player leaderDialogOnPlayer( "obj_destroy", "bomb" );
excludeList[0] = player;
leaderDialog( "bomb_taken", team, "bomb", excludeList );
if ( !level.splitscreen )
{
leaderDialog( "bomb_lost", otherTeam, "bomb" );
leaderDialog( "obj_defend", otherTeam, "bomb" );
}
player.isBombCarrier = true;
// recovered the bomb before abandonment timer elapsed
if ( team == self maps\mp\gametypes\_gameobjects::getOwnerTeam() )
{
//printOnTeamArg( &"MP_EXPLOSIVES_RECOVERED_BY", team, player );
playSoundOnPlayers( game["bomb_recovered_sound"], team );
}
else
{
//printOnTeamArg( &"MP_EXPLOSIVES_RECOVERED_BY", team, player );
playSoundOnPlayers( game["bomb_recovered_sound"] );
}
self maps\mp\gametypes\_gameobjects::setOwnerTeam( team );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_kill" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_escort" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_escort" );
level.bombZones[team] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.bombZones[otherTeam] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
player incPlayerStat( "bombscarried", 1 );
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
}
onDrop( player )
{
if ( level.bombPlanted )
{
}
else
{
if ( isDefined( player ) )
printOnTeamArg( &"MP_EXPLOSIVES_DROPPED_BY", self maps\mp\gametypes\_gameobjects::getOwnerTeam(), player );
playSoundOnPlayers( game["bomb_dropped_sound"], self maps\mp\gametypes\_gameobjects::getOwnerTeam() );
thread abandonmentThink( 0.0 );
}
}
abandonmentThink( delay )
{
level endon ( "bomb_picked_up" );
wait ( delay );
if ( isDefined( self.carrier ) )
return;
if ( self maps\mp\gametypes\_gameobjects::getOwnerTeam() == "allies" )
otherTeam = "axis";
else
otherTeam = "allies";
// printOnTeamArg( &"MP_EXPLOSIVES_DROPPED_BY", otherTeam, &"MP_THE_ENEMY" );
playSoundOnPlayers( game["bomb_dropped_sound"], otherTeam );
self maps\mp\gametypes\_gameobjects::setOwnerTeam( "neutral" );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_bomb" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_bomb" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
level.bombZones["allies"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.bombZones["axis"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
}
onUse( player )
{
team = player.pers["team"];
otherTeam = level.otherTeam[team];
// planted the bomb
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
player notify ( "bomb_planted" );
player playSound( "mp_bomb_plant" );
level thread teamPlayerCardSplash( "callout_bombplanted", player );
leaderDialog( "bomb_planted" );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
player incPlayerStat( "bombsplanted", 1 );
player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
player.bombPlantedTime = getTime();
//if ( !inOvertime() )
level thread bombPlanted( self, player.pers["team"] );
level.bombOwner = player;
level.sabBomb.autoResetTime = undefined;
level.sabBomb maps\mp\gametypes\_gameobjects::allowCarry( "none" );
level.sabBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.sabBomb maps\mp\gametypes\_gameobjects::setDropped();
self.useWeapon = "briefcase_bomb_defuse_mp";
self setUpForDefusing();
}
else // defused the bomb
{
player notify ( "bomb_defused" );
leaderDialog( "bomb_defused" );
level thread teamPlayerCardSplash( "callout_bombdefused", player );
if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 3000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
else
player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
player incPlayerStat( "bombsdefused", 1 );
player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origin );
if ( inOvertime() )
{
thread maps\mp\gametypes\_gamelogic::endGame( team, game["strings"]["target_destroyed"] );
return;
}
level thread bombDefused( self );
self resetBombsite();
level.sabBomb maps\mp\gametypes\_gameobjects::allowCarry( "any" );
level.sabBomb maps\mp\gametypes\_gameobjects::setPickedUp( player );
}
}
onCantUse( player )
{
player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
bombPlanted( destroyedObj, team )
{
level endon ( "overtime" );
maps\mp\gametypes\_gamelogic::pauseTimer();
level.bombPlanted = true;
level.timeLimitOverride = true;
level.scoreLimitOverride = true;
setDvar( "ui_bomb_timer", 1 );
// communicate timer information to menus
setGameEndTime( int( getTime() + (level.bombTimer * 1000) ) );
destroyedObj.visuals[0] thread maps\mp\gametypes\_gamelogic::playTickingSound();
starttime = gettime();
bombTimerWait();
setDvar( "ui_bomb_timer", 0 );
destroyedObj.visuals[0] maps\mp\gametypes\_gamelogic::stopTickingSound();
if ( !level.bombPlanted )
{
if ( level.hotPotato )
{
timePassed = (gettime() - starttime) / 1000;
level.bombTimer -= timePassed;
}
return;
}
explosionOrigin = level.sabBomb.visuals[0].origin;
level.bombExploded = true;
setDvar( "ui_danger_team", "BombExploded" );
if ( isdefined( level.bombowner ) )
{
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, level.bombowner );
level.bombowner incPlayerStat( "targetsdestroyed", 1 );
}
else
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
rot = randomfloat(360);
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
triggerFx( explosionEffect );
PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
earthquake( 0.75, 2.0, explosionOrigin, 2000 );
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
if ( isDefined( destroyedObj.exploderIndex ) )
exploder( destroyedObj.exploderIndex );
level.sabBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.bombZones["allies"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.bombZones["axis"] maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
setGameEndTime( 0 );
level.scoreLimitOverride = true;
if ( level.scoreMode )
maps\mp\gametypes\_gamescore::_setTeamScore( team, int( max( getWatchedDvar( "scorelimit" ), maps\mp\gametypes\_gamescore::_getTeamScore( level.otherTeam[team] ) + 1 ) ) );
else
maps\mp\gametypes\_gamescore::_setTeamScore( team, 1 );
maps\mp\gametypes\_gamescore::updateTeamScore( team );
if ( isDefined( level.bombOwner ) )
{
level.bombOwner thread maps\mp\gametypes\_rank::giveRankXP( "destroy" );
maps\mp\gametypes\_gamescore::givePlayerScore( "destroy", level.bombOwner );
level thread teamPlayerCardSplash( "callout_destroyed_objective", level.bombOwner );
}
wait 3;
thread maps\mp\gametypes\_gamelogic::endGame( team, game["strings"]["target_destroyed"] );
}
bombTimerWait()
{
level endon("bomb_defused");
level endon("overtime_ended");
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( level.bombTimer );
}
giveLastOnTeamWarning()
{
self endon("death");
self endon("disconnect");
level endon( "game_ended" );
self waitTillRecoveredHealth( 3 );
otherTeam = getOtherTeam( self.pers["team"] );
level thread teamPlayerCardSplash( "callout_lastteammemberalive", self, self.pers["team"] );
level thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
level notify ( "last_alive", self );
//self maps\mp\gametypes\_missions::lastManSD();
}
onTimeLimit()
{
if ( level.bombExploded )
return;
if( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "axis", game["strings"]["time_limit_reached"] );
}
else if( game["teamScores"]["axis"] < game["teamScores"]["allies"] )
{
thread maps\mp\gametypes\_gamelogic::endGame( "allies", game["strings"]["time_limit_reached"] );
}
else if( game["teamScores"]["axis"] == game["teamScores"]["allies"] )
{
if ( inOvertime() )
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game["strings"]["time_limit_reached"] );
else
thread maps\mp\gametypes\_gamelogic::endGame( "overtime", game["strings"]["time_limit_reached"] );
}
}
overtimeThread( time )
{
level endon( "game_ended" );
level.inOvertime = true;
wait ( 5.0 );
level.disableSpawning = true;
}
/*
overtimeThread()
{
level.inOvertime = getTime();
level notify ( "overtime" );
thread bombDistanceThread();
foreach ( player in level.players )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "sab_overtime" );
maps\mp\gametypes\_gamelogic::pauseTimer();
level.bombPlanted = true;
level.timeLimitOverride = true;
setDvar( "ui_bomb_timer", 1 );
// communicate timer information to menus
setGameEndTime( int( getTime() + (level.bombTimer * 1000) ) );
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( level.bombTimer );
setDvar( "ui_bomb_timer", 0 );
if ( isDefined( level.sabBomb.carrier ) )
{
explosionEnt = level.sabBomb.carrier;
}
else
{
explosionEnt = level.sabBomb.visuals[0];
}
level.bombExploded = true;
if ( isdefined( level.bombowner ) )
explosionEnt radiusDamage( explosionEnt.origin, 512, 200, 20, level.bombowner );
else
explosionEnt radiusDamage( explosionEnt.origin, 512, 200, 20 );
rot = randomfloat(360);
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionEnt.origin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
triggerFx( explosionEffect );
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionEnt.origin );
setGameEndTime( 0 );
team = getOtherTeam( level.dangerTeam );
wait 3;
//maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( team, 1 );
maps\mp\gametypes\_gamelogic::endGame( team, game["strings"]["target_destroyed"] );
}
*/
bombDistanceThread()
{
level endon ( "game_ended" );
if ( cointoss() )
level.dangerTeam = "allies";
else
level.dangerTeam = "axis";
for ( ;; )
{
if ( isDefined( level.sabBomb.carrier ) )
bombEnt = level.sabBomb.carrier;
else
bombEnt = level.sabBomb.visuals[0];
if ( distance( bombEnt.origin, level.bombZones[getOtherTeam(level.dangerTeam)].visuals[0].origin ) < distance( bombEnt.origin, level.bombZones[level.dangerTeam].visuals[0].origin ) )
level.dangerTeam = getOtherTeam( level.dangerTeam );
wait ( 0.05 );
}
}
resetBombsite()
{
self maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
self maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
self maps\mp\gametypes\_gameobjects::setKeyObject( level.sabBomb );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
self.useWeapon = "briefcase_bomb_mp";
}
setUpForDefusing()
{
self maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
self maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
self maps\mp\gametypes\_gameobjects::setKeyObject( undefined );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
}
bombDefused( object )
{
setDvar( "ui_bomb_timer", 0 );
maps\mp\gametypes\_gamelogic::resumeTimer();
level.bombPlanted = false;
level.timeLimitOverride = false;
level.scoreLimitOverride = false;
level notify("bomb_defused");
}
onOneLeftEvent( team )
{
if ( level.bombExploded )
return;
lastPlayer = getLastLivingPlayer( team );
lastPlayer thread giveLastOnTeamWarning();
}
onNormalDeath( victim, attacker, lifeId, lifeId )
{
if ( victim.isPlanting )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
}
else if ( victim.isBombCarrier )
{
attacker incPlayerStat( "bombcarrierkills", 1 );
thread maps\mp\_matchdata::logKillEvent( lifeId, "carrying" );
}
else if ( victim.isDefusing )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
}
if ( attacker.isBombCarrier )
attacker incPlayerStat( "killsasbombcarrier", 1 );
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
}
+794
View File
@@ -0,0 +1,794 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
// Rallypoints should be destroyed on leaving your team/getting killed
// Compass icons need to be looked at
// Doesn't seem to be setting angle on spawn so that you are facing your rallypoint
/*
Search and Destroy
Attackers objective: Bomb one of 2 positions
Defenders objective: Defend these 2 positions / Defuse planted bombs
Round ends: When one team is eliminated, bomb explodes, bomb is defused, or roundlength time is reached
Map ends: When one team reaches the score limit, or time limit or round limit is reached
Respawning: Players remain dead for the round and will respawn at the beginning of the next round
Level requirements
------------------
Allied Spawnpoints:
classname mp_sd_spawn_attacker
Allied players spawn from these. Place at least 16 of these relatively close together.
Axis Spawnpoints:
classname mp_sd_spawn_defender
Axis players spawn from these. Place at least 16 of these relatively close together.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
Bombzones:
classname trigger_multiple
targetname bombzone
script_gameobjectname bombzone
script_bombmode_original <if defined this bombzone will be used in the original bomb mode>
script_bombmode_single <if defined this bombzone will be used in the single bomb mode>
script_bombmode_dual <if defined this bombzone will be used in the dual bomb mode>
script_team Set to allies or axis. This is used to set which team a bombzone is used by in dual bomb mode.
script_label Set to A or B. This sets the letter shown on the compass in original mode.
This is a volume of space in which the bomb can planted. Must contain an origin brush.
Bomb:
classname trigger_lookat
targetname bombtrigger
script_gameobjectname bombzone
This should be a 16x16 unit trigger with an origin brush placed so that it's center lies on the bottom plane of the trigger.
Must be in the level somewhere. This is the trigger that is used when defusing a bomb.
It gets moved to the position of the planted bomb model.
Level script requirements
-------------------------
Team Definitions:
game["attackers"] = "allies";
game["defenders"] = "axis";
This sets which team is attacking and which team is defending. Attackers plant the bombs. Defenders protect the targets.
Exploder Effects:
Setting script_noteworthy on a bombzone trigger to an exploder group can be used to trigger additional effects.
*/
/*QUAKED mp_sd_spawn_attacker (0.0 1.0 0.0) (-16 -16 0) (16 16 72)
Attacking players spawn randomly at one of these positions at the beginning of a round.*/
/*QUAKED mp_sd_spawn_defender (1.0 0.0 0.0) (-16 -16 0) (16 16 72)
Defending players spawn randomly at one of these positions at the beginning of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 3, 0, 9 );
registerTimeLimitDvar( level.gameType, 2.5, 0, 1440 );
registerScoreLimitDvar( level.gameType, 1, 0, 500 );
registerRoundLimitDvar( level.gameType, 0, 0, 12 );
registerWinLimitDvar( level.gameType, 4, 0, 12 );
registerNumLivesDvar( level.gameType, 1, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.objectiveBased = true;
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onPlayerKilled = ::onPlayerKilled;
level.onDeadEvent = ::onDeadEvent;
level.onOneLeftEvent = ::onOneLeftEvent;
level.onTimeLimit = ::onTimeLimit;
level.onNormalDeath = ::onNormalDeath;
level.initGametypeAwards = ::initGametypeAwards;
game["dialog"]["gametype"] = "searchdestroy";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "obj_destroy";
game["dialog"]["defense_obj"] = "obj_defend";
}
onPrecacheGameType()
{
game["bomb_dropped_sound"] = "mp_war_objective_lost";
game["bomb_recovered_sound"] = "mp_war_objective_taken";
precacheShader("waypoint_bomb");
precacheShader("hud_suitcase_bomb");
precacheShader("waypoint_target");
precacheShader("waypoint_target_a");
precacheShader("waypoint_target_b");
precacheShader("waypoint_defend");
precacheShader("waypoint_defend_a");
precacheShader("waypoint_defend_b");
precacheShader("waypoint_defuse");
precacheShader("waypoint_defuse_a");
precacheShader("waypoint_defuse_b");
precacheShader("waypoint_escort");
/*
precacheShader("waypoint_target");
precacheShader("waypoint_target_a");
precacheShader("waypoint_target_b");
precacheShader("waypoint_defend");
precacheShader("waypoint_defend_a");
precacheShader("waypoint_defend_b");
precacheShader("waypoint_defuse");
precacheShader("waypoint_defuse_a");
precacheShader("waypoint_defuse_b");
*/
precacheString( &"MP_EXPLOSIVES_RECOVERED_BY" );
precacheString( &"MP_EXPLOSIVES_DROPPED_BY" );
precacheString( &"MP_EXPLOSIVES_PLANTED_BY" );
precacheString( &"MP_EXPLOSIVES_DEFUSED_BY" );
precacheString( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
precacheString( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
precacheString( &"MP_CANT_PLANT_WITHOUT_BOMB" );
precacheString( &"MP_PLANTING_EXPLOSIVE" );
precacheString( &"MP_DEFUSING_EXPLOSIVE" );
}
onStartGameType()
{
if ( !isDefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setClientNameMode( "manual_change" );
game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
game["strings"]["bomb_defused"] = &"MP_BOMB_DEFUSED";
precacheString( game["strings"]["target_destroyed"] );
precacheString( game["strings"]["bomb_defused"] );
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
setObjectiveText( game["attackers"], &"OBJECTIVES_SD_ATTACKER" );
setObjectiveText( game["defenders"], &"OBJECTIVES_SD_DEFENDER" );
if ( level.splitscreen )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_SD_ATTACKER" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_SD_DEFENDER" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_SD_ATTACKER_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_SD_DEFENDER_SCORE" );
}
setObjectiveHintText( game["attackers"], &"OBJECTIVES_SD_ATTACKER_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_SD_DEFENDER_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sd_spawn_attacker" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sd_spawn_defender" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = "sd";
allowed[1] = "bombzone";
allowed[2] = "blocker";
maps\mp\gametypes\_gameobjects::main(allowed);
maps\mp\gametypes\_rank::registerScoreInfo( "win", 2 );
maps\mp\gametypes\_rank::registerScoreInfo( "loss", 1 );
maps\mp\gametypes\_rank::registerScoreInfo( "tie", 1.5 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "plant", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 100 );
thread updateGametypeDvars();
thread bombs();
}
getSpawnPoint()
{
if(self.pers["team"] == game["attackers"])
spawnPointName = "mp_sd_spawn_attacker";
else
spawnPointName = "mp_sd_spawn_defender";
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( spawnPointName );
assert( spawnPoints.size );
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
return spawnpoint;
}
onSpawnPlayer()
{
self.isPlanting = false;
self.isDefusing = false;
self.isBombCarrier = false;
if ( level.multiBomb && !isDefined( self.carryIcon ) && self.pers["team"] == game["attackers"] && !level.bombPlanted )
{
if ( level.splitscreen )
{
self.carryIcon = createIcon( "hud_suitcase_bomb", 33, 33 );
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", 0, -78 );
self.carryIcon.alpha = 0.75;
}
else
{
self.carryIcon = createIcon( "hud_suitcase_bomb", 50, 50 );
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -90, -65 );
self.carryIcon.alpha = 0.75;
}
}
level notify ( "spawned_player" );
}
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
{
thread checkAllowSpectating();
}
checkAllowSpectating()
{
wait ( 0.05 );
update = false;
if ( !level.aliveCount[ game["attackers"] ] )
{
level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
update = true;
}
if ( !level.aliveCount[ game["defenders"] ] )
{
level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
update = true;
}
if ( update )
maps\mp\gametypes\_spectating::updateSpectateSettings();
}
sd_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
onDeadEvent( team )
{
if ( level.bombExploded || level.bombDefused )
return;
if ( team == "all" )
{
if ( level.bombPlanted )
sd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
else
sd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["attackers"] )
{
if ( level.bombPlanted )
return;
level thread sd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
level thread sd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
onOneLeftEvent( team )
{
if ( level.bombExploded || level.bombDefused )
return;
lastPlayer = getLastLivingPlayer( team );
lastPlayer thread giveLastOnTeamWarning();
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
team = victim.team;
if ( game["state"] == "postgame" && (victim.team == game["defenders"] || !level.bombPlanted) )
attacker.finalKill = true;
if ( victim.isPlanting )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
}
else if ( victim.isBombCarrier )
{
attacker incPlayerStat( "bombcarrierkills", 1 );
thread maps\mp\_matchdata::logKillEvent( lifeId, "carrying" );
}
else if ( victim.isDefusing )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
}
if ( attacker.isBombCarrier )
attacker incPlayerStat( "killsasbombcarrier", 1 );
}
giveLastOnTeamWarning()
{
self endon("death");
self endon("disconnect");
level endon( "game_ended" );
self waitTillRecoveredHealth( 3 );
otherTeam = getOtherTeam( self.pers["team"] );
level thread teamPlayerCardSplash( "callout_lastteammemberalive", self, self.pers["team"] );
level thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
level notify ( "last_alive", self );
self maps\mp\gametypes\_missions::lastManSD();
}
onTimeLimit()
{
sd_endGame( game["defenders"], game["strings"]["time_limit_reached"] );
}
updateGametypeDvars()
{
level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
level.bombTimer = dvarFloatValue( "bombtimer", 45, 1, 300 );
level.multiBomb = dvarIntValue( "multibomb", 0, 0, 1 );
}
bombs()
{
level.bombPlanted = false;
level.bombDefused = false;
level.bombExploded = false;
trigger = getEnt( "sd_bomb_pickup_trig", "targetname" );
if ( !isDefined( trigger ) )
{
error("No sd_bomb_pickup_trig trigger found in map.");
return;
}
visuals[0] = getEnt( "sd_bomb", "targetname" );
if ( !isDefined( visuals[0] ) )
{
error("No sd_bomb script_model found in map.");
return;
}
precacheModel( "prop_suitcase_bomb" );
visuals[0] setModel( "prop_suitcase_bomb" );
if ( !level.multiBomb )
{
level.sdBomb = maps\mp\gametypes\_gameobjects::createCarryObject( game["attackers"], trigger, visuals, (0,0,32) );
level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "friendly" );
level.sdBomb maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
level.sdBomb maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
level.sdBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
level.sdBomb maps\mp\gametypes\_gameobjects::setCarryIcon( "hud_suitcase_bomb" );
level.sdBomb.allowWeapons = true;
level.sdBomb.onPickup = ::onPickup;
level.sdBomb.onDrop = ::onDrop;
}
else
{
trigger delete();
visuals[0] delete();
}
level.bombZones = [];
bombZones = getEntArray( "bombzone", "targetname" );
for ( index = 0; index < bombZones.size; index++ )
{
trigger = bombZones[index];
visuals = getEntArray( bombZones[index].target, "targetname" );
bombZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,64) );
bombZone maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
bombZone maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
bombZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
bombZone maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
if ( !level.multiBomb )
bombZone maps\mp\gametypes\_gameobjects::setKeyObject( level.sdBomb );
label = bombZone maps\mp\gametypes\_gameobjects::getLabel();
bombZone.label = label;
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + label );
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + label );
bombZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
bombZone.onBeginUse = ::onBeginUse;
bombZone.onEndUse = ::onEndUse;
bombZone.onUse = ::onUsePlantObject;
bombZone.onCantUse = ::onCantUse;
bombZone.useWeapon = "briefcase_bomb_mp";
for ( i = 0; i < visuals.size; i++ )
{
if ( isDefined( visuals[i].script_exploder ) )
{
bombZone.exploderIndex = visuals[i].script_exploder;
break;
}
}
level.bombZones[level.bombZones.size] = bombZone;
bombZone.bombDefuseTrig = getent( visuals[0].target, "targetname" );
assert( isdefined( bombZone.bombDefuseTrig ) );
bombZone.bombDefuseTrig.origin += (0,0,-10000);
bombZone.bombDefuseTrig.label = label;
}
for ( index = 0; index < level.bombZones.size; index++ )
{
array = [];
for ( otherindex = 0; otherindex < level.bombZones.size; otherindex++ )
{
if ( otherindex != index )
array[ array.size ] = level.bombZones[otherindex];
}
level.bombZones[index].otherBombZones = array;
}
}
onBeginUse( player )
{
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
player playSound( "mp_bomb_defuse" );
player.isDefusing = true;
if ( isDefined( level.sdBombModel ) )
level.sdBombModel hide();
}
else
{
player.isPlanting = true;
if ( level.multibomb )
{
for ( i = 0; i < self.otherBombZones.size; i++ )
{
//self.otherBombZones[i] maps\mp\gametypes\_gameobjects::disableObject();
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::allowUse( "none" );
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
}
}
}
}
onEndUse( team, player, result )
{
if ( !isDefined( player ) )
return;
if ( isAlive( player ) )
{
player.isDefusing = false;
player.isPlanting = false;
}
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
if ( isDefined( level.sdBombModel ) && !result )
{
level.sdBombModel show();
}
}
else
{
if ( level.multibomb && !result )
{
for ( i = 0; i < self.otherBombZones.size; i++ )
{
//self.otherBombZones[i] maps\mp\gametypes\_gameobjects::enableObject();
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
self.otherBombZones[i] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
}
}
}
}
onCantUse( player )
{
player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
onUsePlantObject( player )
{
// planted the bomb
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
level thread bombPlanted( self, player );
//player logString( "bomb planted: " + self.label );
// disable all bomb zones except this one
for ( index = 0; index < level.bombZones.size; index++ )
{
if ( level.bombZones[index] == self )
continue;
level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
}
player playSound( "mp_bomb_plant" );
player notify ( "bomb_planted" );
//if ( !level.hardcoreMode )
// iPrintLn( &"MP_EXPLOSIVES_PLANTED_BY", player );
leaderDialog( "bomb_planted" );
level thread teamPlayerCardSplash( "callout_bombplanted", player );
level.bombOwner = player;
player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
player.bombPlantedTime = getTime();
maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
player incPlayerStat( "bombsplanted", 1 );
player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
}
}
onUseDefuseObject( player )
{
player notify ( "bomb_defused" );
//player logString( "bomb defused: " + self.label );
level thread bombDefused();
// disable this bomb zone
self maps\mp\gametypes\_gameobjects::disableObject();
//if ( !level.hardcoreMode )
// iPrintLn( &"MP_EXPLOSIVES_DEFUSED_BY", player );
leaderDialog( "bomb_defused" );
level thread teamPlayerCardSplash( "callout_bombdefused", player );
if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 3000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
else
player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
player incPlayerStat( "bombsdefused", 1 );
player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origin );
}
onDrop( player )
{
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
maps\mp\_utility::playSoundOnPlayers( game["bomb_dropped_sound"], game["attackers"] );
}
onPickup( player )
{
player.isBombCarrier = true;
player incPlayerStat( "bombscarried", 1 );
player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_escort" );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_escort" );
if ( !level.bombDefused )
{
teamPlayerCardSplash( "callout_bombtaken", player, player.team );
leaderDialog( "bomb_taken", player.pers["team"] );
}
maps\mp\_utility::playSoundOnPlayers( game["bomb_recovered_sound"], game["attackers"] );
}
onReset()
{
}
bombPlanted( destroyedObj, player )
{
maps\mp\gametypes\_gamelogic::pauseTimer();
level.bombPlanted = true;
destroyedObj.visuals[0] thread maps\mp\gametypes\_gamelogic::playTickingSound();
level.tickingObject = destroyedObj.visuals[0];
level.timeLimitOverride = true;
setGameEndTime( int( gettime() + (level.bombTimer * 1000) ) );
setDvar( "ui_bomb_timer", 1 );
if ( !level.multiBomb )
{
level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "none" );
level.sdBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
level.sdBomb maps\mp\gametypes\_gameobjects::setDropped();
level.sdBombModel = level.sdBomb.visuals[0];
}
else
{
for ( index = 0; index < level.players.size; index++ )
{
if ( isDefined( level.players[index].carryIcon ) )
level.players[index].carryIcon destroyElem();
}
trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000), false, player );
tempAngle = randomfloat( 360 );
forward = (cos( tempAngle ), sin( tempAngle ), 0);
forward = vectornormalize( forward - common_scripts\utility::vector_multiply( trace["normal"], vectordot( forward, trace["normal"] ) ) );
dropAngles = vectortoangles( forward );
level.sdBombModel = spawn( "script_model", trace["position"] );
level.sdBombModel.angles = dropAngles;
level.sdBombModel setModel( "prop_suitcase_bomb" );
}
destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" );
destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
/*
destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", undefined );
destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", undefined );
destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", undefined );
destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", undefined );
*/
label = destroyedObj maps\mp\gametypes\_gameobjects::getLabel();
// create a new object to defuse with.
trigger = destroyedObj.bombDefuseTrig;
trigger.origin = level.sdBombModel.origin;
visuals = [];
defuseObject = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,32) );
defuseObject maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
defuseObject maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
defuseObject maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
defuseObject maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
defuseObject maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
defuseObject maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" + label );
defuseObject maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" + label );
defuseObject maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" + label );
defuseObject maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" + label );
defuseObject.label = label;
defuseObject.onBeginUse = ::onBeginUse;
defuseObject.onEndUse = ::onEndUse;
defuseObject.onUse = ::onUseDefuseObject;
defuseObject.useWeapon = "briefcase_bomb_defuse_mp";
BombTimerWait();
setDvar( "ui_bomb_timer", 0 );
destroyedObj.visuals[0] maps\mp\gametypes\_gamelogic::stopTickingSound();
if ( level.gameEnded || level.bombDefused )
return;
level.bombExploded = true;
explosionOrigin = level.sdBombModel.origin;
level.sdBombModel hide();
if ( isdefined( player ) )
{
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player );
player incPlayerStat( "targetsdestroyed", 1 );
}
else
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
rot = randomfloat(360);
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
triggerFx( explosionEffect );
PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
earthquake( 0.75, 2.0, explosionOrigin, 2000 );
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
if ( isDefined( destroyedObj.exploderIndex ) )
exploder( destroyedObj.exploderIndex );
for ( index = 0; index < level.bombZones.size; index++ )
level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
defuseObject maps\mp\gametypes\_gameobjects::disableObject();
setGameEndTime( 0 );
wait 3;
sd_endGame( game["attackers"], game["strings"]["target_destroyed"] );
}
BombTimerWait()
{
level endon( "game_ended" );
level endon( "bomb_defused" );
maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( level.bombTimer );
}
bombDefused()
{
level.tickingObject maps\mp\gametypes\_gamelogic::stopTickingSound();
level.bombDefused = true;
setDvar( "ui_bomb_timer", 0 );
level notify("bomb_defused");
wait 1.5;
setGameEndTime( 0 );
sd_endGame( game["defenders"], game["strings"]["bomb_defused"] );
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
}
+447
View File
@@ -0,0 +1,447 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
VIP
Objective: Escort the VIP to safety, or eliminate the VIP beofore he reaches extraction
Map ends: When one team eliminates the enemy team, or the flag is reached
Respawning: Beginning of next round
Level requirementss
------------------
Spawnpoints:
classname mp_tdm_spawn
Spectator Spawnpoints:
classname mp_global_intermission
*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 500, 0, 5000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 1, 0, 10 );
registerWatchDvarInt( "halftime", 0 );
level.teamBased = true;
level.objectiveBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onNormalDeath = ::onNormalDeath;
level.onPlayerKilled = ::onPlayerKilled;
level.onDeadEvent = ::onDeadEvent;
game["dialog"]["gametype"] = "VIP";
}
onPrecacheGameType()
{
precacheShader( "compass_waypoint_captureneutral" );
precacheShader( "compass_waypoint_capture" );
precacheShader( "compass_waypoint_defend" );
precacheShader( "waypoint_captureneutral" );
precacheShader( "waypoint_capture" );
precacheShader( "waypoint_defend" );
precacheString( &"MP_ELIMINATED_VIP" );
precacheString( &"MP_DEFENDED_VIP" );
precacheString( &"SPLASHES_VIP" );
game["flagmodels"] = [];
game["flagmodels"]["neutral"] = "prop_flag_neutral";
game["flagmodels"]["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
game["flagmodels"]["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
precacheModel( game["flagmodels"]["neutral"] );
precacheModel( game["flagmodels"]["allies"] );
precacheModel( game["flagmodels"]["axis"] );
}
onStartGameType()
{
setClientNameMode("auto_change");
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setObjectiveText( "allies", &"OBJECTIVES_VIP" );
setObjectiveText( "axis", &"OBJECTIVES_VIP" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_VIP" );
setObjectiveScoreText( "axis", &"OBJECTIVES_VIP" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_VIP_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_VIP_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_VIP_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_VIP_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = "vip";
allowed[1] = "sd";
//maps\mp\gametypes\_rank::registerScoreInfo( "capture", 200 );
maps\mp\gametypes\_gameobjects::main(allowed);
self thread waitToProcess();
}
waitToProcess()
{
level endon( "game_end" );
level endon( "waitSkipped" );
self thread extractionZone();
self thread skipWait();
gameFlagWait( "prematch_done" );
gameFlagWait( "graceperiod_done" );
self notify( "graceComplete" );
self thread vipSelection();
}
skipWait()
{
self endon( "graceComplete" );
for(;;)
{
if( level.players.size > 2 )
break;
wait( .5 );
}
self notify( "waitSkipped" );
self thread vipSelection();
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + spawnteam + "_start" );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onSpawnPlayer()
{
self.isVip = false;
self.usingObj = undefined;
level notify ( "spawned_player" );
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
attacker maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( attacker.pers["team"], score );
team = victim.team;
if ( isDefined( victim.isVip ) && victim.isVip )
{
level thread vip_endGame( game["attackers"], &"MP_ELIMINATED_VIP" );
attacker.finalKill = true;
}
}
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
{
thread checkAllowSpectating();
}
onTimeLimit()
{
if ( game["status"] == "overtime" )
{
winner = "forfeit";
}
else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
{
winner = "overtime";
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
winner = "axis";
}
else
{
winner = "allies";
}
thread maps\mp\gametypes\_gamelogic::endGame( winner, game["strings"]["time_limit_reached"] );
}
checkAllowSpectating()
{
wait ( 0.05 );
update = false;
if ( !level.aliveCount[ game["attackers"] ] )
{
level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
update = true;
}
if ( !level.aliveCount[ game["defenders"] ] )
{
level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
update = true;
}
if ( update )
maps\mp\gametypes\_spectating::updateSpectateSettings();
}
onDeadEvent( team )
{
if ( team == game["attackers"] )
{
level thread vip_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
level thread vip_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
vip_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
vipSelection()
{
println( "SELECTION" );
potentialVIPs = [];
abortTime = 0;
for( ;; )
{
if ( level.players.size >= 2 )
break;
if ( abortTime >= 100 )
{
iPrintlnBold( "Game mode only playable with 2 or more players" );
wait( 2 );
maps\mp\gametypes\_callbacksetup::AbortLevel();
}
abortTime++;
wait( .1 );
}
foreach ( player in level.players )
{
if ( player.team == game["defenders"] )
potentialVIPs[ potentialVIPs.size ] = player;
}
selectedVIPNum = RandomIntRange( 0, potentialVIPs.size );
selectedPlayer = potentialVIPs[ selectedVIPNum ];
if ( !isAlive(selectedPlayer ) && !isSubStr( selectedPlayer.guid, "bot" ) )
selectedPlayer forceVIPSpawn();
setupVip( selectedPlayer );
}
setupVip ( vipPlayer )
{
vipPlayer TakeAllWeapons();
vipPlayer _clearPerks();
vipPlayer.isVip = true;
vipPlayer giveWeapon( "deserteagle_fmj_mp" );
vipPlayer giveStartAmmo( "deserteagle_fmj_mp" );
vipPlayer giveWeapon( "riotshield_mp" );
vipPlayer switchToWeapon( "riotshield_mp" );
vipPlayer _setPerk( "specialty_armorvest" );
vipPlayer _setPerk( "specialty_finalstand" );
vipPlayer iPrintlnBold( "You Are the VIP" );
//TO DO: add defend icon on the VIP
}
extractionZone()
{
extractionZone = getEntArray("extraction_vip", "targetname");
// check to see if zone is available.
if ( !isDefined( extractionZone ) )
{
println("WARNING: no extraction zone specified" );
printLn( "^1Not enough extraction zones found in level!" );
maps\mp\gametypes\_callbacksetup::AbortLevel();
return;
}
else
level.extractionZone = extractionZone;
trigger = level.extractionZone[0];
if ( isDefined( trigger.target ) )
{
visuals[0] = getEnt( trigger.target, "targetname" );
}
else
{
visuals[0] = spawn( "script_model", trigger.origin );
visuals[0].angles = trigger.angles;
}
extractionZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,100) );
extractionZone maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
extractionZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
extractionZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_CALLING_EXTRACTION" );
extractionZone maps\mp\gametypes\_gameobjects::setUseTime( 0 );
extractionZone.onUse = ::onUse;
extractionZone.onCantUse = ::onCantUse;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( game["defenders"] );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
extractionZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
extractionZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend");
extractionZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
level.extractionZone = extractionZone;
}
setVIPUse()
{
foreach (player in level.players)
{
if ( ! player.isVip )
self.trigger disablePlayerUse(player);
}
}
onUse( player )
{
if ( !isDefined( player.isVip ) || ! player.isVip )
{
return;
}
iPrintlnBold( "Extraction on its way" );
self handleTimer( player );
}
handleTimer( player )
{
player endon( "death" );
level endon( "game_end" );
level.extractionTime = 45;
maps\mp\gametypes\_gamelogic::pauseTimer();
level.timeLimitOverride = true;
setGameEndTime( int( getTime() + (level.extractionTime * 1000) ) );
wait level.extractionTime;
//call the sentry airdrops
level thread vip_endGame( game["defenders"], &"MP_DEFENDED_VIP" );
}
onEndUse( team, player, success )
{
println( "End Use" );
}
onCantUse( player )
{
// player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
spawnFxDelay( fxid, pos, forward, right, delay )
{
wait delay;
effect = spawnFx( fxid, pos, forward, right );
triggerFx( effect );
}
forceVIPSpawn()
{
self endon ( "death" );
self endon ( "disconnect" );
self endon ( "spawned" );
if ( self.hasSpawned )
return;
if ( !isValidClass( self.pers["class"] ) )
{
self.pers["class"] = "CLASS_CUSTOM1";
self.class = self.pers["class"];
}
self closeMenus();
self thread maps\mp\gametypes\_playerlogic::spawnClient();
}
+171
View File
@@ -0,0 +1,171 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
War
Objective: Score points for your team by eliminating players on the opposing team
Map ends: When one team reaches the score limit, or time limit is reached
Respawning: No wait / Near teammates
Level requirementss
------------------
Spawnpoints:
classname mp_tdm_spawn
All players spawn from these. The spawnpoint chosen is dependent on the current locations of teammates and enemies
at the time of spawn. Players generally spawn behind their teammates relative to the direction of enemies.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
*/
/*QUAKED mp_tdm_spawn (0.0 0.0 1.0) (-16 -16 0) (16 16 72)
Players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_tdm_spawn_axis_start (0.5 0.0 1.0) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_tdm_spawn_allies_start (0.0 0.5 1.0) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 500, 0, 5000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.teamBased = true;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onNormalDeath = ::onNormalDeath;
//level.onTimeLimit = ::onTimeLimit; // overtime not fully supported yet
game["dialog"]["gametype"] = "tm_death";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["strings"]["overtime_hint"] = &"MP_FIRST_BLOOD";
}
onStartGameType()
{
setClientNameMode("auto_change");
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setObjectiveText( "allies", &"OBJECTIVES_WAR" );
setObjectiveText( "axis", &"OBJECTIVES_WAR" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_WAR" );
setObjectiveScoreText( "axis", &"OBJECTIVES_WAR" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_WAR_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_WAR_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_WAR_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_WAR_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = level.gameType;
allowed[1] = "airdrop_pallet";
maps\mp\gametypes\_gameobjects::main(allowed);
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + spawnteam + "_start" );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
attacker maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( attacker.pers["team"], score );
if ( game["state"] == "postgame" && game["teamScores"][attacker.team] > game["teamScores"][level.otherTeam[attacker.team]] )
attacker.finalKill = true;
}
onTimeLimit()
{
if ( game["status"] == "overtime" )
{
winner = "forfeit";
}
else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
{
winner = "overtime";
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
winner = "axis";
}
else
{
winner = "allies";
}
thread maps\mp\gametypes\_gamelogic::endGame( winner, game["strings"]["time_limit_reached"] );
}