10 [
Attribute(defvalue:
"c:/Reforger/Data/Arland",
desc:
"Folder of the map to export")]
11 string m_sExportMapDir;
13 [
Attribute(defvalue:
"Assets/_SharedData",
desc:
"Relative paths to shared data to be copied over")]
14 ref array<string> m_aCopyPathsMixed;
16 [
Attribute(defvalue:
"edds;emat;gamemat",
desc:
"Shared data extensions, only these will be copied over")]
17 string m_sCopyPathsMixedExtensions;
19 [
Attribute(defvalue:
"",
desc:
"Paths to copy .xob files from")]
22 [
Attribute(defvalue:
"Tree::StaticModelEntity",
desc:
"Classname to Classname conversion mapping during the export process. First class will be converted to the second class, the separator is ::")]
25 [
Attribute(defvalue:
"RoadGeneratorEntity",
desc:
"Entities/Prefabs inheriting classes in this list are not converted, even if they match any other criteria")]
28 [
Attribute(defvalue:
"",
desc:
"Entities/Prefabs inheriting classes containing keywords from this list are converted to their corresponding classes")]
31 [
Attribute(defvalue:
"MeshObject",
desc:
"Components inheriting these classes in this list are not converted, even if they match any other criteria")]
34 [
Attribute(defvalue:
"export-cache",
desc:
"Path prefix added to the resources that are converted during the export process, typically prefabs")]
35 string m_sExportCachePrefix;
37 [
Attribute(defvalue:
"true",
desc:
"After export is finished, automatically delete temporary files created during the export")]
38 bool m_bDeleteTempFiles;
40 [
Attribute(defvalue:
"",
desc:
"Resources with these GUIDs will not be copied over")]
43 [
Attribute(defvalue:
"",
desc:
"When cloning prefabs, ignore the ones coming from PrefabLibrary and alter prefab inheritance accordingly")]
44 bool m_bSkipPrefabLibrary;
46 [
Attribute(defvalue:
"false",
desc:
"Export source files along with the resource files. (will export FBX, TIF etc.. which are not used at run time)")]
47 bool m_bExportSourceFiles;
49 [
Attribute(defvalue:
"true",
desc:
"Export files belonging to map (terrain tiles, etc.)")]
52 [
Attribute(defvalue:
"$ArmaReforger",
desc:
"FIlesystem of the project we are exporting world from.")]
55 [
Attribute(
desc:
"Root resources to start reference crawling from.")]
60 if (m_aModelPaths == null || m_aModelPaths.Count() == 0)
63 if (m_aCopyPathsMixed == null || m_aCopyPathsMixed.Count() == 0)
66 if (m_sCopyPathsMixedExtensions.IsEmpty())
69 if (m_aClassMappings == null || m_aClassMappings.Count() == 0)
72 if (m_aEntityClassWhitelist == null || m_aEntityClassWhitelist.Count() == 0)
75 if (m_aEntityClassBlacklistKeywords == null || m_aEntityClassBlacklistKeywords.Count() == 0)
78 if (m_aComponentClassWhitelist == null || m_aComponentClassWhitelist.Count() == 0)
81 if (m_aResourceExcludeGUIDs == null || m_aResourceExcludeGUIDs.Count() == 0)
101#ifdef WE_LOGGING_ENABLED
102class WorldExporterLogItem
104 string messageA, messageB;
105 int StartTime, EndTime;
109 return EndTime - StartTime;
114class ResourceExportCrawler
116 ResourceManager m_ResourceManager = Workbench.GetModule(ResourceManager);
117 ref set<ResourceName> m_Visited =
new set<ResourceName>();
153 void CrawlGamemat(ResourceName
resourceName, BaseContainer container = null)
162 resource = BaseContainerTools.LoadContainer(
resourceName);
163 container = resource.GetResource().ToBaseContainer();
166 ResourceName physicsMaterial;
167 container.Get(
"Physics material", physicsMaterial);
168 if (physicsMaterial && physicsMaterial.GetPath())
169 CrawlPhysmat(physicsMaterial);
171 ResourceName vhcsurf;
172 container.Get(
"Vehicle contact surface", vhcsurf);
173 if (vhcsurf && vhcsurf.GetPath())
174 CrawlVhcsurf(vhcsurf);
176 BaseContainer baseGamemat = container.GetAncestor();
178 CrawlGamemat(baseGamemat.GetResourceName(), baseGamemat);
200 MetaFile meta = m_ResourceManager.GetMetaFile(
resourceName.GetPath());
201 BaseContainerList configurations = meta.GetObjectArray(
"Configurations");
202 for (
int cfgIdx = 0, cfgCount = configurations.Count(); cfgIdx < cfgCount; cfgIdx++)
204 BaseContainer cfg = configurations.Get(cfgIdx);
206 string materialAssigns;
207 array<string> pairs =
new array<string>;
208 cfg.Get(
"MaterialAssigns", materialAssigns);
209 materialAssigns.Split(
";", pairs,
true);
211 foreach (
string pair : pairs)
213 array<string> keyValue =
new array<string>;
214 pair.Split(
",", keyValue,
true);
215 CrawlEmat(keyValue[1]);
218 BaseContainerList geometryParams = cfg.GetObjectArray(
"GeometryParams");
219 for (
int i = 0, iCount = geometryParams.Count(); i < iCount; i++)
221 BaseContainer geometryParam = geometryParams.Get(i);
222 array<ResourceName> surfaceProperties;
223 geometryParam.Get(
"SurfaceProperties", surfaceProperties);
224 foreach(ResourceName gamematOrPhysmat : surfaceProperties)
226 Crawl(gamematOrPhysmat);
239 Resource resource = BaseContainerTools.LoadContainer(
resourceName);
240 BaseContainer container = resource.GetResource().ToBaseContainer();
241 for (
int i = 0, count = container.GetNumVars(); i < count; i++)
243 if (container.GetDataVarType(i) !=
DataVarType.TEXTURE)
246 string varName = container.GetVarName(i);
247 ResourceName texture;
248 container.Get(varName, texture);
250 array<string> textures =
new array<string>;
251 texture.Split(
" ", textures,
true);
252 if (textures.Count() > 1)
254 foreach (
string txt : textures)
256 if (txt.Get(0) ==
"{")
268 ResourceName surfaceProperties;
269 container.Get(
"SurfaceProperties", surfaceProperties);
270 if (surfaceProperties && surfaceProperties.GetPath())
271 CrawlGamemat(surfaceProperties);
273 ResourceName plantMat;
274 container.Get(
"PlantMat", plantMat);
275 if (plantMat && plantMat.GetPath())
278 ResourceName clutterConfig;
279 container.Get(
"ClutterConfig", clutterConfig);
280 if (clutterConfig && clutterConfig.GetPath())
281 CrawlConf(clutterConfig);
291 void CrawlConf(ResourceName
resourceName, BaseContainer container = null)
300 resource = BaseContainerTools.LoadContainer(
resourceName);
301 container = resource.GetResource().ToBaseContainer();
304 CrawlConfObject(container);
308 void CrawlConfObject(BaseContainer container)
310 BaseContainer ancestor = container.GetAncestor();
313 ResourceName myName = container.GetResourceName();
314 ResourceName ancestorName = ancestor.GetResourceName();
318 if (myName != ancestorName)
319 CrawlConf(ancestorName, ancestor);
322 for (
int i = 0, iCount = container.GetNumVars(); i < iCount; i++)
324 string varName = container.GetVarName(i);
325 switch (container.GetDataVarType(i))
328 BaseContainer obj = container.GetObject(varName);
330 CrawlConfObject(obj);
334 container.Get(varName, varVal);
338 BaseContainerList objects = container.GetObjectArray(varName);
339 for (
int j = 0, jCount = objects.Count(); j < jCount; j++)
341 BaseContainer obj = objects.Get(j);
343 CrawlConfObject(obj);
347 auto varVal =
new array<ResourceName>();
348 container.Get(varName, varVal);
349 foreach(ResourceName entry : varVal)
358class WorldExportScript
360 void OnBeforeEntityProcessed(WorldExporterPlugin plugin, IEntitySource source)
364 void OnAfterEntityProcessed(WorldExporterPlugin plugin, IEntitySource source)
368 void OnAfterEntityCloned(WorldExporterPlugin plugin, IEntitySource oldEntSrc, IEntitySource newEntSrc)
372 void OnAfterEntityReparented(WorldExporterPlugin plugin, IEntitySource source, IEntitySource newParent)
377[
WorkbenchPluginAttribute(name:
"Map Exporter", wbModules: {
"WorldEditor" }, shortcut:
"Ctrl+`", awesomeFontCode: 0xF338)]
378class WorldExporterPlugin : WorkbenchPlugin
383 [
Attribute(defvalue:
"c:/Work/MapExport/",
desc:
"Destination folder for the export")]
384 string m_ExportDestination;
386 [
Attribute(defvalue:
"true",
desc:
"Mostly for debug purposes, enables/disables copying of files identified during export, for normal export, leave enabled")]
387 bool m_AllowResourceCopy;
390 bool m_CrawlFromRootResources;
393 WorldEditor m_WorldEditor;
397 ref set<BaseContainer> m_sDiscoveredPrefabs;
400 ref set<ResourceName> m_sPrefabsToMigrate;
401 ref set<ResourceName> m_sModelsToMigrate;
402 ref set<ResourceName> m_sMaterialsToMigrate;
403 ref set<ResourceName> m_sTexturesToMigrate;
404 ref set<ResourceName> m_sMiscToMigrate;
405 ref set<ResourceName> m_sResourceExcludeGUIDs;
406 ref set<ResourceName> m_sGamematsToMigrate;
407 #ifdef WE_LOGGING_ENABLED
408 ref array<ref WorldExporterLogItem> m_aLogItems;
412 ref WorldExportScript MapSpecificScript;
414 ResourceManager resourceManager;
415 bool m_PerformExport;
416 string m_sFilesystem;
421 protected bool ButtonExport()
428 m_PerformExport =
true;
432 protected bool Init()
435 if (!m_Config || !m_Config.IsValid())
441 m_sFilesystem = m_Config.m_sFilesystem +
":";
443 m_WorldEditor = Workbench.GetModule(WorldEditor);
444 m_WEapi = m_WorldEditor.GetApi();
445 resourceManager = Workbench.GetModule(ResourceManager);
448 m_sResourceExcludeGUIDs =
new set<ResourceName> ();
450 foreach(
string turnInto:m_Config.m_aClassMappings)
453 turnInto.Split(
"::",output,
true);
454 m_mEntityClassBlacklist.Insert(output[0], output[1]);
457 foreach(
ResourceName resName: m_Config.m_aResourceExcludeGUIDs)
459 m_sResourceExcludeGUIDs.Insert(resName);
462 MapSpecificScript =
new WorldExportScript();
466 protected void InitVars()
468 m_PerformExport =
false;
469 m_sDiscoveredPrefabs =
new set<BaseContainer>;
471 m_aCreatedFiles = {};
473 m_sPrefabsToMigrate =
new set<ResourceName>;
474 m_sModelsToMigrate =
new set<ResourceName>;
475 m_sMaterialsToMigrate =
new set<ResourceName>;
476 m_sTexturesToMigrate =
new set<ResourceName>;
477 m_sMiscToMigrate =
new set<ResourceName>;
478 m_sGamematsToMigrate =
new set<ResourceName>;
479 #ifdef WE_LOGGING_ENABLED
480 m_aLogItems =
new array<ref WorldExporterLogItem>;
494 reload = Workbench.ScriptDialog(
"Map Exporter",
"This tool coverts the assets used on a map as well as the map \nentities based on the predefined rules, many of which can be adjusted in the config file.\nThe result is a folder containing the converted assets, as well as map data.\nIt's meant to strip the map of any gameplay specific features,\nleaving only the bare minimum to aproach a visual parity with the original map.\n\nAfter loading the map in the project the export is meant for, it's recommended to run the Re-save plugin which cleans the data by\ngetting rid of some properties of uknown types,\nreducing the number of errors displayed when loading the map.\n\n!!! This Tool expects to be provided a configuration file, as well as external script. \nThe script needs to be placed in the same folder as the config file !!!",
this);
504 if (m_CrawlFromRootResources)
506 auto crawler =
new ResourceExportCrawler();
512 ExportFiles(crawler.m_Visited);
525 array<IEntitySource> entitiesToProcess = {};
527 int selectedEntCount = m_WEapi.GetSelectedEntitiesCount();
528 if(selectedEntCount > 0)
530 for (
int i = 0; i < selectedEntCount; i++)
533 if(!entitySource.GetParent())
534 entitiesToProcess.Insert(entitySource);
539 int countAll = m_WEapi.GetEditorEntityCount();
541 Print(
"Entities overall:"+countAll);
542 for (
int i = 0; i < countAll; i++)
545 if(!entitySource.GetParent())
546 entitiesToProcess.Insert(entitySource);
550 Print(
"walk entities array count: "+entitiesToProcess.Count());
551 m_WEapi.BeginEntityAction(
"MAP_EXPORT");
552 WBProgressDialog progress =
new WBProgressDialog(
"Exporting map...", m_WorldEditor);
557 Print(
"Entities processed: " + x +
"/"+entitiesToProcess.Count());
558 progress.SetProgress((x / entitiesToProcess.Count()) * 0.9);
564 ProcessEntityRecur(entSource,null,
false);
567 m_WEapi.EndEntityAction(
"MAP_EXPORT");
569 if(m_AllowResourceCopy)
570 PerformResourceExport(progress);
571 if(m_Config.m_bDeleteTempFiles)
572 ClearExportSourceData();
573 #ifdef WE_LOGGING_ENABLED
581 Workbench.ScriptDialog(
"Configure Map Exporter plugin",
"",
this);
588 if (!configResource.IsValid())
590 Print(
string.Format(
"Cannot load config '%1'!", configPath),
LogLevel.ERROR);
595 if (!configContainer)
598 BaseContainer configBase = configContainer.ToBaseContainer();
602 if (configBase.GetClassName() !=
"WorldExporterConfig")
604 Print(
string.Format(
"Config '%1' is of type '%2', must be 'WorldExporterConfig'!", configPath, configBase.GetClassName()),
LogLevel.ERROR);
618 if (!resource.GetPath())
623 bool registered =
false;
627 case ExporterAssetType.PREFAB:
628 registered = m_sPrefabsToMigrate.Insert(resource);
630 case ExporterAssetType.XOB:
631 registered = m_sModelsToMigrate.Insert(resource);
633 case ExporterAssetType.MAT:
634 registered = m_sMaterialsToMigrate.Insert(resource);
636 case ExporterAssetType.GAMEMAT:
637 registered = m_sGamematsToMigrate.Insert(resource);
639 case ExporterAssetType.TXT:
640 registered = m_sTexturesToMigrate.Insert(resource);
642 case ExporterAssetType.MISC:
643 registered = m_sMiscToMigrate.Insert(resource);
654 string entClassName = entSource.GetClassName();
656 if(m_Config.m_aEntityClassWhitelist.Contains(entClassName))
658 if(m_mEntityClassBlacklist.Contains(entClassName))
661 foreach(
string keyword:m_Config.m_aEntityClassBlacklistKeywords)
662 if(entClassName.Contains(keyword))
668 string GetAlternateClassName(
string currentName)
670 if(m_mEntityClassBlacklist.Contains(currentName))
671 return m_mEntityClassBlacklist.Get(currentName);
672 return "GenericEntity";
675 bool IsComponentClassBlacklisted(
string className)
677 return !m_Config.m_aComponentClassWhitelist.Contains(className);
681 bool IsAnyComponentIncompatible(notnull
IEntitySource entSource)
683 int componentsCount = entSource.GetComponentCount();
684 for (
int i = 0; i < componentsCount; i++)
687 if(IsComponentClassBlacklisted(componentSource.GetClassName()))
696 if(IsEntityClassBlacklisted(entSource))
698 if(IsAnyComponentIncompatible(entSource))
702 return DoesPrefabNeedReplacingFast(prefab);
711 if(m_mPrefabsNeedingReplace.Contains(resource))
713 return m_mPrefabsNeedingReplace.Get(resource);
717 bool result = DoesPrefabNeedReplacing(prefab);
718 m_mPrefabsNeedingReplace.Insert(resource, result);
727 if(IsEntityClassBlacklisted(prefab))
733 if(IsAnyComponentIncompatible(prefab))
737 int childCount = prefab.GetNumChildren();
739 for(
int i = 0; i < childCount; i++)
742 if(DoesEntityNeedReplacing(child))
748 RunPrefabDiscovery(prefab);
762 DiscoverMeshObjectMaterialOverrides(meshObjectComp,
resourceName);
769 BaseContainer container = FindComponentSource(entSource,
"MeshObject");
777 BaseContainer componentSourceAnc = FindComponentSource(ancestor,
"MeshObject");
778 if(container == componentSourceAnc)
782 RegisterXob(container);
791 for (
int i = 0; i < materials.Count(); i++)
795 materialData.Get(
"AssignedMaterial", matTgt);
798 RegisterMaterial(matTgt);
804 void GetMaterialsFromXobs()
808 MetaFile meta = resourceManager.GetMetaFile(res.GetPath());
814 for (
int cfgIdx = 0, cfgCount = configurations.Count(); cfgIdx < cfgCount; cfgIdx++)
818 string materialAssigns;
819 array<string> pairs =
new array<string>;
820 cfg.Get(
"MaterialAssigns", materialAssigns);
821 materialAssigns.Split(
";", pairs,
true);
823 foreach (
string pair : pairs)
825 array<string> keyValue =
new array<string>;
826 pair.Split(
",", keyValue,
true);
828 RegisterMaterial(resName);
832 for (
int i = 0, count = geometryParams.Count(); i < count; i++)
835 array<ResourceName> surfaceProperties;
836 geometryParam.Get(
"SurfaceProperties", surfaceProperties);
839 RegisterGamemat(gamemat);
847 void GetTexturesFromMaterials()
849 for(
int j = 0; j < m_sMaterialsToMigrate.Count();j++)
854 if(!resource || !resource.IsValid())
862 int varCount = container.GetNumVars();
864 for(
int i = 0; i < varCount; i++)
866 if(container.GetDataVarType(i) ==
DataVarType.TEXTURE)
868 string varName = container.GetVarName(i);
870 container.Get(varName,texture);
872 array<string> textures =
new array<string>;
873 texture.Split(
" ", textures,
true);
874 if(textures.Count() > 1)
876 foreach(
string txt:textures)
878 if(txt.Get(0) ==
"{")
880 AddAssetToMigrate(ExporterAssetType.TXT,txt, resName);
886 AddAssetToMigrate(ExporterAssetType.TXT,texture, resName);
895 if(m_sMaterialsToMigrate.Contains(resName))
897 AddAssetToMigrate(ExporterAssetType.MAT,resName);
906 if(!containerMaterial)
910 RegisterMaterial(containerMaterial.GetAncestor().GetResourceName());
912 int varCount = containerMaterial.GetNumVars();
914 for(
int i = 0; i < varCount; i++)
916 if(containerMaterial.GetDataVarType(i) ==
DataVarType.RESOURCE_NAME)
918 string varName = containerMaterial.GetVarName(i);
920 containerMaterial.Get(varName,material);
921 if(!material.GetPath() || !material.GetPath().Contains(
".emat"))
923 RegisterMaterial(material);
932 bool registered = AddAssetToMigrate(ExporterAssetType.GAMEMAT, resName);
950 RegisterGamemat(anc.GetResourceName());
957 #ifdef WE_LOGGING_ENABLED
958 int indx = LogTimedStart(
"RunPrefabDiscovery:"+prefab);
961 RegisterPrefabXob(prefab);
963 if(m_sDiscoveredPrefabs.Contains(prefab))
968 if(resName && resName.GetPath())
970 m_sDiscoveredPrefabs.Insert(prefab);
973 int childCount = prefab.GetNumChildren();
974 for(
int i = 0; i < childCount; i++)
977 RunPrefabDiscovery(child);
982 RunPrefabDiscovery(ancestor);
983 #ifdef WE_LOGGING_ENABLED
990 void ProcessEntityRecur(
IEntitySource entSource,
IEntitySource parent,
bool parentToBeDeleted, array<IEntitySource> toReparent = null)
992 int childCount = entSource.GetNumChildren();
995 OnBeforeEntityProcessed(entSource);
996 bool isPrefabChild = IsPartOfPrefab(entSource);
998 RegisterPrefabXob(entSource);
1001 if(DoesEntityNeedReplacing(entSource))
1003 newEntitySrc = CloneEntityFull(entSource, parent);
1004 if(!parentToBeDeleted)
1009 if (entSource.GetParent() != parent)
1011 IEntity entParent = m_WEapi.SourceToEntity(parent);
1012 IEntity entChild = m_WEapi.SourceToEntity(entSource);
1013 if(entParent && entChild)
1015 toReparent.Insert(entSource);
1021 array<IEntitySource> children =
new array<IEntitySource>();
1022 for(
int x = 0; x < childCount; x++)
1025 children.Insert(childSource);
1028 if(!children.IsEmpty())
1030 array<IEntitySource> entitiesToReparent = {};
1033 ProcessEntityRecur(child, newEntitySrc, toBeDeleted, entitiesToReparent);
1035 #ifdef WE_LOGGING_ENABLED
1036 int indx = LogTimedStart(
"Reparenting:"+children.Count());
1038 if(!entitiesToReparent.IsEmpty())
1040 m_WEapi.ParentEntities(newEntitySrc, entitiesToReparent,
false);
1042 OnAfterEntityReparented(ent,newEntitySrc);
1045 #ifdef WE_LOGGING_ENABLED
1051 string name = entSource.GetName();
1052 m_WEapi.DeleteEntity(entSource);
1055 newEntitySrc.SetName(name);
1057 OnAfterEntityProcessed(newEntitySrc);
1059 else if(!parentToBeDeleted)
1061 OnAfterEntityProcessed(entSource);
1069 string className = entSource.GetClassName();
1071 if(IsEntityClassBlacklisted(entSource))
1073 className = GetAlternateClassName(className);
1079 if(DoesPrefabNeedReplacingFast(prefab))
1086 className = newPrefab.GetPath();
1089 Print(
"Something went wrong with prefab replace:" + prefab.GetResourceName(),
LogLevel.ERROR);
1093 IEntitySource newEntSrc = CloneSingleEntity(className, entSource, parent, entSource.GetLayerID());
1095 CopyComponents(entSource, newEntSrc);
1104 if(!m_mCreatedPrefabs.Contains(prefabResName))
1106 newPrefab = ClonePrefabSlow(prefab);
1110 newPrefab = m_mCreatedPrefabs.Get(prefabResName);
1117 return prefab.GetPath().Contains(
"PrefabLibrary");
1123 ResourceName originalPrefabName = originalPrefab.GetResourceName();
1124 #ifdef WE_LOGGING_ENABLED
1125 int indx = LogTimedStart(
"ClonePrefabSlow:"+originalPrefabName);
1127 BaseContainer ancestorPrefab = originalPrefab.GetAncestor();
1132 if(DoesPrefabNeedReplacingFast(ancestorPrefab))
1134 ancestorPrefabName = ClonePrefabFast(ancestorPrefab);
1138 ancestorPrefabName = ancestorPrefab.GetResourceName();
1144 if(m_Config.m_bSkipPrefabLibrary && IsFromPrefabLibrary(originalPrefabName) && ancestorPrefabName)
1146 #ifdef WE_LOGGING_ENABLED
1149 RegisterNewPrefab(originalPrefabName,ancestorPrefabName);
1150 return ancestorPrefabName;
1153 string originalPrefabPath = originalPrefabName.GetPath();
1154 string newPrefabPath =
FilePath.Concat(m_Config.m_sExportCachePrefix, originalPrefabPath);
1155 string newPrefabPathAbs;
1156 Workbench.GetAbsolutePath(newPrefabPath, newPrefabPathAbs,
false);
1158 if(newPrefabPathAbs)
1160 PrintFormat(
"New prefab alternative not found for %1, lets create it", originalPrefabName);
1162 entSrc = DeepPrefabEntityCloneRecur(originalPrefab, null, ancestorPrefabName);
1165 m_WEapi.CreateEntityTemplate(entSrc, newPrefabPathAbs);
1166 resourceManager.WaitForFile(m_sFilesystem + newPrefabPath, 10000);
1167 ResourceName newPrefabName = Workbench.GetResourceName(newPrefabPath);
1169 AddAssetToMigrate(ExporterAssetType.PREFAB, newPrefabName);
1170 RegisterNewPrefab(originalPrefabName, newPrefabName);
1172 PrintFormat(
"new prefab ready for:%1, new resource name:%2", originalPrefabName, newPrefabName);
1176 m_WEapi.DeleteEntity(entSrc);
1177 #ifdef WE_LOGGING_ENABLED
1180 return newPrefabName;
1182 return string.Empty;
1189 if(!IsPartOfPrefab(prefab))
1191 string className = prefab.GetClassName();
1193 if(IsEntityClassBlacklisted(prefab))
1195 className = GetAlternateClassName(className);
1201 if(DoesPrefabNeedReplacingFast(anc))
1206 className = newPrefab;
1208 Print(
"Something went wrong with prefab replace:" + anc.GetResourceName(),
LogLevel.ERROR);
1212 className = GetPrefabName(prefab);
1216 newEntSrc = CloneSingleEntity(className, prefab, parent);
1217 if(ancestor && ancestor.GetPath())
1219 newEntSrc.SetAncestor(ancestor);
1222 CopyComponents(prefab, newEntSrc);
1225 int childCount = prefab.GetNumChildren();
1227 for(
int i = 0; i < childCount;i++)
1232 newEntSrc = parent.GetChild(i);
1235 DeepPrefabEntityCloneRecur(child,newEntSrc,
string.Empty);
1244 m_mCreatedPrefabs.Insert(resNameOriginal, resNameNew);
1245 m_aCreatedFiles.Insert(resNameNew.GetPath());
1252 if(entSource.GetAncestor() && entSource.GetAncestor().GetParent())
1253 thisEntPrefabRoot = entSource.GetAncestor().GetParent();
1258 if(parentSource && parentSource.GetAncestor())
1259 parentPrefab = parentSource.GetAncestor();
1261 return (thisEntPrefabRoot && parentPrefab && parentPrefab == thisEntPrefabRoot);
1275 container = container.GetAncestor();
1288 prefabRes = container.GetResourceName();
1291 container = container.GetAncestor();
1300 for (
int v = 0, varCount = sourceContainer.GetNumVars(); v < varCount; v++)
1302 varName = sourceContainer.GetVarName(v);
1303 if (!sourceContainer.IsVariableSetDirectly(varName))
1305 switch (sourceContainer.GetDataVarType(v))
1315 sourceContainer.Get(varName, valueSrc);
1316 targetContainer.Get(varName, valueTrg);
1317 if(valueSrc != valueTrg)
1318 m_WEapi.SetVariableValue(targetEntity,
path, varName, valueSrc);
1325 string valueSrc, valueTrg;
1326 sourceContainer.Get(varName, valueSrc);
1327 targetContainer.Get(varName, valueTrg);
1328 if(valueSrc != valueTrg)
1329 m_WEapi.SetVariableValue(targetEntity,
path, varName, valueSrc);
1335 int valueSrc, valueTrg;
1336 sourceContainer.Get(varName, valueSrc);
1337 targetContainer.Get(varName, valueTrg);
1339 if(valueSrc != valueTrg)
1340 m_WEapi.SetVariableValue(targetEntity,
path, varName, valueSrc.ToString());
1345 float valueSrc, valueTrg;
1346 sourceContainer.Get(varName, valueSrc);
1347 targetContainer.Get(varName, valueTrg);
1349 if(valueSrc != valueTrg)
1350 m_WEapi.SetVariableValue(targetEntity,
path, varName, valueSrc.ToString());
1355 vector valueSrc, valueTrg;
1356 sourceContainer.Get(varName, valueSrc);
1357 targetContainer.Get(varName, valueTrg);
1359 if(valueSrc != valueTrg)
1360 m_WEapi.SetVariableValue(targetEntity,
path, varName, valueSrc.ToString(
false));
1365 int valueSrc, valueTrg;
1366 sourceContainer.Get(varName, valueSrc);
1367 targetContainer.Get(varName, valueTrg);
1369 if(valueSrc != valueTrg)
1371 m_WEapi.SetVariableValue(targetEntity,
path, varName, valueSrc.ToString());
1377 int valueSrc, valueTrg;
1378 sourceContainer.Get(varName, valueSrc);
1379 targetContainer.Get(varName, valueTrg);
1381 if(valueSrc != valueTrg)
1382 m_WEapi.SetVariableValue(targetEntity,
path, varName, valueSrc.ToString());
1387 Print(
string.Format(
"Cannot copy variable '%1' from template, it has unsupported type %2!", varName,
typename.EnumToString(
DataVarType, sourceContainer.GetDataVarType(v))),
LogLevel.ERROR);
1395 array<string> componentsToCopy = {
"MeshObject",
"Hierarchy",
"RigidBody"};
1396 foreach (
string componentName : componentsToCopy)
1398 CopyComponent(componentName, source, target);
1405 BaseContainer componentSource = FindComponentSource(source, componentName);
1410 BaseContainer componentSourceAnc = FindComponentSource(ancestor, componentName);
1411 if(componentSource == componentSourceAnc)
1415 if (componentSource)
1418 BaseContainer componentTarget = FindComponentSource(target, componentName);
1420 if (!componentTarget)
1422 componentTarget = m_WEapi.CreateComponent(target, componentName);
1425 CopyContainerProperties(componentSource, componentTarget, target, containerPath);
1426 CopyContainerPropertiesSpecial(componentName, componentSource, componentTarget, target, containerPath);
1432 if(componentName ==
"MeshObject")
1434 RegisterXob(sourceComponent);
1435 if(!sourceComponent.IsVariableSetDirectly(
"Materials"))
1438 BaseContainerList materialsSource = sourceComponent.GetObjectArray(
"Materials");
1439 BaseContainerList materialsTarget = targetComponent.GetObjectArray(
"Materials");
1441 if (materialsSource)
1443 for (
int i = 0; i < materialsSource.Count(); i++)
1448 materialDataSource.Get(
"AssignedMaterial", matSrc);
1449 materialDataSource.Get(
"SourceMaterial", nameSrc);
1451 m_WEapi.CreateObjectArrayVariableMember(targetEntity,
path,
"Materials",
"MaterialAssignClass", i);
1453 array<ref ContainerIdPathEntry> containerPath = {};
1455 containerPath.Insert(entry);
1458 m_WEapi.SetVariableValue(targetEntity, containerPath,
"SourceMaterial", nameSrc);
1459 m_WEapi.SetVariableValue(targetEntity, containerPath,
"AssignedMaterial", matSrc);
1465 void ExportFiles(set<ResourceName> resourceNames)
1469 if(m_sResourceExcludeGUIDs.Contains(name))
1471 string filePath = name.GetPath();
1472 ExportFile(filePath);
1476 void ExportFile(
string srcFilePath)
1478 string dstFilePath = srcFilePath;
1479 if (dstFilePath.StartsWith(m_Config.m_sExportCachePrefix))
1481 int prefixLen = m_Config.m_sExportCachePrefix.Length() + 1;
1482 dstFilePath = dstFilePath.Substring(prefixLen, dstFilePath.Length() - prefixLen);
1484 dstFilePath =
FilePath.Concat(m_ExportDestination, dstFilePath);
1488 string srcMetaPath = srcFilePath +
".meta";
1489 string dstMetaPath = dstFilePath +
".meta";
1491 if (
FileIO.FileExists(srcFilePath))
1492 FileIO.CopyFile(srcFilePath, dstFilePath);
1494 if (
FileIO.FileExists(srcMetaPath))
1495 FileIO.CopyFile(srcMetaPath, dstMetaPath);
1497 if (m_Config.m_bExportSourceFiles)
1499 MetaFile meta = resourceManager.GetMetaFile(srcFilePath);
1502 string sourceFilePath = meta.GetSourceFilePath();
1503 string fsName =
FilePath.FileSystemNameFromFileName(sourceFilePath);
1504 string fsComplete =
"$"+fsName+
":";
1505 sourceFilePath.Replace(fsComplete,
"");
1506 string sourceFilename =
FilePath.StripPath(sourceFilePath);
1507 if(!sourceFilename.IsEmpty())
1509 string destination3 = m_ExportDestination+sourceFilePath;
1510 if (
FileIO.FileExists(sourceFilePath))
1511 FileIO.CopyFile(sourceFilePath, destination3);
1518 void ExportMapData()
1521 FileIO.FindFiles(files.Insert,m_Config.m_sExportMapDir,
string.Empty);
1522 foreach(
string filePath:files)
1523 ExportFile(filePath);
1526 void ExportSharedData()
1528 set<ResourceName> foundResources =
new set<ResourceName>();
1530 array<string> extensions = {};
1531 m_Config.m_sCopyPathsMixedExtensions.Split(
";",extensions,
true);
1533 foreach(
string path: m_Config.m_aCopyPathsMixed)
1536 filter.rootPath = m_sFilesystem +
path;
1537 filter.fileExtensions = extensions;
1542 foreach(
string path: m_Config.m_aModelPaths)
1545 filter.rootPath = m_sFilesystem +
path;
1546 filter.fileExtensions = {
"xob"};
1551 ExportFiles(foundResources);
1554 #ifdef WE_LOGGING_ENABLED
1555 int LogTimedStart(
string message)
1557 WorldExporterLogItem item =
new WorldExporterLogItem();
1561 item.messageA = message;
1562 item.StartTime =
System.GetTickCount();
1564 return m_aLogItems.Insert(item);
1567 void LogTimedEnd(
int index,
string message =
string.Empty)
1569 if(m_aLogItems.IsIndexValid(
index))
1571 WorldExporterLogItem item = m_aLogItems.Get(
index);
1576 item.messageB = message;
1577 item.EndTime =
System.GetTickCount();
1584 foreach(WorldExporterLogItem item: m_aLogItems)
1586 Print(
string.Format(
"Timed:,%1,%2,took(ms):,%3,", item.messageA, item.messageB, item.GetTime().ToString()));
1594 #ifdef WE_LOGGING_ENABLED
1595 int indx = LogTimedStart(
"CloneSingleEntity:"+className);
1600 oldEntSrc.Get(
"angles",
angles);
1604 OnAfterEntityCloned(oldEntSrc, newEntSrc);
1609 #ifdef WE_LOGGING_ENABLED
1617 MapSpecificScript.OnBeforeEntityProcessed(
this, source);
1622 MapSpecificScript.OnAfterEntityProcessed(
this, source);
1627 CopyEntityProperties(oldEntSrc, newEntSrc);
1628 MapSpecificScript.OnAfterEntityCloned(
this, oldEntSrc, newEntSrc);
1633 MapSpecificScript.OnAfterEntityReparented(
this, source, newParent);
1638 if(oldEntSrc.IsVariableSetDirectly(
"Flags"))
1641 oldEntSrc.Get(
"Flags",
flags);
1642 m_WEapi.SetVariableValue(newEntSrc, {},
"Flags",
flags.ToString());
1644 if(oldEntSrc.IsVariableSetDirectly(
"scale"))
1647 oldEntSrc.Get(
"scale",
scale);
1648 m_WEapi.SetVariableValue(newEntSrc, {},
"scale",
scale.ToString());
1650 if(oldEntSrc.IsVariableSetDirectly(
"coords"))
1653 oldEntSrc.Get(
"coords",
coords);
1654 m_WEapi.SetVariableValue(newEntSrc, {},
"coords",
coords.ToString(
false));
1656 if(oldEntSrc.IsVariableSetDirectly(
"placement"))
1659 oldEntSrc.Get(
"placement", placement);
1660 m_WEapi.SetVariableValue(newEntSrc, {},
"placement", placement);
1666 void ProcessDiscoveredPrefabs()
1670 RegisterPrefabXob(prefab);
1672 if(!m_mCreatedPrefabs.Contains(resName))
1674 AddAssetToMigrate(ExporterAssetType.PREFAB,resName);
1679 void PerformResourceExport(WBProgressDialog dialog)
1681 ProcessDiscoveredPrefabs();
1682 GetMaterialsFromXobs();
1683 GetTexturesFromMaterials();
1685 auto crawler =
new ResourceExportCrawler();
1687 ExportFiles(m_sPrefabsToMigrate);
1688 dialog.SetProgress(0.91);
1689 ExportFiles(m_sModelsToMigrate);
1690 dialog.SetProgress(0.92);
1693 ExportFiles(m_sTexturesToMigrate);
1694 dialog.SetProgress(0.94);
1703 ExportFiles(crawler.m_Visited);
1704 dialog.SetProgress(0.96);
1706 #ifdef WE_LOGGING_ENABLED
1707 Print(
"---------------------------Models------------------------------");
1711 Print(
"---------------------------Materials------------------------------");
1715 Print(
"---------------------------Textures------------------------------");
1719 Print(
"-------------------------Prefabs --------------------------------");
1723 Print(
"-------------------------Misc --------------------------------");
1729 dialog.SetProgress(0.98);
1730 m_WorldEditor.Save();
1731 if (m_Config.m_ExportMapData)
1733 dialog.SetProgress(0.99);
1736 void ClearExportSourceData()
1740 DeleteFilePlus(resName.GetPath());
1742 foreach(
string filePath:m_aCreatedFiles)
1744 DeleteFilePlus(filePath);
1748 void DeleteFilePlus(
string path)
1750 string pathMeta =
path +
".meta";
1753 FileIO.DeleteFile(pathMeta);
1756 bool IsExportTargetFolderEmpty()
1759 FileIO.FindFiles(filesAndDirs.Insert,m_ExportDestination,
string.Empty);
1760 return filesAndDirs.Count() == 0;
1769 for (
int i, componentsCount = prefabEntity.GetComponentCount(); i < componentsCount; i++)
1771 componentSource = prefabEntity.GetComponent(i);
1772 if (componentSource.GetClassName() == componentClassName)
1773 return componentSource;
SCR_EAIThreatSectorFlags flags
void ContainerIdPathEntry(string propertyName, int index=-1)
ref array< string > coords
ref array< string > angles
SCR_AIAnimation_Loitering BaseContainerProps
Commanding menu commanding element class.
ResourceName resourceName
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
class WorkbenchDialog_AbortRetryIgnore ButtonAttribute("OK", true)
Object holding reference to resource. In destructor release the resource.
Object used for holding filtering params for ResourceDatabase.SearchResources() method.
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
proto void PrintFormat(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL, LogLevel level=LogLevel.NORMAL)
SCR_FieldOfViewSettings Attribute
EntityFlags
Various entity flags.
PerceptionManagerClass GenericEntityClass GetTime()
array< string > TStringArray
array< ResourceName > TResourceNameArray