Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Functions.c
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------------------
5 //------------------------------------------------------------------------------------------------
6 class SCR_Global
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");
24  if (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 = GetGame().GetBackendApi().GetCredentialsItem(EBackendCredentials.EBCRED_PLATFORMUID);
65  return name;
66  }
67 
68  BaseContainer gameplaySettings = GetGame().GetGameUserSettings().GetModule("SCR_GameplaySettings");
69  if (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 
1393  DamageManagerComponent dmc = DamageManagerComponent.Cast(genEnt.FindComponent(DamageManagerComponent));
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  //------------------------------------------------------------------------------------------------
1586  static vector ProjWorldEditorMouseScreenToWorld(GenericEntity referenceEntity)
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  IEntity player = GetGame().GetPlayerManager().GetPlayerControlledEntity(playerId);
1641  if (!player)
1642  return false;
1643 
1644  //~ Player teleport feedback
1645  PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(playerId);
1646  if (playerController)
1647  {
1648  SCR_PlayerTeleportedFeedbackComponent teleportFeedback = SCR_PlayerTeleportedFeedbackComponent.Cast(playerController.FindComponent(SCR_PlayerTeleportedFeedbackComponent));
1649  if (teleportFeedback)
1650  teleportFeedback.PlayerTeleported(player, false, teleportReason);
1651  }
1652 
1653  vector startingPosition = player.GetOrigin();
1654 
1655  //--- When in a vehcile, teleport the vehicle instead
1657  if (compartmentAccess)
1658  {
1659  IEntity vehicle = compartmentAccess.GetVehicle();
1660  if (vehicle)
1661  player = vehicle;
1662  }
1663 
1664  //--- Apply transformation
1665  vector transform[4];
1666  player.GetWorldTransform(transform);
1667  transform[3] = worldPosition;
1668 
1669  //~ Align to terrain if not a character
1670  if (!ChimeraCharacter.Cast(player))
1671  SCR_TerrainHelper.OrientToTerrain(transform);
1672 
1673  BaseGameEntity baseGameEntity = BaseGameEntity.Cast(player);
1674  if (baseGameEntity)
1675  baseGameEntity.Teleport(transform);
1676  else
1677  player.SetWorldTransform(transform);
1678 
1679  Physics phys = player.GetPhysics();
1680  if (phys)
1681  {
1682  phys.SetVelocity(vector.Zero);
1683  phys.SetAngularVelocity(vector.Zero);
1684  }
1685 
1686 #ifdef ENABLE_DIAG
1687  #ifndef WORKBENCH
1688  //~ Send notification to all players if player teleported and Diag is enabled
1689  if (teleportReason == SCR_EPlayerTeleportedReason.DEFAULT && Replication.IsRunning())
1690  SCR_NotificationsComponent.SendToEveryone(ENotification.PLAYER_TELEPORTED_SELF, SCR_PlayerController.GetLocalPlayerId(), vector.Distance(startingPosition, player.GetOrigin()) * 100);
1691  #endif
1692 #endif
1693 
1694  return true;
1695 
1696  /*
1697  ArmaReforgerScripted game = GetGame();
1698  if (!world && game)
1699  {
1700  world = game.GetWorld();
1701  }
1702  if (!world) return false;
1703 
1704  if (!playerEntity) return false;
1705 
1706  ChimeraCharacter character = ChimeraCharacter.Cast(playerEntity);
1707  if (character)
1708  {
1709  CompartmentAccessComponent compartmentAccess = character.GetCompartmentAccessComponent();
1710  if (compartmentAccess && compartmentAccess.IsInCompartment())
1711  {
1712  BaseCompartmentSlot compartmentSlot = compartmentAccess.GetCompartment();
1713  if (compartmentSlot && compartmentSlot.GetOwner())
1714  {
1715  playerEntity = compartmentSlot.GetOwner();
1716  }
1717  }
1718  }
1719 
1720  BaseGameEntity baseGameEntity = BaseGameEntity.Cast(playerEntity);
1721  if (baseGameEntity)
1722  {
1723  vector mat[4];
1724  baseGameEntity.GetWorldTransform(mat);
1725  mat[3] = worldPosition;
1726  baseGameEntity.Teleport(mat);
1727  }
1728  else
1729  playerEntity.SetOrigin(worldPosition);
1730  return true;
1731  */
1732  }
1733 
1734  //------------------------------------------------------------------------------------------------
1744  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)
1745  {
1746  vector line[2] = {matrix[3], matrix[3] + matrix[0] * scale};
1747  Shape.CreateLines(colorX, flags, line, 2);
1748 
1749  line = {matrix[3], matrix[3] + matrix[1] * scale};
1750  Shape.CreateLines(colorY, flags, line, 2);
1751 
1752  line = {matrix[3], matrix[3] + matrix[2] * scale};
1753  Shape.CreateLines(colorZ, flags, line, 2);
1754  }
1755 
1756  //------------------------------------------------------------------------------------------------
1765  static void DrawTrace(TraceParam trace, float traceCoef = -1, ShapeFlags flags = ShapeFlags.ONCE | ShapeFlags.NOZBUFFER | ShapeFlags.NOOUTLINE, int colorEnd = Color.BLACK, int colorIntersect = Color.PINK)
1766  {
1767  vector lines[2];
1768  lines[0] = trace.Start;
1769 
1770  if (traceCoef != -1)
1771  {
1772  lines[0] = vector.Lerp(trace.Start, trace.End, traceCoef);
1773  lines[1] = trace.Start;
1774  Shape.CreateLines(colorIntersect, flags, lines, 2);
1775  Shape.CreateSphere(colorIntersect, flags, lines[0], 0.05);
1776  }
1777 
1778  lines[1] = trace.End;
1779  Shape.CreateLines(colorEnd, flags, lines, 2);
1780  Shape.CreateSphere(colorEnd, flags, trace.Start, 0.05);
1781  }
1782 
1783  //------------------------------------------------------------------------------------------------
1790  static void SetMaterial(IEntity entity, ResourceName material, bool recursively = true)
1791  {
1792  //--- Remap textures of the current mesh
1793  VObject mesh = entity.GetVObject();
1794  if (mesh)
1795  {
1796  string remap;
1797  string materials[256];
1798  int numMats = mesh.GetMaterials(materials);
1799  for (int i = 0; i < numMats; i++)
1800  {
1801  remap += string.Format("$remap '%1' '%2';", materials[i], material);
1802  }
1803  entity.SetObject(mesh, remap);
1804  }
1805 
1806  //--- Iterate through children
1807  if (recursively)
1808  {
1809  IEntity child = entity.GetChildren();
1810  while (child)
1811  {
1812  SetMaterial(child, material);
1813  child = child.GetSibling();
1814  }
1815  }
1816  }
1817 
1818  //------------------------------------------------------------------------------------------------
1826  static bool IsChangedMouseAndKeyboard(EInputDeviceType oldDevice, EInputDeviceType newDevice)
1827  {
1828  return (oldDevice == EInputDeviceType.KEYBOARD && newDevice == EInputDeviceType.MOUSE) || (oldDevice == EInputDeviceType.MOUSE && newDevice == EInputDeviceType.KEYBOARD);
1829  }
1830 
1831  //------------------------------------------------------------------------------------------------
1838  static ResourceName GetRootWorld(ResourceName worldPath = ResourceName.Empty)
1839  {
1840  if (!worldPath)
1841  worldPath = GetResourceName(GetGame().GetWorldFile());
1842 
1843  Resource worldResource = BaseContainerTools.LoadContainer(worldPath);
1844  if (!worldResource || !worldResource.IsValid())
1845  return ResourceName.Empty;
1846 
1847  BaseContainer container = worldResource.GetResource().ToBaseContainer();
1848  ResourceName parent;
1849  container.Get("Parent", parent);
1850  if (parent)
1851  return GetRootWorld(parent);
1852  else
1853  return worldPath;
1854  }
1855 
1856  //------------------------------------------------------------------------------------------------
1863  static ResourceName GetResourceName(string path)
1864  {
1865  Resource meta = BaseContainerTools.LoadContainer(path + ".meta");
1866  if (!meta || !meta.IsValid())
1867  return ResourceName.Empty;
1868 
1869  ResourceName resourceName;
1870  meta.GetResource().ToBaseContainer().Get("Name", resourceName);
1871  return resourceName;
1872  }
1873 
1874  //------------------------------------------------------------------------------------------------
1881  static int GetFrequencies(SCR_GadgetManagerComponent gadgetManager, out notnull set<int> outFrequencies)
1882  {
1883  if (!gadgetManager)
1884  return 0;
1885 
1886  BaseRadioComponent radioComponent;
1887  array<SCR_GadgetComponent> gadgets = gadgetManager.GetGadgetsByType(EGadgetType.RADIO);
1888  gadgets.InsertAll(gadgetManager.GetGadgetsByType(EGadgetType.RADIO_BACKPACK));
1889  foreach (SCR_GadgetComponent gadget : gadgets)
1890  {
1891  radioComponent = BaseRadioComponent.Cast(gadget.GetOwner().FindComponent(BaseRadioComponent));
1892 
1893  if (!radioComponent || !radioComponent.IsPowered() || radioComponent.TransceiversCount() == 0)
1894  continue;
1895 
1896  for (int i = radioComponent.TransceiversCount() - 1; i >= 0; --i)
1897  {
1898  outFrequencies.Insert(radioComponent.GetTransceiver(i).GetFrequency());
1899  }
1900  }
1901  return outFrequencies.Count();
1902  }
1903 
1904  //------------------------------------------------------------------------------------------------
1910  static bool IsAdminRole(EPlayerRole role)
1911  {
1912  return SCR_Enum.HasPartialFlag(role, EPlayerRole.ADMINISTRATOR | EPlayerRole.SESSION_ADMINISTRATOR);
1913  }
1914 
1915  //------------------------------------------------------------------------------------------------
1921  static bool IsAdmin(int playerID)
1922  {
1923  return GetGame().GetPlayerManager().HasPlayerRole(playerID, EPlayerRole.ADMINISTRATOR)
1924  || GetGame().GetPlayerManager().HasPlayerRole(playerID, EPlayerRole.SESSION_ADMINISTRATOR);
1925  }
1926 
1927  //------------------------------------------------------------------------------------------------
1932  static bool IsAdmin()
1933  {
1934  int playerID = GetGame().GetPlayerController().GetPlayerId();
1935  return GetGame().GetPlayerManager().HasPlayerRole(playerID, EPlayerRole.ADMINISTRATOR)
1936  || GetGame().GetPlayerManager().HasPlayerRole(playerID, EPlayerRole.SESSION_ADMINISTRATOR);
1937  }
1938 
1939  //------------------------------------------------------------------------------------------------
1947  static ResourceName GetPrefabAttributeResource(notnull IEntity entity, string containerType, string attributeName)
1948  {
1949  EntityPrefabData prefabData = entity.GetPrefabData();
1950  if (!prefabData)
1951  return ResourceName.Empty;
1952 
1953  BaseContainer prefabSource = prefabData.GetPrefab();
1954  if (!prefabSource)
1955  return ResourceName.Empty;
1956 
1957  IEntitySource entitySource = prefabSource.ToEntitySource();
1958  if (!entitySource)
1959  return ResourceName.Empty;
1960 
1961  BaseContainer container = SCR_BaseContainerTools.FindComponentSource(entitySource, containerType);
1962  if (!container)
1963  return ResourceName.Empty;
1964 
1965  ResourceName resourceName;
1966  container.Get(attributeName, resourceName);
1967 
1968  return resourceName;
1969  }
1970 };
SCR_TerrainHelper
Definition: SCR_TerrainHelper.c:1
SCR_EPlayerTeleportedReason
SCR_EPlayerTeleportedReason
Definition: SCR_PlayerTeleportedFeedbackComponent.c:50
SCR_PlayerController
Definition: SCR_PlayerController.c:31
SCR_EntityHelper
Definition: SCR_EntityHelper.c:1
SCR_Enum
Definition: SCR_Enum.c:1
SCR_DestructibleBuildingEntity
Definition: SCR_DestructibleBuildingEntity.c:47
SCR_CompartmentAccessComponent
Definition: SCR_CompartmentAccessComponent.c:15
EPlayerRole
EPlayerRole
Definition: EPlayerRole.c:7
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_GadgetManagerComponent
Definition: SCR_GadgetManagerComponent.c:138
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
ENotification
ENotification
Definition: ENotification.c:4
CreateSimpleText
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)
Definition: DebugShapes.c:236
SCR_BaseContainerTools
Definition: SCR_BaseContainerTools.c:3
index
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Definition: SCR_DestructionSynchronizationComponent.c:17
SCR_Global
Definition: Functions.c:6
type
EDamageType type
Definition: SCR_DestructibleTreeV2.c:32
EDamageType
EDamageType
Definition: EDamageType.c:12
SCR_BuildingRegionEntity
Definition: SCR_BuildingRegionEntity.c:7
DamageManagerComponent
Definition: DamageManagerComponent.c:12
int
SCR_PossessingManagerComponentClass int
Obsolete
RespawnSystemComponentClass GameComponentClass Obsolete()] proto external GenericEntity DoSpawn(string prefab
RespawnSystemComponent should be attached to a gamemode to handle player spawning and respawning.
Building
Definition: Building.c:12