Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_EditorImagePositionEntity.c
Go to the documentation of this file.
1[EntityEditorProps(category: "GameScripted/Editor", description: "Image generator for pecific subset of entities", color: "255 0 0 255")]
2class SCR_EditorImagePositionEntityClass : GenericEntityClass
3{
4}
5
8
12class SCR_EditorImagePositionEntity : GenericEntity
13{
14 protected const float ANIM_TIME_STEP = 30.0;
15 protected const string ANIM_ARM_IK = "ArmIK";
16
17 [Attribute("0", uiwidget: UIWidgets.SearchComboBox, "Use this location fo entities with these labels.", "", ParamEnumArray.FromEnum(EEditableEntityLabel), category: "Configuration")]
18 protected ref array<EEditableEntityLabel> m_Labels;
19
20 [Attribute("2", uiwidget:UIWidgets.Slider, "Delay between creating the entity and taking a screenshot.", params: "1 5 0.5", category: "Configuration")]
21 protected float m_fDelay;
22
23 [Attribute("0", desc: "Order in which the position will be evaluated.\nHigher numbers are processed first.", category: "Configuration")]
24 protected int m_iPriority;
25
26 [Attribute(uiwidget:UIWidgets.ResourcePickerThumbnail, params: "xob", category: "Configuration")]
28
29 [Attribute(desc: "", category: "Configuration")]
30 protected bool m_bEnablePhysics;
31
32 [Attribute(desc: "Position the entity by center of its bounding box, not by center of the prefab.", category: "Configuration")]
33 protected bool m_bUseBoundingCenter;
34
35 [Attribute(desc: "When enabled, the prefab must fit into camera view. When that's not the game, another camera tied to the position will be searched for.", category: "Configuration")]
36 protected bool m_bMustFitInView;
37
38 [Attribute(desc: "Names of camera entities belonging to this position. Multiple positions could refer to the same camera.", category: "Configuration")]
39 protected ref array<string> m_aCameraNames;
40
41 // hidden (unused)
42
43 [Attribute(uiwidget: UIWidgets.None, params: "agr", category: "Animation")]
45
46 [Attribute(uiwidget: UIWidgets.None, params: "asi", category: "Animation")]
48
49 [Attribute(uiwidget: UIWidgets.None, category: "Animation")]
50 protected string m_sStartNode;
51
52 [Attribute(uiwidget: UIWidgets.None, category: "Animation")]
53 protected string m_sPoseVar;
54
55 [Attribute(uiwidget: UIWidgets.None, category: "Animation")]
56 protected int m_iPoseID;
57
58 [Attribute(uiwidget: UIWidgets.None, category: "Animation", params: "1 7 1")]
59 protected int m_iArmIK;
60
61 [Attribute(uiwidget:UIWidgets.None, params: "anm", category: "Animation")]
63
64 [Attribute("-1", uiwidget: UIWidgets.None, category: "Animation", enums: SCR_Enum.GetList(EWeaponType, ParamEnum("<Unchanged>", "-1")))]
66
67 // /hidden
68
69 [Attribute("-4", uiwidget:UIWidgets.Slider, params: "-90 90 1", category: "Environment")]
70 protected float m_fLatitude;
71
72 [Attribute("71", uiwidget:UIWidgets.Slider, params: "-180 180 1", category: "Environment")]
73 protected float m_fLongitude;
74
75 [Attribute("0.415", uiwidget:UIWidgets.Slider, params: "0 1 0.01", category: "Environment")]
76 protected float m_fTime;
77
78 [Attribute("1985", uiwidget: UIWidgets.Slider, params: "1899 2050 1", category: "Environment")]
79 protected int m_iYear;
80
81 [Attribute("5", uiwidget: UIWidgets.Slider, params: "1 12 1", category: "Environment")]
82 protected int m_iMonth;
83
84 [Attribute("8", uiwidget: UIWidgets.Slider, params: "1 31 1", category: "Environment")]
85 protected int m_iDay;
86
87 [Attribute(defvalue: "Clear", uiwidget: UIWidgets.ComboBox, category: "Environment", enums: { ParamEnum("Clear", "Clear"), ParamEnum("Cloudy", "Cloudy"), ParamEnum("Overcast", "Overcast"), ParamEnum("Rainy", "Rainy") }, desc: "Area shape")]
88 private string m_sWeatherState;
89
90 [Attribute(desc: "Default pose that should be used if no faction specific pose is defined", category: "Animation - Character")]
92
93 [Attribute(desc: "List of pose for each faction. Use default pose if selected character faction pose is not defined", category: "Animation - Character")]
94 protected ref array<ref SCR_EditorImagePositionCharacterPose> m_aFactionPoses;
95
96#ifdef WORKBENCH
97 protected ref array<SCR_CameraBase> m_aCameras = {};
98 protected SCR_EditorImagePositionEntity m_Parent;
99 protected ref SCR_SortedArray<SCR_EditorImagePositionEntity> m_aSubPositions = new SCR_SortedArray<SCR_EditorImagePositionEntity>();
100 protected IEntity m_Entity;
101 protected ref array<IEntity> m_aCurrentNearbyEntities = {};
102 protected ref array<IEntity> m_aOriginalNearbyEntities = {};
103 protected string m_sNewWeaponMesh;
104 protected string m_sCurrentWeaponMesh;
105
106 //------------------------------------------------------------------------------------------------
108 float GetDelay()
109 {
110 return m_fDelay;
111 }
112
113 //------------------------------------------------------------------------------------------------
115 int GetPriority()
116 {
117 return m_iPriority;
118 }
119
120 //------------------------------------------------------------------------------------------------
123 bool IsSuitable(array<EEditableEntityLabel> labels)
124 {
125 foreach (EEditableEntityLabel label : m_Labels)
126 {
127 //--- All position labels must be compatible with the editable entity. If even one is missing, ignore the position.
128 if (!labels.Contains(label))
129 return false;
130 }
131 return true;
132 }
133
134 //------------------------------------------------------------------------------------------------
139 SCR_EditorImagePositionEntity FindSuitableSubPosition(SCR_SortedArray<SCR_EditorImagePositionEntity> subPositions, array<EEditableEntityLabel> labels)
140 {
141 for (int i = subPositions.Count() - 1; i >= 0; i--)
142 {
143 if (subPositions.GetValue(i).IsSuitable(labels))
144 return subPositions.GetValue(i);
145 }
146 return null;
147 }
148
149 //------------------------------------------------------------------------------------------------
153 bool ActivatePosition(ResourceName prefab)
154 {
155 //--- Prevent AI groups from creating members themselves, do it manually here
156 SCR_AIGroup.IgnoreSpawning(true);
157
158 //--- Create prefab
159 EntitySpawnParams spawnParams = new EntitySpawnParams();
160 GetTransform(spawnParams.Transform);
161 m_Entity = GetGame().SpawnEntityPrefab(Resource.Load(prefab), GetWorld(), spawnParams);
162 if (!m_Entity)
163 {
164 Debug.Error2(Type().ToString(), string.Format("Error when creating prefab '%1'!", prefab));
165 return false;
166 }
167
168 //--- Orient composition to terrain
169 SCR_SlotCompositionComponent composition = SCR_SlotCompositionComponent.Cast(m_Entity.FindComponent(SCR_SlotCompositionComponent));
170 if (composition)
171 {
172 SCR_EditableEntityComponent editableComposition = SCR_EditableEntityComponent.GetEditableEntity(m_Entity);
173 editableComposition.SetTransformWithChildren(spawnParams.Transform);
174 //composition.OrientToTerrain();
175 }
176
177 //--- Set environment
178 ChimeraWorld world = GetWorld();
179 TimeAndWeatherManagerEntity envManager = world.GetTimeAndWeatherManager();
180 if (envManager)
181 {
182 int h, m, s;
183 envManager.SetCurrentLatitude(m_fLatitude);
184 envManager.SetCurrentLongitude(m_fLongitude);
185 envManager.TimeToHoursMinutesSeconds(m_fTime * 24, h, m, s);
186 envManager.SetHoursMinutesSeconds(h, m, s, false);
187 envManager.SetDate(m_iYear, m_iMonth, m_iDay, true);
188
189 //Set weather
190 BaseWeatherStateTransitionManager weatherTransitionManager = envManager.GetTransitionManager();
191 if (weatherTransitionManager)
192 {
193 WeatherStateTransitionNode transitionNode = weatherTransitionManager.CreateStateTransition(m_sWeatherState, 0, 1);
194 transitionNode.SetLooping(true);
195
196 weatherTransitionManager.EnqueueStateTransition(transitionNode, false);
197 weatherTransitionManager.RequestStateTransitionImmediately(transitionNode);
198 }
199
200 //int hX, mX, sX;
201 //envManager.GetHoursMinutesSeconds(hX, mX, sX);
202 //PrintFormat("%1 == %2, %3 == %4, %5 == %6", h, hX, m, mX, s, sX);
203 }
204
205 //--- Move group members to sub-positions
206 SCR_AIGroup group = SCR_AIGroup.Cast(m_Entity);
207 if (group)
208 {
209 /*
210 bool success = ActivateGroupPosition(group, spawnParams);
211 if (!success)
212 return false;
213 */
214
215 group.SetMemberSpawnDelay(0);
216 group.SpawnUnits();
217
218 GetGame().GetCallqueue().CallLater(ActivateGroupPosition, 1000, false, group, spawnParams);
219 }
220 else
221 {
222 SCR_EditableCharacterComponent character = SCR_EditableCharacterComponent.Cast(m_Entity.FindComponent(SCR_EditableCharacterComponent));
223 if (character)
224 ActivateCharacterPosition(prefab);
225
226 //--- Position the entity by its bounding center, not mesh origin
228 {
229 vector min, max;
230 SCR_Global.GetWorldBoundsWithChildren(m_Entity, min, max);
231 vector bCenter = min + (max - min) * 0.5;
232 m_Entity.SetOrigin(2 * m_Entity.GetOrigin() - bCenter);
233 m_Entity.Update();
234 }
235 }
236
237 //--- Activate physics
239 {
240 Physics phys = m_Entity.GetPhysics();
241 if (phys)
242 phys.SetActive(true);
243 }
244
245 //--- Activate camera
246 SCR_CameraBase camera;
248 {
249 vector min, max;
250 SCR_Global.GetWorldBoundsWithChildren(m_Entity, min, max);
251 array<vector> corners = {
252 min,
253 Vector(min[0], min[1], max[2]),
254 Vector(min[0], max[1], min[2]),
255 Vector(max[0], min[1], min[2]),
256 Vector(max[0], max[1], min[2]),
257 Vector(max[0], min[1], max[2]),
258 Vector(min[0], max[1], max[2]),
259 max
260 };
261
262 foreach (SCR_CameraBase cameraCandidate : m_aCameras)
263 {
264 bool isInView = true;
265 for (int i = 0; i < 8; i++)
266 {
267 if (!cameraCandidate.IsInView(corners[i]))
268 {
269 isInView = false;
270 break;
271 }
272 }
273 if (isInView)
274 {
275 camera = cameraCandidate;
276 break;
277 }
278 }
279 }
280 else
281 {
282 camera = m_aCameras[0];
283 }
284
285 if (camera)
286 {
287 CameraManager cameraManager = GetGame().GetCameraManager();
288 if (cameraManager)
289 cameraManager.SetCamera(camera);
290 }
291 else
292 Debug.Error2(Type().ToString(), string.Format("No camera which would fit '%1' found on position '%2'!", prefab, GetPositionName()));
293
294 return true;
295 }
296
297 //------------------------------------------------------------------------------------------------
299 void DeactivatePosition()
300 {
301 UpdateNearbyEntities();
302 foreach (IEntity entity : m_aCurrentNearbyEntities)
303 {
304 if (!m_aOriginalNearbyEntities.Contains(entity))
305 delete entity;
306 }
307 }
308
309 protected void AddSubPosition(SCR_EditorImagePositionEntity subPosition)
310 {
311 m_aSubPositions.Insert(subPosition.GetPriority(), subPosition);
312 }
313 protected void UpdateNearbyEntities()
314 {
315 m_aCurrentNearbyEntities.Clear();
316 GetWorld().QueryEntitiesByAABB(GetOrigin() + vector.One * -128, GetOrigin() + vector.One * 128, QueryEntitiesCallback);
317 }
318 protected bool QueryEntitiesCallback(IEntity e)
319 {
320 m_aCurrentNearbyEntities.Insert(e);
321 return true;
322 }
323 protected string GetPositionName()
324 {
325 if (GetName().IsEmpty())
326 return GetOrigin().ToString();
327 else
328 return GetName();
329 }
330
331 //------------------------------------------------------------------------------------------------
334 event void EOnImagePositonActivate(IEntity entity)
335 {
336 }
337
338 override void EOnInit(IEntity owner)
339 {
340 if (SCR_Global.IsEditMode(this))
341 return;
342
343 SCR_EditorImageGeneratorEntity manager = SCR_EditorImageGeneratorEntity.GetInstance();
344 if (!manager)
345 {
346 Debug.Error2(Type().ToString(), "SCR_EditorImageGeneratorEntity is missing in the world!");
347 return;
348 }
349
350 if (m_Parent)
351 {
352 //--- Sub-position
353 m_Parent.AddSubPosition(this);
354 }
355 else
356 {
357 //--- Main position
358 SCR_CameraBase camera;
359
360 //--- Find referenced camera entities
361 for (int i = 0, count = m_aCameraNames.Count(); i < count; i++)
362 {
363 camera = SCR_CameraBase.Cast(GetWorld().FindEntityByName(m_aCameraNames[i]));
364 if (camera && !m_aCameras.Contains(camera))
365 m_aCameras.Insert(camera);
366 }
367
368 //--- Find child camera entities
369 IEntity child = GetChildren();
370 while (child)
371 {
372 camera = SCR_CameraBase.Cast(child);
373 if (camera && !m_aCameras.Contains(camera))
374 m_aCameras.Insert(camera);
375
376 child = child.GetSibling();
377 }
378
379 if (m_aCameras.IsEmpty())
380 {
381 Print("SCR_EditorImagePositionEntity is missing child entity of type SCR_CameraBase!", LogLevel.WARNING);
382 return;
383 }
384
385 manager.AddPosition(this);
386 }
387
388 //--- Get nearby entities
389 UpdateNearbyEntities();
390 m_aOriginalNearbyEntities.Copy(m_aCurrentNearbyEntities);
391 }
392
393 //------------------------------------------------------------------------------------------------
394 // constructor
397 void SCR_EditorImagePositionEntity(IEntitySource src, IEntity parent)
398 {
399 m_Parent = SCR_EditorImagePositionEntity.Cast(parent);
400
401 if (SCR_Global.IsEditMode(this))
402 {
403 if (m_PreviewMesh)
404 {
405 Resource resource = Resource.Load(m_PreviewMesh);
406 if (!resource.IsValid())
407 {
408 Print("Cannot load " + m_PreviewMesh + " | " + FilePath.StripPath(__FILE__) + ":" + __LINE__, LogLevel.WARNING);
409 return;
410 }
411
412 SetObject(resource.GetResource().ToVObject(), "");
413 }
414
415 return;
416 }
417
418 SetEventMask(EntityEvent.INIT);
419 }
420
421 //------------------------------------------------------------------------------------------------
422 // destructor
423 void ~SCR_EditorImagePositionEntity()
424 {
425 WorldEditorAPI api = _WB_GetEditorAPI();
426 if (api && api.IsEntitySelected(api.EntityToSource(this)))
427 SCR_EditorImageGeneratorEntity.AddSelectedPosition(this);
428 }
429
430 //------------------------------------------------------------------------------------------------
431 override int _WB_GetAfterWorldUpdateSpecs(IEntitySource src)
432 {
433 return EEntityFrameUpdateSpecs.CALL_WHEN_ENTITY_VISIBLE;
434 }
435
436 //------------------------------------------------------------------------------------------------
437 override void _WB_AfterWorldUpdate(float timeSlice)
438 {
439 if (m_Labels.IsEmpty())
440 return;
441
442 string name;
443 for (int i = 0, count = m_Labels.Count(); i < count; i++)
444 {
445 if (i != 0)
446 {
447 if (i % 2 == 0)
448 name += ",\n";
449 else
450 name += ", ";
451 }
452
453 name += typename.EnumToString(EEditableEntityLabel, m_Labels[i]);
454 }
455
456 float fontSize = 12;
457 if (m_Parent)
458 fontSize = 8;
459
460 vector pos = GetOrigin();
461 DebugTextWorldSpace.Create(GetWorld(), name, DebugTextFlags.CENTER | DebugTextFlags.FACE_CAMERA | DebugTextFlags.ONCE, pos[0], pos[1], pos[2], fontSize, Color.WHITE, ARGBF(1, 0.5, 0, 1));
462 }
463
464 //------------------------------------------------------------------------------------------------
465 // Character position
466 //------------------------------------------------------------------------------------------------
467
468 //------------------------------------------------------------------------------------------------
469 protected void ActivateCharacterPosition(ResourceName prefab)
470 {
471 // Check faction and get pose
472 SCR_EditorImagePositionCharacterPose pose = CurrentPose(m_Entity);
473
474 Resource characterResource = Resource.Load(prefab);
475 ResourceName weaponIK = CharacterWeaponIK(characterResource, pose);
476
477 // Select weapon
478 EWeaponType forceWeaponType = pose.GetForceWeaponType();
479
480 if (forceWeaponType >= 0)
481 {
482 InventoryStorageManagerComponent inventoryStorage = InventoryStorageManagerComponent.Cast(m_Entity.FindComponent(InventoryStorageManagerComponent));
483 if (inventoryStorage)
484 {
485 array<IEntity> items = {};
486 for (int i = inventoryStorage.GetItems(items) - 1; i >= 0; i--)
487 {
488 BaseWeaponComponent weapon = BaseWeaponComponent.Cast(items[i].FindComponent(BaseWeaponComponent));
489 if (!weapon)
490 continue;
491
492 if (weapon.GetWeaponType() == forceWeaponType)
493 {
494 m_sNewWeaponMesh = items[i].GetVObject().GetResourceName();
495 break;
496 }
497 }
498 }
499
500 BaseWeaponManagerComponent weaponManager = BaseWeaponManagerComponent.Cast(m_Entity.FindComponent(BaseWeaponManagerComponent));
501 if (weaponManager)
502 {
503 BaseWeaponComponent currentWeapon = weaponManager.GetCurrentWeapon();
504 if (currentWeapon)
505 m_sCurrentWeaponMesh = currentWeapon.GetOwner().GetVObject().GetResourceName();
506 }
507 }
508
509 vector transform[4];
510 m_Entity.GetTransform(transform);
511 CloneCharacter(m_Entity, transform);
512
513 SetPose(m_Entity, pose, weaponIK);
514 }
515
516 //------------------------------------------------------------------------------------------------
518 protected SCR_EditorImagePositionCharacterPose CurrentPose(notnull IEntity entity, SCR_EditorImagePositionEntity position = this)
519 {
520 if (!position)
521 position = this;
522
523 // Get faction key
524 SCR_EditableCharacterComponent editable = SCR_EditableCharacterComponent.Cast(entity.FindComponent(SCR_EditableCharacterComponent));
525 if (!editable)
526 {
527 Print("No editable entity for: " + entity.GetName(), LogLevel.WARNING);
528 return null;
529 }
530
531 SCR_UIInfo uiInfoBase = editable.GetInfo();
532 if (!uiInfoBase)
533 {
534 return null;
535 }
536
537 SCR_EditableEntityUIInfo uiInfo = SCR_EditableEntityUIInfo.Cast(editable.GetInfo());
538 if (!uiInfo)
539 {
540 Print("No uiinfo for: " + entity.GetName(), LogLevel.WARNING);
541 return null;
542 }
543
544 FactionKey factionKey = uiInfo.GetFactionKey();
545
546 // Find pose based on faction
547 foreach (SCR_EditorImagePositionCharacterPose pose : position.m_aFactionPoses)
548 {
549 if (pose.GetFactionKey() == factionKey)
550 return pose;
551 }
552
553 // Use default if no faction pose is defined
554 return position.m_DefaultPose;
555 }
556
557 //------------------------------------------------------------------------------------------------
559 protected void SetPose(IEntity entity, notnull SCR_EditorImagePositionCharacterPose pose, ResourceName armsIK)
560 {
561 ResourceName poseGraph = pose.GetPoseGraph();
562 ResourceName poseInstance = pose.GetPosesInstance();
563 string startNode = pose.GetStartNode();
564
565 if (poseGraph.IsEmpty() && poseInstance.IsEmpty() && startNode.IsEmpty())
566 return;
567
568 PreviewAnimationComponent animComponent = PreviewAnimationComponent.Cast(entity.FindComponent(PreviewAnimationComponent));
569 animComponent.SetGraphResource(entity, poseGraph, poseInstance, startNode);
570
571 // Perform one frame step to apply animations immediately
572 animComponent.UpdateFrameStep(entity, 1.0 / ANIM_TIME_STEP);
573
574 // Find variable that we want to change
575 int poseVar = animComponent.BindIntVariable(pose.GetPosVar());
576 if (poseVar == -1)
577 {
578 Debug.Error2(Type().ToString(), string.Format("Unable to set character pose at positon '%1'!", GetPositionName()));
579 return;
580 }
581
582 // change pose
583 animComponent.SetIntVariable(poseVar, pose.GetPosId());
584
585 // Set hands IK
586 int armIkVar = pose.BindAnimValueInteger(animComponent, ANIM_ARM_IK);
587 if (armIkVar != -1)
588 {
589 animComponent.SetIntVariable(armIkVar, pose.GetArmIK());
590 animComponent.SetHandsIKPose(entity, armsIK);
591 }
592
593 // Perform one frame step to submit graph variable change
594 animComponent.UpdateFrameStep(entity, 1.0 / ANIM_TIME_STEP);
595 }
596
597 //------------------------------------------------------------------------------------------------
599 protected ResourceName CharacterWeaponIK(Resource characterResource, SCR_EditorImagePositionCharacterPose pose)
600 {
601 //Resource characterResource = Resource.Load(prefab);
602
603 array<ref array<IEntityComponentSource>> weaponSlotComponents = {};
604 array<string> componentTypeArray = { "CharacterWeaponSlotComponent" };
605 int weaponSlotCount = SCR_BaseContainerTools.FindComponentSources(characterResource, componentTypeArray, weaponSlotComponents);
606
607 array<IEntityComponentSource> weaponSlotComponentSources = weaponSlotComponents.Get(0);
608 if (!weaponSlotComponentSources)
609 return ResourceName.Empty;
610
611 foreach (IEntityComponentSource weaponSlotComponent : weaponSlotComponentSources)
612 {
613 ResourceName weaponPrefab;
614 if (!weaponSlotComponent.Get("WeaponTemplate", weaponPrefab))
615 return ResourceName.Empty;
616
617 if (!weaponPrefab)
618 continue;
619
620 Resource resource = Resource.Load(weaponPrefab);
621 if (!resource.IsValid())
622 continue;
623
624 IEntitySource weaponSource = SCR_BaseContainerTools.FindEntitySource(resource);
625 if (!weaponSource)
626 continue;
627
628 // Check type
629 IEntityComponentSource weaponComponentSource = SCR_BaseContainerTools.FindComponentSource(resource, WeaponComponent);
630 if (!weaponComponentSource)
631 continue;
632
633 EWeaponType forcedWeaponType = pose.GetForceWeaponType();
634
635 if (forcedWeaponType != -1)
636 {
637 EWeaponType weaponType;
638 weaponComponentSource.Get("WeaponType", weaponType);
639
640 if (weaponType != pose.GetForceWeaponType())
641 continue;
642 }
643
644 // Get anim
645 IEntityComponentSource weaponEntitySource = SCR_ComponentHelper.GetInventoryItemComponentSource(weaponSource);
646
647 BaseContainer attributesContainer = weaponEntitySource.GetObject("Attributes");
648
649 BaseContainer animAttributes = attributesContainer.GetObject("ItemAnimationAttributes");
650
651 ResourceName animIkResourceName;
652 animAttributes.Get("AnimationIKPose", animIkResourceName);
653 return animIkResourceName;
654 }
655
656 return ResourceName.Empty;
657 }
658
659 //------------------------------------------------------------------------------------------------
660 protected void CloneCharacter(out IEntity character, vector transform[4])
661 {
662 InventoryItemComponent inventoryComponent = InventoryItemComponent.Cast(character.FindComponent(InventoryItemComponent));
663 if (!inventoryComponent)
664 return;
665
666 //--- Clone character using inventory preview function so we can play animations on it
667 IEntity clone = inventoryComponent.CreatePreviewEntity(GetWorld(), GetWorld().GetCurrentCameraId());
668 if (!clone)
669 return;
670
671 //--- Swap weapons
672 if (m_sNewWeaponMesh != m_sCurrentWeaponMesh)
673 {
674 IEntity currentWeapon, newWeapon;
675 TNodeId currentPivot, newPivot;
676 vector currentLocalTransform[4], newLocalTransform[4];
677
678 IEntity child = clone.GetChildren();
679 while (child)
680 {
681 VObject mesh = child.GetVObject();
682 if (mesh)
683 {
684 if (mesh.GetResourceName() == m_sCurrentWeaponMesh)
685 {
686 currentWeapon = child;
687 currentPivot = child.GetPivot();
688 child.GetLocalTransform(currentLocalTransform);
689 }
690 if (mesh.GetResourceName() == m_sNewWeaponMesh)
691 {
692 newWeapon = child;
693 newPivot = child.GetPivot();
694 child.GetLocalTransform(newLocalTransform);
695 }
696 }
697 child = child.GetSibling();
698 }
699
700 clone.AddChild(newWeapon, currentPivot);
701 newWeapon.SetLocalTransform(currentLocalTransform);
702
703 clone.AddChild(currentWeapon, newPivot);
704 currentWeapon.SetLocalTransform(newLocalTransform);
705 }
706
707 SCR_EntityHelper.DeleteEntityAndChildren(character);
708 character = clone;
709 character.SetTransform(transform);
710 }
711
712 //------------------------------------------------------------------------------------------------
713 // Groups position
714 //------------------------------------------------------------------------------------------------
715
716 //------------------------------------------------------------------------------------------------
717 protected bool ActivateGroupPosition(SCR_AIGroup group, EntitySpawnParams spawnParams)
718 {
719 //--- Make sure group AI members are spawned instantly, not asynchronously
720 //group.SetMemberSpawnDelay(0);
721 //group.SpawnUnits();
722
723 array<AIAgent> agents = {};
724 int agentCount = group.GetAgents(agents);
725
726 if (agentCount > m_aSubPositions.Count())
727 {
728 //Print(string.Format("Cannot capture group @\"%1\"! It has %2 members, but the position '%3' has only %4 sub-positions!", prefab, agentCount, GetPositionName(), m_aSubPositions.Count()), LogLevel.WARNING);
729 return false;
730 }
731
732 m_Entity = GetGame().SpawnEntity(GenericEntity, GetWorld(), spawnParams);
733 IEntity member;
734 vector transform[4];
735 SCR_SortedArray<SCR_EditorImagePositionEntity> subPositions = new SCR_SortedArray<SCR_EditorImagePositionEntity>();
736 subPositions.CopyFrom(m_aSubPositions);
737 SCR_EditorImagePositionEntity subPosition;
738 bool failed = false;
739
740 for (int i = 0; i < agentCount; i++)
741 {
742 member = agents[i].GetControlledEntity();
743
744 //--- Get member labels
745 SCR_EditableEntityComponent editableMember = SCR_EditableEntityComponent.GetEditableEntity(member);
746 SCR_EditableEntityUIInfo info = SCR_EditableEntityUIInfo.Cast(editableMember.GetInfo());
747 array<EEditableEntityLabel> memberLabels = {};
748 if (info)
749 info.GetEntityLabels(memberLabels);
750
751 //--- Find suitable sub-position, taking member labels into consideration
752 subPosition = FindSuitableSubPosition(subPositions, memberLabels);
753 if (subPosition)
754 {
755 // Prepare position values
756 SCR_EditorImagePositionCharacterPose pose = CurrentPose(member, subPosition);
757
758 Resource characterResource = BaseContainerTools.CreateContainerFromInstance(member);
759 ResourceName weaponIK = CharacterWeaponIK(characterResource, pose);
760
761 // Apply position
762 subPositions.RemoveValues(subPosition);
763 subPosition.GetTransform(transform);
764
765 CloneCharacter(member, transform);
766 //m_Entity.AddChild(member, -1, EAddChildFlags.RECALC_LOCAL_TRANSFORM); //--- Crashes the game! Not needed, area garbage collection removes clones anyway.
767 subPosition.SetPose(member, pose, weaponIK);
768 subPosition.EOnImagePositonActivate(member);
769 }
770 else
771 {
772 PrintFormat("Cannot capture group member @\"%1\"! Unable to find suitable sub-position for %1!", member.GetPrefabData().GetPrefabName(), level: LogLevel.WARNING);
773 failed = true;
774 }
775 }
776 SCR_EntityHelper.DeleteEntityAndChildren(group);
777
778 if (failed)
779 return false;
780
781 EOnImagePositonActivate(m_Entity);
782 return true;
783 }
784#endif
785}
GetTransformResult JsonApiStruct GetTransform(notnull const BlenderRestAPI connection, string object_name)
EEditableEntityLabel
string FactionKey
Faction unique identifier type.
Definition FactionKey.c:2
ArmaReforgerScripted GetGame()
Definition game.c:1398
void SCR_AIGroup(IEntitySource src, IEntity parent)
int m_iPriority
enum EAITargetInfoCategory m_Entity
vector GetOrigin()
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
vector position
ref array< ref SCR_EditorImagePositionCharacterPose > m_aFactionPoses
ResourceName m_PreviewMesh
ref array< string > m_aCameraNames
ResourceName m_sPosesGraph
ref SCR_EditorImagePositionCharacterPose m_DefaultPose
const string ANIM_ARM_IK
ref array< EEditableEntityLabel > m_Labels
ResourceName m_sArmIKResource
bool m_bUseBoundingCenter
ResourceName m_sPosesInstance
EWeaponType m_eForceWeaponType
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
void GetChildren(out array< SCR_ScenarioFrameworkLayerBase > children)
int Type
enum EVehicleType IEntity
float GetDelay()
proto external Managed FindComponent(typename typeName)
proto external bool SetLocalTransform(vector mat[4])
See IEntity::SetTransform. Returns false, if there is no change in transformation.
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 IEntity GetChildren()
proto external bool SetTransform(vector mat[4])
proto external EntityPrefabData GetPrefabData()
proto external TNodeId GetPivot()
Returns pivot ID from hierarchy component.
proto external IEntity GetSibling()
proto external VObject GetVObject()
Returns visual object set to this Entity. No reference is added.
proto external void GetLocalTransform(out vector mat[])
See IEntity::GetTransform.
void SpawnUnits()
void SetMemberSpawnDelay(int memberSpawnDelay)
void SetTransformWithChildren(vector transform[4])
SCR_UIInfo GetInfo(IEntity owner=null)
int GetEntityLabels(out notnull array< EEditableEntityLabel > entityLabels)
void EntitySpawnParams()
Definition gameLib.c:130
override void EOnInit(IEntity owner)
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
DebugTextFlags
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
proto void PrintFormat(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL, LogLevel level=LogLevel.NORMAL)
SCR_FieldOfViewSettings Attribute
SCR_EditorImagePositionEntityClass ANIM_TIME_STEP
EntityEvent
Various entity events.
Definition EntityEvent.c:14
int TNodeId
Node global id is a hash of name of the node.
Definition EnEntity.c:18
proto external string ToString()
Plain C++ pointer, no weak pointers, no memory management.
proto native vector Vector(float x, float y, float z)
proto native bool IsEmpty()
void Debug()
Definition Types.c:327
EWeaponType
Definition EWeaponType.c:13
func QueryEntitiesCallback
Definition EnWorld.c:6
proto int ARGBF(float fa, float fr, float fg, float fb)
Converts <0.0, 1.0> ARGB into color.