2023-04-13 17:30:38 +02:00

1239 lines
37 KiB
Plaintext

#using scripts\shared\callbacks_shared;
#using scripts\shared\challenges_shared;
#using scripts\shared\demo_shared;
#using scripts\shared\gameobjects_shared;
#using scripts\shared\hostmigration_shared;
#using scripts\shared\math_shared;
#using scripts\shared\popups_shared;
#using scripts\shared\scoreevents_shared;
#using scripts\shared\util_shared;
#using scripts\mp\gametypes\_globallogic;
#using scripts\mp\gametypes\_globallogic_audio;
#using scripts\mp\gametypes\_globallogic_score;
#using scripts\mp\gametypes\_globallogic_utils;
#using scripts\mp\gametypes\_hostmigration;
#using scripts\mp\gametypes\_spawning;
#using scripts\mp\gametypes\_spawnlogic;
#using scripts\mp\_util;
/*
Bot Wars
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.
Level script requirements
-------------------------
Team Definitions:
game["allies"] = "marines";
game["axis"] = "nva";
This sets the nationalities of the teams. Allies can be american, british, or russian. Axis can be german.
If using minefields or exploders:
load::main();
Optional level script settings
------------------------------
Soldier Type and Variation:
game["american_soldiertype"] = "normandy";
game["german_soldiertype"] = "normandy";
This sets what character models are used for each nationality on a particular map.
Valid settings:
american_soldiertype normandy
british_soldiertype normandy, africa
russian_soldiertype coats, padded
german_soldiertype normandy, africa, winterlight, winterdark
*/
/*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_flag_a (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_flag_b (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_flag_c (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.*/
#precache( "material", "compass_waypoint_captureneutral" );
#precache( "material", "compass_waypoint_capture" );
#precache( "material", "compass_waypoint_defend" );
#precache( "material", "compass_waypoint_captureneutral_a" );
#precache( "material", "compass_waypoint_capture_a" );
#precache( "material", "compass_waypoint_defend_a" );
#precache( "material", "compass_waypoint_captureneutral_b" );
#precache( "material", "compass_waypoint_capture_b" );
#precache( "material", "compass_waypoint_defend_b" );
#precache( "material", "compass_waypoint_captureneutral_c" );
#precache( "material", "compass_waypoint_capture_c" );
#precache( "material", "compass_waypoint_defend_c" );
#precache( "string", "OBJECTIVES_DOM" );
#precache( "string", "OBJECTIVES_DOM_SCORE" );
#precache( "string", "OBJECTIVES_DOM_HINT" );
#precache( "string", "MP_CAPTURING_FLAG" );
#precache( "string", "MP_LOSING_FLAG" );
//#precache( "string", "MP_LOSING_LAST_FLAG" );
#precache( "string", "MP_DOM_YOUR_FLAG_WAS_CAPTURED" );
#precache( "string", "MP_DOM_ENEMY_FLAG_CAPTURED" );
#precache( "string", "MP_DOM_NEUTRAL_FLAG_CAPTURED" );
#precache( "string", "MP_ENEMY_FLAG_CAPTURED_BY" );
#precache( "string", "MP_NEUTRAL_FLAG_CAPTURED_BY" );
#precache( "string", "MP_FRIENDLY_FLAG_CAPTURED_BY" );
#precache( "string", "MP_DOM_FLAG_A_CAPTURED_BY" );
#precache( "string", "MP_DOM_FLAG_B_CAPTURED_BY" );
#precache( "string", "MP_DOM_FLAG_C_CAPTURED_BY" );
#precache( "string", "MP_DOM_FLAG_D_CAPTURED_BY" );
#precache( "string", "MP_DOM_FLAG_E_CAPTURED_BY" );
//#precache( "fx", "_t6/misc/fx_ui_flagbase_gold_t5" );//TODO T7 - contact FX team to get proper replacement
function main()
{
globallogic::init();
util::registerTimeLimit( 0, 1440 );
util::registerScoreLimit( 0, 1000 );
util::registerRoundLimit( 0, 10 );
util::registerRoundWinLimit( 0, 10 );
util::registerRoundSwitch( 0, 9 );
util::registerNumLives( 0, 100 );
globallogic::registerFriendlyFireDelay( level.gameType, 15, 0, 1440 );
level.scoreRoundWinBased = ( GetGametypeSetting( "cumulativeRoundScores" ) == false );
level.teamBased = false;
level.overrideTeamScore = true;
level.overridePlayerScore = true;
level.onStartGameType =&onStartGameType;
level.onPlayerKilled =&onPlayerKilled;
level.onRoundSwitch =&onRoundSwitch;
level.onPrecacheGameType =&onPrecacheGameType;
level.onEndGame=&onEndGame;
level.onRoundEndGame =&onRoundEndGame;
gameobjects::register_allowed_gameobject( "dom" );
game["dialog"]["gametype"] = "dom_start";
game["dialog"]["gametype_hardcore"] = "hcdom_start";
game["dialog"]["offense_obj"] = "cap_start";
game["dialog"]["defense_obj"] = "cap_start";
level.lastDialogTime = 0;
// Sets the scoreboard columns and determines with data is sent across the network
globallogic::setvisiblescoreboardcolumns( "score", "kills", "deaths" , "captures", "defends");
}
function onPrecacheGameType()
{
}
function onStartGameType()
{
util::setObjectiveText( "allies", &"OBJECTIVES_DOM" );
util::setObjectiveText( "axis", &"OBJECTIVES_DOM" );
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
if ( level.splitscreen )
{
util::setObjectiveScoreText( "allies", &"OBJECTIVES_DOM" );
util::setObjectiveScoreText( "axis", &"OBJECTIVES_DOM" );
}
else
{
util::setObjectiveScoreText( "allies", &"OBJECTIVES_DOM_SCORE" );
util::setObjectiveScoreText( "axis", &"OBJECTIVES_DOM_SCORE" );
}
util::setObjectiveHintText( "allies", &"OBJECTIVES_DOM_HINT" );
util::setObjectiveHintText( "axis", &"OBJECTIVES_DOM_HINT" );
level.flagBaseFXid = [];
level.flagBaseFXid[ "allies" ] = "_t6/misc/fx_ui_flagbase_gold_t5";//TODO T7 - contact FX team to get proper replacement
level.flagBaseFXid[ "axis" ] = "_t6/misc/fx_ui_flagbase_gold_t5";//TODO T7 - contact FX team to get proper replacement
setClientNameMode("auto_change");
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
spawnlogic::place_spawn_points( "mp_dom_spawn_allies_start" );
spawnlogic::place_spawn_points( "mp_dom_spawn_axis_start" );
level.mapCenter = math::find_box_center( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
spawnpoint = spawnlogic::get_random_intermission_point();
setDemoIntermissionPoint( spawnpoint.origin, spawnpoint.angles );
level.spawn_all = spawnlogic::get_spawnpoint_array( "mp_dom_spawn" );
level.spawn_axis_start = spawnlogic::get_spawnpoint_array( "mp_dom_spawn_axis_start" );
level.spawn_allies_start = spawnlogic::get_spawnpoint_array( "mp_dom_spawn_allies_start" );
flagSpawns = spawnlogic::get_spawnpoint_array( "mp_dom_spawn_flag_a" );
//assert( flagSpawns.size > 0 );
level.startPos["allies"] = level.spawn_allies_start[0].origin;
level.startPos["axis"] = level.spawn_axis_start[0].origin;
// now that the game objects have been deleted place the influencers
spawning::create_map_placed_influencers();
if ( !util::isOneRound() && level.scoreRoundWinBased )
{
globallogic_score::resetTeamScores();
}
updateGametypeDvars();
bwars_init();
level thread bwars_update_scores();
bwars_spawns_update();
}
function onEndGame( winningTeam )
{
}
function onRoundEndGame( roundWinner )
{
if ( level.scoreRoundWinBased )
{
[[level._setTeamScore]]( "allies", game["roundswon"]["allies"] );
[[level._setTeamScore]]( "axis", game["roundswon"]["axis"] );
}
axisScore = [[level._getTeamScore]]( "axis" );
alliedScore = [[level._getTeamScore]]( "allies" );
if ( axisScore == alliedScore )
{
winner = "tie";
}
else if ( axisScore > alliedScore )
{
winner = "axis";
}
else
{
winner = "allies";
}
return winner;
}
function updateGametypeDvars()
{
level.flagCaptureTime = GetGametypeSetting( "captureTime" );
level.flagCaptureLPM = math::clamp( GetDvarFloat( "maxFlagCapturePerMinute", 3 ), 0, 10 );
level.playerCaptureLPM = math::clamp( GetDvarFloat( "maxPlayerCapturePerMinute", 2 ), 0, 10 );
level.playerCaptureMax = math::clamp( GetDvarFloat( "maxPlayerCapture", 1000 ), 0, 1000 );
level.playerOffensiveMax = math::clamp( GetDvarFloat( "maxPlayerOffensive", 16 ), 0, 1000 );
level.playerDefensiveMax = math::clamp( GetDvarFloat( "maxPlayerDefensive", 16 ), 0, 1000 );
}
function bwars_init()
{
level.lastStatus["allies"] = 0;
level.lastStatus["axis"] = 0;
triggers = GetEntArray( "flag_primary", "targetname" );
if ( !triggers.size )
{
printLn( "^1Not enough domination flags found in level!" );
callback::abort_level();
return;
}
level.bwars_flags = [];
foreach( trigger in triggers )
{
visuals = trigger flag_model_init();
flag = gameobjects::create_use_object( "neutral", trigger, visuals, ( 0, 0, 100 ) );
Objective_Delete( flag.objIDAllies );
gameobjects::release_obj_id( flag.objIDAllies );
flag gameobjects::allow_use( "any" );
flag gameobjects::set_use_time( level.flagCaptureTime );
flag gameobjects::set_use_text( &"MP_CAPTURING_FLAG" );
flag gameobjects::set_visible_team( "any" );
flag flag_compass_init();
flag.onUse =&onUse;
flag.onBeginUse =&onBeginUse;
flag.onUseUpdate =&onUseUpdate;
flag.onEndUse =&onEndUse;
level.bwars_flags[ level.bwars_flags.size ] = flag;
}
}
function player_hud_init()
{
if ( isdefined( self.bwars_hud ) )
{
return;
}
self.bwars_hud = [];
x = -40;
y = 300;
for( i = 0; i < 4; i++ )
{
hud = NewClientHudElem( self );
hud.alignX = "left";
hud.alignY = "middle";
hud.foreground = 1;
hud.fontScale = 1.5;
hud.alpha = .8;
hud.x = x;
hud.y = y;
hud.hidewhendead = 1;
hud.hidewheninkillcam = 1;
hud.score = NewClientHudElem( self );
hud.score.alignX = "left";
hud.score.alignY = "middle";
hud.score.foreground = 1;
hud.score.fontScale = 1.5;
hud.score.alpha = .8;
hud.score.x = x + 125;
hud.score.y = y;
hud.score.hidewhendead = 1;
hud.score.hidewheninkillcam = 1;
self.bwars_hud[ self.bwars_hud.size ] = hud;
y += 15;
}
level bwars_scoreboard_update();
}
function player_hud_update( names, scores )
{
if ( !isdefined( self.bwars_hud ) )
{
return;
}
for( i = 0; i < 4; i++ )
{
self.bwars_hud[i] SetText( names[i] );
if ( names[i] == "" )
{
self.bwars_hud[i].score SetText( "" );
}
else
{
self.bwars_hud[i].score SetValue( scores[i] );
}
if ( names[i] == self.name )
{
self.bwars_hud[i].color = ( 1, 0.84, 0 );
self.bwars_hud[i].score.color = ( 1, 0.84, 0 );
}
else
{
self.bwars_hud[i].color = ( 1, 1, 1 );
self.bwars_hud[i].score.color = ( 1, 1, 1 );
}
}
}
function bubblesort_players()
{
players = GetPlayers();
while( true )
{
swapped = false;
for ( i = 1; i < players.size; i++ )
{
if ( players[i-1].score < players[i].score )
{
t = players[i-1];
players[i-1] = players[i];
players[i] = t;
swapped = true;
}
}
if ( !swapped )
{
break;
}
}
return players;
}
function bwars_scoreboard_update()
{
names = [];
scores = [];
players = bubblesort_players();
for( i = 0; i < 4; i++ )
{
if ( players.size > i )
{
names[i] = players[i].name;
scores[i] = players[i].score;
}
else
{
names[i] = "";
scores[i] = -1;
}
}
foreach( player in players )
{
player player_hud_update( names, scores );
}
}
function flag_model_init()
{
visuals = [];
visuals[0] = spawn( "script_model", self.origin );
visuals[0].angles = self.angles;
visuals[0] SetModel( "p7_mp_flag_neutral" );
visuals[0] SetInvisibleToAll();
visuals[1] = spawn( "script_model", self.origin );
visuals[1].angles = self.angles;
visuals[1] SetModel( "p7_mp_flag_neutral" );
visuals[1] SetVisibleToAll();
return visuals;
}
function flag_model_update()
{
owner = self gameobjects::get_owner_team();
self.visuals[0] SetModel( "p7_mp_flag_allies" );
self.visuals[0] SetInvisibleToAll();
self.visuals[0] SetVisibleToPlayer( owner );
self.visuals[1] SetModel( "p7_mp_flag_axis" );
self.visuals[1] SetVisibleToAll();
self.visuals[1] SetInvisibleToPlayer( owner );
}
function flag_compass_init()
{
self.compass_icons = [];
self.compass_icons[ 0 ] = gameobjects::get_next_obj_id();
self.compass_icons[ 1 ] = gameobjects::get_next_obj_id();
label = self gameobjects::get_label();
Objective_Add( self.compass_icons[ 0 ], "active", self.curOrigin );
Objective_Icon( self.compass_icons[ 0 ], "compass_waypoint_defend" + label );
Objective_SetInvisibleToAll( self.compass_icons[ 0 ] );
Objective_Add( self.compass_icons[ 1 ], "active", self.curOrigin );
Objective_Icon( self.compass_icons[ 1 ], "compass_waypoint_captureneutral" + label );
Objective_SetVisibleToAll( self.compass_icons[ 1 ] );
}
function flag_compass_update()
{
label = self gameobjects::get_label();
owner = self gameobjects::get_owner_team();
Objective_Icon( self.compass_icons[ 0 ], "compass_waypoint_defend" + label );
Objective_State( self.compass_icons[ 0 ], "active" );
Objective_SetInvisibleToAll( self.compass_icons[ 0 ] );
Objective_SetVisibleToPlayer( self.compass_icons[ 0 ], owner );
Objective_Icon( self.compass_icons[ 1 ], "compass_waypoint_capture" + label );
Objective_State( self.compass_icons[ 1 ], "active" );
Objective_SetVisibleToAll( self.compass_icons[ 1 ] );
Objective_SetInvisibleToPlayer( self.compass_icons[ 1 ], owner );
}
function player_world_icon_init()
{
if ( isdefined( self.bwars_icons ) )
{
return;
}
self.bwars_icons = [];
foreach( flag in level.bwars_flags )
{
icon = NewClientHudElem( self );
icon.flag = flag;
icon.x = flag.curOrigin[0];
icon.y = flag.curOrigin[1];
icon.z = flag.curOrigin[2] + 100;
icon.fadeWhenTargeted = true;
icon.archived = false;
icon.alpha = 1;
self.bwars_icons[ self.bwars_icons.size ] = icon;
}
self player_world_icon_update();
}
function player_world_icon_update()
{
assert( isdefined( self.bwars_icons ) );
foreach( icon in self.bwars_icons )
{
label = icon.flag gameobjects::get_label();
owner = icon.flag gameobjects::get_owner_team();
if ( IsString( owner ) && owner == "neutral" )
{
icon SetWaypoint( true, "waypoint_captureneutral" + label );
}
else if ( owner == self )
{
icon SetWaypoint( true, "waypoint_defend" + label );
}
else
{
icon SetWaypoint( true, "waypoint_capture" + label );
}
}
}
function world_icon_update()
{
players = GetPlayers();
foreach( player in players )
{
player player_world_icon_update();
}
}
function 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;
}
function onBeginUse( player )
{
}
function onUseUpdate( team, progress, change )
{
}
function statusDialog( dialog, team )
{
time = getTime();
if ( getTime() < level.lastStatus[team] + 6000 )
return;
thread delayedLeaderDialog( dialog, team );
level.lastStatus[team] = getTime();
}
function statusDialogEnemies( dialog, friend_team )
{
foreach ( team in level.teams )
{
if ( team == friend_team )
continue;
statusDialog( dialog, team );
}
}
function onEndUse( team, player, success )
{
}
function resetFlagBaseEffect()
{
/*
// once these get setup we never change them
if ( isdefined( self.baseeffect ) )
return;
team = self gameobjects::get_owner_team();
if ( team != "axis" && team != "allies" )
return;
fxid = level.flagBaseFXid[ team ];
self.baseeffect = spawnFx( fxid, self.baseeffectpos, self.baseeffectforward, self.baseeffectright );
triggerFx( self.baseeffect );
*/
}
function onUse( player )
{
self gameobjects::set_owner_team( player );
self gameobjects::allow_use( "enemy" );
self flag_compass_update();
self flag_model_update();
level world_icon_update();
level bwars_spawns_update();
// self resetFlagBaseEffect();
//level.useStartSpawns = false;
/*
string = &"";
switch ( label )
{
case "_a":
string = &"MP_DOM_FLAG_A_CAPTURED_BY";
break;
case "_b":
string = &"MP_DOM_FLAG_B_CAPTURED_BY";
break;
case "_c":
string = &"MP_DOM_FLAG_C_CAPTURED_BY";
break;
case "_d":
string = &"MP_DOM_FLAG_D_CAPTURED_BY";
break;
case "_e":
string = &"MP_DOM_FLAG_E_CAPTURED_BY";
break;
default:
break;
}
assert ( string != &"" );
// Copy touch list so there aren't any threading issues
touchList = [];
touchKeys = GetArrayKeys( self.touchList[team] );
for ( i = 0 ; i < touchKeys.size ; i++ )
touchList[touchKeys[i]] = self.touchList[team][touchKeys[i]];
thread give_capture_credit( touchList, string );
bbPrint( "mpobjective", "gametime %d objtype %s label %s team %s playerx %d playery %d playerz %d", gettime(), "dom_capture", label, team, player.origin );
if ( oldTeam == "neutral" )
{
thread util::printAndSoundOnEveryone( team, undefined, &"", &"", "mp_war_objective_taken", undefined, "" );
thread sound::play_on_players( "mus_dom_captured"+"_"+level.teamPostfix[team] );
if ( getTeamFlagCount( team ) == level.flags.size )
{
statusDialog( "secure_all", team );
statusDialogEnemies( "lost_all", team );
}
else
{
statusDialog( "secured"+self.label, team );
statusDialogEnemies( "lost"+self.label, team );
}
}
else
{
thread util::printAndSoundOnEveryone( team, oldTeam, &"", &"", "mp_war_objective_taken", "mp_war_objective_lost", "" );
// thread delayedLeaderDialogBothTeams( "obj_lost", oldTeam, "obj_taken", team );
// thread sound::play_on_players( "mus_dom_captured"+"_"+level.teamPostfix[team] );
if ( getTeamFlagCount( team ) == level.flags.size )
{
statusDialog( "secure_all", team );
statusDialog( "lost_all", oldTeam );
}
else
{
statusDialog( "secured"+self.label, team );
statusDialog( "lost"+self.label, oldTeam );
}
level.bestSpawnFlag[ oldTeam ] = self.levelFlag;
}
if ( dominated_challenge_check() )
{
challenges::dominated( team );
}
self update_spawn_influencers( team );
level dom::change_dom_spawns();
*/
}
function give_capture_credit( touchList, string )
{
wait .05;
util::WaitTillSlowProcessAllowed();
self updateCapsPerMinute();
players = getArrayKeys( touchList );
for ( i = 0; i < players.size; i++ )
{
player_from_touchlist = touchList[players[i]].player;
player_from_touchlist updateCapsPerMinute();
if ( !isScoreBoosting( player_from_touchlist, self ) )
{
//scoreevents::processScoreEvent( "position_secure", player_from_touchlist ); TFLAME 8/28 - We shouldn't need this event for bot wars
if( isdefined(player_from_touchlist.pers["captures"]) )
{
player_from_touchlist.pers["captures"]++;
player_from_touchlist.captures = player_from_touchlist.pers["captures"];
}
demo::bookmark( "event", gettime(), player_from_touchlist );
player_from_touchlist AddPlayerStatWithGameType( "CAPTURES", 1 );
}
level thread popups::DisplayTeamMessageToAll( string, player_from_touchlist );
}
}
function delayedLeaderDialog( sound, team )
{
wait .1;
util::WaitTillSlowProcessAllowed();
globallogic_audio::leader_dialog( sound, team );
}
function delayedLeaderDialogBothTeams( sound1, team1, sound2, team2 )
{
wait .1;
util::WaitTillSlowProcessAllowed();
// Eran: this function is missing.
// globallogic_audio::leaderdialogBothTeams( sound1, team1, sound2, team2 );
}
function bwars_update_scores()
{
while ( !level.gameEnded )
{
foreach( flag in level.bwars_flags )
{
owner = flag gameobjects::get_owner_team();
if ( IsPlayer( owner ) )
{
owner.score += 1;
}
}
level bwars_scoreboard_update();
players = GetPlayers();
foreach( player in players )
{
player globallogic::checkScoreLimit();
}
wait ( 5.0 );
hostmigration::waitTillHostMigrationDone();
}
}
function onRoundSwitch()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
game["switchedsides"] = !game["switchedsides"];
if ( level.cumulativeRoundScore == false )
{
[[level._setTeamScore]]( "allies", game["roundswon"]["allies"] );
[[level._setTeamScore]]( "axis", game["roundswon"]["axis"] );
}
}
function onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
{
}
function getTeamFlagCount( team )
{
score = 0;
for (i = 0; i < level.flags.size; i++)
{
if ( level.domFlags[i] gameobjects::get_owner_team() == team )
score++;
}
return score;
}
function getFlagTeam()
{
return self.useObj gameobjects::get_owner_team();
}
function 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 gameobjects::get_owner_team() != level.flags[i].adjflags[j].useObj gameobjects::get_owner_team() )
{
bflags[bflags.size] = level.flags[i];
break;
}
}
}
return bflags;
}
function 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;
}
function 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.
function 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
function 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;
}
function 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 = spawnlogic::get_spawnpoint_array( "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------------------------------------");
util::error("Map errors. See above");
#/
callback::abort_level();
return;
}
}
function createFlagSpawnInfluencers()
{
ss = level.spawnsystem;
for (flag_index = 0; flag_index < level.flags.size; flag_index++)
{
if ( level.domFlags[flag_index] == self )
break;
}
// domination: owned flag influencers
self.owned_flag_influencer = self spawning::create_influencer( "dom_friendly", self.trigger.origin, 0 );
// domination: un-owned inner flag influencers
self.neutral_flag_influencer = self spawning::create_influencer( "dom_neutral", self.trigger.origin, 0 );
// domination: enemy flag influencers
self.enemy_flag_influencer = self spawning::create_influencer( "dom_enemy", self.trigger.origin, 0 );
// default it to neutral
self update_spawn_influencers("neutral");
}
function update_spawn_influencers( team )
{
assert(isdefined(self.neutral_flag_influencer));
assert(isdefined(self.owned_flag_influencer));
assert(isdefined(self.enemy_flag_influencer));
if ( team == "neutral" )
{
EnableInfluencer(self.neutral_flag_influencer, true);
EnableInfluencer(self.owned_flag_influencer, false);
EnableInfluencer(self.enemy_flag_influencer, false);
}
else
{
EnableInfluencer(self.neutral_flag_influencer, false);
EnableInfluencer(self.owned_flag_influencer, true);
EnableInfluencer(self.enemy_flag_influencer, true);
SetInfluencerTeammask(self.owned_flag_influencer, util::getTeamMask(team) );
SetInfluencerTeammask(self.enemy_flag_influencer, util::getOtherTeamsMask(team) );
}
}
function bwars_spawns_update()
{
spawnlogic::clear_spawn_points();
spawnlogic::add_spawn_points( "axis", "mp_dom_spawn" );
spawnlogic::add_spawn_points( "allies", "mp_dom_spawn" );
spawning::updateAllSpawnPoints();
}
function dominated_challenge_check()
{
num_flags = level.flags.size;
allied_flags = 0;
axis_flags = 0;
for ( i = 0 ; i < num_flags ; i++ )
{
flag_team = level.flags[i] getFlagTeam();
if ( flag_team == "allies" )
{
allied_flags++;
}
else if ( flag_team == "axis" )
{
axis_flags++;
}
else
{
return false;
}
if ( ( allied_flags > 0 ) && ( axis_flags > 0 ) )
return false;
}
return true;
}
//This function checks to see if one team owns all three flags
function dominated_check()
{
num_flags = level.flags.size;
allied_flags = 0;
axis_flags = 0;
for ( i = 0 ; i < num_flags ; i++ )
{
flag_team = level.flags[i] getFlagTeam();
if ( flag_team == "allies" )
{
allied_flags++;
}
else if ( flag_team == "axis" )
{
axis_flags++;
}
if ( ( allied_flags > 0 ) && ( axis_flags > 0 ) )
return false;
}
return true;
}
function updateCapsPerMinute()
{
if ( !isdefined( self.capsPerMinute ) )
{
self.numCaps = 0;
self.capsPerMinute = 0;
}
self.numCaps++;
minutesPassed = globallogic_utils::getTimePassed() / ( 60 * 1000 );
// players use the actual time played
if ( IsPlayer( self ) && isdefined(self.timePlayed["total"]) )
minutesPassed = self.timePlayed["total"] / 60;
self.capsPerMinute = self.numCaps / minutesPassed;
if ( self.capsPerMinute > self.numCaps )
self.capsPerMinute = self.numCaps;
}
function isScoreBoosting( player, flag )
{
if ( !level.rankedMatch )
return false;
if ( player.capsPerMinute > level.playerCaptureLPM )
return true;
if ( flag.capsPerMinute > level.flagCaptureLPM )
return true;
if ( player.numCaps > level.playerCaptureMax )
return true;
return false;
}