‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_incendiary.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\callbacks_shared;
4 #using scripts\shared\challenges_shared;
5 #using scripts\shared\clientfield_shared;
6 #using scripts\shared\damagefeedback_shared;
7 #using scripts\shared\entityheadicons_shared;
8 #using scripts\shared\killcam_shared;
9 #using scripts\shared\scoreevents_shared;
10 #using scripts\shared\system_shared;
11 #using scripts\shared\util_shared;
12 #using scripts\shared\weapons\_tacticalinsertion;
13 #using scripts\shared\weapons\_weaponobjects;
14 #using scripts\shared\_burnplayer;
15 
16 #insert scripts\shared\shared.gsh;
17 #insert scripts\shared\version.gsh;
18 
19 
20 #namespace incendiary;
21 
22 ‪REGISTER_SYSTEM( "incendiary_grenade", &‪init_shared, undefined )
23 
24 
25 function ‪init_shared()
26 {
27  level.incendiaryfireDamage = GetDvarInt( "scr_incendiaryfireDamage", 35 ); // how much damage will the fire do each tick
28  level.incendiaryfireDamageHardcore = GetDvarInt( "scr_incendiaryfireDamageHardcore", 15 ); // how much damage will the fire do each tick in hardcore
29  level.incendiaryfireDuration = GetDvarInt ("scr_incendiaryfireDuration", 5 ); // time damage triggers will last.
30  level.incendiaryfxDuration = GetDvarFloat( "scr_incendiaryfxDuration", 0.4 ); // Incendiary fx duration
31  level.incendiaryDamageRadius = GetDvarInt( "scr_incendiaryDamageRadius", 125 ); // radius of individual damages
32  level.incendiaryfireDamageTickTime = GetDvarFloat( "scr_incendiaryfireDamageTickTime", 1 ); // time between damage hits
33 
34 
35  level.incendiaryDamageThisTick = [];
36 
38 }
39 
40 function ‪create_incendiary_watcher() // self == player
41 {
42  watcher = self ‪weaponobjects::createUseWeaponObjectWatcher( "incendiary_grenade", self.team );
43 
44  watcher.onSpawn = &‪incendiary_system_spawn;
45 }
46 
47 function ‪incendiary_system_spawn( watcher, player ) // self == incendiary grenade
48 {
49  player endon( "death" );
50  player endon( "disconnect" );
51  level endon( "game_ended" );
52 
53  player AddWeaponStat( self.weapon, "used", 1 );
54  thread ‪watchForExplode( player );
55 }
56 
57 
58 function ‪watchForExplode( owner )
59 {
60  self endon( "hacked" );
61  self endon( "delete" );
62 
63  killCamEnt = ‪spawn( "script_model", self.origin );
64  killCamEnt ‪util::deleteAfterTime( 15.0 );
65  killCamEnt.startTime = gettime();
66  killCamEnt linkto( self );
67  killCamEnt setWeapon( self.weapon );
68 
70 
71  self waittill( "projectile_impact_explode", origin, normal, surface );
72  killCamEnt unlink();
73  PlaySoundAtPosition ("wpn_incendiary_core_start" ,self.origin);
74 
75  ‪generateLocations( origin, owner, normal, killCamEnt );
76 }
77 
78 function ‪getstepoutdistance( normal )
79 {
80  if ( normal[2] < 0.5 )
81  {
82  stepoutdistance = normal * GetDvarInt( "scr_incendiary_stepout_wall", 50 );
83  }
84  else
85  {
86  stepoutdistance = normal * GetDvarInt( "scr_incendiary_stepout_ground", 12 );
87  }
88  return stepoutdistance;
89 }
90 
91 function ‪generateLocations( position, owner, normal, killCamEnt )
92 {
93  startPos = position + ‪getstepoutdistance( normal );
94  desiredEndPos = startPos + ( 0, 0, 60 );
95  physTrace = PhysicsTrace( startPos, desiredEndPos, ( -4, -4, -4 ), ( 4, 4, 4 ), self, ‪PHYSICS_TRACE_MASK_PHYSICS );
96  goalPos = ( ( physTrace[ "fraction" ] < 1 ) ? physTrace[ "position"] : desiredEndPos );
97 
98  killCamEnt moveto( goalPos, 0.5 );
99  rotation = RandomInt( 360 );
100 
101  if ( normal[2] < 0.1 ) // vertical wall
102  {
103  black = ( 0.1, 0.1, 0.1 );
104 
105  ‪trace = ‪hitPos( startPos, startpos + ( -normal * 70 ) + ( 0,0, -1 ) * 70, black );
106  tracePosition = ‪trace["position"];
107  incendiaryGrenade = GetWeapon( "incendiary_fire" );
108 
109  if ( ‪trace["fraction"] < 0.9 )
110  {
111  wallnormal = ‪trace["normal"];
112  SpawnTimedFX( incendiaryGrenade, ‪trace["position"], wallnormal, level.incendiaryfireDuration, self.team );
113  }
114  }
115 
116  fxCount = GetDvarInt( "scr_incendiary_fx_count", 6 );
117  ‪spawnAllLocs( owner, startPos, normal, 1, rotation, killcament, fxCount );
118 }
119 
120 function ‪getLocationForFX( startPos, fxIndex, fxCount, defaultDistance, rotation )
121 {
122  currentAngle = ( ( 360 / fxCount ) * fxIndex );
123  cosCurrent = cos( currentAngle + rotation );
124  sinCurrent = sin( currentAngle + rotation );
125 
126  return startPos + ( defaultDistance * cosCurrent, defaultDistance * sinCurrent, 0 );
127 }
128 
129 function ‪spawnAllLocs( owner, startPos, normal, multiplier, rotation, killcament, fxCount )
130 {
131  defaultDistance = GetDvarInt( "scr_incendiary_trace_distance", 220 ) * multiplier;
132  defaultDropDistance = GetDvarInt( "scr_incendiary_trace_down_distance", 90 );
133 
134  // DROCHE:TODO
135  // if we are going to keep this grenade this should be moved to code
136 
137  colorArray = [];
138  colorArray[colorArray.size] = ( 0.9, 0.2, 0.2 );
139  colorArray[colorArray.size] = ( 0.2, 0.9, 0.2 );
140  colorArray[colorArray.size] = ( 0.2, 0.2, 0.9 );
141  colorArray[colorArray.size] = ( 0.9, 0.9, 0.9 );
142 
143 
144  locations = [];
145  locations["color"] = [];
146  locations["loc"] = [];
147  locations["tracePos"] = [];
148  locations["distSqrd"] = [];
149  locations["fxtoplay"] = [];
150  locations["radius"] = [];
151 
152 
153  for( fxIndex = 0; fxIndex < fxCount; fxIndex++ )
154  {
155  locations["point"][fxIndex] = ‪getLocationForFX( startPos, fxIndex, fxCount, defaultDistance, rotation );
156  locations["color"][fxIndex] = colorArray[fxIndex % colorArray.size];
157  }
158 
159  for ( count = 0; count < fxCount; count++ )
160  {
161  ‪trace = ‪hitPos( startPos, locations["point"][count], locations["color"][count] );
162  tracePosition = ‪trace["position"];
163  locations["tracePos"][count] = tracePosition;
164 
165  if ( ‪trace["fraction"] < 0.7 )
166  {
167  locations["loc"][count] = tracePosition;
168  locations["normal"][count] = ‪trace["normal"];
169  continue;
170  }
171 
172  average = startPos/2 + tracePosition/2;
173 
174  ‪trace = ‪hitPos( average, average - ( 0, 0, defaultDropDistance ), locations["color"][count] );
175  if ( ‪trace["fraction"] != 1 )
176  {
177  locations["loc"][count] = ‪trace["position"];
178  locations["normal"][count] = ‪trace["normal"];
179  }
180  }
181 
182  // startPos = startPos - getstepoutdistance( normal ); // start pos is already a good position for fx, we are using a different sized trigger now.
183 
184  incendiaryGrenade = GetWeapon( "incendiary_fire" );
185 
186  SpawnTimedFX( incendiaryGrenade, startPos, normal, level.incendiaryfireDuration, self.team );
187 
188  level.incendiaryDamageRadius = GetDvarInt( "scr_incendiaryDamageRadius", level.incendiaryDamageRadius );
189 
190  thread ‪damageEffectArea ( owner, startPos, level.incendiaryDamageRadius, level.incendiaryDamageRadius, killCamEnt );
191 
192  for ( count = 0; count < locations["point"].size; count++ )
193  {
194  if ( isdefined ( locations["loc"][count] ) )
195  {
196  normal = locations["normal"][count];
197 
198  SpawnTimedFX( incendiaryGrenade, locations["loc"][count], normal, level.incendiaryfireDuration, self.team );
199  }
200  }
201 }
202 
203 function ‪damageEffectArea ( owner, position, radius, height, killCamEnt )
204 {
205  trigger_radius_position = position - ( 0 , 0, height );
206  trigger_radius_height = height * 2;
207 
208  fireEffectArea = ‪spawn( "trigger_radius", trigger_radius_position, 0, radius, trigger_radius_height );
209 
210  // Create head icon
211 // objective = GetEquipmentHeadObjective( GetWeapon( "incendiary_grenade" ) );
212 // killCamEnt entityheadicons::setEntityHeadIcon( owner.pers["team"], owner, (0,0,0), objective );
213 
214 
215  // raps stuff
216  if ( isdefined( level.rapsOnBurnRaps ) )
217  {
218  owner thread [[level.rapsOnBurnRaps]]( fireEffectArea );
219  }
220 
221  // loop variables
222  loopWaitTime = level.incendiaryFireDamageTickTime;
223  durationOfIncendiary = level.incendiaryFireDuration;
224 
225  // loop for the duration of the effect
226  while (durationOfIncendiary > 0)
227  {
228  durationOfIncendiary -= loopWaitTime;
229  damageApplied = false;
230 
231  potential_targets = self ‪getPotentialTargets( owner );
232  foreach( target in potential_targets )
233  {
234  self ‪tryToApplyFireDamage( target, owner, position, fireEffectArea, loopWaitTime, killcament );
235  }
236 
237  wait (loopWaitTime);
238  }
239 
240  // Delete head icon
241  if ( isdefined( killCamEnt ) )
243  // clean up
244  fireEffectArea delete();
245 }
246 
247 function ‪getPotentialTargets( owner ) // self == incendiary grenade
248 {
249  // try getting team based targets first
250  owner_team = ( isdefined( owner ) ? owner.team : undefined );
251  if ( level.teambased && isdefined( owner_team ) && level.friendlyfire == 0 )
252  {
253  enemy_team = ( owner_team == "axis" ? "allies" : "axis" );
254  potential_targets = [];
255  potential_targets = ArrayCombine( potential_targets, GetPlayers( enemy_team ), false, false );
256  potential_targets = ArrayCombine( potential_targets, GetAITeamArray( enemy_team ), false, false );
257  potential_targets = ArrayCombine( potential_targets, GetVehicleTeamArray( enemy_team ), false, false );
258  potential_targets[ potential_targets.size ] = owner;
259  return potential_targets;
260  }
261 
262  // now get all targets
263  all_targets = [];
264  all_targets = ArrayCombine( all_targets, level.players, false, false );
265  all_targets = ArrayCombine( all_targets, GetAIArray(), false, false );
266  all_targets = ArrayCombine( all_targets, GetVehicleArray(), false, false );
267 
268  // if this is hardcore, then every entity is a potential target
269  if ( level.friendlyfire > 0 )
270  return all_targets;
271 
272  // remove all targets not on the same team, except owner
273  potential_targets = [];
274  foreach( target in all_targets )
275  {
276  if ( !isdefined( target ) )
277  continue;
278 
279  if( !isdefined( target.team ) )
280  continue;
281 
282  if( isdefined( owner ) )
283  {
284  if( target != owner )
285  {
286  if( !isdefined( owner_team ) )
287  continue;
288 
289  if( target.team == owner_team )
290  continue;
291  }
292  }
293  else
294  {
295  if ( !isdefined( self ) )
296  continue;
297 
298  if( !isdefined( self.team ) )
299  continue;
300 
301  if( target.team == self.team )
302  continue;
303  }
304 
305  potential_targets[ potential_targets.size ] = target;
306  }
307 
308  return potential_targets;
309 }
310 
311 function ‪tryToApplyFireDamage( target, owner, position, fireEffectArea, resetFireTime, killcament ) // self == incendiary grenade
312 {
313  // see if we're not in the fire area
314  if ( ( !isdefined(target.infireArea) ) || (target.infireArea == false) )
315  {
316  // since we're not in the poison area, now see if we're in the fire area
317  if ( target istouching(fireEffectArea) && ( !isdefined(target.sessionstate) || target.sessionstate == "playing" ) )
318  {
319  ‪trace = bullettrace( position, target GetShootAtPos(), false, target, true );
320 
321  if ( ‪trace["fraction"] == 1 )
322  {
323  target.lastburnedBy = owner;
324  target thread ‪damageInFireArea( fireEffectArea, killcament, ‪trace, position, resetFireTime );
325  }
326  }
327  }
328 }
329 
330 function ‪damageInFireArea( fireEffectArea, killcament, ‪trace, position, resetFireTime ) // self == player in fire area
331 {
332  self endon( "disconnect" );
333  self endon( "death" );
334 
335  ‪timer = 0;
336 
337  ‪damage = level.incendiaryfireDamage;
338  if( level.hardcoreMode )
339  {
340  ‪damage = level.incendiaryfireDamageHardcore;
341  }
342 
343  if ( ‪canDoFireDamage( killCamEnt, self, resetFireTime ) )
344  {
345  self DoDamage( ‪damage, fireEffectArea.origin, self.lastburnedBy, killCamEnt, "none", "MOD_BURNED", 0, GetWeapon( "incendiary_fire" ) );
346 
347  entnum = self getentitynumber();
348 
349  self thread ‪sndFireDamage();
350  }
351 }
352 
353 
355 {
356  self notify( "sndFire" );
357  self endon( "death" );
358  self endon( "disconnect" );
359  self endon( "sndFire" );
360 
361  if( !isdefined( self.sndFireEnt ) )
362  {
363  self.sndFireEnt = ‪spawn( "script_origin", self.origin );
364  self.sndFireEnt linkto( self, "tag_origin" );
365  self.sndFireEnt playsound( "chr_burn_start" );
366  self thread ‪sndFireDamage_DeleteEnt(self.sndFireEnt);
367  }
368 
369  self.sndFireEnt playloopsound( "chr_burn_start_loop", .5 );
370  wait(3);
371  self.sndFireEnt delete();
372  self.sndFireEnt = undefined;
373 }
375 {
376  self endon( "disconnect" );
377  self waittill( "death" );
378 
379  if( isdefined( ent ) )
380  ent delete(); //pfx_fire_incendiary
381 }
382 
383 
384 function ‪hitPos( start, ‪end, color )
385 {
386  ‪trace = bullettrace( start, ‪end, false, undefined );
387 
388  return ‪trace;
389 }
390 
391 function ‪canDoFireDamage( killCamEnt, victim, resetFireTime )
392 {
393  entNum = victim getentitynumber();
394  if ( !isdefined( level.incendiaryDamageThisTick[entNum] ) )
395  {
396  level.incendiaryDamageThisTick[entNum] = 0;
397  level thread ‪resetFireDamage( entnum, resetFireTime );
398  return true;
399  }
400 
401  return false;
402 }
403 
404 function ‪resetFireDamage( entnum, time )
405 {
406  if ( time > 0.05 )
407  {
408  wait( time - 0.05 );
409  }
410  level.incendiaryDamageThisTick[entnum] = undefined;
411 }
412 
413 
‪watchForExplode
‪function watchForExplode(owner)
Definition: _incendiary.gsc:58
‪damageEffectArea
‪function damageEffectArea(owner, position, radius, height, killCamEnt)
Definition: _incendiary.gsc:203
‪canDoFireDamage
‪function canDoFireDamage(killCamEnt, victim, resetFireTime)
Definition: _incendiary.gsc:391
‪hitPos
‪function hitPos(start, end, color)
Definition: _incendiary.gsc:384
‪timer
‪function timer(n_time, str_endon, x, y, height)
Definition: lui_shared.gsc:163
‪tryToApplyFireDamage
‪function tryToApplyFireDamage(target, owner, position, fireEffectArea, resetFireTime, killcament)
Definition: _incendiary.gsc:311
‪destroyEntityHeadIcons
‪function destroyEntityHeadIcons()
Definition: entityheadicons_shared.gsc:234
‪getPotentialTargets
‪function getPotentialTargets(owner)
Definition: _incendiary.gsc:247
‪deleteAfterTime
‪function deleteAfterTime(time)
Definition: util_shared.gsc:2710
‪sndFireDamage
‪function sndFireDamage()
Definition: _incendiary.gsc:354
‪trace
‪function trace(from, to, target)
Definition: grapple.gsc:369
‪spawn
‪function spawn(v_origin=(0, 0, 0), v_angles=(0, 0, 0))
Definition: struct.csc:23
‪create_incendiary_watcher
‪function create_incendiary_watcher()
Definition: _incendiary.gsc:40
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪on_spawned
‪function on_spawned(func, obj)
Definition: callbacks_shared.csc:245
‪incendiary_system_spawn
‪function incendiary_system_spawn(watcher, player)
Definition: _incendiary.gsc:47
‪sndFireDamage_DeleteEnt
‪function sndFireDamage_DeleteEnt(ent)
Definition: _incendiary.gsc:374
‪end
‪function end(final)
Definition: _killcam.gsc:511
‪PHYSICS_TRACE_MASK_PHYSICS
‪#define PHYSICS_TRACE_MASK_PHYSICS
Definition: shared.gsh:130
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪getstepoutdistance
‪function getstepoutdistance(normal)
Definition: _incendiary.gsc:78
‪damageInFireArea
‪function damageInFireArea(fireEffectArea, killcament, trace, position, resetFireTime)
Definition: _incendiary.gsc:330
‪getLocationForFX
‪function getLocationForFX(startPos, fxIndex, fxCount, defaultDistance, rotation)
Definition: _incendiary.gsc:120
‪store_killcam_entity_on_entity
‪function store_killcam_entity_on_entity(killcam_entity)
Definition: killcam_shared.gsc:27
‪createUseWeaponObjectWatcher
‪function createUseWeaponObjectWatcher(weaponname, ownerTeam)
Definition: _weaponobjects.gsc:1297
‪resetFireDamage
‪function resetFireDamage(entnum, time)
Definition: _incendiary.gsc:404
‪init_shared
‪function init_shared()
Definition: _incendiary.gsc:25
‪spawnAllLocs
‪function spawnAllLocs(owner, startPos, normal, multiplier, rotation, killcament, fxCount)
Definition: _incendiary.gsc:129
‪generateLocations
‪function generateLocations(position, owner, normal, killCamEnt)
Definition: _incendiary.gsc:91