Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_EditableEntityStruct.c
Go to the documentation of this file.
1 
7 {
8  //--- Constants
9  protected static const int TARGET_NONE = -1;
10  protected static const int TARGET_SLOT = -2;
11 
12  //--- Serialized (names shortened to save memory)
13  protected ResourceName pf; //--- Prefab
14  protected bool hy; //--- Was hierarchy changed by user
15  protected EEditableEntityFlag ef; //--- EEditableEntityFlag
16  protected int pi = -1; //--- Parent ID
17  protected int ti = TARGET_NONE; //--- Target ID
18  protected int tv = -1; //--- Target value
19  protected float px; //--- Pos X
20  protected float py; //--- Pos Y
21  protected float pz; //--- Pos Y
22  protected float qx; //--- Quaternion X
23  protected float qy; //--- Quaternion Y
24  protected float qz; //--- Quaternion Z
25  protected float qw; //--- Quaternion W
26  protected float sc; //--- Scale
27  protected ref array<ref SCR_EditorAttributeStruct> at = {}; //--- Attributes
28 
29  //--- Non-serialized
30  protected SCR_EditableEntityComponent m_Entity;
31  protected SCR_EditableEntityComponent m_Target;
32  protected static SCR_CompositionSlotManagerComponent m_SlotManager;
33  protected static IEntity m_PlayerEntity;
34 
40  static void SerializeEntities(out notnull array<ref SCR_EditableEntityStruct> outEntries, SCR_EditorAttributeList attributeList, EEditableEntityFlag requiredFlags)
41  {
42  //--- Clear existing array
43  outEntries.Clear();
44 
45  //--- Get root entities
46  set<SCR_EditableEntityComponent> children;
48  if (core)
49  {
50  children = new set<SCR_EditableEntityComponent>();
51  core.GetAllEntities(children, true);
52  }
53  m_SlotManager = SCR_CompositionSlotManagerComponent.GetInstance();
54 
55  //--- Process root entities
56  array<int> entriesWithTarget = {};
57  foreach (SCR_EditableEntityComponent child: children)
58  {
59  SerializeEntity(child, -1, outEntries, attributeList, requiredFlags, entriesWithTarget, false);
60  }
61 
62  //--- Link attached entities together (only after all of them were registered)
63  int entriesCount = outEntries.Count();
65  for (int i = 0, count = entriesWithTarget.Count(); i < count; i++)
66  {
67  entry = outEntries[entriesWithTarget[i]];
68  for (int e = 0; e < entriesCount; e++)
69  {
70  if (entry.m_Target == outEntries[e].m_Entity)
71  {
72  entry.ti = e;
73  break;
74  }
75  }
76  if (entry.ti == TARGET_NONE)
77  entry.m_Entity.Log("Error when serializing attach link!", true, LogLevel.WARNING);
78  }
79  m_SlotManager = null;
80  }
81  protected static void SerializeEntity(SCR_EditableEntityComponent entity, int parentID, out notnull array<ref SCR_EditableEntityStruct> outEntries, SCR_EditorAttributeList attributeList, EEditableEntityFlag requiredFlags, out array<int> entriesWithTarget, bool isParentDirty)
82  {
83  if (requiredFlags != 0 && !entity.HasEntityFlag(requiredFlags))
84  return;
85 
87  int targetValue = TARGET_NONE;
88  EEditableEntitySaveFlag saveFlags = 0;
89  if (!entity.Serialize(target, targetValue, saveFlags))
90  return;
91 
92  //--- Only placeable entities can have dirty hierarchy, artifically created ones (e.g., custom layer) are exempted
93  bool canBeDirty = entity.HasEntityFlag(EEditableEntityFlag.PLACEABLE);
94 
96  entry.m_Entity = entity;
97  entry.pi = parentID;
98  parentID = outEntries.Insert(entry);
99 
100  entry.pf = entity.GetPrefab(true);
101 
102  if (saveFlags != 0)
103  entry.pf += saveFlags.ToString();
104 
105  entry.sc = entity.GetOwner().GetScale();
106  entry.hy = isParentDirty || entity.HasEntityFlag(EEditableEntityFlag.INDIVIDUAL_CHILDREN) || entity.HasEntityFlag(EEditableEntityFlag.DIRTY_HIERARCHY);
107  entry.ef = entity.GetEntityFlags();
108 
109  vector transform[4];
110  entity.GetOwner().GetWorldTransform(transform);
111  entry.px = transform[3][0];
112  entry.py = transform[3][1];
113  entry.pz = transform[3][2];
114 
115  float quat[4];
116  Math3D.MatrixToQuat(transform, quat);
117  entry.qx = quat[0];
118  entry.qy = quat[1];
119  entry.qz = quat[2];
120  entry.qw = quat[3];
121 
122  entry.tv = targetValue; //--- Assigned even when target is not, some entities may use it for other purposes (e.g., task faction)
123  if (target)
124  {
125  entry.m_Target = target;
126  entriesWithTarget.Insert(parentID);
127  }
128  else if (m_SlotManager)
129  {
130  SCR_EditableEntityUIInfo info = SCR_EditableEntityUIInfo.Cast(entity.GetInfo());
131  if (info && info.GetSlotPrefab() && m_SlotManager.IsInSlot(entity.GetOwner()))
132  entry.ti = TARGET_SLOT;
133  }
134 
135  SCR_EditorAttributeStruct.SerializeAttributes(entry.at, attributeList, entity);
136 
137  //--- Process children if the composition is dirty or artificially created (i.e., non-placeable)
138  if (entry.hy || !canBeDirty)
139  {
140  for (int c = 0, count = entity.GetChildrenCount(true); c < count; c++)
141  {
142  SerializeEntity(entity.GetChild(c), parentID, outEntries, attributeList, requiredFlags, entriesWithTarget, entry.hy && canBeDirty);
143  }
144  }
145  }
151  static void DeserializeEntities(notnull array<ref SCR_EditableEntityStruct> entries, SCR_EditorAttributeList attributeList = null)
152  {
153  SCR_CompositionSlotManagerComponent slotManager = SCR_CompositionSlotManagerComponent.GetInstance();
154 
156  map<int, SCR_EditableEntityComponent> entities = new map<int, SCR_EditableEntityComponent>();
157  array<int> entriesWithTarget = {};
158  foreach (int id, SCR_EditableEntityStruct entry: entries)
159  {
160  //--- Extract optional params (encoded in prefab name, so they don't need a variable in every struct)
161  ResourceName prefab = entry.pf;
162  EEditableEntitySaveFlag saveFlags = 0;
163  "{"; // fix indent
164  int guidIndex = prefab.LastIndexOf("}") + 1;
165  int prefabParamsCount = prefab.Length() - guidIndex;
166  if (prefabParamsCount > 0)
167  {
168  string prefabParams = prefab.Substring(guidIndex, prefabParamsCount);
169  saveFlags = prefabParams.ToInt();
170  prefab = prefab.Substring(0, guidIndex);
171  }
172 
173  //--- Don't spawn SP player entity in MP
174  if (Replication.IsRunning() && (saveFlags & EEditableEntitySaveFlag.PLAYER))
175  continue;
176 
177  if (entry.pi != -1)
178  {
179  if (!entities.Find(entry.pi, parent))
180  {
181  Print(string.Format("SCR_EditableEntityStruct: Error when spawning entity @\"%1\", parent with ID %2 not found!", entry.pf, entry.pi), LogLevel.WARNING);
182  continue;
183  }
184  }
185  else
186  {
187  parent = null;
188  }
189 
190  EntitySpawnParams spawnParams = new EntitySpawnParams();
191 
192  float quat[4];
193  quat[0] = entry.qx;
194  quat[1] = entry.qy;
195  quat[2] = entry.qz;
196  quat[3] = entry.qw;
197  Math3D.QuatToMatrix(quat, spawnParams.Transform);
198  spawnParams.Transform[3] = Vector(entry.px, entry.py, entry.pz);// + Vector(10, 0, 0); //--- DEBUG OFFSET
199  spawnParams.TransformMode = ETransformMode.WORLD;
200 
201  SCR_EditorLinkComponent.IgnoreSpawning(SCR_Enum.HasFlag(entry.ef, EEditableEntityFlag.SPAWN_UNFINISHED));
202  SCR_AIGroup.IgnoreSpawning(true);
203 
204  if (saveFlags & EEditableEntitySaveFlag.NOT_SPAWNED)
205  SCR_EditorLinkComponent.IgnoreSpawning(true);
206 
207  IEntity rawEntity = GetGame().SpawnEntityPrefab(Resource.Load(prefab), GetGame().GetWorld(), spawnParams);
208  entry.m_Entity = SCR_EditableEntityComponent.GetEditableEntity(rawEntity);
209  if (entry.m_Entity)
210  {
211  entities.Insert(id, entry.m_Entity);
212 
213  rawEntity.SetScale(entry.sc);
214  entry.m_Entity.EOnEditorSessionLoad(parent);
215  entry.m_Entity.SetParentEntity(parent);
216  if (entry.hy)
217  entry.m_Entity.SetHierarchyAsDirty();
218 
219  entry.m_Entity.CopyEntityFlags(entry.ef);
220 
221  SCR_EditorAttributeStruct.DeserializeAttributes(entry.at, attributeList, entry.m_Entity);
222 
223  if (entry.ti != TARGET_NONE)
224  {
225  if (entry.ti == TARGET_SLOT)
226  slotManager.SetOccupant(spawnParams.Transform[3], rawEntity);
227  else
228  entriesWithTarget.Insert(id);
229  }
230 
231  if (!Replication.IsRunning() && (saveFlags & EEditableEntitySaveFlag.PLAYER))
232  {
233  m_PlayerEntity = rawEntity;
234  RequestLocalPlayerSpawn(SCR_PlayerController.GetLocalPlayerId());
235  }
236 
237  if (saveFlags & EEditableEntitySaveFlag.DESTROYED)
238  {
239  entry.m_Entity.Destroy();
240  }
241 
242  Print(string.Format("SCR_EditableEntityStruct: Entity @\"%1\" spawned at %2 as a child of %3", entry.pf, spawnParams.Transform, parent), LogLevel.VERBOSE);
243  }
244  else
245  {
246  SCR_EntityHelper.DeleteEntityAndChildren(rawEntity);
247  Print(string.Format("SCR_EditableEntityStruct: Error when spawning entity @\"%1\" at %2, SCR_EditableEntityComponent not found!", entry.pf, spawnParams.Transform, parent), LogLevel.WARNING);
248  }
249  }
250 
251  //--- Once all entities were spawned, call Deserialize() on them
252  foreach (int id, SCR_EditableEntityStruct entry: entries)
253  {
254  if (entriesWithTarget.Contains(id))
255  entry.m_Entity.Deserialize(entries[entry.ti].m_Entity, entry.tv); //--- Link attached entities together (e.g., crew in vehicles)
256  else
257  entry.m_Entity.Deserialize(null, entry.tv);
258  }
259 
260  SCR_EditorLinkComponent.IgnoreSpawning(false);
261  SCR_AIGroup.IgnoreSpawning(false);
262  }
263  protected static void RequestLocalPlayerSpawn(int playerId)
264  {
265  SCR_RespawnComponent respawnComponent = SCR_RespawnComponent.Cast(GetGame().GetPlayerManager().GetPlayerRespawnComponent(playerId));
266  if (respawnComponent)
267  {
268  //--- Assign player comtrol using respawn system
269  SCR_PossessSpawnData spawnData = SCR_PossessSpawnData.FromEntity(m_PlayerEntity);
270  respawnComponent.RequestSpawn(spawnData);
271  }
272  else
273  {
274  //--- Player not initialized yet, do so once that happens
276  if (gameMode)
277  gameMode.GetOnPlayerRegistered().Insert(RequestLocalPlayerSpawn);
278  }
279  }
284  static void ClearEntities(notnull array<ref SCR_EditableEntityStruct> entries)
285  {
286  for (int i = 0, count = entries.Count(); i < count; i++)
287  {
288  if (entries[i].m_Entity)
289  entries[i].m_Entity.Delete();
290  }
291  }
297  static void LogEntities(notnull array<ref SCR_EditableEntityStruct> entries, SCR_EditorAttributeList attributeList = null)
298  {
299  Print(" SCR_EditableEntityStruct: " + entries.Count());
300  //string textDefault = " %1: %2 | file: %3 | pos: %4 | ang: %5 | scl: %6 | drt: %9 | tgt: N/A (#%8)";
301  //string textTarget = " %1: %2 | file: %3 | pos: %4 | ang: %5 | scl: %6 | drt: %9 | tgt: %7 (#%8)";
302  float quat[4];
303  vector angles;
304  Resource resource;
305  string resourceName;
306  foreach (int id, SCR_EditableEntityStruct entry: entries)
307  {
308  quat[0] = entry.qx;
309  quat[1] = entry.qy;
310  quat[2] = entry.qz;
311  quat[3] = entry.qw;
312  angles = Math3D.QuatToAngles(quat);
313 
314  //--- Get flags
315  ResourceName prefab = entry.pf;
316  EEditableEntitySaveFlag saveFlags = 0;
317  "{"; // fix indent
318  int guidIndex = prefab.LastIndexOf("}") + 1;
319  int prefabParamsCount = prefab.Length() - guidIndex;
320  if (prefabParamsCount > 0)
321  {
322  string prefabParams = prefab.Substring(guidIndex, prefabParamsCount);
323  saveFlags = prefabParams.ToInt();
324  }
325 
326  resource = Resource.Load(entry.pf);
327  resourceName = resource.GetResource().GetResourceName();
328 
329  /*
330  if (entry.ti != TARGET_NONE)
331  PrintFormat(textTarget, id, entry.pi, FilePath.StripPath(resourceName), Vector(entry.px, entry.py, entry.pz), angles, entry.sc, entry.ti, entry.tv, entry.hy);
332  else
333  PrintFormat(textDefault, id, entry.pi, FilePath.StripPath(resourceName), Vector(entry.px, entry.py, entry.pz), angles, entry.sc, entry.ti, entry.tv, entry.hy);
334  */
335 
336  string result = " " + id + ": " + entry.pi;
337  result += " | " + FilePath.StripPath(resourceName);
338  result += " | pos: " + Vector(entry.px, entry.py, entry.pz);
339  result += " | ang: " + angles;
340  result += " | scl: " + entry.sc;
341  result += " | flg: " + SCR_Enum.FlagsToString(EEditableEntitySaveFlag, saveFlags);
342  result += " | drt: " + entry.hy;
343 
344  if (entry.ti == TARGET_NONE)
345  result += " | tgt: N/A";
346  else
347  result += " | tgt: " + entry.ti;
348 
349  result += " (#" + entry.tv + ")";
350 
351  Print("" + result);
352 
353  SCR_EditorAttributeStruct.LogAttributes(entry.at, attributeList, " ");
354  }
355  }
356  /*
357  override void OnExpand()
358  {
359  Print("OnExpand()");
360  }
361  override void OnPack()
362  {
363  Print("OnPack()");
364  }
365  override void OnSuccess(int errorCode)
366  {
367  Print("OnSuccess() = " + errorCode);
368  }
369  override void OnError(int errorCode)
370  {
371  Print("OnError() = " + errorCode);
372  }
373  */
375  {
376  RegV("pf");
377  RegV("ef");
378  RegV("hy");
379  RegV("pi");
380  RegV("ti");
381  RegV("tv");
382  RegV("px");
383  RegV("py");
384  RegV("pz");
385  RegV("qx");
386  RegV("qy");
387  RegV("qz");
388  RegV("qw");
389  RegV("sc");
390  RegV("at");
391  }
392 };
SCR_BaseGameMode
Definition: SCR_BaseGameMode.c:137
EEditableEntityFlag
EEditableEntityFlag
Unique flags of the entity.
Definition: EEditableEntityFlag.c:5
SCR_EditableEntityCore
Definition: SCR_EditableEntityCore.c:10
SCR_RespawnComponent
void SCR_RespawnComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_RespawnComponent.c:576
SCR_PlayerController
Definition: SCR_PlayerController.c:31
SCR_EntityHelper
Definition: SCR_EntityHelper.c:1
SCR_Enum
Definition: SCR_Enum.c:1
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
JsonApiStruct
Parameters for joining server.
Definition: FeedbackDialogUI.c:2
SCR_EditableEntityUIInfo
Definition: SCR_EditableEntityUIInfo.c:2
m_Entity
enum EAITargetInfoCategory m_Entity
GetGameMode
SCR_BaseGameMode GetGameMode()
Definition: SCR_BaseGameModeComponent.c:15
m_SlotManager
SCR_SlotServiceComponentClass m_SlotManager
Service with basic slot handling functionalities.
SCR_EditorAttributeList
Definition: SCR_EditorAttributeConfig.c:2
SCR_EditableEntityComponent
Definition: SCR_EditableEntityComponent.c:13
SCR_EditableEntityStruct
Definition: SCR_EditableEntityStruct.c:6
EEditableEntitySaveFlag
EEditableEntitySaveFlag
Definition: EEditableEntitySaveFlag.c:9
SCR_AIGroup
Definition: SCR_AIGroup.c:68
SCR_EditorAttributeStruct
Definition: SCR_EditorAttributeStruct.c:6
SCR_PossessSpawnData
Definition: SCR_PossessSpawnData.c:2