Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_AIGetAimCompensation.c
Go to the documentation of this file.
2{
3 protected static float FIXED_AIM_POINT_LEAD_TIME_FACTOR = 3.5; // How much of predicted projectile flight time we want to lead for fixed aim points (leadTime = predictionTime * FIXED_AIM_POINT_LEAD_TIME_FACTOR)
4 protected static float FIXED_AIM_POINT_TIMEOUT_FACTOR = 0.5; // After what proportion of lead time we want to timeout aim point (and start closing it to target, timeoutTime = leadTime * FIXED_AIM_POINT_TIMEOUT_FACTOR)
5 protected static float FIXED_AIM_POINT_TIMEOUT_LERP_FACTOR = 0.04; // How much fixed aim point should lerp between current pos and target pos during each evaluation after fixed aim point is timeouted
6
7 protected static float FIXED_AIM_POINT_MIN_SPEED_MS = 6; // Minimal relative speed of target in meters/second for fixed aim point aiming
8 protected static float FIXED_AIM_POINT_MIN_DIST_M = 15; // Minimal distance to target in meters for fixed aim point aiming
9
10 protected static float CQB_COMPENSATION_MAX_DIST_M = 30; // Max distance in meters to use CQB compensation
11 protected static float CQB_COMPENSATION_MAX_MULTIPLIER = 0.4; // Max multiplier used to compensate CQB (linear distance scale, from 1 to CQB_COMPENSATION_MAX_DIST_M)
12
13 protected static float SURFACE_CORRECTION_MAX_ELEVATION_M = 2.5; // Max elevation of target (ATL) to correct for surface in meters
14
15 // Minimal distance at which grenade launchers should aim at surface instead of target
16 // NOTE: This is used/applied only if target is below SURFACE_CORRECTION_MAX_ELEVATION_M
17 protected static float GL_SURFACE_AIMING_MIN_DIST_M = 30;
18
19 protected static float SOLUTION_UPDATE_INTERVAL_MS = 750; // Default interval of solution updates in milliseconds
20
21 // Input
22 protected static string TARGET_ENTITY_PORT = "TargetEntity";
23 protected static string TARGET_POSITION_PORT = "TargetPosition";
24 protected static string AIMPOINT_PORT = "AimPoint";
25 protected static string VECTOR_IN_PORT = "VectorIn";
26 protected static string INITIAL_SPEED_COEFFICIENT = "InitialSpeedCoefficient";
27
28 // Output
29 protected static string VECTOR_OUT_PORT = "VectorOut";
30
31 // Entities
33
34 // Components
35 protected SCR_AIUtilityComponent m_UtilityComponent;
36 protected CharacterControllerComponent m_CharacterControllerComponent;
37 protected BaseWeaponManagerComponent m_WeaponManagerComponent;
38
39 // Logic data
40 protected vector m_vPointLeadAimPos; // World pos of fixed lead aim point, v.Zero means we're following target constantly
41 protected float m_fPointLeadAimPosTimeout; // World time after which lead point will be timed out (starts closing to target)
42 protected float m_fPointLeadAimTargetDist; // Last measured distance from lead aim point to target, used to check validity of current aim point
43 protected float m_fRandomFactor; // Random factor
44 protected float m_fNextUpdate; // World time of next solution update
45
46 protected IEntity m_TargetEntity; // Last passed target entity
47 protected EAIUnitType m_RelevantTargetEntityType; // Perceived type of relevant target entity, used in surface checks
48 protected IEntity m_RelevantTargetEntity; // Target or vehicle he's inside
49 protected IEntity m_RelevantShooterEntity; // Shooter or vehicle he's inside
50 protected EWeaponType m_eCurrentWeaponType; // Type of currently used weapon
51
52 // Node attributes
53 [Attribute("1", UIWidgets.CheckBox, "Compensate for distance")]
54 protected bool m_bRangeCompensation;
55
56 [Attribute("1", UIWidgets.CheckBox, "Compensate for velocity")]
58
59#ifdef WORKBENCH
60 //Diagnostic visualization
61 ref array<ref Shape> m_aDbgShapes = {};
62#endif
63
64 //------------------------------------------------------------------------------------------------
65 override void OnInit(AIAgent owner)
66 {
67 m_ShooterCharacter = ChimeraCharacter.Cast(owner.GetControlledEntity());
69 return;
70
71 m_UtilityComponent = SCR_AIUtilityComponent.Cast(owner.FindComponent(SCR_AIUtilityComponent));
72 m_CharacterControllerComponent = CharacterControllerComponent.Cast(m_ShooterCharacter.FindComponent(CharacterControllerComponent));
73 m_WeaponManagerComponent = BaseWeaponManagerComponent.Cast(m_ShooterCharacter.FindComponent(BaseWeaponManagerComponent));
74 }
75
76 //------------------------------------------------------------------------------------------------
78 {
79 if (entity)
80 {
81 Physics physics = entity.GetPhysics();
82 if (physics)
83 return physics.GetVelocity();
84 }
85
86 return vector.Zero;
87 }
88
89 //------------------------------------------------------------------------------------------------
90 float GetMuzzleAimData(BaseMuzzleComponent currentMuzzle, vector targetPos, vector targetVelocity, int iterations, out float targetDistance, out float predictionTime, out vector muzzlePos, out vector muzzleDir)
91 {
92 vector muzzleMat[4];
93 m_WeaponManagerComponent.GetCurrentMuzzleTransform(muzzleMat);
94 muzzlePos = muzzleMat[3];
95 muzzleDir = muzzleMat[2];
96
97 float rangeOffset;
98 vector futureTargetPos = targetPos;
99 targetDistance = vector.Distance(muzzlePos, futureTargetPos);
100
101 // Add random error in initial distance measurement
102 targetDistance += targetDistance * m_fRandomFactor;
103
104 // Refine measurements
105 for (int i = 0; i < iterations; i++)
106 {
107 rangeOffset = BallisticTable.GetAimHeightOfNextProjectile(targetDistance, predictionTime, currentMuzzle);
108 futureTargetPos = targetPos + (targetVelocity * predictionTime);
109 targetDistance = vector.Distance(muzzlePos, futureTargetPos);
110 }
111
112 return rangeOffset;
113 }
114
115 //------------------------------------------------------------------------------------------------
116 float GetEntityAimData(IEntity entity, float initSpeedCoef, vector targetPos, vector targetVelocity, int iterations, out float targetDistance, out float predictionTime, out vector muzzlePos, out vector muzzleDir)
117 {
118 vector shooterMat[3];
119 entity.GetTransform(shooterMat);
120 muzzlePos = entity.GetOrigin();
121 muzzleDir = shooterMat[2];
122
123 float rangeOffset;
124 vector futureTargetPos = targetPos;
125 targetDistance = vector.Distance(muzzlePos, futureTargetPos);
126
127 // Add random error in initial distance measurement
128 targetDistance += targetDistance * m_fRandomFactor;
129
130 // Refine measurements
131 for (int i = 0; i < iterations; i++)
132 {
133 rangeOffset = BallisticTable.GetHeightFromProjectile(targetDistance, predictionTime, entity, initSpeedCoef);
134 futureTargetPos = targetPos + (targetVelocity * predictionTime);
135 targetDistance = vector.Distance(muzzlePos, futureTargetPos);
136 }
137
138 return rangeOffset;
139 }
140
141 //------------------------------------------------------------------------------------------------
142 // Returns vehicle if given entity is a character inside a vehicle, otherwise returns given entity
144 {
145 ChimeraCharacter character = ChimeraCharacter.Cast(entity);
146 if (!character || !character.IsInVehicle())
147 return entity;
148
149 CompartmentAccessComponent compAccComp = character.GetCompartmentAccessComponent();
150 if (!compAccComp)
151 return entity;
152
153 IEntity vehicle = compAccComp.GetVehicleIn(character);
154 if (!vehicle)
155 return entity;
156
157 return vehicle;
158 }
159
160 //------------------------------------------------------------------------------------------------
161 void CorrectForSurface(out vector aimCorrectionVector, vector targetPos, vector aimPos, float speedMs, float targetDistance)
162 {
163 // No surface correction if target is flying
164 if (m_RelevantTargetEntityType == EAIUnitType.UnitType_Aircraft)
165 return;
166
167 BaseWorld world = GetGame().GetWorld();
168 float targetElev = targetPos[1] - world.GetSurfaceY(targetPos[0], targetPos[2]);
169
170 // No surface correction if target is too high over surface
171 if (targetElev > SURFACE_CORRECTION_MAX_ELEVATION_M)
172 return;
173
174 float aimPosSurfY = world.GetSurfaceY(aimPos[0], aimPos[2]);
175 float aimPosElev = aimPos[1] - aimPosSurfY;
176
177 // Aim at the surface if GL and outside of CQB range
178 if (m_eCurrentWeaponType == EWeaponType.WT_GRENADELAUNCHER && targetDistance > GL_SURFACE_AIMING_MIN_DIST_M)
179 aimCorrectionVector[1] = aimCorrectionVector[1] - (aimPosElev * 0.85);
180 else
181 {
182 float surfYDiff = targetElev - aimPosElev;
183
184 // Confidence in Y prediction, faster the target is moving, less confident we are in predicting elevation in relation to surface
185 float confidence = Math.Clamp(Math.Map(speedMs, 3, 32, 1, 0.7), 0.2, 1);
186 surfYDiff *= confidence;
187
188 // Prevent going into underworld with predicted position
189 float predSurfYDiff = (aimPos[1] + aimCorrectionVector[1] + surfYDiff) - aimPosSurfY;
190 if (predSurfYDiff < 0.1)
191 surfYDiff += Math.AbsFloat(predSurfYDiff - 0.1);
192
193 aimCorrectionVector[1] = aimCorrectionVector[1] + surfYDiff;
194 }
195 }
196
197 //------------------------------------------------------------------------------------------------
198 // Creates new fixed aim point (will be assigned to member variable)
199 void CreateFixedAimPoint(BaseWeaponComponent currentWeapon, BaseMuzzleComponent currentMuzzle, vector targetPos, vector targetVelocity, float initSpeedCoef, float time)
200 {
201 float targetDistance, predictionTime, rangeOffset;
202 vector muzzlePos, muzzleDir;
203
204 if (currentWeapon && currentMuzzle)
205 rangeOffset = GetMuzzleAimData(currentMuzzle, targetPos, targetVelocity, 2, targetDistance, predictionTime, muzzlePos, muzzleDir);
206 else if (currentWeapon)
207 rangeOffset = GetEntityAimData(m_ShooterCharacter, initSpeedCoef, targetPos, targetVelocity, 1, targetDistance, predictionTime, muzzlePos, muzzleDir);
208
209 float leadTime = predictionTime * FIXED_AIM_POINT_LEAD_TIME_FACTOR;
210
211 leadTime += predictionTime * m_fRandomFactor;
212
213 m_vPointLeadAimPos = targetPos + targetVelocity * leadTime;
215 m_fNextUpdate = time + ((leadTime - predictionTime) * 1000);
216
217 // Measure distance to compare later
219
220 // Adjust position for surface
221 vector surfaceCorrection;
222 CorrectForSurface(surfaceCorrection, targetPos, m_vPointLeadAimPos, targetVelocity.Length(), m_fPointLeadAimTargetDist);
223 m_vPointLeadAimPos[1] = m_vPointLeadAimPos[1] + surfaceCorrection[1];
224 }
225
226 //------------------------------------------------------------------------------------------------
227 // Validates fixed aim point - checks if should be discarded or timeouted
228 void ValidateFixedAimPoint(out vector fixedAimPoint, vector targetPos, float time)
229 {
230 if (fixedAimPoint == vector.Zero)
231 return;
232
233 float aimPointTargetDist = vector.Distance(targetPos, fixedAimPoint);
234
235 // Discard fixed aim point if it's moving away from target
236 if (aimPointTargetDist > m_fPointLeadAimTargetDist)
237 fixedAimPoint = vector.Zero;
238 else
239 {
240 m_fPointLeadAimTargetDist = aimPointTargetDist;
241
242 // If waypoint timeouted, start moving it towards target
243 if (time > m_fPointLeadAimPosTimeout)
244 fixedAimPoint -= (fixedAimPoint - targetPos) * FIXED_AIM_POINT_TIMEOUT_LERP_FACTOR;
245 }
246 }
247
248 //------------------------------------------------------------------------------------------------
249 // Returns EMPIRICAL factors for aim correction based on angle and distance
250 void GetDynamicAimCorrectionFactors(out float angleFactor, out float distanceFactor)
251 {
252 if (m_eCurrentWeaponType == EWeaponType.WT_ROCKETLAUNCHER)
253 angleFactor = 2.32;
254 else if (m_eCurrentWeaponType == EWeaponType.WT_GRENADELAUNCHER)
255 angleFactor = 0.82;
256 else
257 angleFactor = 6.48;
258
259 distanceFactor = 0.0006; // Average distance error per 1m
260 }
261
262 //------------------------------------------------------------------------------------------------
263 // Calculates aim correction vector for aiming "disability" during dynamic aiming (following target constantly)
264 vector GetDynamicAimCorrectionVector(vector targetPos, vector aimVector, vector muzzlePos, vector targetVelocity, float targetDistance)
265 {
266 // Adjust for angle difference between target and aim position
267 vector aimPos = targetPos + aimVector;
268 vector dirToAimPoint = vector.Direction(muzzlePos, aimPos).Normalized();
269 vector dirToTarget = vector.Direction(muzzlePos, targetPos).Normalized();
270
271 float angleFactor, distanceFactor;
272 GetDynamicAimCorrectionFactors(angleFactor, distanceFactor);
273
274 float angle = Math.Acos(vector.Dot(dirToTarget, dirToAimPoint));
275 float angleTime = angle * angleFactor;
276 float distanceTime = targetDistance * distanceFactor;
277
278 // CQB aiming compensation - Temporarly disabled due to changes in aim speed
279 // if (targetDistance < CQB_COMPENSATION_MAX_DIST_M && targetDistance > 1)
280 // angleTime += angleTime * CQB_COMPENSATION_MAX_MULTIPLIER * ((CQB_COMPENSATION_MAX_DIST_M - targetDistance) / CQB_COMPENSATION_MAX_DIST_M);
281
282 // Adjust random factor
283 float correctionTime = angleTime + distanceTime;
284 correctionTime += correctionTime * m_fRandomFactor;
285
286 vector aimCorrectionVector = targetVelocity * correctionTime;
287
288 // Adjust for surface differences
289 CorrectForSurface(aimCorrectionVector, targetPos, aimPos, targetVelocity.Length(), targetDistance);
290
291 return aimCorrectionVector;
292 }
293
294 //------------------------------------------------------------------------------------------------
295 override ENodeResult EOnTaskSimulate(AIAgent owner, float dt)
296 {
298 return ENodeResult.FAIL;
299
300 float time = GetGame().GetWorld().GetWorldTime();
301
302 // Input
303 vector aimVector;
304 float initSpeedCoef = 1.0;
305 GetVariableIn(VECTOR_IN_PORT, aimVector);
307
308 vector targetPos;
309
310 // Entity
311 IEntity targetEntity;
312 GetVariableIn(TARGET_ENTITY_PORT, targetEntity);
313 if (!targetEntity)
314 {
315 Print("GetAimCompensation: provided null entity", LogLevel.WARNING);
316 return ENodeResult.FAIL;
317 }
318
319 // Aimpoint
320 AimPoint aimPoint;
321 if (GetVariableIn(AIMPOINT_PORT, aimPoint))
322 {
323 if (!aimPoint)
324 {
325 Print("GetAimCompensation: provided null aimpoint", LogLevel.WARNING);
326 return ENodeResult.FAIL;
327 }
328
329 targetPos = aimPoint.GetPosition();
330 }
331 // Fallback to connected pos var or entity position
332 else
333 {
334 // Get position of center of the model
335 if (!GetVariableIn(TARGET_POSITION_PORT, targetPos))
336 targetPos = targetEntity.GetOrigin();
337 }
338
339 //-------------------------------------------------------------------------------------- IN
340
341 // Check if we need to update aim solution
342 bool updateSolution = m_TargetEntity != targetEntity || !m_RelevantTargetEntity || time > m_fNextUpdate;
343
344 // Update entities
345 if (updateSolution)
346 {
347 m_fRandomFactor = Math.RandomGaussFloat(0.045, 0.065);
348 m_TargetEntity = targetEntity;
351
352 if (m_UtilityComponent.m_CombatComponent)
353 m_WeaponManagerComponent = m_UtilityComponent.m_CombatComponent.GetCurrentWeaponManager();
354
355 // Fail and reset update time update time so we can check again in next node run
357 {
358 m_fNextUpdate = 0;
359 return ENodeResult.FAIL;
360 }
361
362 // Get target entity unit type
363 m_RelevantTargetEntityType = EAIUnitType.UnitType_Infantry;
365 if (perceivable)
366 m_RelevantTargetEntityType = perceivable.GetUnitType();
367
368 // Schedule next update (note: fixed aim point selection can override update time)
370 }
371
372 // Resolve current weapon and muzzle
373 BaseWeaponComponent currentWeapon = m_WeaponManagerComponent.GetCurrentWeapon();
374 BaseMuzzleComponent currentMuzzle;
375 if (currentWeapon)
376 currentMuzzle = currentWeapon.GetCurrentMuzzle();
377
378 // Velocities
381
382 // Aim data
383 vector muzzlePos, muzzleDir;
384 float targetDistance, rangeOffset, predictionTime;
385 float relativeAbsSpeed = Math.AbsFloat((targetVelocity - shooterVelocity).Length()); // Relative abs speed in m/s
386
387 // Check if fixed aim point should be used
388 if (updateSolution)
389 {
391
392 // Update weapon type
394 if (currentWeapon)
395 m_eCurrentWeaponType = SCR_AIWeaponHandling.GetWeaponType(currentWeapon, true);
396
397 // Simplified distance just to check if we should use fixed aim point
398 targetDistance = vector.Distance(targetPos, m_RelevantShooterEntity.GetOrigin());
399
400 // Fixed aim point is used for MGs shooting at fast-moving, distant targets
401 /*
402 // For now it's disabled because the 0.5*dt compensation shows better results
403 if (m_eCurrentWeaponType == EWeaponType.WT_MACHINEGUN && relativeAbsSpeed > FIXED_AIM_POINT_MIN_SPEED_MS &&
404 targetDistance > FIXED_AIM_POINT_MIN_DIST_M)
405 CreateFixedAimPoint(currentWeapon, currentMuzzle, targetPos, targetVelocity, initSpeedCoef, time);
406 */
407 }
408
409 // Check validity of current fixed aim pos
410 if (m_vPointLeadAimPos != vector.Zero)
412
413 // Determine how accurate we want to be in aiming / how many times we will calculate correction for aim prediction
414 int iterations = 2;
415 if (!m_bVelocityCompensation || relativeAbsSpeed < 2)
416 iterations = 1;
417
418 // Get aim data
419 if (currentWeapon && currentMuzzle)
420 rangeOffset = GetMuzzleAimData(currentMuzzle, targetPos, targetVelocity, iterations, targetDistance, predictionTime, muzzlePos, muzzleDir);
421 else if (currentWeapon)
422 rangeOffset = GetEntityAimData(m_ShooterCharacter, initSpeedCoef, targetPos, targetVelocity, iterations, targetDistance, predictionTime, muzzlePos, muzzleDir);
423
424 // Threat based compensation error
425 if (m_UtilityComponent.m_ThreatSystem)
426 {
427 float suppression = m_UtilityComponent.m_ThreatSystem.GetSuppressionMeasure();
428 if (suppression > 0.01)
429 predictionTime += predictionTime * (suppression - Math.RandomFloat(0, suppression * 2));
430 }
431
432 vector aimCorrectionVector;
434 {
435 // Adjust for shooter velocity
436 aimVector -= (shooterVelocity * predictionTime);
437
438 // Dynamic aiming
439 if (m_vPointLeadAimPos == vector.Zero)
440 {
441 // Adjust for target velocity
442 // 0.5*dt is here because AI aiming samples target position at AI update interval (dt).
443 // therefore data is delayed by 0.5*dt on average.
444 aimVector += (targetVelocity * (predictionTime + 0.5*dt));
445 }
446 // Fixed aim point
447 else
448 aimVector += m_vPointLeadAimPos - targetPos;
449 }
450
451 // Apply range compensation
453 aimVector[1] = aimVector[1] + rangeOffset;
454
455 //-------------------------------------------------------------------------------------- OUT
456#ifdef WORKBENCH
457 m_aDbgShapes.Clear();
458 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_AI_SHOW_AIM_LEAD_DEBUG))
459 {
460 m_aDbgShapes.Insert(Shape.CreateSphere(Color.DARK_GREEN, ShapeFlags.TRANSP | ShapeFlags.NOOUTLINE, targetPos, 0.12));
461 m_aDbgShapes.Insert(Shape.CreateSphere(Color.RED, ShapeFlags.TRANSP | ShapeFlags.NOOUTLINE, targetPos + aimVector, 0.12));
462 m_aDbgShapes.Insert(Shape.CreateSphere(Color.CYAN, ShapeFlags.TRANSP | ShapeFlags.NOOUTLINE, targetPos + aimVector + aimCorrectionVector, 0.12));
463
464 if (m_vPointLeadAimPos != vector.Zero)
465 m_aDbgShapes.Insert(Shape.CreateSphere(Color.VIOLET, ShapeFlags.TRANSP | ShapeFlags.NOOUTLINE, m_vPointLeadAimPos, 0.12));
466 }
467#endif
468 SetVariableOut(VECTOR_OUT_PORT, aimVector + aimCorrectionVector);
469 return ENodeResult.SUCCESS;
470 }
471
472 //------------------------------------------------------------------------------------------------
473 protected static ref TStringArray s_aVarsOut = {VECTOR_OUT_PORT};
475
476 //------------------------------------------------------------------------------------------------
478 override TStringArray GetVariablesIn() { return s_aVarsIn; }
479
480 //------------------------------------------------------------------------------------------------
481 override static bool VisibleInPalette() {return true;}
482
483 //------------------------------------------------------------------------------------------------
484 protected override static string GetOnHoverDescription() {return "Returns offset for compensation of target range and velocity. Offset will be added to VectorIn, so it can be used for build-in imprecision.";}
485}
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
ArmaReforgerScripted GetGame()
Definition game.c:1398
Definition Color.c:13
Diagnostic and developer menu system.
Definition DiagMenu.c:18
proto external vector GetOrigin()
proto external Physics GetPhysics()
proto external void GetTransform(out vector mat[])
Definition Math.c:13
proto void SetVariableOut(string name, void val)
proto bool GetVariableIn(string name, out void val)
vector GetEntityVelocity(IEntity entity)
float GetEntityAimData(IEntity entity, float initSpeedCoef, vector targetPos, vector targetVelocity, int iterations, out float targetDistance, out float predictionTime, out vector muzzlePos, out vector muzzleDir)
void CorrectForSurface(out vector aimCorrectionVector, vector targetPos, vector aimPos, float speedMs, float targetDistance)
float GetMuzzleAimData(BaseMuzzleComponent currentMuzzle, vector targetPos, vector targetVelocity, int iterations, out float targetDistance, out float predictionTime, out vector muzzlePos, out vector muzzleDir)
vector GetDynamicAimCorrectionVector(vector targetPos, vector aimVector, vector muzzlePos, vector targetVelocity, float targetDistance)
override TStringArray GetVariablesIn()
static override bool VisibleInPalette()
void ValidateFixedAimPoint(out vector fixedAimPoint, vector targetPos, float time)
override void OnInit(AIAgent owner)
void GetDynamicAimCorrectionFactors(out float angleFactor, out float distanceFactor)
void CreateFixedAimPoint(BaseWeaponComponent currentWeapon, BaseMuzzleComponent currentMuzzle, vector targetPos, vector targetVelocity, float initSpeedCoef, float time)
override ENodeResult EOnTaskSimulate(AIAgent owner, float dt)
SCR_AIUtilityComponent m_UtilityComponent
static ref TStringArray s_aVarsOut
override TStringArray GetVariablesOut()
BaseWeaponManagerComponent m_WeaponManagerComponent
static ref TStringArray s_aVarsIn
IEntity GetRelevantEntity(IEntity entity)
CharacterControllerComponent m_CharacterControllerComponent
static override string GetOnHoverDescription()
Instance of created debug visualizer.
Definition Shape.c:14
ENodeResult
Definition ENodeResult.c:13
EAIUnitType
Definition EAIUnitType.c:13
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
ShapeFlags
Definition ShapeFlags.c:13
SCR_FieldOfViewSettings Attribute
array< string > TStringArray
Definition Types.c:385
EWeaponType
Definition EWeaponType.c:13