Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_AIObserveThreatSystemBehavior.c
Go to the documentation of this file.
1
3{
4 protected bool m_bBehaviorActive;
5
6 protected int m_iCurrentSector;
7 protected float m_fCurrentSectorDanger;
9 protected int m_iCurrentSectorObserveCounter; // How many times we observed current sector
10
13
15
16 protected static const float HIGH_PRIORITY_INITIAL_DURATION_S = 6.0;
17
18 //--------------------------------------------------------------------------------------------------------------------------
19 void SCR_AIObserveThreatSystemBehavior(SCR_AIUtilityComponent utility, SCR_AIActivityBase groupActivity)
20 {
21 if (!utility || !utility.GetAIAgent())
22 return;
23
24 m_sBehaviorTree = "{496CEB065448925C}AI/BehaviorTrees/Chimera/Soldier/ObserveThreatSystemBehavior.bt";
25 m_bAllowLook = false; // Disable standard looking
26 m_bUseCombatMove = true;
27
29
30 utility.m_SectorThreatFilter.GetOnEscalationInvoker().Insert(OnThreatSectorEscalation);
31 utility.m_SectorThreatFilter.GetOnMajorSectorChangedInvoker().Insert(OnMajorSectorChanged);
32 utility.m_SectorThreatFilter.GetOnDamageTaken().Insert(OnDamageTaken);
33
34 Reset();
35 }
36
37 //--------------------------------------------------------------------------------------------------------------------------
39 {
40 if (m_Utility && m_Utility.m_SectorThreatFilter)
41 {
42 m_Utility.m_SectorThreatFilter.GetOnEscalationInvoker().Remove(OnThreatSectorEscalation);
43 m_Utility.m_SectorThreatFilter.GetOnMajorSectorChangedInvoker().Remove(OnMajorSectorChanged);
44 }
45 }
46
47 //--------------------------------------------------------------------------------------------------------------------------
58
59 //--------------------------------------------------------------------------------------------------------------------------
60 override void OnActionSelected()
61 {
62 super.OnActionSelected();
63
64 // Randomly report under fire
65 if (Math.RandomFloat01() < 0.2)
66 {
67 if (!m_Utility.m_CommsHandler.CanBypass())
68 {
69 SCR_AITalkRequest rq = new SCR_AITalkRequest(ECommunicationType.REPORT_UNDER_FIRE, null, vector.Zero, 0, false, true, SCR_EAITalkRequestPreset.IRRELEVANT);
70 m_Utility.m_CommsHandler.AddRequest(rq);
71 }
72 }
73
75 m_Utility.m_CombatMoveState.EnableAiming(true);
76 }
77
78 //--------------------------------------------------------------------------------------------------------------------------
79 override void OnActionDeselected()
80 {
81 super.OnActionDeselected();
82 m_CombatMoveLogic.Reset();
83 }
84
85 //--------------------------------------------------------------------------------------------------------------------------
86 override float CustomEvaluate()
87 {
89 return 0;
90
91 // Makes no sense for driver
92 if (m_Utility.m_AIInfo.HasUnitState(EUnitState.PILOT))
93 return 0;
94
96 {
97 WorldTimestamp timestamp = GetGame().GetWorld().GetTimestamp();
98 float highPriorityTimePassed_s = timestamp.DiffSeconds(m_TimestampStartHighPriorityState);
99 if (highPriorityTimePassed_s > m_fHighPriorityDuration_s)
100 {
103 }
104 }
105
107 return PRIORITY_BEHAVIOR_OBSERVE_THREATS_HIGH_PRIORITY;
108
109 // Not in high priority state
110 if (m_Utility.ShouldKeepFormation())
111 {
112 if (!m_Utility.GetSubformationLeaderMoving() && m_Utility.GetNearSubformationLeader())
113 return PRIORITY_BEHAVIOR_OBSERVE_THREATS_LOW_PRIORITY;
114 else
115 return 0; // Subformation leader wants to move, and we must follow him, so disregard looking at this threat further
116 }
117 else
118 return PRIORITY_BEHAVIOR_OBSERVE_THREATS_LOW_PRIORITY;
119 }
120
121 //--------------------------------------------------------------------------------------------------------------------------
122 override void OnActionExecuted()
123 {
124 if (!m_Utility.m_AIInfo.HasUnitState(EUnitState.IN_VEHICLE))
125 m_CombatMoveLogic.Update();
126 }
127
128 //--------------------------------------------------------------------------------------------------------------------------
129 void OnThreatSectorEscalation(SCR_AISectorThreatFilter ts, int sectorId, float dangerValue)
130 {
131 // Don't care if it's not about the current sector
132 if (sectorId != m_iCurrentSector)
133 return;
134
135 m_fCurrentSectorDanger = dangerValue;
136 m_CombatMoveLogic.ReactToSector(sectorId);
138 }
139
140 //--------------------------------------------------------------------------------------------------------------------------
141 void OnMajorSectorChanged(SCR_AISectorThreatFilter ts, int newSectorId, int oldSectorId, float dangerValue)
142 {
143 if (newSectorId != -1)
144 {
145 if (dangerValue > m_fCurrentSectorDanger || m_iCurrentSector == -1)
146 {
148 m_CombatMoveLogic.ReactToSector(newSectorId);
149 }
150
151 m_bBehaviorActive = true;
152 m_iCurrentSector = newSectorId;
153 m_fCurrentSectorDanger = dangerValue;
154 m_eCurrentSectorFlags = ts.GetSectorFlags(newSectorId);
155 }
156 else
157 {
158 // Major sector id switched to -1, this means there is no threat in threat system any more
159 m_CombatMoveLogic.Reset();
160 Reset();
161 }
162 }
163
164 //--------------------------------------------------------------------------------------------------------------------------
166 {
167 if (sectorId != m_iCurrentSector)
168 return;
169
170 // Every time we take damage, interrupt current behavior and try to find a new position
172 m_CombatMoveLogic.ReactToSector(sectorId);
173 }
174
175 //--------------------------------------------------------------------------------------------------------------------------
177 void OnMovementCompleted(bool inCover)
178 {
179 if (GetActionState() != EAIActionState.RUNNING || !m_bBehaviorActive || m_iCurrentSector == -1 || !m_Utility.m_SectorThreatFilter.IsSectorActive(m_iCurrentSector))
180 return;
181
182 // After movement is done, figure out how long we need to look at this, and activate high priority state again for this duration
183 float observeDuration = CalculateObserveDuration(m_iCurrentSector);
184 SwitchToHighPriorityState(observeDuration);
185 }
186
187 //--------------------------------------------------------------------------------------------------------------------------
190 protected float CalculateObserveDuration(int sectorId)
191 {
192 vector threatPos = m_Utility.m_SectorThreatFilter.GetSectorPos(sectorId);
193 float threatDist = vector.Distance(m_Utility.m_OwnerEntity.GetOrigin(), threatPos);
194 float baseDuration = 0.1 * threatDist;
195
196 float danger = m_Utility.m_SectorThreatFilter.GetSectorDanger(sectorId);
197 float dangerCoef = Math.Map(danger, 0, 10, 1, 3);
198
199 float duration_s = (0.4 * baseDuration * dangerCoef) / (1.0 + m_iCurrentSectorObserveCounter);
200
201 // In this combat mode we care even less
202 if (m_Utility.m_CombatComponent.GetCombatMode() == EAIGroupCombatMode.HOLD_FIRE)
203 duration_s *= 0.5;
204
205 if (duration_s < 1.0)
206 duration_s = 1.0;
207
208 return duration_s * Math.RandomFloat(0.75, 1.25);
209 }
210
211 //--------------------------------------------------------------------------------------------------------------------------
212 protected void SwitchToHighPriorityState(float duration_s)
213 {
214 WorldTimestamp timestamp = GetGame().GetWorld().GetTimestamp();
215 m_fHighPriorityDuration_s = duration_s;
217 }
218
219 //--------------------------------------------------------------------------------------------------------------------------
220 protected void StopHighPriorityState()
221 {
223 }
224
225 //--------------------------------------------------------------------------------------------------------------------------
226 protected bool IsInHighPriorityState()
227 {
228 return m_fHighPriorityDuration_s != 0;
229 }
230
231 //---------------------------------------------------------------------------------------------------------------------------------
232 override int GetCause()
233 {
235 return SCR_EAIBehaviorCause.DANGER_HIGH; // If we were hit once then we will get hit second time soon
237 return SCR_EAIBehaviorCause.COMBAT; // If bullets are flying by then it's clearly a combat situation
238 else
239 return SCR_EAIBehaviorCause.DANGER_LOW;
240 }
241};
ArmaReforgerScripted GetGame()
Definition game.c:1398
ResourceName m_sBehaviorTree
void SCR_AIActivityBase(SCR_AIGroupUtilityComponent utility, AIWaypoint relatedWaypoint)
enum SCR_EAIActivityCause m_Utility
void SCR_AIBehaviorBase(SCR_AIUtilityComponent utility, SCR_AIActivityBase groupActivity)
bool m_bUseCombatMove
SCR_EAIBehaviorCause
bool m_bAllowLook
SCR_EAIThreatSectorFlags
ECommunicationType
void SCR_AITalkRequest(ECommunicationType type, IEntity entity, vector pos, int enumSignal, bool transmitIfNoReceivers, bool transmitIfPassenger, SCR_EAITalkRequestPreset preset)
Definition Math.c:13
void SCR_AIObserveThreatSystemBehavior(SCR_AIUtilityComponent utility, SCR_AIActivityBase groupActivity)
ref SCR_AICombatMoveLogic_HideFromThreatSystem m_CombatMoveLogic
void OnThreatSectorEscalation(SCR_AISectorThreatFilter ts, int sectorId, float dangerValue)
void Reset()
Resets whole behavior to default state.
void OnMajorSectorChanged(SCR_AISectorThreatFilter ts, int newSectorId, int oldSectorId, float dangerValue)
void OnDamageTaken(SCR_AISectorThreatFilter ts, int sectorId)
void OnMovementCompleted(bool inCover)
Called by combat movement logic.
SCR_EAIThreatSectorFlags GetSectorFlags(int sectorId)
EAIActionState