Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
GridSpawnerEntity.c
Go to the documentation of this file.
1 // #define DEBUG_PRINT
2 // #define KC_ALPHA_CONTROLS
3 [EntityEditorProps(category: "GameScripted/Utility", description: "Entity used for spawning grids filled with models", color: "0 0 255 255")]
4 class SCR_GridSpawnerEntityClass: GenericEntityClass
5 {
6 };
7 
9 {
10  GSOT_NONE = 0,
13 };
14 
15 //------------------------------------------------------------------------------------------------
20 {
21 
23  [Attribute("100", UIWidgets.Slider, "The amount of objects to spawn", "0 100000 1")]
24  private int m_iObjectsCount;
25 
27  [Attribute("0", UIWidgets.CheckBox, "If enabled, bounding boxes will not be taken into account, spacing will be absolute", "")]
28  private bool m_bUseAbsoluteSpacing;
29 
31  [Attribute("0.1", UIWidgets.Slider, "Spacing between each entity (counting with BBOX)", "-5 50 0.05")]
32  private float m_fSpacing;
33 
35  [Attribute("0", UIWidgets.Slider, "Seed used for randomized rotations. Leave 0 for no randomization.", "0 1337 1")]
36  private int m_iRandomizationSeed;
37 
40  [Attribute("", UIWidgets.EditBox, "List of entities in text file. Overrides the default array if not empty.", "")]
41  private string m_sObjectsListPath;
42 
44  [Attribute("", UIWidgets.ResourceNamePicker, "Assets to be spawned. Models (xob) or prefabs (et).", "xob et")]
45  private ref array<ResourceName> m_aObjects;
46 
48  private ref array<IEntity> m_aSpawnedEntities = null;
49 
50  //------------------------------------------------------------------------------------------------
51  sealed array<IEntity> GetSpawnedEntities()
52  {
53  return m_aSpawnedEntities;
54  }
55 
56  //------------------------------------------------------------------------------------------------
57  protected int GetObjectCount()
58  {
59  if (m_aObjects)
60  return m_aObjects.Count();
61  else
62  return 0;
63  }
64 
65  //------------------------------------------------------------------------------------------------
66  protected bool GetObjectName(int index, out string name)
67  {
68  if (m_aObjects)
69  {
70  if (index >= 0 && index < GetObjectCount())
71  {
72  name = m_aObjects[index];
73  return true;
74  }
75  }
76 
77  return false;
78  }
79 
80  //------------------------------------------------------------------------------------------------
81  private int GetObjectType(string object)
82  {
83  if (object == string.Empty)
84  return GridSpawnerObjectType.GSOT_NONE;
85 
86  int lastDotIndex = object.LastIndexOf(".");
87  int count = object.Length();
88  string ext = object.Substring(lastDotIndex, count-lastDotIndex);
89 
90  switch (ext)
91  {
92  case ".et":
93  return GridSpawnerObjectType.GSOT_TEMPLATE;
94 
95  case ".xob":
96  return GridSpawnerObjectType.GSOT_MODEL;
97 
98  default:
99  return GridSpawnerObjectType.GSOT_NONE;
100  }
101 
102  return false;
103  }
104 
105  //------------------------------------------------------------------------------------------------
108  bool Spawn(int index)
109  {
110  vector v;
111  return Spawn(index, v);
112  }
113 
114 
115  //------------------------------------------------------------------------------------------------
118  protected bool Spawn(int index, out vector centerPoint)
119  {
120  // Not in game, bailing out.
121  BaseWorld baseWorld = GetGame().GetWorld();
122  if (!baseWorld)
123  return false;
124 
125  // No array of objects, bail out.
126  if (!m_aObjects)
127  {
128  #ifdef DEBUG_PRINT
129  Print("GridSpawner: Error, no objects specified!", LogLevel.ERROR);
130  #endif
131  return false;
132  }
133 
134  // Index out of range, bail out.
135  int objectsCount = m_aObjects.Count();
136  if (index < 0 || index >= objectsCount)
137  {
138  #ifdef DEBUG_PRINT
139  Print("GridSpawner: Error, index " + index + " is out of bounds!", LogLevel.ERROR);
140  #endif
141  return false;
142  }
143 
144 
145  ResourceName object = m_aObjects[index];
146 
147  // Empty string, bailing out.
148  if (object == string.Empty)
149  return false;
150 
151  // Check if object is .et or .xob, else bail out.
152  int type = GetObjectType(object);
153  if (type == GridSpawnerObjectType.GSOT_NONE)
154  {
155  #ifdef DEBUG_PRINT
156  Print("GridSpawnerEntity: Trying to spawn an invalid object. You must specify a valid template (.et) or mesh (.xob).", LogLevel.ERROR);
157  #endif
158  return false;
159  }
160 
161  // Delete existing entities if they exist and create new array
162  if (m_aSpawnedEntities)
163  DeleteEntities();
164 
165  if (!m_aSpawnedEntities)
166  m_aSpawnedEntities = new array<IEntity>();
167 
168  // Get origin, cell size and resource
169  vector currentPosition = GetOrigin();
170  int countPerAxis = Math.Floor(Math.Sqrt(m_iObjectsCount));
171  Resource resource = Resource.Load(object);
172  IEntity spawnedObject = null;
173 
174  // Define spacing - if not absolute, get data from bounding box, add spacing to that
175  float spacing = m_fSpacing;
176 
177  // Set randomization seed, if we want randomization (!= 0)
178  if (m_iRandomizationSeed != 0)
179  {
180  Math.Randomize(m_iRandomizationSeed);
181  }
182 
183  // If relative (i.e. based on model bounds) spacing is desired,
184  // spawn a dummy object and read data from it before deleting it
185  if (!m_bUseAbsoluteSpacing)
186  {
187  // Get identity matrix
188  vector dummyMatrix[4];
189  Math3D.MatrixIdentity4(dummyMatrix);
190 
191  // .........
192  // let's not talk about this
193  const float dummyOffset = -999;
194  for (int i = 0; i < 3; i++)
195  dummyMatrix[3][i] = dummyOffset;
196 
197  autoptr EntitySpawnParams spawnParams = new EntitySpawnParams();
198  spawnParams.TransformMode = ETransformMode.WORLD;
199  for (int comp = 0; comp < 4; comp++)
200  {
201  spawnParams.Transform[comp] = dummyMatrix[comp];
202  }
203 
204  // Spawn dummy object to read mins and maxes
205  IEntity dummyObject;
206  switch (type)
207  {
208  case GridSpawnerObjectType.GSOT_TEMPLATE:
209  dummyObject = GetGame().SpawnEntityPrefab(resource, baseWorld, spawnParams);
210  break;
211 
212  case GridSpawnerObjectType.GSOT_MODEL:
213  VObject obj = resource.GetResource().ToVObject();
214  dummyObject = GetGame().SpawnEntity(GenericEntity, baseWorld, spawnParams);
215  dummyObject.SetObject(obj, "");
216  break;
217  }
218 
219  // Read data from dummy object and dispose of it
220  if (dummyObject)
221  {
222  vector min, max;
223  dummyObject.GetBounds(min, max);
224  // Do not take height into account
225  max[1] = min[1];
226 
227  float boundsSpan = vector.Distance(min, max);
228  spacing += boundsSpan;
229 
230  // Delete dummy object
231  // NOTE: If children don't have Hierarchy component,
232  // they will "leak" into the world and never get removed
233  SCR_EntityHelper.DeleteEntityAndChildren(dummyObject);
234  dummyObject = null;
235  }
236  }
237 
238  // Spawn each object on a grid
239  for (int i = 0; i < countPerAxis; i++)
240  {
241  for (int j = 0; j < countPerAxis; j++)
242  {
243  // Get identity matrix
244  vector mat[4];
245  Math3D.MatrixIdentity4(mat);
246 
247  // Set rotation if we are using randomized yaw
248  if (m_iRandomizationSeed != 0)
249  {
250  vector yawPitchRoll = Vector(Math.RandomFloat(0, 360), 0.0, 0.0);
251  Math3D.AnglesToMatrix(yawPitchRoll, mat);
252  }
253 
254  // Calculate and set new position
255  vector newPos = currentPosition;
256  newPos[0] = newPos[0] + i * spacing;
257  newPos[2] = newPos[2] + j * spacing;
258  mat[3] = newPos;
259 
260  // Prepare spawn params so entity is spawned
261  // at the proper position and with proper rotation
262  // straight away
263  autoptr EntitySpawnParams spawnParams = new EntitySpawnParams();
264  spawnParams.TransformMode = ETransformMode.WORLD;
265  for (int comp = 0; comp < 4; comp++)
266  {
267  spawnParams.Transform[comp] = mat[comp];
268  }
269 
270  // Either spawn a template or create a new generic entity,
271  // that will be assigned a model based on GridSpawnerObjectType
272  switch (type)
273  {
274  case GridSpawnerObjectType.GSOT_TEMPLATE:
275  spawnedObject = GetGame().SpawnEntityPrefab(resource, baseWorld, spawnParams);
276  break;
277 
278  case GridSpawnerObjectType.GSOT_MODEL:
279  VObject obj = resource.GetResource().ToVObject();
280  spawnedObject = GetGame().SpawnEntity(GenericEntity, baseWorld, spawnParams);
281  spawnedObject.SetObject(obj, "");
282  spawnedObject.SetFlags(EntityFlags.VISIBLE, true);
283  break;
284  }
285 
286  // Register entity
287  m_aSpawnedEntities.Insert(spawnedObject);
288  }
289  }
290 
291  // Set new center point
292  centerPoint[0] = 0.5 * (float)countPerAxis * spacing;
293  centerPoint[2] = 0.5 * (float)countPerAxis * spacing;
294  return true;
295  }
296 
297  //------------------------------------------------------------------------------------------------
298  protected void DeleteEntities()
299  {
300  if (m_aSpawnedEntities)
301  {
302  int count = m_aSpawnedEntities.Count();
303 
304  // Iterate trough all entities that were spawned
305  for (int i = count-1; i >= 0; i--)
306  {
307  if (m_aSpawnedEntities[i])
308  {
309  SCR_EntityHelper.DeleteEntityAndChildren( m_aSpawnedEntities[i] );
310 
311  delete m_aSpawnedEntities[i];
312  m_aSpawnedEntities[i] = null;
313  }
314  }
315 
316  m_aSpawnedEntities.Clear();
317  m_aSpawnedEntities = null;
318  }
319  }
320 
321  //------------------------------------------------------------------------------------------------
322  protected override void EOnFrame(IEntity owner, float timeSlice)
323  {
324  }
325 
326  //------------------------------------------------------------------------------------------------
327  protected override void EOnInit(IEntity owner)
328  {
329  // Is in playmode?
330  if (!GetGame().GetWorldEntity())
331  return;
332 
333  // Load list from file?
334  if (m_sObjectsListPath != string.Empty)
335  {
336  // Open file
337  FileHandle file = FileIO.OpenFile(m_sObjectsListPath, FileMode.READ);
338  if (file)
339  {
340  // Make some room, read data
341  m_aObjects.Clear();
342  string line = string.Empty;
343  while (file.ReadLine(line) > 0)
344  {
345  if (line != string.Empty)
346  m_aObjects.Insert(line);
347  }
348 
349  file.Close();
350  }
351  }
352  }
353 
354  //------------------------------------------------------------------------------------------------
355  void SCR_GridSpawnerEntity(IEntitySource src, IEntity parent)
356  {
357  SetEventMask(EntityEvent.POSTFRAME | EntityEvent.FRAME | EntityEvent.INIT);
358  }
359 
360  //------------------------------------------------------------------------------------------------
361  void ~SCR_GridSpawnerEntity()
362  {
363  if (m_aSpawnedEntities)
364  DeleteEntities();
365  }
366 };
GSOT_TEMPLATE
@ GSOT_TEMPLATE
Definition: GridSpawnerEntity.c:11
SCR_GridSpawnerEntity
Definition: GridSpawnerEntity.c:19
SCR_EntityHelper
Definition: SCR_EntityHelper.c:1
EntityEditorProps
enum EQueryType EntityEditorProps(category:"GameScripted/Sound", description:"THIS IS THE SCRIPT DESCRIPTION.", color:"0 0 255 255")
Definition: SCR_AmbientSoundsComponent.c:12
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
GSOT_MODEL
@ GSOT_MODEL
Definition: GridSpawnerEntity.c:12
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
SCR_GridSpawnerEntityClass
Definition: GridSpawnerEntity.c:4
GetOrigin
vector GetOrigin()
Definition: SCR_AIUtilityComponent.c:279
Attribute
typedef Attribute
Post-process effect of scripted camera.
GSOT_NONE
@ GSOT_NONE
Definition: GridSpawnerEntity.c:10
index
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Definition: SCR_DestructionSynchronizationComponent.c:17
type
EDamageType type
Definition: SCR_DestructibleTreeV2.c:32
m_aSpawnedEntities
protected ref array< IEntity > m_aSpawnedEntities
Definition: SCR_ScenarioFrameworkLayerBase.c:62
GridSpawnerObjectType
GridSpawnerObjectType
Definition: GridSpawnerEntity.c:8
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180