12 void StoreVicinityObject(
Object object,
Object parent =
null)
16 if (ib && (ib.IsBeingPlaced() || ib.IsHologram()))
36 for (
int i = 0; i < objects.Count(); i++)
40 StoreVicinityObject(objects[i]);
46 void ClearVicinityObjects()
59 if (ib && !ib.IsTakeable())
62 vicinityObjects.Insert(GetObject(i));
65 return vicinityObjects;
74 vicinityObjects.Insert(GetObject(i));
77 return vicinityObjects;
104 for (
int i = 0; i < objects.Count(); i++)
156 string res =
"ActionTarget dump = {";
161 res = res +
"; m_Utility: " +
m_Utility.ToString();
202 Object cursorTarget =
null;
207 int hitComponentIndex;
208 vector playerPos = m_Player.GetPosition();
209 vector headingDirection = MiscGameplayFunctions.GetHeadingVector(m_Player);
211 m_RayStart =
GetGame().GetCurrentCameraPosition();
212 m_RayEnd = m_RayStart +
GetGame().GetCurrentCameraDirection() * c_RayDistance;
219 if (
DayZPhysics.RaycastRVProxy(rayInput, results) )
221 if ( results.Count() > 0 )
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() )
267 hitComponentIndex = res.component;
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);
298 FilterObstructedObjectsEx(cursorTarget, vicinityObjects);
306 float utility = ComputeUtility(
object, m_RayStart, m_RayEnd, cursorTarget, m_HitPos);
309 int targetComponent = -1;
310 targetComponent = hitComponentIndex;
320 if (m_HitPos ==
vector.Zero)
322 vector contact_pos, contact_dir, hitNormal;
323 int contactComponent;
327 m_RayEnd = m_RayStart +
GetGame().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));
336 #ifdef DIAG_DEVELOPER
339 ShowDebugActionTargets(
true);
340 DrawDebugActionTargets(
true);
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(); }
374 {
return m_Targets.Get(index); }
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 )
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();
437 if (
vector.DistanceSq(playerPosXZ, hitPosXZ) <= c_MaxTargetDistance * c_MaxTargetDistance )
438 return c_UtilityMaxValue;
441 float distSqr = DistSqrPoint2Line(pTarget.GetPosition(), pRayStart, pRayEnd);
442 return (c_UtilityMaxDistFromRaySqr - distSqr) / c_UtilityMaxDistFromRaySqr;
454 float c1 =
vector.Dot(w,v);
455 float c2 =
vector.Dot(v,v);
457 if ( c1 <= 0 || c2 == 0 )
458 return vector.DistanceSq(pPoint, pL1);
461 vector nearestPoint = pL1 + (v * b);
462 return vector.DistanceSq(pPoint, nearestPoint);
465 private void FilterObstructedObjectsEx(
Object cursor_target,
array<Object> vicinityObjects)
467 #ifdef DIAG_DEVELOPER
469 CleanupDebugShapes(obstruction);
473 MiscGameplayFunctions.FilterObstructingObjects(vicinityObjects, obstructingObjects);
475 if ( obstructingObjects.Count() > 0 )
479 int numObstructed = 0;
482 if (mCount > GROUPING_COUNT_THRESHOLD)
485 MiscGameplayFunctions.FilterObstructedObjectsByGrouping(m_RayStart, c_MaxTargetDistance, c_DistanceDelta,
m_VicinityObjects.GetRawVicinityObjects(), vicinityObjects, filteredObjects);
491 FilterObstructedObjects(cursor_target);
496 private void FilterObstructedObjects(
Object cursor_target)
498 int numObstructed = 0;
504 for (
int i = mCount; i >= 0; --i )
510 if (
object && !parent)
514 if (numObstructed > OBSTRUCTED_COUNT_THRESHOLD &&
object != cursor_target)
521 if (
object != cursor_target && IsObstructedEx(
object, cache))
532 #ifdef DIAG_DEVELOPER
539 void ShowDebugActionTargets(
bool enabled)
546 DbgUI.BeginCleanupScope();
550 for (
int i = 0; i < GetTargetsCount(); i++ )
552 obj = m_Targets.Get(i).GetObject();
555 float util = m_Targets.Get(i).GetUtility();
556 int compIdx = m_Targets.Get(i).GetComponentIndex();
559 compName = obj.GetActionComponentName(compIdx);
560 obj.GetActionComponentNameList(compIdx, compNames);
562 if ( compNames.Count() > 0 )
564 for (
int c = 0; c < compNames.Count(); c++ )
566 DbgUI.Text(obj.GetDisplayName() +
" :: " + obj +
" | util: " + util +
" | compIdx: " + compIdx +
" | compName: " + compNames[c] +
"| wPos: " + obj.GetWorldPosition() );
571 DbgUI.Text(obj.GetDisplayName() +
" :: " + obj +
" | util: " + util +
" | compIdx: " + compIdx +
" | compName: " + compName +
"| wPos: " + obj.GetWorldPosition() );
579 DbgUI.EndCleanupScope();
582 void DrawDebugActionTargets(
bool enabled)
592 CleanupDebugShapes(shapes);
594 for (
int i = 0; i < GetTargetsCount(); i++ )
596 obj = m_Targets.Get(i).GetObject();
599 w_pos = obj.GetPosition();
602 w_pos_sphr[1] = w_pos_sphr[1] + 0.5;
605 w_pos_lend[1] = w_pos_lend[1] + 0.5;
621 CleanupDebugShapes(shapes);
624 private void DrawDebugCone(
bool enabled)
627 vector start, end, endL, endR;
633 CleanupDebugShapes(dbgConeShapes);
635 start = m_Player.GetPosition();
636 playerAngle = MiscGameplayFunctions.GetHeadingAngle(m_Player);
639 start[1] = start[1] + 0.2;
643 xL = c_MaxTargetDistance *
Math.Cos(playerAngle +
Math.PI_HALF + c_ConeAngle *
Math.DEG2RAD);
644 zL = c_MaxTargetDistance *
Math.Sin(playerAngle +
Math.PI_HALF + c_ConeAngle *
Math.DEG2RAD);
645 xR = c_MaxTargetDistance *
Math.Cos(playerAngle +
Math.PI_HALF - c_ConeAngle *
Math.DEG2RAD);
646 zR = c_MaxTargetDistance *
Math.Sin(playerAngle +
Math.PI_HALF - c_ConeAngle *
Math.DEG2RAD);
647 endL[0] = endL[0] + xL;
648 endL[2] = endL[2] + zL;
649 endR[0] = endR[0] + xR;
650 endR[2] = endR[2] + zR;
657 CleanupDebugShapes(dbgConeShapes);
660 private void DrawSelectionPos(
bool enabled)
664 CleanupDebugShapes(dbgPosShapes);
665 if (GetTargetsCount() > 0 && GetTarget(0).
GetUtility() > -1 )
670 string compName = at.GetObject().GetActionComponentName(at.GetComponentIndex());
671 vector modelPos = at.GetObject().GetSelectionPositionMS(compName);
672 vector worldPos = at.GetObject().ModelToWorld(modelPos);
678 CleanupDebugShapes(dbgPosShapes);
681 private void DrawDebugRay(
bool enabled)
685 CleanupDebugShapes(rayShapes);
690 CleanupDebugShapes(rayShapes);
695 for (
int it = 0; it < shapesArr.Count(); ++it )
697 Debug.RemoveShape( shapesArr[it] );
718 private vector m_RayStart;
726 private const float c_RayDistance = 5.0;
727 private const float c_MaxTargetDistance = 3.0;
729 private const float c_ConeAngle = 30.0;
730 private const float c_ConeHeightMin = -0.5;
731 private const float c_ConeHeightMax = 2.0;
732 private const float c_DistanceDelta = 0.3;
735 private const float c_UtilityMaxValue = 10000;
736 private const float c_UtilityMaxDistFromRaySqr = 0.8 * 0.8;
739 private const string CE_CENTER =
"ce_center";
740 private const float HEIGHT_OFFSET = 0.2;
743 private const int OBSTRUCTED_COUNT_THRESHOLD = 3;
744 private const int GROUPING_COUNT_THRESHOLD = 10;
747 vector CalculateRayStart();