17class SCR_GeneratorBaseEntity : GeneratorBaseEntity
23 [
Attribute(defvalue:
"1",
category:
"Generation",
desc:
"Allow entities generation by this generator - useful in order to adjust shape and settings without generating unwanted entities\nKeep it ticked before saving!\nNote: does not prevent terrain shaping and other generator features")]
24 protected bool m_bEnableGeneration;
26 [
Attribute(defvalue: DEFAULT_SEED.ToString(),
category:
"Generation",
desc:
"Randomisation Seed used by this generator",
params:
string.Format(
"%1 %2", MIN_RANDOM_SEED, MAX_RANDOM_SEED))]
27 protected int m_iSeed;
30 protected bool m_bRandomiseSeedOnUse;
33 protected static const int DEFAULT_SEED = 42;
34 protected static const int MIN_RANDOM_SEED = 0;
35 protected static const int MAX_RANDOM_SEED = 0x7FFF;
41 protected int m_iSourceLayerID;
45 protected bool m_bIsChangingWorkbenchKey;
47 protected static const int BASE_GENERATOR_COLOUR =
Color.WHITE;
52 super._WB_OnParentChange(src, prevParentSrc);
55 if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
59 m_ParentShapeSource = m_Source.GetParent();
60 if (!m_ParentShapeSource
61 || !m_ParentShapeSource.GetClassName().ToType()
62 || !m_ParentShapeSource.GetClassName().ToType().IsInherited(ShapeEntity))
67 override bool _WB_OnKeyChanged(BaseContainer src,
string key, BaseContainerList ownerContainers,
IEntity parent)
69 super._WB_OnKeyChanged(src, key, ownerContainers, parent);
71 if (m_bIsChangingWorkbenchKey)
74 WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
75 if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
78 m_ParentShapeSource = GetShapeSource();
79 bool sameParentChange = parent && worldEditorAPI.EntityToSource(parent) == m_ParentShapeSource;
84 bool isSetDirectly = src.IsVariableSetDirectly(
"scale");
87 Print(
"Do not modify a generator entity itself! Change its parent shape instead",
LogLevel.WARNING);
89 m_bIsChangingWorkbenchKey =
true;
92 worldEditorAPI.ClearVariableValue(src, null,
"scale");
96 worldEditorAPI.SetVariableValue(src, null,
"scale",
"1");
97 Print(
"Generator has scale set in Prefab! " + src.GetResourceName(),
LogLevel.WARNING);
100 m_bIsChangingWorkbenchKey =
false;
106 bool isSetDirectly = src.IsVariableSetDirectly(
"angles");
108 if (sameParentChange)
109 Print(
"Do not modify a generator entity itself! Change its parent shape instead",
LogLevel.WARNING);
111 m_bIsChangingWorkbenchKey =
true;
114 worldEditorAPI.ClearVariableValue(src, null,
"angles");
118 worldEditorAPI.SetVariableValue(src, null,
"angles",
"0 0 0");
119 Print(
"Generator has angles set in Prefab! " + src.GetResourceName(),
LogLevel.WARNING);
122 m_bIsChangingWorkbenchKey =
false;
128 if (parent && key ==
"coords")
131 src.Get(
"coords",
coords);
132 bool isSetDirectly = src.IsVariableSetDirectly(
"coords");
133 if (isSetDirectly ||
coords != vector.Zero)
135 if (sameParentChange)
136 Print(
"Do not modify a generator entity itself! Change its parent shape instead",
LogLevel.WARNING);
138 m_bIsChangingWorkbenchKey =
true;
141 worldEditorAPI.ClearVariableValue(src, null,
"coords");
145 worldEditorAPI.SetVariableValue(src, null,
"coords",
"0 0 0");
146 Print(
"Generator has coords set in Prefab! " + src.GetResourceName(),
LogLevel.WARNING);
149 m_bIsChangingWorkbenchKey =
false;
153 ShapeEntity parentShape = ShapeEntity.Cast(parent);
155 m_ParentShapeSource = worldEditorAPI.EntityToSource(parentShape);
157 m_ParentShapeSource = null;
166 override bool _WB_CanSelect(IEntitySource src)
174 super.OnIntersectingShapeChangedXZInternal(shapeEntitySrc, other, mins, maxes);
175 m_ParentShapeSource = shapeEntitySrc;
179 override void OnShapeChangedInternal(IEntitySource shapeEntitySrc, ShapeEntity shapeEntity, array<vector> mins, array<vector> maxes)
181 super.OnShapeChangedInternal(shapeEntitySrc, shapeEntity, mins, maxes);
182 m_ParentShapeSource = shapeEntitySrc;
183 ResetGeneratorPosition(shapeEntity);
189 super.OnShapeInitInternal(shapeEntitySrc, shapeEntity);
190 m_ParentShapeSource = shapeEntitySrc;
195 protected void ResetGeneratorPosition(ShapeEntity shapeEntity = null)
197 WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
198 if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
201 bool manageEditAction = !worldEditorAPI.IsDoingEditAction();
202 if (manageEditAction)
203 worldEditorAPI.BeginEntityAction();
206 if (m_Source.IsVariableSetDirectly(
"coords"))
207 worldEditorAPI.ClearVariableValue(m_Source, null,
"coords");
209 if (m_Source.Get(
"coords",
coords) &&
coords != vector.Zero)
210 Print(
"Generator has coords set in Prefab! " + m_Source.GetResourceName(),
LogLevel.WARNING);
212 if (manageEditAction)
213 worldEditorAPI.EndEntityAction();
218 protected void DeleteAllChildren()
220 int count = m_Source.GetNumChildren();
224 WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
228 array<IEntitySource> entities = {};
229 for (
int i = m_Source.GetNumChildren() - 1; i >= 0; --i)
231 entities.Insert(m_Source.GetChild(i));
234 worldEditorAPI.DeleteEntities(entities);
239 protected static WorldEditorAPI GetWorldEditorAPI()
241 WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
245 return worldEditor.GetApi();
249 [
Obsolete(
"Use GetAnchorPoints instead")]
250 protected static array<vector> GetPoints(notnull IEntitySource shapeEntitySrc)
252 return GetAnchorPoints(shapeEntitySrc);
261 protected static array<vector> GetAnchorPoints(notnull IEntitySource shapeEntitySrc,
float offset = 0,
bool isShapeClosed =
false)
263 BaseContainerList points = shapeEntitySrc.GetObjectArray(
"Points");
267 array<vector> result = {};
269 for (
int i, count = points.Count(); i < count; ++i)
271 points.Get(i).Get(
"Position", pos);
278 return SCR_ParallelShapeHelper.GetOffsetPointsFromPoints(result, offset, isShapeClosed);
285 protected static array<vector> GetWorldAnchorPoints(notnull IEntitySource shapeEntitySrc)
287 WorldEditorAPI worldEditorAPI = GetWorldEditorAPI();
291 ShapeEntity shapeEntity = ShapeEntity.Cast(worldEditorAPI.SourceToEntity(shapeEntitySrc));
295 array<vector> result = {};
296 shapeEntity.GetPointsPositions(result);
298 foreach (
int i, vector point : result)
300 result[i] = shapeEntity.CoordToParent(point);
311 protected static array<vector> GetTesselatedShapePoints(notnull IEntitySource shapeEntitySrc,
float offset = 0,
bool isShapeClosed =
false)
313 WorldEditorAPI worldEditorAPI = GetWorldEditorAPI();
317 ShapeEntity shapeEntity = ShapeEntity.Cast(worldEditorAPI.SourceToEntity(shapeEntitySrc));
321 array<vector> result = {};
322 shapeEntity.GenerateTesselatedShape(result);
326 return SCR_ParallelShapeHelper.GetOffsetPointsFromPoints(result, offset, isShapeClosed);
332 protected static array<vector> GetWorldTesselatedShapePoints(notnull IEntitySource shapeEntitySrc)
334 WorldEditorAPI worldEditorAPI = GetWorldEditorAPI();
338 ShapeEntity shapeEntity = ShapeEntity.Cast(worldEditorAPI.SourceToEntity(shapeEntitySrc));
342 array<vector> result = {};
343 shapeEntity.GenerateTesselatedShape(result);
345 foreach (
int i, vector point : result)
347 result[i] = shapeEntity.CoordToParent(point);
356 map<int, ref ShapePointDataScriptBase> GetFirstPointDataMap(
typename wantedType = ShapePointDataScriptBase)
358 if (!m_ParentShapeSource)
361 BaseContainerList points = m_ParentShapeSource.GetObjectArray(
"Points");
365 map<int, ref ShapePointDataScriptBase> result =
new map<int, ref ShapePointDataScriptBase>();
367 array<ref ShapePointDataScriptBase> pointDataArray;
368 ShapePointDataScriptBase pointData;
369 for (
int i, pointsCount = points.Count(); i < pointsCount; ++i)
371 if (!points.Get(i).Get(
"Data", pointDataArray))
374 if (wantedType && wantedType != ShapePointDataScriptBase)
376 for (
int j = 0, countJ = pointDataArray.Count(); j < countJ; ++j)
378 pointData = pointDataArray[j];
379 if (pointData.IsInherited(wantedType))
381 result.Insert(i, pointData);
394 map<int, ref array<ref ShapePointDataScriptBase>> GetPointDataMap(
typename wantedType = ShapePointDataScriptBase)
396 if (!m_ParentShapeSource)
399 BaseContainerList points = m_ParentShapeSource.GetObjectArray(
"Points");
403 map<int, ref array<ref ShapePointDataScriptBase>> result =
new map<int, ref array<ref ShapePointDataScriptBase>>();
405 array<ref ShapePointDataScriptBase> pointDataArray;
406 for (
int i, pointsCount = points.Count(); i < pointsCount; ++i)
408 if (!points.Get(i).Get(
"Data", pointDataArray))
411 if (wantedType && wantedType != ShapePointDataScriptBase)
413 for (
int j = pointDataArray.Count() - 1; j >= 0; --j)
416 pointDataArray.RemoveOrdered(j);
420 if (!pointDataArray.IsEmpty())
421 result.Insert(i, pointDataArray);
423 pointDataArray = null;
431 protected void SetSeed()
434 if (m_bRandomiseSeedOnUse)
435 wantedSeed = Math.RandomInt(MIN_RANDOM_SEED, MAX_RANDOM_SEED);
437 wantedSeed = m_iSeed;
439 WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
443 IEntitySource source = worldEditorAPI.EntityToSource(
this);
444 IEntitySource ancestor = source.GetAncestor();
446 if (!ancestor || !ancestor.Get(
"m_iSeed", ancestorSeed))
447 ancestorSeed = DEFAULT_SEED;
449 m_bIsChangingWorkbenchKey =
true;
451 if (wantedSeed == ancestorSeed)
452 worldEditorAPI.ClearVariableValue(source, null,
"m_iSeed");
454 worldEditorAPI.SetVariableValue(source, null,
"m_iSeed", wantedSeed.ToString());
456 m_bIsChangingWorkbenchKey =
false;
459 m_iSeed = wantedSeed;
465 SCR_GeneratorBaseEntityClass prefabData = SCR_GeneratorBaseEntityClass.Cast(
GetPrefabData());
467 return Color.FromInt(BASE_GENERATOR_COLOUR);
469 return Color.FromInt(prefabData.m_Color.PackToInt());
473 override void _WB_OnCreate(IEntitySource src)
475 super._WB_OnCreate(src);
480 WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
481 if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
485 IEntitySource shapeEntitySrc = src.GetParent();
488 ShapeEntity shapeEntity = ShapeEntity.Cast(worldEditorAPI.SourceToEntity(shapeEntitySrc));
494 src.Get(
"Flags",
flags);
495 bool manageEditAction = !worldEditorAPI.IsDoingEditAction();
496 if (manageEditAction)
497 worldEditorAPI.BeginEntityAction();
499 worldEditorAPI.SetVariableValue(src, null,
"Flags", (
flags |
EntityFlags.EDITOR_ONLY).ToString());
501 if (manageEditAction)
502 worldEditorAPI.EndEntityAction();
507 protected void ColorShape()
512 WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
513 if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
516 IEntitySource parentSource = m_Source.GetParent();
520 array<ref ContainerIdPathEntry> containerPath = {};
523 string colorString =
string.Format(
"%1 %2 %3 %4", color.R(), color.G(), color.B(), color.A());
525 bool manageEditAction = !worldEditorAPI.IsDoingEditAction();
526 if (manageEditAction)
527 worldEditorAPI.BeginEntityAction();
529 worldEditorAPI.SetVariableValue(parentSource, containerPath,
"LineColor", colorString);
531 if (manageEditAction)
532 worldEditorAPI.EndEntityAction();
537 protected IEntitySource GetShapeSource()
541 Print(
"[SCR_GeneratorBaseEntity.GetShapeSource] no generator source available (" + __FILE__ +
" L" + __LINE__ +
")",
LogLevel.ERROR);
545 IEntitySource parentSource = m_Source.GetParent();
549 if (!parentSource.GetClassName().ToType() || !parentSource.GetClassName().ToType().IsInherited(ShapeEntity))
569 protected void SCR_GeneratorBaseEntity(IEntitySource src,
IEntity parent)
574 if (!_WB_GetEditorAPI())
578 m_iSourceLayerID = m_Source.GetLayerID();
582 WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
583 if (worldEditor && !ShapeEntity.Cast(parent) && !worldEditor.IsPrefabEditMode())
585 Print(
"A Generator is not a direct child of a shape - " +
Debug.GetEntityLinkString(
this),
LogLevel.WARNING);
589 m_ParentShapeSource = m_Source.GetParent();