1 #using scripts\shared\demo_shared;
2 #using scripts\shared\exploder_shared;
3 #using scripts\shared\gameobjects_shared;
4 #using scripts\shared\hostmigration_shared;
5 #using scripts\shared\hud_util_shared;
6 #using scripts\shared\math_shared;
7 #using scripts\shared\medals_shared;
8 #using scripts\shared\rank_shared;
9 #using scripts\shared\popups_shared;
10 #using scripts\shared\scoreevents_shared;
11 #using scripts\shared\sound_shared;
12 #using scripts\shared\util_shared;
13 #using scripts\mp\gametypes\_dogtags;
14 #using scripts\mp\gametypes\_globallogic_spawn;
16 #using scripts\shared\abilities\gadgets\_gadget_resurrect;
18 #insert scripts\shared\shared.gsh;
20 #using scripts\mp\gametypes\_battlechatter;
21 #using scripts\mp\gametypes\_globallogic;
22 #using scripts\mp\gametypes\_globallogic_audio;
23 #using scripts\mp\gametypes\_globallogic_defaults;
24 #using scripts\mp\gametypes\_globallogic_score;
25 #using scripts\mp\gametypes\_globallogic_utils;
26 #using scripts\mp\gametypes\_hostmigration;
27 #using scripts\mp\gametypes\_spawning;
28 #using scripts\mp\gametypes\_spawnlogic;
29 #using scripts\mp\gametypes\_spectating;
31 #using scripts\mp\_challenges;
32 #using scripts\mp\_util;
113 #define CARRY_ICON_X 130
114 #define CARRY_ICON_Y -60
116 #define OBJECTIVE_FLAG_DEFUSED 0
117 #define OBJECTIVE_FLAG_PLANTED 1
119 #precache( "fx", "explosions/fx_exp_bomb_demo_mp" );
120 #precache( "material","compass_waypoint_target" );
121 #precache( "material","compass_waypoint_target_a" );
122 #precache( "material","compass_waypoint_target_b" );
123 #precache( "material","compass_waypoint_defend" );
124 #precache( "material","compass_waypoint_defend_a" );
125 #precache( "material","compass_waypoint_defend_b" );
126 #precache( "material","compass_waypoint_defuse" );
127 #precache( "material","compass_waypoint_defuse_a" );
128 #precache( "material","compass_waypoint_defuse_b" );
129 #precache( "model", "p7_mp_suitcase_bomb" );
130 #precache( "objective", "sd_bomb" );
131 #precache( "objective", "sd_a" );
132 #precache( "objective", "sd_defuse_a" );
133 #precache( "objective", "sd_b" );
134 #precache( "objective", "sd_defuse_b" );
135 #precache( "string", "OBJECTIVES_SD_ATTACKER" );
136 #precache( "string", "OBJECTIVES_SD_DEFENDER" );
137 #precache( "string", "OBJECTIVES_SD_ATTACKER_SCORE" );
138 #precache( "string", "OBJECTIVES_SD_DEFENDER_SCORE" );
139 #precache( "string", "OBJECTIVES_SD_ATTACKER_HINT" );
140 #precache( "string", "OBJECTIVES_SD_DEFENDER_HINT" );
141 #precache( "string", "MP_EXPLOSIVES_BLOWUP_BY" );
142 #precache( "string", "MP_EXPLOSIVES_RECOVERED_BY" );
143 #precache( "string", "MP_EXPLOSIVES_DROPPED_BY" );
144 #precache( "string", "MP_EXPLOSIVES_PLANTED_BY" );
145 #precache( "string", "MP_EXPLOSIVES_DEFUSED_BY" );
146 #precache( "string", "PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
147 #precache( "string", "PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
148 #precache( "string", "MP_CANT_PLANT_WITHOUT_BOMB" );
149 #precache( "string", "MP_PLANTING_EXPLOSIVE" );
150 #precache( "string", "MP_DEFUSING_EXPLOSIVE" );
151 #precache( "string", "MP_TARGET_DESTROYED" );
152 #precache( "string", "MP_BOMB_DEFUSED" );
153 #precache( "string", "bomb" );
154 #precache( "triggerstring", "PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
155 #precache( "triggerstring", "PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
170 level.teamBased =
true;
171 level.overrideTeamScore =
true;
186 level.endGameOnScoreLimit =
false;
195 if ( !SessionModeIsSystemlink() && !SessionModeIsOnlineGame() && IsSplitScreen() )
204 game[
"bomb_dropped_sound"] =
"fly_bomb_drop_plr";
205 game[
"bomb_recovered_sound"] =
"fly_bomb_pickup_plr";
212 if ( ( isdefined(
self.isDefusing ) &&
self.isDefusing ) || ( isdefined(
self.isPlanting ) &&
self.isPlanting ) )
214 teamkill_penalty = teamkill_penalty * level.teamKillPenaltyMultiplier;
217 return teamkill_penalty;
224 if ( ( isdefined(
self.isDefusing ) &&
self.isDefusing ) || ( isdefined(
self.isPlanting ) &&
self.isPlanting ) )
226 teamkill_score = teamkill_score * level.teamKillScoreMultiplier;
229 return int(teamkill_score);
235 if ( !isdefined( game[
"switchedsides"] ) )
236 game[
"switchedsides"] =
false;
238 if ( game[
"teamScores"][
"allies"] == level.scorelimit - 1 && game[
"teamScores"][
"axis"] == level.scorelimit - 1 )
242 if ( aheadTeam != game[
"defenders"] )
244 game[
"switchedsides"] = !game[
"switchedsides"];
246 level.halftimeType =
"overtime";
250 level.halftimeType =
"halftime";
251 game[
"switchedsides"] = !game[
"switchedsides"];
259 deaths[
"allies"] = 0;
262 for ( i = 0; i < level.players.size; i++ )
264 player = level.players[i];
265 team = player.pers[
"team"];
266 if ( isdefined( team ) && (team ==
"allies" || team ==
"axis") )
268 kills[ team ] += player.kills;
269 deaths[ team ] += player.deaths;
273 if ( kills[
"allies"] > kills[
"axis"] )
275 else if ( kills[
"axis"] > kills[
"allies"] )
280 if ( deaths[
"allies"] < deaths[
"axis"] )
282 else if ( deaths[
"axis"] < deaths[
"allies"] )
287 if ( randomint(2) == 0 )
294 SetBombTimer(
"A", 0 );
295 SetMatchFlag(
"bomb_timer_a", 0 );
296 SetBombTimer(
"B", 0 );
297 SetMatchFlag(
"bomb_timer_b", 0 );
299 if ( !isdefined( game[
"switchedsides"] ) )
300 game[
"switchedsides"] =
false;
302 if ( game[
"switchedsides"] )
304 oldAttackers = game[
"attackers"];
305 oldDefenders = game[
"defenders"];
306 game[
"attackers"] = oldDefenders;
307 game[
"defenders"] = oldAttackers;
310 setClientNameMode(
"manual_change" );
312 game[
"strings"][
"target_destroyed"] = &
"MP_TARGET_DESTROYED";
313 game[
"strings"][
"bomb_defused"] = &
"MP_BOMB_DEFUSED";
315 level._effect[
"bombexplosion"] =
"explosions/fx_exp_bomb_demo_mp";
320 if ( level.splitscreen )
333 level.alwaysUseStartSpawns =
true;
338 level.spawnMins = ( 0, 0, 0 );
339 level.spawnMaxs = ( 0, 0, 0 );
344 setMapCenter( level.mapCenter );
347 setDemoIntermissionPoint( spawnpoint.origin, spawnpoint.angles );
350 level.spawn_start = [];
363 self.isPlanting =
false;
364 self.isDefusing =
false;
365 self.isBombCarrier =
false;
372 level notify (
"spawned_player" );
375 function onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
379 if(
IS_TRUE( level.droppedTagRespawn ) )
390 if ( isPlayer( attacker ) && attacker.pers[
"team"] !=
self.pers[
"team"])
397 for ( index = 0; index < level.bombZones.size; index++ )
399 dist = Distance2dSquared(
self.origin, level.bombZones[index].curorigin);
400 if ( dist < level.defaultOffenseRadiusSQ )
403 currentObjective = level.bombZones[index];
408 if ( inBombZone && isPlayer( attacker ) && attacker.pers[
"team"] !=
self.pers[
"team"] )
410 if ( game[
"defenders"] ==
self.pers[
"team"] )
414 self RecordKillModifier(
"defending");
419 if( isdefined(attacker.pers[
"defends"]) )
421 attacker.pers[
"defends"]++;
422 attacker.defends = attacker.pers[
"defends"];
427 self RecordKillModifier(
"assaulting");
432 if ( isPlayer( attacker ) && attacker.pers[
"team"] !=
self.pers[
"team"] && isdefined(
self.isBombCarrier ) &&
self.isBombCarrier ==
true )
434 self RecordKillModifier(
"carrying");
436 attacker RecordGameEvent(
"kill_carrier");
439 if(
self.isPlanting ==
true )
440 self RecordKillModifier(
"planting");
442 if(
self.isDefusing ==
true )
443 self RecordKillModifier(
"defusing");
449 self endon(
"disconnect");
455 livesLeft = !(level.numLives && !
self.pers[
"lives"]);
457 if ( !level.aliveCount[ game[
"attackers"] ] && !livesLeft )
459 level.spectateOverride[game[
"attackers"]].allowEnemySpectate = 1;
462 if ( !level.aliveCount[ game[
"defenders"] ] && !livesLeft )
464 level.spectateOverride[game[
"defenders"]].allowEnemySpectate = 1;
474 if ( isdefined( winningTeam ) )
488 if ( level.bombExploded || level.bombDefused )
493 if ( level.bombPlanted )
498 else if ( team == game[
"attackers"] )
500 if ( level.bombPlanted )
505 else if ( team == game[
"defenders"] )
514 if ( level.bombExploded || level.bombDefused )
524 if ( level.teamBased )
525 sd_endGame( game[
"defenders"], game[
"strings"][
"time_limit_reached"] );
527 sd_endGame( undefined, game[
"strings"][
"time_limit_reached"] );
533 if ( !isdefined( level.warnedLastPlayer ) )
534 level.warnedLastPlayer = [];
536 if ( isdefined( level.warnedLastPlayer[team] ) )
539 level.warnedLastPlayer[team] =
true;
541 players = level.players;
542 for ( i = 0; i < players.size; i++ )
546 if ( isdefined( player.pers[
"team"] ) && player.pers[
"team"] == team && isdefined( player.pers[
"class"] ) )
548 if ( player.sessionstate ==
"playing" && !player.afk )
553 if ( i == players.size )
565 self endon(
"disconnect");
570 self.lastManSD =
true;
572 enemyTeam = game[
"defenders"];
574 if ( team == enemyTeam )
576 enemyTeam = game[
"attackers"];
580 if ( level.aliveCount[enemyTeam] > 2 )
582 self.lastManSDDefeat3Enemies =
true;
588 if (
self.health !=
self.maxhealth )
591 fullHealthTime += interval;
595 if (
self.health ==
self.maxhealth && fullHealthTime >= 3)
600 self playlocalsound (
"mus_last_stand");
606 level.plantTime = GetGametypeSetting(
"plantTime" );
607 level.defuseTime = GetGametypeSetting(
"defuseTime" );
608 level.bombTimer = GetGametypeSetting(
"bombTimer" );
609 level.multiBomb = GetGametypeSetting(
"multiBomb" );
611 level.teamKillPenaltyMultiplier = GetGametypeSetting(
"teamKillPenalty" );
612 level.teamKillScoreMultiplier = GetGametypeSetting(
"teamKillScore" );
614 level.playerKillsMax = GetGametypeSetting(
"playerKillsMax" );
615 level.totalKillsMax = GetGametypeSetting(
"totalKillsMax" );
620 level.bombPlanted =
false;
621 level.bombDefused =
false;
622 level.bombExploded =
false;
624 trigger = getEnt(
"sd_bomb_pickup_trig",
"targetname" );
625 if ( !isdefined( trigger ) )
627 /#
util::error(
"No sd_bomb_pickup_trig trigger found in map.");#/
631 visuals[0] = getEnt(
"sd_bomb",
"targetname" );
632 if ( !isdefined( visuals[0] ) )
634 /#
util::error(
"No sd_bomb script_model found in map.");#/
640 if ( !level.multiBomb )
648 level.sdBomb.allowWeapons =
true;
652 foreach( visual
in level.sdBomb.visuals )
653 visual.team =
"free";
662 level.bombZones = [];
664 bombZones = getEntArray(
"bombzone",
"targetname" );
666 for ( index = 0; index < bombZones.size; index++ )
668 trigger = bombZones[index];
669 visuals = getEntArray( bombZones[index].target,
"targetname" );
671 name = istring(
"sd"+trigger.script_label);
678 if ( !level.multiBomb )
681 bombZone.label = label;
691 bombZone.useWeapon = GetWeapon(
"briefcase_bomb" );
692 bombZone.visuals[0].killCamEnt =
spawn(
"script_model", bombZone.visuals[0].origin + (0,0,128) );
694 if ( isdefined( level.bomb_zone_fixup ) )
695 [[ level.bomb_zone_fixup ]]( bombZone );
697 if ( !level.multiBomb )
698 bombZone.trigger SetInvisibleToAll();
700 for ( i = 0; i < visuals.size; i++ )
702 if ( isdefined( visuals[i].script_exploder ) )
704 bombZone.exploderIndex = visuals[i].script_exploder;
709 foreach( visual
in bombZone.visuals )
710 visual.team =
"free";
712 level.bombZones[level.bombZones.size] = bombZone;
714 bombZone.bombDefuseTrig = getent( visuals[0].target,
"targetname" );
715 assert( isdefined( bombZone.bombDefuseTrig ) );
716 bombZone.bombDefuseTrig.origin += (0,0,-10000);
717 bombZone.bombDefuseTrig.label = label;
720 for ( index = 0; index < level.bombZones.size; index++ )
723 for ( otherindex = 0; otherindex < level.bombZones.size; otherindex++ )
725 if ( otherindex != index )
728 level.bombZones[index].otherBombZones =
array;
734 self endon (
"death" );
735 self endon (
"disconnect" );
736 self endon (
"joined_team");
737 self endon (
"joined_spectators");
739 self waittill(
"weapon_change", weapon );
741 if ( weapon == useObject.useWeapon )
743 self SetWeaponOverheating( overheated, heat, weapon );
751 player playSound(
"mpl_sd_bomb_defuse" );
752 player.isDefusing =
true;
756 if ( isdefined( level.sdBombModel ) )
757 level.sdBombModel hide();
761 player.isPlanting =
true;
765 if ( level.multibomb )
767 for ( i = 0; i <
self.otherBombZones.size; i++ )
773 player playSound(
"fly_bomb_raise_plr" );
778 if ( !isdefined( player ) )
781 player.isDefusing =
false;
782 player.isPlanting =
false;
783 player notify(
"event_ended" );
787 if ( isdefined( level.sdBombModel ) && !
result )
789 level.sdBombModel show();
794 if ( level.multibomb && !
result )
796 for ( i = 0; i <
self.otherBombZones.size; i++ )
806 player iPrintLnBold( &
"MP_CANT_PLANT_WITHOUT_BOMB" );
816 /#print(
"bomb planted: " +
self.label );#/
819 for ( index = 0; index < level.bombZones.size; index++ )
821 if ( level.bombZones[index] ==
self )
823 level.bombZones[index].isPlanted =
true;
830 player notify (
"bomb_planted" );
834 if( isdefined(player.pers[
"plants"]) )
836 player.pers[
"plants"]++;
837 player.plants = player.pers[
"plants"];
841 player AddPlayerStatWithGameType(
"PLANTS", 1 );
846 player RecordGameEvent(
"plant");
853 player notify (
"bomb_defused" );
854 /#print(
"bomb defused: " +
self.label );#/
860 for ( index = 0; index < level.bombZones.size; index++ )
862 level.bombZones[index].isPlanted =
false;
867 if( isdefined(player.pers[
"defuses"]) )
869 player.pers[
"defuses"]++;
870 player.defuses = player.pers[
"defuses"];
873 player AddPlayerStatWithGameType(
"DEFUSES", 1 );
878 if ( player.lastManSD ===
true && level.aliveCount[ game[
"attackers"] ] > 0 )
881 player addplayerstat(
"defused_bomb_last_man_alive", 1 );
887 player RecordGameEvent(
"defuse");
893 if ( !level.bombPlanted )
897 if ( isdefined( player ) )
898 print(
"bomb dropped" );
900 print(
"bomb dropped" );
904 player notify(
"event_ended" );
910 if ( isdefined(level.bombDropBotEvent) )
912 [[level.bombDropBotEvent]]();
919 player.isBombCarrier =
true;
921 player RecordGameEvent(
"pickup");
925 if ( !level.bombDefused )
927 if ( isdefined( player ) && isdefined( player.name ) )
929 player AddPlayerStatWithGameType(
"PICKUPS", 1 );
938 /#print(
"bomb taken" );#/
941 player playsound (
"fly_bomb_pickup_plr" );
943 for ( i = 0; i < level.bombZones.size; i++ )
945 level.bombZones[i].trigger SetInvisibleToAll();
946 level.bombZones[i].trigger SetVisibleToPlayer( player );
949 if ( isdefined(level.bombPickupBotEvent) )
951 [[level.bombPickupBotEvent]]();
963 level endon (
"bomb_defused");
966 time = (level.bombtimer - 30);
977 level.bombPlanted =
true;
978 player SetWeaponOverheating(
true, 100, destroyedObj.useWeapon );
979 team = player.pers[
"team"];
985 level.tickingObject = destroyedObj.visuals[0];
987 level.timeLimitOverride =
true;
988 setGameEndTime(
int( gettime() + (level.bombTimer * 1000) ) );
991 SetMatchFlag(
"bomb_timer"+label, 1 );
994 SetBombTimer(
"A",
int( gettime() + level.bombTimer * 1000 ) );
995 SetMatchFlag(
"bomb_timer_a", 1 );
999 SetBombTimer(
"B",
int( gettime() + level.bombTimer * 1000 ) );
1000 SetMatchFlag(
"bomb_timer_b", 1 );
1004 if ( !level.multiBomb )
1009 level.sdBombModel = level.sdBomb.visuals[0];
1014 for ( index = 0; index < level.players.size; index++ )
1016 if ( isdefined( level.players[index].carryIcon ) )
1020 trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000),
false, player );
1022 tempAngle = randomfloat( 360 );
1023 forward = (cos( tempAngle ), sin( tempAngle ), 0);
1024 forward = vectornormalize( forward - VectorScale(
trace[
"normal"], vectordot( forward,
trace[
"normal"] ) ) );
1025 dropAngles = vectortoangles( forward );
1027 level.sdBombModel =
spawn(
"script_model",
trace[
"position"] );
1028 level.sdBombModel.angles = dropAngles;
1029 level.sdBombModel setModel(
"p7_mp_suitcase_bomb" );
1037 trigger = destroyedObj.bombDefuseTrig;
1038 trigger.origin = level.sdBombModel.origin;
1051 defuseObject.label = label;
1055 defuseObject.useWeapon = GetWeapon(
"briefcase_bomb_defuse" );
1057 player.isBombCarrier =
false;
1058 player PlayBombPlant();
1061 SetBombTimer(
"A", 0 );
1062 SetBombTimer(
"B", 0 );
1063 SetMatchFlag(
"bomb_timer_a", 0 );
1064 SetMatchFlag(
"bomb_timer_b", 0 );
1068 if ( level.gameEnded || level.bombDefused )
1071 level.bombExploded =
true;
1074 if ( isdefined( player ) )
1076 origin = player.origin;
1079 explosionOrigin = level.sdBombModel.origin+(0,0,12);
1080 level.sdBombModel hide();
1082 if ( isdefined( player ) )
1084 destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player,
"MOD_EXPLOSIVE", GetWeapon(
"briefcase_bomb" ) );
1087 player AddPlayerStatWithGameType(
"DESTRUCTIONS", 1 );
1088 player AddPlayerStatWithGameType(
"captures", 1 );
1089 player RecordGameEvent(
"destroy");
1092 destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, undefined,
"MOD_EXPLOSIVE", GetWeapon(
"briefcase_bomb" ) );
1094 rot = randomfloat(360);
1095 explosionEffect = spawnFx( level._effect[
"bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
1096 triggerFx( explosionEffect );
1100 if ( isdefined( destroyedObj.exploderIndex ) )
1104 foreach ( zone
in level.bombZones )
1107 setGameEndTime( 0 );
1111 sd_endGame( game[
"attackers"], game[
"strings"][
"target_destroyed"] );
1116 level endon(
"game_ended");
1117 level endon(
"bomb_defused");
1124 level.bombDefused =
true;
1125 player SetWeaponOverheating(
true, 100, defusedObject.useWeapon );
1126 SetBombTimer(
"A", 0 );
1127 SetBombTimer(
"B", 0 );
1128 SetMatchFlag(
"bomb_timer_a", 0 );
1129 SetMatchFlag(
"bomb_timer_b", 0 );
1131 player PlayBombDefuse();
1133 level notify(
"bomb_defused");
1138 setGameEndTime( 0 );
1140 sd_endGame( game[
"defenders"], game[
"strings"][
"bomb_defused"] );
1147 if ( level.playerKillsMax == 0 )
1150 if ( game[
"totalKills"] > ( level.totalKillsMax * (roundsPlayed + 1) ) )
1153 if (
self.kills > ( level.playerKillsMax * (roundsPlayed + 1)) )
1156 if ( level.teambased && (
self.team ==
"allies" ||
self.team ==
"axis" ))
1158 if ( game[
"totalKillsTeam"][
self.team] > ( level.playerKillsMax * (roundsPlayed + 1)) )
1167 if ( level.hardcoreMode && level.friendlyfire > 0 && isdefined( victim ) && ( victim.isPlanting ===
true || victim.isDefusing ===
true ) )
1172 return level.friendlyfire;