Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_AIAttackBehavior.c
Go to the documentation of this file.
2{
3#ifdef WORKBENCH
4 ref Shape m_Shape;
5#endif
6
7 // Be careful, here we want to store a ref to BaseTarget
8 ref SCR_BTParamRef<BaseTarget> m_Target = new SCR_BTParamRef<BaseTarget>(SCR_AIActionTask.TARGET_PORT);
9
10 // Direction to target which is calculated when the behavior is created. This is used to calculate flanking path.
11 ref SCR_BTParam<vector> m_vInitialDirToTgt = new SCR_BTParam<vector>("InitialDirToTgt");
12
13 // Wait time before we start shooting
14 ref SCR_BTParam<float> m_fWaitTime = new SCR_BTParam<float>("WaitTime");
15
16 SCR_AIWorld m_AIWorld;
17 SCR_AICombatComponent m_CombatComponent;
18
19 bool m_bSelected = false;
20 bool m_bCloseRange = false;
21
22 // This delay is executed before shooting starts
23 protected static const float WAIT_TIME_UNEXPECTED = 0.25;
24 protected static const float WAIT_TIME_OVERTHREATENED = 0.8;
25
26 //---------------------------------------------------------------------------------------------------------------------------------
27 override int GetCause()
28 {
29 return SCR_EAIBehaviorCause.COMBAT;
30 }
31
32 //----------------------------------------------------------------------------------
33 void InitParameters(BaseTarget target, float waitTime)
34 {
35 m_Target.Init(this, target);
36 m_fWaitTime.Init(this, waitTime);
37 m_vInitialDirToTgt.Init(this, vector.Zero);
38 }
39
40 //----------------------------------------------------------------------------------
41 override void OnActionSelected()
42 {
43 super.OnActionSelected();
44 m_bSelected = true;
46
47 // Update target selection properties if in close combat
48 m_bCloseRange = m_Target.m_Value.GetDistance() < SCR_AICombatComponent.CLOSE_RANGE_COMBAT_DISTANCE;
49 m_CombatComponent.SetTargetSelectionProperties(m_bCloseRange);
50 }
51
52 //----------------------------------------------------------------------------------
53 override void OnActionDeselected()
54 {
55 super.OnActionDeselected();
57
58 // Reset target selection properties
59 m_bCloseRange = false;
60 m_CombatComponent.SetTargetSelectionProperties(m_bCloseRange);
61 }
62
63 //----------------------------------------------------------------------------------
64 override void OnActionCompleted()
65 {
66 super.OnActionCompleted();
68 }
69
70 //----------------------------------------------------------------------------------
71 override void OnActionFailed()
72 {
73 super.OnActionFailed();
75 }
76
77 //----------------------------------------------------------------------------------
78 override string GetActionDebugInfo()
79 {
80 return this.ToString() + " attacking " + m_Target.m_Value.ToString();
81 }
82
83 //----------------------------------------------------------------------------------
84 void SCR_AIAttackBehavior(SCR_AIUtilityComponent utility, SCR_AIActivityBase groupActivity, BaseTarget target, BaseTarget prevTarget, float priorityLevel = PRIORITY_LEVEL_NORMAL)
85 {
86 InitParameters(target, 4);
87 if (!utility)
88 return;
89
90 m_fPriorityLevel.m_Value = priorityLevel;
91 SetPriority(PRIORITY_BEHAVIOR_ATTACK_NOT_SELECTED);
92 m_fThreat = 1.01 * SCR_AIThreatSystem.VIGILANT_THRESHOLD;
93 m_sBehaviorTree = "AI/BehaviorTrees/Chimera/Soldier/Attack.bt";
94 m_bAllowLook = false;
95 m_bResetLook = true;
96 SetIsUniqueInActionQueue(false);
97 m_AIWorld = SCR_AIWorld.Cast(GetGame().GetAIWorld());
98 m_CombatComponent = utility.m_CombatComponent;
99
100 // Init wait time, but only if we didn't have target before.
101 // Otherwise if we are switching between targets, it should be instant.
102 if (!prevTarget)
103 InitWaitTime(utility);
104 else
105 m_fWaitTime.m_Value = 0;
106
107 // Init initial direction to target, used for flanking
108 vector dirToTgt = target.GetLastSeenPosition() - utility.m_OwnerEntity.GetOrigin();
109 dirToTgt.Normalize();
110 m_vInitialDirToTgt.m_Value = dirToTgt;
111 }
112
113 //----------------------------------------------------------------------------------
114 override float CustomEvaluate()
115 {
116 BaseTarget baseTarget = m_Target.m_Value;
117
118 // Return 0 if it's not current target selected by weapon&target selector
119 // Since weapon&target selector selects both weapon and target, if we chose to attack a different target,
120 // it might happen that we use a wrong weapon
121 if (baseTarget != m_CombatComponent.GetCurrentTarget())
122 return 0;
123
124 // Update m_bUseCombatMove
125 m_bUseCombatMove = true;
126
127 if (m_Utility.m_AIInfo.HasUnitState(EUnitState.IN_TURRET))
128 m_bUseCombatMove = false;
129 else if (m_Utility.m_AIInfo.HasUnitState(EUnitState.IN_VEHICLE)) // inside vehicle we dont attack unless in turret
130 return 0;
131
132 // Update target selection properties if needed
133 bool closeRange = baseTarget.GetDistance() < SCR_AICombatComponent.CLOSE_RANGE_COMBAT_DISTANCE;
134 if (closeRange != m_bCloseRange)
135 {
136 m_bCloseRange = closeRange;
137 m_CombatComponent.SetTargetSelectionProperties(m_bCloseRange);
138 }
139
140 // Combat mode?
141 if (m_CombatComponent.GetCombatMode() == EAIGroupCombatMode.HOLD_FIRE)
142 return PRIORITY_BEHAVIOR_ATTACK_DISREGARD_THREATS;
143
144 float targetScore = m_Utility.m_CombatComponent.m_WeaponTargetSelector.CalculateTargetScore(baseTarget);
145
146 if (baseTarget.IsEndangering() || baseTarget.GetTimeSinceEndangered() < SCR_AICombatComponent.TARGET_ENDANGERED_TIMEOUT_S)
147 targetScore *= SCR_AICombatComponent.ENDANGERING_TARGET_SCORE_MULTIPLIER;
148
149 if (targetScore >= SCR_AICombatComponent.TARGET_SCORE_HIGH_PRIORITY_ATTACK)
150 return PRIORITY_BEHAVIOR_ATTACK_HIGH_PRIORITY;
151
152 if (m_bSelected)
153 return PRIORITY_BEHAVIOR_ATTACK_SELECTED;
154
155 return PRIORITY_BEHAVIOR_ATTACK_NOT_SELECTED;
156 }
157
158 // Sets the delay until shooting starts.
159 protected void InitWaitTime(SCR_AIUtilityComponent utility)
160 {
161 float threatMeasure = utility.m_ThreatSystem.GetThreatMeasure();
162
163 // Delay depending on threat
164 float threatDelay;
166 threatDelay = WAIT_TIME_UNEXPECTED;
167 else if (threatMeasure < SCR_AIThreatSystem.THREATENED_THRESHOLD)
168 threatDelay = 0;
169 else
170 threatDelay = WAIT_TIME_OVERTHREATENED;
171
172 // Delay depending on distance
173 // 0m - 0ms
174 // 100m - 340ms
175 // 300m - 700ms
176 // 500m - 870ms
177 // 800m - 1018ms
178 float distance = vector.Distance(m_Utility.m_OwnerEntity.GetOrigin(), m_Target.m_Value.GetLastSeenPosition());
179 float distanceDelay = (1.4 * distance) / (300 + distance);
180
181 m_fWaitTime.m_Value = threatDelay + distanceDelay;
182 }
183
184 void EnableFriendlyFireCheck(bool enable)
185 {
186 if (m_Utility && m_Utility.m_PerceptionComponent)
187 m_Utility.m_PerceptionComponent.SetFriendlyFireCheck(enable);
188 }
189};
ArmaReforgerScripted GetGame()
Definition game.c:1398
ref SCR_BTParam< float > m_fPriorityLevel
enum EAIActionFailReason PRIORITY_LEVEL_NORMAL
ResourceName m_sBehaviorTree
void SCR_AIActivityBase(SCR_AIGroupUtilityComponent utility, AIWaypoint relatedWaypoint)
enum SCR_EAIActivityCause m_Utility
float m_fThreat
void SCR_AIBehaviorBase(SCR_AIUtilityComponent utility, SCR_AIActivityBase groupActivity)
bool m_bResetLook
bool m_bUseCombatMove
SCR_EAIBehaviorCause
bool m_bAllowLook
float distance
override float CustomEvaluate()
override void OnActionSelected()
override void OnActionCompleted()
void InitParameters(BaseTarget target, float waitTime)
void SCR_AIAttackBehavior(SCR_AIUtilityComponent utility, SCR_AIActivityBase groupActivity, BaseTarget target, BaseTarget prevTarget, float priorityLevel=PRIORITY_LEVEL_NORMAL)
override void OnActionDeselected()
override string GetActionDebugInfo()
void EnableFriendlyFireCheck(bool enable)
override void OnActionFailed()
static const float WAIT_TIME_OVERTHREATENED
void InitWaitTime(SCR_AIUtilityComponent utility)
static const float WAIT_TIME_UNEXPECTED
static const float THREATENED_THRESHOLD
static const float ATTACK_DELAYED_THRESHOLD
Instance of created debug visualizer.
Definition Shape.c:14
proto external string ToString()
Plain C++ pointer, no weak pointers, no memory management.