Arma Reforger Explorer
1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Toggle main menu visibility
Loading...
Searching...
No Matches
SCR_AIDangerReaction_Vehicle.c
Go to the documentation of this file.
1
[
BaseContainerProps
()]
2
class
SCR_AIDangerReaction_Vehicle
:
SCR_AIDangerReaction
3
{
4
#ifdef AI_DEBUG
5
protected
ref array<ref Shape>
m_aShapes
= {};
6
#endif
7
8
//----------------------------------------------------------------------------------------------------------------------------------------------------------
9
override
bool
PerformReaction(notnull SCR_AIUtilityComponent utility, notnull
SCR_AIThreatSystem
threatSystem,
AIDangerEvent
dangerEvent,
int
dangerEventCount)
10
{
11
SCR_ChimeraAIAgent
agent =
SCR_ChimeraAIAgent
.Cast(utility.GetOwner());
12
13
IEntity
vehicleEntity = dangerEvent.GetVictim();
14
if
(!vehicleEntity)
15
return
false
;
16
17
/*
18
Disabled until vehicle front light tweaks
19
20
// Call driver behavior about incoming vehicle if active
21
SCR_AIIdleBehavior_Driver driverBehavior = SCR_AIIdleBehavior_Driver.Cast(utility.FindActionOfType(SCR_AIIdleBehavior_Driver));
22
if (driverBehavior)
23
driverBehavior.OnVehicleApproaching();
24
*/
25
26
// Ignore if we already have an action to move from that vehicle
27
if
(
SCR_AIMoveFromDangerBehavior
.ExistsBehaviorForEntity(utility, vehicleEntity))
28
return
false
;
29
30
SCR_BaseCompartmentManagerComponent compManager = SCR_BaseCompartmentManagerComponent.Cast(vehicleEntity.
FindComponent
(SCR_BaseCompartmentManagerComponent));
31
if
(!compManager)
32
return
false
;
33
34
array<IEntity> occupants = {};
35
compManager.GetOccupantsOfType(occupants,
ECompartmentType
.PILOT);
36
37
// Ignore if no driver
38
if
(occupants.Count() == 0)
39
return
false
;
40
41
// Different functionality if we are in vehicle
42
if
(utility.m_AIInfo.HasUnitState(EUnitState.PILOT))
43
{
44
45
IEntity
myVehicle = utility.m_OwnerEntity.
GetRootParent
();
46
47
bool
incomingCollision =
VehicleIntersectsMyPath
(myVehicle, vehicleEntity);
48
49
if
(incomingCollision)
50
{
51
if
(!
SCR_AIMoveFromDangerBehavior
.ExistsBehaviorForEntity(utility, vehicleEntity))
52
{
53
SCR_AIPilotMoveFromIncomingVehicleBehavior
behavior =
new
SCR_AIPilotMoveFromIncomingVehicleBehavior
(
54
utility, null, vehicleEntity.
GetOrigin
(), vehicleEntity);
55
utility.AddAction(behavior);
56
}
57
}
58
59
return
true
;
60
}
61
else
if
(!utility.m_AIInfo.HasUnitState(EUnitState.IN_VEHICLE))
62
{
63
// On foot
64
// Ignore if the behavior would fail immediately after start
65
if
(!
SCR_AIMoveFromIncomingVehicleBehavior
.ExecuteBehaviorCondition(utility, vehicleEntity))
66
return
false
;
67
68
SCR_AIMoveFromDangerBehavior
behavior =
new
SCR_AIMoveFromIncomingVehicleBehavior
(utility, null,
vector
.Zero, dangerEntity: vehicleEntity);
69
utility.AddAction(behavior);
70
71
return
true
;
72
}
73
74
return
false
;
75
}
76
77
//----------------------------------------------------------------------------------------------------------------------------------------------------------
78
protected
bool
VehicleIntersectsMyPath
(notnull
IEntity
myVehicle, notnull
IEntity
otherVehicle)
79
{
80
Physics
myPhysics = myVehicle.GetPhysics();
81
Physics
otherPhysics = otherVehicle.GetPhysics();
82
83
// Without physics, how can we know?
84
if
(!myPhysics || !otherPhysics)
85
return
false
;
86
87
vector
myVelWorld = myPhysics.GetVelocity();
88
vector
otherVelWorld = otherPhysics.GetVelocity();
89
90
// otherVehicle velocity relative to myVehicle
91
vector
relVelWorld = otherVelWorld - myVelWorld;
92
93
vector
myBbMinLocal;
94
vector
myBbMaxLocal;
95
myVehicle.GetBounds(myBbMinLocal, myBbMaxLocal);
96
vector
myBbCenterLocal = 0.5 * (myBbMinLocal + myBbMaxLocal);
97
vector
myBbCenterWorld = myVehicle.CoordToParent(myBbCenterLocal);
98
99
vector
otherBbMinOtherLocal;
// In other vehicle local space
100
vector
otherBbMaxOtherLocal;
101
otherVehicle.GetBounds(otherBbMinOtherLocal, otherBbMaxOtherLocal);
102
vector
otherBbCenterOtherLocal = 0.5 * (otherBbMinOtherLocal + otherBbMaxOtherLocal);
103
vector
otherBbCenterWorld = otherVehicle.CoordToParent(otherBbCenterOtherLocal);
104
105
// Estimate vehicle 'radiuses' based on widths of BB
106
float
myR = 0.5*(myBbMaxLocal[0] - myBbMinLocal[0]);
107
float
otherR = 0.5*(otherBbMaxOtherLocal[1] - otherBbMinOtherLocal[1]);
108
109
float
intersectionTime;
110
bool
intersectionTestResult =
MovingPointSphereIntersectionTest
(otherBbCenterWorld - myBbCenterWorld, relVelWorld, myR + otherR, intersectionTime);
111
112
const
float
maxTimeToCollision_s = 10.0;
113
bool
testResult = intersectionTestResult && (intersectionTime < maxTimeToCollision_s);
114
115
/*
116
#ifdef AI_DEBUG
117
m_aShapes.Clear();
118
119
int mySphereColor = Color.GREEN;
120
if (testResult)
121
mySphereColor = Color.RED;
122
Shape shapeMySphere = Shape.CreateSphere(mySphereColor, ShapeFlags.VISIBLE | ShapeFlags.WIREFRAME, myBbCenterWorld, otherR);
123
m_aShapes.Insert(shapeMySphere);
124
125
Shape shapeMySphereCombined = Shape.CreateSphere(mySphereColor, ShapeFlags.VISIBLE | ShapeFlags.WIREFRAME, myBbCenterWorld, myR + otherR);
126
m_aShapes.Insert(shapeMySphereCombined);
127
128
vector velLineEnd = otherBbCenterWorld + maxTimeToCollision_s*otherVelWorld;
129
Shape shapeOtherVel = Shape.Create(ShapeType.LINE, Color.RED, ShapeFlags.DEFAULT, otherBbCenterWorld, velLineEnd);
130
m_aShapes.Insert(shapeOtherVel);
131
132
vector velLineEndSize = Vector(0.15, 0.15, 0.15);
133
Shape shapeOtherVelEnd = Shape.Create(ShapeType.BBOX, Color.RED, ShapeFlags.DEFAULT, velLineEnd - velLineEndSize, velLineEnd + velLineEndSize);
134
m_aShapes.Insert(shapeOtherVelEnd);
135
136
if (testResult)
137
{
138
vector impactPosWorld = otherBbCenterWorld + intersectionTime * otherVelWorld;
139
vector impactPosSize = Vector (0.5, 0.5, 0.5);
140
Shape shapeImpactPos = Shape.Create(ShapeType.BBOX, Color.RED, ShapeFlags.DEFAULT, impactPosWorld - impactPosSize, impactPosWorld + impactPosSize);
141
m_aShapes.Insert(shapeImpactPos);
142
}
143
#endif
144
*/
145
146
return
testResult;
147
}
148
149
//----------------------------------------------------------------------------------------------------------------------------------------------------------
159
*/
160
protected
static
bool
MovingPointSphereIntersectionTest
(
vector
p,
vector
v,
float
r, out
float
outT)
161
{
162
// This is a quadratic equation, it has up to two roots. First check if it has roots at all.
163
164
float
px = p[0];
165
float
py = p[1];
166
float
pz = p[2];
167
float
vx = v[0];
168
float
vy = v[1];
169
float
vz = v[2];
170
171
float
vx2 = vx*vx;
172
float
vy2 = vy*vy;
173
float
vz2 = vz*vz;
174
float
vLen2 = vx2 + vy2 + vz2;
175
176
if
(vLen2 == 0)
177
{
178
outT = 0;
179
return
false
;
180
}
181
182
// Calculate D
183
float
_a = px*vy - py*vx;
184
float
_b = px*vz - pz*vx;
185
float
_c = py*vz - pz*vy;
186
187
float
D = r*r*vLen2 - (_a*_a) - (_b*_b) - (_c*_c);
188
189
// No solutions in real numbers
190
if
(D < 0)
191
{
192
outT = 0;
193
return
false
;
194
}
195
196
float
tBase = -(px*vx + py*vy + pz*vz)/vLen2;
197
198
if
(D == 0)
199
{
200
// One intersection
201
if
(tBase >= 0)
202
{
203
outT = tBase;
204
return
true
;
205
}
206
else
207
{
208
outT = 0;
209
return
false
;
210
}
211
}
212
213
float
sqrtD =
Math
.Sqrt(D);
214
float
t0 = tBase + sqrtD/vLen2;
215
float
t1 = tBase - sqrtD/vLen2;
216
217
// Two solutions, we need only positive one, but smallest if there are two positives
218
if
(t0 < 0 && t1 < 0)
219
{
220
// Both intersections are in the past
221
outT = 0;
222
return
false
;
223
}
224
else
if
(t0 >= 0 && t1 >= 0)
225
{
226
// Both are positive (in future), return smallest one
227
outT =
Math
.Min(t0, t1);
228
return
true
;
229
}
230
else
231
{
232
// One is positive and another isn't, return the positive one
233
if
(t0 > t1)
234
outT = t0;
235
else
236
outT = t1;
237
return
true
;
238
}
239
}
240
};
ECompartmentType
ECompartmentType
Definition
ECompartmentType.c:8
BaseContainerProps
SCR_AIAnimation_Loitering BaseContainerProps
Commanding menu commanding element class.
Definition
SCR_AIAnimationWaypoint.c:14
SCR_AIPilotMoveFromIncomingVehicleBehavior
void SCR_AIPilotMoveFromIncomingVehicleBehavior(SCR_AIUtilityComponent utility, SCR_AIActivityBase groupActivity, vector dangerPos, IEntity dangerEntity)
Definition
SCR_AIMoveFromDanger.c:218
SCR_AIMoveFromIncomingVehicleBehavior
void SCR_AIMoveFromIncomingVehicleBehavior(SCR_AIUtilityComponent utility, SCR_AIActivityBase groupActivity, vector dangerPos, IEntity dangerEntity)
Definition
SCR_AIMoveFromDanger.c:125
m_aShapes
ref array< ref Shape > m_aShapes
Definition
SCR_PlayerControllerCommandingComponent.c:32
AIDangerEvent
Event which gets broadcasted from danger-causing places to AI.
Definition
AIDangerEvent.c:14
IEntity
Definition
IEntity.c:13
IEntity::FindComponent
proto external Managed FindComponent(typename typeName)
IEntity::GetOrigin
proto external vector GetOrigin()
IEntity::GetRootParent
proto external IEntity GetRootParent()
Math
Definition
Math.c:13
Physics
Definition
Physics.c:22
SCR_AIDangerReaction_Vehicle
Definition
SCR_AIDangerReaction_Vehicle.c:3
SCR_AIDangerReaction_Vehicle::MovingPointSphereIntersectionTest
static bool MovingPointSphereIntersectionTest(vector p, vector v, float r, out float outT)
Definition
SCR_AIDangerReaction_Vehicle.c:159
SCR_AIDangerReaction_Vehicle::VehicleIntersectsMyPath
bool VehicleIntersectsMyPath(notnull IEntity myVehicle, notnull IEntity otherVehicle)
Definition
SCR_AIDangerReaction_Vehicle.c:78
SCR_AIDangerReaction
Definition
SCR_AIDangerReaction.c:5
SCR_AIMoveFromDangerBehavior
Definition
SCR_AIMoveFromDanger.c:5
SCR_AIThreatSystem
Definition
SCR_AIThreatSystem.c:18
SCR_ChimeraAIAgent
Definition
SCR_ChimeraAIAgent.c:6
vector
Definition
vector.c:13
scripts
Game
AI
Reaction
Danger
SCR_AIDangerReaction_Vehicle.c
Generated by
1.17.0