Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_GeneratorBaseEntity.c
Go to the documentation of this file.
1 class SCR_GeneratorBaseEntityClass : GeneratorBaseEntityClass
2 {
4  ref Color m_Color;
5 }
6 
12 class SCR_GeneratorBaseEntity : GeneratorBaseEntity
13 {
14 
15 #ifdef WORKBENCH
16 
17  protected IEntitySource m_Source;
18  protected IEntitySource m_ParentShapeSource;
19 
20  protected bool m_bIsChangingWorkbenchKey;
21 
22  protected static const ref Color BASE_GENERATOR_COLOR = Color.White;
23  protected static const ref array<string> ACCEPTED_PARENT_CLASSNAMES = { "SplineShapeEntity", "PolylineShapeEntity" }; // hardcoded, ok for now
24 
25  //------------------------------------------------------------------------------------------------
26  override void _WB_OnParentChange(IEntitySource src, IEntitySource prevParentSrc)
27  {
28  super._WB_OnParentChange(src, prevParentSrc);
29 
30  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
31  if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
32  return;
33 
34  m_ParentShapeSource = src.GetParent();
35  if (!m_ParentShapeSource || !ACCEPTED_PARENT_CLASSNAMES.Contains(m_ParentShapeSource.GetClassName()))
36  DeleteAllChildren();
37  }
38 
39  //------------------------------------------------------------------------------------------------
40  override bool _WB_OnKeyChanged(BaseContainer src, string key, BaseContainerList ownerContainers, IEntity parent)
41  {
42  super._WB_OnKeyChanged(src, key, ownerContainers, parent);
43 
44  if (m_bIsChangingWorkbenchKey)
45  return false;
46 
47  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
48  if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
49  return true;
50 
51  bool sameParentChange = parent && worldEditorAPI.EntityToSource(parent) == m_ParentShapeSource;
52 
53  // keep the scale at 1
54  if (key == "scale")
55  {
56  if (sameParentChange)
57  Print("Do not modify a generator entity itself! Change its parent shape instead", LogLevel.WARNING);
58 
59  m_bIsChangingWorkbenchKey = true;
60  worldEditorAPI.SetVariableValue(src, null, "scale", "1");
61  m_bIsChangingWorkbenchKey = false;
62  }
63 
64  // keep the angles at 0
65  array<string> angles = { "angleX", "angleY", "angleZ" };
66  foreach (string angle : angles)
67  {
68  if (key == angle)
69  {
70  if (sameParentChange)
71  Print("Do not modify a generator entity itself! Change its parent shape instead", LogLevel.WARNING);
72 
73  m_bIsChangingWorkbenchKey = true;
74  worldEditorAPI.SetVariableValue(src, null, angle, "0");
75  m_bIsChangingWorkbenchKey = false;
76  }
77  }
78 
79  if (!parent) // if no parent, do not set to 0 0 0
80  return true; // do not warn about no parent here as the constructor does it
81 
82  // keep the generator at (relative) 0 0 0 as long as it has a parent
83  if (key == "coords")
84  {
85  vector coords;
86  src.Get("coords", coords);
87  if (coords != vector.Zero) // because this can trigger when changing parent shape's points
88  {
89  if (sameParentChange)
90  Print("Do not modify a generator entity itself! Change its parent shape instead", LogLevel.WARNING);
91 
92  m_bIsChangingWorkbenchKey = true;
93  worldEditorAPI.SetVariableValue(src, null, "coords", "0 0 0");
94  m_bIsChangingWorkbenchKey = false;
95  }
96  }
97 
98  ShapeEntity parentShape = ShapeEntity.Cast(parent);
99  if (parentShape)
100  m_ParentShapeSource = worldEditorAPI.EntityToSource(parentShape);
101  else
102  m_ParentShapeSource = null;
103 
104  // let's not save here for the moment
105  // BaseContainerTools.WriteToInstance(this, worldEditorAPI.EntityToSource(this));
106 
107  return true;
108  }
109 
110  //------------------------------------------------------------------------------------------------
111  override bool _WB_CanSelect(IEntitySource src)
112  {
113  return false;
114  }
115 
116  //------------------------------------------------------------------------------------------------
117  override void OnShapeChangedInternal(IEntitySource shapeEntitySrc, ShapeEntity shapeEntity, array<vector> mins, array<vector> maxes)
118  {
119  super.OnShapeChangedInternal(shapeEntitySrc, shapeEntity, mins, maxes);
120  m_ParentShapeSource = shapeEntitySrc;
121  ResetGeneratorPosition(shapeEntity);
122  }
123 
124  //------------------------------------------------------------------------------------------------
125  override void OnShapeInitInternal(IEntitySource shapeEntitySrc, ShapeEntity shapeEntity)
126  {
127  super.OnShapeInitInternal(shapeEntitySrc, shapeEntity);
128  m_ParentShapeSource = shapeEntitySrc;
129  ResetGeneratorPosition(shapeEntity);
130  }
131 
132  //------------------------------------------------------------------------------------------------
133  protected void ResetGeneratorPosition(ShapeEntity shapeEntity = null)
134  {
135  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
136  if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
137  return;
138 
139  bool manageEditAction = !worldEditorAPI.IsDoingEditAction();
140  if (manageEditAction)
141  worldEditorAPI.BeginEntityAction();
142 
143  worldEditorAPI.SetVariableValue(m_Source, null, "coords", "0 0 0");
144 
145  if (manageEditAction)
146  worldEditorAPI.EndEntityAction();
147  }
148 
149  //------------------------------------------------------------------------------------------------
151  protected void DeleteAllChildren()
152  {
153  int count = m_Source.GetNumChildren();
154  if (count < 1)
155  return;
156 
157  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
158  if (!worldEditorAPI)
159  return;
160 
161  array<IEntitySource> entities = {};
162  for (int i = m_Source.GetNumChildren() - 1; i >= 0; --i)
163  {
164  entities.Insert(m_Source.GetChild(i));
165  }
166  worldEditorAPI.DeleteEntities(entities);
167  }
168 
169  //------------------------------------------------------------------------------------------------
171  protected static array<vector> GetPoints(notnull IEntitySource shapeEntitySrc)
172  {
173  BaseContainerList points = shapeEntitySrc.GetObjectArray("Points");
174  if (!points)
175  return {};
176 
177  array<vector> result = {};
178  vector pos;
179  for (int i, count = points.Count(); i < count; ++i)
180  {
181  points.Get(i).Get("Position", pos);
182  result.Insert(pos);
183  }
184 
185  return result;
186  }
187 
188  //------------------------------------------------------------------------------------------------
190  protected array<vector> GetWorldAnchorPoints(notnull IEntitySource shapeEntitySrc)
191  {
192  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
193  if (!worldEditorAPI)
194  return null;
195 
196  ShapeEntity shapeEntity = ShapeEntity.Cast(worldEditorAPI.SourceToEntity(shapeEntitySrc));
197  if (!shapeEntity)
198  return null;
199 
200  array<vector> result = {};
201  shapeEntity.GetPointsPositions(result);
202 
203  vector matrix[4];
204  shapeEntity.GetTransform(matrix);
205 
206  for (int i, count = result.Count(); i < count; ++i)
207  {
208  result[i] = result[i].Multiply4(matrix);
209  }
210 
211  return result;
212  }
213 
214  //------------------------------------------------------------------------------------------------
216  protected array<vector> GetTesselatedShapePoints(notnull IEntitySource shapeEntitySrc)
217  {
218  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
219  if (!worldEditorAPI)
220  return null;
221 
222  ShapeEntity shapeEntity = ShapeEntity.Cast(worldEditorAPI.SourceToEntity(shapeEntitySrc));
223  if (!shapeEntity)
224  return null;
225 
226  array<vector> result = {};
227  shapeEntity.GenerateTesselatedShape(result);
228 
229  return result;
230  }
231 
232  //------------------------------------------------------------------------------------------------
234  protected array<vector> GetWorldTesselatedShapePoints(notnull IEntitySource shapeEntitySrc)
235  {
236  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
237  if (!worldEditorAPI)
238  return null;
239 
240  ShapeEntity shapeEntity = ShapeEntity.Cast(worldEditorAPI.SourceToEntity(shapeEntitySrc));
241  if (!shapeEntity)
242  return null;
243 
244  array<vector> result = {};
245  shapeEntity.GenerateTesselatedShape(result);
246 
247  vector matrix[4];
248  shapeEntity.GetTransform(matrix);
249 
250  for (int i, count = result.Count(); i < count; ++i)
251  {
252  result[i] = result[i].Multiply4(matrix);
253  }
254 
255  return result;
256  }
257 
258  //------------------------------------------------------------------------------------------------
259  protected Color GetColor()
260  {
262  if (!prefabData)
263  return Color.FromInt(BASE_GENERATOR_COLOR.PackToInt());
264 
265  return Color.FromInt(prefabData.m_Color.PackToInt());
266  }
267 
268  //------------------------------------------------------------------------------------------------
269  override void _WB_OnCreate(IEntitySource src)
270  {
271  super._WB_OnCreate(src);
272 
273  ColorShape();
274 
275  // when generator entity gets created by any edit activity (given by _WB_OnCreate event) then re-generate its generated content
276  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
277  if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
278  return;
279 
280  // re-generate content only if it's created with a parent
281  IEntitySource shapeEntitySrc = src.GetParent();
282  if (shapeEntitySrc)
283  {
284  ShapeEntity shapeEntity = ShapeEntity.Cast(worldEditorAPI.SourceToEntity(shapeEntitySrc));
285  if (shapeEntity)
286  OnShapeInit(shapeEntitySrc, shapeEntity);
287  }
288 
289  EntityFlags flags;
290  src.Get("Flags", flags);
291  bool manageEditAction = !worldEditorAPI.IsDoingEditAction();
292  if (manageEditAction)
293  worldEditorAPI.BeginEntityAction();
294 
295  worldEditorAPI.SetVariableValue(src, null, "Flags", (flags | EntityFlags.EDITOR_ONLY).ToString());
296 
297  if (manageEditAction)
298  worldEditorAPI.EndEntityAction();
299  }
300 
301  //------------------------------------------------------------------------------------------------
303  protected void ColorShape()
304  {
305  if (!m_Source)
306  return;
307 
308  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
309  if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
310  return;
311 
312  IEntitySource parentSource = m_Source.GetParent();
313  if (!parentSource)
314  return;
315 
316  array<ref ContainerIdPathEntry> containerPath = {};
317 
318  Color color = GetColor();
319  string colorString = string.Format("%1 %2 %3 %4", color.R(), color.G(), color.B(), color.A());
320 
321  bool manageEditAction = !worldEditorAPI.IsDoingEditAction();
322  if (manageEditAction)
323  worldEditorAPI.BeginEntityAction();
324 
325  worldEditorAPI.SetVariableValue(parentSource, containerPath, "LineColor", colorString);
326 
327  if (manageEditAction)
328  worldEditorAPI.EndEntityAction();
329  }
330 
331 #endif // WORKBENCH
332 
333  //------------------------------------------------------------------------------------------------
334  // constructor
335  void SCR_GeneratorBaseEntity(IEntitySource src, IEntity parent)
336  {
337 
338 #ifdef WORKBENCH
339 
340  if (!_WB_GetEditorAPI()) // thumbnail generation
341  return;
342 
343  m_Source = src;
344 
345  WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
346  if (worldEditor && !worldEditor.IsPrefabEditMode() && !ShapeEntity.Cast(parent))
347  {
348  Print("A Generator is not a direct child of a shape at " + GetOrigin(), LogLevel.WARNING);
349  return;
350  }
351 
352  m_ParentShapeSource = m_Source.GetParent();
353 
354 #endif // WORKBENCH
355 
356  }
357 }
SCR_GeneratorBaseEntity
SCR_GeneratorBaseEntityClass GeneratorBaseEntityClass SCR_GeneratorBaseEntity(IEntitySource src, IEntity parent)
Definition: SCR_GeneratorBaseEntity.c:335
GetPrefabData
SCR_VehicleDamageManagerComponentClass GetPrefabData()
Definition: SCR_VehicleDamageManagerComponent.c:260
GetOrigin
vector GetOrigin()
Definition: SCR_AIUtilityComponent.c:279
Attribute
typedef Attribute
Post-process effect of scripted camera.
m_Source
protected IEntitySource m_Source
Definition: SCR_PowerPole.c:14
GetColor
Color GetColor()
Definition: SCR_EditableCommentComponent.c:52
SCR_GeneratorBaseEntityClass
Definition: SCR_GeneratorBaseEntity.c:1