Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_PrefabHelper.c
Go to the documentation of this file.
1#ifdef WORKBENCH
2// temporary entity/Source solutions as container creation might come soon™ (BaseContainerTools.CreatePrefabEntityContainer)
3class SCR_PrefabHelper
4{
5 static const string PREFAB_BASE_SUFFIX = "_base"; //<! used by SCR_PrefabManagementTool to strip it when creating a child
6
7 protected static const string MESHOBJECT_CLASSNAME = "MeshObject";
8 protected static const string DEFAULT_PARENT_PREFAB = "GenericEntity";
9 protected static const string PREFAB_DOTTED_EXTENSION = ".et";
10
11 protected static const ref array<ResourceName> PREFAB_SEARCH_DIRECTORIES = {
12 "Prefabs/", // 0
13 "PrefabLibrary/", // 1
14 "PrefabsEditable/", // 2
15 };
16
17 //------------------------------------------------------------------------------------------------
22 static ResourceName ClonePrefab(ResourceName sourcePrefab, string absoluteFilePath)
23 {
24 if (SCR_StringHelper.IsEmptyOrWhiteSpace(sourcePrefab))
25 {
26 Print("Source Prefab is empty", LogLevel.WARNING);
27 return string.Empty;
28 }
29
30 if (SCR_StringHelper.IsEmptyOrWhiteSpace(absoluteFilePath))
31 {
32 Print("Absolute File Path is empty", LogLevel.WARNING);
33 return string.Empty;
34 }
35
36 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
37 if (!worldEditorAPI)
38 {
39 Print("WorldEditorAPI is not available", LogLevel.ERROR);
40 return string.Empty;
41 }
42
43 if (!absoluteFilePath.EndsWith(PREFAB_DOTTED_EXTENSION))
44 absoluteFilePath += PREFAB_DOTTED_EXTENSION;
45
46 string absoluteDirPath = FilePath.StripFileName(absoluteFilePath);
47 if (!FileIO.FileExists(absoluteDirPath))
48 {
49 if (!FileIO.MakeDirectory(absoluteDirPath))
50 {
51 Print("Cannot create the destination directory (" + absoluteDirPath + ")", LogLevel.ERROR);
52 return string.Empty;
53 }
54 }
55
56 IEntitySource entitySource = CreateEntitySourceWithoutEntity(sourcePrefab);
57 if (!entitySource)
58 {
59 Print("Prefab's entity source cannot be created", LogLevel.ERROR);
60 return string.Empty;
61 }
62
63 IEntitySource actualPrefab = IEntitySource.Cast(entitySource.GetAncestor());
64 if (!actualPrefab)
65 {
66 Print("Created entity's source does not have an ancestor", LogLevel.ERROR);
67 return string.Empty;
68 }
69
70 if (!worldEditorAPI.CreateEntityTemplate(actualPrefab, absoluteFilePath))
71 {
72 Print("Cannot save Prefab", LogLevel.ERROR);
73 return string.Empty;
74 }
75
76 MetaFile metaFile = SCR_WorldEditorToolHelper.GetResourceManager().GetMetaFile(absoluteFilePath);
77 if (!metaFile)
78 {
79 Print("Created Prefab's meta file cannot be found", LogLevel.WARNING);
80 return string.Empty;
81 }
82
83 return metaFile.GetResourceID();
84 }
85
86 //------------------------------------------------------------------------------------------------
91 static ResourceName CreateChildPrefab(ResourceName sourcePrefab, string absoluteFilePath)
92 {
93 if (SCR_StringHelper.IsEmptyOrWhiteSpace(sourcePrefab))
94 {
95 Print("Source Prefab is empty", LogLevel.WARNING);
96 return string.Empty;
97 }
98
99 if (SCR_StringHelper.IsEmptyOrWhiteSpace(absoluteFilePath))
100 {
101 Print("Absolute File Path is empty", LogLevel.WARNING);
102 return string.Empty;
103 }
104
105 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
106 if (!worldEditorAPI)
107 {
108 Print("WorldEditorAPI is not available", LogLevel.ERROR);
109 return string.Empty;
110 }
111
112 if (!absoluteFilePath.EndsWith(PREFAB_DOTTED_EXTENSION))
113 absoluteFilePath += PREFAB_DOTTED_EXTENSION;
114
115 string absoluteDirPath = FilePath.StripFileName(absoluteFilePath);
116 if (!FileIO.FileExists(absoluteDirPath))
117 {
118 if (!FileIO.MakeDirectory(absoluteDirPath))
119 {
120 Print("Cannot create directory \"" + absoluteDirPath + "\"", LogLevel.ERROR);
121 return string.Empty;
122 }
123 }
124
125 IEntitySource entitySource = CreateEntitySourceWithoutEntity(sourcePrefab);
126 if (!entitySource)
127 {
128 Print("Prefab's entity source cannot be created", LogLevel.ERROR);
129 return string.Empty;
130 }
131
132 if (!worldEditorAPI.CreateEntityTemplate(entitySource, absoluteFilePath))
133 {
134 Print("Cannot create Prefab", LogLevel.ERROR);
135 return string.Empty;
136 }
137
138 MetaFile metaFile = SCR_WorldEditorToolHelper.GetResourceManager().GetMetaFile(absoluteFilePath);
139 if (!metaFile)
140 {
141 Print("Created Prefab's meta file cannot be found", LogLevel.WARNING);
142 return string.Empty;
143 }
144
145 return metaFile.GetResourceID();
146 }
147
148 //------------------------------------------------------------------------------------------------
157 static array<ResourceName> CreatePrefabsFromXOBs(notnull array<ResourceName> xobs, string absoluteDirPath, ResourceName parentPrefab = string.Empty, bool createBasePrefab = false)
158 {
159 if (xobs.IsEmpty())
160 return {};
161
162 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
163 if (!worldEditorAPI)
164 {
165 Print("WorldEditorAPI is not available", LogLevel.ERROR);
166 return null;
167 }
168
169 if (!FileIO.FileExists(absoluteDirPath))
170 {
171 if (!FileIO.MakeDirectory(absoluteDirPath))
172 {
173 Print("Cannot create directory \"" + absoluteDirPath + "\"", LogLevel.ERROR);
174 return null;
175 }
176 }
177
178 bool manageEditAction = BeginEntityAction();
179
180 IEntitySource entitySource = CreateEntitySourceWithoutEntity(parentPrefab);
181 if (!entitySource)
182 {
183 Print("Prefab's entity source cannot be created", LogLevel.ERROR);
184 EndEntityAction(manageEditAction);
185 return null;
186 }
187
188 // if the MeshObject component doesn't exist, create it
189 if (!CreateEntitySourceComponentIfNeeded(entitySource, MESHOBJECT_CLASSNAME))
190 {
191 Print("Cannot add MeshObject component", LogLevel.ERROR);
192 EndEntityAction(manageEditAction);
193 return null;
194 }
195
196 array<ResourceName> result = {};
197 array<ref ContainerIdPathEntry> meshObjectPath = { new ContainerIdPathEntry(MESHOBJECT_CLASSNAME) };
198
199 foreach (ResourceName xob : xobs)
200 {
201 if (SCR_StringHelper.IsEmptyOrWhiteSpace(xob))
202 {
203 Print("Provided XOB is empty - skipping", LogLevel.WARNING);
204 continue;
205 }
206
207 string prefabFileName = FilePath.StripExtension(FilePath.StripPath(xob.GetPath())) + PREFAB_DOTTED_EXTENSION;
208
209 // apply XOB path to mesh
210 if (!worldEditorAPI.SetVariableValue(entitySource, meshObjectPath, "Object", xob))
211 {
212 Print("Cannot apply XOB model to " + prefabFileName, LogLevel.ERROR);
213 continue;
214 }
215
216 ResourceName resourceName = SaveEntitySourceAsPrefab(entitySource, absoluteDirPath, prefabFileName, createBasePrefab);
217 if (resourceName.IsEmpty())
218 {
219 Print("Cannot save Prefab " + prefabFileName, LogLevel.WARNING);
220 continue;
221 }
222
223 result.Insert(resourceName);
224 }
225
226 EndEntityAction(manageEditAction);
227
228 return result;
229 }
230
231 //------------------------------------------------------------------------------------------------
241 static ResourceName CreatePrefabFromXOB(ResourceName xob, string absoluteDestinationPath, ResourceName parentPrefab = string.Empty, bool createBasePrefab = false)
242 {
243 if (SCR_StringHelper.IsEmptyOrWhiteSpace(xob))
244 {
245 Print("Provided XOB is empty", LogLevel.ERROR);
246 return string.Empty;
247 }
248
249 if (!absoluteDestinationPath.EndsWith(PREFAB_DOTTED_EXTENSION)) // use the already existing method
250 {
251 array<ResourceName> result = CreatePrefabsFromXOBs({ xob }, absoluteDestinationPath, parentPrefab, createBasePrefab);
252 if (result.IsEmpty())
253 return string.Empty;
254 else
255 return result[0];
256 }
257
258 string absoluteDirPath = FilePath.StripFileName(absoluteDestinationPath);
259 if (absoluteDirPath.EndsWith("/"))
260 absoluteDirPath = absoluteDirPath.Substring(0, absoluteDirPath.Length() - 1);
261
262 if (!FileIO.MakeDirectory(absoluteDirPath))
263 {
264 Print("Cannot create directory \"" + absoluteDirPath + "\"", LogLevel.ERROR);
265 return string.Empty;
266 }
267
268 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
269 if (!worldEditorAPI)
270 {
271 Print("WorldEditorAPI is not available", LogLevel.ERROR);
272 return string.Empty;
273 }
274
275 bool manageEditAction = BeginEntityAction();
276
277 IEntitySource entitySource = CreateEntitySourceFromXOB(xob, parentPrefab);
278 SCR_WorldEditorToolHelper.DeleteEntityFromSource(entitySource);
279
280 EndEntityAction(manageEditAction);
281
282 if (!entitySource)
283 {
284 Print("Prefab's entity source cannot be created", LogLevel.ERROR);
285 return string.Empty;
286 }
287
288 string prefabFileName = FilePath.StripPath(absoluteDestinationPath);
289 return SaveEntitySourceAsPrefab(entitySource, absoluteDirPath, prefabFileName, createBasePrefab);
290 }
291
292 //------------------------------------------------------------------------------------------------
297 static bool CreatePrefabStructure(notnull SCR_PrefabHelper_Structure structure, string addonPathPrefix)
298 {
299 structure.m_sName.TrimInPlace();
300 if (!structure.m_sName)
301 {
302 Print("Name is empty", LogLevel.ERROR);
303 return false;
304 }
305
306 if (!SCR_FileIOHelper.IsValidFileName(structure.m_sName))
307 {
308 Print("Name is invalid - " + structure.m_sName, LogLevel.ERROR);
309 return false;
310 }
311
312 if (!structure.m_Directory)
313 {
314 Print("Main directory is null", LogLevel.ERROR);
315 return false;
316 }
317
318 string absolutePath;
319 if (!Workbench.GetAbsolutePath(addonPathPrefix, absolutePath, false))
320 {
321 Print("Cannot get absolute path for " + addonPathPrefix + structure.m_Directory.m_sRelativePath, LogLevel.ERROR);
322 return false;
323 }
324
325 return CreatePrefabStructureDirectory(structure.m_sName, structure.m_Directory, absolutePath);
326 }
327
328 //------------------------------------------------------------------------------------------------
334 protected static bool CreatePrefabStructureDirectory(string structureName, notnull SCR_PrefabHelper_StructureDirectory directory, string absoluteParentPath)
335 {
336 string absoluteDirectoryPath = string.Format(FilePath.Concat(absoluteParentPath, directory.m_sRelativePath), structureName);
337 if (!FileIO.MakeDirectory(absoluteDirectoryPath))
338 {
339 Print("Cannot create directory " + absoluteDirectoryPath, LogLevel.ERROR);
340 return false;
341 }
342
343 foreach (SCR_PrefabHelper_StructureFile file : directory.m_aFiles)
344 {
345 string absoluteFilePath = string.Format(FilePath.Concat(absoluteDirectoryPath, file.m_sFileName), structureName);
346 ResourceName createdResource = CreateChildPrefab(file.m_sParentResource, absoluteFilePath);
347 if (!createdResource)
348 {
349 Print("Cannot create file " + absoluteFilePath, LogLevel.WARNING);
350 continue;
351 }
352 }
353
354 foreach (SCR_PrefabHelper_StructureDirectory subDirectory : directory.m_aSubDirectories)
355 {
356 string absoluteSubDirectoryPath = string.Format(FilePath.Concat(absoluteDirectoryPath, subDirectory.m_sRelativePath), structureName);
357 if (!FileIO.MakeDirectory(absoluteSubDirectoryPath))
358 {
359 Print("Cannot create directory " + absoluteSubDirectoryPath, LogLevel.WARNING);
360 continue;
361 }
362
363 CreatePrefabStructureDirectory(structureName, subDirectory, absoluteSubDirectoryPath); // did you mean recursion?
364 }
365
366 return true;
367 }
368
369 //------------------------------------------------------------------------------------------------
374 static IEntitySource CreateEntitySource(ResourceName parentPrefab = string.Empty)
375 {
376 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
377 if (!worldEditorAPI)
378 {
379 Print("WorldEditorAPI is not available", LogLevel.ERROR);
380 return null;
381 }
382
383 if (SCR_StringHelper.IsEmptyOrWhiteSpace(parentPrefab))
384 parentPrefab = DEFAULT_PARENT_PREFAB;
385
386 bool manageEditAction = BeginEntityAction();
387
388 IEntitySource entitySource = worldEditorAPI.CreateEntity(parentPrefab, "", worldEditorAPI.GetCurrentEntityLayerId(), null, vector.Zero, vector.Zero);
389 if (!entitySource)
390 {
391 Print("Entity cannot be created (parent = " + parentPrefab + ")", LogLevel.ERROR);
392 EndEntityAction(manageEditAction);
393 return null;
394 }
395
396 EndEntityAction(manageEditAction);
397
398 return entitySource;
399 }
400
401 //------------------------------------------------------------------------------------------------
405 protected static IEntitySource CreateEntitySourceWithoutEntity(ResourceName parentPrefab = string.Empty)
406 {
407 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
408
409 bool manageEditAction = BeginEntityAction();
410
411 IEntitySource entitySource = CreateEntitySource(parentPrefab);
412 SCR_WorldEditorToolHelper.DeleteEntityFromSource(entitySource);
413
414 EndEntityAction(manageEditAction);
415
416 return entitySource;
417 }
418
419 //------------------------------------------------------------------------------------------------
422 // protected for now
426 protected static IEntitySource CreateEntitySourceFromXOB(ResourceName xob, ResourceName parentPrefab = string.Empty)
427 {
428 if (SCR_StringHelper.IsEmptyOrWhiteSpace(xob))
429 {
430 Print("Provided XOB is empty", LogLevel.ERROR);
431 return null;
432 }
433
434 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
435 if (!worldEditorAPI)
436 {
437 Print("WorldEditorAPI is not available", LogLevel.ERROR);
438 return null;
439 }
440
441 string xobName = FilePath.StripPath(xob.GetPath());
442
443 bool manageEditAction = BeginEntityAction();
444
445 IEntitySource entitySource = CreateEntitySource(parentPrefab); // do NOT switch to CreateEntitySourceWithoutEntity!
446 if (!entitySource)
447 {
448 Print("Prefab's entity source cannot be created for xob " + xobName, LogLevel.ERROR);
449 EndEntityAction(manageEditAction);
450 return null;
451 }
452
453 // if the MeshObject component doesn't exist, create it
454 if (!CreateEntitySourceComponentIfNeeded(entitySource, MESHOBJECT_CLASSNAME))
455 {
456 Print("Cannot add MeshObject component", LogLevel.ERROR);
457 EndEntityAction(manageEditAction);
458 return null;
459 }
460
461 // apply XOB path to mesh
462 if (!worldEditorAPI.SetVariableValue(entitySource, { new ContainerIdPathEntry(MESHOBJECT_CLASSNAME) }, "Object", xob))
463 {
464 Print("Cannot apply XOB model to IEntitySource for xob " + xobName, LogLevel.ERROR);
465 EndEntityAction(manageEditAction);
466 return null;
467 }
468
469 EndEntityAction(manageEditAction);
470
471 return entitySource;
472 }
473
474 //------------------------------------------------------------------------------------------------
479 static IEntityComponentSource CreateEntitySourceComponentIfNeeded(notnull IEntitySource entitySource, string componentClassname)
480 {
481 if (SCR_StringHelper.IsEmptyOrWhiteSpace(componentClassname))
482 {
483 Print("Provided componentClassname is empty", LogLevel.WARNING);
484 return null;
485 }
486
487 IEntityComponentSource result = SCR_BaseContainerTools.FindComponentSource(entitySource, componentClassname);
488 if (result)
489 return result;
490
491 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
492
493 bool manageEditAction = BeginEntityAction();
494
495 result = worldEditorAPI.CreateComponent(entitySource, componentClassname);
496 if (!result)
497 Print("Cannot add the " + MESHOBJECT_CLASSNAME + " component to the Prefab", LogLevel.ERROR);
498
499 EndEntityAction(manageEditAction);
500
501 return result;
502 }
503
504 //------------------------------------------------------------------------------------------------
513 static map<int, ref array<ResourceName>> GetPrefabs(int addonIndex = -1, int getMode = -1)
514 {
515 array<string> addonIDs;
516 if (addonIndex < 0)
517 {
518 addonIDs = SCR_AddonTool.GetAllAddonIDs();
519 }
520 else
521 {
522 string addonID = SCR_AddonTool.GetAddonID(addonIndex);
523 if (!addonID) // IsEmpty()
524 {
525 addonIndex = -1;
526 addonIDs = SCR_AddonTool.GetAllAddonIDs();
527 }
528 else
529 {
530 addonIDs = { addonID };
531 }
532 }
533
534 map<int, ref array<ResourceName>> result = new map<int, ref array<ResourceName>>();
535
536 SearchResourcesFilter searchFilter = new SearchResourcesFilter();
537 searchFilter.fileExtensions = { "et" };
538
539 array<ResourceName> resourceNames;
540 foreach (int index, string addonID : addonIDs)
541 {
542 if (addonIndex > -1)
543 index = addonIndex; // little one-loop cheat
544
545 if (PREFAB_SEARCH_DIRECTORIES.IsIndexValid(getMode))
546 searchFilter.rootPath = SCR_AddonTool.GetAddonFileSystem(index) + PREFAB_SEARCH_DIRECTORIES[getMode];
547 else
548 searchFilter.rootPath = SCR_AddonTool.GetAddonFileSystem(index);
549
550 resourceNames = {};
551 ResourceDatabase.SearchResources(searchFilter, resourceNames.Insert);
552 result.Insert(index, resourceNames);
553 }
554
555 return result;
556 }
557
558 //------------------------------------------------------------------------------------------------
563 static string GetResourceNameAbsolutePath(ResourceName resourceName, bool mustExist = true)
564 {
565 string result;
566 if (!Workbench.GetAbsolutePath(resourceName.GetPath(), result, mustExist))
567 return string.Empty;
568
569 return result;
570 }
571
572 //------------------------------------------------------------------------------------------------
585 static string GetRelativeParentDirectory(string relativeSourceDirectory, string relativeTargetDirectory)
586 {
587 if (relativeSourceDirectory.IsEmpty())
588 return FormatRelativePath(relativeTargetDirectory);
589
590 if (relativeTargetDirectory.IsEmpty())
591 return FormatRelativePath(relativeSourceDirectory);
592
593 relativeSourceDirectory = FormatRelativePath(relativeSourceDirectory);
594 relativeTargetDirectory = FormatRelativePath(relativeTargetDirectory);
595
596 // both are root directories
597 if (!relativeSourceDirectory.Contains("/") && !relativeTargetDirectory.Contains("/"))
598 return relativeTargetDirectory;
599
600 bool slashFound;
601 string path;
602 for (int i, length = relativeSourceDirectory.Length(); i < length; i++)
603 {
604 string character = relativeSourceDirectory[i];
605 if (!slashFound)
606 {
607 if (character == "/")
608 slashFound = true;
609 }
610 else
611 {
612 path += character;
613 }
614 }
615
616 if (!slashFound)
617 path = relativeSourceDirectory;
618
619 return relativeTargetDirectory + "/" + path;
620 }
621
622 //------------------------------------------------------------------------------------------------
626 protected static string FormatRelativePath(string relativePath)
627 {
628 if (relativePath.IsEmpty())
629 return string.Empty;
630
631 relativePath.Replace(SCR_StringHelper.ANTISLASH, SCR_StringHelper.SLASH);
632 relativePath.Replace(SCR_StringHelper.DOUBLE_SLASH, SCR_StringHelper.SLASH);
633
634 if (relativePath.StartsWith("/"))
635 relativePath = relativePath.Substring(1, relativePath.Length() - 1);
636
637 if (relativePath.EndsWith("/"))
638 relativePath = relativePath.Substring(0, relativePath.Length() - 1);
639
640 return relativePath;
641 }
642
643 //------------------------------------------------------------------------------------------------
647 static bool UpdatePrefabFromEntitySourceAncestor(notnull BaseContainer actualPrefab)
648 {
649 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
650 if (!worldEditorAPI)
651 {
652 Print("WorldEditorAPI is not available", LogLevel.ERROR);
653 return string.Empty;
654 }
655
656 bool manageEditAction = BeginEntityAction();
657 bool result = worldEditorAPI.SaveEntityTemplate(actualPrefab); // no IEntitySource casting required
658 EndEntityAction(manageEditAction);
659
660 return result;
661 }
662
663 //------------------------------------------------------------------------------------------------
670 static ResourceName SaveEntitySourceAsPrefab(notnull IEntitySource entitySource, string absoluteDirPath, string prefabFileName, bool createBasePrefab = false)
671 {
672 if (SCR_StringHelper.IsEmptyOrWhiteSpace(absoluteDirPath))
673 {
674 Print("Provided absoluteDirPath is empty", LogLevel.ERROR);
675 return string.Empty;
676 }
677
678 if (SCR_StringHelper.IsEmptyOrWhiteSpace(prefabFileName))
679 {
680 Print("Provided prefabFileName is empty", LogLevel.ERROR);
681 return string.Empty;
682 }
683
684 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
685 if (!worldEditorAPI)
686 {
687 Print("WorldEditorAPI is not available", LogLevel.ERROR);
688 return string.Empty;
689 }
690
691 if (!absoluteDirPath.EndsWith("/"))
692 absoluteDirPath += "/";
693
694 if (!FileIO.FileExists(absoluteDirPath) && !FileIO.MakeDirectory(absoluteDirPath))
695 {
696 Print("Cannot create the destination directory (" + absoluteDirPath + ")", LogLevel.ERROR);
697 return string.Empty;
698 }
699
700 if (!prefabFileName.EndsWith(PREFAB_DOTTED_EXTENSION))
701 prefabFileName += PREFAB_DOTTED_EXTENSION;
702
703 string absoluteFilePath = absoluteDirPath + prefabFileName;
704 MetaFile metaFile;
705
706 if (createBasePrefab)
707 {
708 string basePrefabFileName = FilePath.StripExtension(prefabFileName) + PREFAB_BASE_SUFFIX + PREFAB_DOTTED_EXTENSION;
709 string absoluteBaseFilePath = absoluteDirPath + basePrefabFileName;
710
711 // save base as Prefab
712 if (!worldEditorAPI.CreateEntityTemplate(entitySource, absoluteBaseFilePath))
713 {
714 Print("Cannot save base prefab " + basePrefabFileName + " at " + absoluteBaseFilePath, LogLevel.WARNING);
715 return string.Empty;
716 }
717
718 metaFile = SCR_WorldEditorToolHelper.GetResourceManager().GetMetaFile(absoluteBaseFilePath);
719 if (!metaFile)
720 {
721 Print("Created base Prefab's meta file cannot be found", LogLevel.WARNING);
722 return string.Empty;
723 }
724
725 // base prefab has been created, now let's create the inheriting child prefab
726
727 entitySource = CreateEntitySourceWithoutEntity(metaFile.GetResourceID());
728 if (!entitySource)
729 {
730 Print("Prefab's child entity source cannot be created", LogLevel.ERROR);
731 return string.Empty;
732 }
733 }
734
735 // save as Prefab
736 if (!worldEditorAPI.CreateEntityTemplate(entitySource, absoluteFilePath))
737 {
738 Print("Cannot save prefab " + prefabFileName + " at " + absoluteFilePath, LogLevel.WARNING);
739 return string.Empty;
740 }
741
742 metaFile = SCR_WorldEditorToolHelper.GetResourceManager().GetMetaFile(absoluteFilePath);
743 if (!metaFile)
744 {
745 Print("Created Prefab's meta file cannot be found", LogLevel.WARNING);
746 return string.Empty;
747 }
748
749 return metaFile.GetResourceID();
750 }
751
752 //------------------------------------------------------------------------------------------------
756 static bool UpdatePrefab(IEntitySource actualPrefab)
757 {
758 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
759 if (!worldEditorAPI)
760 {
761 Print("WorldEditorAPI is not available", LogLevel.ERROR);
762 return false;
763 }
764
765 return worldEditorAPI.SaveEntityTemplate(actualPrefab);
766 }
767
768 //------------------------------------------------------------------------------------------------
771 protected static bool BeginEntityAction()
772 {
773 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
774 if (worldEditorAPI.IsDoingEditAction())
775 {
776 return false;
777 }
778 else
779 {
780 worldEditorAPI.BeginEntityAction();
781 return true;
782 }
783 }
784
785 //------------------------------------------------------------------------------------------------
788 protected static void EndEntityAction(bool manageEditAction)
789 {
790 if (manageEditAction)
791 SCR_WorldEditorToolHelper.GetWorldEditorAPI().EndEntityAction();
792 }
793}
794
795[BaseContainerProps(configRoot: true), SCR_BaseContainerCustomTitleField("m_sName")]
796class SCR_PrefabHelper_Structure
797{
798 [Attribute(defvalue: "Structure name", desc: "Config type's friendly display name")]
799 string m_sName;
800
801 [Attribute(desc: "Root directory")]
802 ref SCR_PrefabHelper_StructureDirectory m_Directory;
803}
804
806class SCR_PrefabHelper_StructureDirectory
807{
808 [Attribute(defvalue: "Prefabs/Category/SubCategory/%1", desc: "Directory path - can be empty (root), a simple name (one directory) or multiple (sub)directories separated by a slash\n%1 = project name (e.g S105)")]
809 string m_sRelativePath;
810
811 [Attribute(desc: "Subdirectories")]
812 ref array<ref SCR_PrefabHelper_StructureDirectory> m_aSubDirectories;
813
814 [Attribute(desc: "Files")]
815 ref array<ref SCR_PrefabHelper_StructureFile> m_aFiles;
816}
817
819class SCR_PrefabHelper_StructureFile
820{
821 [Attribute(defvalue: "%1_base.et", desc: "Relative file path in which this Prefab is created - extension is optional and will be defined from parent Prefab\n%1 = project name (e.g S105)")]
822 string m_sFileName;
823
824 [Attribute(defvalue: "", desc: "The parent resource from which this one inherits", uiwidget: UIWidgets.ResourceNamePicker, params: "et conf")]
825 ResourceName m_sParentResource;
826}
827#endif // WORKBENCH
string path
void ContainerIdPathEntry(string propertyName, int index=-1)
Definition worldEditor.c:30
SCR_AIAnimation_Loitering BaseContainerProps
Commanding menu commanding element class.
ResourceName resourceName
Definition SCR_AIGroup.c:66
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
SCR_Faction ScriptedFaction SCR_BaseContainerCustomTitleField("m_sCallsign")
LocalizedString m_sName
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
string m_sFileName
bool xob
Attribute to use a ResourceName filename.
Definition Attributes.c:239
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
SCR_FieldOfViewSettings Attribute