‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
gameobjects_shared.gsc
Go to the documentation of this file.
1 #using scripts\shared\callbacks_shared;
2 #using scripts\shared\hostmigration_shared;
3 #using scripts\shared\hud_util_shared;
4 #using scripts\shared\killstreaks_shared;
5 #using scripts\shared\math_shared;
6 #using scripts\shared\objpoints_shared;
7 #using scripts\shared\system_shared;
8 #using scripts\shared\trigger_shared;
9 #using scripts\shared\tweakables_shared;
10 #using scripts\shared\util_shared;
11 #using scripts\shared\weapons_shared;
12 
13 #insert scripts\shared\shared.gsh;
14 
15 #define CARRY_ICON_X 130
16 #define CARRY_ICON_Y -60
17 
18 #define MAX_OBJECTIVE_IDS 128
19 #define HIGHEST_OBJECTIVE_ID ( MAX_OBJECTIVE_IDS - 1 )
20 
21 #namespace gameobjects;
22 
23 ‪REGISTER_SYSTEM( "gameobjects", &‪__init__, undefined )
24 
25 function ‪__init__()
26 {
27  level.numGametypeReservedObjectives = 0;
28  level.releasedObjectives = [];
29 
33 }
34 
35 function ‪main()
36 {
37  level.vehiclesEnabled = GetGametypeSetting( "vehiclesEnabled" );
38  level.vehiclesTimed = GetGametypeSetting( "vehiclesTimed" );
39  level.objectivePingDelay = GetGametypeSetting( "objectivePingTime" );
40 
41  level.nonTeamBasedTeam = "allies";
42 
43  if ( !IsDefined( level.allowedGameObjects ) )
44  {
45  level.allowedGameObjects = [];
46  }
47 
48  if (level.vehiclesEnabled)
49  {
50  level.allowedGameObjects[level.allowedGameObjects.size]= "vehicle";
52  }
53 
54  entities= GetEntArray();
55  for (entity_index= entities.size-1; entity_index>=0; entity_index--)
56  {
57  entity= entities[entity_index];
58  if (!‪entity_is_allowed(entity, level.allowedGameObjects))
59  {
60  entity delete();
61  }
62  }
63 
64  return;
65 }
66 
67 function ‪register_allowed_gameobject( gameobject )
68 {
69  if ( !IsDefined( level.allowedGameObjects ) )
70  {
71  level.allowedGameObjects = [];
72  }
73 
74  level.allowedGameObjects[level.allowedGameObjects.size] = gameobject;
75 }
76 
78 {
79  level.allowedGameObjects = [];
80 }
81 
82 //bool
83 function ‪entity_is_allowed( entity, allowed_game_modes )
84 {
85  allowed= true;
86 
87  // is entity allowed for any of the give game modes?
88  if (isdefined(entity.script_gameobjectname) &&
89  entity.script_gameobjectname!="[all_modes]" )
90  {
91  allowed= false;
92  // allow a space-separated list of gameobjectnames
93  gameobjectnames= strtok(entity.script_gameobjectname, " ");
94  for (i= 0; i<allowed_game_modes.size && !allowed; i++)
95  {
96  for (j= 0; j<gameobjectnames.size && !allowed; j++)
97  {
98  allowed= (gameobjectnames[j]==allowed_game_modes[i]);
99  }
100  }
101  }
102 
103  return allowed;
104 }
105 
106 //bool
107 function ‪location_is_allowed( entity, location )
108 {
109  allowed = true;
110 
111  location_list = undefined;
112 
113  // Check if Location stored on Script_Noteworthy
114  //----------------------------------------------
115  if ( IsDefined( entity.script_noteworthy ) )
116  {
117  location_list = entity.script_noteworthy;
118  }
119 
120  // Check if Location stored on Script_Location, Takes Prescedence over Script_Noteworthy
121  //--------------------------------------------------------------------------------------
122  if ( IsDefined( entity.script_location ) )
123  {
124  location_list = entity.script_location;
125  }
126 
127  if ( IsDefined( location_list ) )
128  {
129  if ( location_list == "[all_modes]" )
130  {
131  allowed = true;
132  }
133  else
134  {
135  allowed = false;
136 
137  gameobjectlocations = StrTok( location_list, " " );
138 
139  for ( j = 0; j < gameobjectlocations.size; j++ )
140  {
141  if ( gameobjectlocations[ j ] == location )
142  {
143  allowed = true;
144  break;
145  }
146  }
147  }
148  }
149 
150  return allowed;
151 }
152 
153 // this function filters out script_vehicles (which are usually placed as prefabs)
154 // based on associated vehicle_descriptor objects
156  allowed_game_modes)
157 {
158  vehicle_descriptors= GetEntArray("vehicle_descriptor", "targetname");
159  script_vehicles= GetEntArray("script_vehicle", "classname");
160 
161  vehicles_to_remove= [];
162 
163  for (descriptor_index= 0; descriptor_index<vehicle_descriptors.size; descriptor_index++)
164  {
165  descriptor= vehicle_descriptors[descriptor_index];
166  closest_distance_sq= 1000000000000.0;
167  closest_vehicle= undefined;
168 
169  for (vehicle_index= 0; vehicle_index<script_vehicles.size; vehicle_index++)
170  {
171  vehicle= script_vehicles[vehicle_index];
172  dsquared= DistanceSquared(vehicle GetOrigin(), descriptor GetOrigin());
173  if (dsquared < closest_distance_sq)
174  {
175  closest_distance_sq= dsquared;
176  closest_vehicle= vehicle;
177  }
178  }
179 
180  if (isdefined(closest_vehicle))
181  {
182  if (!‪entity_is_allowed(descriptor, allowed_game_modes))
183  {
184  vehicles_to_remove[vehicles_to_remove.size]= closest_vehicle;
185  }
186  }
187  }
188 
189  for (vehicle_index= 0; vehicle_index<vehicles_to_remove.size; vehicle_index++)
190  {
191  vehicles_to_remove[vehicle_index] delete();
192  }
193 
194  return;
195 }
196 
197 
198 //=====================================================================================
199 // Callback functions
200 //=====================================================================================
202 {
203  self endon( "disconnect" );
204  level endon ( "game_ended" );
205 
206  self thread ‪on_death();
207  self.touchTriggers = [];
208  self.packObject = [];
209  self.packIcon = [];
210  self.carryObject = undefined;
211  self.claimTrigger = undefined;
212  self.canPickupObject = true;
213  self.disabledWeapon = 0;
214  self.killedInUse = undefined;
215 }
216 
217 //Drops any carried object when the player dies
218 function ‪on_death()
219 {
220  level endon ( "game_ended" );
221  self endon("killOnDeathMonitor");
222 
223  self waittill ( "death" );
224 
225  self thread ‪gameObjects_dropped();
226 }
227 
228 //Drops any carried object when the player disconnects
230 {
231  level endon ( "game_ended" );
232 
233  self thread ‪gameObjects_dropped();
234 }
235 
236 //Drops any carried object when the player enters laststand
238 {
239  self thread ‪gameObjects_dropped();
240 }
241 
243 {
244  if ( isdefined( self.carryObject ) )
245  {
246  self.carryObject thread ‪set_dropped();
247  }
248 
249  if ( isdefined( self.packObject ) && self.packObject.size > 0 )
250  {
251  foreach(item in self.packObject)
252  {
253  item thread ‪set_dropped();
254  }
255  }
256 }
257 //=====================================================================================
258 
259 /*
260 =============
261 create_carry_object
262 
263 Creates and returns a carry object
264 =============
265 */
266 function ‪create_carry_object( ownerTeam, trigger, visuals, offset, objectiveName, hitSound )
267 {
268  carryObject = spawnStruct();
269  carryObject.type = "carryObject";
270  carryObject.curOrigin = trigger.origin;
271  carryObject.entNum = trigger getEntityNumber();
272  carryObject.hitSound = hitSound;
273 
274  if ( isSubStr( trigger.classname, "use" ) )
275  {
276  carryObject.triggerType = "use";
277  }
278  else
279  {
280  carryObject.triggerType = "proximity";
281  }
282 
283  // associated trigger
284  trigger.baseOrigin = trigger.origin;
285  carryObject.trigger = trigger;
286 
287  carryObject.useWeapon = undefined;
288 
289  if ( !isdefined( offset ) )
290  {
291  offset = (0,0,0);
292  }
293 
294  carryObject.offset3d = offset;
295 
296  carryObject.newStyle = false;
297 
298  if ( isdefined( objectiveName ) )
299  {
300  if( !SessionModeIsCampaignGame() )
301  {
302  carryObject.newStyle = true;
303  }
304  }
305  else
306  {
307  objectiveName = &"";
308  }
309 
310  // associated visual objects
311  for ( index = 0; index < visuals.size; index++ )
312  {
313  visuals[index].baseOrigin = visuals[index].origin;
314  visuals[index].baseAngles = visuals[index].angles;
315  }
316  carryObject.visuals = visuals;
317 
318  carryObject ‪_set_team( ownerTeam );
319 
320  // compass objectives
321  carryObject.compassIcons = [];
322  carryObject.objID =[];
323  // this block will completely go away when we have fully switched to the new style
324  if ( !carryObject.newStyle )
325  {
326  foreach( team in level.teams )
327  {
328  carryObject.objID[team] = ‪get_next_obj_id();
329  }
330  }
331  carryObject.objIDPingFriendly = false;
332  carryObject.objIDPingEnemy = false;
333  level.objIDStart += 2;
334 
335  // this block will completely go away when we have fully switched to the new style
336  if ( !carryObject.newStyle )
337  {
338  if ( level.teamBased )
339  {
340  foreach ( team in level.teams )
341  {
342  if( SessionModeIsCampaignGame() )
343  {
344  if( team == "allies" )
345  {
346  objective_add( carryObject.objID[team], "active", carryObject.curOrigin, objectiveName );
347  }
348  else
349  {
350  objective_add( carryObject.objID[team], "invisible", carryObject.curOrigin, objectiveName );
351  }
352  }
353  else
354  {
355  objective_add( carryObject.objID[team], "invisible", carryObject.curOrigin, objectiveName );
356  }
357 
358  objective_team( carryObject.objID[team], team );
359  carryObject.objPoints[team] = ‪objpoints::create( "objpoint_" + team + "_" + carryObject.entNum, carryObject.curOrigin + offset, team, undefined );
360  carryObject.objPoints[team].alpha = 0;
361  }
362  }
363  else
364  {
365  // TODO MTEAM - not sure why the we only use allies in dm
366  objective_add( carryObject.objID[level.nonTeamBasedTeam], "invisible", carryObject.curOrigin, objectiveName );
367  carryObject.objPoints[level.nonTeamBasedTeam] = ‪objpoints::create( "objpoint_"+ level.nonTeamBasedTeam + "_" + carryObject.entNum, carryObject.curOrigin + offset, "all", undefined );
368  carryObject.objPoints[level.nonTeamBasedTeam].alpha = 0;
369  }
370  }
371 
372  carryObject.objectiveID = ‪get_next_obj_id();
373 
374  // new style objective
375  if ( carryObject.newStyle )
376  {
377  objective_add( carryObject.objectiveID, "invisible", carryObject.curOrigin, objectiveName );
378  }
379 
380  // carrying player
381  carryObject.carrier = undefined;
382 
383  // misc
384  carryObject.isResetting = false;
385  carryObject.interactTeam = "none"; // "none", "any", "friendly", "enemy";
386  carryObject.allowWeapons = false;
387  carryObject.visibleCarrierModel = undefined;
388  carryObject.dropOffset = 0;
389  carryObject.disallowRemoteControl = false;
390 
391  // 3d world icons
392  carryObject.worldIcons = [];
393  carryObject.carrierVisible = false; // carryObject only
394  carryObject.visibleTeam = "none"; // "none", "any", "friendly", "enemy";
395  carryObject.worldIsWaypoint = [];
396 
397  carryObject.worldIcons_disabled = [];
398 
399  carryObject.carryIcon = undefined;
400 
401  // callbacks
402  carryObject.setDropped = undefined;
403  carryObject.onDrop = undefined;
404  carryObject.onPickup = undefined;
405  carryObject.onReset = undefined;
406 
407 
408  if ( carryObject.triggerType == "use" )
409  {
410  carryObject thread ‪carry_object_use_think();
411  }
412  else
413  {
414  carryObject.numTouching["neutral"] = 0;
415  carryObject.numTouching["none"] = 0;
416  carryObject.touchList["neutral"] = [];
417  carryObject.touchList["none"] = [];
418 
419  foreach( team in level.teams )
420  {
421  carryObject.numTouching[team] = 0;
422  carryObject.touchList[team] = [];
423  }
424 
425  carryObject.curProgress = 0;
426  carryObject.useTime = 0;
427  carryObject.useRate = 0;
428  carryObject.claimTeam = "none";
429  carryObject.claimPlayer = undefined;
430  carryObject.lastClaimTeam = "none";
431  carryObject.lastClaimTime = 0;
432  carryObject.claimGracePeriod = 0;
433  carryObject.mustMaintainClaim = false;
434  carryObject.canContestClaim = false;
435  carryObject.decayProgress = false;
436 
437  carryObject.teamUseTimes = [];
438  carryObject.teamUseTexts = [];
439 
440  carryObject.onUse =&‪set_picked_up;
441 
442  carryObject thread ‪use_object_prox_think();
443 
444  //carryObject thread carry_object_prox_think();
445  }
446 
447  carryObject thread ‪update_carry_object_origin();
448  carryObject thread ‪update_carry_object_objective_origin();
449 
450  return carryObject;
451 }
452 
453 
454 /*
455 =============
456 carry_object_use_think
457 
458 Think function for "use" type carry objects
459 =============
460 */
462 {
463  level endon ( "game_ended" );
464  self.trigger endon( "destroyed" );
465 
466  while ( true )
467  {
468  self.trigger waittill ( "trigger", player );
469 
470  if ( self.isResetting )
471  {
472  continue;
473  }
474 
475  if ( !isAlive( player ) )
476  {
477  continue;
478  }
479 
480  if ( isdefined(player.laststand) && player.laststand )
481  {
482  continue;
483  }
484 
485  if ( !self ‪can_interact_with( player ) )
486  {
487  continue;
488  }
489 
490  if ( !player.canPickupObject )
491  {
492  continue;
493  }
494 
495  if ( player.throwingGrenade )
496  {
497  continue;
498  }
499 
500  if ( isdefined( self.carrier ) )
501  {
502  continue;
503  }
504 
505  if ( player isInVehicle() )
506  {
507  continue;
508  }
509 
510  if ( player isRemoteControlling() || player ‪util::isUsingRemote() )
511  {
512  continue;
513  }
514 
515  if ( ‪IS_TRUE( player.selectingLocation ) )
516  {
517  continue;
518  }
519 
520  if ( player IsWeaponViewOnlyLinked() )
521  {
522  continue;
523  }
524 
525  if( !player isTouching( self.trigger ) )
526  {
527  continue;
528  }
529 
530  self ‪set_picked_up( player );
531  }
532 }
533 
534 /*
535 =============
536 carry_object_prox_think
537 
538 Think function for "proximity" type carry objects
539 =============
540 */
542 {
543  level endon ( "game_ended" );
544  self.trigger endon( "destroyed" );
545 
546  while ( true )
547  {
548  self.trigger waittill ( "trigger", player );
549 
550  if ( self.isResetting )
551  {
552  continue;
553  }
554 
555  if ( !isAlive( player ) )
556  {
557  continue;
558  }
559 
560  if ( isdefined(player.laststand) && player.laststand )
561  {
562  continue;
563  }
564 
565  if ( !self ‪can_interact_with( player ) )
566  {
567  continue;
568  }
569 
570  if ( !player.canPickupObject )
571  {
572  continue;
573  }
574 
575  if ( player.throwingGrenade )
576  {
577  continue;
578  }
579 
580  if ( isdefined( self.carrier ) )
581  {
582  continue;
583  }
584 
585  if ( player isInVehicle() )
586  {
587  continue;
588  }
589 
590  if ( player isRemoteControlling() || player ‪util::isUsingRemote() )
591  {
592  continue;
593  }
594 
595  if ( ‪IS_TRUE( player.selectingLocation ) )
596  {
597  continue;
598  }
599 
600  if ( player IsWeaponViewOnlyLinked() )
601  {
602  continue;
603  }
604 
605  //Fix for player being able to respawn with the flag. This occured due to
606  //trigger collisions being stored and used a frame later than the collision occured.
607  if( !player isTouching( self.trigger ) )
608  {
609  continue;
610  }
611 
612  self ‪set_picked_up( player );
613  }
614 }
615 
616 
617 /*
618 =============
619 pickup_object_delay
620 
621 Temporarily disallows picking up of "proximity" type objects
622 =============
623 */
624 function ‪pickup_object_delay( origin )
625 {
626  level endon ( "game_ended" );
627 
628  self endon("death");
629  self endon("disconnect");
630 
631  self.canPickupObject = false;
632 
633  for( ;; )
634  {
635  if ( distanceSquared( self.origin, origin ) > 64*64 )
636  {
637  break;
638  }
639 
640  wait 0.2;
641  }
642 
643  self.canPickupObject = true;
644 }
645 
646 
647 /*
648 =============
649 set_picked_up
650 
651 Sets this object as picked up by passed player
652 =============
653 */
654 function ‪set_picked_up( player )
655 {
656  if ( !IsAlive( player ) )
657  {
658  return;
659  }
660 
661  if ( self.type == "carryObject" )
662  {
663  if(isdefined( player.carryObject ))
664  {
665  if ( ‪IS_TRUE( player.carryObject.swappable ) )
666  {
667  player.carryObject thread ‪set_dropped();
668  }
669  else
670  {
671  if ( isdefined( self.onPickupFailed ) )
672  {
673  self [[self.onPickupFailed]]( player );
674  }
675 
676  return;
677  }
678  }
679 
680  player ‪give_object( self );
681  }
682  else if( self.type == "packObject")
683  {
684  if(IsDefined(level.max_packObjects) && (level.max_packObjects <= player.packObject.size))
685  {
686  if ( isdefined( self.onPickupFailed ) )
687  {
688  self [[self.onPickupFailed]]( player );
689  }
690 
691  return;
692  }
693 
694  player ‪give_pack_object( self );
695  }
696 
697  self ‪set_carrier( player );
698 
699  self ‪ghost_visuals();
700 
701  // this should get replaced triggerenable functionality
702  self.trigger.origin += (0,0,10000);
703 
704  self notify ( "pickup_object" );
705  if ( isdefined( self.‪onPickup ) )
706  {
707  self [[self.onPickup]]( player );
708  }
709 
711  self ‪update_world_icons();
712  self ‪update_objective();
713 }
714 
716 {
717  radius = 32;
718  origin = self.origin;
719  grenades = getentarray( "grenade", "classname" );
720  radiusSq = radius * radius;
721  linkedGrenades = [];
722 
723  foreach( grenade in grenades )
724  {
725  if( DistanceSquared( origin, grenade.origin ) < radiusSq )
726  {
727  if ( grenade islinkedto( self ) )
728  {
729  grenade unlink();
730 
731  linkedGrenades[linkedGrenades.size] = grenade;
732  }
733  }
734  }
735 
736  waittillframeend;
737 
738  foreach( grenade in linkedGrenades )
739  {
740  grenade ‪launch( (RandomFloatRange( -5, 5 ),RandomFloatRange( -5, 5 ),5) );
741  }
742 }
743 
745 {
746  foreach ( visual in self.visuals )
747  {
748  visual Ghost();
749  visual thread ‪unlink_grenades();
750  }
751 }
752 
754 {
755  level endon ( "game_ended" );
756  self.trigger endon( "destroyed" );
757 
758  if ( self.newStyle )
759  {
760  return;
761  }
762 
763  objPingDelay = level.objectivePingDelay;
764  for ( ;; )
765  {
766  if ( isdefined( self.carrier ) && level.teamBased )
767  {
768  self.curOrigin = self.carrier.origin + (0,0,75);
769 
770  foreach ( team in level.teams )
771  {
772  self.objPoints[team] ‪objpoints::update_origin( self.curOrigin );
773  }
774 
775  if ( (self.visibleTeam == "friendly" || self.visibleTeam == "any") && self.objIDPingFriendly )
776  {
777  foreach ( team in level.teams )
778  {
779  if ( self ‪is_friendly_team( team ) )
780  {
781  if ( self.objPoints[team].isShown )
782  {
783  self.objPoints[team].alpha = self.objPoints[team].baseAlpha;
784  self.objPoints[team] fadeOverTime( objPingDelay + 1.0 );
785  self.objPoints[team].alpha = 0;
786  }
787  objective_position( self.objID[team], self.curOrigin );
788  }
789  }
790  }
791 
792  if ( (self.visibleTeam == "enemy" || self.visibleTeam == "any") && self.objIDPingEnemy )
793  {
794  if ( !self ‪is_friendly_team( team ) )
795  {
796  if ( self.objPoints[team].isShown )
797  {
798  self.objPoints[team].alpha = self.objPoints[team].baseAlpha;
799  self.objPoints[team] fadeOverTime( objPingDelay + 1.0 );
800  self.objPoints[team].alpha = 0;
801  }
802  objective_position( self.objID[team], self.curOrigin );
803  }
804  }
805 
806 
807  self ‪util::wait_endon( objPingDelay, "dropped", "reset" );
808  }
809  else if( isdefined( self.carrier ) )
810  {
811  self.curOrigin = self.carrier.origin + (0,0,75);
812  self.objPoints[level.nonTeamBasedTeam] ‪objpoints::update_origin( self.curOrigin );
813  objective_position( self.objID[level.nonTeamBasedTeam], self.curOrigin );
814 
816  }
817  else
818  {
819  if ( level.teamBased )
820  {
821  foreach( team in level.teams )
822  {
823  self.objPoints[team] ‪objpoints::update_origin( self.curOrigin + self.offset3d );
824  }
825  }
826  else
827  {
828  self.objPoints[level.nonTeamBasedTeam] ‪objpoints::update_origin( self.curOrigin + self.offset3d );
829  }
830 
832  }
833  }
834 }
835 
837 {
838  level endon ( "game_ended" );
839  self.trigger endon( "destroyed" );
840 
841  if ( !self.newStyle )
842  {
843  return;
844  }
845 
846  objPingDelay = level.objectivePingDelay;
847  for ( ;; )
848  {
849  if ( isdefined( self.carrier ) )
850  {
851  self.curOrigin = self.carrier.origin;
852  objective_position( self.objectiveID, self.curOrigin );
853  self ‪util::wait_endon( objPingDelay, "dropped", "reset" );
854  }
855  else
856  {
857  objective_position( self.objectiveID, self.curOrigin );
859  }
860  }
861 }
862 
863 
864 /*
865 =============
866 give_object
867 
868 Set player as holding this object
869 Should only be called from set_picked_up
870 =============
871 */
872 function ‪give_object( object )
873 {
874  assert( !isdefined( self.carryObject ) );
875 
876  self.carryObject = object;
877  self thread ‪track_carrier(object);
878 
879  if ( IsDefined(object.carryWeapon) )
880  {
881  //object.carrierWeaponCurrent = self GetCurrentWeapon();
882  //So we don't take the weapon if the player has it in their loadout.
883  //object.carrierHasCarryWeaponInLoadout = self HasWeapon(object.carryWeapon);
884  if ( isDefined(object.carryWeaponThink) )
885  {
886  self thread [[object.carryWeaponThink]]();
887  }
888 
889  count = 0;
890  while( self IsMeleeing() && count < 10 )
891  {
892  count++;
893  wait 0.2;
894  }
895 
896  self GiveWeapon( object.carryWeapon );
897 
898  if( self IsSwitchingWeapons() )
899  self ‪util::waittill_any_timeout( 2, "weapon_change" );
900 
901  self SwitchToWeaponImmediate( object.carryWeapon );
902  self setblockweaponpickup( object.carryWeapon, true );
903  self DisableWeaponCycling();
904  }
905  else if ( !object.allowWeapons )
906  {
908  self thread ‪manual_drop_think();
909  }
910 
911  self.disallowVehicleUsage = true;
912 
913  if ( isdefined( object.visibleCarrierModel ) )
914  {
916  }
917 
918  if ( !object.newStyle )
919  {
920  if ( isdefined( object.carryIcon ) )
921  {
922  if ( self IsSplitscreen() )
923  {
924  self.carryIcon = ‪hud::createIcon( object.carryIcon, 35, 35 );
925  self.carryIcon.x = -130;
926  self.carryIcon.y = -90;
927  self.carryIcon.horzAlign = "right";
928  self.carryIcon.vertAlign = "bottom";
929  }
930  else
931  {
932  self.carryIcon = ‪hud::createIcon( object.carryIcon, 50, 50 );
933 
934  if ( !object.allowWeapons )
935  {
936  self.carryIcon ‪hud::setPoint( "CENTER", "CENTER", 0, 60 );
937  }
938  else
939  {
940  self.carryIcon.x = ‪CARRY_ICON_X;
941  self.carryIcon.y = ‪CARRY_ICON_Y;
942  self.carryIcon.horzAlign = "user_left";
943  self.carryIcon.vertAlign = "user_bottom";
944  }
945  }
946  self.carryIcon.alpha = 0.75;
947  self.carryIcon.hidewhileremotecontrolling = true;
948  self.carryIcon.hidewheninkillcam = true;
949  }
950  }
951 }
952 
954 {
955  foreach( visual in self.visuals )
956  {
957  visual.origin = visual.baseOrigin;
958  visual.angles = visual.baseAngles;
959  visual DontInterpolate();
960  visual show();
961  }
962 }
963 
964 /*
965 =============
966 return_home
967 
968 Resets a carryObject to it's default home position
969 =============
970 */
971 function ‪return_home()
972 {
973  self.isResetting = true;
974 
975  // trigger is more up to date then self.curOrigin
976  prev_origin = self.trigger.origin;
977 
978  self notify ( "reset" );
980  self.trigger.origin = self.trigger.baseOrigin;
981 
982  self.curOrigin = self.trigger.origin;
983 
984  if ( isdefined( self.‪onReset ) )
985  {
986  self [[self.onReset]](prev_origin);
987  }
988 
989  self ‪clear_carrier();
990 
994 
995  self.isResetting = false;
996 }
997 
998 
999 /*
1000 =============
1001 is_object_away_from_home
1002 =============
1003 */
1005 {
1006  if ( isdefined( self.carrier ) )
1007  {
1008  return true;
1009  }
1010 
1011  if ( distancesquared(self.trigger.origin,self.trigger.baseOrigin) > 4 )
1012  {
1013  return true;
1014  }
1015 
1016  return false;
1017 }
1018 
1019 
1020 /*
1021 =============
1022 set_position
1023 
1024 set a carryObject to a new position
1025 =============
1026 */
1027 function ‪set_position( origin, angles )
1028 {
1029  self.isResetting = true;
1030 
1031  foreach( visual in self.visuals )
1032  {
1033  visual.origin = origin;
1034  visual.angles = angles;
1035  visual DontInterpolate();
1036  visual show();
1037  }
1038  self.trigger.origin = origin;
1039 
1040  self.curOrigin = self.trigger.origin;
1041 
1042  self ‪clear_carrier();
1043 
1047 
1048  self.isResetting = false;
1049 }
1050 
1051 function ‪set_drop_offset( height )
1052 {
1053  self.dropOffset = height;
1054 }
1055 
1056 /*
1057 =============
1058 set_dropped
1059 
1060 Sets this carry object as dropped and calculates dropped position
1061 =============
1062 */
1063 function ‪set_dropped()
1064 {
1065  if ( isdefined(self.setDropped) )
1066  {
1067  if ( [[self.setDropped]]() )
1068  return;
1069  }
1070 
1071  self.isResetting = true;
1072 
1073  self notify ( "dropped" );
1074 
1075  startOrigin = (0,0,0);
1076  endOrigin = (0,0,0);
1077  body = undefined;
1078  if ( isdefined( self.carrier ) && self.carrier.team != "spectator" )
1079  {
1080  startOrigin = self.carrier.origin + (0,0,20);
1081  endOrigin = self.carrier.origin - (0,0,2000);
1082  body = self.carrier.body;
1083  }
1084  else
1085  {
1086  if( isdefined( self.safeOrigin ) )
1087  {
1088  startOrigin = self.safeOrigin + (0,0,20);
1089  endOrigin = self.safeOrigin - (0,0,20);
1090  }
1091  else
1092  {
1093  startOrigin = self.curorigin + (0,0,20);
1094  endOrigin = self.curorigin - (0,0,20);
1095  }
1096 
1097  }
1098 
1099  trace_size = 10;
1100  ‪trace = PhysicsTrace( startOrigin, endOrigin, ( -trace_size, -trace_size, -trace_size ), ( trace_size, trace_size, trace_size ), self, ‪PHYSICS_TRACE_MASK_PLAYER );
1101  droppingPlayer = self.carrier;
1102 
1103  self ‪clear_carrier();
1104 
1105  if ( isdefined( ‪trace ) )
1106  {
1107 
1108  tempAngle = randomfloat( 360 );
1109 
1110  dropOrigin = ‪trace["position"] + ( 0, 0, self.dropOffset );
1111  if ( ‪trace["fraction"] < 1 /*&& distance( trace["position"], trace ) < 10.0*/ )
1112  {
1113  forward = (cos( tempAngle ), sin( tempAngle ), 0);
1114  forward = vectornormalize( forward - VectorScale( ‪trace["normal"], vectordot( forward, ‪trace["normal"] ) ) );
1115 
1116  // TU HACK: this block should not be multiplayer only. Post ship caution.
1117  if(SessionModeIsMultiplayerGame())
1118  {
1119  if ( isdefined( ‪trace["walkable"] ) )
1120  {
1121  if ( ‪trace["walkable"] == false )
1122  {
1123  if ( self ‪should_be_reset( ‪trace["position"][2], startOrigin[2], true ) )
1124  {
1125  self thread ‪return_home();
1126  self.isResetting = false;
1127  return;
1128  }
1129 
1130  end_reflect = (forward * 1000) + ‪trace["position"];
1131  reflect_trace = PhysicsTrace( ‪trace["position"], end_reflect, ( -trace_size, -trace_size, -trace_size ), ( trace_size, trace_size, trace_size ), self, ‪PHYSICS_TRACE_MASK_PLAYER );
1132 
1133  if ( isdefined( reflect_trace ) && (reflect_trace["normal"][2] < 0.0) )
1134  {
1135  dropOrigin_reflect = reflect_trace["position"] + ( 0, 0, self.dropOffset );
1136 
1137 
1138  if ( self ‪should_be_reset( dropOrigin_reflect[2], ‪trace["position"][2], true ) )
1139  {
1140  self thread ‪return_home();
1141  self.isResetting = false;
1142  return;
1143  }
1144  }
1145  }
1146  }
1147  }
1148 
1149  dropAngles = vectortoangles( forward );
1150  }
1151  else
1152  {
1153  dropAngles = (0,tempAngle,0);
1154  }
1155 
1156  foreach( visual in self.visuals )
1157  {
1158  visual.origin = dropOrigin;
1159  visual.angles = dropAngles;
1160  visual DontInterpolate();
1161  visual show();
1162  }
1163  self.trigger.origin = dropOrigin;
1164 
1165  self.curOrigin = self.trigger.origin;
1166 
1167  self thread ‪pickup_timeout( ‪trace["position"][2], startOrigin[2] );
1168  }
1169  else
1170  {
1171  self ‪move_visuals_to_base();
1172  self.trigger.origin = self.trigger.baseOrigin;
1173 
1174  self.curOrigin = self.trigger.baseOrigin;
1175  }
1176 
1177  if ( IsDefined( self.‪onDrop ) )
1178  {
1179  self [[self.onDrop]]( droppingPlayer );
1180  }
1181 
1183 
1184  self.isResetting = false;
1185 }
1186 
1188 {
1189  self ‪update_compass_icons();
1190  self ‪update_world_icons();
1191  self ‪update_objective();
1192 }
1193 
1194 function ‪set_carrier( carrier )
1195 {
1196  self.carrier = carrier;
1197  Objective_SetPlayerUsing( self.objectiveID, carrier );
1198 
1200 }
1201 
1202 /*
1203 =============
1204 get_carrier
1205 
1206 Returns the carrier entity for this gameobject
1207 =============
1208 */
1209 
1210 // CP TODO - Added
1211 function ‪get_carrier()
1212 {
1213  return( self.carrier );
1214 }
1215 
1216 
1218 {
1219  if ( !isdefined( self.carrier ) )
1220  {
1221  return;
1222  }
1223 
1224  self.carrier ‪take_object( self );
1225  Objective_ClearPlayerUsing( self.objectiveID, self.carrier );
1226 
1227  self.carrier = undefined;
1228 
1229  self notify("carrier_cleared");
1230 }
1231 
1232 function ‪is_touching_any_trigger( triggers, minZ, maxZ )
1233 {
1234  foreach( trigger in triggers )
1235  {
1236  if( self isTouchingSwept( trigger, minZ, maxZ ) )
1237  return true;
1238  }
1239  return false;
1240 }
1241 
1242 function ‪is_touching_any_trigger_key_value( value, key, minZ, maxZ )
1243 {
1244  return self ‪is_touching_any_trigger( getEntArray( value, key ), minZ, maxZ );
1245 }
1246 
1247 function ‪should_be_reset( minZ, maxZ, testHurtTriggers )
1248 {
1249  if ( self.visuals[0] ‪is_touching_any_trigger_key_value( "minefield", "targetname", minZ, maxZ ) )
1250  return true;
1251 
1252  if ( ‪IS_TRUE( testHurtTriggers ) && self.visuals[0] ‪is_touching_any_trigger_key_value( "trigger_hurt", "classname", minZ, maxZ ) )
1253  return true;
1254 
1255  if ( self.visuals[0] ‪is_touching_any_trigger( level.oob_triggers, minZ, maxZ ) )
1256  return true;
1257 
1258  elevators = GetEntArray( "script_elevator", "targetname" );
1259 
1260  foreach( elevator in elevators )
1261  {
1262  assert( isdefined( elevator.occupy_volume ) );
1263 
1264  if ( self.visuals[0] isTouchingSwept( elevator.occupy_volume, minZ, maxZ ) )
1265  return true;
1266  }
1267 
1268  return false;
1269 }
1270 
1271 
1272 function ‪pickup_timeout( minZ, maxZ )
1273 {
1274  self endon ( "pickup_object" );
1275  self endon ( "reset" );
1276 
1278 
1279  if ( self ‪should_be_reset( minZ, maxZ, true ) )
1280  {
1281  self thread ‪return_home();
1282  return;
1283  }
1284 
1285  if ( isdefined( self.pickupTimeoutOverride ) )
1286  {
1287  self thread [[self.pickupTimeoutOverride]]();
1288  }
1289  else if ( isdefined( self.autoResetTime ) )
1290  {
1291  wait ( self.autoResetTime );
1292 
1293  if ( !isdefined( self.carrier ) )
1294  {
1295  self thread ‪return_home();
1296  }
1297  }
1298 }
1299 
1300 /*
1301 =============
1302 take_object
1303 
1304 Set player as dropping this object
1305 =============
1306 */
1307 function ‪take_object( object )
1308 {
1309 
1310  if ( isdefined( object.visibleCarrierModel ) )
1311  {
1313  }
1314 
1315  shouldEnableWeapon = true;
1316  if( isDefined(object.carryWeapon) && !IsDefined( self.player_disconnected ) )
1317  {
1318  shouldEnableWeapon = false;
1319  self thread ‪wait_take_carry_weapon( object.carryWeapon );
1320  }
1321 
1322  if(object.type == "carryObject")
1323  {
1324  if ( isdefined( self.carryIcon ) )
1325  {
1326  self.carryIcon ‪hud::destroyElem();
1327  }
1328 
1329  self.carryObject = undefined;
1330  }
1331  else if(object.type == "packObject")
1332  {
1333  if ( isdefined( self.packIcon ) && self.packIcon.size > 0 )
1334  {
1335  for( i = 0; i < self.packIcon.size; i++ )
1336  {
1337  if(IsDefined(self.packIcon[i].script_string))
1338  {
1339  if(self.packIcon[i].script_string == object.packIcon)
1340  {
1341  elem = self.packIcon[i];
1342  ArrayRemoveValue(self.packIcon, elem);
1343  elem ‪hud::destroyElem();
1344 
1345  //adjust remaining icons
1346  self thread ‪adjust_remaining_packIcons();
1347  }
1348  }
1349  }
1350  }
1351 
1352  ArrayRemoveValue(self.packObject, object);
1353  }
1354 
1355  if ( !isAlive( self ) || IsDefined( self.player_disconnected ) )
1356  {
1357  return;
1358  }
1359 
1360  self notify ( "drop_object" );
1361 
1362  self.disallowVehicleUsage = false;
1363 
1364  if ( object.triggerType == "proximity" )
1365  {
1366  self thread ‪pickup_object_delay( object.trigger.origin );
1367  }
1368 
1369  if ( isdefined( object.visibleCarrierModel ) )
1370  {
1372  }
1373 
1374  if ( !object.allowWeapons && shouldEnableWeapon )
1375  {
1376  self ‪util::_enableWeapon();
1377  }
1378 }
1379 
1380 function ‪wait_take_carry_weapon( weapon )
1381 {
1382  self thread ‪take_carry_weapon_on_death( weapon );
1383 
1384  // Take some time away otherwise it tends to 'flash' before disappearing
1385  wait( Max( 0, weapon.fireTime - ( 2 * ‪SERVER_FRAME ) ) );
1386 
1387  self ‪take_carry_weapon( weapon );
1388 }
1389 
1391 {
1392  self endon( "take_carry_weapon" );
1393  self waittill( "death" );
1394 
1395  self ‪take_carry_weapon( weapon );
1396 }
1397 
1398 function ‪take_carry_weapon( weapon )
1399 {
1400  self notify( "take_carry_weapon" );
1401 
1402  if ( self HasWeapon( weapon, true ) )
1403  {
1404  ballWeapon = GetWeapon( "ball" );
1405  currWeapon = self GetCurrentWeapon();
1406  if( ( weapon == ballWeapon ) && ( currWeapon === ballWeapon ) )
1408  self setblockweaponpickup( weapon, false );
1409  self TakeWeapon( weapon );
1410  self EnableWeaponCycling();
1411  if( level.gameType == "ball" )
1412  self EnableOffhandWeapons();
1413  }
1414 }
1415 
1416 /*
1417 =============
1418 track_carrier
1419 
1420 Calculates and updates a safe drop origin for a carry object based on the current carriers position
1421 =============
1422 */
1423 function ‪track_carrier(object)
1424 {
1425  level endon ( "game_ended" );
1426  self endon ( "disconnect" );
1427  self endon ( "death" );
1428  self endon ( "drop_object" );
1429 
1430  ‪WAIT_SERVER_FRAME; // wait a frame so the carrier gets set
1431 
1432  while ( (isdefined( object.carrier ) && object.carrier == self) && isAlive( self ) )
1433  {
1434  if ( self isOnGround() )
1435  {
1436  ‪trace = bulletTrace( self.origin + (0,0,20), self.origin - (0,0,20), false, undefined );
1437  if ( ‪trace["fraction"] < 1 ) // if there is ground at the player's origin (not necessarily true just because of isOnGround)
1438  {
1439  object.safeOrigin = ‪trace["position"];
1440  }
1441  }
1443  }
1444 }
1445 
1446 
1447 /*
1448 =============
1449 manual_drop_think
1450 
1451 Allows the player to manually drop this object by pressing the fire button
1452 Does not allow drop if the use button is pressed
1453 =============
1454 */
1456 {
1457  level endon ( "game_ended" );
1458 
1459  self endon ( "disconnect" );
1460  self endon ( "death" );
1461  self endon ( "drop_object" );
1462 
1463  for( ;; )
1464  {
1465  while ( self attackButtonPressed() || self fragButtonPressed() || self secondaryOffhandButtonPressed() || self meleeButtonPressed() )
1466  {
1467  wait .05;
1468  }
1469 
1470  while ( !self attackButtonPressed() && !self fragButtonPressed() && !self secondaryOffhandButtonPressed() && !self meleeButtonPressed() )
1471  {
1472  wait .05;
1473  }
1474 
1475  if ( isdefined( self.carryObject ) && !self useButtonPressed() )
1476  {
1477  self.carryObject thread ‪set_dropped();
1478  }
1479  }
1480 }
1481 
1482 
1483 /*
1484 =============
1485 create_use_object
1486 
1487 Creates and returns a use object
1488 In FFA gametypes, ownerTeam should be the player who owns the object
1489 =============
1490 */
1491 function ‪create_use_object( ownerTeam, trigger, visuals, offset, objectiveName, allowInitialHoldDelay = false, allowWeaponCyclingDuringHold = false )
1492 {
1493  useObject = ‪Spawn( "script_model", trigger.origin );
1494  useObject.type = "useObject";
1495  useObject.curOrigin = trigger.origin;
1496  useObject.entNum = trigger getEntityNumber();
1497  useObject.keyObject = undefined;
1498 
1499  if ( isSubStr( trigger.classname, "use" ) )
1500  {
1501  useObject.triggerType = "use";
1502  }
1503  else
1504  {
1505  useObject.triggerType = "proximity";
1506  }
1507 
1508  // associated trigger
1509  useObject.trigger = trigger;
1510  useObject LinkTo( trigger );
1511 
1512  // associated visual object
1513  for ( index = 0; index < visuals.size; index++ )
1514  {
1515  visuals[index].baseOrigin = visuals[index].origin;
1516  visuals[index].baseAngles = visuals[index].angles;
1517  }
1518  useObject.visuals = visuals;
1519 
1520  useObject ‪_set_team( ownerTeam );
1521 
1522  if ( !isdefined( offset ) )
1523  {
1524  offset = (0,0,0);
1525  }
1526 
1527  useObject.offset3d = offset;
1528 
1529  useObject.newStyle = false;
1530 
1531  if ( isdefined( objectiveName ) )
1532  {
1533  useObject.newStyle = true;
1534  }
1535  else
1536  {
1537  objectiveName = &"";
1538  }
1539 
1540  // this block will completely go away when we have fully switched to the new style
1541  {
1542  // compass objectives
1543  useObject.compassIcons = [];
1544  useObject.objID = [];
1545  if ( !useObject.newStyle )
1546  {
1547  foreach( team in level.teams )
1548  {
1549  useObject.objID[team] = ‪get_next_obj_id();
1550  }
1551 
1552  if ( level.teamBased )
1553  {
1554  foreach( team in level.teams )
1555  {
1556  if( SessionModeIsCampaignGame() )
1557  {
1558  objective_add( useObject.objID[ "allies" ], "active", useObject.curOrigin, objectiveName );
1559  break;
1560  }
1561  else
1562  {
1563  objective_add( useObject.objID[team], "invisible", useObject.curOrigin, objectiveName );
1564  }
1565 
1566  objective_team( useObject.objID[team], team );
1567  }
1568  }
1569  else
1570  {
1571  objective_add( useObject.objID[level.nonTeamBasedTeam], "invisible", useObject.curOrigin, objectiveName );
1572  }
1573  }
1574  }
1575 
1576  useObject.objectiveID = ‪get_next_obj_id();
1577 
1578  // new style objective
1579  if ( useObject.newStyle )
1580  {
1581  if( SessionModeIsCampaignGame() )
1582  {
1583  objective_add( useObject.objectiveID, "invisible", useObject, objectiveName );
1584  useObject.keepWeapon = true;
1585  }
1586  else
1587  {
1588  objective_add( useObject.objectiveID, "invisible", useObject.curOrigin + offset, objectiveName );
1589  }
1590  }
1591 
1592  if ( !useObject.newStyle )
1593  {
1594  if ( level.teamBased )
1595  {
1596  foreach( team in level.teams )
1597  {
1598  useObject.objPoints[team] = ‪objpoints::create( "objpoint_" + team + "_" + useObject.entNum, useObject.curOrigin + offset, team, undefined );
1599  useObject.objPoints[team].alpha = 0;
1600  }
1601  }
1602  else
1603  {
1604  useObject.objPoints[level.nonTeamBasedTeam] = ‪objpoints::create( "objpoint_allies_" + useObject.entNum, useObject.curOrigin + offset, "all", undefined );
1605  useObject.objPoints[level.nonTeamBasedTeam].alpha = 0;
1606  }
1607  }
1608 
1609  // misc
1610  useObject.interactTeam = "none"; // "none", "any", "friendly", "enemy";
1611 
1612  // 3d world icons
1613  useObject.worldIcons = [];
1614  useObject.visibleTeam = "none"; // "none", "any", "friendly", "enemy";
1615  useObject.worldIsWaypoint = [];
1616 
1617  useObject.worldIcons_disabled = [];
1618 
1619  // calbacks
1620  useObject.onUse = undefined;
1621  useObject.onCantUse = undefined;
1622 
1623  useObject.useText = "default";
1624  useObject.useTime = 10000;
1625  useObject ‪clear_progress();
1626 
1627  // if this is true, decay the flag back down instead of just resetting it to 0
1628  useObject.decayProgress = false;
1629 
1630  if ( useObject.triggerType == "proximity" )
1631  {
1632  useObject.numTouching["neutral"] = 0;
1633  useObject.numTouching["none"] = 0;
1634  useObject.touchList["neutral"] = [];
1635  useObject.touchList["none"] = [];
1636 
1637  foreach( team in level.teams )
1638  {
1639  useObject.numTouching[team] = 0;
1640  useObject.touchList[team] = [];
1641  }
1642 
1643  useObject.teamUseTimes = [];
1644  useObject.teamUseTexts = [];
1645 
1646  useObject.useRate = 0;
1647  useObject.claimTeam = "none";
1648  useObject.claimPlayer = undefined;
1649  useObject.lastClaimTeam = "none";
1650  useObject.lastClaimTime = 0;
1651  useObject.claimGracePeriod = 1.0;
1652  useObject.mustMaintainClaim = false;
1653  useObject.canContestClaim = false;
1654 
1655  useObject thread ‪use_object_prox_think();
1656  }
1657  else
1658  {
1659  useObject.useRate = 1;
1660  useObject thread ‪use_object_use_think( !allowInitialHoldDelay, !allowWeaponCyclingDuringHold );
1661  }
1662 
1663  return useObject;
1664 }
1665 
1666 
1667 /*
1668 =============
1669 set_key_object
1670 
1671 function Sets this use object to require carry object(s)
1672 =============
1673 */
1674 function ‪set_key_object( object )
1675 {
1676  if ( !isdefined( object ) )
1677  {
1678  self.keyObject = undefined;
1679 
1680  return;
1681  }
1682 
1683  if ( !isdefined( self.keyObject ) )
1684  {
1685  self.keyObject = [];
1686  }
1687 
1688  self.keyObject[ self.keyObject.size ] = object;
1689 }
1690 
1691 
1692 /*
1693 =============
1694 has_key_object
1695 
1696 function Checks if player is carrying key object(s)
1697 =============
1698 */
1700 {
1701  if(!isdefined( ‪use.keyObject ) )
1702  {
1703  return false;
1704  }
1705 
1706  for ( x = 0; x < ‪use.keyObject.size; x++ )
1707  {
1708  if ( isdefined( self.carryObject ) && ( self.carryObject == ‪use.keyObject[ x ] ) )
1709  {
1710  return true;
1711  }
1712  else if( isdefined(self.packObject) )
1713  {
1714  for ( i = 0; i < self.packObject.size; i++ )
1715  {
1716  if(self.packObject[i] == ‪use.keyObject[x] )
1717  {
1718  return true;
1719  }
1720  }
1721  }
1722  }
1723 
1724  return false;
1725 }
1726 
1727 
1728 /*
1729 =============
1730 use_object_use_think
1731 
1732 Think function for "use" type carry objects
1733 =============
1734 */
1735 function ‪use_object_use_think( disableInitialHoldDelay, disableWeaponCyclingDuringHold )
1736 {
1737  self.trigger endon( "destroyed" );
1738 
1739  if( self.useTime > 0 && disableInitialHoldDelay )
1740  {
1741  // If script is going to do its own use time then ignore the code g_holdUseTime before getting the "trigger" notify
1742  self.trigger UseTriggerIgnoreUseHoldTime();
1743  }
1744 
1745  while ( true )
1746  {
1747  self.trigger waittill ( "trigger", player );
1748 
1749  if( level.gameEnded )
1750  {
1751  continue;
1752  }
1753 
1754  if ( !isAlive( player ) )
1755  {
1756  continue;
1757  }
1758 
1759  if ( !self ‪can_interact_with( player ) )
1760  {
1761  continue;
1762  }
1763 
1764  if ( IsDefined( self.canInteractWithPlayer ) && ![[self.canInteractWithPlayer]]( player ) )
1765  {
1766  continue;
1767  }
1768 
1769  if ( !player isOnGround() || player IsWallRunning() )
1770  {
1771  continue;
1772  }
1773 
1774  if ( player isInVehicle() )
1775  {
1776  continue;
1777  }
1778 
1779  if ( isdefined( self.keyObject ) && !player ‪has_key_object( self ) )
1780  {
1781  if ( isdefined( self.‪onCantUse ) )
1782  {
1783  self [[self.onCantUse]]( player );
1784  }
1785  continue;
1786  }
1787 
1788  ‪result = true;
1789  if ( self.useTime > 0 )
1790  {
1791  if ( isdefined( self.‪onBeginUse ) )
1792  {
1793  if( isdefined( self.classObj ) )
1794  {
1795  [[self.classObj]]->onBeginUse( player );
1796  }
1797  else
1798  {
1799  self [[self.onBeginUse]]( player );
1800  }
1801  }
1802 
1803  team = player.pers["team"];
1804 
1805  ‪result = self ‪use_hold_think( player, disableWeaponCyclingDuringHold );
1806 
1807  if ( isdefined( self.‪onEndUse ) )
1808  {
1809  self [[self.onEndUse]]( team, player, ‪result );
1810  }
1811  }
1812 
1813  if ( !‪IS_TRUE(‪result) )
1814  {
1815  continue;
1816  }
1817 
1818  if ( isdefined( self.‪onUse ) )
1819  {
1820  if( ‪IS_TRUE( self.onUse_thread ) )
1821  {
1822  //used in co-op situations when we need simultaneous interaction
1823  //with the use object. Example: mobile armory
1824  self thread use_object_OnUse( player );
1825  }
1826  else
1827  {
1828  self use_object_OnUse( player );
1829  }
1830  }
1831  }
1832 }
1833 
1834 function ‪use_object_onUse( player )
1835 {
1836  level endon( "game_ended" );
1837  self.trigger endon( "destroyed" );
1838 
1839  if( isdefined( self.classObj ) )
1840  {
1841  [[self.classObj]]->onUse( player );
1842  }
1843  else
1844  {
1845  self [[self.onUse]]( player );
1846  }
1847 }
1848 
1849 
1851 {
1852  assert( self.claimTeam != "none" );
1853  team = self.claimTeam;
1854 
1855  earliestPlayer = self.claimPlayer;
1856 
1857  if ( self.touchList[team].size > 0 )
1858  {
1859  // find earliest touching player
1860  earliestTime = undefined;
1861  players = getArrayKeys( self.touchList[team] );
1862  for ( index = 0; index < players.size; index++ )
1863  {
1864  touchdata = self.touchList[team][players[index]];
1865  if ( !isdefined( earliestTime ) || touchdata.starttime < earliestTime )
1866  {
1867  earliestPlayer = touchdata.player;
1868  earliestTime = touchdata.starttime;
1869  }
1870  }
1871  }
1872 
1873  return earliestPlayer;
1874 }
1875 
1876 
1877 /*
1878 =============
1879 use_object_prox_think
1880 
1881 Think function for "proximity" type carry objects
1882 =============
1883 */
1885 {
1886  level endon ( "game_ended" );
1887  self.trigger endon( "destroyed" );
1888 
1889  self thread ‪prox_trigger_think();
1890 
1891  while ( true )
1892  {
1893  if ( self.useTime && self.curProgress >= self.useTime )
1894  {
1895  self ‪clear_progress();
1896 
1897  creditPlayer = ‪get_earliest_claim_player();
1898 
1899  if ( isdefined( self.‪onEndUse ) )
1900  {
1901  self [[self.onEndUse]]( self ‪get_claim_team(), creditPlayer, isdefined( creditPlayer ) );
1902  }
1903 
1904  if ( isdefined( creditPlayer ) && isdefined( self.‪onUse ) )
1905  {
1906  self [[self.onUse]]( creditPlayer );
1907  }
1908 
1909  if ( !self.mustMaintainClaim )
1910  {
1911  self ‪set_claim_team( "none" );
1912  self.claimPlayer = undefined;
1913  }
1914  }
1915 
1916  if ( self.claimTeam != "none" )
1917  {
1918  if ( self ‪use_object_locked_for_team( self.claimTeam ) )
1919  {
1920  if ( isdefined( self.‪onEndUse ) )
1921  {
1922  self [[self.onEndUse]]( self ‪get_claim_team(), self.claimPlayer, false );
1923  }
1924 
1925  self ‪set_claim_team( "none" );
1926  self.claimPlayer = undefined;
1927  self ‪clear_progress();
1928  }
1929  else
1930  {
1931  if ( self.useTime &&
1932  ( !self.mustMaintainClaim || ( self ‪get_owner_team() != self ‪get_claim_team() ) ) )
1933  {
1934  if ( self.decayProgress && !self.numTouching[self.claimTeam] )
1935  {
1936  if ( isdefined( self.claimPlayer ) )
1937  {
1938  if ( isdefined( self.‪onEndUse ) )
1939  {
1940  self [[self.onEndUse]]( self ‪get_claim_team(), self.claimPlayer, false );
1941  }
1942 
1943  self.claimPlayer = undefined;
1944  }
1945 
1946  decayScale = 0;
1947  if ( self.decayTime )
1948  {
1949  decayScale = self.useTime / self.decayTime;
1950  }
1951 
1952  self.curProgress -= (50 * self.useRate * decayScale);
1953  if ( self.curProgress <= 0 )
1954  {
1955  self ‪clear_progress();
1956  }
1957 
1959 
1960  if ( isdefined( self.‪onUseUpdate ) )
1961  {
1962  self [[self.onUseUpdate]]( self ‪get_claim_team(), self.curProgress / self.useTime, (50*self.useRate*decayScale) / self.useTime );
1963  }
1964 
1965  if ( self.curProgress == 0 )
1966  {
1967  self ‪set_claim_team( "none" );
1968  }
1969  }
1970  else if ( !self.numTouching[self.claimTeam] )
1971  {
1972  if ( isdefined( self.‪onEndUse ) )
1973  {
1974  self [[self.onEndUse]]( self ‪get_claim_team(), self.claimPlayer, false );
1975  }
1976 
1977  self ‪set_claim_team( "none" );
1978  self.claimPlayer = undefined;
1979  }
1980  else
1981  {
1982  self.curProgress += (50 * self.useRate);
1984  if ( isdefined( self.‪onUseUpdate ) )
1985  {
1986  self [[self.onUseUpdate]]( self ‪get_claim_team(), self.curProgress / self.useTime, (50*self.useRate) / self.useTime );
1987  }
1988  }
1989  }
1990  else if ( !self.mustMaintainClaim )
1991  {
1992  if ( isdefined( self.‪onUse ) )
1993  {
1994  self [[self.onUse]]( self.claimPlayer );
1995  }
1996 
1997  // onUse may toggle on mustMaintainClaim
1998  if ( !self.mustMaintainClaim )
1999  {
2000  self ‪set_claim_team( "none" );
2001  self.claimPlayer = undefined;
2002  }
2003  }
2004  else if ( !self.numTouching[self.claimTeam] )
2005  {
2006  if ( isdefined( self.onUnoccupied ) )
2007  {
2008  self [[self.onUnoccupied]]();
2009  }
2010 
2011  self ‪set_claim_team( "none" );
2012  self.claimPlayer = undefined;
2013  }
2014  else if ( self.canContestClaim )
2015  {
2016  numOther = ‪get_num_touching_except_team( self.claimTeam );
2017 
2018  if ( numOther > 0 )
2019  {
2020  if ( isdefined( self.onContested ) )
2021  {
2022  self [[self.onContested]]();
2023  }
2024 
2025  self ‪set_claim_team( "none" );
2026  self.claimPlayer = undefined;
2027  }
2028  }
2029  }
2030 
2031  }
2032  else
2033  {
2034  if ( self.curProgress > 0 && getTime() - self.lastClaimTime > ( self.claimGracePeriod * 1000 ) )
2035  {
2036  self ‪clear_progress();
2037  }
2038 
2039  if ( self.mustMaintainClaim && ( self ‪get_owner_team() != "none" ) )
2040  {
2041  if ( !self.numTouching[self ‪get_owner_team()] )
2042  {
2043  if ( isdefined( self.onUnoccupied ) )
2044  {
2045  self [[self.onUnoccupied]]();
2046  }
2047  }
2048  else if ( self.canContestClaim && self.lastClaimTeam != "none" && self.numTouching[self.lastClaimTeam] )
2049  {
2050  numOther = ‪get_num_touching_except_team( self.lastClaimTeam );
2051 
2052  if ( numOther == 0 )
2053  {
2054  if ( isdefined( self.onUncontested ) )
2055  {
2056  self [[self.onUncontested]](self.lastClaimTeam);
2057  }
2058  }
2059  }
2060  }
2061  }
2062 
2065  }
2066 }
2067 
2068 
2069 /*
2070 =============
2071 use_object_locked_for_team
2072 
2073 Verify that a team is not locked from using an object
2074 =============
2075 */
2077 {
2078  if ( isdefined( self.teamLock ) && isdefined( level.teams[team] ) )
2079  {
2080  return self.teamLock[team];
2081  }
2082 
2083  return false;
2084 }
2085 
2086 /*
2087 =============
2088 can_claim
2089 
2090 Determine if the player can claim
2091 =============
2092 */
2093 function ‪can_claim( player )
2094 {
2095  if ( isdefined( self.carrier ) )
2096  {
2097  return false;
2098  }
2099 
2100  if ( self.canContestClaim )
2101  {
2102  numOther = ‪get_num_touching_except_team( player.pers["team"] );
2103 
2104  if ( numOther != 0 )
2105  {
2106  return false;
2107  }
2108  }
2109 
2110  if ( !isdefined( self.keyObject ) || player ‪has_key_object( self ) )
2111  {
2112  return true;
2113  }
2114 
2115  return false;
2116 }
2117 
2118 /*
2119 =============
2120 function prox_trigger_think ("proximity" only)
2121 
2122 Handles setting the current claiming team and player, as well as starting threads to track players touching the trigger
2123 =============
2124 */
2126 {
2127  level endon ( "game_ended" );
2128  self.trigger endon( "destroyed" );
2129 
2130  entityNumber = self.entNum;
2131 
2132  ‪DEFAULT( self.trigger.remote_control_player_can_trigger, false );
2133 
2134  while ( true )
2135  {
2136  self.trigger waittill ( "trigger", player );
2137 
2138  if( !IsPlayer( player ) )
2139  {
2140  continue; //might be an AI in zombies
2141  }
2142 
2143  if ( player.using_map_vehicle === true )
2144  {
2145  if ( !isdefined( self.allow_map_vehicles ) || self.allow_map_vehicles == false )
2146  continue;
2147  }
2148 
2149  // TODO: Notify the player if they are attempting to capture a locked flag
2150  if ( !isAlive( player ) || self ‪use_object_locked_for_team( player.pers["team"] ) )
2151  {
2152  continue;
2153  }
2154 
2155  if ( ‪IS_TRUE( player.laststand ))
2156  {
2157  continue;
2158  }
2159 
2160  if ( player.spawntime == GetTime() ) // It's possible to get the "trigger" notify from the origin of the beginning of this frame when the player was dead
2161  {
2162  continue; // and then have the player spawn in, changing origins later this frame and this will no longer be valid.
2163  }
2164 
2165 // if ( player isInVehicle() )
2166 // {
2167 // continue;
2168 // }
2169 
2170  if ( self.trigger.remote_control_player_can_trigger == false )
2171  {
2172  if ( player isRemoteControlling() || player ‪util::isUsingRemote() )
2173  {
2174  continue;
2175  }
2176  }
2177 
2178  if ( ‪IS_TRUE( player.selectingLocation ) )
2179  {
2180  continue;
2181  }
2182 
2183  if ( player IsWeaponViewOnlyLinked() )
2184  {
2185  continue;
2186  }
2187 
2188  if ( self ‪is_excluded( player ) )
2189  {
2190  continue;
2191  }
2192 
2193  if( IsDefined(self.canUseObject) && ![[self.canUseObject]](player) )
2194  {
2195  continue;
2196  }
2197 
2198  if ( self ‪can_interact_with( player ) && self.claimTeam == "none" )
2199  {
2200  if ( self ‪can_claim( player ) )
2201  {
2202  ‪set_claim_team( player.pers["team"] );
2203  self.claimPlayer = player;
2204 
2205  relativeTeam = self ‪get_relative_team( player.pers["team"] );
2206  if ( isdefined( self.teamUseTimes[relativeTeam] ) )
2207  {
2208  self.useTime = self.teamUseTimes[relativeTeam];
2209  // TODO we don't store the base self.useTime setting... we should.
2210  }
2211 
2212  if ( self.useTime && isdefined( self.‪onBeginUse ) )
2213  {
2214  self [[self.onBeginUse]]( self.claimPlayer );
2215  }
2216  }
2217  else
2218  {
2219  if ( isdefined( self.‪onCantUse ) )
2220  {
2221  self [[self.onCantUse]]( player );
2222  }
2223  }
2224  }
2225 
2226  if ( isAlive( player ) && !isdefined( player.touchTriggers[entityNumber] ) )
2227  {
2228  player thread ‪trigger_touch_think( self );
2229  }
2230  }
2231 }
2232 
2233 function ‪is_excluded( player )
2234 {
2235  if ( !isdefined( self.exclusions ) )
2236  {
2237  return false;
2238  }
2239 
2240  foreach( exclusion in self.exclusions )
2241  {
2242  if ( exclusion istouching( player ) )
2243  {
2244  return true;
2245  }
2246  }
2247 
2248  return false;
2249 }
2250 
2252 {
2253  self.curProgress = 0;
2254 
2256 
2257  if ( isdefined( self.onUseClear ) )
2258  {
2259  self [[self.onUseClear]]( );
2260  }
2261 }
2262 
2263 /*
2264 =============
2265 function set_claim_team ("proximity" only)
2266 
2267 Sets this object as claimed by specified team including grace period to prevent
2268 object reset when claiming team leave trigger for short periods of time
2269 =============
2270 */
2271 function ‪set_claim_team( newTeam )
2272 {
2273  assert( newTeam != self.claimTeam );
2274 
2275  if ( self.claimTeam == "none" && getTime() - self.lastClaimTime > ( self.claimGracePeriod * 1000 ) )
2276  {
2277  self ‪clear_progress();
2278  }
2279  else if ( newTeam != "none" && newTeam != self.lastClaimTeam )
2280  {
2281  self ‪clear_progress();
2282  }
2283 
2284  self.lastClaimTeam = self.claimTeam;
2285  self.lastClaimTime = getTime();
2286  self.claimTeam = newTeam;
2287 
2288  self ‪update_use_rate();
2289 }
2290 
2291 
2293 {
2294  return self.claimTeam;
2295 }
2296 
2297 function ‪continue_trigger_touch_think(team,object) // self == player
2298 {
2299  if ( !isAlive( self ) )
2300  {
2301  return false;
2302  }
2303 
2304  if ( self.using_map_vehicle === true )
2305  {
2306  if ( !isdefined( object.allow_map_vehicles ) || object.allow_map_vehicles == false )
2307  return false;
2308  }
2309  else
2310  {
2311  if ( !isdefined( object ) || !isdefined( object.trigger ) || !isdefined( object.trigger.remote_control_player_can_trigger ) || object.trigger.remote_control_player_can_trigger == false )
2312  {
2313  if ( self isinvehicle() )
2314  {
2315  return false;
2316  }
2317  else if ( self isRemoteControlling() || self ‪util::isUsingRemote() )
2318  {
2319  return false;
2320  }
2321  }
2322  else if ( self isinvehicle() && !(self isRemoteControlling() || self ‪util::isUsingRemote()))
2323  {
2324  return false;
2325  }
2326  }
2327 
2328  if ( self ‪use_object_locked_for_team( team ) )
2329  {
2330  return false;
2331  }
2332 
2333  if ( ‪IS_TRUE( self.laststand ))
2334  {
2335  return false;
2336  }
2337 
2338  if ( !isdefined( object ) || !isdefined( object.trigger ) )
2339  return false;
2340 
2341  if( !object.trigger IsTriggerEnabled() )
2342  return false;
2343 
2344  if ( !self isTouching( object.trigger ) )
2345  {
2346  return false;
2347  }
2348 
2349  return true;
2350 }
2351 
2352 /*
2353 =============
2354 function trigger_touch_think ("proximity" only)
2355 
2356 Updates use object while player is touching the trigger and updates the players visual use bar
2357 =============
2358 */
2359 function ‪trigger_touch_think( object )
2360 {
2361  team = self.pers["team"];
2362 
2363  score = 1;
2364 
2365  object.numTouching[team] = object.numTouching[team] + score;
2366 
2367  if ( object.useTime )
2368  {
2369  object ‪update_use_rate();
2370  }
2371 
2372  touchName = "player" + self.clientid;
2373  struct = spawnstruct();
2374  struct.player = self;
2375  struct.starttime = gettime();
2376  object.touchList[team][touchName] = struct;
2377  Objective_SetPlayerUsing( object.objectiveID, self );
2378 
2379  self.touchTriggers[object.entNum] = object.trigger;
2380 
2381  if ( isdefined( object.onTouchUse ) )
2382  {
2383  object [[object.onTouchUse]]( self );
2384  }
2385 
2386  while ( self ‪continue_trigger_touch_think(team,object) )
2387  {
2388  if ( object.useTime )
2389  {
2390  self ‪update_prox_bar( object, false );
2391  }
2393  }
2394 
2395  // disconnected player will skip this code
2396  if ( isdefined( self ) )
2397  {
2398  if ( object.useTime )
2399  {
2400  self ‪update_prox_bar( object, true );
2401  }
2402  self.touchTriggers[object.entNum] = undefined;
2403  Objective_ClearPlayerUsing( object.objectiveID, self );
2404  }
2405 
2406  if ( level.gameEnded )
2407  {
2408  return;
2409  }
2410 
2411  object.touchList[team][touchName] = undefined;
2412 
2413  object.numTouching[team] = object.numTouching[team] - score;
2414  // there's a bug here because of the specialty_fastinteract, so we need to see if we're less than 1
2415  // reason being is because the team can never have less than 1 person on the flag, so if it's less than 1 then we can say no one is on it
2416  if( object.numTouching[team] < 1 )
2417  {
2418  object.numTouching[team] = 0;
2419  }
2420 
2421  if ( object.useTime )
2422  {
2423  // There was a timing bug here where a player could leave the trigger but have just completed its progress so:
2424  // If no one is touching make sure progress is not completed in the same frame
2425  if ( object.numTouching[team] <= 0 && ( object.curProgress >= object.useTime ) )
2426  {
2427  object.curProgress = object.useTime - 1;
2428  object ‪update_current_progress();
2429  }
2430  }
2431 
2432  if ( isdefined( self ) && isdefined( object.onEndTouchUse ) )
2433  {
2434  object [[object.onEndTouchUse]]( self );
2435  }
2436 
2437  object ‪update_use_rate();
2438 }
2439 
2440 
2441 /*
2442 =============
2443 function update_prox_bar ("proximity" only)
2444 
2445 Updates drawing of the players use bar when using a use object
2446 =============
2447 */
2448 function ‪update_prox_bar( object, forceRemove )
2449 {
2450  if ( object.newStyle )
2451  {
2452  return;
2453  }
2454 
2455  if ( !forceRemove && object.decayProgress )
2456  {
2457  if ( !object ‪can_interact_with( self ) )
2458  {
2459  if ( isdefined( self.proxBar ) )
2460  {
2461  self.proxBar ‪hud::hideElem();
2462  }
2463 
2464  if ( isdefined( self.proxBarText ) )
2465  {
2466  self.proxBarText ‪hud::hideElem();
2467  }
2468  return;
2469  }
2470  else
2471  {
2472  if ( !isdefined( self.proxBar ) )
2473  {
2474  self.proxBar = ‪hud::createPrimaryProgressBar();
2475  self.proxBar.lastUseRate = -1;
2476  }
2477 
2478  if ( self.pers["team"] == object.claimTeam )
2479  {
2480  if ( self.proxBar.bar.color != ( 1, 1, 1 ) )
2481  {
2482  self.proxBar.bar.color = ( 1, 1, 1 );
2483  self.proxBar.lastUseRate = -1;
2484  }
2485  }
2486  else
2487  {
2488  if ( self.proxBar.bar.color != ( 1, 0, 0 ) )
2489  {
2490  self.proxBar.bar.color = ( 1, 0, 0 );
2491  self.proxBar.lastUseRate = -1;
2492  }
2493  }
2494  }
2495  }
2496  else if ( forceRemove || !object ‪can_interact_with( self ) || self.pers["team"] != object.claimTeam )
2497  {
2498  if ( isdefined( self.proxBar ) )
2499  {
2500  self.proxBar ‪hud::hideElem();
2501  }
2502 
2503  if ( isdefined( self.proxBarText ) )
2504  {
2505  self.proxBarText ‪hud::hideElem();
2506  }
2507  return;
2508  }
2509 
2510  if ( !isdefined( self.proxBar ) )
2511  {
2512  self.proxBar = ‪hud::createPrimaryProgressBar();
2513  self.proxBar.lastUseRate = -1;
2514  self.proxBar.lastHostMigrationState = false;
2515  }
2516 
2517  if ( self.proxBar.hidden )
2518  {
2519  self.proxBar ‪hud::showElem();
2520  self.proxBar.lastUseRate = -1;
2521  self.proxBar.lastHostMigrationState = false;
2522  }
2523 
2524  if ( !isdefined( self.proxBarText ) )
2525  {
2526  self.proxBarText = ‪hud::createPrimaryProgressBarText();
2527  self.proxBarText setText( object.useText );
2528  }
2529 
2530  if ( self.proxBarText.hidden )
2531  {
2532  self.proxBarText ‪hud::showElem();
2533  self.proxBarText setText( object.useText );
2534  }
2535 
2536  if ( self.proxBar.lastUseRate != object.useRate || self.proxBar.lastHostMigrationState != isdefined( level.hostMigrationTimer ) )
2537  {
2538  if( object.curProgress > object.useTime)
2539  {
2540  object.curProgress = object.useTime;
2541  }
2542 
2543  if ( object.decayProgress && self.pers["team"] != object.claimTeam )
2544  {
2545  if ( object.curProgress > 0 )
2546  {
2547  progress = object.curProgress / object.useTime;
2548  rate = (1000 / object.useTime) * ( object.useRate * -1 );
2549  if ( isdefined( level.hostMigrationTimer ) )
2550  {
2551  rate = 0;
2552  }
2553  self.proxBar ‪hud::updateBar( progress, rate );
2554  }
2555  }
2556  else
2557  {
2558  progress = object.curProgress / object.useTime;
2559  rate = (1000 / object.useTime) * object.useRate;
2560  if ( isdefined( level.hostMigrationTimer ) )
2561  {
2562  rate = 0;
2563  }
2564  self.proxBar ‪hud::updateBar( progress, rate );
2565  }
2566  self.proxBar.lastHostMigrationState = isdefined( level.hostMigrationTimer );
2567  self.proxBar.lastUseRate = object.useRate;
2568  }
2569 }
2570 
2571 function ‪get_num_touching_except_team( ignoreTeam )
2572 {
2573  numTouching = 0;
2574  foreach( team in level.teams )
2575  {
2576  if ( ignoreTeam == team )
2577  {
2578  continue;
2579  }
2580  numTouching += self.numTouching[team];
2581  }
2582 
2583  return numTouching;
2584 }
2585 
2586 /*
2587 =============
2588 function update_use_rate ("proximity" only)
2589 
2590 Handles the rate a which a use objects progress bar is filled based on the number of players touching the trigger
2591 Stops updating if an enemy is touching the trigger
2592 =============
2593 */
2595 {
2596  numClaimants = self.numTouching[self.claimTeam];
2597  numOther = 0;
2598 
2599  numOther = ‪get_num_touching_except_team( self.claimTeam );
2600 
2601  self.useRate = 0;
2602 
2603  if ( self.decayProgress )
2604  {
2605  if ( numClaimants && !numOther )
2606  {
2607  self.useRate = numClaimants;
2608  }
2609  else if ( !numClaimants && numOther )
2610  {
2611  self.useRate = numOther;
2612  }
2613  else if ( !numClaimants && !numOther )
2614  {
2615  self.useRate = 0;
2616  }
2617  }
2618  else
2619  {
2620  if ( numClaimants && !numOther )
2621  {
2622  self.useRate = numClaimants;
2623  }
2624  }
2625 
2626  if ( isdefined( self.‪onUpdateUseRate ) )
2627  {
2628  self [[self.onUpdateUseRate]]( );
2629  }
2630 }
2631 
2632 
2633 //attachUseModel()
2634 //{
2635 // self endon("death");
2636 // self endon("disconnect");
2637 // self endon("done_using");
2638 //
2639 // wait 1.3;
2640 //
2641 // self attach( "weapon_explosives", "tag_inhand", true );
2642 // self.attachedUseModel = "weapon_explosives";
2643 //}
2644 
2645 /*
2646 =============
2647 use_hold_think
2648 
2649 Claims the use trigger for player and displays a use bar
2650 Returns true if the player sucessfully fills the use bar
2651 =============
2652 */
2653 function ‪use_hold_think( player, disableWeaponCyclingDuringHold )
2654 {
2655  player notify ( "use_hold" );
2656 
2657  if ( !‪IS_TRUE( self.dontLinkPlayerToTrigger ) )
2658  {
2659  if(!SessionModeIsMultiplayerGame()) //allow 3d person rotation for linked player since the trigger doesn't get sent to client, ToDo: make this an option
2660  {
2661  gameobject_link = ‪util::spawn_model( "tag_origin", player.origin, player.angles );
2662  player PlayerLinkTo( gameobject_link);
2663  }
2664  else
2665  {
2666  player playerLinkTo( self.trigger );
2667  player PlayerLinkedOffsetEnable();
2668  }
2669  }
2670 
2671  player clientClaimTrigger( self.trigger );
2672  player.claimTrigger = self.trigger;
2673 
2674  useWeapon = self.useWeapon;
2675 
2676  if ( isdefined( useWeapon ) )
2677  {
2678  player giveWeapon( useWeapon );
2679  player setWeaponAmmoStock( useWeapon, 0 );
2680  player setWeaponAmmoClip( useWeapon, 0 );
2681  player switchToWeapon( useWeapon );
2682  }
2683  else if ( self.keepWeapon !== true )
2684  {
2685  player ‪util::_disableWeapon();
2686  }
2687 
2688  self ‪clear_progress();
2689  self.inUse = true;
2690  self.useRate = 0;
2691  Objective_SetPlayerUsing( self.objectiveID, player );
2692  player thread ‪personal_use_bar( self );
2693 
2694  if ( disableWeaponCyclingDuringHold )
2695  {
2696  player DisableWeaponCycling();
2697  enableWeaponCyclingAfterHold = true;
2698  }
2699 
2700  ‪result = ‪use_hold_think_loop( player );
2701 
2702  self.inUse = false;
2703 
2704  if ( isdefined( player ) )
2705  {
2706  if ( enableWeaponCyclingAfterHold === true )
2707  {
2708  player EnableWeaponCycling();
2709  }
2710 
2711  Objective_ClearPlayerUsing( self.objectiveID, player );
2712  self ‪clear_progress();
2713  if ( isdefined( player.attachedUseModel ) )
2714  {
2715  player detach( player.attachedUseModel, "tag_inhand" );
2716  player.attachedUseModel = undefined;
2717  }
2718 
2719  player notify( "done_using" );
2720 
2721  if ( isdefined( useWeapon ) )
2722  {
2723  player thread ‪take_use_weapon( useWeapon );
2724  }
2725 
2726  player.claimTrigger = undefined;
2727  player clientReleaseTrigger( self.trigger );
2728 
2729  if ( isdefined( useWeapon ) )
2730  {
2732  }
2733  else if ( self.keepWeapon !== true )
2734  {
2735  player ‪util::_enableWeapon();
2736  }
2737 
2738  if ( !‪IS_TRUE( self.dontLinkPlayerToTrigger ) )
2739  {
2740  player unlink();
2741  }
2742 
2743  if ( !isAlive( player ) )
2744  {
2745  player.killedInUse = true;
2746  }
2747 
2748  if ( level.gameEnded )
2749  {
2751  }
2752  }
2753 
2754  if(isdefined(gameobject_link))
2755  {
2756  gameobject_link Delete();
2757  }
2758 
2759  return ‪result;
2760 }
2761 
2763 {
2764  player = self;
2765 
2766  wait wait_time;
2767 
2768  if ( isdefined( player ) && level.gameEnded )
2769  {
2770  player FreezeControls( true );
2771  }
2772 }
2773 
2774 function ‪take_use_weapon( useWeapon )
2775 {
2776  self endon( "use_hold" );
2777  self endon( "death" );
2778  self endon( "disconnect" );
2779  level endon( "game_ended" );
2780 
2781  while ( self getCurrentWeapon() == useWeapon && !self.throwingGrenade )
2783 
2784  self takeWeapon( useWeapon );
2785 }
2786 
2787 function ‪continue_hold_think_loop(player, waitForWeapon, timedOut, useTime)
2788 {
2789  maxWaitTime = 1.5; // must be greater than the putaway timer for all weapons
2790 
2791  if (!IsAlive(player))
2792  {
2793  return false;
2794  }
2795 
2796  if ( isdefined( player.laststand ) && player.laststand )
2797  {
2798  return false;
2799  }
2800 
2801  if ( self.curProgress >= useTime )
2802  {
2803  return false;
2804  }
2805 
2806  if ( !(player useButtonPressed()) )
2807  {
2808  return false;
2809  }
2810 
2811  if (player.throwingGrenade)
2812  {
2813  return false;
2814  }
2815 
2816  //if ( player meleeButtonPressed() )
2817  //{
2818  // return false;
2819  //}
2820 
2821  if ( player isinvehicle() )
2822  {
2823  return false;
2824  }
2825 
2826  if ( player isRemoteControlling() || player ‪util::isUsingRemote() )
2827  {
2828  return false;
2829  }
2830 
2831  if ( ‪IS_TRUE( player.selectingLocation ) )
2832  {
2833  return false;
2834  }
2835 
2836  if ( player IsWeaponViewOnlyLinked() )
2837  {
2838  return false;
2839  }
2840 
2841  if ( !(player isTouching( self.trigger ) ) )
2842  {
2843  // Make sure the code doesn't think we are too far
2844  if( !isdefined( player.cursorHintEnt ) || player.cursorHintEnt != self )
2845  {
2846  return false;
2847  }
2848  }
2849 
2850  if ( !self.useRate && !waitForWeapon )
2851  {
2852  return false;
2853  }
2854 
2855  if (waitForWeapon && timedOut > maxWaitTime)
2856  {
2857  return false;
2858  }
2859 
2860  if ( ‪IS_TRUE( self.interrupted ) )
2861  {
2862  return false;
2863  }
2864 
2865  if( level.gameEnded )
2866  {
2867  return false;
2868  }
2869 
2870  return true;
2871 }
2872 
2874 {
2875  if ( self.useTime )
2876  {
2877  if ( isdefined( self.curProgress ) )
2878  {
2879  progress = float(self.curProgress) / self.useTime;
2880  }
2881  else
2882  {
2883  progress = 0;
2884  }
2885 
2886  Objective_SetProgress( self.objectiveID, ‪math::clamp(progress,0,1) );
2887  }
2888 }
2889 
2890 function ‪use_hold_think_loop( player )
2891 {
2892  self endon("disabled");
2893 
2894  useWeapon = self.useWeapon;
2895  waitForWeapon = true;
2896  timedOut = 0;
2897 
2898  useTime = self.useTime;
2899 
2900  while( self ‪continue_hold_think_loop( player, waitForWeapon, timedOut, useTime ) )
2901  {
2902  timedOut += 0.05;
2903 
2904  if ( !isdefined( useWeapon ) || player getCurrentWeapon() == useWeapon )
2905  {
2906  self.curProgress += (50 * self.useRate);
2908  self.useRate = 1;
2909  waitForWeapon = false;
2910  }
2911  else
2912  {
2913  self.useRate = 0;
2914  }
2915 
2916  if ( SessionModeIsMultiplayerGame() )
2917  {
2918  // MP wants minimal delay always
2919 
2920  if ( self.curProgress >= useTime )
2921  {
2922  return true;
2923  }
2924 
2926  }
2927  else
2928  {
2930 
2931  if ( self.curProgress >= useTime )
2932  {
2933  ‪util::wait_network_frame(); // Let the client see the 100% progress before clearing it after returning
2934  return true;
2935  }
2936  }
2937 
2939  }
2940 
2941  return false;
2942 }
2943 
2944 /*
2945 =============
2946 personal_use_bar
2947 
2948 Displays and updates a players use bar
2949 =============
2950 */
2951 function ‪personal_use_bar( object )
2952 {
2953  self endon("disconnect");
2954 
2955  if ( object.newStyle )
2956  {
2957  return;
2958  }
2959 
2960  if( isdefined( self.useBar ) )
2961  {
2962  return;
2963  }
2964 
2965  self.useBar = ‪hud::createPrimaryProgressBar();
2966  self.useBarText = ‪hud::createPrimaryProgressBarText();
2967  self.useBarText setText( object.useText );
2968 
2969  useTime = object.useTime;
2970 
2971  lastRate = -1;
2972  lastHostMigrationState = isdefined( level.hostMigrationTimer );
2973  while ( isAlive( self ) && object.inUse && !level.gameEnded )
2974  {
2975  if ( lastRate != object.useRate || lastHostMigrationState != isdefined( level.hostMigrationTimer ) )
2976  {
2977  if( object.curProgress > useTime)
2978  {
2979  object.curProgress = useTime;
2980  }
2981 
2982  if ( object.decayProgress && self.pers["team"] != object.claimTeam )
2983  {
2984  if ( object.curProgress > 0 )
2985  {
2986  progress = object.curProgress / useTime;
2987  rate = (1000 / useTime) * ( object.useRate * -1 );
2988  if ( isdefined( level.hostMigrationTimer ) )
2989  {
2990  rate = 0;
2991  }
2992  self.proxBar ‪hud::updateBar( progress, rate );
2993  }
2994  }
2995  else
2996  {
2997  progress = object.curProgress / useTime;
2998  rate = (1000 / useTime) * object.useRate;
2999  if ( isdefined( level.hostMigrationTimer ) )
3000  {
3001  rate = 0;
3002  }
3003  self.useBar ‪hud::updateBar( progress, rate );
3004  }
3005 
3006  if ( !object.useRate )
3007  {
3008  self.useBar ‪hud::hideElem();
3009  self.useBarText ‪hud::hideElem();
3010  }
3011  else
3012  {
3013  self.useBar ‪hud::showElem();
3014  self.useBarText ‪hud::showElem();
3015  }
3016  }
3017  lastRate = object.useRate;
3018  lastHostMigrationState = isdefined( level.hostMigrationTimer );
3020  }
3021 
3022  self.useBar ‪hud::destroyElem();
3023  self.useBarText ‪hud::destroyElem();
3024 }
3025 
3026 
3027 /*
3028 =============
3029 update_trigger
3030 
3031 Displays and updates a players use bar
3032 =============
3033 */
3035 {
3036  if ( self.triggerType != "use" )
3037  {
3038  return;
3039  }
3040 
3041  if ( self.interactTeam == "none" )
3042  {
3043  self.trigger TriggerEnable( false );
3044  }
3045  else if ( ( self.interactTeam == "any" ) || !level.teamBased )
3046  {
3047  self.trigger TriggerEnable( true );
3048  self.trigger setTeamForTrigger( "none" );
3049  }
3050  else if ( self.interactTeam == "friendly" )
3051  {
3052  self.trigger TriggerEnable( true );
3053  if ( isdefined( level.teams[self.ownerTeam] ) )
3054  {
3055  self.trigger setTeamForTrigger( self.ownerTeam );
3056  }
3057  else
3058  {
3059  self.trigger TriggerEnable( false );
3060  }
3061  }
3062  else if ( self.interactTeam == "enemy" )
3063  {
3064  self.trigger TriggerEnable( true );
3065  self.trigger SetExcludeTeamForTrigger( self.ownerTeam );
3066  }
3067 }
3068 
3070 {
3071  if ( !self.newStyle )
3072  {
3073  return;
3074  }
3075 
3076  objective_team( self.objectiveID, self.ownerTeam );
3077 
3078  if ( self.visibleTeam == "any" )
3079  {
3080  objective_state( self.objectiveID, "active");
3081  objective_visibleteams( self.objectiveID, level.spawnsystem.iSPAWN_TEAMMASK["all"] );
3082  }
3083  else if ( self.visibleTeam == "friendly" )
3084  {
3085  objective_state( self.objectiveID, "active");
3086  // TODO convert level.spawnsystem.iSPAWN_TEAMMASK to be more global
3087  objective_visibleteams( self.objectiveID, level.spawnsystem.iSPAWN_TEAMMASK[self.ownerTeam] );
3088  }
3089  else if ( self.visibleTeam == "enemy" )
3090  {
3091  objective_state( self.objectiveID, "active");
3092  // TODO convert level.spawnsystem.iSPAWN_TEAMMASK to be more global
3093  objective_visibleteams( self.objectiveID, level.spawnsystem.iSPAWN_TEAMMASK["all"] & ~(level.spawnsystem.iSPAWN_TEAMMASK[self.ownerTeam]) );
3094  }
3095  else
3096  {
3097  objective_state( self.objectiveID, "invisible");
3098  objective_visibleteams( self.objectiveID, 0 );
3099  }
3100 
3101  if ( (self.type == "carryObject") || (self.type == "packObject"))
3102  {
3103  if ( isAlive( self.carrier ) )
3104  {
3105  objective_onentity( self.objectiveID, self.carrier );
3106  }
3107  else if ( IsDefined(self.objectiveOnVisuals) && self.objectiveOnVisuals )
3108  {
3109  objective_onentity( self.objectiveID, self.visuals[0] );
3110  }
3111  else
3112  {
3113  objective_clearentity( self.objectiveID );
3114  }
3115  }
3116 }
3117 
3119 {
3120  if ( self.visibleTeam == "any" )
3121  {
3122  ‪update_world_icon( "friendly", true );
3123  ‪update_world_icon( "enemy", true );
3124  }
3125  else if ( self.visibleTeam == "friendly" )
3126  {
3127  ‪update_world_icon( "friendly", true );
3128  ‪update_world_icon( "enemy", false );
3129  }
3130  else if ( self.visibleTeam == "enemy" )
3131  {
3132  ‪update_world_icon( "friendly", false );
3133  ‪update_world_icon( "enemy", true );
3134  }
3135  else
3136  {
3137  ‪update_world_icon( "friendly", false );
3138  ‪update_world_icon( "enemy", false );
3139  }
3140 }
3141 
3142 
3143 function ‪update_world_icon( relativeTeam, showIcon )
3144 {
3145  if ( self.newStyle )
3146  {
3147  return;
3148  }
3149 
3150  if ( !isdefined( self.worldIcons[relativeTeam] ) )
3151  {
3152  showIcon = false;
3153  }
3154 
3155  updateTeams = ‪get_update_teams( relativeTeam );
3156 
3157  for ( index = 0; index < updateTeams.size; index++ )
3158  {
3159  if ( !level.teamBased && updateTeams[index] != level.nonTeamBasedTeam )
3160  {
3161  continue;
3162  }
3163  opName = "objpoint_" + updateTeams[index] + "_" + self.entNum;
3164  objPoint = ‪objpoints::get_by_name( opName );
3165 
3166  objPoint notify( "stop_flashing_thread" );
3167  objPoint thread ‪objpoints::stop_flashing();
3168 
3169  if ( showIcon )
3170  {
3171  objPoint setShader( self.worldIcons[relativeTeam], level.objPointSize, level.objPointSize );
3172  objPoint fadeOverTime( 0.05 ); // overrides old fadeOverTime setting from flashing thread
3173  objPoint.alpha = objPoint.baseAlpha;
3174  objPoint.isShown = true;
3175 
3176  isWaypoint = true;
3177  if ( isdefined(self.worldIsWaypoint[relativeTeam]) )
3178  {
3179  isWaypoint = self.worldIsWaypoint[relativeTeam];
3180  }
3181 
3182  if ( isdefined( self.compassIcons[relativeTeam] ) )
3183  {
3184  objPoint setWayPoint( isWaypoint, self.worldIcons[relativeTeam] );
3185  }
3186  else
3187  {
3188  objPoint setWayPoint( isWaypoint );
3189  }
3190 
3191  if ( (self.type == "carryObject") || (self.type == "packObject"))
3192  {
3193  if ( isdefined( self.carrier ) && !‪should_ping_object( relativeTeam ) )
3194  {
3195  objPoint SetTargetEnt( self.carrier );
3196  }
3197  else
3198  {
3199  objPoint ClearTargetEnt();
3200  }
3201  }
3202  }
3203  else
3204  {
3205  objPoint fadeOverTime( 0.05 );
3206  objPoint.alpha = 0;
3207  objPoint.isShown = false;
3208  objPoint ClearTargetEnt();
3209  }
3210  }
3211 }
3212 
3213 
3215 {
3216  if ( self.visibleTeam == "any" )
3217  {
3218  ‪update_compass_icon( "friendly", true );
3219  ‪update_compass_icon( "enemy", true );
3220  }
3221  else if ( self.visibleTeam == "friendly" )
3222  {
3223  ‪update_compass_icon( "friendly", true );
3224  ‪update_compass_icon( "enemy", false );
3225  }
3226  else if ( self.visibleTeam == "enemy" )
3227  {
3228  ‪update_compass_icon( "friendly", false );
3229  ‪update_compass_icon( "enemy", true );
3230  }
3231  else
3232  {
3233  ‪update_compass_icon( "friendly", false );
3234  ‪update_compass_icon( "enemy", false );
3235  }
3236 }
3237 
3238 
3239 function ‪update_compass_icon( relativeTeam, showIcon )
3240 {
3241  if ( self.newStyle )
3242  {
3243  return;
3244  }
3245 
3246  updateTeams = ‪get_update_teams( relativeTeam );
3247 
3248  for ( index = 0; index < updateTeams.size; index++ )
3249  {
3250  showIconThisTeam = showIcon;
3251  if ( !showIconThisTeam && ‪should_show_compass_due_to_radar( updateTeams[ index ] ) )
3252  {
3253  showIconThisTeam = true;
3254  }
3255 
3256  if ( level.teamBased )
3257  {
3258  objId = self.objID[updateTeams[ index ]];
3259  }
3260  else
3261  {
3262  objId = self.objID[level.nonTeamBasedTeam];
3263  }
3264 
3265  if ( !isdefined( self.compassIcons[relativeTeam] ) || !showIconThisTeam )
3266  {
3267  if( !SessionModeIsCampaignGame() )
3268  {
3269  objective_state( objId, "invisible" );
3270  }
3271 
3272  continue;
3273  }
3274 
3275  objective_icon( objId, self.compassIcons[relativeTeam] );
3276 
3277  if( !SessionModeIsCampaignGame() )
3278  {
3279  objective_state( objId, "active" );
3280  }
3281 
3282  if ( (self.type == "carryObject") || (self.type == "packObject"))
3283  {
3284  if ( isAlive( self.carrier ) && !‪should_ping_object( relativeTeam ) )
3285  {
3286  objective_onentity( objId, self.carrier );
3287  }
3288  else
3289  {
3290  if( !SessionModeIsCampaignGame() )
3291  {
3292  objective_clearentity( objId );
3293  }
3294 
3295  objective_position( objId, self.curOrigin );
3296  }
3297  }
3298  }
3299 }
3300 
3301 function ‪hide_waypoint( e_player )
3302 {
3303  if ( isdefined( e_player ) )
3304  {
3305  Assert( IsPlayer( e_player ), "Passed a non-player entity into gameobjects::hide_waypoint()" );
3306 
3307  Objective_SetInvisibleToPlayer( self.objectiveid, e_player );
3308  }
3309  else
3310  {
3311  Objective_SetInvisibleToAll( self.objectiveid );
3312  }
3313 }
3314 
3315 function ‪show_waypoint( e_player )
3316 {
3317  if ( isdefined( e_player ) )
3318  {
3319  Assert( IsPlayer( e_player ), "Passed a non-player entity into gameobjects::hide_waypoint()" );
3320 
3321  Objective_SetVisibleToPlayer( self.objectiveid, e_player );
3322  }
3323  else
3324  {
3325  Objective_SetVisibleToAll( self.objectiveid );
3326  }
3327 }
3328 
3329 function ‪should_ping_object( relativeTeam )
3330 {
3331  if ( relativeTeam == "friendly" && self.objIDPingFriendly )
3332  {
3333  return true;
3334  }
3335  else if ( relativeTeam == "enemy" && self.objIDPingEnemy )
3336  {
3337  return true;
3338  }
3339 
3340  return false;
3341 }
3342 
3343 
3344 function ‪get_update_teams( relativeTeam )
3345 {
3346  updateTeams = [];
3347  if ( level.teamBased )
3348  {
3349  if ( relativeTeam == "friendly" )
3350  {
3351  foreach( team in level.teams )
3352  {
3353  if ( self ‪is_friendly_team( team ) )
3354  {
3355  updateTeams[updateTeams.size] = team;
3356  }
3357  }
3358  }
3359  else if ( relativeTeam == "enemy" )
3360  {
3361  foreach( team in level.teams )
3362  {
3363  if ( !self ‪is_friendly_team( team ) )
3364  {
3365  updateTeams[updateTeams.size] = team;
3366  }
3367  }
3368  }
3369  }
3370  else
3371  {
3372  if ( relativeTeam == "friendly" )
3373  {
3374  updateTeams[updateTeams.size] = level.nonTeamBasedTeam;
3375  }
3376  else
3377  {
3378  updateTeams[updateTeams.size] = "axis";
3379  }
3380  }
3381 
3382  return updateTeams;
3383 }
3384 
3386 {
3387  showCompass = false;
3388  if ( !isdefined( self.carrier ) )
3389  {
3390  return false;
3391  }
3392 
3393  if ( self.carrier hasPerk( "specialty_gpsjammer" ) == false )
3394  {
3395  if( ‪killstreaks::HasUAV( team ) )
3396  {
3397  showCompass = true;
3398  }
3399  }
3400 
3401  if( ‪killstreaks::HasSatellite( team ) )
3402  {
3403  showCompass = true;
3404  }
3405 
3406  return showCompass;
3407 }
3408 
3410 {
3411  self endon("death");
3412  self endon("carrier_cleared");
3413 
3414  while(1)
3415  {
3416  level waittill("radar_status_change");
3417  self ‪update_compass_icons();
3418  }
3419 }
3420 
3421 function private ‪_set_team( team )
3422 {
3423  self.ownerTeam = team;
3424 
3425  if ( team != "any" )
3426  {
3427  self.team = team;
3428 
3429  foreach( visual in self.visuals )
3430  {
3431  visual.team = team;
3432  }
3433  }
3434 
3435 }
3436 
3437 function ‪set_owner_team( team )
3438 {
3439  self ‪_set_team( team );
3440 
3441  self ‪update_trigger();
3443 }
3444 
3446 {
3447  return self.ownerTeam;
3448 }
3449 
3450 function ‪set_decay_time( time )
3451 {
3452  self.decayTime = int( time * 1000 );
3453 }
3454 
3455 function ‪set_use_time( time )
3456 {
3457  self.useTime = int( time * 1000 );
3458 }
3459 
3460 function ‪set_use_text( text )
3461 {
3462  self.useText = text;
3463 }
3464 
3465 function ‪set_team_use_time( relativeTeam, time )
3466 {
3467  self.teamUseTimes[relativeTeam] = int( time * 1000 );
3468 }
3469 
3470 function ‪set_team_use_text( relativeTeam, text )
3471 {
3472  self.teamUseTexts[relativeTeam] = text;
3473 }
3474 
3475 function ‪set_use_hint_text( text )
3476 {
3477  self.trigger setHintString( text );
3478 }
3479 
3480 function ‪allow_carry( relativeTeam )
3481 {
3482  ‪allow_use( relativeTeam );
3483 }
3484 
3485 function ‪allow_use( relativeTeam )
3486 {
3487  self.interactTeam = relativeTeam;
3489 }
3490 
3491 function ‪set_visible_team( relativeTeam )
3492 {
3493  self.visibleTeam = relativeTeam;
3494 
3495  if ( !‪tweakables::getTweakableValue( "hud", "showobjicons" ) )
3496  {
3497  self.visibleTeam = "none";
3498  }
3499 
3501 }
3502 
3503 function ‪set_model_visibility( visibility )
3504 {
3505  if ( visibility )
3506  {
3507  for ( index = 0; index < self.visuals.size; index++ )
3508  {
3509  self.visuals[index] show();
3510  if ( self.visuals[index].classname == "script_brushmodel" || self.visuals[index].classname == "script_model" )
3511  {
3512  self.visuals[index] thread ‪make_solid();
3513  }
3514  }
3515  }
3516  else
3517  {
3518  for ( index = 0; index < self.visuals.size; index++ )
3519  {
3520  self.visuals[index] Ghost();
3521  if ( self.visuals[index].classname == "script_brushmodel" || self.visuals[index].classname == "script_model" )
3522  {
3523  self.visuals[index] notify("changing_solidness");
3524  self.visuals[index] notsolid();
3525  }
3526  }
3527  }
3528 }
3529 
3530 function ‪make_solid()
3531 {
3532  self endon("death");
3533  self notify("changing_solidness");
3534  self endon("changing_solidness");
3535 
3536  while(1)
3537  {
3538  for ( i = 0; i < level.players.size; i++ )
3539  {
3540  if ( level.players[i] isTouching( self ) )
3541  {
3542  break;
3543  }
3544  }
3545  if ( i == level.players.size )
3546  {
3547  self solid();
3548  break;
3549  }
3550  wait .05;
3551  }
3552 }
3553 
3554 function ‪set_carrier_visible( relativeTeam )
3555 {
3556  self.carrierVisible = relativeTeam;
3557 }
3558 
3559 function ‪set_can_use( relativeTeam )
3560 {
3561  self.useTeam = relativeTeam;
3562 }
3563 
3564 function ‪set_2d_icon( relativeTeam, shader )
3565 {
3566  self.compassIcons[relativeTeam] = shader;
3568 }
3569 
3570 function ‪set_3d_icon( relativeTeam, shader )
3571 {
3572  if( !IsDefined(shader) )
3573  {
3574  self.worldIcons_disabled[relativeTeam] = true;
3575  }
3576  else
3577  {
3578  self.worldIcons_disabled[relativeTeam] = false;
3579  }
3580 
3581  self.worldIcons[relativeTeam] = shader;
3583 }
3584 
3585 // Added
3586 function ‪set_3d_icon_color( relativeTeam, v_color, alpha )
3587 {
3588  updateTeams = ‪get_update_teams( relativeTeam );
3589 
3590  for ( index = 0; index < updateTeams.size; index++ )
3591  {
3592  if ( !level.teamBased && updateTeams[index] != level.nonTeamBasedTeam )
3593  {
3594  continue;
3595  }
3596 
3597  opName = "objpoint_" + updateTeams[index] + "_" + self.entNum;
3598  objPoint = ‪objpoints::get_by_name( opName );
3599 
3600  if ( isdefined( objPoint ) )
3601  {
3602  if ( isdefined( v_color ) )
3603  {
3604  objPoint.color = v_color;
3605  }
3606 
3607  if ( isdefined( alpha ) )
3608  {
3609  objPoint.alpha = alpha;
3610  }
3611  }
3612  }
3613 }
3614 
3615 function ‪set_objective_color( relativeTeam, v_color, alpha = 1 ) // self = gameobject
3616 {
3617  if ( self.newstyle )
3618  {
3619  Objective_SetColor( self.objectiveID, v_color[ 0 ], v_color[ 1 ], v_color[ 2 ], alpha );
3620  }
3621  else
3622  {
3623  a_teams = ‪get_update_teams( relativeTeam );
3624 
3625  for ( index = 0; index < a_teams.size; index++ )
3626  {
3627  if ( !level.teamBased && a_teams[ index ] != level.nonTeamBasedTeam )
3628  {
3629  continue;
3630  }
3631 
3632  Objective_SetColor( self.objID[ a_teams[ index ] ], v_color[ 0 ], v_color[ 1 ], v_color[ 2 ], alpha );
3633  }
3634  }
3635 }
3636 
3637 function ‪set_objective_entity( entity ) // self = gameobject
3638 {
3639  if ( self.newstyle )
3640  {
3641  if ( IsDefined( self.objectiveID ) )
3642  {
3643  Objective_OnEntity( self.objectiveID, entity );
3644  }
3645  }
3646  else
3647  {
3648  a_teams = ‪gameobjects::get_update_teams( self.interactTeam );
3649 
3650  foreach ( str_team in a_teams )
3651  {
3652  Objective_OnEntity( self.objID[ str_team ], entity );
3653  }
3654  }
3655 }
3656 
3657 function ‪get_objective_ids( str_team ) // self = gameobject
3658 {
3659  a_objective_ids = [];
3660 
3661  if ( ‪IS_TRUE( self.newstyle ) )
3662  {
3663  // newStyle objectives only use one objective index
3664  ‪ARRAY_ADD( a_objective_ids, self.objectiveID );
3665  }
3666  else
3667  {
3668  // oldStyle objectives use two objective indicies
3669  a_keys = GetArrayKeys( self.objID );
3670 
3671  for ( i = 0; i < a_keys.size; i++ )
3672  {
3673  if ( !IsDefined( str_team ) || ( str_team == a_keys[ i ] ) )
3674  {
3675  ‪ARRAY_ADD( a_objective_ids, self.objID[ a_keys[ i ] ] );
3676  }
3677  }
3678 
3679  ‪ARRAY_ADD( a_objective_ids, self.objectiveID );
3680  }
3681 
3682  return a_objective_ids;
3683 }
3684 
3685 // Added
3686 // v_color
3687 // hide_distance - Hide icon if player futher away than this distance
3688 // los_check - Trace check?
3689 // ignore_ent - (optional) ignore ent in los check
3690 function ‪hide_icon_distance_and_los( v_color, hide_distance, los_check, ignore_ent )
3691 {
3692  self endon( "disabled" );
3693  self endon( "destroyed_complete" );
3694  while( 1 )
3695  {
3696  hide = 0;
3697 
3698  if( IsDefined(self.worldIcons_disabled["friendly"]) && (self.worldIcons_disabled["friendly"] == true) )
3699  {
3700  hide = 1;
3701  }
3702 
3703  if( !hide )
3704  {
3705  hide = 1;
3706  for( i=0; i<level.players.size; i++ )
3707  {
3708  n_dist = ( Distance( level.players[i].origin, self.curorigin ) );
3709  if( n_dist < hide_distance )
3710  {
3711  if( ‪IS_TRUE(los_check) )
3712  {
3713  b_cansee = level.players[i] ‪gameobject_is_player_looking_at( self.curorigin, 0.8, true, ignore_ent, 42 );
3714  if( b_cansee )
3715  {
3716  hide = 0;
3717  break;
3718  }
3719  }
3720  else
3721  {
3722  hide = 0;
3723  break;
3724  }
3725  }
3726  }
3727  }
3728 
3729  if( hide )
3730  {
3731  self ‪gameobjects::set_3d_icon_color( "friendly", v_color, 0 );
3732  }
3733  else
3734  {
3735  self ‪gameobjects::set_3d_icon_color( "friendly", v_color, 1 );
3736  }
3738  }
3739 }
3740 
3741 function ‪gameobject_is_player_looking_at( origin, dot, do_trace, ignore_ent, ignore_trace_distance )
3742 {
3743  assert(IsPlayer(self), "player_looking_at must be called on a player.");
3744 
3745  if (!isdefined(dot))
3746  {
3747  dot = .7;
3748  }
3749 
3750  if (!isdefined(do_trace))
3751  {
3752  do_trace = true;
3753  }
3754 
3755  eye = self ‪util::get_eye();
3756 
3757  delta_vec = AnglesToForward(VectorToAngles(origin - eye));
3758  view_vec = AnglesToForward(self GetPlayerAngles());
3759 
3760  new_dot = VectorDot( delta_vec, view_vec );
3761  if ( new_dot >= dot )
3762  {
3763  if (do_trace)
3764  {
3765  ‪trace = BulletTrace( eye, origin, false, ignore_ent );
3766  // If no collision, we pass
3767  if( ‪trace[ "position" ] == origin )
3768  {
3769  return( true );
3770  }
3771  // if collision is close to the origin, the trace can pass
3772  else if( IsDefined(ignore_trace_distance) )
3773  {
3774  n_mag = Distance( origin, eye );
3775  n_dist = Distance( ‪trace[ "position" ], eye );
3776  n_delta = abs( n_dist - n_mag );
3777  if( n_delta <= ignore_trace_distance )
3778  {
3779  return( true );
3780  }
3781  }
3782  }
3783  else
3784  {
3785  return true;
3786  }
3787  }
3788 
3789  return false;
3790 }
3791 
3792 // Hides both compass and world icons
3793 function ‪hide_icons( team )
3794 {
3795  // Flag which icons should be hidden
3796  if( (self.visibleTeam == "any") || (self.visibleTeam == "friendly") )
3797  {
3798  hide_friendly = true;
3799  }
3800  else
3801  {
3802  hide_friendly = false;
3803  }
3804  if( (self.visibleTeam == "any") || (self.visibleTeam == "enemy") )
3805  {
3806  hide_enemy = true;
3807  }
3808  else
3809  {
3810  hide_enemy = false;
3811  }
3812 
3813  // Hide icons
3814  self.hidden_compassIcon = [];
3815  self.hidden_worldIcon = [];
3816  if( hide_friendly == true )
3817  {
3818  self.hidden_compassIcon["friendly"] = self.compassIcons["friendly"];
3819  self.hidden_worldIcon["friendly"] = self.worldIcons["friendly"];
3820 
3821  }
3822  if( hide_enemy == true )
3823  {
3824  self.hidden_compassIcon["enemy"] = self.compassIcons["enemyy"];
3825  self.hidden_worldIcon["enemy"] = self.worldIcons["enemy"];
3826  }
3827 
3828  self ‪gameobjects::set_2d_icon( team, undefined );
3829  self ‪gameobjects::set_3d_icon( team, undefined );
3830 }
3831 
3832 // Shows hidden compass and world icons
3833 function ‪show_icons( team )
3834 {
3835  if( IsDefined(self.hidden_compassIcon[team]) )
3836  {
3837  self ‪gameobjects::set_2d_icon( team, self.hidden_compassIcon[team] );
3838  }
3839  if( IsDefined(self.hidden_worldIcon[team]) )
3840  {
3841  self ‪gameobjects::set_3d_icon( team, self.hidden_worldIcon[team] );
3842  }
3843 }
3844 
3845 function ‪set_3d_use_icon( relativeTeam, shader )
3846 {
3847  self.worldUseIcons[relativeTeam] = shader;
3848 }
3849 
3850 function ‪set_3d_is_waypoint( relativeTeam, waypoint )
3851 {
3852  self.worldIsWaypoint[relativeTeam] = waypoint;
3853 }
3854 
3855 function ‪set_carry_icon( shader )
3856 {
3857  assert(self.type == "carryObject", "for packObjects use: set_pack_icon() instead.");
3858 
3859  self.carryIcon = shader;
3860 }
3861 
3862 function ‪set_visible_carrier_model( visibleModel )
3863 {
3864  self.visibleCarrierModel = visibleModel;
3865 }
3866 
3868 {
3869  return self.visibleCarrierModel;
3870 }
3871 
3872 function ‪destroy_object( deleteTrigger, forceHide, b_connect_paths = false )
3873 {
3874  if ( !isdefined( forceHide ) )
3875  {
3876  forceHide = true;
3877  }
3878 
3879  self ‪disable_object( forceHide );
3880 
3881  foreach ( visual in self.visuals )
3882  {
3883  if ( b_connect_paths )
3884  {
3885  visual ConnectPaths();
3886  }
3887 
3888  if ( IsDefined( visual ) )
3889  {
3890  visual Ghost();
3891  visual Delete();
3892  }
3893  }
3894 
3895  self.trigger notify( "destroyed" );
3896 
3897  if ( ‪IS_TRUE( deleteTrigger ) )
3898  {
3899  self.trigger Delete();
3900  }
3901  else
3902  {
3903  self.trigger TriggerEnable( true );
3904  }
3905 
3906  self notify( "destroyed_complete" );
3907 }
3908 
3909 function ‪disable_object( forceHide )
3910 {
3911  self notify("disabled");
3912 
3913  if ( (self.type == "carryObject") || (self.type == "packObject") || ( isdefined( forceHide ) && forceHide ) )
3914  {
3915  if ( isdefined( self.carrier ) )
3916  {
3917  self.carrier ‪take_object( self );
3918  }
3919 
3920  for ( index = 0; index < self.visuals.size; index++ )
3921  {
3922  if( IsDefined(self.visuals[index]) )
3923  {
3924  self.visuals[index] Ghost();
3925  }
3926  }
3927  }
3928 
3929  self.trigger TriggerEnable( false );
3930  self ‪set_visible_team( "none" );
3931 
3932  if( isdefined( self.objectiveid ) )
3933  {
3934  objective_clearentity( self.objectiveID );
3935  }
3936 }
3937 
3938 function ‪enable_object( forceShow )
3939 {
3940  if ( (self.type == "carryObject") || (self.type == "packObject") || ( isdefined( forceShow ) && forceShow ) )
3941  {
3942  for ( index = 0; index < self.visuals.size; index++ )
3943  {
3944  self.visuals[index] show();
3945  }
3946  }
3947 
3948  self.trigger TriggerEnable( true );
3949  self ‪set_visible_team( "any" );
3950 
3951  if( isdefined( self.objectiveid ) )
3952  {
3953  objective_onentity( self.objectiveID, self );
3954  }
3955 }
3956 
3957 
3958 function ‪get_relative_team( team )
3959 {
3960  if( self.ownerTeam == "any" )
3961  {
3962  return "friendly";
3963  }
3964 
3965  if ( team == self.ownerTeam )
3966  {
3967  return "friendly";
3968  }
3969  else if ( team == ‪get_enemy_team( self.ownerTeam ) )
3970  {
3971  return "enemy";
3972  }
3973  else
3974  {
3975  return "neutral";
3976  }
3977 }
3978 
3979 
3980 function ‪is_friendly_team( team )
3981 {
3982  if ( !level.teamBased )
3983  {
3984  return true;
3985  }
3986 
3987  if ( self.ownerTeam == "any" )
3988  {
3989  return true;
3990  }
3991 
3992  if ( self.ownerTeam == team )
3993  {
3994  return true;
3995  }
3996 
3997  return false;
3998 }
3999 
4000 
4001 function ‪can_interact_with( player )
4002 {
4003  if ( player.using_map_vehicle === true )
4004  {
4005  if ( !isdefined( self.allow_map_vehicles ) || self.allow_map_vehicles == false )
4006  return false;
4007  }
4008 
4009  team = player.pers["team"];
4010  switch( self.interactTeam )
4011  {
4012  case "none":
4013  return false;
4014 
4015  case "any":
4016  return true;
4017 
4018  case "friendly":
4019  if ( level.teamBased )
4020  {
4021  if ( team == self.ownerTeam )
4022  {
4023  return true;
4024  }
4025  else
4026  {
4027  return false;
4028  }
4029  }
4030  else
4031  {
4032  if ( player == self.ownerTeam )
4033  {
4034  return true;
4035  }
4036  else
4037  {
4038  return false;
4039  }
4040  }
4041 
4042  case "enemy":
4043  if ( level.teamBased )
4044  {
4045  if ( team != self.ownerTeam )
4046  {
4047  return true;
4048  }
4049  else if ( isdefined(self.decayProgress) && self.decayProgress && self.curProgress > 0 )
4050  {
4051  return true;
4052  }
4053  else
4054  {
4055  return false;
4056  }
4057  }
4058  else
4059  {
4060  if ( player != self.ownerTeam )
4061  {
4062  return true;
4063  }
4064  else
4065  {
4066  return false;
4067  }
4068  }
4069 
4070  default:
4071  assert( 0, "invalid interactTeam" );
4072  return false;
4073  }
4074 }
4075 
4076 
4077 function ‪is_team( team )
4078 {
4079  switch( team )
4080  {
4081  case "neutral":
4082  case "any":
4083  case "none":
4084  return true;
4085  break;
4086  }
4087 
4088  if ( isdefined( level.teams[team] ) )
4089  {
4090  return true;
4091  }
4092 
4093  return false;
4094 }
4095 
4096 function ‪is_relative_team( relativeTeam )
4097 {
4098  switch( relativeTeam )
4099  {
4100  case "friendly":
4101  case "enemy":
4102  case "any":
4103  case "none":
4104  return true;
4105  break;
4106 
4107  default:
4108  return false;
4109  break;
4110  }
4111 }
4112 
4113 
4114 function ‪get_enemy_team( team )
4115 {
4116  switch( team )
4117  {
4118  case "neutral":
4119  return "none";
4120  break;
4121  // TODO MTEAM - figure out how to determine enemy team
4122  case "allies":
4123  return "axis";
4124  break;
4125 
4126  default:
4127  return "allies";
4128  break;
4129  }
4130 }
4131 
4133 {
4134  nextID = 0;
4135 
4136  if ( level.releasedObjectives.size > 0 )
4137  {
4138  nextID = level.releasedObjectives[ level.releasedObjectives.size - 1 ];
4139  level.releasedObjectives[ level.releasedObjectives.size - 1 ] = undefined;
4140  }
4141  else
4142  {
4143  nextID = level.numGametypeReservedObjectives;
4144  level.numGametypeReservedObjectives++;
4145  }
4146 
4147 /#
4148  //No longer an assert, but still print a warning so we know when it happens.
4149  if( nextId >= ‪MAX_OBJECTIVE_IDS )
4150  {
4151  println("^3SCRIPT WARNING: Ran out of objective IDs");
4152  }
4153 #/
4154 
4155  // if for some reason we ever overrun the objective array then just going
4156  // to keep using the last objective id. This should only happen in extreme
4157  // situations (ie. trying to make this happen).
4158  if ( nextId > ‪HIGHEST_OBJECTIVE_ID )
4159  {
4160  nextId = ‪HIGHEST_OBJECTIVE_ID;
4161  }
4162 
4163  return nextID;
4164 }
4165 
4166 function ‪release_obj_id( objID )
4167 {
4168  Assert( objID < level.numGametypeReservedObjectives );
4169  for ( i = 0; i < level.releasedObjectives.size; i++ )
4170  {
4171  if ( objID == level.releasedObjectives[i] && objID == ‪HIGHEST_OBJECTIVE_ID )
4172  {
4173  return;
4174  }
4175 /#
4176  Assert( objID != level.releasedObjectives[i] );
4177 #/
4178  }
4179  level.releasedObjectives[ level.releasedObjectives.size ] = objID;
4180 
4181  // reset color and alpha
4182  Objective_SetColor( objID, 1, 1, 1, 1 );
4183 
4184  // clear objective state
4185  Objective_State( objID, "empty" );
4186 }
4187 
4188 function ‪release_all_objective_ids() // self = gameobject
4189 {
4190  if ( IsDefined( self.objID ) )
4191  {
4192  a_keys = GetArrayKeys( self.objID );
4193  {
4194  for ( i = 0; i < a_keys.size; i++ )
4195  {
4196  ‪release_obj_id( self.objID[ a_keys[ i ] ] );
4197  }
4198  }
4199  }
4200 
4201  if ( IsDefined( self.objectiveID ) )
4202  {
4203  ‪release_obj_id( self.objectiveID );
4204  }
4205 }
4206 
4207 function ‪get_label()
4208 {
4209  label = self.trigger.script_label;
4210  if ( !isdefined( label ) )
4211  {
4212  label = "";
4213  return label;
4214  }
4215 
4216  if ( label[0] != "_" )
4217  {
4218  return ("_" + label);
4219  }
4220 
4221  return label;
4222 }
4223 
4224 function ‪must_maintain_claim( enabled )
4225 {
4226  self.mustMaintainClaim = enabled;
4227 }
4228 
4229 function ‪can_contest_claim( enabled )
4230 {
4231  self.canContestClaim = enabled;
4232 }
4233 
4234 function ‪set_flags( flags )
4235 {
4236  Objective_SetGamemodeFlags( self.objectiveID, flags );
4237 }
4238 
4239 function ‪get_flags( flags )
4240 {
4241  return Objective_GetGamemodeFlags( self.objectiveID );
4242 }
4243 
4244 //=====================================================================================
4245 // create_pack_object
4246 // dcs: 042314
4247 // Creates and returns a pack object
4248 // pack objects are line carry objects except you can carry more than one at a time.
4249 //=====================================================================================
4250 function ‪create_pack_object( ownerTeam, trigger, visuals, offset, objectiveName )
4251 {
4252  if(!IsDefined(level.max_packObjects))
4253  {
4254  level.max_packObjects = 4;
4255  }
4256 
4257  Assert( level.max_packObjects < 5, "packObject system not currently designed to handle more than 4 objects" );
4258 
4259  packObject = spawnStruct();
4260  packObject.type = "packObject";
4261  packObject.curOrigin = trigger.origin;
4262  packObject.entNum = trigger getEntityNumber();
4263 
4264  if ( isSubStr( trigger.classname, "use" ) )
4265  {
4266  packObject.triggerType = "use";
4267  }
4268  else
4269  {
4270  packObject.triggerType = "proximity";
4271  }
4272 
4273  // associated trigger
4274  trigger.baseOrigin = trigger.origin;
4275  packObject.trigger = trigger;
4276 
4277  packObject.useWeapon = undefined;
4278 
4279  if ( !isdefined( offset ) )
4280  {
4281  offset = (0,0,0);
4282  }
4283 
4284  packObject.offset3d = offset;
4285 
4286  packObject.newStyle = false;
4287  if ( isdefined( objectiveName ) )
4288  {
4289  if( !SessionModeIsCampaignGame() )
4290  {
4291  packObject.newStyle = true;
4292  }
4293  }
4294  else
4295  {
4296  objectiveName = &"";
4297  }
4298 
4299  // associated visual objects
4300  for ( index = 0; index < visuals.size; index++ )
4301  {
4302  visuals[index].baseOrigin = visuals[index].origin;
4303  visuals[index].baseAngles = visuals[index].angles;
4304  }
4305  packObject.visuals = visuals;
4306 
4307  packObject ‪_set_team( ownerTeam );
4308 
4309  // compass objectives
4310  packObject.compassIcons = [];
4311  packObject.objID =[];
4312  // this block will completely go away when we have fully switched to the new style
4313  if ( !packObject.newStyle )
4314  {
4315  foreach( team in level.teams )
4316  {
4317  packObject.objID[team] = ‪get_next_obj_id();
4318  }
4319  }
4320  packObject.objIDPingFriendly = false;
4321  packObject.objIDPingEnemy = false;
4322  level.objIDStart += 2;
4323 
4324  // this block will completely go away when we have fully switched to the new style
4325  if ( !packObject.newStyle )
4326  {
4327  if ( level.teamBased )
4328  {
4329  foreach ( team in level.teams )
4330  {
4331  objective_add( packObject.objID[team], "invisible", packObject.curOrigin );
4332  objective_team( packObject.objID[team], team );
4333  packObject.objPoints[team] = ‪objpoints::create( "objpoint_" + team + "_" + packObject.entNum, packObject.curOrigin + offset, team, undefined );
4334  packObject.objPoints[team].alpha = 0;
4335  }
4336  }
4337  else
4338  {
4339  // TODO MTEAM - not sure why the we only use allies in dm
4340  objective_add( packObject.objID[level.nonTeamBasedTeam], "invisible", packObject.curOrigin );
4341  packObject.objPoints[level.nonTeamBasedTeam] = ‪objpoints::create( "objpoint_"+ level.nonTeamBasedTeam + "_" + packObject.entNum, packObject.curOrigin + offset, "all", undefined );
4342  packObject.objPoints[level.nonTeamBasedTeam].alpha = 0;
4343  }
4344  }
4345 
4346  packObject.objectiveID = ‪get_next_obj_id();
4347 
4348  // new style objective
4349  if ( packObject.newStyle )
4350  {
4351  objective_add( packObject.objectiveID, "invisible", packObject.curOrigin, objectiveName );
4352  }
4353 
4354  // carrying player
4355  packObject.carrier = undefined;
4356 
4357  // misc
4358  packObject.isResetting = false;
4359  packObject.interactTeam = "none"; // "none", "any", "friendly", "enemy";
4360  packObject.allowWeapons = true;
4361  packObject.visibleCarrierModel = undefined;
4362  packObject.dropOffset = 0;
4363 
4364  // 3d world icons
4365  packObject.worldIcons = [];
4366  packObject.carrierVisible = false; // packObject only
4367  packObject.visibleTeam = "none"; // "none", "any", "friendly", "enemy";
4368  packObject.worldIsWaypoint = [];
4369 
4370  packObject.worldIcons_disabled = [];
4371 
4372  packObject.packIcon = undefined;
4373 
4374  // callbacks
4375  packObject.setDropped = undefined;
4376  packObject.onDrop = undefined;
4377  packObject.onPickup = undefined;
4378  packObject.onReset = undefined;
4379 
4380 
4381  if ( packObject.triggerType == "use" )
4382  {
4383  packObject thread ‪carry_object_use_think();
4384  }
4385  else
4386  {
4387  packObject.numTouching["neutral"] = 0;
4388  packObject.numTouching["none"] = 0;
4389  packObject.touchList["neutral"] = [];
4390  packObject.touchList["none"] = [];
4391 
4392  foreach( team in level.teams )
4393  {
4394  packObject.numTouching[team] = 0;
4395  packObject.touchList[team] = [];
4396  }
4397 
4398  packObject.curProgress = 0;
4399  packObject.useTime = 0;
4400  packObject.useRate = 0;
4401  packObject.claimTeam = "none";
4402  packObject.claimPlayer = undefined;
4403  packObject.lastClaimTeam = "none";
4404  packObject.lastClaimTime = 0;
4405  packObject.claimGracePeriod = 0;
4406  packObject.mustMaintainClaim = false;
4407  packObject.canContestClaim = false;
4408  packObject.decayProgress = false;
4409 
4410  packObject.teamUseTimes = [];
4411  packObject.teamUseTexts = [];
4412 
4413  packObject.onUse =&‪set_picked_up;
4414 
4415  packObject thread ‪use_object_prox_think();
4416 
4417  //packObject thread carry_object_prox_think();
4418  }
4419 
4420  packObject thread ‪update_carry_object_origin();
4421  packObject thread ‪update_carry_object_objective_origin();
4422 
4423  return packObject;
4424 }
4425 
4426 //=====================================================================================
4427 //give_pack_object
4428 //Set player as holding this object
4429 //Should only be called from set_picked_up
4430 //=====================================================================================
4431 #define PACK_ICON_SPLIT_X -130
4432 #define PACK_ICON_X -40
4433 #define PACK_ICON_Y -110
4434 #define SPLIT_SIZE 25
4435 #define STANDARD_SIZE 35
4436 
4437 function ‪give_pack_object( object )
4438 {
4439  self.packObject[ self.packObject.size ] = object;
4440  self thread ‪track_carrier(object);
4441 
4442  if ( !object.newStyle )
4443  {
4444  if ( isdefined( object.packIcon ))
4445  {
4446  if ( self IsSplitscreen() )
4447  {
4448  elem = ‪hud::createIcon( object.packIcon, ‪SPLIT_SIZE, ‪SPLIT_SIZE );
4449  elem.y = -90;
4450  elem.horzAlign = "right";
4451  elem.vertAlign = "bottom";
4452  }
4453  else
4454  {
4455  elem = ‪hud::createIcon( object.packIcon, ‪STANDARD_SIZE, ‪STANDARD_SIZE );
4456  elem.y = ‪PACK_ICON_Y;
4457  elem.horzAlign = "user_right";
4458  elem.vertAlign = "user_bottom";
4459  }
4460 
4461  elem.x = ‪get_packIcon_offset(self.packIcon.size);
4462  elem.alpha = 0.75;
4463  elem.hidewhileremotecontrolling = true;
4464  elem.hidewheninkillcam = true;
4465  elem.script_string = object.packIcon;
4466 
4467  self.packIcon[ self.packIcon.size ] = elem;
4468  }
4469  }
4470 }
4471 
4472 function ‪get_packIcon_offset(index)
4473 {
4474  if(!IsDefined(index))
4475  {
4476  index = 0;
4477  }
4478 
4479  if( self IsSplitscreen() )
4480  {
4481  size = ‪SPLIT_SIZE;
4482  base = ‪PACK_ICON_SPLIT_X;
4483  }
4484  else
4485  {
4486  size = ‪STANDARD_SIZE;
4487  base = ‪PACK_ICON_X;
4488  }
4489 
4490  int = base - (size * index);
4491  return int;
4492 }
4493 
4495 {
4496  if(!IsDefined(self.packIcon))
4497  {
4498  return;
4499  }
4500 
4501  if(self.packIcon.size > 0)
4502  {
4503  for( i = 0; i < self.packIcon.size; i++ )
4504  {
4505  self.packIcon[i].x = ‪get_packIcon_offset(i);
4506  }
4507  }
4508 }
4509 
4510 function ‪set_pack_icon( shader )
4511 {
4512  assert(self.type == "packObject", "for carryObjects use: set_carry_icon() instead.");
4513 
4514  self.packIcon = shader;
4515 }
4516 //=====================================================================================
4517 
‪create_use_object
‪function create_use_object(ownerTeam, trigger, visuals, offset, objectiveName, allowInitialHoldDelay=false, allowWeaponCyclingDuringHold=false)
Definition: gameobjects_shared.gsc:1491
‪set_3d_icon_color
‪function set_3d_icon_color(relativeTeam, v_color, alpha)
Definition: gameobjects_shared.gsc:3586
‪waitTillHostMigrationDone
‪function waitTillHostMigrationDone()
Definition: hostmigration_shared.gsc:193
‪use_object_use_think
‪function use_object_use_think(disableInitialHoldDelay, disableWeaponCyclingDuringHold)
Definition: gameobjects_shared.gsc:1735
‪HIGHEST_OBJECTIVE_ID
‪#define HIGHEST_OBJECTIVE_ID
Definition: gameobjects_shared.gsc:19
‪createPrimaryProgressBarText
‪function createPrimaryProgressBarText()
Definition: hud_util_shared.gsc:612
‪get_earliest_claim_player
‪function get_earliest_claim_player()
Definition: gameobjects_shared.gsc:1850
‪allow_use
‪function allow_use(relativeTeam)
Definition: gameobjects_shared.gsc:3485
‪create_pack_object
‪function create_pack_object(ownerTeam, trigger, visuals, offset, objectiveName)
Definition: gameobjects_shared.gsc:4250
‪set_owner_team
‪function set_owner_team(team)
Definition: gameobjects_shared.gsc:3437
‪set_carrier
‪function set_carrier(carrier)
Definition: gameobjects_shared.gsc:1194
‪get_update_teams
‪function get_update_teams(relativeTeam)
Definition: gameobjects_shared.gsc:3344
‪ghost_visuals
‪function ghost_visuals()
Definition: gameobjects_shared.gsc:744
‪give_pack_object
‪function give_pack_object(object)
Definition: gameobjects_shared.gsc:4437
‪onCantUse
‪function onCantUse(player)
Definition: sd.gsc:804
‪wait_take_carry_weapon
‪function wait_take_carry_weapon(weapon)
Definition: gameobjects_shared.gsc:1380
‪update_icons_and_objective
‪function update_icons_and_objective()
Definition: gameobjects_shared.gsc:1187
‪move_visuals_to_base
‪function move_visuals_to_base()
Definition: gameobjects_shared.gsc:953
‪hide_waypoint
‪function hide_waypoint(e_player)
Definition: gameobjects_shared.gsc:3301
‪MAX_OBJECTIVE_IDS
‪#define MAX_OBJECTIVE_IDS
Definition: gameobjects_shared.gsc:18
‪get_label
‪function get_label()
Definition: gameobjects_shared.gsc:4207
‪should_show_compass_due_to_radar
‪function should_show_compass_due_to_radar(team)
Definition: gameobjects_shared.gsc:3385
‪use_hold_think
‪function use_hold_think(player, disableWeaponCyclingDuringHold)
Definition: gameobjects_shared.gsc:2653
‪set_use_time
‪function set_use_time(time)
Definition: gameobjects_shared.gsc:3455
‪onUseUpdate
‪function onUseUpdate(team, progress, change)
Definition: dom.gsc:466
‪continue_hold_think_loop
‪function continue_hold_think_loop(player, waitForWeapon, timedOut, useTime)
Definition: gameobjects_shared.gsc:2787
‪register_allowed_gameobject
‪function register_allowed_gameobject(gameobject)
Definition: gameobjects_shared.gsc:67
‪on_player_spawned
‪function on_player_spawned()
Definition: gameobjects_shared.gsc:201
‪update_prox_bar
‪function update_prox_bar(object, forceRemove)
Definition: gameobjects_shared.gsc:2448
‪set_visible_carrier_model
‪function set_visible_carrier_model(visibleModel)
Definition: gameobjects_shared.gsc:3862
‪set_position
‪function set_position(origin, angles)
Definition: gameobjects_shared.gsc:1027
‪onReset
‪function onReset()
Definition: ctf.gsc:1052
‪gameObjects_dropped
‪function gameObjects_dropped()
Definition: gameobjects_shared.gsc:242
‪set_dropped
‪function set_dropped()
Definition: gameobjects_shared.gsc:1063
‪should_ping_object
‪function should_ping_object(relativeTeam)
Definition: gameobjects_shared.gsc:3329
‪is_object_away_from_home
‪function is_object_away_from_home()
Definition: gameobjects_shared.gsc:1004
‪update_trigger
‪function update_trigger()
Definition: gameobjects_shared.gsc:3034
‪set_2d_icon
‪function set_2d_icon(relativeTeam, shader)
Definition: gameobjects_shared.gsc:3564
‪is_friendly_team
‪function is_friendly_team(team)
Definition: gameobjects_shared.gsc:3980
‪clear_allowed_gameobjects
‪function clear_allowed_gameobjects()
Definition: gameobjects_shared.gsc:77
‪launch
‪function launch(ent_1, str_tag1, ent_2, str_tag2, str_beam_type)
Definition: beam_shared.csc:11
‪set_3d_icon
‪function set_3d_icon(relativeTeam, shader)
Definition: gameobjects_shared.gsc:3570
‪manual_drop_think
‪function manual_drop_think()
Definition: gameobjects_shared.gsc:1455
‪show_icons
‪function show_icons(team)
Definition: gameobjects_shared.gsc:3833
‪is_touching_any_trigger
‪function is_touching_any_trigger(triggers, minZ, maxZ)
Definition: gameobjects_shared.gsc:1232
‪get_carrier
‪function get_carrier()
Definition: gameobjects_shared.gsc:1211
‪hide_icons
‪function hide_icons(team)
Definition: gameobjects_shared.gsc:3793
‪setPoint
‪function setPoint(point, relativePoint, xOffset, yOffset, moveTime)
Definition: hud_util_shared.gsc:53
‪WaitThenFreezePlayerControlsIfGameEndedStill
‪function WaitThenFreezePlayerControlsIfGameEndedStill(wait_time=1.0)
Definition: gameobjects_shared.gsc:2762
‪getTweakableValue
‪function getTweakableValue(category, name)
Definition: _tweakables.gsc:12
‪main
‪function main()
Definition: gameobjects_shared.gsc:35
‪stop_flashing
‪function stop_flashing()
Definition: objpoints_shared.gsc:167
‪location_is_allowed
‪function location_is_allowed(entity, location)
Definition: gameobjects_shared.gsc:107
‪trace
‪function trace(from, to, target)
Definition: grapple.gsc:369
‪destroyElem
‪function destroyElem()
Definition: hud_util_shared.gsc:755
‪set_picked_up
‪function set_picked_up(player)
Definition: gameobjects_shared.gsc:654
‪set_claim_team
‪function set_claim_team(newTeam)
Definition: gameobjects_shared.gsc:2271
‪carry_object_prox_think
‪function carry_object_prox_think()
Definition: gameobjects_shared.gsc:541
‪get_visible_carrier_model
‪function get_visible_carrier_model()
Definition: gameobjects_shared.gsc:3867
‪on_laststand
‪function on_laststand(func, obj)
Definition: callbacks_shared.gsc:543
‪update_use_rate
‪function update_use_rate()
Definition: gameobjects_shared.gsc:2594
‪set_3d_use_icon
‪function set_3d_use_icon(relativeTeam, shader)
Definition: gameobjects_shared.gsc:3845
‪must_maintain_claim
‪function must_maintain_claim(enabled)
Definition: gameobjects_shared.gsc:4224
‪waittill_any_timeout
‪function waittill_any_timeout(n_timeout, string1, string2, string3, string4, string5)
Definition: util_shared.csc:423
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪allow_carry
‪function allow_carry(relativeTeam)
Definition: gameobjects_shared.gsc:3480
‪_enableWeapon
‪function _enableWeapon()
Definition: util_shared.gsc:1145
‪set_flags
‪function set_flags(flags)
Definition: gameobjects_shared.gsc:4234
‪update_world_icons
‪function update_world_icons()
Definition: gameobjects_shared.gsc:3118
‪pickup_object_delay
‪function pickup_object_delay(origin)
Definition: gameobjects_shared.gsc:624
‪update_current_progress
‪function update_current_progress()
Definition: gameobjects_shared.gsc:2873
‪update_compass_icon
‪function update_compass_icon(relativeTeam, showIcon)
Definition: gameobjects_shared.gsc:3239
‪set_objective_entity
‪function set_objective_entity(entity)
Definition: gameobjects_shared.gsc:3637
‪use
‪function use(str_name, str_key="targetname", ent, b_assert=true)
Definition: trigger_shared.gsc:1059
‪spawn_model
‪function spawn_model(n_client, str_model, origin=(0, 0, 0), angles=(0, 0, 0))
Definition: util_shared.csc:92
‪get_next_obj_id
‪function get_next_obj_id()
Definition: gameobjects_shared.gsc:4132
‪set_key_object
‪function set_key_object(object)
Definition: gameobjects_shared.gsc:1674
‪take_use_weapon
‪function take_use_weapon(useWeapon)
Definition: gameobjects_shared.gsc:2774
‪set_team_use_time
‪function set_team_use_time(relativeTeam, time)
Definition: gameobjects_shared.gsc:3465
‪get_by_name
‪function get_by_name(name)
Definition: objpoints_shared.gsc:128
‪isUsingRemote
‪function isUsingRemote()
Definition: util_shared.gsc:2705
‪take_object
‪function take_object(object)
Definition: gameobjects_shared.gsc:1307
‪set_decay_time
‪function set_decay_time(time)
Definition: gameobjects_shared.gsc:3450
‪hideElem
‪function hideElem()
Definition: hud_util_shared.gsc:673
‪should_be_reset
‪function should_be_reset(minZ, maxZ, testHurtTriggers)
Definition: gameobjects_shared.gsc:1247
‪has_key_object
‪function has_key_object(use)
Definition: gameobjects_shared.gsc:1699
‪filter_script_vehicles_from_vehicle_descriptors
‪function filter_script_vehicles_from_vehicle_descriptors(allowed_game_modes)
Definition: gameobjects_shared.gsc:155
‪PACK_ICON_Y
‪#define PACK_ICON_Y
Definition: gameobjects_shared.gsc:4433
‪update_world_icon
‪function update_world_icon(relativeTeam, showIcon)
Definition: gameobjects_shared.gsc:3143
‪get_flags
‪function get_flags(flags)
Definition: gameobjects_shared.gsc:4239
‪update_carry_object_objective_origin
‪function update_carry_object_objective_origin()
Definition: gameobjects_shared.gsc:836
‪get_num_touching_except_team
‪function get_num_touching_except_team(ignoreTeam)
Definition: gameobjects_shared.gsc:2571
‪switch_to_last_non_killstreak_weapon
‪function switch_to_last_non_killstreak_weapon(immediate, awayfromBall)
Definition: killstreaks_shared.gsc:36
‪on_death
‪function on_death()
Definition: gameobjects_shared.gsc:218
‪set_model_visibility
‪function set_model_visibility(visibility)
Definition: gameobjects_shared.gsc:3503
‪release_obj_id
‪function release_obj_id(objID)
Definition: gameobjects_shared.gsc:4166
‪get_owner_team
‪function get_owner_team()
Definition: gameobjects_shared.gsc:3445
‪onEndUse
‪function onEndUse(team, player, success)
Definition: dom.gsc:524
‪createPrimaryProgressBar
‪function createPrimaryProgressBar()
Definition: hud_util_shared.gsc:602
‪detach_all_weapons
‪function detach_all_weapons()
Definition: weapons_shared.gsc:55
‪DEFAULT
‪#define DEFAULT(__var, __default)
Definition: shared.gsh:270
‪on_spawned
‪function on_spawned(func, obj)
Definition: callbacks_shared.csc:245
‪STANDARD_SIZE
‪#define STANDARD_SIZE
Definition: gameobjects_shared.gsc:4435
‪return_home
‪function return_home()
Definition: gameobjects_shared.gsc:971
‪force_stowed_weapon_update
‪function force_stowed_weapon_update()
Definition: weapons_shared.gsc:36
‪release_all_objective_ids
‪function release_all_objective_ids()
Definition: gameobjects_shared.gsc:4188
‪hide_icon_distance_and_los
‪function hide_icon_distance_and_los(v_color, hide_distance, los_check, ignore_ent)
Definition: gameobjects_shared.gsc:3690
‪wait_network_frame
‪function wait_network_frame(n_count=1)
Definition: util_shared.gsc:64
‪updateBar
‪function updateBar(barFrac, rateOfChange)
Definition: hud_util_shared.gsc:294
‪set_visible_team
‪function set_visible_team(relativeTeam)
Definition: gameobjects_shared.gsc:3491
‪show_waypoint
‪function show_waypoint(e_player)
Definition: gameobjects_shared.gsc:3315
‪take_carry_weapon
‪function take_carry_weapon(weapon)
Definition: gameobjects_shared.gsc:1398
‪CARRY_ICON_Y
‪#define CARRY_ICON_Y
Definition: gameobjects_shared.gsc:16
‪use_object_prox_think
‪function use_object_prox_think()
Definition: gameobjects_shared.gsc:1884
‪set_pack_icon
‪function set_pack_icon(shader)
Definition: gameobjects_shared.gsc:4510
‪_disableWeapon
‪function _disableWeapon()
Definition: util_shared.gsc:1137
‪onBeginUse
‪function onBeginUse(player)
Definition: dom.gsc:449
‪enable_object
‪function enable_object(forceShow)
Definition: gameobjects_shared.gsc:3938
‪use_object_onUse
‪function use_object_onUse(player)
Definition: gameobjects_shared.gsc:1834
‪HasSatellite
‪function HasSatellite(team_or_entnum)
Definition: _satellite.gsc:259
‪can_interact_with
‪function can_interact_with(player)
Definition: gameobjects_shared.gsc:4001
‪update_compass_icons
‪function update_compass_icons()
Definition: gameobjects_shared.gsc:3214
‪on_player_last_stand
‪function on_player_last_stand()
Definition: gameobjects_shared.gsc:237
‪track_carrier
‪function track_carrier(object)
Definition: gameobjects_shared.gsc:1423
‪get_packIcon_offset
‪function get_packIcon_offset(index)
Definition: gameobjects_shared.gsc:4472
‪take_carry_weapon_on_death
‪function take_carry_weapon_on_death(weapon)
Definition: gameobjects_shared.gsc:1390
‪is_excluded
‪function is_excluded(player)
Definition: gameobjects_shared.gsc:2233
‪ARRAY_ADD
‪#define ARRAY_ADD(__array, __item)
Definition: shared.gsh:304
‪create
‪function create(name, origin, team, shader, alpha, scale)
Definition: objpoints_shared.gsc:32
‪HasUAV
‪function HasUAV(team_or_entnum)
Definition: _uav.gsc:304
‪SERVER_FRAME
‪#define SERVER_FRAME
Definition: shared.gsh:264
‪showElem
‪function showElem()
Definition: hud_util_shared.gsc:695
‪get_claim_team
‪function get_claim_team()
Definition: gameobjects_shared.gsc:2292
‪_set_team
‪function private _set_team(team)
Definition: gameobjects_shared.gsc:3421
‪__init__
‪function __init__()
Definition: gameobjects_shared.gsc:25
‪PHYSICS_TRACE_MASK_PLAYER
‪#define PHYSICS_TRACE_MASK_PLAYER
Definition: shared.gsh:135
‪set_carry_icon
‪function set_carry_icon(shader)
Definition: gameobjects_shared.gsc:3855
‪SPLIT_SIZE
‪#define SPLIT_SIZE
Definition: gameobjects_shared.gsc:4434
‪trigger_touch_think
‪function trigger_touch_think(object)
Definition: gameobjects_shared.gsc:2359
‪on_disconnect
‪function on_disconnect()
Definition: gameobjects_shared.gsc:229
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪PACK_ICON_SPLIT_X
‪#define PACK_ICON_SPLIT_X
Definition: gameobjects_shared.gsc:4431
‪get_relative_team
‪function get_relative_team(team)
Definition: gameobjects_shared.gsc:3958
‪set_carrier_visible
‪function set_carrier_visible(relativeTeam)
Definition: gameobjects_shared.gsc:3554
‪Spawn
‪function Spawn(parent, onDeathCallback)
Definition: _flak_drone.gsc:427
‪onUpdateUseRate
‪function onUpdateUseRate()
Definition: dom.gsc:1683
‪create_carry_object
‪function create_carry_object(ownerTeam, trigger, visuals, offset, objectiveName, hitSound)
Definition: gameobjects_shared.gsc:266
‪update_objective
‪function update_objective()
Definition: gameobjects_shared.gsc:3069
‪set_use_hint_text
‪function set_use_hint_text(text)
Definition: gameobjects_shared.gsc:3475
‪onUse
‪function onUse(player)
Definition: _dogtags.gsc:146
‪entity_is_allowed
‪function entity_is_allowed(entity, allowed_game_modes)
Definition: gameobjects_shared.gsc:83
‪set_objective_color
‪function set_objective_color(relativeTeam, v_color, alpha=1)
Definition: gameobjects_shared.gsc:3615
‪onDrop
‪function onDrop(player)
Definition: ctf.gsc:707
‪clear_carrier
‪function clear_carrier()
Definition: gameobjects_shared.gsc:1217
‪can_claim
‪function can_claim(player)
Definition: gameobjects_shared.gsc:2093
‪can_contest_claim
‪function can_contest_claim(enabled)
Definition: gameobjects_shared.gsc:4229
‪gameobject_is_player_looking_at
‪function gameobject_is_player_looking_at(origin, dot, do_trace, ignore_ent, ignore_trace_distance)
Definition: gameobjects_shared.gsc:3741
‪is_relative_team
‪function is_relative_team(relativeTeam)
Definition: gameobjects_shared.gsc:4096
‪pickup_timeout
‪function pickup_timeout(minZ, maxZ)
Definition: gameobjects_shared.gsc:1272
‪set_drop_offset
‪function set_drop_offset(height)
Definition: gameobjects_shared.gsc:1051
‪personal_use_bar
‪function personal_use_bar(object)
Definition: gameobjects_shared.gsc:2951
‪PACK_ICON_X
‪#define PACK_ICON_X
Definition: gameobjects_shared.gsc:4432
‪use_object_locked_for_team
‪function use_object_locked_for_team(team)
Definition: gameobjects_shared.gsc:2076
‪update_origin
‪function update_origin(origin)
Definition: objpoints_shared.gsc:108
‪set_3d_is_waypoint
‪function set_3d_is_waypoint(relativeTeam, waypoint)
Definition: gameobjects_shared.gsc:3850
‪set_can_use
‪function set_can_use(relativeTeam)
Definition: gameobjects_shared.gsc:3559
‪set_use_text
‪function set_use_text(text)
Definition: gameobjects_shared.gsc:3460
‪is_touching_any_trigger_key_value
‪function is_touching_any_trigger_key_value(value, key, minZ, maxZ)
Definition: gameobjects_shared.gsc:1242
‪unlink_grenades
‪function unlink_grenades()
Definition: gameobjects_shared.gsc:715
‪make_solid
‪function make_solid()
Definition: gameobjects_shared.gsc:3530
‪is_team
‪function is_team(team)
Definition: gameobjects_shared.gsc:4077
‪clamp
‪function clamp(val, val_min, val_max)
Definition: math_shared.csc:16
‪update_visibility_according_to_radar
‪function update_visibility_according_to_radar()
Definition: gameobjects_shared.gsc:3409
‪use_hold_think_loop
‪function use_hold_think_loop(player)
Definition: gameobjects_shared.gsc:2890
‪result
‪function result(death, attacker, mod, weapon)
Definition: _zm_aat_blast_furnace.gsc:46
‪carry_object_use_think
‪function carry_object_use_think()
Definition: gameobjects_shared.gsc:461
‪prox_trigger_think
‪function prox_trigger_think()
Definition: gameobjects_shared.gsc:2125
‪continue_trigger_touch_think
‪function continue_trigger_touch_think(team, object)
Definition: gameobjects_shared.gsc:2297
‪get_objective_ids
‪function get_objective_ids(str_team)
Definition: gameobjects_shared.gsc:3657
‪createIcon
‪function createIcon(shader, width, height)
Definition: hud_util_shared.gsc:417
‪give_object
‪function give_object(object)
Definition: gameobjects_shared.gsc:872
‪destroy_object
‪function destroy_object(deleteTrigger, forceHide, b_connect_paths=false)
Definition: gameobjects_shared.gsc:3872
‪adjust_remaining_packIcons
‪function adjust_remaining_packIcons()
Definition: gameobjects_shared.gsc:4494
‪CARRY_ICON_X
‪#define CARRY_ICON_X
Definition: gameobjects_shared.gsc:15
‪onPickup
‪function onPickup(event)
Definition: _dogtags.gsc:225
‪clear_progress
‪function clear_progress()
Definition: gameobjects_shared.gsc:2251
‪get_enemy_team
‪function get_enemy_team(team)
Definition: gameobjects_shared.gsc:4114
‪update_carry_object_origin
‪function update_carry_object_origin()
Definition: gameobjects_shared.gsc:753
‪disable_object
‪function disable_object(forceHide)
Definition: gameobjects_shared.gsc:3909
‪wait_endon
‪function wait_endon(waitTime, endOnString, endonString2, endonString3, endonString4)
Definition: _util.gsc:396
‪set_team_use_text
‪function set_team_use_text(relativeTeam, text)
Definition: gameobjects_shared.gsc:3470
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪get_eye
‪function get_eye()
Definition: util_shared.csc:948