Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
Functions.c
Go to the documentation of this file.
1//------------------------------------------------------------------------------------------------
5//------------------------------------------------------------------------------------------------
7{
9 static Widget m_DebugLayoutCanvas;
10
12 static IEntity g_TraceFilterEnt = null;
13
15 static ref set<IEntity> g_TraceFilterList = new set<IEntity>();
16
18 static float g_fPhysicsHz = 60;
19
20 //------------------------------------------------------------------------------------------------
21 static bool IsScope2DEnabled()
22 {
23 BaseContainer gameplaySettings = GetGame().GetGameUserSettings().GetModule("SCR_GameplaySettings");
25 {
26 bool bval;
27 if (gameplaySettings.Get("m_b2DScopes", bval))
28 return bval;
29 }
30
31 // 2d scopes enabled by default = supresses PIP which is less performant
32 return true;
33 }
34
35 //------------------------------------------------------------------------------------------------
36 static string GetPlatformName(PlatformKind kind)
37 {
38 switch (kind)
39 {
40 case PlatformKind.NONE:
41 return "platform-windows";
42
43 case PlatformKind.PSN:
44 return "platform-playstation";
45
46 case PlatformKind.XBOX:
47 return "platform-xbox";
48
49 case PlatformKind.STEAM:
50 return "platform-windows";
51 }
52
53 return string.Empty;
54 }
55
56 //------------------------------------------------------------------------------------------------
57 static string GetProfileName()
58 {
59 string name;
60
61 if (GetGame().GetBackendApi().IsLocalPlatformAssigned())
62 {
63 Print("Profile - Using Local Platform Name!");
64 name = BohemiaAccountApi.GetName();
65 return name;
66 }
67
68 BaseContainer gameplaySettings = GetGame().GetGameUserSettings().GetModule("SCR_GameplaySettings");
70 {
71 gameplaySettings.Get("m_sProfileName", name);
72 }
73
74 if (name == string.Empty)
75 {
76 name = System.GetProfileName();
77 if (name == string.Empty)
78 {
79 Print("Profile - Using MachineName!");
80 name = System.GetMachineName();
81 }
82 }
83
84 return name;
85 }
86
87 //------------------------------------------------------------------------------------------------
89 // unused (and to fix!)
90 static vector FixVector180(vector vec)
91 {
92 for (int a = 0; a < 3; a++)
93 {
94 float v = vec[a];
95 while (v > 180)
96 v -= 360;
97 while (v < -180)
98 v += 360;
99 vec[a] = v;
100 }
101
102 return vec;
103 }
104
105 //------------------------------------------------------------------------------------------------
108 // unused
109 static vector GetVectorClampedToWorldBounds(vector pos)
110 {
111 if (!GetGame().GetWorldEntity().GetWorld().IsOcean())
112 return pos;
113
114 if (!GetGame().GetWorldEntity())
115 return pos;
116
117 vector min, max;
118 GetGame().GetWorldEntity().GetWorldBounds(min, max);
119
120 for (int a = 0; a < 3; a++)
121 {
122 if (pos[a] < min[a])
123 pos[a] = min[a];
124 if (pos[a] > max[a])
125 pos[a] = max[a];
126 }
127
128 return pos;
129 }
130
131 //------------------------------------------------------------------------------------------------
137 // unused
138 static bool GetIntersectPointPlane(vector start, vector end, out vector result, float height)
139 {
140 vector dir = end - start;
141 float dist = dir.NormalizeSize();
142
143 vector mins = start;
144 vector maxs = start;
145
146 for (int a = 0; a < 3; a++)
147 {
148 if (a == 1)
149 continue;
150
151 float val1 = start[a];
152 float val2 = end[a];
153 if (val1 < mins[a])
154 mins[a] = val1;
155 if (val2 < mins[a])
156 mins[a] = val2;
157 if (val1 > maxs[a])
158 maxs[a] = val1;
159 if (val2 > maxs[a])
160 maxs[a] = val2;
161 }
162 mins[1] = height;
163 maxs[1] = height;
164 float intersectPct = Math3D.IntersectionRayBox(start, end, mins - "1 0 1", maxs + "1 0 1");
165 if (intersectPct < 0)
166 return false;
167
168 result = dir * dist * intersectPct + start;
169
170 return true;
171 }
172
173 //------------------------------------------------------------------------------------------------
179 // unused
180 static void GetDistForHUD(float dist, bool imperial, out string tgtDist, out string distFormat)
181 {
182 if (imperial)
183 {
184 dist *= 0.9144; // To yards
185 if (dist >= 1000)
186 {
187 dist /= 1760; // To miles
188 dist = Math.Floor(dist * 10) * 0.1;
189 tgtDist = dist.ToString();
190 distFormat = "mi";
191 }
192 else if (dist >= 100)
193 {
194 dist = Math.Floor(dist * 10) * 0.1;
195 tgtDist = dist.ToString();
196 distFormat = "yd";
197 }
198 else if (dist >= 1)
199 {
200 dist = Math.Floor(dist * 100) * 0.01;
201 tgtDist = dist.ToString();
202 distFormat = "yd";
203 }
204 else
205 {
206 dist = Math.Floor(dist * 360) * 0.1;
207 tgtDist = dist.ToString();
208 distFormat = "in";
209 }
210 }
211 else
212 {
213 if (dist >= 1000)
214 {
215 dist /= 1000; // To kilometers
216 dist = Math.Floor(dist * 10) * 0.1;
217 tgtDist = dist.ToString();
218 distFormat = "km";
219 }
220 else if (dist >= 100)
221 {
222 dist = Math.Floor(dist * 10) * 0.1;
223 tgtDist = dist.ToString();
224 distFormat = "m";
225 }
226 else if (dist >= 1)
227 {
228 dist = Math.Floor(dist * 100) * 0.01;
229 tgtDist = dist.ToString();
230 distFormat = "m";
231 }
232 else
233 {
234 dist = Math.Floor(dist * 1000) * 0.1;
235 tgtDist = dist.ToString();
236 distFormat = "cm";
237 }
238 }
239 }
240
241 //------------------------------------------------------------------------------------------------
243 static bool FilterCallback_IgnoreNotInList(notnull IEntity target)
244 {
245 if (g_TraceFilterList.Contains(target))
246 return true;
247
248 return false;
249 }
250
251 //------------------------------------------------------------------------------------------------
253 // unused
254 static bool FilterCallback_IgnoreCharactersWithChildren(notnull IEntity target)
255 {
256 while (target)
257 {
258 if (ChimeraCharacter.Cast(target))
259 return false;
260
261 target = target.GetParent();
262 }
263
264 return true;
265 }
266
267 //------------------------------------------------------------------------------------------------
269 // unused
270 static bool FilterCallback_IgnoreCharacters(notnull IEntity target)
271 {
272 if (ChimeraCharacter.Cast(target))
273 return false;
274
275 return true;
276 }
277
278 //------------------------------------------------------------------------------------------------
280 // unused
281 static bool FilterCallback_IgnoreEntityWithChildren(notnull IEntity target, vector rayorigin, vector raydirection)
282 {
283 if (g_TraceFilterEnt == null)
284 return true;
285
286 while (target)
287 {
288 if (target == g_TraceFilterEnt)
289 return false;
290
291 target = target.GetParent();
292 }
293
294 return true;
295 }
296
297 //------------------------------------------------------------------------------------------------
299 static bool FilterCallback_IgnoreAllButEntityWithChildren(notnull IEntity target, vector rayorigin, vector raydirection)
300 {
301 if (g_TraceFilterEnt == null)
302 return false;
303
304 while (target)
305 {
306 if (target == g_TraceFilterEnt)
307 return true;
308
309 target = target.GetParent();
310 }
311
312 return false;
313 }
314
315 //------------------------------------------------------------------------------------------------
317 static bool FilterCallback_IgnoreAllButEntity(notnull IEntity target, vector rayorigin, vector raydirection)
318 {
319 if (g_TraceFilterEnt == null)
320 return false;
321
322 if (target == g_TraceFilterEnt)
323 return true;
324
325 return false;
326 }
327
328 //------------------------------------------------------------------------------------------------
332 // unused
333 static bool FilterCallback_IgnoreAllButMeleeAttackable(notnull IEntity target, vector rayorigin, vector raydirection)
334 {
335 typename type = target.Type();
336
337 if (ChimeraCharacter == type)
338 return true;
339
340 if (Tree == type)
341 return true;
342
343 if (Building == type)
344 return true;
345
346 if (target.FindComponent(DamageManagerComponent))
347 return true;
348
349 return false;
350 }
351
352 //------------------------------------------------------------------------------------------------
354 // unused
355 static bool FilterCallback_IgnoreAllButBuildingRegions(notnull IEntity target, vector rayorigin, vector raydirection)
356 {
357 typename type = target.Type();
359 return true;
360
362 return true;
363
364 return false;
365 }
366
367 //------------------------------------------------------------------------------------------------
369 static float GetScaledStructuralDamage(float damage, EDamageType type)
370 {
371 float dmgScale = 1;
372
373 switch (type)
374 {
375 case EDamageType.REGENERATION:
376 case EDamageType.BLEEDING:
377 {
378 dmgScale = 0;
379 break;
380 }
381 }
382
383 return damage * dmgScale;
384 }
385
386 //------------------------------------------------------------------------------------------------
388 // unused
389 static int GetChildIndex(IEntity ent)
390 {
391 IEntity parent = ent.GetParent();
392 if (!parent)
393 return -1;
394
395 int index = 0;
396 IEntity child = parent.GetChildren();
397 while (child)
398 {
399 if (child == ent)
400 return index;
401
402 index++;
403 child = child.GetSibling();
404 }
405
406 return -1;
407 }
408
409 //------------------------------------------------------------------------------------------------
411 static array<ref ParamEnum> GetBonesAsParamEnums(IEntity entity)
412 {
413 array<ref ParamEnum> retEnums = new array<ref ParamEnum>;
414 array<string> boneNames = new array<string>;
415 Animation anim = entity.GetAnimation();
416 anim.GetBoneNames(boneNames);
417
418 retEnums.Insert(new ParamEnum("NONE", "-1", "")); // Always have NONE as an option
419 foreach (string s : boneNames)
420 {
421 int nodeid = anim.GetBoneIndex(s);
422 retEnums.Insert(new ParamEnum(s, nodeid.ToString(), ""));
423 }
424
425 return retEnums;
426 }
427
428 //------------------------------------------------------------------------------------------------
430 // unused
431 static void SetEntityAsChildToParent(IEntity parent, IEntity child)
432 {
433 vector parentMat[4];
434 parent.GetTransform(parentMat);
435
436 vector childMat[4];
437 child.GetTransform(childMat);
438
439 vector childLocalMat[4];
440 Math3D.MatrixInvMultiply4(parentMat, childMat, childLocalMat);
441 child.SetTransform(childLocalMat);
442
443 parent.AddChild(child, -1);
444 }
445
446 //------------------------------------------------------------------------------------------------
448 // unused
449 static vector ScaleVectorByVector(vector inputVec, vector scaleVec)
450 {
451 vector result = vector.Zero;
452
453 result[0] = inputVec[0] * scaleVec[0];
454 result[1] = inputVec[1] * scaleVec[1];
455 result[2] = inputVec[2] * scaleVec[2];
456
457 return result;
458 }
459
460 //------------------------------------------------------------------------------------------------
462 // unused
463 static float GetGlobalYawForMat(vector mat[4])
464 {
465 vector fw = mat[0] * vector.Up;
466 fw.Normalize();
467 vector angs = fw.VectorToAngles();
468
469 return angs[0];
470 }
471
472 //------------------------------------------------------------------------------------------------
473 // Lerps between 2 matrices
474 // unused
475 static void LerpMatrix(vector mat1[4], vector mat2[4], out vector matOut[4], float pct)
476 {
477 if (pct == 0)
478 {
479 matOut[0] = mat1[0];
480 matOut[1] = mat1[1];
481 matOut[2] = mat1[2];
482 matOut[3] = mat1[3];
483 return;
484 }
485 else if (pct == 1)
486 {
487 matOut[0] = mat2[0];
488 matOut[1] = mat2[1];
489 matOut[2] = mat2[2];
490 matOut[3] = mat2[3];
491 return;
492 }
493
494 float q1[4], q2[4], qOut[4];
495 Math3D.MatrixToQuat(mat1, q1);
496 Math3D.MatrixToQuat(mat2, q2);
497 Math3D.QuatLerp(qOut, q1, q2, pct);
498 Math3D.QuatToMatrix(qOut, matOut);
499 matOut[3] = (mat2[3] - mat1[3]) * pct + mat1[3];
500 }
501
502 //------------------------------------------------------------------------------------------------
504 // unused
505 static void GetLocalMatrix(vector parentMat[4], vector childMat[4])
506 {
507 vector childOrigMat[4];
508 Math3D.MatrixCopy(childMat, childOrigMat);
509 Math3D.MatrixInvMultiply4(parentMat, childOrigMat, childMat);
510 }
511
512 //------------------------------------------------------------------------------------------------
514 // unused
515 static void GetWorldBoundsForEntity(vector mat[4], out vector mins, out vector maxs)
516 {
517 vector pt1, pt2;
518 pt1 = mins.Multiply4(mat);
519 pt2 = maxs.Multiply4(mat);
520 mins = pt1;
521 maxs = pt2;
522 for (int i = 0; i < 3; i++)
523 {
524 if (pt1[i] < mins[i])
525 mins[i] = pt1[i];
526 if (pt2[i] < mins[i])
527 mins[i] = pt2[i];
528 if (pt1[i] > maxs[i])
529 maxs[i] = pt1[i];
530 if (pt2[i] > maxs[i])
531 maxs[i] = pt2[i];
532 }
533 }
534
535 //------------------------------------------------------------------------------------------------
542 static void GetWorldBoundsWithChildren(IEntity entity, out vector min, out vector max, bool isChild = false)
543 {
544 if (!entity)
545 return;
546
547 if (!isChild)
548 {
549 min = Vector(float.MAX, float.MAX, float.MAX);
550 max = -Vector(float.MAX, float.MAX, float.MAX);
551 }
552
553 if (entity.GetVObject())
554 {
555 vector entityMin, entityMax;
556 entity.GetWorldBounds(entityMin, entityMax);
557
558 min[0] = Math.Min(min[0], entityMin[0]);
559 min[1] = Math.Min(min[1], entityMin[1]);
560 min[2] = Math.Min(min[2], entityMin[2]);
561
562 max[0] = Math.Max(max[0], entityMax[0]);
563 max[1] = Math.Max(max[1], entityMax[1]);
564 max[2] = Math.Max(max[2], entityMax[2]);
565 }
566
567 entity = entity.GetChildren();
568 while (entity)
569 {
570 GetWorldBoundsWithChildren(entity, min, max, true);
571 entity = entity.GetSibling();
572 }
573 }
574
575 //------------------------------------------------------------------------------------------------
577 // unused
578 static bool GetObjectAtOffsetFromObject(IEntity parent, IEntity child, vector localPos, vector localAng, float tolerancePos, float toleranceAng)
579 {
580 vector parentMat[4];
581 parent.GetTransform(parentMat);
582
583 vector offsetMat[4];
584 Math3D.AnglesToMatrix(localAng, offsetMat);
585 offsetMat[3] = localPos;
586
587 vector parentOffsetMat[4];
588 Math3D.MatrixMultiply4(parentMat, offsetMat, parentOffsetMat);
589
590 vector childMat[4];
591 child.GetTransform(childMat);
592
593 vector relativeMat[4];
594 Math3D.MatrixInvMultiply4(parentOffsetMat, childMat, relativeMat);
595
596 vector pos = relativeMat[3];
597 if (pos.Length() > tolerancePos)
598 return false;
599
600 float cross;
601 vector dir;
602
603 dir = relativeMat[0];
604 cross = dir * vector.Right;
605 if (Math.AbsFloat(cross) > toleranceAng)
606 return false;
607
608 dir = relativeMat[1];
609 cross = dir * vector.Up;
610 if (Math.AbsFloat(cross) > toleranceAng)
611 return false;
612
613 dir = relativeMat[2];
614 cross = dir * vector.Forward;
615 if (Math.AbsFloat(cross) > toleranceAng)
616 return false;
617
618 return true;
619 }
620
621 //------------------------------------------------------------------------------------------------
623 static bool IntersectBoxPoint(vector pos, vector mins, vector maxs)
624 {
625 for (int i = 0; i < 3; i++)
626 {
627 if (pos[i] > maxs[i])
628 return false;
629 if (pos[i] < mins[i])
630 return false;
631 }
632
633 return true;
634 }
635
636 //------------------------------------------------------------------------------------------------
638 // unused
639 static bool IntersectBoxSphere(vector center, float radius, vector mins, vector maxs, out float intersectDist = 0)
640 {
641 float dist_sq = -Math.Pow(radius, 2);
642
643 if (center[0] < mins[0])
644 dist_sq += Math.Pow(center[0] - mins[0], 2);
645 else if (center[0] > maxs[0])
646 dist_sq += Math.Pow(center[0] - maxs[0], 2);
647 if (center[1] < mins[1])
648 dist_sq += Math.Pow(center[1] - mins[1], 2);
649 else if (center[1] > maxs[1])
650 dist_sq += Math.Pow(center[1] - maxs[1], 2);
651 if (center[2] < mins[2])
652 dist_sq += Math.Pow(center[2] - mins[2], 2);
653 else if (center[2] > maxs[2])
654 dist_sq += Math.Pow(center[2] - maxs[2], 2);
655
656 if (dist_sq < 0)
657 intersectDist = -Math.Sqrt(-dist_sq);
658 else
659 intersectDist = Math.Sqrt(dist_sq);
660
661 if (dist_sq < 0)
662 return true;
663 else
664 return false;
665 }
666
667 //------------------------------------------------------------------------------------------------
669 static float FractionOf(float input, float fracOf)
670 {
671 float result = input / fracOf;
672
673 while (result >= 1)
674 result -= 1;
675 while (result <= -1)
676 result += 1;
677
678 return result;
679 }
680
681 //------------------------------------------------------------------------------------------------
683 // local usage, can be protected
684 static float ClampToGrid(float input, float grid)
685 {
686 float frac = FractionOf(input, grid);
687
688 if (frac >= 0.5) input += (1 - frac) * grid;
689 else if (frac > 0 && frac < 0.5) input -= frac * grid;
690 else if (frac <= -0.5) input -= (1 + frac) * grid;
691 else if (frac < 0 && frac > -0.5) input += -frac * grid;
692
693 return input;
694 }
695
696 //------------------------------------------------------------------------------------------------
698 // unused
699 static vector GetDirectionAngles(vector viewMat[4], vector posTo)
700 {
701 vector dir = posTo - viewMat[3];
702 dir.Normalize();
703 vector dirAng = dir.InvMultiply3(viewMat);
704 dirAng = dirAng.VectorToAngles();
705 dirAng = dirAng.MapAngles();
706
707 return dirAng;
708 }
709
710 //------------------------------------------------------------------------------------------------
712 [Obsolete("Use SCR_Math.fmod or Math.Repeat instead")]
713 static float fmod(float dividend, float divisor)
714 {
715 if (divisor == 0)
716 return 0;
717 return dividend - Math.Floor(dividend/divisor) * divisor;
718 }
719
720 //------------------------------------------------------------------------------------------------
722 // unused
723 static void WorldClampMatrixWithinBounds(vector mat[4], vector mins, vector maxs)
724 {
725 vector pos = mat[3];
726 for (int i = 0; i < 3; i++)
727 {
728 if (pos[i] > maxs[i])
729 pos[i] = maxs[i];
730 if (pos[i] < mins[i])
731 pos[i] = mins[i];
732 }
733 mat[3] = pos;
734 }
735
736 //------------------------------------------------------------------------------------------------
738 // unused
739 static int VectorToRGBA255(vector colorVec, float alpha)
740 {
741 float x,y,z;
742 int r,g,b,a;
743
744 x = colorVec[0];
745 y = colorVec[1];
746 z = colorVec[2];
747
748 a = (int)alpha << 24;
749 r = (int)x << 16;
750 g = (int)y << 8;
751 b = z;
752
753 return r | g | b | a;
754 }
755
756 //------------------------------------------------------------------------------------------------
758 // unused
759 static void WorldClampObjectAndMatrixWithinBounds(GenericEntity ent, vector mat[4], vector mins, vector maxs, vector gridSize)
760 {
761 bool snapToGrid = false;
762 if (gridSize != vector.Zero)
763 snapToGrid = true;
764
765 vector entmins, entmaxs;
766 ent.GetBounds(entmins, entmaxs);
767 vector point1 = entmins.Multiply3(mat);
768 vector point2 = entmaxs.Multiply3(mat);
769 entmins = point1;
770 entmaxs = point2;
771 for (int i = 0; i < 3; i++)
772 {
773 if (point1[i] < entmins[i])
774 entmins[i] = point1[i];
775 if (point2[i] < entmins[i])
776 entmins[i] = point2[i];
777 if (point1[i] > entmaxs[i])
778 entmaxs[i] = point1[i];
779 if (point2[i] > entmaxs[i])
780 entmaxs[i] = point2[i];
781 }
782
783 vector pos = mat[3];
784 for (int i = 0; i < 3; i++)
785 {
786 float posAxis = pos[i];
787 float min = entmins[i];
788 float max = entmaxs[i];
789 float grid = gridSize[i];
790
791 if (snapToGrid)
792 {
793 min = ClampToGrid(min, grid * 0.5);
794 max = ClampToGrid(max, grid * 0.5);
795 }
796 if (pos[i] > maxs[i] - max)
797 posAxis = maxs[i] - max;
798 if (pos[i] < mins[i] - min)
799 posAxis = mins[i] - min;
800
801 pos[i] = posAxis;
802 }
803 mat[3] = pos;
804 }
805
806 //------------------------------------------------------------------------------------------------
808 // unused
809 static void LocalClampObjectAndMatrixWithinBounds(vector localMat[4], GenericEntity ent, vector origMat[4], vector localMins, vector localMaxs, vector gridSize)
810 {
811 vector mat[4];
812 Math3D.MatrixInvMultiply4(localMat, origMat, mat);
813
814 bool snapToGrid = false;
815 if (gridSize != vector.Zero)
816 snapToGrid = true;
817
818 vector entmins, entmaxs;
819 ent.GetBounds(entmins, entmaxs);
820 vector point1 = entmins.Multiply3(mat);
821 vector point2 = entmaxs.Multiply3(mat);
822 entmins = point1;
823 entmaxs = point2;
824 for (int i = 0; i < 3; i++)
825 {
826 if (point1[i] < entmins[i])
827 entmins[i] = point1[i];
828 if (point2[i] < entmins[i])
829 entmins[i] = point2[i];
830 if (point1[i] > entmaxs[i])
831 entmaxs[i] = point1[i];
832 if (point2[i] > entmaxs[i])
833 entmaxs[i] = point2[i];
834 }
835
836 vector pos = mat[3];
837 for (int i = 0; i < 3; i++)
838 {
839 float posAxis = pos[i];
840 float min = entmins[i];
841 float max = entmaxs[i];
842 float grid = gridSize[i];
843
844 if (snapToGrid)
845 {
846 min = ClampToGrid(min, grid * 0.5);
847 max = ClampToGrid(max, grid * 0.5);
848 }
849 if (pos[i] > localMaxs[i] - max)
850 posAxis = localMaxs[i] - max;
851 if (pos[i] < localMins[i] - min)
852 posAxis = localMins[i] - min;
853
854 pos[i] = posAxis;
855 }
856 mat[3] = pos;
857
858 Math3D.MatrixMultiply4(localMat, mat, origMat);
859 }
860
861 //------------------------------------------------------------------------------------------------
863 // unused
864 static void WorldSnapMatrix(vector mat[4], vector gridSize)
865 {
866 // Snap position
867 if (gridSize != vector.Zero)
868 {
869 vector tempPos = mat[3];
870 for (int i = 0; i < 3; i++)
871 {
872 float grid = gridSize[i];
873 float pos = ClampToGrid(tempPos[i], grid);
874
875 tempPos[i] = pos;
876 }
877 mat[3] = tempPos;
878 }
879
880 // Create world oriented normals
881 vector norms[6];
882 norms[0] = "1 0 0";
883 norms[1] = "0 1 0";
884 norms[2] = "0 0 1";
885 norms[3] = "-1 0 0";
886 norms[4] = "0 -1 0";
887 norms[5] = "0 0 -1";
888
889 // Snap orientation
890 vector mat0 = mat[0];
891 vector mat1 = mat[1];
892 vector mat2 = mat[2];
893 vector bestVecs[3];
894 float bestVecsVal[3];
895 bestVecsVal[0] = -1;
896 bestVecsVal[1] = -1;
897 bestVecsVal[2] = -1;
898
899 for (int i = 0; i < 6; i++)
900 {
901 vector norm = norms[i];
902 float calc = mat0 * norm;
903 if (calc > bestVecsVal[0])
904 {
905 bestVecsVal[0] = calc;
906 bestVecs[0] = norms[i];
907 }
908
909 calc = mat1 * norm;
910 if (calc > bestVecsVal[1])
911 {
912 bestVecsVal[1] = calc;
913 bestVecs[1] = norms[i];
914 }
915
916 calc = mat2 * norm;
917 if (calc > bestVecsVal[2])
918 {
919 bestVecsVal[2] = calc;
920 bestVecs[2] = norms[i];
921 }
922 }
923
924 float bestAxisVal1 = -1;
925 int bestAxisNum1;
926 for (int i = 0; i < 3; i++)
927 {
928 if (bestVecsVal[i] > bestAxisVal1)
929 {
930 bestAxisVal1 = bestVecsVal[i];
931 bestAxisNum1 = i;
932 }
933 }
934 float bestAxisVal2 = -1;
935 int bestAxisNum2;
936 for (int i = 0; i < 3; i++)
937 {
938 if (i == bestAxisNum1)
939 continue;
940
941 if (bestVecsVal[i] > bestAxisVal2)
942 {
943 bestAxisVal2 = bestVecsVal[i];
944 bestAxisNum2 = i;
945 }
946 }
947
948 vector bestAxis1 = bestVecs[bestAxisNum1];
949 vector bestAxis2 = bestVecs[bestAxisNum2];
950 vector bestAxis3;
951 if (bestAxisNum1 == 2 && bestAxisNum2 == 0)
952 bestAxis3 = bestAxis1 * bestAxis2;
953 else if (bestAxisNum1 == 0 && bestAxisNum2 == 2)
954 bestAxis3 = bestAxis2 * bestAxis1;
955 else if (bestAxisNum2 < bestAxisNum1)
956 bestAxis3 = bestAxis2 * bestAxis1;
957 else
958 bestAxis3 = bestAxis1 * bestAxis2;
959
960 for (int i = 0; i < 3; i++)
961 {
962 if (i == bestAxisNum1 || i == bestAxisNum2)
963 continue;
964
965 mat[i] = bestAxis3;
966 break;
967 }
968 mat[bestAxisNum1] = bestAxis1;
969 mat[bestAxisNum2] = bestAxis2;
970 }
971
972 //------------------------------------------------------------------------------------------------
974 // unused
975 static void LocalSnapMatrix(vector localMat[4], vector origMat[4], vector gridSize)
976 {
977 vector mat[4];
978 Math3D.MatrixInvMultiply4(localMat, origMat, mat);
979
980 // Snap position
981 if (gridSize != vector.Zero)
982 {
983 vector tempPos = mat[3];
984 for (int i = 0; i < 3; i++)
985 {
986 float grid = gridSize[i];
987 float pos = ClampToGrid(tempPos[i], grid);
988
989 tempPos[i] = pos;
990 }
991 mat[3] = tempPos;
992 }
993
994 // Create world oriented normals
995 vector norms[6];
996 norms[0] = "1 0 0";
997 norms[1] = "0 1 0";
998 norms[2] = "0 0 1";
999 norms[3] = "-1 0 0";
1000 norms[4] = "0 -1 0";
1001 norms[5] = "0 0 -1";
1002
1003 // Snap orientation
1004 vector mat0 = mat[0];
1005 vector mat1 = mat[1];
1006 vector mat2 = mat[2];
1007 vector bestVecs[3];
1008 float bestVecsVal[3];
1009 bestVecsVal[0] = -1;
1010 bestVecsVal[1] = -1;
1011 bestVecsVal[2] = -1;
1012
1013 for (int i = 0; i < 6; i++)
1014 {
1015 vector norm = norms[i];
1016 float calc = mat0 * norm;
1017 if (calc > bestVecsVal[0])
1018 {
1019 bestVecsVal[0] = calc;
1020 bestVecs[0] = norms[i];
1021 }
1022
1023 calc = mat1 * norm;
1024 if (calc > bestVecsVal[1])
1025 {
1026 bestVecsVal[1] = calc;
1027 bestVecs[1] = norms[i];
1028 }
1029
1030 calc = mat2 * norm;
1031 if (calc > bestVecsVal[2])
1032 {
1033 bestVecsVal[2] = calc;
1034 bestVecs[2] = norms[i];
1035 }
1036 }
1037
1038 float bestAxisVal1 = -1;
1039 int bestAxisNum1;
1040 for (int i = 0; i < 3; i++)
1041 {
1042 if (bestVecsVal[i] > bestAxisVal1)
1043 {
1044 bestAxisVal1 = bestVecsVal[i];
1045 bestAxisNum1 = i;
1046 }
1047 }
1048 float bestAxisVal2 = -1;
1049 int bestAxisNum2;
1050 for (int i = 0; i < 3; i++)
1051 {
1052 if (i == bestAxisNum1)
1053 continue;
1054
1055 if (bestVecsVal[i] > bestAxisVal2)
1056 {
1057 bestAxisVal2 = bestVecsVal[i];
1058 bestAxisNum2 = i;
1059 }
1060 }
1061
1062 vector bestAxis1 = bestVecs[bestAxisNum1];
1063 vector bestAxis2 = bestVecs[bestAxisNum2];
1064 vector bestAxis3;
1065 if (bestAxisNum1 == 2 && bestAxisNum2 == 0)
1066 bestAxis3 = bestAxis1 * bestAxis2;
1067 else if (bestAxisNum1 == 0 && bestAxisNum2 == 2)
1068 bestAxis3 = bestAxis2 * bestAxis1;
1069 else if (bestAxisNum2 < bestAxisNum1)
1070 bestAxis3 = bestAxis2 * bestAxis1;
1071 else
1072 bestAxis3 = bestAxis1 * bestAxis2;
1073
1074 for (int i = 0; i < 3; i++)
1075 {
1076 if (i == bestAxisNum1 || i == bestAxisNum2)
1077 continue;
1078
1079 mat[i] = bestAxis3;
1080 break;
1081 }
1082 mat[bestAxisNum1] = bestAxis1;
1083 mat[bestAxisNum2] = bestAxis2;
1084
1085 Math3D.MatrixMultiply4(localMat, mat, origMat);
1086 }
1087
1088 //------------------------------------------------------------------------------------------------
1090 // can be protected
1091 static float GetMatAndBoundsSurfaceAreaInDir(IEntity ent, vector dir, vector mat[4], vector mins, vector maxs)
1092 {
1093 float min_x, min_y, min_z;
1094 float max_x, max_y, max_z;
1095 min_x = mins[0];
1096 min_y = mins[1];
1097 min_z = mins[2];
1098 max_x = maxs[0];
1099 max_y = maxs[1];
1100 max_z = maxs[2];
1101
1102 float surfArea_top = Math.AbsFloat(max_z - min_z) * Math.AbsFloat(max_x - min_x);
1103 float surfArea_right = Math.AbsFloat(max_z - min_z) * Math.AbsFloat(max_y - min_y);
1104 float surfArea_front = Math.AbsFloat(max_x - min_x) * Math.AbsFloat(max_y - min_y);
1105
1106 vector objRt = mat[0];
1107 vector objUp = mat[1];
1108 vector objFw = mat[2];
1109
1110 float result = Math.AbsFloat(dir * objFw * surfArea_front);
1111 result += Math.AbsFloat(dir * objRt * surfArea_right);
1112 result += Math.AbsFloat(dir * objUp * surfArea_top);
1113
1114 return result;
1115 }
1116
1117 //------------------------------------------------------------------------------------------------
1119 static float GetSurfaceAreaInDir(IEntity ent, vector dir)
1120 {
1121 vector matObj[4];
1122 ent.GetTransform(matObj);
1123
1124 vector mins, maxs;
1125 ent.GetBounds(mins, maxs); // Get the bounding box
1126
1127 return GetMatAndBoundsSurfaceAreaInDir(ent, dir, matObj, mins, maxs);
1128 }
1129
1130 //------------------------------------------------------------------------------------------------
1132 // unused
1133 static vector GetEntityCenterLocal(IEntity ent)
1134 {
1135 vector entMins, entMaxs;
1136 ent.GetBounds(entMins, entMaxs);
1137
1138 return (entMaxs + entMins) * 0.5;
1139 }
1140
1141 //------------------------------------------------------------------------------------------------
1143 // unused
1144 static bool GetStringContainsInvalidCharacters(string s)
1145 {
1146 int ascii_FwSlash = 47;
1147 int ascii_BkSlash = 92;
1148 int ascii_Quote = 34;
1149
1150 if (s == "") return true;
1151 else if (s.Contains("~")) return true;
1152 else if (s.Contains("#")) return true;
1153 else if (s.Contains("%")) return true;
1154 else if (s.Contains("\"")) return true;
1155 else if (s.Contains("&")) return true;
1156 else if (s.Contains("*")) return true;
1157 else if (s.Contains("{")) return true;
1158 else if (s.Contains("}")) return true;
1159 else if (s.Contains(ascii_BkSlash.AsciiToString())) return true;
1160 else if (s.Contains(":")) return true;
1161 else if (s.Contains("<")) return true;
1162 else if (s.Contains(">")) return true;
1163 else if (s.Contains("?")) return true;
1164 else if (s.Contains(ascii_FwSlash.AsciiToString())) return true;
1165 else if (s.Contains("|")) return true;
1166 else if (s.Contains(ascii_Quote.AsciiToString())) return true;
1167
1168 return false;
1169 }
1170
1171 //------------------------------------------------------------------------------------------------
1173 // unused
1174 static void DisplayEntityNameText(IEntity ent, int color, int camIndex)
1175 {
1176 vector pos = SCR_EntityHelper.GetEntityCenterWorld(ent);
1177
1178 vector textMat[4];
1179 ent.GetWorld().GetCamera(camIndex, textMat);
1180
1181 float distScale = vector.Distance(textMat[3], pos) * 0.07;
1182 distScale = Math.Clamp(distScale, 0.5, 10);
1183
1184 float textEndSize = (0.2 * distScale) / vector.Distance(textMat[3], ent.GetOrigin());
1185 if (textEndSize < 0.005)
1186 return;
1187
1188 textMat[3] = pos + textMat[1] * 0.7;
1189 CreateSimpleText(ent.GetName(), textMat, 0.2 * distScale, color, ShapeFlags.NOZBUFFER | ShapeFlags.ONCE, null);
1190 }
1191
1192 //------------------------------------------------------------------------------------------------
1194 protected static void SetHierarchyChildVelocity(notnull IEntity ent, vector newVelocity, bool recursive = true)
1195 {
1196 Physics entPhys = ent.GetPhysics();
1197 if (entPhys)
1198 {
1199 if (entPhys.IsDynamic())
1200 entPhys.SetVelocity(newVelocity);
1201 }
1202
1203 IEntity child = ent.GetChildren();
1204 while (child)
1205 {
1206 SetHierarchyChildVelocity(child, newVelocity, recursive);
1207 child = child.GetSibling();
1208 }
1209 }
1210
1211 //------------------------------------------------------------------------------------------------
1213 // unused
1214 static void SetHierarchyVelocity(notnull IEntity ent, vector newVelocity)
1215 {
1216 Physics entPhys = ent.GetPhysics();
1217 if (entPhys)
1218 {
1219 if (entPhys.IsDynamic())
1220 entPhys.SetVelocity(newVelocity);
1221 }
1222
1223 IEntity child = ent.GetChildren();
1224 while (child)
1225 {
1226 SetHierarchyChildVelocity(child, newVelocity, true);
1227 child = child.GetSibling();
1228 }
1229 }
1230
1231 //------------------------------------------------------------------------------------------------
1233 protected static void SetHierarchyChildAngularVelocity(notnull IEntity ent, vector newAngularVelocity, IEntity entFrom, bool recursive = true)
1234 {
1235 Physics entPhys = ent.GetPhysics();
1236 Physics entFromPhys = entFrom.GetPhysics();
1237 if (entPhys)
1238 {
1239 if (entPhys.IsDynamic())
1240 {
1241 entPhys.SetAngularVelocity(newAngularVelocity);
1242 if (entFrom && entFromPhys && entFromPhys.IsDynamic())
1243 {
1244 vector velAt = entFromPhys.GetVelocityAt(ent.GetOrigin());
1245 entPhys.SetVelocity(velAt);
1246 }
1247 }
1248
1249 }
1250
1251 IEntity child = ent.GetChildren();
1252 while (child)
1253 {
1254 SetHierarchyChildAngularVelocity(child, newAngularVelocity, entFrom, recursive);
1255 child = child.GetSibling();
1256 }
1257 }
1258
1259 //------------------------------------------------------------------------------------------------
1261 // unused
1262 static void SetHierarchyAngularVelocity(notnull IEntity ent, vector newAngularVelocity)
1263 {
1264 Physics entPhys = ent.GetPhysics();
1265 if (entPhys && entPhys.IsDynamic())
1266 entPhys.SetAngularVelocity(newAngularVelocity);
1267
1268 IEntity child = ent.GetChildren();
1269 while (child)
1270 {
1271 SetHierarchyChildAngularVelocity(child, newAngularVelocity, ent, true);
1272 child = child.GetSibling();
1273 }
1274 }
1275
1276 //------------------------------------------------------------------------------------------------
1278 protected static void SetHierarchyChildBodyActive(notnull IEntity ent, ActiveState activeState, bool recursive = true, bool resetVelocity = false)
1279 {
1280 Physics entPhys = ent.GetPhysics();
1281 if (entPhys)
1282 {
1283 if (entPhys.IsDynamic())
1284 {
1285 entPhys.SetActive(activeState);
1286 if (resetVelocity)
1287 {
1288 entPhys.SetVelocity( vector.Zero );
1289 entPhys.SetAngularVelocity( vector.Zero );
1290 }
1291
1292 }
1293 }
1294
1295 IEntity child = ent.GetChildren();
1296 while (child)
1297 {
1298 SetHierarchyChildBodyActive(child, activeState, resetVelocity);
1299 child = child.GetSibling();
1300 }
1301 }
1302
1303 //------------------------------------------------------------------------------------------------
1305 // unused
1306 static void SetHierarchyBodyActive(notnull IEntity ent, ActiveState activeState, bool resetVelocity = false)
1307 {
1308 Physics entPhys = ent.GetPhysics();
1309 if (entPhys)
1310 {
1311 if (entPhys.IsDynamic())
1312 {
1313
1314 entPhys.SetActive(activeState);
1315 if (resetVelocity)
1316 {
1317 entPhys.SetVelocity( vector.Zero );
1318 entPhys.SetAngularVelocity( vector.Zero );
1319 }
1320
1321 }
1322 }
1323
1324 IEntity child = ent.GetChildren();
1325 while (child)
1326 {
1327 SetHierarchyChildBodyActive(child, activeState, true);
1328 child = child.GetSibling();
1329 }
1330 }
1331
1332 //------------------------------------------------------------------------------------------------
1334 // unused
1335 static bool IsAnyInherited(notnull IEntity entity, array<typename> typenames)
1336 {
1337 bool ret;
1338 for (int i = 0; i < typenames.Count(); i++)
1339 {
1340 ret = ret || entity.IsInherited( typenames.Get(i) );
1341 }
1342
1343 return ret;
1344 }
1345
1346 //------------------------------------------------------------------------------------------------
1347 static bool ApplyDamage(IEntity entity, IEntity weapon, float dmg, EDamageType dmgType, string hitZone, SurfaceProperties surface, int nodeIdx)
1348 {
1349 vector hitPosDirNorm[3];
1350
1351 /*
1353 Tree tree = Tree.Cast(entity);
1354 if (tree)
1355 {
1356 tree.OnDamage(
1357 dmg,
1358 dmgType,
1359 entity,
1360 hitPosDirNorm,
1361 weapon,
1362 null,
1363 hitZone,
1364 0, 0);
1365
1366 return true;
1367 }
1368 else
1369 {
1370 Building building = Building.Cast(entity);
1371 if (building)
1372 {
1373 building.OnDamage(
1374 dmg,
1375 dmgType,
1376 entity,
1377 hitPosDirNorm,
1378 weapon,
1379 null,
1380 hitZone,
1381 0, 0);
1382
1383 return true;
1384 }
1385 }
1386 */
1388 GenericEntity genEnt = GenericEntity.Cast(entity);
1389 if (!genEnt)
1390 return false;
1391
1394 if (dmc)
1395 {
1397 bool useDefaultHZ = false;
1398 if (hitZone.Empty)
1399 useDefaultHZ = true;
1400
1401 if (useDefaultHZ && dmc.GetDefaultHitZone())
1402 hitZone = dmc.GetDefaultHitZone().GetName();
1403
1404
1405
1406 return true;
1407 }
1408
1409 return false;
1410 }
1411
1412 //------------------------------------------------------------------------------------------------
1416 // unused
1417 static ActionsManagerComponent FindActionsManagerComponent( IEntity entity, bool activeOnly = true)
1418 {
1419 auto genericEntity = GenericEntity.Cast(entity);
1420 if (!genericEntity)
1421 return null;
1422
1423 auto actionsManager = ActionsManagerComponent.Cast(genericEntity.FindComponent(ActionsManagerComponent));
1424 if (actionsManager != null)
1425 {
1426 if (activeOnly && !actionsManager.IsActive())
1427 return null;
1428
1429 return actionsManager;
1430 }
1431
1432 return null;
1433 }
1434
1435 //------------------------------------------------------------------------------------------------
1439 // unused
1440 static SCR_EditorActionsManagerComponent FindEditorActionsManagerComponent( IEntity entity)
1441 {
1442 auto genericEntity = GenericEntity.Cast(entity);
1443 if (!genericEntity)
1444 return null;
1445
1446 auto actionsManager = SCR_EditorActionsManagerComponent.Cast(genericEntity.FindComponent(SCR_EditorActionsManagerComponent));
1447 if (actionsManager != null)
1448 return actionsManager;
1449
1450 return null;
1451 }
1452
1453 //------------------------------------------------------------------------------------------------
1455 static bool GetModelAndRemapFromResource(ResourceName resourcePath, out ResourceName modelPath, out string remap)
1456 {
1457 modelPath = ResourceName.Empty;
1458 remap = string.Empty;
1459
1460 if (resourcePath == ResourceName.Empty)
1461 return false;
1462
1463 Resource resource = Resource.Load(resourcePath);
1464 if (!resource)
1465 return false;
1466
1467 BaseResourceObject prefabBase = resource.GetResource();
1468 if (!prefabBase)
1469 return false;
1470
1471 // Is a model not a prefab
1472 if (prefabBase.ToVObject())
1473 {
1474 modelPath = resourcePath;
1475
1476 return true;
1477 }
1478
1479 // Prefab
1480 BaseContainer prefabSrc = prefabBase.ToBaseContainer();
1481 if (!prefabSrc)
1482 return false;
1483
1484 BaseContainerList components = prefabSrc.GetObjectArray("components");
1485 if (!components)
1486 return false;
1487
1488 BaseContainer meshComponent = null;
1489 for (int c = components.Count() - 1; c >= 0; c--)
1490 {
1491 meshComponent = components.Get(c);
1492 if (meshComponent.GetClassName() == "MeshObject")
1493 break;
1494
1495 meshComponent = null;
1496 }
1497
1498 if (!meshComponent)
1499 return false;
1500
1501 meshComponent.Get("Object", modelPath);
1502 BaseContainerList materialsRemap = meshComponent.GetObjectArray("Materials");
1503 if (materialsRemap)
1504 {
1505 ResourceName matSrc = ResourceName.Empty;
1506 ResourceName matTgt = ResourceName.Empty;
1507 for (int m = materialsRemap.Count() - 1; m >= 0; m--)
1508 {
1509 BaseContainer material = materialsRemap.Get(m);
1510
1511 material.Get("SourceMaterial", matSrc);
1512 material.Get("AssignedMaterial", matTgt);
1513 remap += "$remap '" + matSrc + "' '" + matTgt + "';";
1514 }
1515 }
1516
1517 return true;
1518 }
1519
1520 //------------------------------------------------------------------------------------------------
1522 static bool GetResourceContainsComponent(ResourceName resourcePath, string componentClassName, out bool isPrefab)
1523 {
1524 isPrefab = false;
1525
1526 if (resourcePath == ResourceName.Empty)
1527 return false;
1528
1529 Resource resource = Resource.Load(resourcePath);
1530 if (!resource)
1531 return false;
1532
1533 BaseResourceObject prefabBase = resource.GetResource();
1534 if (!prefabBase)
1535 return false;
1536
1537 // Is not a prefab
1538 if (!prefabBase.ToEntitySource())
1539 return false;
1540
1541 // Prefab
1542 BaseContainer prefabSrc = prefabBase.ToBaseContainer();
1543 if (!prefabSrc)
1544 return false;
1545
1546 isPrefab = true;
1547
1548 BaseContainerList components = prefabSrc.GetObjectArray("components");
1549 if (!components)
1550 return false;
1551
1552 BaseContainer component = null;
1553 for (int c = components.Count() - 1; c >= 0; c--)
1554 {
1555 component = components.Get(c);
1556 if (component.GetClassName() == componentClassName)
1557 return true;
1558 }
1559
1560 return false;
1561 }
1562
1563 //------------------------------------------------------------------------------------------------
1566 static bool IsEditMode()
1567 {
1568 ArmaReforgerScripted game = GetGame();
1569 return !game || !game.InPlayMode();
1570 }
1571
1572 //------------------------------------------------------------------------------------------------
1576 static bool IsEditMode(notnull IEntity entity)
1577 {
1578 BaseWorld world = entity.GetWorld();
1579 return world && world.IsEditMode();
1580 }
1581
1582 //------------------------------------------------------------------------------------------------
1587 {
1588 vector camMat[4];
1589 referenceEntity.GetWorld().GetCurrentCamera(camMat);
1590 vector dir = camMat[2];
1591
1592 #ifdef WORKBENCH
1593 WorldEditorAPI worldEdAPI = referenceEntity._WB_GetEditorAPI();
1594 WorkspaceWidget workspace = GetGame().GetWorkspace();
1595 if (worldEdAPI && workspace)
1596 {
1597 int imouseX = worldEdAPI.GetMousePosX(true);
1598 int imouseY = worldEdAPI.GetMousePosY(true);
1599 int realScreenX = worldEdAPI.GetScreenWidth();
1600 int realScreenY = worldEdAPI.GetScreenHeight();
1601 if (imouseX > 0 && imouseX < realScreenX && imouseY > 0 && imouseY < realScreenY)
1602 {
1603 float xMult = realScreenX / realScreenY;
1604 float mouseXPct = (imouseX / realScreenX - 0.5) * xMult;
1605 float mouseYPct = imouseY / realScreenY;
1606 float width, height;
1607 workspace.GetScreenSize(width, height);
1608 float mouseX = mouseXPct * width + width * 0.5;
1609 float mouseY = mouseYPct * height;
1610 workspace.ProjScreenToWorldNative(mouseX, mouseY, dir, referenceEntity.GetWorld(), referenceEntity.GetWorld().GetCurrentCameraId());
1611 }
1612 }
1613 #endif
1614
1615 return dir;
1616 }
1617
1618 //------------------------------------------------------------------------------------------------
1625 static bool TeleportLocalPlayer(vector worldPosition, SCR_EPlayerTeleportedReason teleportReason = SCR_EPlayerTeleportedReason.DEFAULT)
1626 {
1627 return TeleportPlayer(SCR_PlayerController.GetLocalPlayerId(), worldPosition, teleportReason);
1628 }
1629
1630 //------------------------------------------------------------------------------------------------
1638 static bool TeleportPlayer(int playerId, vector worldPosition, SCR_EPlayerTeleportedReason teleportReason = SCR_EPlayerTeleportedReason.DEFAULT)
1639 {
1640 if (!IsPositionWithinTerrainBounds(worldPosition))
1641 return false;
1642
1643 IEntity player = GetGame().GetPlayerManager().GetPlayerControlledEntity(playerId);
1644 if (!player)
1645 return false;
1646
1647 //~ Player teleport feedback
1648 PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(playerId);
1649 if (playerController)
1650 {
1651 SCR_PlayerTeleportedFeedbackComponent teleportFeedback = SCR_PlayerTeleportedFeedbackComponent.Cast(playerController.FindComponent(SCR_PlayerTeleportedFeedbackComponent));
1652 if (teleportFeedback)
1653 teleportFeedback.PlayerTeleported(player, false, teleportReason);
1654 }
1655
1656 vector startingPosition = player.GetOrigin();
1657
1658 //--- When in a vehcile, teleport the vehicle instead
1660 if (compartmentAccess)
1661 {
1662 IEntity vehicle = compartmentAccess.GetVehicle();
1663 if (vehicle)
1664 player = vehicle;
1665 }
1666
1667 //--- Apply transformation
1668 vector transform[4];
1669 player.GetWorldTransform(transform);
1670 transform[3] = worldPosition;
1671
1672 //~ Align to terrain if not a character
1673 if (!ChimeraCharacter.Cast(player))
1675
1676 BaseGameEntity baseGameEntity = BaseGameEntity.Cast(player);
1677 if (baseGameEntity)
1678 baseGameEntity.Teleport(transform);
1679 else
1680 player.SetWorldTransform(transform);
1681
1682 Physics phys = player.GetPhysics();
1683 if (phys)
1684 {
1685 phys.SetVelocity(vector.Zero);
1686 phys.SetAngularVelocity(vector.Zero);
1687 }
1688
1689#ifdef ENABLE_DIAG
1690 #ifndef WORKBENCH
1691 //~ Send notification to all players if player teleported and Diag is enabled
1692 if (teleportReason == SCR_EPlayerTeleportedReason.DEFAULT && Replication.IsRunning())
1693 SCR_NotificationsComponent.SendToEveryone(ENotification.PLAYER_TELEPORTED_SELF, SCR_PlayerController.GetLocalPlayerId(), vector.Distance(startingPosition, player.GetOrigin()) * 100);
1694 #endif
1695#endif
1696
1697 return true;
1698
1699 /*
1700 ArmaReforgerScripted game = GetGame();
1701 if (!world && game)
1702 {
1703 world = game.GetWorld();
1704 }
1705 if (!world) return false;
1706
1707 if (!playerEntity) return false;
1708
1709 ChimeraCharacter character = ChimeraCharacter.Cast(playerEntity);
1710 if (character)
1711 {
1712 CompartmentAccessComponent compartmentAccess = character.GetCompartmentAccessComponent();
1713 if (compartmentAccess && compartmentAccess.IsInCompartment())
1714 {
1715 BaseCompartmentSlot compartmentSlot = compartmentAccess.GetCompartment();
1716 if (compartmentSlot && compartmentSlot.GetOwner())
1717 {
1718 playerEntity = compartmentSlot.GetOwner();
1719 }
1720 }
1721 }
1722
1723 BaseGameEntity baseGameEntity = BaseGameEntity.Cast(playerEntity);
1724 if (baseGameEntity)
1725 {
1726 vector mat[4];
1727 baseGameEntity.GetWorldTransform(mat);
1728 mat[3] = worldPosition;
1729 baseGameEntity.Teleport(mat);
1730 }
1731 else
1732 playerEntity.SetOrigin(worldPosition);
1733 return true;
1734 */
1735 }
1736
1737 //------------------------------------------------------------------------------------------------
1747 static void DrawMatrix(vector matrix[4], float scale = 1, ShapeFlags flags = ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, int colorX = Color.RED, int colorY = Color.GREEN, int colorZ = Color.BLUE)
1748 {
1749 vector line[2] = {matrix[3], matrix[3] + matrix[0] * scale};
1750 Shape.CreateLines(colorX, flags, line, 2);
1751
1752 line = {matrix[3], matrix[3] + matrix[1] * scale};
1753 Shape.CreateLines(colorY, flags, line, 2);
1754
1755 line = {matrix[3], matrix[3] + matrix[2] * scale};
1756 Shape.CreateLines(colorZ, flags, line, 2);
1757 }
1758
1759 //------------------------------------------------------------------------------------------------
1768 static void DrawTrace(TraceParam trace, float traceCoef = -1, ShapeFlags flags = ShapeFlags.ONCE | ShapeFlags.NOZBUFFER | ShapeFlags.NOOUTLINE, int colorEnd = Color.BLACK, int colorIntersect = Color.PINK)
1769 {
1770 vector lines[2];
1771 lines[0] = trace.Start;
1772
1773 if (traceCoef != -1)
1774 {
1775 lines[0] = vector.Lerp(trace.Start, trace.End, traceCoef);
1776 lines[1] = trace.Start;
1777 Shape.CreateLines(colorIntersect, flags, lines, 2);
1778 Shape.CreateSphere(colorIntersect, flags, lines[0], 0.05);
1779 }
1780
1781 lines[1] = trace.End;
1782 Shape.CreateLines(colorEnd, flags, lines, 2);
1783 Shape.CreateSphere(colorEnd, flags, trace.Start, 0.05);
1784 }
1785
1786 //------------------------------------------------------------------------------------------------
1793 static void SetMaterial(IEntity entity, ResourceName material, bool recursively = true)
1794 {
1795 //--- Remap textures of the current mesh
1796 VObject mesh = entity.GetVObject();
1797 if (mesh)
1798 {
1799 string remap;
1800 string materials[256];
1801 int numMats = mesh.GetMaterials(materials);
1802 for (int i = 0; i < numMats; i++)
1803 {
1804 remap += string.Format("$remap '%1' '%2';", materials[i], material);
1805 }
1806 entity.SetObject(mesh, remap);
1807 }
1808
1809 //--- Iterate through children
1810 if (recursively)
1811 {
1812 IEntity child = entity.GetChildren();
1813 while (child)
1814 {
1815 SetMaterial(child, material);
1816 child = child.GetSibling();
1817 }
1818 }
1819 }
1820
1821 //------------------------------------------------------------------------------------------------
1829 static bool IsChangedMouseAndKeyboard(EInputDeviceType oldDevice, EInputDeviceType newDevice)
1830 {
1831 return (oldDevice == EInputDeviceType.KEYBOARD && newDevice == EInputDeviceType.MOUSE) || (oldDevice == EInputDeviceType.MOUSE && newDevice == EInputDeviceType.KEYBOARD);
1832 }
1833
1834 //------------------------------------------------------------------------------------------------
1842 {
1843 if (!worldPath)
1844 worldPath = GetResourceName(GetGame().GetWorldFile());
1845
1846 Resource worldResource = BaseContainerTools.LoadContainer(worldPath);
1847 if (!worldResource || !worldResource.IsValid())
1848 return ResourceName.Empty;
1849
1850 BaseContainer container = worldResource.GetResource().ToBaseContainer();
1851 ResourceName parent;
1852 container.Get("Parent", parent);
1853 if (parent)
1854 return GetRootWorld(parent);
1855 else
1856 return worldPath;
1857 }
1858
1859 //------------------------------------------------------------------------------------------------
1867 {
1868 Resource meta = BaseContainerTools.LoadContainer(path + ".meta");
1869 if (!meta || !meta.IsValid())
1870 return ResourceName.Empty;
1871
1873 meta.GetResource().ToBaseContainer().Get("Name", resourceName);
1874 return resourceName;
1875 }
1876
1877 //------------------------------------------------------------------------------------------------
1884 static int GetFrequencies(SCR_GadgetManagerComponent gadgetManager, out notnull set<int> outFrequencies)
1885 {
1886 if (!gadgetManager)
1887 return 0;
1888
1889 BaseRadioComponent radioComponent;
1890 array<SCR_GadgetComponent> gadgets = gadgetManager.GetGadgetsByType(EGadgetType.RADIO);
1891 gadgets.InsertAll(gadgetManager.GetGadgetsByType(EGadgetType.RADIO_BACKPACK));
1892 foreach (SCR_GadgetComponent gadget : gadgets)
1893 {
1894 if (!gadget)
1895 continue;
1896
1897 radioComponent = BaseRadioComponent.Cast(gadget.GetOwner().FindComponent(BaseRadioComponent));
1898
1899 if (!radioComponent || !radioComponent.IsPowered() || radioComponent.TransceiversCount() == 0)
1900 continue;
1901
1902 for (int i = radioComponent.TransceiversCount() - 1; i >= 0; --i)
1903 {
1904 outFrequencies.Insert(radioComponent.GetTransceiver(i).GetFrequency());
1905 }
1906 }
1907 return outFrequencies.Count();
1908 }
1909
1910 //------------------------------------------------------------------------------------------------
1916 static bool IsAdminRole(EPlayerRole role)
1917 {
1918 return SCR_Enum.HasPartialFlag(role, EPlayerRole.ADMINISTRATOR | EPlayerRole.SESSION_ADMINISTRATOR);
1919 }
1920
1921 //------------------------------------------------------------------------------------------------
1927 static bool IsAdmin(int playerID)
1928 {
1929 return GetGame().GetPlayerManager().HasPlayerRole(playerID, EPlayerRole.ADMINISTRATOR)
1930 || GetGame().GetPlayerManager().HasPlayerRole(playerID, EPlayerRole.SESSION_ADMINISTRATOR);
1931 }
1932
1933 //------------------------------------------------------------------------------------------------
1938 static bool IsAdmin()
1939 {
1940 int playerID = GetGame().GetPlayerController().GetPlayerId();
1941 return GetGame().GetPlayerManager().HasPlayerRole(playerID, EPlayerRole.ADMINISTRATOR)
1942 || GetGame().GetPlayerManager().HasPlayerRole(playerID, EPlayerRole.SESSION_ADMINISTRATOR);
1943 }
1944
1945 //------------------------------------------------------------------------------------------------
1953 static ResourceName GetPrefabAttributeResource(notnull IEntity entity, string containerType, string attributeName)
1954 {
1955 EntityPrefabData prefabData = entity.GetPrefabData();
1956 if (!prefabData)
1957 return ResourceName.Empty;
1958
1959 BaseContainer prefabSource = prefabData.GetPrefab();
1960 if (!prefabSource)
1961 return ResourceName.Empty;
1962
1963 IEntitySource entitySource = prefabSource.ToEntitySource();
1964 if (!entitySource)
1965 return ResourceName.Empty;
1966
1967 BaseContainer container = SCR_BaseContainerTools.FindComponentSource(entitySource, containerType);
1968 if (!container)
1969 return ResourceName.Empty;
1970
1972 container.Get(attributeName, resourceName);
1973
1974 return resourceName;
1975 }
1976
1977 //------------------------------------------------------------------------------------------------
1982 {
1983 float x = pos[0];
1984 float y = pos[1];
1985 float z = pos[2];
1986
1988 vector mins, maxs;
1989 game.GetWorldEntity().GetTerrain(0, 0).GetTerrainBoundBox(mins, maxs);
1990 if (x < mins[0] || x > maxs[0])
1991 return false;
1992
1993 if (z < mins[2] || z > maxs[2])
1994 return false;
1995
1996 float surfaceY = game.GetWorld().GetSurfaceY(x, z);
1997 return y > surfaceY || float.AlmostEqual(y, surfaceY, 0.01); // script has lower precision, thus values rounded from game code might be slightly different
1998 }
1999}
SCR_EAIThreatSectorFlags flags
string path
vector scale
void ParamEnum(string key, string value, string desc="")
Definition attributes.c:25
ref DSGameConfig game
Definition DSConfig.c:81
void CreateSimpleText(string text, vector mat[4], float size, int color, ShapeFlags flags, array< ref Shape > output=null, float scaleWidth=1, bool doBackground=false, int backgroundColor=0x80000000)
ENotification
EPlayerRole
Definition EPlayerRole.c:8
ArmaReforgerScripted GetGame()
Definition game.c:1398
PlatformKind
Definition PlatformKind.c:8
ResourceName resourceName
Definition SCR_AIGroup.c:66
EDamageType type
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
SCR_HelicopterControllerComponentClass gameplaySettings
Definition Color.c:13
proto external WorldEditorAPI _WB_GetEditorAPI()
This returns world editor API, which is safe to use from editor events bellow.
proto external Managed FindComponent(typename typeName)
proto external vector GetOrigin()
proto external Physics GetPhysics()
proto external int AddChild(notnull IEntity child, TNodeId pivot, EAddChildFlags flags=EAddChildFlags.AUTO_TRANSFORM)
Add Entity to hierarchy. Pivot is pivot index, or -1 for center of parent.
proto external void GetBounds(out vector mins, out vector maxs)
proto external IEntity GetChildren()
proto external void GetWorldTransform(out vector mat[])
See IEntity::GetTransform.
proto external Animation GetAnimation()
proto external BaseWorld GetWorld()
proto external bool SetTransform(vector mat[4])
proto external void GetWorldBounds(out vector mins, out vector maxs)
proto external bool SetWorldTransform(vector mat[4])
See IEntity::SetTransform. Returns false, if there is no change in transformation.
proto external void GetTransform(out vector mat[])
proto external IEntity GetParent()
proto external string GetName()
proto external IEntity GetSibling()
proto external VObject GetVObject()
Returns visual object set to this Entity. No reference is added.
Definition Math.c:13
Main replication API.
Definition Replication.c:14
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
array< SCR_GadgetComponent > GetGadgetsByType(EGadgetType type)
static ResourceName GetPrefabAttributeResource(notnull IEntity entity, string containerType, string attributeName)
Definition Functions.c:1953
static void SetHierarchyVelocity(notnull IEntity ent, vector newVelocity)
Set linear velocity for whole hierarchy.
Definition Functions.c:1214
static void SetMaterial(IEntity entity, ResourceName material, bool recursively=true)
Definition Functions.c:1793
static ResourceName GetResourceName(string path)
Definition Functions.c:1866
static bool GetResourceContainsComponent(ResourceName resourcePath, string componentClassName, out bool isPrefab)
Read the input resource and returns whether it contains a component on input name,...
Definition Functions.c:1522
static bool IsPositionWithinTerrainBounds(vector pos)
Definition Functions.c:1981
static bool IsAdmin()
Definition Functions.c:1938
static bool GetModelAndRemapFromResource(ResourceName resourcePath, out ResourceName modelPath, out string remap)
Read the input resource and returns whether a model was successfully found, filling the output model ...
Definition Functions.c:1455
static SCR_EditorActionsManagerComponent FindEditorActionsManagerComponent(IEntity entity)
Definition Functions.c:1440
static void DrawMatrix(vector matrix[4], float scale=1, ShapeFlags flags=ShapeFlags.ONCE|ShapeFlags.NOZBUFFER, int colorX=Color.RED, int colorY=Color.GREEN, int colorZ=Color.BLUE)
Definition Functions.c:1747
static bool TeleportLocalPlayer(vector worldPosition, SCR_EPlayerTeleportedReason teleportReason=SCR_EPlayerTeleportedReason.DEFAULT)
Definition Functions.c:1625
static bool IsEditMode()
Definition Functions.c:1566
static bool IsEditMode(notnull IEntity entity)
Definition Functions.c:1576
static void SetHierarchyChildVelocity(notnull IEntity ent, vector newVelocity, bool recursive=true)
Called from SetHierarchyVelocity.
Definition Functions.c:1194
static bool IsAnyInherited(notnull IEntity entity, array< typename > typenames)
Returns true if the given entity is inherited from list of typesnames given as argument.
Definition Functions.c:1335
static bool IsChangedMouseAndKeyboard(EInputDeviceType oldDevice, EInputDeviceType newDevice)
Definition Functions.c:1829
static void SetHierarchyAngularVelocity(notnull IEntity ent, vector newAngularVelocity)
Set angular velocity for whole hierarchy.
Definition Functions.c:1262
static int GetFrequencies(SCR_GadgetManagerComponent gadgetManager, out notnull set< int > outFrequencies)
Definition Functions.c:1884
static ActionsManagerComponent FindActionsManagerComponent(IEntity entity, bool activeOnly=true)
Definition Functions.c:1417
static bool IsAdmin(int playerID)
Definition Functions.c:1927
static vector ProjWorldEditorMouseScreenToWorld(GenericEntity referenceEntity)
Definition Functions.c:1586
static void SetHierarchyBodyActive(notnull IEntity ent, ActiveState activeState, bool resetVelocity=false)
Sets physics active state for whole hierarchy.
Definition Functions.c:1306
static bool IsAdminRole(EPlayerRole role)
Definition Functions.c:1916
static void SetHierarchyChildAngularVelocity(notnull IEntity ent, vector newAngularVelocity, IEntity entFrom, bool recursive=true)
Called from SetHierarchyAngularVelocity.
Definition Functions.c:1233
static ResourceName GetRootWorld(ResourceName worldPath=ResourceName.Empty)
Definition Functions.c:1841
static void DrawTrace(TraceParam trace, float traceCoef=-1, ShapeFlags flags=ShapeFlags.ONCE|ShapeFlags.NOZBUFFER|ShapeFlags.NOOUTLINE, int colorEnd=Color.BLACK, int colorIntersect=Color.PINK)
Definition Functions.c:1768
static void SetHierarchyChildBodyActive(notnull IEntity ent, ActiveState activeState, bool recursive=true, bool resetVelocity=false)
Called from SetHierarchyBodyActive.
Definition Functions.c:1278
static bool ApplyDamage(IEntity entity, IEntity weapon, float dmg, EDamageType dmgType, string hitZone, SurfaceProperties surface, int nodeIdx)
Definition Functions.c:1347
static bool TeleportPlayer(int playerId, vector worldPosition, SCR_EPlayerTeleportedReason teleportReason=SCR_EPlayerTeleportedReason.DEFAULT)
Definition Functions.c:1638
static int GetLocalPlayerId()
Returns either a valid ID of local player or 0.
static bool OrientToTerrain(out vector transform[4], BaseWorld world=null, bool noUnderwater=false, TraceParam trace=null)
Instance of created debug visualizer.
Definition Shape.c:14
Definition Tree.c:11
Visual object.
Definition VObject.c:14
Definition int.c:13
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
ShapeFlags
Definition ShapeFlags.c:13
EDamageType
Definition EDamageType.c:13
ActiveState
Definition ActiveState.c:16
@ MAX
proto native vector Vector(float x, float y, float z)