429 {
430 const float DEFAULT_HANDLE_OFFSET = 0.2;
431 const string CE_CENTER_COMP_NAME = "ce_center";
432 const string MEM_LOD_NAME = LOD.NAME_MEMORY;
433
434 int compIdx;
435 float pivotOffset = 0.0;
436 float memOffset = 0.0;
437 string compName;
438
439 bool isTargetForced = false;
440
441 vector worldPos;
442 vector modelPos;
443
444 LOD lod;
445
446 array<Selection> memSelections = new array<Selection>();
447 array<string> components = new array<string>;
448
450
452 {
454 compIdx =
m_Target.GetComponentIndex();
455
456 if (
m_Target.GetCursorHitPos() == vector.Zero)
457 isTargetForced = true;
458 }
459 else
460 {
461 return;
462 }
463
464 if (object)
465 {
466 if (!isTargetForced)
467 {
468 compName = object.GetActionComponentName(compIdx);
469 int namedComponentType = object.GetActionComponentNameList(compIdx, components);
470
472 {
474 return;
475 }
476
477 pivotOffset = object.ConfigGetFloat("actionTargetPivotOffsetY");
478 memOffset = object.ConfigGetFloat("actionTargetMemOffsetY");
479
481 lod = object.GetLODByName(MEM_LOD_NAME);
482 if (lod != null)
483 {
486
487
488 if (MiscGameplayFunctions.IsComponentInSelection(memSelections, CE_CENTER_COMP_NAME))
489 {
490 for (int i2 = 0; i2 < memSelections.Count(); ++i2)
491 {
492 if (memSelections[i2].
GetName() == CE_CENTER_COMP_NAME && memSelections[i2].GetVertexCount() == 1)
493 {
495 modelPos = object.GetSelectionPositionMS(CE_CENTER_COMP_NAME);
496 worldPos = object.ModelToWorld(modelPos);
497 if (memOffset != 0.0)
498 {
499 worldPos[1] = worldPos[1] + memOffset;
500 }
501 else
502 {
503 worldPos[1] = worldPos[1] + DEFAULT_HANDLE_OFFSET;
504 }
505 }
506 }
507
510 }
513 {
514 for (int i1 = 0; i1 < memSelections.Count(); ++i1)
515 {
517 if (memSelections[i1].
GetName() == compName && memSelections[i1].GetVertexCount() == 1)
518 {
519 modelPos = object.GetSelectionPositionMS(compName);
520 worldPos = object.ModelToWorld(modelPos);
521
525
526 if (memOffset != 0.0)
527 {
528 worldPos[1] = worldPos[1] + memOffset;
529 }
530 else
531 {
532 worldPos[1] = worldPos[1] + DEFAULT_HANDLE_OFFSET;
533 }
534 }
535
537 if (memSelections[i1].
GetName() == compName && memSelections[i1].GetVertexCount() > 1)
538 {
539 for (int j = 0; j < components.Count(); ++j)
540 {
542 {
543 modelPos = object.GetSelectionPositionMS(components[j]);
544 worldPos = object.ModelToWorld(modelPos);
545
547 if (memOffset != 0.0)
548 {
549 worldPos[1] = worldPos[1] + memOffset;
550 }
551 else
552 {
553 worldPos[1] = worldPos[1] + DEFAULT_HANDLE_OFFSET;
554 }
555 }
556 }
557 }
558 }
559
562 }
565 {
566 vector ladderHandlePointLS, ladderHandlePointWS;
567 vector closestHandlePos;
568 float lastDistance = 0;
569
570 for (int i3 = 0; i3 < memSelections.Count(); ++i3)
571 {
572 if (memSelections[i3].
GetName() == compName && memSelections[i3].GetVertexCount() > 1)
573 {
574 ladderHandlePointLS = memSelections[i3].GetVertexPosition(lod, 0);
575 ladderHandlePointWS = object.ModelToWorld(ladderHandlePointLS);
576 closestHandlePos = ladderHandlePointWS;
577 lastDistance = Math.AbsFloat(vector.DistanceSq(ladderHandlePointWS,
m_Player.GetPosition()));
578
579 for (int k = 1; k < memSelections[i3].GetVertexCount(); ++k)
580 {
581 ladderHandlePointLS = memSelections[i3].GetVertexPosition(lod, k);
582 ladderHandlePointWS = object.ModelToWorld(ladderHandlePointLS);
583
584 if (lastDistance > Math.AbsFloat(vector.DistanceSq(ladderHandlePointWS,
m_Player.GetPosition())))
585 {
586 lastDistance = Math.AbsFloat(vector.DistanceSq(ladderHandlePointWS,
m_Player.GetPosition()));
587 closestHandlePos = ladderHandlePointWS;
588 }
589 }
590
592 worldPos = closestHandlePos;
593 if (memOffset != 0.0)
594 {
595 worldPos[1] = worldPos[1] + memOffset;
596 }
597 else
598 {
599 worldPos[1] = worldPos[1] + DEFAULT_HANDLE_OFFSET;
600 }
601 }
602 }
603
606 }
607 else
608 {
610 }
611 }
612 else
613 {
615 }
616 }
617 else
618 {
620 }
621
623
626 }
627
628 worldPos = vector.
Zero;
629 isTargetForced = false;
630 }
eBleedingSourceType GetType()
override bool CanUseConstruction()
override bool HasFixedActionTargetCursorPosition()
bool IsComponentInSelection(array< Selection > selection, string compName)
vector TransformToScreenPos(vector pWorldPos)
transform world pos to screen pos (related to parent widget size)
ref ATCCachedObject m_CachedObject
proto native bool GetSelections(notnull out array< Selection > selections)
bool Contains(string sample)
Returns true if sample is substring of string.