Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
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")]
4class SCR_GridSpawnerEntityClass: GenericEntityClass
5{
6};
7
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)
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 // If relative (i.e. based on model bounds) spacing is desired,
178 // spawn a dummy object and read data from it before deleting it
179 if (!m_bUseAbsoluteSpacing)
180 {
181 // Get identity matrix
182 vector dummyMatrix[4];
183 Math3D.MatrixIdentity4(dummyMatrix);
184
185 // .........
186 // let's not talk about this
187 const float dummyOffset = -999;
188 for (int i = 0; i < 3; i++)
189 dummyMatrix[3][i] = dummyOffset;
190
191 autoptr EntitySpawnParams spawnParams = new EntitySpawnParams();
192 spawnParams.TransformMode = ETransformMode.WORLD;
193 for (int comp = 0; comp < 4; comp++)
194 {
195 spawnParams.Transform[comp] = dummyMatrix[comp];
196 }
197
198 // Spawn dummy object to read mins and maxes
199 IEntity dummyObject;
200 switch (type)
201 {
202 case GridSpawnerObjectType.GSOT_TEMPLATE:
203 dummyObject = GetGame().SpawnEntityPrefab(resource, baseWorld, spawnParams);
204 break;
205
206 case GridSpawnerObjectType.GSOT_MODEL:
207 VObject obj = resource.GetResource().ToVObject();
208 dummyObject = GetGame().SpawnEntity(GenericEntity, baseWorld, spawnParams);
209 dummyObject.SetObject(obj, "");
210 break;
211 }
212
213 // Read data from dummy object and dispose of it
214 if (dummyObject)
215 {
216 vector min, max;
217 dummyObject.GetBounds(min, max);
218 // Do not take height into account
219 max[1] = min[1];
220
221 float boundsSpan = vector.Distance(min, max);
222 spacing += boundsSpan;
223
224 // Delete dummy object
225 // NOTE: If children don't have Hierarchy component,
226 // they will "leak" into the world and never get removed
227 SCR_EntityHelper.DeleteEntityAndChildren(dummyObject);
228 dummyObject = null;
229 }
230 }
231
232 // Spawn each object on a grid
233 for (int i = 0; i < countPerAxis; i++)
234 {
235 for (int j = 0; j < countPerAxis; j++)
236 {
237 // Get identity matrix
238 vector mat[4];
239 Math3D.MatrixIdentity4(mat);
240
241 // Set rotation if we are using randomized yaw
242 if (m_iRandomizationSeed != 0)
243 {
244 vector yawPitchRoll = Vector(Math.RandomFloat(0, 360), 0.0, 0.0);
245 Math3D.AnglesToMatrix(yawPitchRoll, mat);
246 }
247
248 // Calculate and set new position
249 vector newPos = currentPosition;
250 newPos[0] = newPos[0] + i * spacing;
251 newPos[2] = newPos[2] + j * spacing;
252 mat[3] = newPos;
253
254 // Prepare spawn params so entity is spawned
255 // at the proper position and with proper rotation
256 // straight away
257 autoptr EntitySpawnParams spawnParams = new EntitySpawnParams();
258 spawnParams.TransformMode = ETransformMode.WORLD;
259 for (int comp = 0; comp < 4; comp++)
260 {
261 spawnParams.Transform[comp] = mat[comp];
262 }
263
264 // Either spawn a template or create a new generic entity,
265 // that will be assigned a model based on GridSpawnerObjectType
266 switch (type)
267 {
268 case GridSpawnerObjectType.GSOT_TEMPLATE:
269 spawnedObject = GetGame().SpawnEntityPrefab(resource, baseWorld, spawnParams);
270 break;
271
272 case GridSpawnerObjectType.GSOT_MODEL:
273 VObject obj = resource.GetResource().ToVObject();
274 spawnedObject = GetGame().SpawnEntity(GenericEntity, baseWorld, spawnParams);
275 spawnedObject.SetObject(obj, "");
276 spawnedObject.SetFlags(EntityFlags.VISIBLE, true);
277 break;
278 }
279
280 // Register entity
281 m_aSpawnedEntities.Insert(spawnedObject);
282 }
283 }
284
285 // Set new center point
286 centerPoint[0] = 0.5 * (float)countPerAxis * spacing;
287 centerPoint[2] = 0.5 * (float)countPerAxis * spacing;
288 return true;
289 }
290
291 //------------------------------------------------------------------------------------------------
292 protected void DeleteEntities()
293 {
294 if (m_aSpawnedEntities)
295 {
296 int count = m_aSpawnedEntities.Count();
297
298 // Iterate trough all entities that were spawned
299 for (int i = count-1; i >= 0; i--)
300 {
301 if (m_aSpawnedEntities[i])
302 {
303 SCR_EntityHelper.DeleteEntityAndChildren( m_aSpawnedEntities[i] );
304
305 delete m_aSpawnedEntities[i];
306 m_aSpawnedEntities[i] = null;
307 }
308 }
309
310 m_aSpawnedEntities.Clear();
311 m_aSpawnedEntities = null;
312 }
313 }
314
315 //------------------------------------------------------------------------------------------------
316 protected override void EOnFrame(IEntity owner, float timeSlice)
317 {
318 }
319
320 //------------------------------------------------------------------------------------------------
321 protected override void EOnInit(IEntity owner)
322 {
323 // Is in playmode?
324 if (!GetGame().GetWorldEntity())
325 return;
326
327 // Load list from file?
328 if (m_sObjectsListPath != string.Empty)
329 {
330 // Open file
331 FileHandle file = FileIO.OpenFile(m_sObjectsListPath, FileMode.READ);
332 if (file)
333 {
334 // Make some room, read data
335 m_aObjects.Clear();
336 string line = string.Empty;
337 while (file.ReadLine(line) > 0)
338 {
339 if (line != string.Empty)
340 m_aObjects.Insert(line);
341 }
342
343 file.Close();
344 }
345 }
346
347 // Set randomization seed, if we want randomization (!= 0)
348 // Note: The generator is shared - seeding may not be deterministic
349 if (m_iRandomizationSeed != 0)
350 {
351 s_AIRandomGenerator.SetSeed(m_iRandomizationSeed);
352 }
353 }
354
355 //------------------------------------------------------------------------------------------------
357 {
358 SetEventMask(EntityEvent.POSTFRAME | EntityEvent.FRAME | EntityEvent.INIT);
359 }
360
361 //------------------------------------------------------------------------------------------------
363 {
364 if (m_aSpawnedEntities)
366 }
367};
ArmaReforgerScripted GetGame()
Definition game.c:1398
GridSpawnerObjectType
@ GSOT_MODEL
@ GSOT_NONE
@ GSOT_TEMPLATE
class SCR_AINodePortsHelpers s_AIRandomGenerator
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
EDamageType type
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
array< IEntity > GetSpawnedEntities()
void IEntity(IEntitySource src, IEntity parent)
protected script Constructor
proto external EntityEvent SetEventMask(EntityEvent e)
proto external vector GetOrigin()
proto external void GetBounds(out vector mins, out vector maxs)
proto external EntityFlags SetFlags(EntityFlags flags, bool recursively=false)
Definition Math.c:13
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
override void EOnInit(IEntity owner)
void SCR_GridSpawnerEntity(IEntitySource src, IEntity parent)
override void EOnFrame(IEntity owner, float timeSlice)
bool Spawn(int index, out vector centerPoint)
bool GetObjectName(int index, out string name)
Visual object.
Definition VObject.c:14
Definition float.c:13
void EntitySpawnParams()
Definition gameLib.c:130
AISpawnerGroupClass AIGroupClass Spawn()
Spawns a new group entity, sets its transformation and then calls OnSpawn.
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
EntityEvent
Various entity events.
Definition EntityEvent.c:14
EntityFlags
Various entity flags.
Definition EntityFlags.c:14
FileMode
Mode for opening file. See FileSystem::Open.
Definition FileMode.c:14
proto native vector Vector(float x, float y, float z)