1 #using scripts\shared\callbacks_shared;
2 #using scripts\shared\clientfield_shared;
3 #using scripts\shared\flag_shared;
4 #using scripts\shared\gameobjects_shared;
5 #using scripts\shared\system_shared;
6 #using scripts\shared\util_shared;
7 #using scripts\shared\weapons\_tacticalinsertion;
8 #using scripts\shared\abilities\gadgets\_gadget_resurrect;
10 #insert scripts\shared\clientfields.gsh;
11 #insert scripts\shared\shared.gsh;
13 #using scripts\mp\gametypes\_spawnlogic;
15 #insert scripts\mp\gametypes\_spawning.gsh;
17 #using scripts\mp\_util;
18 #using scripts\mp\killstreaks\_airsupport;
19 #using scripts\mp\gametypes\_dogtags;
88 level.influencers = [];
89 level.recently_deceased= [];
91 foreach( team
in level.teams )
98 level.spawnProtectionTime = GetGametypeSetting(
"spawnprotectiontime" );
99 level.spawnProtectionTimeMS = int (
VAL( level.spawnProtectionTime, 0 ) * 1000 );
100 level.spawnTrapTriggerTime = GetGametypeSetting(
"spawntraptriggertime" );
107 level.spawnsystem = spawnstruct();
108 spawnsystem = level.spawnsystem;
110 if (!IsDefined( spawnsystem.sideSwitching ))
111 spawnsystem.sideSwitching = 1;
113 spawnsystem.objective_facing_bonus = 0.0;
115 spawnsystem.iSPAWN_TEAMMASK = [];
116 spawnsystem.iSPAWN_TEAMMASK_FREE = ( 1 << 0 );
117 spawnsystem.iSPAWN_TEAMMASK[
"free"] = spawnsystem.iSPAWN_TEAMMASK_FREE;
118 all = spawnsystem.iSPAWN_TEAMMASK_FREE;
120 foreach( team
in level.teams )
122 spawnsystem.iSPAWN_TEAMMASK[team] = ( 1 << count );
123 all = all | spawnsystem.iSPAWN_TEAMMASK[team];
126 spawnsystem.iSPAWN_TEAMMASK[
"all"] = all;
138 level endon (
"game_ended" );
154 self endon(
"disconnect" );
155 level endon (
"game_ended" );
159 self waittill(
"spawned_player" );
162 self airsupport::clearMonitoredSpeed();
167 if ( isdefined(
self.pers[
"hasRadar"] ) &&
self.pers[
"hasRadar"] )
169 self.hasSpyplane =
true;
186 self endon(
"disconnect" );
187 level endon (
"game_ended" );
189 self waittill (
"death" );
206 self endon(
"disconnect" );
207 level endon (
"game_ended" );
211 self waittill (
"joined_team" );
212 self.lastspawnpoint = undefined;
228 self endon(
"disconnect" );
229 level endon (
"game_ended" );
233 self waittill (
"grenade_fire", grenade, weapon );
241 if ( level.teambased )
247 team_mask = level.spawnsystem.iSPAWN_TEAMMASK_FREE;
255 if ( level.teambased )
261 team_mask = level.spawnsystem.iSPAWN_TEAMMASK_FREE;
269 self.influencers[
name] = AddInfluencer(
name, origin, team_mask );
273 return self.influencers[
name];
282 return self.influencersFriendly[
name];
291 return self.influencersEnemy[
name];
296 self.influencers[
name] = AddEntityInfluencer(
name,
self, team_mask );
300 return self.influencers[
name] ;
321 return self.influencersFriendly[
name];
328 return self.influencersEnemy[
name];
333 assert( !isdefined(
self.influencers) );
334 assert( !isdefined(
self.influencers) );
336 if ( !level.teambased )
338 team_mask = level.spawnsystem.iSPAWN_TEAMMASK_FREE;
339 enemy_teams_mask = level.spawnsystem.iSPAWN_TEAMMASK_FREE;
341 else if ( isdefined(
self.pers[
"team"] ) )
343 team =
self.pers[
"team"];
350 enemy_teams_mask = 0;
353 angles =
self.angles;
354 origin =
self.origin;
358 self.influencers = [];
359 self.friendlyInfluencers = [];
360 self.enemyInfluencers = [];
364 if ( level.teambased )
369 if ( !isdefined(
self.pers[
"team"]) ||
self.pers[
"team"] ==
"spectator" )
385 foreach ( influencer
in self.influencers )
387 if ( influencer == to_be_removed )
389 RemoveInfluencer( influencer );
391 ArrayRemoveValue(
self.influencers, influencer );
392 if ( IsDefined(
self.influencersFriendly ) )
394 ArrayRemoveValue(
self.influencersFriendly, influencer );
396 if ( IsDefined(
self.influencersEnemy ) )
398 ArrayRemoveValue(
self.influencersEnemy, influencer );
407 if ( isdefined(
self.influencers ) )
409 foreach ( influencer
in self.influencers )
411 RemoveInfluencer( influencer );
415 self.influencers = [];
416 if ( IsDefined(
self.influencersFriendly ) )
418 self.influencersFriendly = [];
420 if ( IsDefined(
self.influencersEnemy ) )
422 self.influencersEnemy = [];
430 self notify(
"watch_remove_influencer" );
431 self endon(
"watch_remove_influencer" );
433 self waittill(
"influencer_removed", index );
435 ArrayRemoveValue(
self.influencers, index );
436 if ( IsDefined(
self.influencersFriendly ) )
438 ArrayRemoveValue(
self.influencersFriendly, index );
440 if ( IsDefined(
self.influencersEnemy ) )
442 ArrayRemoveValue(
self.influencersEnemy, index );
451 foreach ( influencer
in self.influencers )
453 EnableInfluencer( influencer, enabled );
459 if (!isdefined(
self.influencers))
467 if ( !level.teambased )
469 team_mask = level.spawnsystem.iSPAWN_TEAMMASK_FREE;
470 enemy_teams_mask = level.spawnsystem.iSPAWN_TEAMMASK_FREE;
475 team =
self.pers[
"team"];
481 if ( isDefined(
self.influencersFriendly ) )
483 foreach ( influencer
in self.influencersFriendly )
485 SetInfluencerTeammask( influencer, team_mask );
488 if ( isDefined(
self.influencersEnemy ) )
490 foreach ( influencer
in self.influencersEnemy )
492 SetInfluencerTeammask( influencer, enemy_teams_mask );
499 spawn_influencer = weapon.spawnInfluencer;
501 if ( IsDefined( grenade.origin ) && spawn_influencer !=
"" )
503 if ( !level.teambased )
505 weapon_team_mask = level.spawnsystem.iSPAWN_TEAMMASK_FREE;
512 if ( level.friendlyfire )
524 staticInfluencerEnts = GetEntArray(
"mp_uspawn_influencer",
"classname" );
526 for ( i = 0; i < staticInfluencerEnts.size; i++ )
528 staticInfluencerEnt = staticInfluencerEnts[ i ];
538 if (isdefined(influencer_entity.script_noteworty))
545 assertmsg(
"Radiant-placed spawn influencers require the 'script_noteworty' parameter" );
548 return influencer_id;
554 foreach( team
in level.teams )
561 if ( level.teambased )
563 foreach( team
in level.teams )
571 foreach( team
in level.teams )
578 level.spawnAllMins = level.spawnMins;
579 level.spawnAllMaxs = level.spawnMaxs;
589 if ( !IsDefined( level.player_fallback_points ) )
592 if ( level.teambased )
594 foreach( team
in level.teams )
596 addSpawnPoints( team, level.player_fallback_points[ team ], SPL_FALLBACK );
601 foreach( team
in level.teams )
603 addSpawnPoints(
"free", level.player_fallback_points[ team ], SPL_FALLBACK );
610 if ( !IsDefined( level.player_fallback_points ) )
612 level.player_fallback_points = [];
614 foreach ( level_team
in level.teams )
616 level.player_fallback_points[level_team] = [];
624 if ( IsDefined( level.allowedGameObjects ) && level.convert_spawns_to_structs )
626 for ( i = spawnpoints.size - 1; i >= 0; i-- )
630 spawnpoints[i] = undefined;
633 ArrayRemoveValue( spawnpoints, undefined );
636 level.player_fallback_points[team] = spawnpoints;
643 if ( !level.rankedMatch )
646 if ( isDefined( level.aliveTimesAverage[team] ) && ( level.aliveTimesAverage[team] != 0 ) && ( level.aliveTimesAverage[team] < (level.spawnTrapTriggerTime * 1000) ) )
654 if ( level.alwaysUseStartSpawns )
657 if ( !level.useStartSpawns )
661 if( level.teambased )
663 spawnteam =
self.pers[
"team"];
665 if ( (level.alivePlayers[spawnteam].size + level.spawningPlayers[
self.team].size) >= level.spawn_start[spawnteam].size )
667 if ( !predictedSpawn )
669 level.useStartSpawns =
false;
674 else if ( (level.alivePlayers[
"free"].size + level.spawningPlayers[
"free"].size) >= level.spawn_start.size )
676 if ( !predictedSpawn )
678 level.useStartSpawns =
false;
691 if (!isdefined( predictedSpawn ))
692 predictedSpawn =
false;
697 spawn_origin = undefined;
698 spawn_angles = undefined;
700 if ( spawnResurrect )
702 spawn_origin =
self.resurrect_origin;
703 spawn_angles =
self.resurrect_angles;
705 else if ( spawnOverride )
707 if (predictedSpawn && isdefined(
self.tacticalInsertion ))
711 self predictSpawnPoint(
self.tacticalInsertion.origin,
self.tacticalInsertion.angles );
718 if ( !predictedSpawn )
720 if( level.teambased )
722 level.spawningPlayers[
self.team][level.spawningPlayers[
self.team].size] =
self;
726 level.spawningPlayers[
"free"][level.spawningPlayers[
"free"].size] =
self;
730 if( level.teambased )
732 spawnteam =
self.pers[
"team"];
733 if ( game[
"switchedsides"] )
743 if (isdefined(spawnpoint))
745 spawn_origin = spawnpoint.origin;
746 spawn_angles = spawnpoint.angles;
754 if (isdefined(spawn_point))
756 spawn_origin = spawn_point[
"origin"];
757 spawn_angles = spawn_point[
"angles"];
761 if ( !isdefined(spawn_origin) )
763 /# println(
"ERROR: unable to locate a usable spawn point for player"); #/
767 if ( predictedSpawn )
769 self predictSpawnPoint( spawn_origin, spawn_angles );
773 self spawn( spawn_origin, spawn_angles );
775 self.lastspawntime = gettime();
779 if ( !spawnResurrect && !spawnOverride )
785 if(
IS_TRUE( level.droppedTagRespawn ) )
795 if (!isdefined( predictedSpawn ))
796 predictedSpawn =
false;
798 if (level.teambased )
800 point_team = player_entity.pers[
"team"];
801 influencer_team = player_entity.pers[
"team"];
806 influencer_team =
"free";
811 if (level.teambased && isdefined(game[
"switchedsides"]) && game[
"switchedsides"] && level.spawnsystem.sideSwitching)
825 best_spawn =
get_best_spawnpoint( point_team, influencer_team, player_entity, predictedSpawn );
829 player_entity.last_spawn_origin = best_spawn[
"origin"];
837 if (level.teambased )
843 vis_team_mask = level.spawnsystem.iSPAWN_TEAMMASK[
"all"];
846 spawn_point = GetBestSpawnPoint( point_team, influencer_team, vis_team_mask, player, predictedSpawn );
854 if ( !isdefined( level.player_spawn_points ) )
856 level.player_spawn_points = [];
858 else if ( isdefined( level.player_spawn_points[ player_team ] ) )
864 if ( !isdefined(spawn_entities))
869 level.player_spawn_points[player_team] = spawn_entities;
880 return isdefined( level.hardcoreMode )
881 && level.hardcoreMode;
890 if ( !isdefined( team1 ) || !isdefined( team2 ) || (level.gameType==
"dm"))
893 return team1 !=
"neutral"
894 && team2 !=
"neutral"
903 if( level.convert_spawns_to_structs )
906 spawn_entity_types = [];
911 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dm_spawn";
914 spawn_entity_types[ spawn_entity_types.size ] =
"mp_tdm_spawn_allies_start";
915 spawn_entity_types[ spawn_entity_types.size ] =
"mp_tdm_spawn_axis_start";
916 spawn_entity_types[ spawn_entity_types.size ] =
"mp_tdm_spawn_team1_start";
917 spawn_entity_types[ spawn_entity_types.size ] =
"mp_tdm_spawn_team2_start";
918 spawn_entity_types[ spawn_entity_types.size ] =
"mp_tdm_spawn_team3_start";
919 spawn_entity_types[ spawn_entity_types.size ] =
"mp_tdm_spawn_team4_start";
920 spawn_entity_types[ spawn_entity_types.size ] =
"mp_tdm_spawn_team5_start";
921 spawn_entity_types[ spawn_entity_types.size ] =
"mp_tdm_spawn_team6_start";
922 spawn_entity_types[ spawn_entity_types.size ] =
"mp_tdm_spawn";
925 spawn_entity_types[ spawn_entity_types.size ] =
"mp_ctf_spawn_allies_start";
926 spawn_entity_types[ spawn_entity_types.size ] =
"mp_ctf_spawn_axis_start";
927 spawn_entity_types[ spawn_entity_types.size ] =
"mp_ctf_spawn_allies";
928 spawn_entity_types[ spawn_entity_types.size ] =
"mp_ctf_spawn_axis";
931 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dom_spawn_allies_start";
932 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dom_spawn_axis_start";
933 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dom_spawn_flag_a";
934 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dom_spawn_flag_b";
935 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dom_spawn_flag_c";
936 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dom_spawn";
942 spawn_entity_types[ spawn_entity_types.size ] =
"mp_sab_spawn_allies_start";
943 spawn_entity_types[ spawn_entity_types.size ] =
"mp_sab_spawn_axis_start";
944 spawn_entity_types[ spawn_entity_types.size ] =
"mp_sab_spawn_allies";
945 spawn_entity_types[ spawn_entity_types.size ] =
"mp_sab_spawn_axis";
948 spawn_entity_types[ spawn_entity_types.size ] =
"mp_sd_spawn_attacker";
949 spawn_entity_types[ spawn_entity_types.size ] =
"mp_sd_spawn_defender";
952 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dem_spawn_attacker_start";
953 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dem_spawn_defender_start";
954 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dem_spawn_attackerOT_start";
955 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dem_spawn_defenderOT_start";
956 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dem_spawn_attacker";
957 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dem_spawn_defender";
958 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dem_spawn_defender_a";
959 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dem_spawn_defender_b";
960 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dem_spawn_attacker_remove_a";
961 spawn_entity_types[ spawn_entity_types.size ] =
"mp_dem_spawn_attacker_remove_b";
964 for ( i = 0; i < spawn_entity_types.size; i++ )
977 for ( i = 0; i < spawnpoints.size; i++ )
979 spawnpoints[i]
delete();
985 if ( !isdefined( level.spawn_point_class_names ) )
990 for ( i = 0; i < level.spawn_point_class_names.size; i++ )
992 if ( level.spawn_point_class_names[i] ==
name )
1005 foreach( team
in level.teams )
1011 level.player_spawn_points = undefined;
1017 self endon(
"death" );
1018 self endon(
"disconnect" );
1022 if ( !isdefined( level.spawnProtectionTime ) || level.spawnProtectionTime == 0 )
1027 self.specialty_nottargetedbyairsupport =
true;
1029 self.ignoreme =
true;
1030 wait level.spawnProtectionTime;
1032 self.specialty_nottargetedbyairsupport = undefined;
1033 self.ignoreme =
false;
1038 spawn_point_team_name = team;
1040 if ( !level.multiTeam && game[
"switchedsides"] )
1044 if ( level.multiTeam )
1046 if ( team ==
"axis" )
1047 spawn_point_team_name =
"team1";
1048 else if ( team ==
"allies" )
1049 spawn_point_team_name =
"team2";
1055 number = int( getsubstr( spawn_point_team_name, 4, 5) ) - 1;
1058 number = (( number + game[
"roundsplayed" ]) % level.teams.size) + 1;
1060 spawn_point_team_name =
"team" + number;
1064 return spawnpointNameBase +
"_" + spawn_point_team_name +
"_start" ;