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