1 #using scripts\codescripts\struct;
3 #using scripts\shared\_oob;
4 #using scripts\shared\array_shared;
5 #using scripts\shared\audio_shared;
6 #using scripts\shared\challenges_shared;
7 #using scripts\shared\clientfield_shared;
8 #using scripts\shared\hostmigration_shared;
9 #using scripts\shared\hud_shared;
10 #using scripts\shared\killstreaks_shared;
11 #using scripts\shared\popups_shared;
12 #using scripts\shared\scoreevents_shared;
13 #using scripts\shared\tweakables_shared;
14 #using scripts\shared\util_shared;
15 #using scripts\shared\weapons\_flashgrenades;
16 #using scripts\shared\weapons\_weaponobjects;
17 #using scripts\shared\vehicle_shared;
18 #using scripts\shared\vehicle_death_shared;
20 #using scripts\mp\_challenges;
21 #using scripts\mp\_util;
22 #using scripts\mp\gametypes\_globallogic_audio;
23 #using scripts\mp\gametypes\_globallogic_utils;
24 #using scripts\mp\gametypes\_hostmigration;
25 #using scripts\mp\gametypes\_shellshock;
26 #using scripts\mp\gametypes\_spawning;
27 #using scripts\mp\killstreaks\_emp;
28 #using scripts\mp\killstreaks\_killstreak_bundles;
29 #using scripts\mp\killstreaks\_killstreak_detect;
30 #using scripts\mp\killstreaks\_killstreak_hacking;
31 #using scripts\mp\killstreaks\_killstreakrules;
32 #using scripts\mp\killstreaks\_killstreaks;
33 #using scripts\mp\killstreaks\_remote_weapons;
35 #insert scripts\mp\_hacker_tool.gsh;
36 #insert scripts\mp\killstreaks\_killstreaks.gsh;
37 #insert scripts\shared\shared.gsh;
38 #insert scripts\shared\version.gsh;
40 #precache( "string", "KILLSTREAK_EARNED_RCBOMB" );
41 #precache( "string", "KILLSTREAK_RCBOMB_NOT_AVAILABLE" );
42 #precache( "string", "KILLSTREAK_RCBOMB_INBOUND" );
43 #precache( "string", "KILLSTREAK_RCBOMB_HACKED" );
44 #precache( "string", "KILLSTREAK_DESTROYED_RCBOMB" );
45 #precache( "string", "mpl_killstreak_rcbomb" );
46 #precache( "fx", "_t6/weapon/grenade/fx_spark_disabled_rc_car" );
47 #precache( "fx", "killstreaks/fx_rcxd_lights_grn" );
48 #precache( "fx", "killstreaks/fx_rcxd_lights_red" );
49 #precache( "fx", "killstreaks/fx_rcxd_exp" );
53 #define RCBOMB_NAME "rcbomb"
54 #define RCBOMB_EMP_DEATH_HIDE_DELAY ( 0.2 )
55 #define RCBOMB_WATCH_DEATH_DURATION ( 0.3 )
59 level._effect[
"rcbombexplosion"] =
"killstreaks/fx_rcxd_exp";
63 killstreaks::register_dialog(
RCBOMB_NAME,
"mpl_killstreak_rcbomb",
"rcBombDialogBundle", undefined,
"friendlyRcBomb",
"enemyRcBomb",
"enemyRcBombMultiple",
"friendlyRcBombHacked",
"enemyRcBombHacked",
"requestRcBomb" );
80 rcbomb EnableAimAssist();
81 rcbomb SetDrawInfrared(
true );
82 rcbomb.delete_on_death =
true;
84 rcbomb.disableRemoteWeaponSwitch =
true;
85 rcbomb.overrideVehicleDamage = &
OnDamage;
86 rcbomb.overrideVehicleDeath = &
OnDeath;
88 rcbomb.watch_remote_weapon_death =
true;
91 if ( IsSentient( rcbomb ) ==
false )
92 rcbomb MakeSentient();
98 remote_controlled =
IS_TRUE(
self.control_initiated ) ||
IS_TRUE(
self.controlled );
100 if( remote_controlled )
103 if( notifyString ==
"remote_weapon_end" )
104 self waittill(
"rcbomb_shutdown" );
106 self waittill(
"remote_weapon_end" );
109 self waittill(
"rcbomb_shutdown" );
114 self notify(
"toggleLightsOnAfterTime_singleton");
115 self endon (
"toggleLightsOnAfterTime_singleton");
118 rcbomb endon(
"death" );
127 rcbomb.owner unlink();
130 rcbomb MakeVehicleUnusable();
137 rcbomb MakeVehicleUnusable();
151 assert( IsPlayer(
self ) );
159 if ( player UseButtonPressed() )
167 self iPrintLnBold( &
"KILLSTREAK_RCBOMB_NOT_PLACEABLE" );
177 rcbomb = SpawnVehicle(
RCBOMB_VEHICLE, placement.origin, placement.angles,
"rcbomb" );
181 rcbomb.damageTaken = 0;
182 rcbomb.abandoned =
false;
183 rcbomb.killstreak_id = killstreak_id;
184 rcbomb.activatingKillstreak =
true;
185 rcbomb SetInvisibleToAll();
192 rcbomb.ignore_vehicle_underneath_splash_scalar =
true;
195 self AddWeaponStat( GetWeapon(
"rcbomb" ) ,
"used", 1 );
199 if ( !isdefined( player ) || !isAlive( player ) ||
IS_TRUE( player.laststand ) || player IsEMPJammed() )
201 if ( isdefined( rcbomb ) )
203 rcbomb notify(
"remote_weapon_shutdown" );
204 rcbomb notify(
"rcbomb_shutdown" );
209 rcbomb SetVisibleToAll();
210 rcbomb.activatingKillstreak =
false;
211 Target_Set( rcbomb );
221 if ( rcbomb.health > rcbomb.hackedhealth )
223 rcbomb.health = rcbomb.hackedhealth;
232 rcbomb UseVehicle( player, 0 );
247 if ( exitrequestedbyowner ==
false )
249 rcbomb notify(
"rcbomb_shutdown" );
258 rcbomb endon(
"rcbomb_shutdown" );
259 rcbomb endon(
"death" );
261 while( !rcbomb.owner attackbuttonpressed() )
266 rcbomb notify(
"rcbomb_shutdown" );
269 #define RCBOMB_IN_WATER_TRACE_MINS ( -2, -2, -2 )
270 #define RCBOMB_IN_WATER_TRACE_MAXS ( 2, 2, 2 )
271 #define RCBOMB_IN_WATER_TRACE_MASK ( PHYSICS_TRACE_MASK_WATER )
272 #define RCBOMB_IN_WATER_TRACE_WAIT ( 0.5 )
276 self endon(
"rcbomb_shutdown" );
283 inWater =
trace[
"fraction"] < 1.0;
286 self.abandoned =
true;
287 self notify(
"rcbomb_shutdown" );
292 self notify(
"WatchOwnerGameEvents_singleton");
293 self endon (
"WatchOwnerGameEvents_singleton");
296 rcbomb endon(
"rcbomb_shutdown" );
300 rcbomb.abandoned =
true;
301 rcbomb notify(
"rcbomb_shutdown" );
313 rcbomb notify(
"rcbomb_shutdown" );
319 rcbomb endon(
"death" );
321 rcbomb waittill(
"rcbomb_shutdown" );
323 if ( isdefined( rcbomb.activatingKillstreak ) && rcbomb.activatingKillstreak )
327 rcbomb notify(
"rcbomb_shutdown" );
332 attacker = ( isdefined( rcbomb.owner ) ? rcbomb.owner : undefined );
333 rcbomb DoDamage( rcbomb.health + 1, rcbomb.origin + (0, 0, 10), attacker, attacker,
"none",
"MOD_EXPLOSIVE", 0 );
340 rcbomb endon(
"rcbomb_shutdown" );
344 rcbomb waittill (
"touch", ent );
345 if( isdefined( ent.classname ) && ( ent.classname ==
"trigger_hurt" || ent.classname ==
"trigger_out_of_bounds" ) )
347 rcbomb notify(
"rcbomb_shutdown" );
352 function OnDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
354 if (
self.activatingKillstreak )
359 if ( !isdefined( eAttacker ) || eAttacker !=
self.owner )
361 iDamage =
killstreaks::OnDamagePerWeapon(
RCBOMB_NAME, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon,
self.maxhealth, undefined,
self.maxhealth*0.4, undefined, 0, undefined,
true, 1.0 );
364 if( isdefined( eAttacker ) && isdefined( eAttacker.team ) && eAttacker.team !=
self.team )
368 self.damage_on_death =
false;
369 self.died_by_emp =
true;
370 iDamage =
self.health + 1;
376 if ( weapon.name ==
"satchel_charge" && sMeansOfDeath ==
"MOD_EXPLOSIVE" )
378 iDamage =
self.health + 1;
386 function OnDeath( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime )
389 player = rcbomb.owner;
391 player endon(
"disconnect" );
392 player endon(
"joined_team" );
393 player endon(
"joined_spectators" );
402 rcbomb
Explode( eAttacker, weapon );
405 if( isdefined( player ) )
419 if ( isdefined( rcbomb ) )
420 rcbomb notify(
"rcbomb_shutdown" );
426 rcbomb endon(
"death" );
428 level waittill(
"game_ended");
430 rcbomb.abandoned =
true;
431 rcbomb.selfDestruct =
true;
432 rcbomb notify(
"rcbomb_shutdown" );
437 self endon(
"death" );
440 self SetInvisibleToAll();
445 self endon (
"death");
448 if ( !isdefined( attacker ) && isdefined(
self.owner ) )
450 attacker =
self.owner;
462 self PlayRumbleOnEntity(
"rcbomb_explosion" );
464 if ( !
self.abandoned && attacker !=
self.owner && isPlayer( attacker ) )
470 LUINotifyEvent( &
"player_callout", 2, &
"KILLSTREAK_DESTROYED_RCBOMB", attacker.entnum );
471 if ( isdefined( weapon ) && weapon.isValid )
473 weaponStatName =
"destroyed";
474 level.globalKillstreaksDestroyed++;
476 weapon_rcbomb = GetWeapon(
"rcbomb" );
477 attacker AddWeaponStat( weapon_rcbomb,
"destroyed", 1 );
478 attacker AddWeaponStat( weapon,
"destroyed_controlled_killstreak", 1 );
488 if ( isdefined( eAttacker ) && eAttacker ==
self.owner )
491 if ( isdefined( eInflictor ) && eInflictor islinkedto(
self ) )
501 switch(
self GetStance() )
525 largestCountIndex = 0;
528 testangles[0] = (0,0,0);
529 testangles[1] = (0,20,0);
530 testangles[2] = (0,-20,0);
531 testangles[3] = (0,45,0);
532 testangles[4] = (0,-45,0);
536 for (i = 0; i < testangles.size; i++ )
538 testCheck[i] =
false;
540 startAngles[i] = ( 0, angles[1], 0 );
542 endPoint = startPoint - (0,0,100);
543 startPoint = startPoint + (0,0,startheight);
549 trace = physicstrace( startPoint, endPoint, mins, maxs,
self, mask);
552 if ( isdefined(
trace[
"entity"]) && IsPlayer(
trace[
"entity"]))
558 startPoints[i] =
trace[
"position"] + (0,0,heightoffset);
561 if ( positionWouldTelefrag( startPoints[i] ) )
564 if ( largestCount < wheelCounts[i] )
566 largestCount = wheelCounts[i];
567 largestCountIndex = i;
571 if ( wheelCounts[i] >= 3 )
577 placement = SpawnStruct();
578 placement.origin = startPoints[i];
579 placement.angles = startAngles[i];
585 for (i = 0; i < testangles.size; i++ )
589 if ( wheelCounts[i] >= 2 )
593 placement = SpawnStruct();
594 placement.origin = startPoints[i];
595 placement.angles = startAngles[i];
611 wheels[0] = ( forward, side, 0 );
612 wheels[1] = ( forward, -1 * side, 0 );
613 wheels[2] = ( -1 * forward, -1 * side, 0 );
614 wheels[3] = ( -1 * forward, side, 0 );
619 yawangles = (0,angles[1],0);
621 for (i = 0; i < 4; i++ )
623 wheel = RotatePoint( wheels[i], yawangles );
624 startPoint = origin + wheel;
625 endPoint = startPoint + (0,0,(-1 * height) - heightoffset);
626 startPoint = startPoint + (0,0,height - heightoffset) ;
628 trace = bulletTrace( startPoint, endPoint,
false,
self );
629 if (
trace[
"fraction"] < 1 )
640 liftedorigin = origin + (0,0,5);
643 mins = (-1 * size,-1 * size,0 );
644 maxs = ( size,size,height );
645 absmins = liftedorigin + mins;
646 absmaxs = liftedorigin + maxs;
648 if( BoundsWouldTelefrag( absmins, absmaxs ) )
653 startheight = getPlacementStartHeight();
659 trace = physicstrace( liftedorigin, (origin +(0,0,1)), mins, maxs,
self, mask);
661 if (
trace[
"fraction"] < 1 )
670 mins = (-1 * size,-1 * size,0 );
671 maxs = ( size,size,height );
673 sweeptrace = physicstrace( (
self.origin + (0,0,startheight)), liftedorigin, mins, maxs,
self, mask);
675 if ( sweeptrace[
"fraction"] < 1 )