Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_PlacingEditorComponent.c
Go to the documentation of this file.
1 [ComponentEditorProps(category: "GameScripted/Editor", description: "Content browser component. Works only with SCR_EditorBaseEntity!", icon: "WBData/ComponentEditorProps/componentEditor.png")]
3 {
4  [Attribute(category: "Placing", uiwidget: UIWidgets.Flags, desc: "System type of the entity.", enums: ParamEnumArray.FromEnum(EEditorPlacingFlags))]
5  protected EEditorPlacingFlags m_AllowedPlacingFlags;
6 
7  [Attribute(category: "Placing", uiwidget: UIWidgets.ResourcePickerThumbnail, desc: "Editable entity used for testing. Should be a sphere 1 m in diameter.")]
8  protected ResourceName m_TestPrefab;
9 
10  [Attribute(category: "Placing")]
11  protected ref array<ref SCR_PlaceableEntitiesRegistry> m_Registries;
12 
13  [Attribute(category: "Effects")]
14  protected ref array<ref SCR_BaseEditorEffect> m_EffectsPlaceStart;
15 
16  [Attribute(category: "Effects")]
17  protected ref array<ref SCR_BaseEditorEffect> m_EffectsPlaceConfirm;
18 
19  [Attribute(category: "Effects")]
20  protected ref array<ref SCR_BaseEditorEffect> m_EffectsPlaceCancel;
21 
22  protected int m_iPrefabCount;
23  protected ref array<int> m_aIndexes = {};
24 
25  array<ref SCR_BaseEditorEffect> GetEffectsPlaceStart()
26  {
27  return m_EffectsPlaceStart;
28  }
29  array<ref SCR_BaseEditorEffect> GetEffectsPlaceConfirm()
30  {
31  return m_EffectsPlaceConfirm;
32  }
33  array<ref SCR_BaseEditorEffect> GetEffectsPlaceCancel()
34  {
35  return m_EffectsPlaceCancel;
36  }
37 
38  /*
39  Get registered prefab with given index.
40  \param index Prefab index from the registry
41  \return Prefab path (empty when the index is invalid)
42  */
43  ResourceName GetPrefab(int index)
44  {
45  for (int i = m_aIndexes.Count() - 1; i >= 0; i--)
46  {
47  int registryIndex = m_aIndexes[i];
48  if (index >= registryIndex)
49  return m_Registries[i].GetPrefabs()[index - registryIndex];
50  }
51  return ResourceName.Empty;
52  }
53  /*
54  Get index of registered prefab
55  \param prefab Prefab path
56  \return Prefab index (-1 when the prefab is not found)
57  */
58  int GetPrefabID(ResourceName prefab)
59  {
60  foreach (int i, SCR_PlaceableEntitiesRegistry registry: m_Registries)
61  {
62  int index = registry.GetPrefabs().Find(prefab);
63  if (index != -1)
64  return index + m_aIndexes[i];
65  }
66  return -1;
67  }
68  /*
69  Get number of prefabs in the registry.
70  \return Number of prefabs
71  */
72  int CountPrefabs()
73  {
74  return m_iPrefabCount;
75  }
76  /*
77  Get registered prefabs.
78  \param[out] outPrefabs Array to be filled with prefabs
79  \return Number of prefabs
80  */
81  int GetPrefabs(out notnull array<ResourceName> outPrefabs, bool onlyExposed = false)
82  {
83  foreach (SCR_PlaceableEntitiesRegistry registry: m_Registries)
84  {
85  outPrefabs.InsertAll(registry.GetPrefabs(onlyExposed));
86  }
87  return outPrefabs.Count();
88  }
89  /*
90  Check if given placing flag is allowed to be changed.
91  \return True when the flag can be changed
92  */
93  bool HasPlacingFlag(EEditorPlacingFlags flag)
94  {
95  return SCR_Enum.HasFlag(m_AllowedPlacingFlags, flag);
96  }
97  /*
98  Get prefab used for testing.
99  \return Prefab
100  */
101  ResourceName GetTestPrefab()
102  {
103  return m_TestPrefab;
104  }
105 
106  void SCR_PlacingEditorComponentClass(BaseContainer prefab)
107  {
108  foreach (SCR_PlaceableEntitiesRegistry registry: m_Registries)
109  {
110  m_aIndexes.Insert(m_iPrefabCount);
111  m_iPrefabCount += registry.GetPrefabs().Count();
112  }
113  }
114 };
115 
119 {
120  [Attribute(defvalue: "10", category: "Placing", desc: "Spacing between entities placed for multiple recipients")]
121  protected float m_fSpacing;
122 
123  private ResourceName m_SelectedPrefab;
124  private SCR_StatesEditorComponent m_StatesManager;
125  protected SCR_PreviewEntityEditorComponent m_PreviewManager;
126  protected SCR_BudgetEditorComponent m_BudgetManager;
127 
128  private SCR_SiteSlotEntity m_Slot;
129  private int m_iEntityIndex;
130  private ref map<int, IEntity> m_WaitingPreviews = new map<int, IEntity>;
131  private vector m_vFixedPosition;
132  private float m_fPreviewAnimationProgress = -1;
133  private EEditorPlacingFlags m_PlacingFlags;
134  private EEditorPlacingFlags m_CompatiblePlacingFlags;
135  private ref set<SCR_EditableEntityComponent> m_Recipients;
136  private ref SCR_EditorPreviewParams m_InstantPlacingParam;
137 
138  protected bool m_bBlockPlacing;
139 
140  private ref ScriptInvoker Event_OnSelectedPrefabChange = new ScriptInvoker;
141  private ref ScriptInvoker Event_OnPlacingPlayerChange = new ScriptInvoker;
142  private ref ScriptInvoker Event_OnPlacingFlagsChange = new ScriptInvoker;
143 
144  private ref ScriptInvoker Event_OnRequestEntity = new ScriptInvoker;
145  private ref ScriptInvoker Event_OnPlaceEntity = new ScriptInvoker;
146 
147  private ref ScriptInvoker Event_OnPlaceEntityServer = new ScriptInvoker;
148 
149  protected static SCR_EditableEntityComponent m_DelayedSpawnEntity;
150  protected static ref SCR_EditorPreviewParams m_DelayedSpawnPreviewParams;
151 
152  void SetPlacingBlocked(bool blocked)
153  {
154  m_bBlockPlacing = blocked;
155  }
156 
157  /*
158  Get registered prefab with given index.
159  \param index Prefab index from the registry
160  \return Prefab path (empty when the index is invalid)
161  */
162  int GetPrefabID(ResourceName prefab)
163  {
164  if (prefab.IsEmpty())
165  return -1;
166 
167  SCR_PlacingEditorComponentClass prefabData = SCR_PlacingEditorComponentClass.Cast(GetEditorComponentData());
168  if (!prefabData)
169  return -1;
170 
171  return prefabData.GetPrefabID(prefab);
172  }
173 
181  bool CreateEntity(bool unselectPrefab = true, bool canBePlayer = false)
182  {
183  //--- Check if placing is allowed. If not, prevent the operation and send a notification to player.
184  ENotification notification = -1;
185  if (!CanCreateEntity(notification))
186  {
187  if (notification != -1)
188  SendNotification(notification);
189  return false;
190  }
191 
192  SCR_PlacingEditorComponentClass prefabData = SCR_PlacingEditorComponentClass.Cast(GetEditorComponentData());
193  if (!prefabData || !m_SelectedPrefab) return false;
194 
195  if (!m_PreviewManager.IsChange() && !m_InstantPlacingParam)
196  {
197  SendNotification(ENotification.EDITOR_TRANSFORMING_INCORRECT_POSITION);
198  SetSelectedPrefab(ResourceName.Empty, true);
199  return false;
200  }
201 
202  int prefabID = prefabData.GetPrefabID(m_SelectedPrefab);
203  if (prefabID == -1)
204  {
205  Print(string.Format("Cannot place prefab @\"%1\", it's not registered in placeable entities!", m_SelectedPrefab.GetPath()), LogLevel.WARNING);
206  SetSelectedPrefab(ResourceName.Empty, true);
207  return false;
208  }
209 
210  //--- If the entity can be spawned as player, get player ID
211  int playerID = GetManager().GetPlayerID();
212 
213  if (!canBePlayer)
214  canBePlayer = HasPlacingFlag(EEditorPlacingFlags.CHARACTER_PLAYER);
215 
216  if (canBePlayer)
217  {
218  Resource prefabResource = Resource.Load(m_SelectedPrefab);
219  IEntityComponentSource component = SCR_BaseContainerTools.FindComponentSource(prefabResource, SCR_EditableEntityComponent);
220  if (component && SCR_EditableEntityComponentClass.GetEntityType(component) != EEditableEntityType.CHARACTER)
221  {
222  SendNotification(ENotification.EDITOR_PLACING_CANNOT_AS_PLAYER);
223  SetSelectedPrefab(ResourceName.Empty, true);
224  return false;
225  }
226  }
227 
228  //~ If placing with crew or passengers. Send notification if not enough budget
229  if (SCR_Enum.HasFlag(m_PlacingFlags, EEditorPlacingFlags.VEHICLE_CREWED) ||SCR_Enum.HasFlag(m_PlacingFlags, EEditorPlacingFlags.VEHICLE_PASSENGER))
230  {
231  array<ref SCR_EntityBudgetValue> budgetCosts = {};
232  Resource resource = Resource.Load(m_SelectedPrefab);
233  if (!resource.IsValid())
234  {
235  Print("Cannot load prefab " + m_SelectedPrefab + " | " + FilePath.StripPath(__FILE__) + ":" + __LINE__, LogLevel.WARNING);
236  return false;
237  }
238 
239  IEntityComponentSource source = SCR_EditableEntityComponentClass.GetEditableEntitySource(resource.GetResource().ToEntitySource());
240  m_BudgetManager.GetVehicleOccupiedBudgetCosts(source, m_PlacingFlags, budgetCosts, false);
241  EEditableEntityBudget blockingBudget;
242 
243  if (!m_BudgetManager.CanPlace(budgetCosts, blockingBudget))
244  SCR_NotificationsComponent.SendLocal(ENotification.EDITOR_PLACING_BUDGET_MAX_FOR_VEHICLE_OCCUPANTS);
245  }
246 
247  //--- Create packet
249  if (m_InstantPlacingParam)
250  {
251  params = m_InstantPlacingParam;
252  }
253  else
254  {
257  if (layersManager)
258  parent = layersManager.GetCurrentLayer();
259 
260  params = SCR_EditorPreviewParams.CreateParamsFromPreview(m_PreviewManager, parent, true);
261  }
262 
263  if (!params)
264  return false;
265 
266  //--- Save placing flags
267  params.m_PlacingFlags = m_PlacingFlags;
268 
269  //--- Copy the preview, it will remain visible until callback from server is received
270  int simulatedDelay = DiagMenu.GetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_NETWORK_DELAY) * 100;
271  m_iEntityIndex++;
272  if (IsProxy() || simulatedDelay > 0)
273  m_WaitingPreviews.Insert(m_iEntityIndex, m_PreviewManager.CreateWaitingPreview());
274 
275  array<RplId> recipientIds;
276  if (m_Recipients)
277  {
278  recipientIds = {};
279  foreach (SCR_EditableEntityComponent entity: m_Recipients)
280  {
281  RplId id = Replication.FindId(entity);
282  if (id.IsValid())
283  recipientIds.Insert(id);
284  }
285  }
286 
287  //--- Send request to server
288  m_StatesManager.SetIsWaiting(true);
289  Event_OnRequestEntity.Invoke(prefabID, params.m_vTransform, null);
290 
291  if (simulatedDelay > 0 && !Replication.IsRunning())
292  GetGame().GetCallqueue().CallLater(CreateEntityServer, simulatedDelay, false, params, prefabID, playerID, m_iEntityIndex, !unselectPrefab, recipientIds, canBePlayer);
293  else
294  Rpc(CreateEntityServer, params, prefabID, playerID, m_iEntityIndex, !unselectPrefab, recipientIds, canBePlayer);
295 
296  //--- ToDo: Fail the request if server didn't respond in given time
297  //GetGame().GetCallqueue().CallLater(CreateEntityOwner, 10000, false, prefabID, -1);
298 
299  m_Slot = null;
300  m_InstantPlacingParam = null;
301 
302  //--- Stop placing (only after packet was created)
303  if (unselectPrefab || m_InstantPlacingParam)
304  SetSelectedPrefab(ResourceName.Empty, true);
305 
306  return true;
307  }
317  bool CreateEntity(ResourceName prefab, SCR_EditorPreviewParams param, bool unselectPrefab = true, bool canBePlayer = false, set<SCR_EditableEntityComponent> recipients = null)
318  {
319  if (m_bBlockPlacing)
320  return false;
321 
322  m_SelectedPrefab = prefab;
323  m_Recipients = recipients;
324  SetInstantPlacing(param);
325  return CreateEntity(unselectPrefab, canBePlayer);
326  }
327 
328  [RplRpc(RplChannel.Reliable, RplRcver.Server)]
329  protected void CreateEntityServer(SCR_EditorPreviewParams params, RplId prefabID, int playerID, int entityIndex, bool isQueue, array<RplId> recipientIds, bool canBePlayer)
330  {
331  if (m_bBlockPlacing)
332  return;
333 
334  SCR_PlacingEditorComponentClass prefabData = SCR_PlacingEditorComponentClass.Cast(GetEditorComponentData());
335  if (RplSession.Mode() == RplMode.Client || !prefabData) return;
336 
337  array<RplId> entityIds = {};
338 
339  if (!CanCreateEntity() || !params.Deserialize())
340  {
341  Rpc(CreateEntityOwner, prefabID, entityIds, entityIndex, false, false, RplId.Invalid(), 0);
342  return;
343  }
344 
345  //--- Get prefab
346  ResourceName prefab = prefabData.GetPrefab(prefabID);
347  if (prefab.IsEmpty())
348  {
349  Print("Cannot create entity, prefab not defined!", LogLevel.ERROR);
350  Rpc(CreateEntityOwner, prefabID, entityIds, entityIndex, false, false, RplId.Invalid(), 0);
351  return;
352  }
353  Resource prefabResource = Resource.Load(prefab);
354  if (!prefabResource || !prefabResource.IsValid())
355  {
356  Print(string.Format("Cannot create entity, error when loading prefab '%1'!", prefab), LogLevel.ERROR);
357  Rpc(CreateEntityOwner, prefabID, entityIds, entityIndex, false, false, RplId.Invalid(), 0);
358  return;
359  }
360  IEntityComponentSource editableEntitySource = SCR_EditableEntityComponentClass.GetEditableEntitySource(prefabResource);
361  if (!editableEntitySource)
362  {
363  Print(string.Format("Cannot create entity, prefab '%1' does not contain SCR_EditableEntityComponent!", prefab), LogLevel.ERROR);
364  Rpc(CreateEntityOwner, prefabID, entityIds, entityIndex, false, false, RplId.Invalid(), 0);
365  return;
366  }
367 
368  EEditableEntityBudget blockingBudget;
369  if (!CanPlaceEntityServer(editableEntitySource, blockingBudget, false, false))
370  {
371  Print(string.Format("Entity budget exceeded for player!"), LogLevel.ERROR);
372  Rpc(CreateEntityOwner, prefabID, entityIds, entityIndex, false, false, RplId.Invalid(), 0);
373  return;
374  }
375 
376  OnBeforeEntityCreatedServer(prefab);
377 
379  bool hasRecipients = false;
380  RplId currentLayerID;
381  array<SCR_EditableEntityComponent> entities = {};
382  if (recipientIds && !recipientIds.IsEmpty())
383  {
384  //--- Spawn entity for selected entities (e.g., waypoints for groups)
385  array<SCR_EditableEntityComponent> recipients = {};
386  foreach (RplId id: recipientIds)
387  {
388  SCR_EditableEntityComponent recipient = SCR_EditableEntityComponent.Cast(Replication.FindItem(id));
389  if (recipient)
390  recipients.Insert(recipient);
391  }
392  array<vector> offsets = GetOffsets(recipients.Count());
393  array<ref array<int>> distances = {};
394 
395  for (int i = 0; i < recipients.Count(); i++)
396  {
397  array<int> distToPosition = {};
398  vector position;
399  recipients[i].GetPos(position);
400  for (int j = 0; j < offsets.Count(); j++)
401  {
402  //precision to meters and 46km as max distance should be enough
403  distToPosition.Insert(Math.Clamp(vector.DistanceSq(position, offsets[j]), 0, int.MAX));
404  }
405  distances.Insert(distToPosition);
406  }
407 
408  // we try to minimize distances from groups to waypoints
409  // in general it produces paths with less scrossings between them
410  array<int> permutation = {};
411  AssignmentSolver.Solve(distances, permutation);
412 
413  foreach (int i, SCR_EditableEntityComponent recipient: recipients)
414  {
415  params.m_Offset = offsets[permutation[i]];
416  entity = SpawnEntityResource(params, prefabResource, playerID, isQueue, recipient, canBePlayer);
417  entities.Insert(entity);
418  entityIds.Insert(Replication.FindId(entity));
419  }
420  hasRecipients = true;
421  currentLayerID = Replication.FindId(recipients[0].GetParentEntity());
422  }
423  else
424  {
425  //--- Spawn stand-alone entity
426  entity = SpawnEntityResource(params, prefabResource, playerID, isQueue, null, canBePlayer);
427  entities.Insert(entity);
428  entityIds.Insert(Replication.FindId(entity));
429  currentLayerID = Replication.FindId(params.m_CurrentLayer);
430  }
431 
432  entity.OnCreatedServer(this);
433  OnEntityCreatedServer(entities);
434 
435  Rpc(CreateEntityOwner, prefabID, entityIds, entityIndex, isQueue, hasRecipients, currentLayerID, 0);
436  Event_OnPlaceEntityServer.Invoke(prefabID, entity, playerID);
437  }
438  [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
439  protected void CreateEntityOwner(int prefabID, array<RplId> entityIds, int entityIndex, int isQueue, bool hasRecipients, RplId currentLayerID, int attempt)
440  {
441  //~ Remove placing flag player
442  if (HasPlacingFlag(EEditorPlacingFlags.CHARACTER_PLAYER))
443  SetPlacingFlag(EEditorPlacingFlags.CHARACTER_PLAYER, false);
444 
445  //~ Todo: Make sure crew and Passenger que placing and placing again budget is updated correctly.
446  //~ Now if placing flag is active on start placing the budget is not correct. Same goes for queing
447  if (HasPlacingFlag(EEditorPlacingFlags.VEHICLE_CREWED))
448  SetPlacingFlag(EEditorPlacingFlags.VEHICLE_CREWED, false);
449  if (HasPlacingFlag(EEditorPlacingFlags.VEHICLE_PASSENGER))
450  SetPlacingFlag(EEditorPlacingFlags.VEHICLE_PASSENGER, false);
451 
452  //--- Delete the ghost preview which was waiting for server callback
453  IEntity waitingPreview;
454  if (m_WaitingPreviews.Find(entityIndex, waitingPreview))
455  {
456  m_WaitingPreviews.Remove(entityIndex);
457  delete waitingPreview;
458  }
459 
460  if (m_StatesManager && !m_StatesManager.SetIsWaiting(false))
461  {
462  SetSelectedPrefab();
463  return;
464  }
465 
466  set<SCR_EditableEntityComponent> entities = new set<SCR_EditableEntityComponent>();
468  for (int i, count = entityIds.Count(); i < count; i++)
469  {
470  entity = SCR_EditableEntityComponent.Cast(Replication.FindItem(entityIds[i]));
471  if (entity)
472  entities.Insert(entity);
473  }
474 
475  //--- Wait for entities to be streamed in
476  if (entities.IsEmpty())
477  {
478  if (attempt < 30)
479  {
480  GetGame().GetCallqueue().CallLater(CreateEntityOwner, 1, false, prefabID, entityIds, entityIndex, isQueue, hasRecipients, currentLayerID, attempt + 1);
481  }
482  else
483  {
484  SCR_PlacingEditorComponentClass prefabData = SCR_PlacingEditorComponentClass.Cast(GetEditorComponentData());
485  Print(string.Format("Error when creating entity from prefab '%1' (id = %2)!", prefabData.GetPrefab(prefabID), prefabID), LogLevel.ERROR);
486  }
487 
488  return;
489  }
490 
491  //--- Select placed entities
493  if (selectedFilter)
494  selectedFilter.Replace(entities);
495 
496  //--- Set current layer to be the parent of newly created entity, to make sure its icon is visible
497  SCR_EditableEntityComponent currentLayer = SCR_EditableEntityComponent.Cast(Replication.FindItem(currentLayerID));
498  if (!currentLayerID.IsValid() || currentLayer)
499  {
501  if (layerManager)
502  layerManager.SetCurrentLayer(currentLayer);
503  }
504 
505  //--- Delayed check if entity is within budget (character budget update is delayed)
506  if (isQueue)
507  {
508  GetGame().GetCallqueue().CallLater(CheckBudgetOwner, 100, false);
509  }
510  else
511  {
512  m_BudgetManager.ResetPreviewCost();
513  }
514 
515  //--- Call event
516  Event_OnPlaceEntity.Invoke(prefabID, entity);
517 
518  //--- Activate effects
519  vector pos;
520  entities[0].GetPos(pos);
521 
522  SCR_PlacingEditorComponentClass prefabData = SCR_PlacingEditorComponentClass.Cast(GetEditorComponentData());
523  if (prefabData) SCR_BaseEditorEffect.Activate(prefabData.GetEffectsPlaceConfirm(), this, pos, entities);
524  }
532  bool CanCreateEntity(out ENotification outNotification = -1, inout SCR_EPreviewState previewStateToShow = SCR_EPreviewState.PLACEABLE)
533  {
534  return !m_bBlockPlacing;
535  }
541  protected void OnBeforeEntityCreatedServer(ResourceName prefab);
547  protected void OnEntityCreatedServer(array<SCR_EditableEntityComponent> entities);
548 
549  protected void CheckBudgetOwner()
550  {
551  EEditableEntityBudget blockingBudget;
552  if (!CanSelectEntityPrefab(m_SelectedPrefab, blockingBudget, true))
553  {
554  m_BudgetManager.ResetPreviewCost();
555  SetSelectedPrefab(ResourceName.Empty, true);
556  }
557  }
558 
559  protected void OnBudgetMaxReached(EEditableEntityBudget entityBudget, bool maxReached)
560  {
561  if (maxReached)
562  SetSelectedPrefab(ResourceName.Empty, true);
563  }
564 
571  static SCR_EditableEntityComponent SpawnEntityResource(ResourceName prefab, vector transform[4])
572  {
573  return SpawnEntityResource(SCR_EditorPreviewParams.CreateParams(transform), Resource.Load(prefab));
574  }
584  static SCR_EditableEntityComponent SpawnEntityResource(SCR_EditorPreviewParams params, Resource prefabResource, int playerID = 0, bool isQueue = false, SCR_EditableEntityComponent recipient = null, bool canBePlayer = false)
585  {
586  if (Replication.IsClient() || !prefabResource|| !prefabResource.IsValid())
587  return null;
588 
589  //--- When spawning a player, get their respawn component first
590  EEditorPlacingFlags compatiblePlacingFlags = GetCompatiblePlacingFlags(prefabResource);
591  SCR_RespawnComponent respawnComponent;
592  if (canBePlayer)
593  {
594  respawnComponent = SCR_RespawnComponent.Cast(GetGame().GetPlayerManager().GetPlayerRespawnComponent(playerID));
595  if (!respawnComponent)
596  return null;
597  }
598 
599  IEntity owner;
600  if (params.m_TargetInteraction == EEditableEntityInteraction.SLOT)
601  {
602  //--- Create in slot
603  GenericEntity targetOwner = params.m_Target.GetOwner();
604  SCR_SiteSlotEntity slot = SCR_SiteSlotEntity.Cast(targetOwner);
605  if (slot)
606  {
607  //--- Use special slot function
608  owner = slot.SpawnEntityInSlot(prefabResource, Math3D.MatrixToAngles(params.m_vTransform)[0], -1/*verticalMode*/);
609  }
610  else
611  {
612  //--- Position on the target
613  EntitySpawnParams spawnParams = new EntitySpawnParams();
614  spawnParams.TransformMode = ETransformMode.WORLD;
615  targetOwner.GetWorldTransform(spawnParams.Transform);
616  owner = GetGame().SpawnEntityPrefab(prefabResource, GetGame().GetWorld(), spawnParams);
617  }
618  }
619  else
620  {
621  //--- Place freely
622  //SCR_AIGroup.IgnoreSnapToTerrain(true);
623  EntitySpawnParams spawnParams = new EntitySpawnParams();
624  spawnParams.TransformMode = ETransformMode.WORLD;
625  params.GetWorldTransform(spawnParams.Transform);
626  owner = GetGame().SpawnEntityPrefab(prefabResource, GetGame().GetWorld(), spawnParams);
627 
628  if (respawnComponent && SCR_Enum.HasFlag(compatiblePlacingFlags, EEditorPlacingFlags.CHARACTER_PLAYER))
629  {
630  SCR_PossessSpawnData spawnData = SCR_PossessSpawnData.FromEntity(owner);
631  if (!respawnComponent.RequestSpawn(spawnData))
632  Print(string.Format("@\"%1\" control cannot be given to playerID=%2, error in RequestSpawn!", prefabResource.GetResource().GetResourceName().GetPath(), playerID), LogLevel.ERROR);
633  }
634  }
635 
636  //--- Initialize
637  SCR_EditableEntityComponent entity = SCR_EditableEntityComponent.GetEditableEntity(owner);
638  if (!entity)
639  return null;
640 
641  SCR_EditableCommentComponent comment = SCR_EditableCommentComponent.Cast(params.m_Target);
642  SCR_CompositionSlotManagerComponent slotManager = SCR_CompositionSlotManagerComponent.GetInstance();
643  if (comment && slotManager)
644  slotManager.SetOccupant(comment.GetOwnerScripted(), owner);
645 
646  //--- Assign faction when placed for a recipient
647  if (recipient)
648  SCR_FactionAffiliationComponent.SetFaction(entity.GetOwner(), recipient.GetFaction());
649 
650  //--- Call custom event
651  SCR_EditableEntityComponent childEntity = entity.EOnEditorPlace(params.m_Parent, recipient, params.m_PlacingFlags, isQueue, playerID);
652 
653  //--- Set parent to current layer
654  if (params.m_Parent)
655  {
656  //~ Force entity as passenger
657  if (params.m_TargetInteraction == EEditableEntityInteraction.PASSENGER)
658  {
659  //~ Forces entities to be spawned into passenger positions
660  SCR_EditableVehicleComponent vehicle = SCR_EditableVehicleComponent.Cast(params.m_Parent);
661  if (vehicle)
662  entity.ForceVehicleCompartments(SCR_BaseCompartmentManagerComponent.PASSENGER_COMPARTMENT_TYPES);
663  }
664  //~ Not forced passenger set parent
665  else
666  {
667  childEntity.SetParentEntity(params.m_Parent);
668  }
669  }
670 
671  //--- New parent was created in EOnEditorPlace, reflect that
672  if (childEntity != entity)
673  params.m_Parent = childEntity;
674 
675  //--- Decide which layer should be set as current
676  params.m_CurrentLayer = childEntity.GetParentEntity();
677 
678  //--- Original entity deleted in SetParentEntity, use parent as the entity (e.g., when placing a group inside a group)
679  if (!owner)
680  entity = params.m_Parent;
681 
682  //--- Orient according to vertical settings
683  if (!entity.HasEntityFlag(EEditableEntityFlag.STATIC_POSITION))
684  {
686 
687  if (groupComp)
688  {
689  //GetGame().GetCallqueue().CallLater(SCR_RefPreviewEntity.SpawnAndApplyReference, 500, false, entity, params);
690 
691  SCR_AIGroup group = SCR_AIGroup.Cast(groupComp.GetOwnerScripted());
692  if (group)
693  {
694  m_DelayedSpawnEntity = entity;
695  m_DelayedSpawnPreviewParams = params;
696  group.GetOnAllDelayedEntitySpawned().Insert(OnAIGroupAllEntitiesSpawned);
697  }
698  }
699  else
700  {
701  SCR_RefPreviewEntity.SpawnAndApplyReference(entity, params);
702  }
703  }
704 
705  //--- Log message. Important for identifying problematic prefabs!
706  vector logTransform[4];
707  if (owner)
708  owner.GetWorldTransform(logTransform);
709  else
710  params.GetWorldTransform(logTransform);
711 
712 
713  if (recipient)
714  Print(string.Format("@\"%1\" placed for %3 at %2", prefabResource.GetResource().GetResourceName().GetPath(), logTransform, recipient.GetDisplayName()), LogLevel.VERBOSE);
715  else if (prefabResource)
716  Print(string.Format("@\"%1\" placed at %2", prefabResource.GetResource().GetResourceName().GetPath(), logTransform), LogLevel.VERBOSE);
717  else
718  Print(string.Format("@\"%1\" placed at %2", "Entity", logTransform), LogLevel.VERBOSE);
719 
720  return entity;
721  }
722 
723  //------------------------------------------------------------------------------------------------
725  protected static void OnAIGroupAllEntitiesSpawned(SCR_AIGroup group)
726  {
727  SCR_RefPreviewEntity.SpawnAndApplyReference(m_DelayedSpawnEntity, m_DelayedSpawnPreviewParams);
728 
729  // Cleanup
730  m_DelayedSpawnEntity = null;
731  m_DelayedSpawnPreviewParams = null;
732  group.GetOnAllDelayedEntitySpawned().Remove(OnAIGroupAllEntitiesSpawned);
733  }
734 
735  protected static EEditorPlacingFlags GetCompatiblePlacingFlags(Resource prefabResource)
736  {
737  IEntityComponentSource component = SCR_EditableEntityComponentClass.GetEditableEntitySource(prefabResource);
738 
739  switch (SCR_EditableEntityComponentClass.GetEntityType(component))
740  {
741  case EEditableEntityType.CHARACTER:
742  return EEditorPlacingFlags.CHARACTER_PLAYER;
743 
744  //~ Check if can spawn occupants within vehicle
745  case EEditableEntityType.VEHICLE:
746  {
748  if (!uiInfo)
749  return 0;
750 
751  EEditorPlacingFlags vehiclePlacingFlags = 0;
752 
753  //~ Check if can spawn with crew
754  if (uiInfo.CanFillWithCrew())
755  vehiclePlacingFlags |= EEditorPlacingFlags.VEHICLE_CREWED;
756 
757  //~ Check if can spawn with passengers
758  if (uiInfo.CanFillWithPassengers())
759  vehiclePlacingFlags |= EEditorPlacingFlags.VEHICLE_PASSENGER;
760 
761  return vehiclePlacingFlags;
762  }
763 
764  case EEditableEntityType.TASK:
765  return EEditorPlacingFlags.TASK_INACTIVE;
766  }
767  return 0;
768  }
769 
770  protected bool CanPlaceEntityServer(IEntityComponentSource editableEntitySource, out EEditableEntityBudget blockingBudget, bool updatePreview, bool showNotification)
771  {
772  if (!m_BudgetManager)
773  {
774  m_BudgetManager = SCR_BudgetEditorComponent.Cast(FindEditorComponent(SCR_BudgetEditorComponent, false, true));
775  if (!m_BudgetManager)
776  return true;
777  }
778 
779  return m_BudgetManager.CanPlaceEntitySource(editableEntitySource, blockingBudget, HasPlacingFlag(EEditorPlacingFlags.CHARACTER_PLAYER), updatePreview, showNotification);
780  }
781 
782  protected bool CanSelectEntityPrefab(ResourceName prefab, out EEditableEntityBudget blockingBudget, bool updatePreview = true, bool showBudgetMaxNotification = true)
783  {
784  if (!m_BudgetManager || prefab.IsEmpty())
785  return false;
786 
787  // Load prefab to check entity budgets or entity type
788  Resource entityPrefab = Resource.Load(prefab);
789  // Get entity source
790  IEntitySource entitySource = SCR_BaseContainerTools.FindEntitySource(entityPrefab);
791  IEntityComponentSource editableEntitySource = SCR_EditableEntityComponentClass.GetEditableEntitySource(entitySource);
792 
793  return CanPlaceEntityServer(editableEntitySource, blockingBudget, updatePreview, showBudgetMaxNotification);
794  }
795 
796  protected array<vector> GetOffsets(int count)
797  {
798  array<vector> result = {};
799  if (count == 0)
800  return result;
801 
802  if (count == 1)
803  {
804  result.Insert(vector.Zero);
805  return result;
806  }
807 
808  int rowCount = Math.Round(Math.Sqrt(count));
809  int columnCount = Math.Ceil(Math.Sqrt(count));
810  vector offset = -Vector((rowCount - 1) * m_fSpacing / 2, 0, (columnCount - 1) * m_fSpacing / 2);
811 
812  int row, column;
813  for (int i = 0; i < count; i++)
814  {
815  row = Math.Floor(i / columnCount);
816  column = i % columnCount;
817  result.Insert(offset + Vector(row * m_fSpacing, 0, column * m_fSpacing));
818  }
819  return result;
820  }
821  protected void OnEntityUnregistered(SCR_EditableEntityComponent entity)
822  {
823  int index = m_Recipients.Find(entity);
824  if (index >= 0)
825  {
826  m_Recipients.Remove(index);
827 
828  //--- No remaining recipients, stop placing
829  if (m_Recipients.IsEmpty())
830  SetSelectedPrefab();
831  }
832  }
833 
839  void SetInstantPlacing(SCR_EditorPreviewParams param)
840  {
841  m_InstantPlacingParam = param;
842  }
843 
849  bool SetSelectedPrefab(ResourceName prefab = "", bool onConfirm = false, bool showBudgetMaxNotification = true, set<SCR_EditableEntityComponent> recipients = null)
850  {
851  if (prefab == m_SelectedPrefab) return true;
852 
853  //--- Check if entity is within budget
854  EEditableEntityBudget blockingBudget;
855  if (!prefab.IsEmpty() && !CanSelectEntityPrefab(prefab, blockingBudget, showBudgetMaxNotification))
856  {
857  return false;
858  }
859 
860  //--- Place instantly
861  if (m_InstantPlacingParam && !prefab.IsEmpty())
862  {
863  //--- This will prevent m_StatesManager.SetIsWaiting(false) from failing in CreateEntityOwner()
864  m_StatesManager.SetSafeDialog(true);
865  m_SelectedPrefab = prefab;
866  m_Recipients = recipients;
867  CreateEntity();
868  return true;
869  }
870 
871  //--- Check if the prefab is registered
872  SCR_PlacingEditorComponentClass prefabData = SCR_PlacingEditorComponentClass.Cast(GetEditorComponentData());
873  if (!prefab.IsEmpty() && prefabData.GetPrefabID(prefab) == -1)
874  {
875  Print(string.Format("Cannot initiate placing of prefab @\"%1\", it's not registered in placeable entities!", prefab), LogLevel.WARNING);
876  return false;
877  }
878 
879  if (prefab.IsEmpty() || HasPlacingFlag(EEditorPlacingFlags.CHARACTER_PLAYER))
880  {
881  m_BudgetManager.ResetPreviewCost();
882  }
883 
884  if (m_StatesManager)
885  {
886  if (prefab)
887  {
888  if (!m_StatesManager.SetState(EEditorState.PLACING)) return false; //--- Exit when cannot set placing state
889  }
890  else
891  {
892  m_StatesManager.UnsetState(EEditorState.PLACING);
893  }
894  }
895 
896  //--- Track if recipients are deleted (stop placing when no recipient remains)
897  if (prefab && recipients)
898  {
900  core.Event_OnEntityUnregistered.Insert(OnEntityUnregistered);
901  }
902  else if (!prefab && m_Recipients)
903  {
905  core.Event_OnEntityUnregistered.Remove(OnEntityUnregistered);
906  }
907 
908  //--- Set the prefab
909  ResourceName prefabPrev = m_SelectedPrefab;
910  m_SelectedPrefab = prefab;
911  m_Recipients = recipients;
912 
913  //--- Create preview entity
914  int instanceCount = 1;
915  if (recipients) instanceCount = recipients.Count();
916  IEntity previewEntity = m_PreviewManager.CreatePreview(prefab, GetOffsets(instanceCount));//, fixedTransform);
917 
918  if (previewEntity)
919  {
920  //--- Teleport camera to fixed position
921  if (m_PreviewManager.IsFixedPosition())
922  {
923  SCR_ManualCamera camera = SCR_CameraEditorComponent.GetCameraInstance();
924  if (camera)
925  {
927  if (teleportComponent) teleportComponent.TeleportCamera(previewEntity.GetOrigin(), true, true);
928  }
929  }
930  m_CompatiblePlacingFlags = GetCompatiblePlacingFlags(Resource.Load(m_SelectedPrefab));
931  }
932  else
933  {
934  SetPlacingFlag(EEditorPlacingFlags.CHARACTER_PLAYER, false);
935  }
936 
937  //--- Call event handlers
938  Event_OnSelectedPrefabChange.Invoke(prefab, prefabPrev);
939 
940  if (prefab && !prefabPrev)
941  SCR_BaseEditorEffect.Activate(prefabData.GetEffectsPlaceStart(), this);
942  else if (!prefab && prefabPrev && !onConfirm)
943  SCR_BaseEditorEffect.Activate(prefabData.GetEffectsPlaceCancel(), this);
944 
945  return true;
946  }
951  ResourceName GetSelectedPrefab()
952  {
953  return m_SelectedPrefab;
954  }
955  bool IsPlacing()
956  {
957  return !m_SelectedPrefab.IsEmpty();
958  }
963  void SetSlot(SCR_SiteSlotEntity slot)
964  {
965  m_Slot = slot;
966  }
971  SCR_SiteSlotEntity GetSlot()
972  {
973  return m_Slot;
974  }
980  void SetPlacingFlag(EEditorPlacingFlags flag, bool toAdd)
981  {
982  //--- When enabling, check if it's allowed (disabloing is always possible)
983  if (toAdd && !IsPlacingFlagAllowed(flag))
984  {
985  Print(string.Format("Cannot enable placing flag %1, placing manager does not allow it!", typename.EnumToString(EEditorPlacingFlags, flag)), LogLevel.WARNING);
986  return;
987  }
988 
989  //--- Set the state
990  EEditorPlacingFlags prevPlacingFlag = m_PlacingFlags;
991  if (toAdd)
992  m_PlacingFlags |= flag;
993  else
994  m_PlacingFlags &= ~flag;
995 
996  //--- If there was a change, call event
997  if (m_PlacingFlags != prevPlacingFlag)
998  Event_OnPlacingFlagsChange.Invoke(flag, toAdd);
999 
1000  //~ Exception - update budget preview when placing as player or placing occupied vehicle
1001  UpdatePlacingFlagBudget(m_SelectedPrefab, flag, m_PlacingFlags, prevPlacingFlag);
1002  }
1003 
1011  protected void UpdatePlacingFlagBudget(ResourceName selectedPrefab, EEditorPlacingFlags flagChanged, EEditorPlacingFlags currentPlacingFlag, EEditorPlacingFlags prevPlacingFlag)
1012  {
1013  if (m_SelectedPrefab.IsEmpty())
1014  return;
1015 
1016  if (flagChanged == EEditorPlacingFlags.CHARACTER_PLAYER)
1017  {
1018  bool isPlacingPlayer = SCR_Enum.HasFlag(currentPlacingFlag, EEditorPlacingFlags.CHARACTER_PLAYER);
1019  EEditableEntityBudget blockingBudget;
1020  Resource resource = Resource.Load(selectedPrefab);
1021  if (!resource.IsValid())
1022  {
1023  Print("Cannot load " + selectedPrefab + " | " + FilePath.StripPath(__FILE__) + ":" + __LINE__, LogLevel.WARNING);
1024  return;
1025  }
1026 
1027  m_BudgetManager.CanPlaceEntitySource(SCR_EditableEntityComponentClass.GetEditableEntitySource(resource.GetResource().ToEntitySource()), blockingBudget, isPlacingPlayer);
1028  }
1029 
1030  if ((currentPlacingFlag & EEditorPlacingFlags.VEHICLE_CREWED || currentPlacingFlag & EEditorPlacingFlags.VEHICLE_PASSENGER) || (prevPlacingFlag & EEditorPlacingFlags.VEHICLE_CREWED || prevPlacingFlag & EEditorPlacingFlags.VEHICLE_PASSENGER))
1031  {
1032  array<ref SCR_EntityBudgetValue> budgetCosts = {};
1033  Resource resource = Resource.Load(selectedPrefab);
1034  if ( !resource.IsValid())
1035  {
1036  Print("Cannot load " + selectedPrefab + " | " + FilePath.StripPath(__FILE__) + ":" + __LINE__, LogLevel.WARNING);
1037  return;
1038  }
1039 
1040  IEntityComponentSource source = SCR_EditableEntityComponentClass.GetEditableEntitySource(resource.GetResource().ToEntitySource());
1041  m_BudgetManager.GetVehicleOccupiedBudgetCosts(source, currentPlacingFlag, budgetCosts);
1042  m_BudgetManager.UpdatePreviewCost(budgetCosts);
1043  }
1044  }
1045 
1050  void TogglePlacingFlag(EEditorPlacingFlags flag)
1051  {
1052  SetPlacingFlag(flag, !HasPlacingFlag(flag));
1053  }
1059  bool HasPlacingFlag(EEditorPlacingFlags flag)
1060  {
1061  return SCR_Enum.HasFlag(m_PlacingFlags, flag);
1062  }
1068  bool IsPlacingFlagCompatible(EEditorPlacingFlags flag)
1069  {
1070  return SCR_Enum.HasFlag(m_CompatiblePlacingFlags, flag);
1071  }
1077  bool IsPlacingFlagAllowed(EEditorPlacingFlags flag)
1078  {
1079  SCR_PlacingEditorComponentClass prefabData = SCR_PlacingEditorComponentClass.Cast(GetEditorComponentData());
1080  return prefabData && prefabData.HasPlacingFlag(flag);
1081  }
1086  ScriptInvoker GetOnSelectedPrefabChange()
1087  {
1088  return Event_OnSelectedPrefabChange;
1089  }
1095  ScriptInvoker GetOnPlacingFlagsChange()
1096  {
1097  return Event_OnPlacingFlagsChange;
1098  }
1104  ScriptInvoker GetOnRequestEntity()
1105  {
1106  return Event_OnRequestEntity;
1107  }
1113  ScriptInvoker GetOnPlaceEntity()
1114  {
1115  return Event_OnPlaceEntity;
1116  }
1117 
1118  ScriptInvoker GetOnPlaceEntityServer()
1119  {
1120  return Event_OnPlaceEntityServer;
1121  }
1122 
1123  override void EOnEditorDebug(array<string> debugTexts)
1124  {
1125  if (!IsActive()) return;
1126  if (m_SelectedPrefab)
1127  {
1128  debugTexts.Insert(string.Format("Placing prefab: %1", FilePath.StripPath(m_SelectedPrefab.GetPath())));
1129  }
1130  else
1131  {
1132  debugTexts.Insert("Placing prefab: N/A");
1133  }
1134  debugTexts.Insert(string.Format("Placing flags: %1", SCR_Enum.FlagsToString(EEditorPlacingFlags, m_PlacingFlags)));
1135  }
1136  override void EOnEditorActivate()
1137  {
1140  m_BudgetManager = SCR_BudgetEditorComponent.Cast(FindEditorComponent(SCR_BudgetEditorComponent, false, true));
1141  if (m_BudgetManager)
1142  {
1143  m_BudgetManager.Event_OnBudgetMaxReached.Insert(OnBudgetMaxReached);
1144  }
1145 
1146  SCR_PlacingEditorComponentClass prefabData = SCR_PlacingEditorComponentClass.Cast(GetEditorComponentData());
1147  }
1148 
1149  override void EOnEditorDeactivate()
1150  {
1151  m_SelectedPrefab = ResourceName.Empty;
1152 
1153  if (m_BudgetManager)
1154  {
1155  m_BudgetManager.Event_OnBudgetMaxReached.Remove(OnBudgetMaxReached);
1156  }
1157  }
1158 };
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
EEditableEntityState
EEditableEntityState
Definition: EEditableEntityState.c:37
EEditableEntityInteraction
EEditableEntityInteraction
Type of suggested interaction when hovering edited entity on top of another entity.
Definition: EEditableEntityInteraction.c:5
EEditableEntityFlag
EEditableEntityFlag
Unique flags of the entity.
Definition: EEditableEntityFlag.c:5
SCR_ManualCamera
Definition: SCR_ManualCamera.c:16
SCR_EditableEntityCore
Definition: SCR_EditableEntityCore.c:10
SCR_RespawnComponent
void SCR_RespawnComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_RespawnComponent.c:576
SCR_Enum
Definition: SCR_Enum.c:1
m_StatesManager
private SCR_StatesEditorComponent m_StatesManager
Definition: SCR_AttributesManagerEditorComponent.c:65
EEditorState
EEditorState
Unique editor state.
Definition: EEditorState.c:5
GetInstance
SCR_TextsTaskManagerComponentClass ScriptComponentClass GetInstance()
Definition: SCR_TextsTaskManagerComponent.c:50
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_CameraEditorComponent
Definition: SCR_CameraEditorComponent.c:13
m_PreviewManager
private SCR_PreviewEntityEditorComponent m_PreviewManager
Definition: SCR_CursorEditorUIComponent.c:22
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
SCR_EditableGroupComponent
void SCR_EditableGroupComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_EditableGroupComponent.c:703
SCR_EPreviewState
SCR_EPreviewState
Definition: SCR_PreviewEntityEditorComponent.c:1138
RplRpc
SCR_AchievementsHandlerClass ScriptComponentClass RplRpc(RplChannel.Reliable, RplRcver.Owner)] void UnlockOnClient(AchievementId achievement)
Definition: SCR_AchievementsHandler.c:11
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
EEditableEntityBudget
EEditableEntityBudget
Definition: EEditableEntityBudget.c:1
SCR_BudgetEditorComponent
Definition: SCR_BudgetEditorComponent.c:18
ENotification
ENotification
Definition: ENotification.c:4
IsProxy
protected bool IsProxy()
Definition: SCR_CampaignBuildingCompositionComponent.c:456
SCR_BaseEditorComponent
Definition: SCR_BaseEditorComponent.c:119
Attribute
typedef Attribute
Post-process effect of scripted camera.
EEditableEntityType
EEditableEntityType
Defines type of SCR_EditableEntityComponent. Assigned automatically based on IEntity inheritance.
Definition: EEditableEntityType.c:5
SendNotification
protected void SendNotification(int msgId, notnull IEntity user, int assetId=-1, int catalogType=-1)
Definition: SCR_CatalogEntitySpawnerComponent.c:819
EEditorPlacingFlags
EEditorPlacingFlags
Definition: EEditorPlacingFlags.c:1
SCR_BaseEditableEntityFilter
Definition: SCR_BaseEditableEntityFilter.c:13
SCR_BaseEditorComponentClass
Definition: SCR_BaseEditorComponent.c:2
SCR_EditableEntityComponent
Definition: SCR_EditableEntityComponent.c:13
SCR_BaseContainerTools
Definition: SCR_BaseContainerTools.c:3
index
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Definition: SCR_DestructionSynchronizationComponent.c:17
SCR_LayersEditorComponent
Definition: SCR_LayersEditorManager.c:11
SCR_SiteSlotEntity
Definition: SCR_SiteSlotEntity.c:26
SCR_PlaceableEntitiesRegistry
Definition: SCR_PlaceableEntitiesRegistry.c:8
SCR_AIGroup
Definition: SCR_AIGroup.c:68
SCR_TeleportToCursorManualCameraComponent
Teleport the camera to the cursor's world position.
Definition: SCR_TeleportToCursorManualCameraComponent.c:5
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
SCR_FactionAffiliationComponent
Definition: SCR_FactionAffiliationComponent.c:10
SCR_StatesEditorComponent
Definition: SCR_StatesEditorComponent.c:9
SCR_RefPreviewEntity
Definition: SCR_RefPreviewEntity.c:10
SCR_PossessSpawnData
Definition: SCR_PossessSpawnData.c:2
IsValid
override bool IsValid(IEntity actionOwner, IEntity actionUser, SCR_BaseUseSupportStationAction action, vector actionPosition, out ESupportStationReasonInvalid reasonInvalid, out int supplyCost)
Definition: SCR_BaseDamageHealSupportStationComponent.c:98
SCR_EditableEntityComponentClass
Definition: SCR_EditableEntityComponentClass.c:2
SCR_DebugMenuID
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition: DebugMenuID.c:3
SCR_PlacingEditorComponent
Definition: SCR_PlacingEditorComponent.c:118
position
vector position
Definition: SCR_DestructibleTreeV2.c:30
IsActive
bool IsActive()
Definition: SCR_LoadoutSaveBlackListHolder.c:82
SCR_EditorPreviewParams
Network packet of variables for entity placing and transformation.
Definition: SCR_EditorPreviewParams.c:4
m_Slot
protected SCR_SiteSlotEntity m_Slot
Definition: SCR_CampaignServiceCompositionComponent.c:16
SCR_BaseEditorEffect
Definition: SCR_BaseEditorEffect.c:7
SCR_PlacingEditorComponentClass
Definition: SCR_PlacingEditorComponent.c:2
SCR_PreviewEntityEditorComponent
Definition: SCR_PreviewEntityEditorComponent.c:12
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180
SCR_EditableVehicleUIInfo
Definition: SCR_EditableVehicleUIInfo.c:2