Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_BatchPrefabsOperationsTool.c
Go to the documentation of this file.
1#ifdef WORKBENCH
5
8
15[WorkbenchToolAttribute("Batch prefabs operations tool", "### Creating new prefabs ###\nTo create new prefabs you need to fill 'Prefab Config', 'Path To Save' and\n'Models To Process'\n\nIf Generate Names is checked, there is no need to fill in New Names array\nUse Prefab Config to store additional settings in new prefab.\n\nOnce everything is set, click on 'Create' button to create new prefabs\n\n### Modifying existing prefabs ###\nTo modify prefabs you need to have at least one prefab in\n'Prefabs To Process' array selected & valid config selected in\n'Prefabs Config'\n\nWith those 2 parameters set, click on 'Modify' button to modify selected prefabs", "2", awesomeFontCode: 0xF085)]
16class SCR_BatchPrefabsOperationsTool : WorldEditorTool
17{
18 [Attribute("1", UIWidgets.ComboBox, "File system where new prefabs will be created", "", SCR_ParamEnumArray.FromAddons(), "General")]
19 protected int m_iAddonToUse;
20
21 [Attribute("", UIWidgets.ResourceNamePicker, "Choose a base class of your prefabs.", "et", null, "Create")]
22 protected ResourceName m_sBaseClass;
23
24 [Attribute("", UIWidgets.ResourceNamePicker, "Choose a path to save your prefabs.", "unregFolders", null, "Create")]
25 protected ResourceName m_sPathToSave;
26
27 [Attribute("", UIWidgets.ResourceAssignArray, "Choose XOB files to process.", "xob", null, "Create")]
28 protected ref array<ResourceName> m_aModelsToProcess;
29
30 [Attribute("", UIWidgets.EditBox, "Choose new names of your prefabs.", "et", null, "Create")]
31 protected ref array<string> m_aNewNames;
32
33 [Attribute("", UIWidgets.CheckBox, "Generate names from source files.","", null, "Create")]
34 protected bool m_bGenerateNames;
35
36 [Attribute("", UIWidgets.ResourceAssignArray, "Choose prefabs to process.", "et", null, "Modify")]
37 protected ref array<ResourceName> m_aPrefabsToProcess;
38
39 [Attribute(defvalue: "", desc: "All prefabs in this directory will be processed. Replaces Prefabs To Process array", params: "unregFolders", category: "Modify")]
40 protected ResourceName m_sDirectoryToProcess;
41
42 [Attribute("", UIWidgets.ResourceNamePicker, "Pick a config with template configuration.", "conf", null, "Modify")]
43 protected ResourceName m_sPrefabConfig;
44
45 //------------------------------------------------------------------------------------------------
51 protected void ProcessComponents(IEntitySource entSrc, SCR_BatchPrefabTemplates prefabGeneratorConfig)
52 {
53 IEntityComponentSource component;
54 array<ref ContainerIdPathEntry> containerPath = {};
55 foreach (SCR_BatchPrefabTemplatesData currentComp : prefabGeneratorConfig.m_ComponentsArray)
56 {
57 int action = currentComp.m_ComponentAction;
58
59 // Check if component already exists
60 component = SCR_BaseContainerTools.FindComponentSource(entSrc, currentComp.m_ComponentName);
61 if (!component)
62 {
63 // Return if modify only flag is used
64 if (action == 2)
65 return;
66
67 // Create new component
68 component = m_API.CreateComponent(entSrc, currentComp.m_ComponentName);
69 }
70
71 // Delete component
72 if (action == 4)
73 {
74 bool success = m_API.DeleteComponent(entSrc, component);
75 if (!success)
76 Print("Unable to delete " + currentComp.m_ComponentName + " from " + entSrc + ". Component is probably inherited", LogLevel.WARNING);
77
78 return;
79 }
80
81 containerPath.Clear();
82 containerPath.Insert(new ContainerIdPathEntry(currentComp.m_ComponentName));
83 ProcessAttributes(entSrc, component, containerPath, currentComp.m_ComponentAttributesArray);
84 //ProcessAttributes(entSrc,containerPath,currentComp.m_SubAttributesArray);
85 }
86 }
87
88 //------------------------------------------------------------------------------------------------
96 protected void ProcessAttributes(IEntitySource entSrc, IEntitySource entSrcAttribute, array<ref ContainerIdPathEntry> containerPath, array<ref SCR_BatchPrefabTemplatesAttributes> TemplateData)
97 {
98 // Add atributes to currently processed component
99 foreach (int currentAtributeIndex, SCR_BatchPrefabTemplatesAttributes currentAttribute : TemplateData)
100 {
101 string attributeName = currentAttribute.m_AttributeName;
102 string attributeValue = currentAttribute.m_AttributeValue;
103 int attributeOperation = currentAttribute.m_AttributeOperation;
104 if (attributeOperation == SCR_EBatchPrefabOperationFlag.MATH)
105 {
106 float m_fCurrentValue;
107 entSrcAttribute.Get(attributeName, m_fCurrentValue);
108
109 // Remove * & / signs from string since ToFloat cannot cope with it
110 string attributeValueShort = attributeValue;
111 attributeValueShort.Replace("*","");
112 attributeValueShort.Replace("/","");
113 float operand = attributeValueShort.ToFloat();
114 if (attributeValue.StartsWith("+") || attributeValue.StartsWith("-"))
115 m_fCurrentValue = m_fCurrentValue + operand;
116
117 if (attributeValue.StartsWith("/"))
118 m_fCurrentValue = m_fCurrentValue / operand; // TODO: Catch division by zero
119
120 if (attributeValue.StartsWith("*"))
121 m_fCurrentValue = m_fCurrentValue * operand;
122
123 attributeValue = m_fCurrentValue.ToString();
124 }
125
126 if (attributeOperation == SCR_EBatchPrefabOperationFlag.ENUM)
127 {
128 int m_iCurrentValue;
129 entSrcAttribute.Get(attributeName, m_iCurrentValue);
130 if (attributeValue.StartsWith("+"))
131 m_iCurrentValue = m_iCurrentValue | attributeValue.ToInt();
132
133 if (attributeValue.StartsWith("-"))
134 m_iCurrentValue = m_iCurrentValue &~ attributeValue.ToInt();
135
136 attributeValue = m_iCurrentValue.ToString();
137 }
138
139 m_API.SetVariableValue(entSrc, containerPath, attributeName, attributeValue);
140 //ProcessAttributes(entSrc,containerPath,currentAttribute.m_SubAttributesArray);
141 }
142 }
143
144 //------------------------------------------------------------------------------------------------
153 [ButtonAttribute("Create")]
154 protected void Execute()
155 {
156 // Input parameters verification
157 if (!m_aModelsToProcess)
158 {
159 Print("Models To Process is empty. Please fill it with at least one model", LogLevel.ERROR);
160 return;
161 }
162
163 if (!m_sPathToSave)
164 {
165 Print("Path To Save is empty. Please select valid save location", LogLevel.ERROR);
166 return;
167 }
168
169 if (!m_sBaseClass)
170 {
171 Print("Base Class is empty. Please select valid base prefab for your window", LogLevel.ERROR);
172 return;
173 }
174
175 if (!m_bGenerateNames && !m_aNewNames)
176 {
177 Print("New Names and Generate Names are empty. Please either check Generate Names or type in new names", LogLevel.ERROR);
178 return;
179 }
180
181 // Strip GUID
182 if (m_sPathToSave.Contains("{") && m_sPathToSave.Contains("}"))
183 {
184 int guidBracket = m_sPathToSave.IndexOf("}");
185 m_sPathToSave = m_sPathToSave.Substring(guidBracket+ 1, m_sPathToSave.Length() - guidBracket - 1);
186 }
187
188 // Get addon
189 string addon = SCR_AddonTool.ToFileSystem(SCR_AddonTool.GetAddonID(m_iAddonToUse));
190
191 // Get absolute path for CreateEntityTemplate
192 string absPath;
193 Workbench.GetAbsolutePath(addon + m_sPathToSave, absPath);
194
195 string tempName;
196
197 IEntitySource entitySource;
198 array<ref ContainerIdPathEntry> containerPath;
199 Resource holder;
200 SCR_BatchPrefabTemplates prefabGeneratorConfig;
201 int layerId = m_API.GetCurrentEntityLayerId();
202 foreach (int currentIndex, ResourceName currentElement : m_aModelsToProcess)
203 {
204 // Load metafile and get resource GUID
205 string modelName = currentElement;
206
207 Print("Processing " + string.Format("@\"%1\"", currentElement.GetPath()), LogLevel.NORMAL);
208
209 m_API.BeginEntityAction("Processing " + modelName);
210
211 // Create entity with selected base class
212 entitySource = m_API.CreateEntity(m_sBaseClass, string.Empty, layerId, null, vector.Zero, vector.Zero);
213
214 containerPath = {};
215
216 // Try to find MeshObject component and if it doesn't exist, then create new one
217 if (!(SCR_BaseContainerTools.FindComponentSource(entitySource, "MeshObject")))
218 m_API.CreateComponent(entitySource, "MeshObject");
219
220 containerPath.Clear();
221 containerPath.Insert(new ContainerIdPathEntry("MeshObject"));
222 m_API.SetVariableValue(entitySource, containerPath, "Object", modelName);
223
224 if (m_sPrefabConfig)
225 {
226 holder = BaseContainerTools.LoadContainer(m_sPrefabConfig);
227 if (!holder)
228 return;
229
230 // Process attributes from config
231 prefabGeneratorConfig = SCR_BatchPrefabTemplates.Cast(BaseContainerTools.CreateInstanceFromContainer(holder.GetResource().ToBaseContainer()));
232 ProcessAttributes(entitySource, entitySource, containerPath, prefabGeneratorConfig.m_AttributesArray);
233 ProcessComponents(entitySource, prefabGeneratorConfig);
234 }
235
236 // Generate new name based on xob file name. If not checked, then custom one is used
237 if (m_bGenerateNames)
238 {
239 array<string> tempArray = {};
240 modelName.Split("/", tempArray, false);
241 tempName = tempArray[tempArray.Count()-1];
242 tempName.Replace(".xob","");
243 }
244 else
245 {
246 tempName = m_aNewNames[currentIndex];
247 }
248
249 // Create file
250 bool fileCreated = m_API.CreateEntityTemplate(entitySource, FilePath.Concat(absPath, tempName + ".et"));
251
252 // End entity manipulation
253 m_API.DeleteEntity(entitySource);
254 m_API.EndEntityAction();
255 }
256 }
257
258 //------------------------------------------------------------------------------------------------
262 [ButtonAttribute("Modify")]
263 protected void ExecuteModify()
264 {
265 // Input parameters verification
266 if (!m_aPrefabsToProcess && !m_sDirectoryToProcess)
267 {
268 Print("m_aPrefabsToProcess & m_sDirectoryToProcess is empty. Please fill with at least one prefab", LogLevel.ERROR);
269 return;
270 }
271
272 if (!m_sPrefabConfig)
273 {
274 Print("Missing config file for batch prefab operation!", LogLevel.ERROR);
275 return;
276 }
277
278 if (!m_sDirectoryToProcess.IsEmpty())
279 {
280 string addon = SCR_AddonTool.ToFileSystem(SCR_AddonTool.GetAddonID(m_iAddonToUse));
281
282 // Get all prefabs from the selected subdirectory
283 SearchResourcesFilter filter = new SearchResourcesFilter();
284 filter.fileExtensions = { "et" };
285 filter.rootPath = addon + m_sDirectoryToProcess.GetPath();
286 ResourceDatabase.SearchResources(filter, m_aPrefabsToProcess.Insert);
287
288 Print("Processing " + m_aPrefabsToProcess.Count(), LogLevel.NORMAL);
289
290 // Exit if there are no valid prefabs in selected folder
291 if (m_aPrefabsToProcess.IsEmpty())
292 {
293 Print("There are no valid prefabs in selected folder", LogLevel.ERROR);
294 return;
295 }
296 }
297
298 IEntitySource entitySource;
299 IEntitySource prefab;
300 array<ref ContainerIdPathEntry> containerPath;
301 Resource holder;
302 SCR_BatchPrefabTemplates prefabGeneratorConfig;
303 int layerId = m_API.GetCurrentEntityLayerId();
304 foreach (int currentIndex, ResourceName currentElement : m_aPrefabsToProcess)
305 {
306 // Load metafile and get resource GUID
307 string modelName = currentElement;
308
309 Print("Processing " + string.Format("@\"%1\"", currentElement.GetPath()), LogLevel.NORMAL);
310 //m_API.BeginEntityAction("Processing - " + modelName);
311
312 // Create entity with selected base class
313 entitySource = m_API.CreateEntity(currentElement, string.Empty, layerId, null, vector.Zero, vector.Zero);
314
315 prefab = entitySource.GetAncestor();
316
317 containerPath = {};
318
319 // Load config and verify if its valid one
320 holder = BaseContainerTools.LoadContainer(m_sPrefabConfig);
321 if (!holder)
322 return;
323
324 // Process all attributes from config
325 prefabGeneratorConfig = SCR_BatchPrefabTemplates.Cast(BaseContainerTools.CreateInstanceFromContainer(holder.GetResource().ToBaseContainer()));
326 ProcessAttributes(prefab, prefab, containerPath, prefabGeneratorConfig.m_AttributesArray);
327 ProcessComponents(prefab, prefabGeneratorConfig);
328
329 // if we use 'entitySource' to modify prefab instance
330 // if we use 'entitySource.GetAncestor()' to modify prefab (first prefab in prefab hierarchy)
331 m_API.DeleteEntity(entitySource);
332 //m_API.EndEntityAction();
333 }
334
335 WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
336 worldEditor.Save(); // invoke world editor save to save changes to the prefab
337 }
338}
339
341class SCR_BatchPrefabTitle : BaseContainerCustomTitle
342{
343 protected string m_aParamString[4];
344
345 //------------------------------------------------------------------------------------------------
346 // constructor
347 void SCR_BatchPrefabTitle(string paramString1, string paramString2 = "", string paramString3 = "", string paramString4 = "")
348 {
349 m_aParamString[0] = paramString1;
350 m_aParamString[1] = paramString2;
351 m_aParamString[2] = paramString3;
352 m_aParamString[3] = paramString4;
353 }
354
355 //------------------------------------------------------------------------------------------------
356 override bool _WB_GetCustomTitle(BaseContainer source, out string title)
357 {
358 string temp;
359 string prop;
360 for (int i = 1; i <= 4; i++)
361 {
362 temp = "";
363 prop = m_aParamString[i - 1];
364 if (!source.Get(prop, temp))
365 temp = prop;
366
367 title = title + temp;
368 }
369
370 return title != string.Empty;
371 }
372}
373
375enum SCR_EBatchPrefabOperationFlag
376{
377 REPLACE = 1,
378 MATH = 2,
379 ENUM = 4
380}
381
382enum SCR_EBatchPrefabOperationComponentFlag
383{
384 CREATE = 1,
385 MODIFY = 2,
386 DELETE = 4
387}
388
389[BaseContainerProps(configRoot: true)]
390class SCR_BatchPrefabTemplates
391{
392 [Attribute(desc: "Array of attributes which be aplied to prefab (not to its components)")]
393 ref array<ref SCR_BatchPrefabTemplatesAttributes> m_AttributesArray;
394
395 [Attribute(desc: "Array of components which will be added or modified")]
396 ref array<ref SCR_BatchPrefabTemplatesData> m_ComponentsArray;
397}
398
399[BaseContainerProps(configRoot: false), SCR_BatchPrefabTitle("Component: ", "m_ComponentName")]
400class SCR_BatchPrefabTemplatesData
401{
402 [Attribute(desc: "Name of component to modify or add")]
403 string m_ComponentName;
404
405 [Attribute(defvalue: "1", UIWidgets.ComboBox, desc: "Create new component if its missing prefab", enumType: SCR_EBatchPrefabOperationComponentFlag)]
406 SCR_EBatchPrefabOperationComponentFlag m_ComponentAction;
407
408 [Attribute(desc: "Array of attributes which will be modified inside component belonging to prefab. If component is not present, new one will be created")]
409 ref array<ref SCR_BatchPrefabTemplatesAttributes> m_ComponentAttributesArray;
410}
411
412[BaseContainerProps(configRoot: false), SCR_BatchPrefabTitle("m_AttributeName",": ","m_AttributeValue")]
413class SCR_BatchPrefabTemplatesAttributes
414{
415 [Attribute(desc: "Name of attribute to modify")]
416 string m_AttributeName;
417
418 [Attribute(desc: "Value which will be stored in prefab. Simple math (adding, multiplying & dividing) & bitwise operations are allowed (use + to add and - to remove flag)")]
419 string m_AttributeValue;
420
421 [Attribute("1", UIWidgets.ComboBox, category: "", desc: "Specifies type of operation that is performed.", enumType: SCR_EBatchPrefabOperationFlag)]
422 SCR_EBatchPrefabOperationFlag m_AttributeOperation;
423
424 [Attribute(desc: "Feature not implemented yet!")]
425 ref array<ref SCR_BatchPrefabTemplatesAttributes> m_SubAttributesArray;
426}
427#endif // WORKBENCH
void ContainerIdPathEntry(string propertyName, int index=-1)
Definition worldEditor.c:30
bool Execute(notnull SCR_AIGroupUtilityComponent groupUtility, vector targetPosition, SCR_AIActivitySmokeCoverFeatureProperties smokeCoverProperties, notnull array< AIAgent > avoidAgents, notnull array< AIAgent > excludeAgents, int maxPositionCount=1, SCR_AIActivityBase contextActivity=null)
SCR_AIAnimation_Loitering BaseContainerProps
Commanding menu commanding element class.
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
class WorkbenchDialog_AbortRetryIgnore ButtonAttribute("OK", true)
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
@ DELETE
Further load on the instance is aborted and is deleted immediately.
class SCR_BaseManualCameraComponent _WB_GetCustomTitle(BaseContainer source, out string title)