Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_ScenarioFrameworkUpdatePlugin.c
Go to the documentation of this file.
1#ifdef WORKBENCH
2// Only SlotAI, SlotKill and SlotDefend have WaypointSets
3
8 name: "Scenario Framework 1.0.0 -> 1.1.0 Update - phase 1",
9 shortcut: "", // "Ctrl+Alt+Z",
10 category: "Update/1.0.0 to 1.1.0",
11 wbModules: { "WorldEditor" },
12 awesomeFontCode: 0x0031, // 0xE54E, // F4D7? meh, more like pathing
13 description: "This plugin updates Scenario Framework Slots from the old (1.0.0) to the new (1.1.0+) standard")]
14class SCR_ScenarioFrameworkConversionPlugin_Phase1 : WorkbenchPlugin
15{
16 static const string GENERIC_CLASSNAME = "GenericEntity";
17
18 // Layer
19 static const string SLOT_WAYPOINT_PREFAB = "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et";
20 static const string SLOT_WAYPOINT_COMPONENT_CLASSNAME = "SCR_ScenarioFrameworkSlotWaypoint";
21 protected static const string LAYER_PREFAB = "{5F9FFF4BF027B3A3}Prefabs/ScenarioFramework/Components/Layer.et";
22 protected static const string CYCLE_WAYPOINT_CLASSNAME = "SCR_ScenarioFrameworkWaypointCycle";
23
24 // Base Slot
25 protected static const string BASE_SLOT_CLASSNAME = "SCR_ScenarioFrameworkSlotBase"; // for EXACT match
26 protected static const string SLOT_PREFAB = "{AA01691FDC4E9167}Prefabs/ScenarioFramework/Components/Slot.et"; // isKindOf
27 protected static const string BASE_SLOT_FIELD = "m_sObjectToSpawn"; // for EXACT match
28
29 // Waypoint Slots
30 protected static const string SLOT_AI_PREFAB = "{8D43830F02C3F114}Prefabs/ScenarioFramework/Components/SlotAI.et"; // isKindOf
31 protected static const string SLOT_KILL_PREFAB = "{C70DC6CBD1AAEC9A}Prefabs/ScenarioFramework/Components/SlotKill.et"; // isKindOf
32 protected static const string SLOT_DEFEND_PREFAB = "{E123BAC59A9B3D5F}Prefabs/ScenarioFramework/Components/SlotDefend.et"; // isKindOf
33 protected static const ref array<string> BASE_SLOTWP_CLASSNAMES = { // for EXACT match
34 "SCR_ScenarioFrameworkSlotAI",
35 "SCR_ScenarioFrameworkSlotKill",
36 "SCR_ScenarioFrameworkSlotDefend",
37 };
38 protected static const string BASE_SLOTWP_FIELD_FROM = "m_aWaypointGroupNames";
39 protected static const string BASE_SLOTWP_FIELD_TO = "m_WaypointSet";
40 static const string WAYPOINT_COMPONENT_FIELD = "m_Waypoint";
41 protected static const string WAYPOINT_CLASSNAME = "SCR_ScenarioFrameworkWaypointSet";
42 protected static const string CYCLE_SUFFIX = "_Cycle";
43
44 protected static const ref array<ref SCR_ScenarioFrameworkConversionPlugin_Rune> CONVERSION_TABLE = {};
45
46 //------------------------------------------------------------------------------------------------
47 override void Run()
48 {
49 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
50 if (!worldEditorAPI)
51 return;
52
53 bool manageEditAction = SCR_WorldEditorToolHelper.BeginEntityAction();
54
55 // TODO: optimise by obtaining all layers + all slots in one go
56 Debug.BeginTimeMeasure();
57 array<IEntitySource> allEntitySources = GetEntitySources();
58 Debug.EndTimeMeasure("Entities obtention (" + allEntitySources.Count() + " found)");
59
60 Debug.BeginTimeMeasure();
61 CreateCycleWaypoints(allEntitySources);
62 Debug.EndTimeMeasure("Cycle waypoints conversion");
63
64 Debug.BeginTimeMeasure();
65 Convert(allEntitySources);
66 Debug.EndTimeMeasure("" + allEntitySources.Count() + " entities conversion");
67
68 SCR_WorldEditorToolHelper.EndEntityAction(manageEditAction);
69 }
70
71 //------------------------------------------------------------------------------------------------
74 protected array<IEntitySource> GetEntitySources()
75 {
76 IEntitySource entitySource;
77 array<IEntitySource> result = {};
78 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
79 for (int i, count = worldEditorAPI.GetEditorEntityCount(); i < count; i++)
80 {
81 entitySource = worldEditorAPI.GetEditorEntity(i);
82 if (!entitySource)
83 continue;
84
85 if (!entitySource.GetAncestor())
86 continue;
87
88 if (entitySource.GetClassName() != GENERIC_CLASSNAME)
89 continue;
90
91 result.Insert(entitySource);
92 }
93
94 return result;
95 }
96
97 //------------------------------------------------------------------------------------------------
100 protected void CreateCycleWaypoints(notnull array<IEntitySource> allEntitySources)
101 {
103 array<ref SCR_WaypointSet> cycleWaypointSets = {};
104
105 GetLayersAndWaypointSets(allEntitySources, namedLayers, cycleWaypointSets);
106
107 if (namedLayers.IsEmpty())
108 return;
109
110 array<ref ContainerIdPathEntry> waypointPath = { new ContainerIdPathEntry(SLOT_WAYPOINT_COMPONENT_CLASSNAME) };
111 array<ref ContainerIdPathEntry> randomOrderBoolPath = {
112 new ContainerIdPathEntry(SLOT_WAYPOINT_COMPONENT_CLASSNAME),
113 new ContainerIdPathEntry(WAYPOINT_COMPONENT_FIELD),
114 };
115 IEntitySource namedLayer;
116 IEntitySource entitySource;
117 IEntity entity;
118 IEntityComponentSource componentSource;
119
120 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
121 bool manageEditAction = SCR_WorldEditorToolHelper.BeginEntityAction();
122
123 foreach (SCR_WaypointSet cycleWaypointSet : cycleWaypointSets)
124 {
125 namedLayer = namedLayers.Get(cycleWaypointSet.m_sName);
126 if (!namedLayer)
127 {
128 Print("Cycle waypoint set is targeting an unknown layer " + cycleWaypointSet.m_sName, LogLevel.WARNING);
129 continue;
130 }
131
132 string cycleWaypointEntityName = cycleWaypointSet.m_sName + CYCLE_SUFFIX;
133 entitySource = worldEditorAPI.FindEntityByName(cycleWaypointEntityName);
134 if (entitySource)
135 {
136 Print("Cycle waypoint already exists - " + cycleWaypointEntityName, LogLevel.WARNING);
137 continue;
138 }
139
140 entitySource = worldEditorAPI.CreateEntity(SLOT_WAYPOINT_PREFAB, cycleWaypointEntityName, namedLayer.GetLayerID(), namedLayer, vector.Zero, vector.Zero);
141 if (!entitySource)
142 {
143 Print("Failed to create cycle waypoint - " + cycleWaypointEntityName, LogLevel.WARNING);
144 continue;
145 }
146
147 if (!worldEditorAPI.FindEntityByName(cycleWaypointEntityName)) // CreateEntity bug
148 {
149 if (!worldEditorAPI.RenameEntity(entitySource, cycleWaypointEntityName) || !worldEditorAPI.FindEntityByName(cycleWaypointEntityName))
150 {
151 Print("Could not name cycle waypoint entity properly - " + cycleWaypointEntityName, LogLevel.WARNING);
152 worldEditorAPI.DeleteEntity(entitySource);
153 continue;
154 }
155 }
156
157 bool dealt;
158 for (int i, count = entitySource.GetComponentCount(); i < count; i++)
159 {
160 componentSource = entitySource.GetComponent(i);
161 if (!componentSource)
162 continue;
163
164 if (componentSource.GetClassName() != SLOT_WAYPOINT_COMPONENT_CLASSNAME) // exact match
165 continue;
166
167 // let's go, any issue is an error from here
168
169 if (!worldEditorAPI.CreateObjectVariableMember(entitySource, waypointPath, WAYPOINT_COMPONENT_FIELD, CYCLE_WAYPOINT_CLASSNAME))
170 {
171 Print("Cannot create component's waypoint - " + cycleWaypointEntityName, LogLevel.WARNING);
172 break;
173 }
174
175 if (!worldEditorAPI.SetVariableValue(entitySource, randomOrderBoolPath, "m_bUseRandomOrder", "1"))
176 {
177 Print("Cannot set component waypoint's UseRandomOrder value - " + cycleWaypointEntityName, LogLevel.WARNING);
178 break;
179 }
180
181 dealt = true;
182 break;
183 }
184
185 if (!dealt)
186 {
187 Print("Waypoint could not be set in SlotWaypoint - " + cycleWaypointEntityName, LogLevel.WARNING);
188 worldEditorAPI.DeleteEntity(entitySource);
189 }
190 }
191
192 SCR_WorldEditorToolHelper.EndEntityAction(manageEditAction);
193 }
194
195 //------------------------------------------------------------------------------------------------
199 protected void GetLayersAndWaypointSets(notnull array<IEntitySource> allEntitySources, out notnull map<string, IEntitySource> namedLayers, out notnull array<ref SCR_WaypointSet> cycleWaypointSets)
200 {
201 namedLayers.Clear();
202 cycleWaypointSets.Clear();
203
204 SCR_WaypointSet waypointSet;
205
206 BaseContainer ancestor;
207 IEntityComponentSource componentSource;
208 BaseContainerList waypointGroupNames;
209 BaseContainer waypointGroupName;
210 string name;
211 bool found, randomOrder, cycle;
212 foreach (IEntitySource entitySource : allEntitySources)
213 {
214 ancestor = entitySource.GetAncestor();
215 if (SCR_BaseContainerTools.IsKindOf(ancestor, LAYER_PREFAB))
216 {
217 name = entitySource.GetName();
218 if (name)
219 namedLayers.Insert(name, entitySource);
220 }
221 else
222 if (
223 SCR_BaseContainerTools.IsKindOf(ancestor, SLOT_AI_PREFAB) ||
224 SCR_BaseContainerTools.IsKindOf(ancestor, SLOT_KILL_PREFAB) ||
225 SCR_BaseContainerTools.IsKindOf(ancestor, SLOT_DEFEND_PREFAB))
226 {
227 for (int i, count = entitySource.GetComponentCount(); i < count; i++)
228 {
229 found = false;
230
231 componentSource = entitySource.GetComponent(i);
232 if (!componentSource) // how
233 continue;
234
235 name = componentSource.GetClassName();
236 if (!BASE_SLOTWP_CLASSNAMES.Contains(name)) // EXACT match
237 continue;
238
239 waypointGroupNames = componentSource.GetObjectArray("m_aWaypointGroupNames");
240 if (!waypointGroupNames)
241 continue;
242
243 for (int j, countJ = waypointGroupNames.Count(); j < countJ; j++)
244 {
245 waypointGroupName = waypointGroupNames.Get(j);
246 if (!waypointGroupName)
247 continue;
248
249 if (!waypointGroupName.Get("m_bCycleWaypoints", cycle)
250 || !cycle
251 || !waypointGroupName.Get("m_sName", name)
252 || !waypointGroupName.Get("m_bUseRandomOrder", randomOrder))
253 continue;
254
255 waypointSet = new SCR_WaypointSet();
256 waypointSet.m_sName = name;
257 waypointSet.m_bCycleWaypoints = cycle;
258 waypointSet.m_bUseRandomOrder = randomOrder;
259
260 cycleWaypointSets.Insert(waypointSet);
261 found = true;
262 }
263
264 if (found)
265 break;
266 }
267 }
268 }
269 }
270
271 //------------------------------------------------------------------------------------------------
273 protected void Convert(notnull array<IEntitySource> allEntitySources)
274 {
275 bool manageEditAction = SCR_WorldEditorToolHelper.BeginEntityAction();
276 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
277
278 IEntity entity;
279 IEntitySource ancestor;
280 foreach (IEntitySource entitySource : allEntitySources)
281 {
282 entity = worldEditorAPI.SourceToEntity(entitySource);
283 if (!entity) // how
284 continue;
285
286 ancestor = entitySource.GetAncestor();
287 if (SCR_BaseContainerTools.IsKindOf(ancestor, SLOT_PREFAB))
288 {
289 TryConvertSlot(entitySource);
290 }
291 else if (
292 SCR_BaseContainerTools.IsKindOf(ancestor, SLOT_AI_PREFAB) ||
293 SCR_BaseContainerTools.IsKindOf(ancestor, SLOT_KILL_PREFAB) ||
294 SCR_BaseContainerTools.IsKindOf(ancestor, SLOT_DEFEND_PREFAB))
295 {
296 TryAndConvertSlotWaypointGroups(entitySource);
297 }
298 }
299
300 SCR_WorldEditorToolHelper.EndEntityAction(manageEditAction);
301 }
302
303 //------------------------------------------------------------------------------------------------
305 protected void TryConvertSlot(notnull IEntitySource entitySource)
306 {
307 IEntityComponentSource componentSource;
308 ResourceName spawnedResourceName;
309 BaseContainer resourceBaseContainer;
310
311 for (int i, count = entitySource.GetComponentCount(); i < count; i++)
312 {
313 componentSource = entitySource.GetComponent(i);
314 if (!componentSource) // how
315 continue;
316
317 if (componentSource.GetClassName() != BASE_SLOT_CLASSNAME) // EXACT match
318 continue;
319
320 if (!componentSource.Get(BASE_SLOT_FIELD, spawnedResourceName)) // how
321 {
322 Print("Cannot obtain " + BASE_SLOT_FIELD + " value", LogLevel.WARNING);
323 continue;
324 }
325
326 if (spawnedResourceName.IsEmpty()) // OK
327 continue;
328
329 Resource resource = Resource.Load(spawnedResourceName);
330 if (!resource.IsValid())
331 {
332 Print("Invalid resource " + spawnedResourceName, LogLevel.WARNING);
333 continue;
334 }
335
336 resourceBaseContainer = resource.GetResource().ToBaseContainer();
337 if (!resourceBaseContainer) // how
338 {
339 Print("No base container for " + spawnedResourceName, LogLevel.WARNING);
340 continue;
341 }
342
343 bool didConvert;
344 foreach (SCR_ScenarioFrameworkConversionPlugin_Rune rune : CONVERSION_TABLE)
345 {
346 if (SCR_BaseContainerTools.IsKindOf(resourceBaseContainer, rune.m_sOldWaypointPrefab))
347 {
348 if (ConvertSlotTo(entitySource, componentSource, rune))
349 {
350 Print("Successfully temp converted " + rune.m_sOldWaypointPrefab + " to " + rune.m_sNewSlotPrefab, LogLevel.NORMAL);
351 didConvert = true;
352 }
353 else
354 {
355 Print("Failed to convert " + rune.m_sOldWaypointPrefab + " to " + rune.m_sNewSlotPrefab, LogLevel.WARNING);
356 }
357
358 break;
359 }
360 }
361
362 if (didConvert)
363 Print("Be sure to save, load the world and run the plugin's part two", LogLevel.WARNING);
364 }
365 }
366
367 //------------------------------------------------------------------------------------------------
372 protected bool ConvertSlotTo(notnull IEntitySource entitySource, notnull IEntitySource componentSource, notnull SCR_ScenarioFrameworkConversionPlugin_Rune rune)
373 {
374 array<IEntityComponentSource> oldComponentSources = {};
375 for (int i = entitySource.GetComponentCount() - 1; i >= 0; --i)
376 {
377 oldComponentSources.Insert(entitySource.GetComponent(i));
378 }
379
380 entitySource.SetAncestor(rune.m_sNewSlotPrefab);
381 if (entitySource.GetAncestor().GetResourceName() != rune.m_sNewSlotPrefab)
382 {
383 Print("Cannot change entitySource ancestor", LogLevel.ERROR);
384 return false;
385 }
386
387 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
388 string componentType = rune.m_ComponentType.ToString();
389 IEntityComponentSource newComponentSource = worldEditorAPI.CreateComponent(entitySource, componentType);
390 if (!newComponentSource)
391 {
392 Print("New component " + rune.m_ComponentType + " was not found in the new ancestor", LogLevel.ERROR);
393 return false;
394 }
395
396 if (!SCR_EntitySourceHelper.CopyDataFromOldToNewComponent(entitySource, componentSource, entitySource, newComponentSource))
397 {
398 Print("Old data cannot be ported over to new component", LogLevel.ERROR);
399 if (!worldEditorAPI.DeleteComponent(entitySource, newComponentSource))
400 Print("And the new component cannot be deleted - do it manually", LogLevel.ERROR);
401
402 return false;
403 }
404
405 int newComponentId = -1;
406 for (int i = entitySource.GetComponentCount() - 1; i >= 0; --i)
407 {
408 if (newComponentSource == entitySource.GetComponent(i))
409 {
410 newComponentId = i;
411 break;
412 }
413 }
414
415 if (newComponentId == -1)
416 {
417 Print("Cannot find the new component's id for path", LogLevel.ERROR);
418 return false;
419 }
420
421 if (!worldEditorAPI.ClearVariableValue(entitySource, { new ContainerIdPathEntry(componentType, newComponentId) }, BASE_SLOT_FIELD))
422 {
423 Print("Cannot clear field, do it manually - " + BASE_SLOT_FIELD, LogLevel.WARNING);
424 }
425
426 // create Waypoint instance
427 BaseContainer baseContainer = newComponentSource.GetObject(WAYPOINT_COMPONENT_FIELD);
428 if (baseContainer)
429 {
430 Print("Waypoint already set, skipping", LogLevel.WARNING);
431 }
432 else
433 {
434 array<ref ContainerIdPathEntry> path = { new ContainerIdPathEntry("components", newComponentId) };
435 string waypointClassname = ((typename)rune.m_WaypointClassType).ToString();
436 if (!worldEditorAPI.CreateObjectVariableMember(entitySource, path, WAYPOINT_COMPONENT_FIELD, waypointClassname))
437 {
438 Print("Cannot create the new waypoint", LogLevel.ERROR);
439 if (!worldEditorAPI.DeleteComponent(entitySource, newComponentSource))
440 Print("And the new component cannot be deleted - do it manually", LogLevel.ERROR);
441
442 return false;
443 }
444
445 // reset ALL values to default
446 // baseContainer.ClearVariables();
447 }
448
449 foreach (IEntityComponentSource oldComponentSource : oldComponentSources)
450 {
451 if (componentSource)
452 worldEditorAPI.DeleteComponent(entitySource, oldComponentSource);
453 }
454
455 return true;
456 }
457
458 //------------------------------------------------------------------------------------------------
461 protected void TryAndConvertSlotWaypointGroups(notnull IEntitySource entitySource)
462 {
463 string classname;
464 IEntityComponentSource componentSource;
465 array<ref SCR_WaypointSet> waypointGroupNameSets;
466 SCR_ScenarioFrameworkWaypointSet existingWaypointSet;
467 BaseContainer resourceBaseContainer;
468 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
469 for (int i, count = entitySource.GetComponentCount(); i < count; i++)
470 {
471 componentSource = entitySource.GetComponent(i);
472 if (!componentSource) // how
473 continue;
474
475 classname = componentSource.GetClassName();
476 if (!BASE_SLOTWP_CLASSNAMES.Contains(classname)) // EXACT match
477 continue;
478
479 if (!componentSource.Get(BASE_SLOTWP_FIELD_FROM, waypointGroupNameSets))
480 continue;
481
482 if (!waypointGroupNameSets) // OK
483 continue;
484
485 if (!componentSource.Get(BASE_SLOTWP_FIELD_TO, existingWaypointSet))
486 continue;
487
488 if (existingWaypointSet)
489 continue;
490
491 array<ref ContainerIdPathEntry> path = { new ContainerIdPathEntry("components", i) };
492
493 if (!worldEditorAPI.CreateObjectVariableMember(entitySource, path, BASE_SLOTWP_FIELD_TO, WAYPOINT_CLASSNAME))
494 {
495 Print("Cannot create " + WAYPOINT_CLASSNAME + " - " + entitySource.GetName(), LogLevel.ERROR);
496 continue;
497 }
498
499 path.Insert(new ContainerIdPathEntry(BASE_SLOTWP_FIELD_TO));
500
501 array<string> waypointNames = {};
502 foreach (int j, SCR_WaypointSet waypointSet : waypointGroupNameSets)
503 {
504 if (waypointSet.m_sName) // !.IsEmpty()
505 {
506 if (waypointSet.m_bCycleWaypoints)
507 waypointNames.Insert(waypointSet.m_sName + CYCLE_SUFFIX);
508 else
509 waypointNames.Insert(waypointSet.m_sName);
510 }
511 }
512
513 if (!worldEditorAPI.SetVariableValue(entitySource, path, "m_aLayerName", SCR_StringHelper.Join(",", waypointNames)))
514 {
515 Print("Cannot set waypoint name array values - " + entitySource.GetName(), LogLevel.ERROR);
516 continue;
517 }
518
519 if (!worldEditorAPI.ClearVariableValue(entitySource, { new ContainerIdPathEntry("components", i) }, BASE_SLOTWP_FIELD_FROM))
520 componentSource.ClearVariable(BASE_SLOTWP_FIELD_FROM);
521
522 if (componentSource.Get(BASE_SLOTWP_FIELD_FROM, waypointGroupNameSets) && (!waypointGroupNameSets || !waypointGroupNameSets.IsEmpty()))
523 {
524 Print("Cannot clear previous waypoint set; do it manually - " + entitySource.GetName(), LogLevel.WARNING);
525 }
526
527 Print("Successfully converted waypoints", LogLevel.DEBUG);
528 break;
529 }
530 }
531
532 //------------------------------------------------------------------------------------------------
533 // constructor
534 protected void SCR_ScenarioFrameworkConversionPlugin_Phase1()
535 {
536 if (!CONVERSION_TABLE.IsEmpty())
537 return;
538
539 array<ref SCR_ScenarioFrameworkConversionPlugin_Rune> runes = {
540 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Attack
541 "{1B0E3436C30FA211}Prefabs/AI/Waypoints/AIWaypoint_Attack.et",
542 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
545 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Capture Relay
546 "{EAAE93F98ED5D218}Prefabs/AI/Waypoints/AIWaypoint_CaptureRelay.et",
547 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
550 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Defend
551 "{93291E72AC23930F}Prefabs/AI/Waypoints/AIWaypoint_Defend.et",
552 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
555 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Defend CP
556 "{2A81753527971941}Prefabs/AI/Waypoints/AIWaypoint_Defend_CP.et",
557 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
560 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Defend Hierarchy
561 "{AAE8882E0DE0761A}Prefabs/AI/Waypoints/AIWaypoint_Defend_Hierarchy.et",
562 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
565 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Defend Large
566 "{FAD1D789EE291964}Prefabs/AI/Waypoints/AIWaypoint_Defend_Large.et",
567 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
570 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Defend Large CO
571 "{A33AF7FC5004F294}Prefabs/AI/Waypoints/AIWaypoint_Defend_Large_CO.et",
572 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
575 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Follow
576 "{A0509D3C4DD4475E}Prefabs/AI/Waypoints/AIWaypoint_Follow.et",
577 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
580 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Forced Move
581 "{06E1B6EBD480C6E0}Prefabs/AI/Waypoints/AIWaypoint_ForcedMove.et",
582 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
585 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Get In
586 "{712F4795CF8B91C7}Prefabs/AI/Waypoints/AIWaypoint_GetIn.et",
587 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
590 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Get In Nearest
591 "{B049D4C74FBC0C4D}Prefabs/AI/Waypoints/AIWaypoint_GetInNearest.et",
592 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
595 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Get Out
596 "{C40316EE26846CAB}Prefabs/AI/Waypoints/AIWaypoint_GetOut.et",
597 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
600 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Heal
601 "{36ED7C150D5BB654}Prefabs/AI/Waypoints/AIWaypoint_Heal.et",
602 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
605 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Loiter CO
606 "{4ECD14650D82F5CA}Prefabs/AI/Waypoints/AIWaypoint_Loiter_CO.et",
607 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
610 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Move
611 "{750A8D1695BD6998}Prefabs/AI/Waypoints/AIWaypoint_Move.et",
612 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
615 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Observation Post
616 "{97FB527ECC7CA49E}Prefabs/AI/Waypoints/AIWaypoint_ObservationPost.et",
617 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
620 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Open Gate
621 "{1966BC58CE769D69}Prefabs/AI/Waypoints/AIWaypoint_OpenGate.et",
622 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
625 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Patrol
626 "{22A875E30470BD4F}Prefabs/AI/Waypoints/AIWaypoint_Patrol.et",
627 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
630 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Attack
631 "{FBA8DC8FDA0E770D}Prefabs/AI/Waypoints/AIWaypoint_Patrol_Hierarchy.et",
632 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
635 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Scout
636 "{A88F0B6CF25BD1DE}Prefabs/AI/Waypoints/AIWaypoint_Scout.et",
637 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
640 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Search and Destroy
641 "{B3E7B8DC2BAB8ACC}Prefabs/AI/Waypoints/AIWaypoint_SearchAndDestroy.et",
642 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
645 new SCR_ScenarioFrameworkConversionPlugin_Rune( // User Action
646 "{04A06A6742FB0AF8}Prefabs/AI/Waypoints/AIWaypoint_UserAction.et",
647 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
650 new SCR_ScenarioFrameworkConversionPlugin_Rune( // Wait
651 "{531EC45063C1F57B}Prefabs/AI/Waypoints/AIWaypoint_Wait.et",
652 "{EBD91177954E8236}Prefabs/ScenarioFramework/Components/SlotWaypoint.et",
655 };
656
657 SCR_ArrayHelperRefT<SCR_ScenarioFrameworkConversionPlugin_Rune>.CopyReferencesFromTo(runes, CONVERSION_TABLE);
658 }
659}
660
661// Only SlotAI, SlotKill and SlotDefend have WaypointSets
662
667 name: "Scenario Framework 1.0.0 -> 1.1.0 Update - phase 2",
668 shortcut: "", // "Ctrl+Alt+S",
669 category: "Update/1.0.0 to 1.1.0",
670 wbModules: { "WorldEditor" },
671 awesomeFontCode: 0x0032, // 0xE54E,
672 description: "This plugin updates Scenario Framework Slots from the old (1.0.0) to the new (1.1.0+) standard")]
673class SCR_ScenarioFrameworkConversionPlugin_Phase2 : WorkbenchPlugin
674{
675 //------------------------------------------------------------------------------------------------
676 protected override void Run()
677 {
678 GetAllSlotWaypointWithTwoSlotWaypointComponentsAndRemoveUnsetOne();
679 }
680
681 //------------------------------------------------------------------------------------------------
683 protected void GetAllSlotWaypointWithTwoSlotWaypointComponentsAndRemoveUnsetOne()
684 {
685 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
686 if (!worldEditorAPI)
687 return;
688
689 bool manageEditAction = SCR_WorldEditorToolHelper.BeginEntityAction();
690
691 IEntitySource entitySource;
692 IEntitySource ancestor;
693 IEntityComponentSource componentSource;
694 array<IEntityComponentSource> sameComponents = {};
695 Debug.BeginTimeMeasure();
696 for (int i, count = worldEditorAPI.GetEditorEntityCount(); i < count; i++)
697 {
698 entitySource = worldEditorAPI.GetEditorEntity(i);
699 if (!entitySource)
700 continue;
701
702 ancestor = entitySource.GetAncestor();
703 if (!ancestor)
704 continue;
705
706 if (entitySource.GetClassName() != SCR_ScenarioFrameworkConversionPlugin_Phase1.GENERIC_CLASSNAME)
707 continue;
708
709 if (!SCR_BaseContainerTools.IsKindOf(ancestor, SCR_ScenarioFrameworkConversionPlugin_Phase1.SLOT_WAYPOINT_PREFAB))
710 continue;
711
712 int compNum;
713 sameComponents.Clear();
714 for (int j, countJ = entitySource.GetComponentCount() - 1; j < countJ; j++)
715 {
716 componentSource = entitySource.GetComponent(j);
717 if (!componentSource)
718 continue;
719
720 if (componentSource.GetClassName() == SCR_ScenarioFrameworkConversionPlugin_Phase1.SLOT_WAYPOINT_COMPONENT_CLASSNAME)
721 {
722 compNum++;
723 sameComponents.Insert(componentSource);
724 if (compNum == 3)
725 break;
726 }
727 }
728
729 if (compNum == 2) // no more, no less
730 {
731 componentSource = sameComponents[0];
732 IEntityComponentSource componentSource2 = sameComponents[1];
733 if (componentSource.IsVariableSetDirectly(SCR_ScenarioFrameworkConversionPlugin_Phase1.WAYPOINT_COMPONENT_FIELD))
734 {
735 SCR_EntitySourceHelper.CopyDataFromOldToNewComponent(entitySource, componentSource, entitySource, componentSource2);
736 worldEditorAPI.DeleteComponent(entitySource, componentSource);
737 }
738 else
739 {
740 SCR_EntitySourceHelper.CopyDataFromOldToNewComponent(entitySource, componentSource2, entitySource, componentSource);
741 worldEditorAPI.DeleteComponent(entitySource, componentSource2);
742 }
743 }
744 }
745
746 Debug.EndTimeMeasure("Moving data from temp component to Prefab's component");
747 SCR_WorldEditorToolHelper.EndEntityAction(manageEditAction);
748 }
749}
750
751// conversion runes, like in Indiana Jones and stuff
752class SCR_ScenarioFrameworkConversionPlugin_Rune
753{
754 ResourceName m_sOldWaypointPrefab;
755 ResourceName m_sNewSlotPrefab;
756 typename m_ComponentType;
757 typename m_WaypointClassType;
758
759 //------------------------------------------------------------------------------------------------
760 // constructor
766 void SCR_ScenarioFrameworkConversionPlugin_Rune(
767 ResourceName oldWaypointPrefab,
768 ResourceName newSlotPrefab,
769 typename componentType,
770 typename waypointClassType)
771 {
772 m_sOldWaypointPrefab = oldWaypointPrefab;
773 m_sNewSlotPrefab = newSlotPrefab;
774 m_ComponentType = componentType;
775 m_WaypointClassType = waypointClassType;
776 }
777}
778#endif
string path
void ContainerIdPathEntry(string propertyName, int index=-1)
Definition worldEditor.c:30
GenerateFlowMaps WorkbenchPlugin WorkbenchPluginAttribute("Regenerate river flow-maps", "Generate and save/overwrite river flow-maps", "", "", {"WorldEditor"}, "", 0xf773)
Definition FlowmapTool.c:59
override void Run()
void SCR_ScenarioFrameworkSlotWaypoint(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition Debug.c:13
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
static string Join(string separator, notnull array< string > pieces, bool joinEmptyEntries=true)
Definition Types.c:486
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
proto external string ToString()
Plain C++ pointer, no weak pointers, no memory management.