1421 lines
39 KiB
Plaintext
1421 lines
39 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\hud_util_shared;
|
|
#using scripts\shared\math_shared;
|
|
#using scripts\shared\medals_shared;
|
|
#using scripts\shared\popups_shared;
|
|
#using scripts\shared\scoreevents_shared;
|
|
#using scripts\shared\sound_shared;
|
|
#using scripts\shared\util_shared;
|
|
#using scripts\shared\weapons\_weapons;
|
|
|
|
|
|
|
|
#using scripts\mp\gametypes\_battlechatter;
|
|
#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\_spawning;
|
|
#using scripts\mp\gametypes\_spawnlogic;
|
|
|
|
#using scripts\mp\_challenges;
|
|
#using scripts\mp\_util;
|
|
#using scripts\mp\killstreaks\_rcbomb;
|
|
#using scripts\mp\killstreaks\_supplydrop;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#precache( "string", "OBJECTIVES_KOTH" );
|
|
#precache( "string", "OBJECTIVES_HQ" );
|
|
#precache( "string", "OBJECTIVES_HQ_SCORE" );
|
|
#precache( "string", "MP_WAITING_FOR_HQ" );
|
|
#precache( "string", "MP_HQ_CAPTURED_BY" );
|
|
#precache( "string", "MP_CONTROL_HQ" );
|
|
#precache( "string", "MP_CAPTURE_HQ" );
|
|
#precache( "string", "MP_DESTROY_HQ" );
|
|
#precache( "string", "MP_DEFEND_HQ" );
|
|
#precache( "string", "MP_HQ_AVAILABLE_IN" );
|
|
#precache( "string", "MP_HQ_DESPAWN_IN" );
|
|
#precache( "string", "MP_HQ_REINFORCEMENTS_IN" );
|
|
#precache( "string", "MP_CAPTURING_HQ" );
|
|
#precache( "string", "MP_DESTROYING_HQ" );
|
|
#precache( "eventstring", "objective" );
|
|
|
|
function main()
|
|
{
|
|
globallogic::init();
|
|
|
|
util::registerTimeLimit( 0, 1440 );
|
|
util::registerScoreLimit( 0, 1000 );
|
|
util::registerNumLives( 0, 100 );
|
|
util::registerRoundSwitch( 0, 9 );
|
|
util::registerRoundWinLimit( 0, 10 );
|
|
|
|
globallogic::registerFriendlyFireDelay( level.gameType, 15, 0, 1440 );
|
|
|
|
|
|
level.teamBased = true;
|
|
level.doPrematch = true;
|
|
level.overrideTeamScore = true;
|
|
level.scoreRoundWinBased = true;
|
|
level.onStartGameType =&onStartGameType;
|
|
level.playerSpawnedCB =&koth_playerSpawnedCB;
|
|
level.onRoundSwitch =&onRoundSwitch;
|
|
level.onPlayerKilled =&onPlayerKilled;
|
|
level.onEndGame=&onEndGame;
|
|
|
|
level.hqAutoDestroyTime = GetGametypeSetting( "autoDestroyTime" );
|
|
level.hqSpawnTime = GetGametypeSetting( "objectiveSpawnTime" );
|
|
level.kothMode = GetGametypeSetting( "kothMode" );
|
|
level.captureTime = GetGametypeSetting( "captureTime" );
|
|
level.destroyTime = GetGametypeSetting( "destroyTime" );
|
|
level.delayPlayer = GetGametypeSetting( "delayPlayer" );
|
|
level.randomHQSpawn = GetGametypeSetting( "randomObjectiveLocations" );
|
|
|
|
level.maxRespawnDelay = GetGametypeSetting( "timeLimit" ) * 60;
|
|
|
|
level.iconoffset = (0,0,32);
|
|
|
|
level.onRespawnDelay =&getRespawnDelay;
|
|
|
|
gameobjects::register_allowed_gameobject( level.gameType );
|
|
|
|
game["dialog"]["gametype"] = "hq_start";
|
|
game["dialog"]["gametype_hardcore"] = "hchq_start";
|
|
game["dialog"]["offense_obj"] = "cap_start";
|
|
game["dialog"]["defense_obj"] = "cap_start";
|
|
|
|
level.lastDialogTime = 0;
|
|
level.radioSpawnQueue = [];
|
|
|
|
// Sets the scoreboard columns and determines with data is sent across the network
|
|
if ( !SessionModeIsSystemlink() && !SessionModeIsOnlineGame() && IsSplitScreen() )
|
|
// local matches only show the first three columns
|
|
globallogic::setvisiblescoreboardcolumns( "score", "kills", "captures", "defends", "deaths" );
|
|
else
|
|
globallogic::setvisiblescoreboardcolumns( "score", "kills", "deaths", "captures", "defends" );
|
|
}
|
|
|
|
function updateObjectiveHintMessages( defenderTeam, defendMessage, attackMessage )
|
|
{
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( defenderTeam == team )
|
|
{
|
|
game["strings"]["objective_hint_" + team] = defendMessage;
|
|
}
|
|
else
|
|
{
|
|
game["strings"]["objective_hint_" + team] = attackMessage;
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateObjectiveHintMessage( message )
|
|
{
|
|
foreach( team in level.teams )
|
|
{
|
|
game["strings"]["objective_hint_" + team] = message;
|
|
}
|
|
}
|
|
|
|
function getRespawnDelay()
|
|
{
|
|
self.lowerMessageOverride = undefined;
|
|
|
|
if ( !isdefined( level.radio.gameobject ) )
|
|
return undefined;
|
|
|
|
hqOwningTeam = level.radio.gameobject gameobjects::get_owner_team();
|
|
if ( self.pers["team"] == hqOwningTeam )
|
|
{
|
|
if ( !isdefined( level.hqDestroyTime ) )
|
|
timeRemaining = level.maxRespawnDelay;
|
|
else
|
|
timeRemaining = (level.hqDestroyTime - gettime()) / 1000;
|
|
|
|
if (!level.playerObjectiveHeldRespawnDelay )
|
|
return undefined;
|
|
|
|
if ( level.playerObjectiveHeldRespawnDelay >= level.hqAutoDestroyTime )
|
|
self.lowerMessageOverride = &"MP_WAITING_FOR_HQ";
|
|
|
|
if ( level.delayPlayer )
|
|
{
|
|
return min( level.spawnDelay, timeRemaining );
|
|
}
|
|
else
|
|
{
|
|
return ceil(timeRemaining);
|
|
}
|
|
}
|
|
}
|
|
|
|
function onStartGameType()
|
|
{
|
|
if ( !isdefined( game["switchedsides"] ) )
|
|
game["switchedsides"] = false;
|
|
|
|
if ( game["switchedsides"] )
|
|
{
|
|
oldAttackers = game["attackers"];
|
|
oldDefenders = game["defenders"];
|
|
game["attackers"] = oldDefenders;
|
|
game["defenders"] = oldAttackers;
|
|
}
|
|
|
|
|
|
globallogic_score::resetTeamScores();
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
util::setObjectiveText( team, &"OBJECTIVES_KOTH" );
|
|
|
|
if ( level.splitscreen )
|
|
{
|
|
util::setObjectiveScoreText( team, &"OBJECTIVES_HQ" );
|
|
}
|
|
else
|
|
{
|
|
util::setObjectiveScoreText( team, &"OBJECTIVES_HQ_SCORE" );
|
|
}
|
|
}
|
|
|
|
level.objectiveHintPrepareHQ = &"MP_CONTROL_HQ";
|
|
level.objectiveHintCaptureHQ = &"MP_CAPTURE_HQ";
|
|
level.objectiveHintDestroyHQ = &"MP_DESTROY_HQ";
|
|
level.objectiveHintDefendHQ = &"MP_DEFEND_HQ";
|
|
|
|
if ( level.kothMode )
|
|
level.objectiveHintDestroyHQ = level.objectiveHintCaptureHQ;
|
|
|
|
if ( level.hqSpawnTime )
|
|
updateObjectiveHintMessage( level.objectiveHintPrepareHQ );
|
|
else
|
|
updateObjectiveHintMessage( level.objectiveHintCaptureHQ );
|
|
|
|
setClientNameMode("auto_change");
|
|
|
|
// now that the game objects have been deleted place the influencers
|
|
spawning::create_map_placed_influencers();
|
|
|
|
// TODO: HQ spawnpoints
|
|
level.spawnMins = ( 0, 0, 0 );
|
|
level.spawnMaxs = ( 0, 0, 0 );
|
|
foreach( team in level.teams )
|
|
{
|
|
spawnlogic::add_spawn_points( team, "mp_tdm_spawn" );
|
|
|
|
spawnlogic::place_spawn_points( spawning::getTDMStartSpawnName(team) );
|
|
}
|
|
|
|
spawning::updateAllSpawnPoints();
|
|
|
|
level.spawn_start = [];
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
level.spawn_start[ team ] = spawnlogic::get_spawnpoint_array( spawning::getTDMStartSpawnName(team) );
|
|
}
|
|
|
|
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_tdm_spawn" );
|
|
if ( !level.spawn_all.size )
|
|
{
|
|
/#
|
|
println("^1No mp_tdm_spawn spawnpoints in level!");
|
|
#/
|
|
callback::abort_level();
|
|
return;
|
|
}
|
|
|
|
|
|
thread SetupRadios();
|
|
|
|
thread HQMainLoop();
|
|
}
|
|
|
|
function spawn_first_radio(delay)
|
|
{
|
|
// pick next HQ object
|
|
if ( level.randomHQSpawn == 1 )
|
|
{
|
|
level.radio = GetNextRadioFromQueue();
|
|
}
|
|
else
|
|
{
|
|
level.radio = GetFirstRadio();
|
|
}
|
|
|
|
/#print("radio spawned: ("+level.radio.trigOrigin[0]+","+level.radio.trigOrigin[1]+","+level.radio.trigOrigin[2]+")");#/
|
|
|
|
level.radio spawning::enable_influencers(true);
|
|
|
|
return;
|
|
}
|
|
|
|
function spawn_next_radio()
|
|
{
|
|
// pick next HQ object
|
|
if ( level.randomHQSpawn != 0 )
|
|
{
|
|
level.radio = GetNextRadioFromQueue();
|
|
}
|
|
else
|
|
{
|
|
level.radio = GetNextRadio();
|
|
}
|
|
|
|
/#print("radio spawned: ("+level.radio.trigOrigin[0]+","+level.radio.trigOrigin[1]+","+level.radio.trigOrigin[2]+")");#/
|
|
|
|
level.radio spawning::enable_influencers(true);
|
|
|
|
return;
|
|
}
|
|
|
|
function HQMainLoop()
|
|
{
|
|
level endon("game_ended");
|
|
|
|
level.hqRevealTime = -100000;
|
|
|
|
hqSpawningInStr = &"MP_HQ_AVAILABLE_IN";
|
|
if ( level.kothMode )
|
|
{
|
|
hqDestroyedInFriendlyStr = &"MP_HQ_DESPAWN_IN";
|
|
hqDestroyedInEnemyStr = &"MP_HQ_DESPAWN_IN";
|
|
}
|
|
else
|
|
{
|
|
hqDestroyedInFriendlyStr = &"MP_HQ_REINFORCEMENTS_IN";
|
|
hqDestroyedInEnemyStr = &"MP_HQ_DESPAWN_IN";
|
|
}
|
|
|
|
spawn_first_radio();
|
|
|
|
objective_name = istring("objective");
|
|
|
|
while ( level.inPrematchPeriod )
|
|
{wait(.05);};
|
|
|
|
wait 5;
|
|
|
|
timerDisplay = [];
|
|
foreach ( team in level.teams )
|
|
{
|
|
timerDisplay[team] = hud::createServerTimer( "objective", 1.4, team );
|
|
timerDisplay[team] hud::setGamemodeInfoPoint();
|
|
timerDisplay[team].label = hqSpawningInStr;
|
|
timerDisplay[team].font = "small";
|
|
timerDisplay[team].alpha = 0;
|
|
timerDisplay[team].archived = false;
|
|
timerDisplay[team].hideWhenInMenu = true;
|
|
timerDisplay[team].hideWhenInKillcam = true;
|
|
timerDisplay[team].showplayerteamhudelemtospectator = true;
|
|
|
|
thread hideTimerDisplayOnGameEnd( timerDisplay[team] );
|
|
}
|
|
|
|
// locationObjID = gameobjects::get_next_obj_id();
|
|
|
|
// objective_add( locationObjID, "invisible", (0,0,0) );
|
|
|
|
while( 1 )
|
|
{
|
|
iPrintLn( &"MP_HQ_REVEALED" );
|
|
sound::play_on_players( "mp_suitcase_pickup" );
|
|
globallogic_audio::leader_dialog( "hq_located" );
|
|
// globallogic_audio::leader_dialog( "move_to_new" );
|
|
|
|
level.radio.gameobject gameobjects::set_model_visibility( true );
|
|
|
|
level.hqRevealTime = gettime();
|
|
|
|
rcbombs = GetEntArray( "rcbomb","targetname" );
|
|
radius = 75;
|
|
for( index = 0; index < rcbombs.size; index ++ )
|
|
{
|
|
if( DistanceSquared( rcbombs[index], level.radio.origin ) < radius * radius )
|
|
{
|
|
rcbombs[index] notify( "rcbomb_shutdown" );
|
|
}
|
|
}
|
|
|
|
if ( level.hqSpawnTime )
|
|
{
|
|
// nextObjPoint = objpoints::create( "objpoint_next_hq", level.radio.origin + level.iconoffset, "all", "waypoint_targetneutral" );
|
|
// nextObjPoint setWayPoint( true, "waypoint_targetneutral" );
|
|
// objective_position( locationObjID, level.radio.trigorigin );
|
|
// objective_icon( locationObjID, "waypoint_targetneutral" );
|
|
// objective_state( locationObjID, "active" );
|
|
|
|
level.radio.gameobject gameobjects::set_visible_team( "any" );
|
|
level.radio.gameobject gameobjects::set_flags( 1 );
|
|
|
|
updateObjectiveHintMessage( level.objectiveHintPrepareHQ );
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
timerDisplay[team].label = hqSpawningInStr;
|
|
timerDisplay[team] setTimer( level.hqSpawnTime );
|
|
timerDisplay[team].alpha = 1;
|
|
}
|
|
|
|
wait level.hqSpawnTime;
|
|
|
|
// objpoints::delete( nextObjPoint );
|
|
// objective_state( locationObjID, "invisible" );
|
|
level.radio.gameobject gameobjects::set_flags( 0 );
|
|
globallogic_audio::leader_dialog( "hq_online" );
|
|
}
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
timerDisplay[team].alpha = 0;
|
|
}
|
|
|
|
waittillframeend;
|
|
|
|
globallogic_audio::leader_dialog( "obj_capture" );
|
|
updateObjectiveHintMessage( level.objectiveHintCaptureHQ );
|
|
sound::play_on_players( "mpl_hq_cap_us" );
|
|
|
|
level.radio.gameobject gameobjects::enable_object();
|
|
level.radio.gameobject.onUpdateUseRate =&onUpdateUseRate;
|
|
|
|
level.radio.gameobject gameobjects::allow_use( "any" );
|
|
level.radio.gameobject gameobjects::set_use_time( level.captureTime );
|
|
level.radio.gameobject gameobjects::set_use_text( &"MP_CAPTURING_HQ" );
|
|
|
|
//objective_icon( locationObjID, "compass_waypoint_captureneutral" );
|
|
// level.radio.gameobject gameobjects::set_2d_icon( "enemy", "compass_waypoint_captureneutral" );
|
|
// level.radio.gameobject gameobjects::set_3d_icon( "enemy", "waypoint_captureneutral" );
|
|
level.radio.gameobject gameobjects::set_visible_team( "any" );
|
|
level.radio.gameobject gameobjects::set_model_visibility( true );
|
|
|
|
level.radio.gameobject.onUse =&onRadioCapture;
|
|
level.radio.gameobject.onBeginUse =&onBeginUse;
|
|
level.radio.gameobject.onEndUse =&onEndUse;
|
|
|
|
level waittill( "hq_captured" );
|
|
|
|
ownerTeam = level.radio.gameobject gameobjects::get_owner_team();
|
|
|
|
if ( level.hqAutoDestroyTime )
|
|
{
|
|
thread DestroyHQAfterTime( level.hqAutoDestroyTime, ownerTeam );
|
|
foreach( team in level.teams )
|
|
{
|
|
timerDisplay[team] setTimer( level.hqAutoDestroyTime );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
level.hqDestroyedByTimer = false;
|
|
}
|
|
|
|
while( 1 )
|
|
{
|
|
ownerTeam = level.radio.gameobject gameobjects::get_owner_team();
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
updateObjectiveHintMessages( ownerTeam, level.objectiveHintDefendHQ, level.objectiveHintDestroyHQ );
|
|
}
|
|
|
|
level.radio.gameobject gameobjects::allow_use( "enemy" );
|
|
// level.radio.gameobject gameobjects::set_2d_icon( "friendly", "compass_waypoint_defend" );
|
|
// level.radio.gameobject gameobjects::set_3d_icon( "friendly", "waypoint_defend" );
|
|
// level.radio.gameobject gameobjects::set_2d_icon( "enemy", "compass_waypoint_capture" );
|
|
// level.radio.gameobject gameobjects::set_3d_icon( "enemy", "waypoint_capture" );
|
|
|
|
if ( !level.kothMode )
|
|
level.radio.gameobject gameobjects::set_use_text( &"MP_DESTROYING_HQ" );
|
|
|
|
level.radio.gameobject.onUse =&onRadioDestroy;
|
|
|
|
if ( level.hqAutoDestroyTime )
|
|
{
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( team == ownerTeam )
|
|
timerDisplay[team].label = hqDestroyedInFriendlyStr;
|
|
else
|
|
timerDisplay[team].label = hqDestroyedInEnemyStr;
|
|
|
|
timerDisplay[team].alpha = 1;
|
|
}
|
|
}
|
|
|
|
level thread dropAllAroundHQ();
|
|
|
|
level waittill( "hq_destroyed", destroy_team );
|
|
|
|
level.radio spawning::enable_influencers(false);
|
|
|
|
if ( !level.kothMode || level.hqDestroyedByTimer )
|
|
break;
|
|
|
|
thread forceSpawnTeam( ownerTeam );
|
|
|
|
if ( isdefined( destroy_team ) )
|
|
{
|
|
level.radio.gameobject gameobjects::set_owner_team( destroy_team );
|
|
}
|
|
}
|
|
|
|
level.radio.gameobject gameobjects::disable_object();
|
|
level.radio.gameobject gameobjects::allow_use( "none" );
|
|
level.radio.gameobject gameobjects::set_owner_team( "neutral" );
|
|
level.radio.gameobject gameobjects::set_model_visibility( false );
|
|
|
|
level notify("hq_reset");
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
timerDisplay[team].alpha = 0;
|
|
}
|
|
|
|
spawn_next_radio();
|
|
|
|
wait .05;
|
|
|
|
thread forceSpawnTeam( ownerTeam );
|
|
|
|
wait 3.0;
|
|
}
|
|
}
|
|
|
|
|
|
function hideTimerDisplayOnGameEnd( timerDisplay )
|
|
{
|
|
level waittill("game_ended");
|
|
timerDisplay.alpha = 0;
|
|
}
|
|
|
|
|
|
function forceSpawnTeam( team )
|
|
{
|
|
players = level.players;
|
|
for ( i = 0; i < players.size; i++ )
|
|
{
|
|
player = players[i];
|
|
if ( !isdefined( player ) )
|
|
continue;
|
|
|
|
if ( player.pers["team"] == team )
|
|
{
|
|
player notify( "force_spawn" );
|
|
wait .1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function onBeginUse( player )
|
|
{
|
|
ownerTeam = self gameobjects::get_owner_team();
|
|
|
|
if ( ownerTeam == "neutral" )
|
|
{
|
|
// self.objPoints[player.pers["team"]] thread objpoints::start_flashing();
|
|
player thread battlechatter::gametype_specific_battle_chatter( "hq_protect", player.pers["team"] );
|
|
}
|
|
else
|
|
{
|
|
// foreach( team in level.teams )
|
|
// {
|
|
// self.objPoints[team] thread objpoints::start_flashing();
|
|
// }
|
|
player thread battlechatter::gametype_specific_battle_chatter( "hq_attack", player.pers["team"] );
|
|
}
|
|
}
|
|
|
|
|
|
function onEndUse( team, player, success )
|
|
{
|
|
// foreach( team in level.teams )
|
|
// {
|
|
// self.objPoints[team] thread objpoints::stop_flashing();
|
|
// }
|
|
player notify( "event_ended" );
|
|
}
|
|
|
|
|
|
function onRadioCapture( player )
|
|
{
|
|
capture_team = player.pers["team"];
|
|
|
|
/#print( "radio captured" );#/
|
|
|
|
string = &"MP_HQ_CAPTURED_BY";
|
|
|
|
level.useStartSpawns = false;
|
|
|
|
thread give_capture_credit( self.touchList[capture_team], string );
|
|
|
|
oldTeam = gameobjects::get_owner_team();
|
|
self gameobjects::set_owner_team( capture_team );
|
|
if ( !level.kothMode )
|
|
self gameobjects::set_use_time( level.destroyTime );
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( team == capture_team )
|
|
{
|
|
thread util::printOnTeamArg( &"MP_HQ_CAPTURED_BY", team, player );
|
|
globallogic_audio::leader_dialog( "hq_secured", team );
|
|
thread sound::play_on_players( "mp_war_objective_taken", team );
|
|
}
|
|
else
|
|
{
|
|
thread util::printOnTeam( &"MP_HQ_CAPTURED_BY_ENEMY", team );
|
|
globallogic_audio::leader_dialog( "hq_enemy_captured", team );
|
|
thread sound::play_on_players( "mp_war_objective_lost", team );
|
|
}
|
|
}
|
|
|
|
level thread awardHQPoints( capture_team );
|
|
|
|
level notify( "hq_captured" );
|
|
player notify( "event_ended" );
|
|
}
|
|
|
|
function give_capture_credit( touchList, string )
|
|
{
|
|
time = getTime();
|
|
wait .05;
|
|
util::WaitTillSlowProcessAllowed();
|
|
|
|
players = getArrayKeys( touchList );
|
|
for ( i = 0; i < players.size; i++ )
|
|
{
|
|
player_from_touchlist = touchList[players[i]].player;
|
|
player_from_touchlist challenges::capturedObjective( time, self ); // TODO: fix this when this game mode can be played, need to pass in the "trigger" not self which is the useObj
|
|
scoreevents::processScoreEvent( "hq_secure", player_from_touchlist );
|
|
player_from_touchlist RecordGameEvent("capture");
|
|
|
|
level thread popups::DisplayTeamMessageToAll( string, player_from_touchlist );
|
|
|
|
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 );
|
|
}
|
|
}
|
|
|
|
function dropAllToGround( origin, radius, stickyObjectRadius )
|
|
{
|
|
PhysicsExplosionSphere( origin, radius, radius, 0 );
|
|
{wait(.05);};
|
|
weapons::drop_all_to_ground( origin, radius );
|
|
// grenades are now done in code when an entity they were on gets deleted
|
|
// weapons::drop_grenades_to_ground( origin, radius );
|
|
supplydrop::dropCratesToGround( origin, radius );
|
|
level notify( "drop_objects_to_ground", origin, stickyObjectRadius );
|
|
}
|
|
|
|
function dropAllAroundHQ( radio )
|
|
{
|
|
origin = level.radio.origin;
|
|
level waittill( "hq_reset" );
|
|
dropAllToGround( origin, 100, 50 );
|
|
}
|
|
|
|
function onRadioDestroy( firstPlayer )
|
|
{
|
|
destroyed_team = firstPlayer.pers["team"];
|
|
|
|
touchList = self.touchList[destroyed_team];
|
|
|
|
touchListKeys = getArrayKeys( touchList );
|
|
foreach( index in touchListKeys )
|
|
{
|
|
player = touchList[index].player;
|
|
/#print( "radio destroyed" );#/
|
|
|
|
scoreevents::processScoreEvent( "hq_destroyed", player );
|
|
player RecordGameEvent("destroy");
|
|
player AddPlayerStatWithGameType( "DESTRUCTIONS", 1 );
|
|
|
|
if( isdefined(player.pers["destructions"]) )
|
|
{
|
|
player.pers["destructions"]++;
|
|
player.destructions = player.pers["destructions"];
|
|
}
|
|
}
|
|
|
|
destroyTeamMessage = &"MP_HQ_DESTROYED_BY";
|
|
otherTeamMessage = &"MP_HQ_DESTROYED_BY_ENEMY";
|
|
|
|
if ( level.kothMode )
|
|
{
|
|
destroyTeamMessage = &"MP_HQ_CAPTURED_BY";
|
|
otherTeamMessage = &"MP_HQ_CAPTURED_BY_ENEMY";
|
|
}
|
|
|
|
level thread popups::DisplayTeamMessageToAll( destroyTeamMessage, player );
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( team == destroyed_team )
|
|
{
|
|
thread util::printOnTeamArg( destroyTeamMessage, team, player );
|
|
globallogic_audio::leader_dialog( "hq_secured", team );
|
|
}
|
|
else
|
|
{
|
|
thread util::printOnTeam( otherTeamMessage, team );
|
|
globallogic_audio::leader_dialog( "hq_enemy_destroyed", team );
|
|
}
|
|
}
|
|
|
|
level notify( "hq_destroyed", destroyed_team );
|
|
|
|
if ( level.kothMode )
|
|
level thread awardHQPoints( destroyed_team );
|
|
|
|
player notify( "event_ended" );
|
|
}
|
|
|
|
|
|
function DestroyHQAfterTime( time, ownerTeam )
|
|
{
|
|
level endon( "game_ended" );
|
|
level endon( "hq_reset" );
|
|
|
|
level.hqDestroyTime = gettime() + time * 1000;
|
|
level.hqDestroyedByTimer = false;
|
|
|
|
wait time;
|
|
|
|
globallogic_audio::leader_dialog( "hq_offline" );
|
|
|
|
level.hqDestroyedByTimer = true;
|
|
checkPlayerCount( ownerTeam );
|
|
|
|
level notify( "hq_destroyed" );
|
|
}
|
|
|
|
function checkPlayerCount( ownerTeam )
|
|
{
|
|
lastPlayerAlive = undefined;
|
|
players = level.players;
|
|
|
|
for ( i = 0 ; i < players.size ; i++ )
|
|
{
|
|
if ( players[i].team != ownerTeam )
|
|
continue;
|
|
|
|
if ( IsAlive( players[i] ) )
|
|
{
|
|
if ( isdefined( lastPlayerAlive ) )
|
|
{
|
|
return; // more than one player alive
|
|
}
|
|
lastPlayerAlive = players[i];
|
|
}
|
|
}
|
|
if ( isdefined ( lastPlayerAlive ) )
|
|
{
|
|
scoreevents::processScoreEvent( "defend_hq_last_man_alive", lastPlayerAlive );
|
|
}
|
|
}
|
|
|
|
function awardHQPoints( team )
|
|
{
|
|
level endon( "game_ended" );
|
|
level endon( "hq_destroyed" );
|
|
|
|
level notify("awardHQPointsRunning");
|
|
level endon("awardHQPointsRunning");
|
|
|
|
seconds = 5;
|
|
|
|
while ( !level.gameEnded )
|
|
{
|
|
globallogic_score::giveTeamScoreForObjective( team, seconds );
|
|
for ( index = 0; index < level.players.size; index++ )
|
|
{
|
|
player = level.players[index];
|
|
|
|
if ( player.pers["team"] == team )
|
|
{
|
|
//scoreevents::processScoreEvent( "defend", player );
|
|
}
|
|
}
|
|
|
|
wait seconds;
|
|
}
|
|
}
|
|
|
|
function koth_playerSpawnedCB()
|
|
{
|
|
self.lowerMessageOverride = undefined;
|
|
}
|
|
|
|
function CompareRadioIndexes( radio_a, radio_b )
|
|
{
|
|
script_index_a = radio_a.script_index;
|
|
script_index_b = radio_b.script_index;
|
|
|
|
if( !isdefined(script_index_a) && !isdefined(script_index_b) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( !isdefined(script_index_a) && isdefined(script_index_b) )
|
|
{
|
|
/#
|
|
println( "KOTH: Missing script_index on radio at " + radio_a.origin );
|
|
#/
|
|
return true;
|
|
}
|
|
|
|
if( isdefined(script_index_a) && !isdefined(script_index_b) )
|
|
{
|
|
/#
|
|
println( "KOTH: Missing script_index on radio at " + radio_b.origin );
|
|
#/
|
|
return false;
|
|
}
|
|
|
|
if( script_index_a > script_index_b )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
function getRadioArray()
|
|
{
|
|
radios = getentarray( "hq_hardpoint", "targetname" );
|
|
|
|
if( !isdefined( radios ) )
|
|
{
|
|
return undefined;
|
|
}
|
|
|
|
swapped = true;
|
|
n = radios.size;
|
|
while ( swapped )
|
|
{
|
|
swapped = false;
|
|
for( i = 0 ; i < n-1 ; i++ )
|
|
{
|
|
if( CompareRadioIndexes(radios[i], radios[i+1]) )
|
|
{
|
|
temp = radios[i];
|
|
radios[i] = radios[i+1];
|
|
radios[i+1] = temp;
|
|
swapped = true;
|
|
}
|
|
}
|
|
n--;
|
|
}
|
|
return radios;
|
|
}
|
|
|
|
|
|
function SetupRadios()
|
|
{
|
|
maperrors = [];
|
|
|
|
radios = getRadioArray();
|
|
|
|
if ( radios.size < 2 )
|
|
{
|
|
maperrors[maperrors.size] = "There are not at least 2 entities with targetname \"radio\"";
|
|
}
|
|
|
|
trigs = getentarray("radiotrigger", "targetname");
|
|
for ( i = 0; i < radios.size; i++ )
|
|
{
|
|
errored = false;
|
|
|
|
radio = radios[i];
|
|
radio.trig = undefined;
|
|
for ( j = 0; j < trigs.size; j++ )
|
|
{
|
|
if ( radio istouching( trigs[j] ) )
|
|
{
|
|
if ( isdefined( radio.trig ) )
|
|
{
|
|
maperrors[maperrors.size] = "Radio at " + radio.origin + " is touching more than one \"radiotrigger\" trigger";
|
|
errored = true;
|
|
break;
|
|
}
|
|
radio.trig = trigs[j];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !isdefined( radio.trig ) )
|
|
{
|
|
if ( !errored )
|
|
{
|
|
maperrors[maperrors.size] = "Radio at " + radio.origin + " is not inside any \"radiotrigger\" trigger";
|
|
continue;
|
|
}
|
|
|
|
// possible fallback (has been tested)
|
|
//radio.trig = spawn( "trigger_radius", radio.origin, 0, 128, 128 );
|
|
//errored = false;
|
|
}
|
|
|
|
assert( !errored );
|
|
|
|
radio.trigorigin = radio.trig.origin;
|
|
|
|
visuals = [];
|
|
visuals[0] = radio;
|
|
|
|
otherVisuals = getEntArray( radio.target, "targetname" );
|
|
for ( j = 0; j < otherVisuals.size; j++ )
|
|
{
|
|
visuals[visuals.size] = otherVisuals[j];
|
|
}
|
|
|
|
objective_name = istring("objective");
|
|
|
|
radio setUpNodes();
|
|
|
|
radio.gameObject = gameobjects::create_use_object( "neutral", radio.trig, visuals, (radio.origin - radio.trigorigin), objective_name );
|
|
radio.gameObject gameobjects::disable_object();
|
|
radio.gameObject gameobjects::set_model_visibility( false );
|
|
radio.trig.useObj = radio.gameObject;
|
|
|
|
radio setUpNearbySpawns();
|
|
radio createRadioSpawnInfluencer();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
level.radios = radios;
|
|
|
|
level.prevradio = undefined;
|
|
level.prevradio2 = undefined;
|
|
|
|
return true;
|
|
}
|
|
|
|
function setUpNearbySpawns()
|
|
{
|
|
spawns = level.spawn_all;
|
|
|
|
for ( i = 0; i < spawns.size; i++ )
|
|
{
|
|
spawns[i].distsq = distanceSquared( spawns[i].origin, self.origin );
|
|
}
|
|
|
|
// sort by distsq
|
|
for ( i = 1; i < spawns.size; i++ )
|
|
{
|
|
thespawn = spawns[i];
|
|
for ( j = i - 1; j >= 0 && thespawn.distsq < spawns[j].distsq; j-- )
|
|
spawns[j + 1] = spawns[j];
|
|
spawns[j + 1] = thespawn;
|
|
}
|
|
|
|
first = [];
|
|
second = [];
|
|
third = [];
|
|
outer = [];
|
|
|
|
thirdSize = spawns.size / 3;
|
|
for ( i = 0; i <= thirdSize; i++ )
|
|
{
|
|
first[ first.size ] = spawns[i];
|
|
}
|
|
for ( ; i < spawns.size; i++ )
|
|
{
|
|
outer[ outer.size ] = spawns[i];
|
|
if ( i <= (thirdSize*2) )
|
|
second[ second.size ] = spawns[i];
|
|
else
|
|
third[ third.size ] = spawns[i];
|
|
}
|
|
|
|
self.gameObject.nearSpawns = first;
|
|
self.gameObject.midSpawns = second;
|
|
self.gameObject.farSpawns = third;
|
|
self.gameObject.outerSpawns = outer;
|
|
}
|
|
|
|
function setUpNodes()
|
|
{
|
|
self.points = [];
|
|
temp = spawn( "script_model", ( 0, 0, 0 ) );
|
|
|
|
maxs = self.trig GetPointInBounds( 1, 1, 1 );
|
|
self.node_radius = Distance( self.trig.origin, maxs );
|
|
|
|
points = util::PositionQuery_PointArray( self.trig.origin, 0, self.node_radius, 70, 128 );
|
|
|
|
foreach( point in points )
|
|
{
|
|
temp.origin = point;
|
|
|
|
if ( temp IsTouching( self.trig ) )
|
|
{
|
|
self.points[ self.points.size ] = point;
|
|
}
|
|
}
|
|
|
|
assert( self.points.size );
|
|
temp delete();
|
|
}
|
|
|
|
function GetFirstRadio()
|
|
{
|
|
radio = level.radios[ 0 ];
|
|
|
|
// old linear and "random" systems
|
|
level.prevradio2 = level.prevradio;
|
|
level.prevradio = radio;
|
|
level.prevRadioIndex = 0;
|
|
|
|
// new shuffled system
|
|
ShuffleRadios();
|
|
ArrayRemoveValue( level.radioSpawnQueue, radio );
|
|
|
|
return radio;
|
|
}
|
|
|
|
function GetNextRadio()
|
|
{
|
|
nextRadioIndex = (level.prevRadioIndex + 1) % level.radios.size;
|
|
radio = level.radios[ nextRadioIndex ];
|
|
level.prevradio2 = level.prevradio;
|
|
level.prevradio = radio;
|
|
level.prevRadioIndex = nextRadioIndex;
|
|
|
|
return radio;
|
|
}
|
|
|
|
function PickRandomRadioToSpawn()
|
|
{
|
|
level.prevRadioIndex = randomint( level.radios.size);
|
|
radio = level.radios[ level.prevRadioIndex ];
|
|
level.prevradio2 = level.prevradio;
|
|
level.prevradio = radio;
|
|
|
|
return radio;
|
|
}
|
|
|
|
function ShuffleRadios()
|
|
{
|
|
level.radioSpawnQueue = [];
|
|
|
|
spawnQueue = ArrayCopy(level.radios);
|
|
total_left = spawnQueue.size;
|
|
|
|
while( total_left > 0 )
|
|
{
|
|
index = randomint( total_left );
|
|
|
|
valid_radios = 0;
|
|
for( radio = 0; radio < level.radios.size; radio++ )
|
|
{
|
|
if ( !isdefined(spawnQueue[radio]) )
|
|
continue;
|
|
|
|
if ( valid_radios == index )
|
|
{
|
|
// dont allow the last radio from the previous shuffle to be put first in the next
|
|
if ( level.radioSpawnQueue.size == 0 && isdefined( level.radio ) && level.radio == spawnQueue[radio] )
|
|
continue;
|
|
|
|
level.radioSpawnQueue[level.radioSpawnQueue.size] = spawnQueue[radio];
|
|
spawnQueue[radio] = undefined;
|
|
break;
|
|
}
|
|
|
|
valid_radios++;
|
|
}
|
|
|
|
total_left--;
|
|
}
|
|
}
|
|
|
|
// shuffled picking
|
|
function GetNextRadioFromQueue()
|
|
{
|
|
if ( level.radioSpawnQueue.size == 0 )
|
|
ShuffleRadios();
|
|
|
|
assert( level.radioSpawnQueue.size > 0 );
|
|
|
|
next_radio = level.radioSpawnQueue[0];
|
|
ArrayRemoveIndex( level.radioSpawnQueue, 0 );
|
|
|
|
return next_radio;
|
|
}
|
|
|
|
function GetCountOfTeamsWithPlayers(num)
|
|
{
|
|
has_players = 0;
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( num[team] > 0 )
|
|
has_players++;
|
|
}
|
|
|
|
return has_players;
|
|
}
|
|
|
|
function GetPointCost( avgpos, origin )
|
|
{
|
|
avg_distance = 0;
|
|
total_error = 0;
|
|
distances = [];
|
|
|
|
foreach( team, position in avgpos )
|
|
{
|
|
distances[team] = Distance(origin, avgpos[team]);
|
|
avg_distance += distances[team];
|
|
}
|
|
|
|
avg_distance = avg_distance / distances.size;
|
|
|
|
foreach( team, dist in distances )
|
|
{
|
|
err = (distances[team] - avg_distance);
|
|
total_error += err * err;
|
|
}
|
|
|
|
return total_error;
|
|
}
|
|
|
|
function PickRadioToSpawn()
|
|
{
|
|
// find average of positions of each team
|
|
// (medians would be better, to get rid of outliers...)
|
|
// and find the radio which has the least difference in distance from those two averages
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
avgpos[team] = (0,0,0);
|
|
num[team] = 0;
|
|
}
|
|
|
|
for ( i = 0; i < level.players.size; i++ )
|
|
{
|
|
player = level.players[i];
|
|
if ( isalive( player ) )
|
|
{
|
|
avgpos[ player.pers["team"] ] += player.origin;
|
|
num[ player.pers["team"] ]++;
|
|
}
|
|
}
|
|
|
|
if ( GetCountOfTeamsWithPlayers(num) <= 1 )
|
|
{
|
|
radio = level.radios[ randomint( level.radios.size) ];
|
|
while ( isdefined( level.prevradio ) && radio == level.prevradio ) // so lazy
|
|
radio = level.radios[ randomint( level.radios.size) ];
|
|
|
|
level.prevradio2 = level.prevradio;
|
|
level.prevradio = radio;
|
|
|
|
return radio;
|
|
}
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( num[team] == 0 )
|
|
{
|
|
avgpos[team] = undefined;
|
|
}
|
|
else
|
|
{
|
|
avgpos[team] = avgpos[team] / num[team];
|
|
}
|
|
}
|
|
|
|
bestradio = undefined;
|
|
lowestcost = undefined;
|
|
for ( i = 0; i < level.radios.size; i++ )
|
|
{
|
|
radio = level.radios[i];
|
|
|
|
// (purposefully using distance instead of distanceSquared)
|
|
cost = GetPointCost( avgpos, radio.origin );
|
|
|
|
if ( isdefined( level.prevradio ) && radio == level.prevradio )
|
|
{
|
|
continue;
|
|
}
|
|
if ( isdefined( level.prevradio2 ) && radio == level.prevradio2 )
|
|
{
|
|
if ( level.radios.size > 2 )
|
|
continue;
|
|
else
|
|
cost += 512 * 512;
|
|
}
|
|
|
|
if ( !isdefined( lowestcost ) || cost < lowestcost )
|
|
{
|
|
lowestcost = cost;
|
|
bestradio = radio;
|
|
}
|
|
}
|
|
assert( isdefined( bestradio ) );
|
|
|
|
level.prevradio2 = level.prevradio;
|
|
level.prevradio = bestradio;
|
|
|
|
return bestradio;
|
|
}
|
|
|
|
function onRoundSwitch()
|
|
{
|
|
game["switchedsides"] = !game["switchedsides"];
|
|
}
|
|
|
|
|
|
function onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
|
|
{
|
|
if ( !isPlayer( attacker ) || (!self.touchTriggers.size && !attacker.touchTriggers.size) || attacker.pers["team"] == self.pers["team"] )
|
|
return;
|
|
|
|
medalGiven = false;
|
|
scoreEventProcessed = false;
|
|
|
|
if ( attacker.touchTriggers.size )
|
|
{
|
|
triggerIds = getArrayKeys( attacker.touchTriggers );
|
|
ownerTeam = attacker.touchTriggers[triggerIds[0]].useObj.ownerTeam;
|
|
|
|
team = attacker.pers["team"];
|
|
if ( team == ownerTeam || ownerTeam == "neutral" )
|
|
{
|
|
if ( !medalGiven )
|
|
{
|
|
if( isdefined(attacker.pers["defends"]) )
|
|
{
|
|
attacker.pers["defends"]++;
|
|
attacker.defends = attacker.pers["defends"];
|
|
}
|
|
|
|
attacker medals::defenseGlobalCount();
|
|
medalGiven = true;
|
|
attacker thread challenges::killedBaseDefender( attacker.touchTriggers[triggerIds[0]] );
|
|
attacker RecordGameEvent("return");
|
|
}
|
|
|
|
attacker challenges::killedZoneAttacker( weapon );
|
|
if (team != ownerTeam )
|
|
{
|
|
scoreevents::processScoreEvent( "kill_enemy_while_capping_hq", attacker, undefined, weapon );
|
|
}
|
|
else
|
|
{
|
|
scoreevents::processScoreEvent( "killed_attacker", attacker, undefined, weapon );
|
|
}
|
|
self RecordKillModifier("assaulting");
|
|
scoreEventProcessed = true;
|
|
}
|
|
else
|
|
{
|
|
if ( !medalGiven )
|
|
{
|
|
attacker medals::offenseGlobalCount();
|
|
medalGiven = true;
|
|
attacker thread challenges::killedBaseOffender( attacker.touchTriggers[triggerIds[0]], weapon );
|
|
}
|
|
scoreevents::processScoreEvent( "kill_enemy_while_capping_hq", attacker, undefined, weapon );
|
|
self RecordKillModifier("defending");
|
|
scoreEventProcessed = true;
|
|
}
|
|
}
|
|
|
|
if ( self.touchTriggers.size )
|
|
{
|
|
triggerIds = getArrayKeys( self.touchTriggers );
|
|
ownerTeam = self.touchTriggers[triggerIds[0]].useObj.ownerTeam;
|
|
|
|
team = self.pers["team"];
|
|
if ( team == ownerTeam )
|
|
{
|
|
if ( !medalGiven )
|
|
{
|
|
attacker medals::offenseGlobalCount();
|
|
attacker thread challenges::killedBaseOffender( self.touchTriggers[triggerIds[0]], weapon );
|
|
medalGiven = true;
|
|
}
|
|
if ( !scoreEventProcessed )
|
|
{
|
|
scoreevents::processScoreEvent( "killed_defender", attacker, undefined, weapon );
|
|
self RecordKillModifier("defending");
|
|
scoreEventProcessed = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !medalGiven )
|
|
{
|
|
if( isdefined(attacker.pers["defends"]) )
|
|
{
|
|
attacker.pers["defends"]++;
|
|
attacker.defends = attacker.pers["defends"];
|
|
}
|
|
|
|
attacker medals::defenseGlobalCount();
|
|
medalGiven = true;
|
|
attacker thread challenges::killedBaseDefender( self.touchTriggers[triggerIds[0]] );
|
|
attacker RecordGameEvent("return");
|
|
}
|
|
|
|
if ( !scoreEventProcessed )
|
|
{
|
|
attacker challenges::killedZoneAttacker( weapon );
|
|
scoreevents::processScoreEvent( "killed_attacker", attacker, undefined, weapon );
|
|
self RecordKillModifier("assaulting");
|
|
scoreEventProcessed = true;
|
|
}
|
|
}
|
|
|
|
if ( scoreEventProcessed == true )
|
|
{
|
|
attacker killWhileContesting( self.touchTriggers[triggerIds[0]].useObj );
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
function killWhileContesting( radio )
|
|
{
|
|
self notify( "killWhileContesting" );
|
|
self endon( "killWhileContesting" );
|
|
self endon( "disconnect" );
|
|
|
|
killTime = getTime();
|
|
playerteam = self.pers["team"];
|
|
if ( !isdefined ( self.clearEnemyCount ) )
|
|
{
|
|
self.clearEnemyCount = 0;
|
|
}
|
|
|
|
self.clearEnemyCount++;
|
|
|
|
radio waittill( "state_change" );
|
|
|
|
if (playerteam != self.pers["team"] || ( isdefined( self.spawntime ) && ( killTime < self.spawntime ) ) )
|
|
{
|
|
self.clearEnemyCount = 0;
|
|
return;
|
|
}
|
|
if ( radio.ownerTeam != playerteam && radio.ownerTeam != "neutral" )
|
|
{
|
|
self.clearEnemyCount = 0;
|
|
return;
|
|
}
|
|
|
|
if ( self.clearEnemyCount >= 2 && killTime + 200 > getTime() )
|
|
{
|
|
scoreevents::processScoreEvent( "clear_2_attackers", self );
|
|
}
|
|
self.clearEnemyCount = 0;
|
|
}
|
|
|
|
|
|
function onEndGame( winningTeam )
|
|
{
|
|
for ( i = 0; i < level.radios.size; i++ )
|
|
{
|
|
level.radios[i].gameobject gameobjects::allow_use( "none" );
|
|
}
|
|
}
|
|
|
|
function createRadioSpawnInfluencer()
|
|
{
|
|
// this affects both teams
|
|
self spawning::create_influencer( "hq_large", self.gameobject.curOrigin, 0 );
|
|
self spawning::create_influencer( "hq_small", self.gameobject.curOrigin, 0 );
|
|
|
|
// turn it off for now
|
|
self spawning::enable_influencers(false);
|
|
}
|
|
|
|
function onUpdateUseRate()
|
|
{
|
|
if ( !isdefined( self.currentContenderCount ) )
|
|
{
|
|
self.currentContenderCount = 0;
|
|
}
|
|
numOthers = gameobjects::get_num_touching_except_team( self.ownerteam ); // 0
|
|
numOwners = self.numTouching[self.ownerteam]; // 1
|
|
previousState = self.currentContenderCount;
|
|
|
|
if ( numOthers == 0 && numOwners == 0 )
|
|
{
|
|
self.currentContenderCount = 0;
|
|
}
|
|
else
|
|
{
|
|
if ( self.ownerteam == "neutral" )
|
|
{
|
|
numOtherClaim = gameobjects::get_num_touching_except_team( self.claimteam ); //1
|
|
|
|
if ( numOtherClaim > 0 )
|
|
{
|
|
self.currentContenderCount = 2;
|
|
}
|
|
else
|
|
{
|
|
self.currentContenderCount = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( numOthers > 0 )
|
|
{
|
|
self.currentContenderCount = 1;
|
|
}
|
|
else
|
|
{
|
|
self.currentContenderCount = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( self.currentContenderCount != previousState )
|
|
{
|
|
self notify( "state_change" );
|
|
}
|
|
} |