12 void StoreVicinityObject(
Object object,
Object parent = null)
16 if (ib && (ib.IsBeingPlaced() || ib.IsHologram()))
26 if ( !m_VicinityObjects.Contains(
object) )
29 m_VicinityObjects.Set(
object, parent);
36 for (
int i = 0; i < objects.Count(); i++)
40 StoreVicinityObject(objects[i]);
46 void ClearVicinityObjects()
48 m_VicinityObjects.Clear();
55 for (
int i = 0; i < m_VicinityObjects.Count(); i++)
65 return vicinityObjects;
72 for (
int i = 0; i < m_VicinityObjects.Count(); i++)
77 return vicinityObjects;
83 return m_VicinityObjects.GetKey(i);
89 return m_VicinityObjects.GetElement(i);
94 return m_VicinityObjects.Count();
99 m_VicinityObjects.Remove(
object);
104 for (
int i = 0; i < objects.Count(); i++)
106 m_VicinityObjects.Remove(objects[i]);
113 void ActionTarget(
Object object,
Object parent,
int componentIndex,
vector cursorHitPos,
float utility)
118 m_CursorHitPos = cursorHitPos;
139 {
return m_Utility; }
142 {
return m_CursorHitPos; }
146 m_CursorHitPos = cursor_position;
156 string res =
"ActionTarget dump = {";
160 res = res +
"; m_CursorHitPos: " + m_CursorHitPos.ToString();
161 res = res +
"; m_Utility: " + m_Utility.ToString();
169 private vector m_CursorHitPos;
170 private float m_Utility;
175 void ActionTargets(PlayerBase player)
178 m_VicinityObjects =
new VicinityObjects;
179 m_Targets =
new array<ref ActionTarget>;
184 static array<Object> GetVicinityObjects()
186 return m_VicinityObjects.GetVicinityObjects();
199 m_VicinityObjects.ClearVicinityObjects();
202 Object cursorTarget = null;
204 array<Object> vicinityObjects =
new array<Object>;
207 int hitComponentIndex;
208 vector playerPos = m_Player.GetPosition();
209 vector headingDirection = MiscGameplayFunctions.GetHeadingVector(m_Player);
211 m_RayStart =
g_Game.GetCurrentCameraPosition();
212 m_RayEnd = m_RayStart +
g_Game.GetCurrentCameraDirection() * c_RayDistance;
214 RaycastRVParams rayInput =
new RaycastRVParams(m_RayStart, m_RayEnd, m_Player);
217 array<ref RaycastRVResult> results =
new array<ref RaycastRVResult>;
219 if ( DayZPhysics.RaycastRVProxy(rayInput, results) )
221 if ( results.Count() > 0 )
223 array<float> distance_helper =
new array<float>;
224 array<float> distance_helper_unsorted =
new array<float>;
227 for (i = 0; i < results.Count(); i++)
229 distance = vector.DistanceSq(results[i].pos, m_RayStart);
230 distance_helper.Insert(distance);
234 distance_helper_unsorted.Copy(distance_helper);
235 distance_helper.Sort();
240 for ( i = 0; i < results.Count(); i++)
242 res = results.Get(distance_helper_unsorted.Find(distance_helper[i]));
244 cursorTarget = res.obj;
245 Class.CastTo(cursorTargetEntity,cursorTarget);
246 if (cursorTarget && !cursorTarget.CanBeActionTarget())
249 if ( res.hierLevel > 0 )
252 if ( !res.parent.IsMan() )
254 m_VicinityObjects.StoreVicinityObject(res.obj, res.parent);
262 m_VicinityObjects.StoreVicinityObject(res.obj, null);
267 hitComponentIndex = res.component;
278 m_HitPos = vector.Zero;
279 hitComponentIndex = -1;
286 if (camera && camera.GetCurrentPitch() <= -45)
287 DayZPlayerUtils.GetEntitiesInCone(playerPos, headingDirection, c_ConeAngle, c_MaxTargetDistance, c_ConeHeightMin, c_ConeHeightMax, vicinityObjects);
290 vicinityObjects.RemoveItem(m_Player);
294 m_VicinityObjects.TransformToVicinityObjects(vicinityObjects);
298 FilterObstructedObjectsEx(cursorTarget, vicinityObjects);
301 for ( i = 0; i < m_VicinityObjects.Count(); i++ )
303 Object object = m_VicinityObjects.GetObject(i);
304 Object parent = m_VicinityObjects.GetParent(i);
306 float utility = ComputeUtility(
object, m_RayStart, m_RayEnd, cursorTarget, m_HitPos);
309 int targetComponent = -1;
310 targetComponent = hitComponentIndex;
312 ActionTarget at =
new ActionTarget(
object, parent, targetComponent, m_HitPos, utility);
320 if (m_HitPos == vector.Zero)
322 vector contact_pos, contact_dir, hitNormal;
323 int contactComponent;
327 m_RayEnd = m_RayStart +
g_Game.GetCurrentCameraDirection() * c_RayDistance * 3;
330 DayZPhysics.RayCastBullet(m_RayStart,m_RayEnd,collisionLayerMask,null,hitObject,contact_pos,hitNormal,hitFraction);
331 m_HitPos = contact_pos;
334 m_Targets.Insert(
new ActionTarget(null, null, -1, m_HitPos, 0));
337 if (DiagMenu.GetBool(
DiagMenuIDs.MISC_ACTION_TARGETS_DEBUG))
339 ShowDebugActionTargets(
true);
340 DrawDebugActionTargets(
true);
343 DrawSelectionPos(DiagMenu.GetBool(
DiagMenuIDs.MISC_ACTION_TARGETS_SELPOS_DEBUG));
347 ShowDebugActionTargets(
false);
348 DrawDebugActionTargets(
false);
349 DrawDebugCone(
false);
351 DrawSelectionPos(
false);
357 private bool IsObstructed(
Object object)
360 return IsObstructedEx(
object, cache);
365 return MiscGameplayFunctions.IsObjectObstructedEx(
object, cache);
369 int GetTargetsCount()
370 {
return m_Targets.Count(); }
373 ActionTarget GetTarget(
int index)
374 {
return m_Targets.Get(index); }
377 private void StoreTarget(ActionTarget pActionTarget)
379 int index = FindIndexForStoring(pActionTarget.GetUtility());
380 m_Targets.InsertAt(pActionTarget, index);
385 private int FindIndexForStoring(
float value)
388 int right = m_Targets.Count() - 1;
389 while ( left <= right )
391 int middle = (left + right) / 2;
392 float middleValue = m_Targets.Get(middle).GetUtility();
394 if ( middleValue == value )
396 else if ( middleValue < value )
406 private float ComputeUtility(
Object pTarget, vector pRayStart, vector pRayEnd,
Object cursorTarget, vector hitPos)
409 if (vector.DistanceSq(hitPos, m_Player.GetPosition()) > c_MaxTargetDistance * c_MaxTargetDistance)
414 if ( pTarget == cursorTarget )
417 if ( pTarget.GetType() ==
string.Empty )
420 if ( pTarget.IsBuilding() )
423 if ( pTarget.IsTransport() )
427 if (pTarget.CanUseConstruction())
430 if ( pTarget.IsWell() )
433 vector playerPosXZ = m_Player.GetPosition();
434 vector hitPosXZ = hitPos;
437 if ( vector.DistanceSq(playerPosXZ, hitPosXZ) <= c_MaxTargetDistance * c_MaxTargetDistance )
438 return c_UtilityMaxValue;
441 if ( PlayerBase.Cast(pTarget) && PlayerBase.Cast(pTarget).IsInVehicle() )
444 float distSqr = DistSqrPoint2Line(pTarget.GetPosition(), pRayStart, pRayEnd);
445 return (c_UtilityMaxDistFromRaySqr - distSqr) / c_UtilityMaxDistFromRaySqr;
452 private float DistSqrPoint2Line(vector pPoint, vector pL1, vector pL2)
454 vector v = pL2 - pL1;
455 vector w = pPoint - pL1;
457 float c1 = vector.Dot(w,v);
458 float c2 = vector.Dot(v,v);
460 if ( c1 <= 0 || c2 == 0 )
461 return vector.DistanceSq(pPoint, pL1);
464 vector nearestPoint = pL1 + (v * b);
465 return vector.DistanceSq(pPoint, nearestPoint);
468 private void FilterObstructedObjectsEx(
Object cursor_target, array<Object> vicinityObjects)
470 #ifdef DIAG_DEVELOPER
471 if (DiagMenu.GetBool(
DiagMenuIDs.MISC_ACTION_TARGETS_DEBUG))
472 CleanupDebugShapes(obstruction);
475 array<Object> obstructingObjects =
new array<Object>;
476 MiscGameplayFunctions.FilterObstructingObjects(vicinityObjects, obstructingObjects);
478 if ( obstructingObjects.Count() > 0 )
480 PlayerBase player = PlayerBase.Cast(
g_Game.GetPlayer());
482 int numObstructed = 0;
483 int mCount = m_VicinityObjects.Count();
485 if (mCount > GROUPING_COUNT_THRESHOLD)
487 array<Object> filteredObjects =
new array<Object>;
488 MiscGameplayFunctions.FilterObstructedObjectsByGrouping(m_RayStart, c_MaxTargetDistance, c_DistanceDelta, m_VicinityObjects.GetRawVicinityObjects(), vicinityObjects, filteredObjects);
489 m_VicinityObjects.ClearVicinityObjects();
490 m_VicinityObjects.TransformToVicinityObjects(filteredObjects);
494 FilterObstructedObjects(cursor_target);
499 private void FilterObstructedObjects(
Object cursor_target)
501 int numObstructed = 0;
502 int mCount = m_VicinityObjects.Count();
507 for (
int i = mCount; i >= 0; --i )
509 Object object = m_VicinityObjects.GetObject(i);
510 Object parent = m_VicinityObjects.GetParent(i);
513 if (
object && !parent)
517 if (numObstructed > OBSTRUCTED_COUNT_THRESHOLD &&
object != cursor_target)
519 m_VicinityObjects.Remove(
object);
524 if (
object != cursor_target && IsObstructedEx(
object, cache))
526 m_VicinityObjects.Remove(
object);
536 ref array<Shape> shapes =
new array<Shape>();
537 ref array<Shape> dbgConeShapes =
new array<Shape>();
538 ref array<Shape> rayShapes =
new array<Shape>();
539 ref array<Shape> obstruction =
new array<Shape>();
540 ref array<Shape> dbgPosShapes =
new array<Shape>();
542 void ShowDebugActionTargets(
bool enabled)
549 DbgUI.BeginCleanupScope();
553 for (
int i = 0; i < GetTargetsCount(); i++ )
555 obj = m_Targets.Get(i).GetObject();
558 float util = m_Targets.Get(i).GetUtility();
559 int compIdx = m_Targets.Get(i).GetComponentIndex();
561 array<string> compNames =
new array<string>;
562 compName = obj.GetActionComponentName(compIdx);
563 obj.GetActionComponentNameList(compIdx, compNames);
565 if ( compNames.Count() > 0 )
567 for (
int c = 0; c < compNames.Count(); c++ )
569 DbgUI.Text(obj.GetDisplayName() +
" :: " + obj +
" | util: " + util +
" | compIdx: " + compIdx +
" | compName: " + compNames[c] +
"| wPos: " + obj.GetWorldPosition() );
574 DbgUI.Text(obj.GetDisplayName() +
" :: " + obj +
" | util: " + util +
" | compIdx: " + compIdx +
" | compName: " + compName +
"| wPos: " + obj.GetWorldPosition() );
582 DbgUI.EndCleanupScope();
585 void DrawDebugActionTargets(
bool enabled)
595 CleanupDebugShapes(shapes);
597 for (
int i = 0; i < GetTargetsCount(); i++ )
599 obj = m_Targets.Get(i).GetObject();
602 w_pos = obj.GetPosition();
605 w_pos_sphr[1] = w_pos_sphr[1] + 0.5;
608 w_pos_lend[1] = w_pos_lend[1] + 0.5;
624 CleanupDebugShapes(shapes);
627 private void DrawDebugCone(
bool enabled)
630 vector start, end, endL, endR;
636 CleanupDebugShapes(dbgConeShapes);
638 start = m_Player.GetPosition();
639 playerAngle = MiscGameplayFunctions.GetHeadingAngle(m_Player);
642 start[1] = start[1] + 0.2;
646 xL = c_MaxTargetDistance * Math.Cos(playerAngle + Math.PI_HALF + c_ConeAngle * Math.DEG2RAD);
647 zL = c_MaxTargetDistance * Math.Sin(playerAngle + Math.PI_HALF + c_ConeAngle * Math.DEG2RAD);
648 xR = c_MaxTargetDistance * Math.Cos(playerAngle + Math.PI_HALF - c_ConeAngle * Math.DEG2RAD);
649 zR = c_MaxTargetDistance * Math.Sin(playerAngle + Math.PI_HALF - c_ConeAngle * Math.DEG2RAD);
650 endL[0] = endL[0] + xL;
651 endL[2] = endL[2] + zL;
652 endR[0] = endR[0] + xR;
653 endR[2] = endR[2] + zR;
660 CleanupDebugShapes(dbgConeShapes);
663 private void DrawSelectionPos(
bool enabled)
667 CleanupDebugShapes(dbgPosShapes);
668 if (GetTargetsCount() > 0 && GetTarget(0).
GetUtility() > -1 )
670 ActionTarget at = GetTarget(0);
673 string compName = at.GetObject().GetActionComponentName(at.GetComponentIndex());
674 vector modelPos = at.GetObject().GetSelectionPositionMS(compName);
675 vector worldPos = at.GetObject().ModelToWorld(modelPos);
681 CleanupDebugShapes(dbgPosShapes);
684 private void DrawDebugRay(
bool enabled)
688 CleanupDebugShapes(rayShapes);
693 CleanupDebugShapes(rayShapes);
696 private void CleanupDebugShapes(array<Shape> shapesArr)
698 for (
int it = 0; it < shapesArr.Count(); ++it )
700 Shape shape = shapesArr[it];
701 Debug.RemoveShape( shape );
712 private PlayerBase m_Player;
715 private ref array<ref ActionTarget> m_Targets;
718 static private ref VicinityObjects m_VicinityObjects
722 private vector m_RayStart;
723 private vector m_RayEnd;
724 private vector m_HitPos;
730 private const float c_RayDistance = 5.0;
731 private const float c_MaxTargetDistance = 3.0;
732 private const float c_MaxActionDistance = UAMaxDistances.DEFAULT;
733 private const float c_ConeAngle = 30.0;
734 private const float c_ConeHeightMin = -0.5;
735 private const float c_ConeHeightMax = 2.0;
736 private const float c_DistanceDelta = 0.3;
739 private const float c_UtilityMaxValue = 10000;
740 private const float c_UtilityMaxDistFromRaySqr = 0.8 * 0.8;
743 private const string CE_CENTER =
"ce_center";
744 private const float HEIGHT_OFFSET = 0.2;
747 private const int OBSTRUCTED_COUNT_THRESHOLD = 3;
748 private const int GROUPING_COUNT_THRESHOLD = 10;
751 vector CalculateRayStart();
756 ref array<Object> Objects =
new array<Object>;
eBleedingSourceType GetType()
void DbgPrintTargetDump()
void SetCursorHitPos(vector cursor_position)
override bool IsTakeable()
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
proto native int GetComponentIndex()
class DayZPlayerCameraResult DayZPlayerCamera(DayZPlayer pPlayer, HumanInputController pInput)
proto void Print(void var)
Prints content of variable to console/log.
void IsObjectObstructedCache(vector rayCastStart, int totalObjects)
class PresenceNotifierNoiseEvents windowPosX
dbgUI settings
override bool CanBeActionTarget()