DayZ 1.27
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
MeleeTargeting.c
См. документацию.
2{
6
7 void MeleeTargetData(Object o, vector p, int c)
8 {
9 Obj = o;
10 HitPos = p;
11 HitComponent = c;
12 }
13}
14
16{
23
26
31 float MaxDist;
32
34 ref array<typename> TargetableObjects
35
36 void MeleeTargetSettings(vector coneOrigin, float coneLength, float coneHalfAngle, float coneMinHeight, float coneMaxHeight, vector rayStart, vector dir, float maxDist, EntityAI pToIgnore, array<typename> targetableObjects)
37 {
38 ConeOrigin = coneOrigin;
39 ConeLength = coneLength;
40 ConeHalfAngle = coneHalfAngle;
41 ConeHalfAngleRad = Math.DEG2RAD * coneHalfAngle;
42 ConeMinHeight = coneMinHeight;
43 ConeMaxHeight = coneMaxHeight;
44
45 RayStart = rayStart;
46 RayEnd = rayStart + Math.SqrFloat(coneLength) * dir;
47
48 Dir = dir;
49
50 XZDir = dir;
51 XZDir[1] = 0;
52 XZDir.Normalize();
53
54 MaxDist = maxDist;
55
56 Attacker = pToIgnore;
57 TargetableObjects = targetableObjects;
58
59 // Calculate cone points
61 }
62}
63
71
72class MeleeTargeting
73{
75
76 MeleeTargetData GetMeleeTargetEx(MeleeTargetSettings settings, out array<Object> allTargets = null, array<string> blacklistedDamageZones = null)
77 {
79
80 // Easier access to MeleeTargetSettings variables
81 vector coneOrigin = settings.ConeOrigin;
82 float coneLength = settings.ConeLength;
83 float coneHalfAngle = settings.ConeHalfAngle;
84 float radAngle = settings.ConeHalfAngleRad;
85 float coneMinHeight = settings.ConeMinHeight;
86 float coneMaxHeight = settings.ConeMaxHeight;
87
88 vector coneLeft = settings.ConeLeftPoint;
89 vector coneRight = settings.ConeRightPoint;
90
91 vector rayStart = settings.RayStart;
92 vector rayEnd = settings.RayEnd;
93 vector dir = settings.Dir;
94 vector xzDir = settings.XZDir;
95 float maxDist = settings.MaxDist;
96
97 EntityAI pToIgnore = settings.Attacker;
98 array<typename> targetableObjects = settings.TargetableObjects;
99
100 // Calculate box size
101 float boxWidth = vector.Distance(coneLeft, coneRight);
102 float boxHeight = coneMaxHeight - coneMinHeight;
103
104 vector boxSize = Vector(boxWidth, boxHeight, coneLength);
105
106 // Calculate box center
107 vector centerHeight = Vector(0, Math.Lerp(coneMinHeight, coneMaxHeight, 0.5), 0);
108 vector offset = xzDir * coneLength * 0.5;
109 vector boxCenter = coneOrigin + offset + centerHeight;
110
111 // Gather all targets
113 params.SetParams(boxCenter, xzDir.VectorToAngles(), boxSize, ObjIntersect.Fire, ObjIntersect.Fire, true);
115 array<Object> toIgnore = { pToIgnore };
116 if (GetGame().IsBoxCollidingGeometryProxy(params, toIgnore, results))
117 {
118 //
119 float retVal = float.MAX;
120 float tgAngle = Math.Tan(radAngle);
121
122 #ifdef DIAG_DEVELOPER
123 if (DiagMenu.GetBool(DiagMenuIDs.MELEE_DRAW_RANGE) && DiagMenu.GetBool(DiagMenuIDs.MELEE_DEBUG))
124 Debug.DrawLine(rayStart, rayEnd, COLOR_GREEN, ShapeFlags.ONCE);
125 #endif
126
127 // Find the most suitable target
128 foreach (BoxCollidingResult bResult : results)
129 {
130 Object obj = bResult.obj;
131
132 // Check for targetable objects
133 if (!obj.IsAnyInherited(targetableObjects) || !obj.IsAlive())
134 {
135 continue;
136 }
137
138 // Ready the defaults for the object
139 vector targetPos = obj.GetPosition();
140 float targetAngle = Math.RAD2DEG * Math.AbsFloat(Math3D.AngleFromPosition(coneOrigin, dir, targetPos));
141 float targetDistance2 = vector.DistanceSq(targetPos, Math3D.NearestPoint(rayStart, rayEnd, targetPos));
142 int hitComponent = -1;
143
144 float csSum = float.MAX;
145
146 // Find the most suitable component
147 ComponentResult result;
148 if (FindMostSuitableComponentEx(obj, bResult, settings, csSum, result, blacklistedDamageZones))
149 {
150 targetPos = result.ComponentPos;
151 targetAngle = result.ComponentAngle;
152 targetDistance2 = result.ComponentDistance2;
153 hitComponent = result.ComponentIdx;
154 }
155
156 // ProxyInfo
157 if (bResult.proxyInfo)
158 {
159 foreach (BoxCollidingResult pInfo : bResult.proxyInfo)
160 {
161 if (FindMostSuitableComponentEx(obj, pInfo, settings, csSum, result, blacklistedDamageZones))
162 {
163 targetPos = result.ComponentPos;
164 targetAngle = result.ComponentAngle;
165 targetDistance2 = result.ComponentDistance2;
166 hitComponent = result.ComponentIdx;
167 }
168 }
169 }
170
171 // No suitable component found
172 if (hitComponent == -1 || csSum == float.MAX)
173 {
174 continue;
175 }
176
177 // Check if it is a better fit than what has been found previously
178 float sum = targetDistance2;
179 if (sum < retVal)
180 {
181 ret = new MeleeTargetData(obj, targetPos, hitComponent);
182 retVal = sum;
183 }
184
185 allTargets.Insert(obj);
186 }
187 }
188
189 return ret;
190 }
191
193 {
194 return GetMeleeTargetEx(settings, allTargets);
195 }
196
197
198 bool FindMostSuitableComponentEx(Object obj, BoxCollidingResult bResult, MeleeTargetSettings settings, out float sum, out ComponentResult result, array<string> blacklistedDamageZones)
199 {
200 foreach (ComponentInfo cInfo : bResult.componentInfo)
201 {
202 ComponentResult cResult = new ComponentResult;
203
204 if (!EvaluateComponentEx(obj, cInfo, settings, cResult, blacklistedDamageZones))
205 {
206 continue;
207 }
208
209 // Smallest number is a winner
210 float cSum = cResult.ComponentDistance2;
211 if (cSum < sum)
212 {
213 sum = cSum;
214 result = cResult;
215 }
216 }
217
218 return result != null;
219 }
220
221 bool FindMostSuitableComponent(Object obj, BoxCollidingResult bResult, MeleeTargetSettings settings, out float sum, out ComponentResult result)
222 {
223 return FindMostSuitableComponentEx(obj, bResult, settings, sum, result, null);
224 }
225
226 bool EvaluateComponentEx(Object obj, ComponentInfo cInfo, MeleeTargetSettings settings, out ComponentResult result, array<string> blacklistedDamageZones)
227 {
229 foreach (string zoneName: blacklistedDamageZones)
230 {
231 if (obj.GetDamageZoneNameByComponentIndex(cInfo.component) == zoneName)
232 {
233 return false;
234 }
235 }
236
237 vector componentPos = cInfo.componentCenter;
238
239 // Too far away! (fast reject)
240 float componentMaxDist2 = Math.SqrFloat(settings.MaxDist + cInfo.componentRadius * obj.GetScale());
241 vector nearestPoint = Math3D.NearestPoint(settings.RayStart, settings.RayEnd, componentPos);
242 float componentDistance2 = vector.DistanceSq(componentPos, nearestPoint);
243 if (componentDistance2 > componentMaxDist2)
244 {
245 return false;
246 }
247
248 // Here some more accurate check could be placed that would adjust the componentPos
249
250 // Outside of the cone angle!
251 float componentAngle = Math.RAD2DEG * Math.AbsFloat(Math3D.AngleFromPosition(settings.ConeOrigin, settings.XZDir, componentPos));
252 if (componentAngle > settings.ConeHalfAngle)
253 {
254 return false;
255 }
256
257 // Obstructed!
258 if (IsMeleeTargetObstructed(settings.RayStart, componentPos))
259 {
260 return false;
261 }
262
263 // We found something, fill it in!
264 result.ComponentPos = componentPos;
265 result.ComponentAngle = componentAngle;
266 result.ComponentDistance2 = componentDistance2;
267 result.ComponentIdx = cInfo.component;
268
269 return true;
270 }
271
272 bool EvaluateComponent(Object obj, ComponentInfo cInfo, MeleeTargetSettings settings, out ComponentResult result)
273 {
274 return EvaluateComponentEx(obj, cInfo, settings, result, {});
275 }
276
277 bool IsMeleeTargetObstructed(vector rayStart, vector rayEnd)
278 {
279 if (rayStart == rayEnd)
280 {
281 return true; // Not possible to trace when this happens (zero length raycast)
282 }
283
284 Object hitObject;
285 vector hitPos, hitNormal;
286 float hitFraction;
287
288 return DayZPhysics.RayCastBullet( rayStart, rayEnd, MELEE_TARGET_OBSTRUCTION_LAYERS, null, hitObject, hitPos, hitNormal, hitFraction);
289 }
290}
PhxInteractionLayers
Определения DayZPhysics.c:2
DiagMenuIDs
Определения EDiagMenuIDs.c:2
const int MAX
Определения EnConvert.c:27
float ConeHalfAngleRad
Определения MeleeTargeting.c:20
vector ConeLeftPoint
Определения MeleeTargeting.c:24
bool EvaluateComponentEx(Object obj, ComponentInfo cInfo, MeleeTargetSettings settings, out ComponentResult result, array< string > blacklistedDamageZones)
Определения MeleeTargeting.c:226
bool FindMostSuitableComponentEx(Object obj, BoxCollidingResult bResult, MeleeTargetSettings settings, out float sum, out ComponentResult result, array< string > blacklistedDamageZones)
Определения MeleeTargeting.c:198
ref array< typename > TargetableObjects void MeleeTargetSettings(vector coneOrigin, float coneLength, float coneHalfAngle, float coneMinHeight, float coneMaxHeight, vector rayStart, vector dir, float maxDist, EntityAI pToIgnore, array< typename > targetableObjects)
Определения MeleeTargeting.c:36
float ConeMinHeight
Определения MeleeTargeting.c:21
float ConeLength
Определения MeleeTargeting.c:18
vector ConeRightPoint
Определения MeleeTargeting.c:25
bool FindMostSuitableComponent(Object obj, BoxCollidingResult bResult, MeleeTargetSettings settings, out float sum, out ComponentResult result)
Определения MeleeTargeting.c:221
vector XZDir
Определения MeleeTargeting.c:30
float MaxDist
Определения MeleeTargeting.c:31
EntityAI Attacker
Определения MeleeTargeting.c:33
MeleeTargetData GetMeleeTarget(MeleeTargetSettings settings, out array< Object > allTargets=null)
Определения MeleeTargeting.c:192
float ConeMaxHeight
Определения MeleeTargeting.c:22
bool IsMeleeTargetObstructed(vector rayStart, vector rayEnd)
Определения MeleeTargeting.c:277
bool EvaluateComponent(Object obj, ComponentInfo cInfo, MeleeTargetSettings settings, out ComponentResult result)
Определения MeleeTargeting.c:272
vector Dir
Определения MeleeTargeting.c:29
class MeleeTargetData ConeOrigin
float ConeHalfAngle
Определения MeleeTargeting.c:19
class ComponentResult MELEE_TARGET_OBSTRUCTION_LAYERS
MeleeTargetData GetMeleeTargetEx(MeleeTargetSettings settings, out array< Object > allTargets=null, array< string > blacklistedDamageZones=null)
Определения MeleeTargeting.c:76
vector RayStart
Определения MeleeTargeting.c:27
vector RayEnd
Определения MeleeTargeting.c:28
proto native void SetParams(vector center, vector orientation, vector edgeLength, ObjIntersect primaryType, ObjIntersect secondaryType, bool fullComponentInfo)
Set the parameters.
Class that holds parameters to feed into CGame.IsBoxCollidingGeometryProxy.
float ComponentAngle
Определения MeleeTargeting.c:67
vector ComponentPos
Определения MeleeTargeting.c:66
float ComponentDistance2
Определения MeleeTargeting.c:68
int ComponentIdx
Определения MeleeTargeting.c:69
Определения MeleeTargeting.c:65
static proto bool RayCastBullet(vector begPos, vector endPos, PhxInteractionLayers layerMask, Object ignoreObj, out Object hitObject, out vector hitPosition, out vector hitNormal, out float hitFraction)
Определения DayZPhysics.c:124
static Shape DrawLine(vector from, vector to, int color=0xFFFFFFFF, int flags=0)
Определения Debug.c:382
Определения Debug.c:2
Определения EnDebug.c:233
Определения Building.c:6
Определения EnMath3D.c:28
Определения EnMath.c:7
vector HitPos
Определения MeleeTargeting.c:4
int HitComponent
Определения MeleeTargeting.c:5
void MeleeTargetData(Object o, vector p, int c)
Определения MeleeTargeting.c:7
Object Obj
Определения MeleeTargeting.c:3
Определения MeleeTargeting.c:2
Определения ObjectTyped.c:2
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
const float MAX
Определения EnConvert.c:99
static proto native float DistanceSq(vector v1, vector v2)
Returns the square distance between tips of two 3D vectors.
static proto native float Distance(vector v1, vector v2)
Returns the distance between tips of two 3D vectors.
proto vector VectorToAngles()
Converts vector to spherical coordinates with radius = 1.
Определения EnConvert.c:106
proto native CGame GetGame()
const int COLOR_GREEN
Определения constants.c:65
ShapeFlags
Определения EnDebug.c:126
static proto bool GetBool(int id, bool reverse=false)
Get value as bool from the given script id.
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
static proto float AngleFromPosition(vector origin, vector originDir, vector target)
Angle that a target is from the direction of an origin.
static proto vector NearestPoint(vector beg, vector end, vector pos)
Point on line beg .. end nearest to pos.
static proto void ConePoints(vector origin, float length, float halfAngle, float angleOffset, out vector leftPoint, out vector rightPoint)
Calculates the points of a right 2D cone in 3D space.
static proto float Lerp(float a, float b, float time)
Linearly interpolates between 'a' and 'b' given 'time'.
static proto float SqrFloat(float f)
Returns squared value.
static proto float Tan(float angle)
Returns tangent of angle in radians.
static proto float Atan2(float y, float x)
Returns angle in radians from tangent.
static const float RAD2DEG
Определения EnMath.c:16
static const float DEG2RAD
Определения EnMath.c:17
static proto float AbsFloat(float f)
Returns absolute value.