4 static const float GRENADE_AVOID_RADIUS = 13;
5 static const float GRENADE_AVOID_RADIUS_MIN = 2;
7 static const float GRENADE_AVOID_REACT_MIN_TIME_MS = 50;
8 static const float GRENADE_AVOID_DIST_REACT_TIME_MS = 2000;
10 static const float GRENADE_AVOID_VIS_REACT_TIME_MS = 1100;
12 static const float GRENADE_AVOID_DIST_CURVE_PARAM = GRENADE_AVOID_DIST_REACT_TIME_MS /
Math.Pow(GRENADE_AVOID_RADIUS - GRENADE_AVOID_RADIUS_MIN, 2);
20 vector agentDir = agentTransform[2];
23 dirToGrenade.Normalize();
25 float angle =
vector.Dot(dirToGrenade, agentDir);
27 return Math.Map(angle, -1, 1, 0, 1);
34 EAIThreatState threatState = threatSystem.GetState();
38 case EAIThreatState.SAFE:
43 case EAIThreatState.VIGILANT:
48 case EAIThreatState.ALERTED:
53 case EAIThreatState.THREATENED:
65 float GetDistanceSQReactionTime(
float distanceToGrenade)
68 return GRENADE_AVOID_DIST_CURVE_PARAM * (
69 distanceToGrenade * distanceToGrenade -
70 2 * GRENADE_AVOID_RADIUS_MIN * distanceToGrenade +
71 GRENADE_AVOID_RADIUS_MIN * GRENADE_AVOID_RADIUS_MIN
77 Faction GetOwnerFaction(SCR_AIUtilityComponent utility)
79 SCR_ChimeraCharacter ownerCharacter = SCR_ChimeraCharacter.Cast(utility.m_OwnerEntity);
83 return ownerCharacter.GetFaction();
88 SCR_ChimeraCharacter GetShooterCharacter(notnull
IEntity grenadeObject)
94 Instigator shooterInst = grenadeComp.GetInstigator();
98 return SCR_ChimeraCharacter.Cast(shooterInst.GetInstigatorEntity());
103 void AddToGroupPerception(SCR_AIUtilityComponent utility,
IEntity shooter,
vector observePosition,
Faction faction)
105 AIGroup group = utility.GetOwner().GetParentGroup();
110 if (!groupUtilityComp)
113 PerceptionManager perceptionMan =
GetGame().GetPerceptionManager();
121 override bool PerformReaction(notnull SCR_AIUtilityComponent utility, notnull
SCR_AIThreatSystem threatSystem,
AIDangerEvent dangerEvent,
int dangerEventCount)
123 IEntity grenadeObject = dangerEvent.GetObject();
127 vector agentPos = utility.GetOrigin();
128 float distanceToGrenade =
vector.Distance(utility.GetOrigin(), grenadePos);
129 if (distanceToGrenade < GRENADE_AVOID_RADIUS)
132 SCR_ChimeraCharacter shooter = GetShooterCharacter(grenadeObject);
133 Faction ownerFaction = GetOwnerFaction(utility);
134 Faction shooterFaction = shooter.GetFaction();
137 if (ownerFaction && shooter && !ownerFaction.IsFactionFriendly(shooterFaction))
138 AddToGroupPerception(utility, shooter, shooter.GetOrigin(), shooterFaction);
140 float reactionDelay = GRENADE_AVOID_REACT_MIN_TIME_MS;
142 if (distanceToGrenade > GRENADE_AVOID_RADIUS_MIN)
144 float visibilityFactor = GetGrenadeVisibilityFactor(utility.m_OwnerEntity, grenadePos);
145 float visbilityReactionTime = GRENADE_AVOID_VIS_REACT_TIME_MS * (1 - visibilityFactor);
146 float threatLevelReactionTime = GetThreatLevelReactionTime(threatSystem);
147 float distanceReactionTime = GetDistanceSQReactionTime(distanceToGrenade);
149 reactionDelay += visbilityReactionTime + threatLevelReactionTime + distanceReactionTime;
152 AddDebugMessage(utility,
string.Format(
"Delayed grenade reaction (visFact: %1 visReactTime: %2ms ThreatLvlTime: %3ms distReactTime %4ms distanceToGrenade %5)", visibilityFactor, visbilityReactionTime, threatLevelReactionTime, distanceReactionTime, distanceToGrenade));
156 AddDebugMessage(utility,
string.Format(
"Grenade distance below min treshold, quick reaction (distanceToGrenade: %1)", distanceToGrenade));
161 utility.AddAction(behavior);