Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_RandomPositionalInsects.c
Go to the documentation of this file.
1
2[BaseContainerProps(configRoot: true)]
4{
5 [Attribute(defvalue: "900", UIWidgets.Slider, params: "100 100000 1", desc: "Random positional insects that exceed this range (squared distance) will be despawned")]
6 protected int m_iDespawnDistanceSq;
7
8 [Attribute()]
9 protected ref array<ref SCR_RandomPositionalInsectsDef> m_aRandomPositionalInsectsDef;
10
11 [Attribute("", UIWidgets.ResourceNamePicker, desc: "Daytime curves config", params: "conf")]
13
14 [Attribute("", UIWidgets.ResourceNamePicker, desc: "Wind modifier curves config", params: "conf")]
16
17 // Configuration
18 protected ref array<ref SCR_InsectGroup> m_aInsectGroup = {};
19 protected ref array<ref SCR_InsectSpawnDef> m_aSpawnDef = {};
20 protected ref array<ref SCR_DayTimeCurveDef> m_aDayTimeCurve = {};
21 protected ref array<ref SCR_WindCurveDef> m_aWindModifier = {};
22
23 // Components
24 protected SoundWorld m_SoundWorld;
25
26 protected const int INVALID = -1;
28 protected ref array<int> m_aDensity = {};
29 protected ref array<float> m_aDensityModifier = {};
30 protected ref array<int> m_aAngleOffset = {};
33
34 protected ref array<ref SCR_InsectParticle> m_aParticles = {};
35
36 //------------------------------------------------------------------------------------------------
37 // Called by SCR_AmbientInsectsComponent.Update()
38 override void Update(float worldTime, vector cameraPos, float timeOfDay, float rainIntensity)
39 {
40
42 RemoveParticlesBasedOnTimeAndWeather(timeOfDay, rainIntensity);
43 UpdateInsectGroup(worldTime, cameraPos, m_iUpdatedInsectGroupIdx);
44
47 return;
48
50
51 UpdateGlobalModifiers(timeOfDay, rainIntensity);
52 }
53
54 //------------------------------------------------------------------------------------------------
58 protected void UpdateGlobalModifiers(float timeOfDay, float rainIntensity)
59 {
61
62 //Update values of wind modifiers curves
63 float windSpeedScaled = Math.InverseLerp(SCR_AmbientSoundsComponent.WINDSPEED_MIN, SCR_AmbientSoundsComponent.WINDSPEED_MAX, m_AmbientInsectsComponent.GetWindSpeed());
64
65 for (int i = 0; i < WIND_CURVE_COUNT; i++)
66 {
67 m_aWindCurveValue[i] = SCR_AmbientSoundsComponent.GetPoint(windSpeedScaled, m_aWindModifier[i].m_Curve);
68 }
69
70 // Get modifiers for all sound types
71 int environmentType = m_AmbientInsectsComponent.GetEnvironmentType();
72
73 foreach (int i, SCR_InsectSpawnDef spawnDef : m_aSpawnDef)
74 {
75 float modifier = SCR_AmbientSoundsComponent.GetPoint(timeOfDay, spawnDef.m_TimeModifier);
76 modifier = modifier * SCR_AmbientSoundsComponent.GetPoint(rainIntensity, spawnDef.m_RainModifier);
77 m_aDensityModifier[i] = modifier * m_aWindCurveValue[spawnDef.m_eWindModifier];
78 }
79
80 // Update values of day time curves
81 for (int i = 0; i < DAY_TIME_CURVE_COUNT; i++)
82 {
83 m_aDayTimeCurveValue[i] = SCR_AmbientSoundsComponent.GetPoint(timeOfDay, m_aDayTimeCurve[i].m_Curve);
84 }
85 }
86
87 //------------------------------------------------------------------------------------------------
90 protected int GetDensityMax(int insectGroup, int soundMapType)
91 {
92 if (soundMapType == 0)
93 return m_aSpawnDef[insectGroup].m_iSeaDensityMax;
94 else if (soundMapType == 1)
95 return m_aSpawnDef[insectGroup].m_iForestDensityMax;
96 else if (soundMapType == 2)
97 return m_aSpawnDef[insectGroup].m_iCityDensityMax;
98 else if (soundMapType == 3)
99 return m_aSpawnDef[insectGroup].m_iMeadowDensityMax;
100 else if (soundMapType == 4)
101 return m_aSpawnDef[insectGroup].m_iRiverDensityMax;
102 else if (soundMapType == 5)
103 return m_aSpawnDef[insectGroup].m_iRiverSlopeDensityMax;
104 else if (soundMapType == 6)
105 return m_aSpawnDef[insectGroup].m_iLakeDensityMax;
106 else
107 return m_aSpawnDef[insectGroup].m_iCoastDensityMax;
108 }
109
110 //------------------------------------------------------------------------------------------------
113 protected void RemoveOutOfRangeParticles(vector cameraPos)
114 {
115 for (int i = m_aParticles.Count() - 1; i >= 0; i--)
116 {
117 if (vector.DistanceSqXZ(m_aParticles[i].m_vPosition, cameraPos) >= m_iDespawnDistanceSq)
118 {
121
122 m_aParticles.Remove(i);
123 }
124 }
125 }
126
127 //------------------------------------------------------------------------------------------------
131 protected void RemoveParticlesBasedOnTimeAndWeather(float timeOfDay, float rainIntensity)
132 {
133 for (int i = m_aParticles.Count() - 1; i >= 0; i--)
134 {
135 float dayTimeCurve = SCR_AmbientSoundsComponent.GetPoint(timeOfDay, m_aSpawnDef[m_aParticles[i].m_iSoundGroup].m_TimeModifier);
136 float rainIntensityCurve = SCR_AmbientSoundsComponent.GetPoint(rainIntensity, m_aSpawnDef[m_aParticles[i].m_iSoundGroup].m_RainModifier);
137 if (dayTimeCurve <= 0 || rainIntensityCurve <= 0)
138 {
141
142 m_aParticles.Remove(i);
143 }
144 }
145 }
146
147 //------------------------------------------------------------------------------------------------
150 protected void RandomizeAnimation(IEntity entity)
151 {
152 AnimationPlayerComponent animComponent = AnimationPlayerComponent.Cast(entity.FindComponent(AnimationPlayerComponent));
153 if (!animComponent)
154 return;
155
156 ResourceName animationResource = animComponent.GetAnimation();
157 if (!animationResource || SCR_StringHelper.IsEmptyOrWhiteSpace(animationResource))
158 return;
159
160 animComponent.Prepare(animationResource, Math.RandomFloatInclusive(1, 5), 1, true);
161 animComponent.Play();
162 }
163
164 //------------------------------------------------------------------------------------------------
169 protected void UpdateInsectGroup(float worldTime, vector camPos, int insectGroup)
170 {
171 // Generate sound position
172 vector vPos;
173 int insectType = INVALID;
174 vPos = GenerateRandomPosition(insectGroup, camPos);
175 insectType = GetSoundMapTypeFromTerrain(vPos, camPos);
176 if (insectType == INVALID)
177 return;
178
179 // Return, if density was reached
180 // Config density modified by time, wind and rain modifiers
181 if (m_aDensity[insectGroup] > GetDensityMax(insectGroup, insectType) * m_aDensityModifier[insectGroup])
182 return;
183
184 // Get random sound definition
185 SCR_InsectDef insectDef;
186 if (m_aInsectGroup[insectGroup].m_aInsectType.IsIndexValid(insectType))
187 insectDef = GetRandomInsectDef(m_aInsectGroup[insectGroup].m_aInsectType[insectType]);
188
189 if (!insectDef)
190 return;
191
192 string particleName = insectDef.m_sParticleEffect;
193 string soundName = insectDef.m_sSoundName;
194 ResourceName prefabName = insectDef.m_sPrefabName;
195
197 spawnParams.Transform[3] = vPos;
198
199 SCR_InsectParticle particle = new SCR_InsectParticle();
200 particle.m_iSoundGroup = insectGroup;
201 particle.m_vPosition = vPos;
202 if (Math.RandomIntInclusive(0, 100) <= m_aRandomPositionalInsectsDef[insectGroup].m_iSpawnChance)
203 {
204 if (!soundName.IsEmpty())
205 particle.m_AudioHandle = m_AmbientSoundsComponent.SoundEventLooped(soundName, spawnParams.Transform);
206
207 if (!prefabName.IsEmpty())
208 {
209 Resource resource = Resource.Load(insectDef.m_sPrefabName);
210 if (resource)
211 {
212 EntitySpawnParams entitySpawnParams = new EntitySpawnParams;
213 entitySpawnParams.Transform = spawnParams.Transform;
214 entitySpawnParams.TransformMode = spawnParams.TransformMode;
215
216 particle.m_InsectEntity = GetGame().SpawnEntityPrefab(resource, GetGame().GetWorld(), entitySpawnParams);
217 if (particle.m_InsectEntity)
218 {
219 particle.m_InsectEntity.SetVComponentFlags(VCFlags.DYNAMICBBOX);
220 RandomizeAnimation(particle.m_InsectEntity);
221 }
222 }
223 }
224 else if (!particleName.IsEmpty())
225 {
226 particle.m_ParticleEffect = ParticleEffectEntity.SpawnParticleEffect(insectDef.m_sParticleEffect, spawnParams);
227 }
228
229#ifdef ENABLE_DIAG
230 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_AMBIENT_LIFE))
231 {
232 if (!soundName.IsEmpty())
233 particle.m_DebugShape = Shape.CreateSphere(COLOR_GREEN, ShapeFlags.NOZWRITE | ShapeFlags.WIREFRAME, spawnParams.Transform[3], 0.2);
234 else
235 particle.m_DebugShape = Shape.CreateSphere(COLOR_BLUE, ShapeFlags.NOZWRITE | ShapeFlags.WIREFRAME, spawnParams.Transform[3], 0.2);
236 }
237#endif
238 }
239
240 m_aParticles.Insert(particle);
241 }
242
243 //------------------------------------------------------------------------------------------------
248 protected vector GenerateRandomPosition(int insectGroup, vector camPos)
249 {
250 // Angle for random position is rotated by 40 deg for each GenerateRandomPosition() call
251 float angle = m_aAngleOffset[insectGroup] * 40;
252
253 m_aAngleOffset[insectGroup] = m_aAngleOffset[insectGroup] + 1;
254 if (m_aAngleOffset[insectGroup] > 9)
255 m_aAngleOffset[insectGroup] = 0;
256
257 vector vPos = vector.FromYaw(angle) * Math.RandomFloat(10, 25);
258
259 return vPos + camPos;
260 }
261
262 //------------------------------------------------------------------------------------------------
266 {
267 if (!insectType)
268 return null;
269
270 int size = insectType.m_aInsectDef.Count();
271 if (size == 0)
272 return null;
273
274 int offset = Math.RandomIntInclusive(0, size - 1);
275
276 for (int i = 0; i < size; i++)
277 {
278 int idx = i + offset;
279 if (idx >= size)
280 idx -= size;
281
282 if (m_aDayTimeCurveValue[insectType.m_aInsectDef[idx].m_eDayTimeCurve] > 0)
283 return insectType.m_aInsectDef[idx];
284 }
285
286 return null;
287 }
288
289 //------------------------------------------------------------------------------------------------
293 protected int GetSoundMapTypeFromTerrain(inout vector worldPos, vector camPos)
294 {
295 ChimeraWorld world = ChimeraWorld.CastFrom(m_AmbientInsectsComponent.GetOwner().GetWorld());
296 if (!world)
297 return INVALID;
298
299 SoundWorld soundWorld = world.GetSoundWorld();
300 if (!soundWorld)
301 return INVALID;
302
303 // We are getting these values twice - once for randomly found position around player, second on the camera position
304 float seaCam, forestCam, cityCam, meadowCam;
305 soundWorld.GetMapValuesAtPos(camPos, seaCam, forestCam, cityCam, meadowCam);
306
307 float seaPos, forestPos, cityPos, meadowPos;
308 soundWorld.GetMapValuesAtPos(worldPos, seaPos, forestPos, cityPos, meadowPos);
309
310 float riverCam, riverSlopeCam, lakeCam, coastCam;
311 soundWorld.GetMapValuesAdvAtPos(camPos, riverCam, riverSlopeCam, lakeCam, coastCam);
312
313 float riverPos, riverSlopePos, lakePos, coastPos;
314 soundWorld.GetMapValuesAdvAtPos(worldPos, riverPos, riverSlopePos, lakePos, coastPos);
315
316 array<float> valuesPos = {seaPos, forestPos, cityPos, meadowPos, riverPos, riverSlopePos, lakePos, coastPos};
317 array<float> valuesCam = {seaCam, forestCam, cityCam, meadowCam, riverCam, riverSlopeCam, lakeCam, coastCam};
318
319 // We want to work with higher number
320 for (int i; i < 8; i++)
321 {
322 if (valuesCam[i] > valuesPos[i])
323 valuesPos[i] = valuesCam[i];
324 }
325
326 // Get maximum
327 float v = valuesPos[0];
328 int idx;
329 int i = 1;
330 for (i; i < 8; i++)
331 {
332 if (valuesPos[i] >= v)
333 {
334 v = valuesPos[i];
335 idx = i;
336 }
337 }
338
339 // Check for fresh water
340 if (idx == 0)
341 {
342 worldPos[1] = 0;
343 }
344 else
345 {
346 float surfaceHeight = world.GetSurfaceY(worldPos[0], worldPos[2]);
347 worldPos[1] = surfaceHeight;
348 }
349
350 EWaterSurfaceType waterSurfaceType;
351 float lakeArea;
352 //Sometimes other biomes overlap and we want to prioritise water
353 if (valuesPos[6] >= 0.75)
354 {
355 idx = 6;
356 worldPos[1] = SCR_WorldTools.GetWaterSurfaceY(world, worldPos, waterSurfaceType, lakeArea);
357 }
358
359 return idx;
360 }
361
362 //------------------------------------------------------------------------------------------------
364 protected void UpdateDensity()
365 {
366 m_aDensity.Clear();
367 m_aDensity.Resize(m_aSpawnDef.Count());
368 foreach (SCR_InsectParticle particle : m_aParticles)
369 {
370 m_aDensity[particle.m_iSoundGroup] = m_aDensity[particle.m_iSoundGroup] + m_aSpawnDef[particle.m_iSoundGroup].m_iDensityConsumption;
371 }
372 }
373
374 //------------------------------------------------------------------------------------------------
376 protected void LoadConfigs()
377 {
379 {
380 SCR_InsectGroup insectGroup;
381 if (def.m_sInsectGroup != string.Empty)
382 {
383 Resource holder = BaseContainerTools.LoadContainer(def.m_sInsectGroup);
384 if (holder)
385 insectGroup = SCR_InsectGroup.Cast(BaseContainerTools.CreateInstanceFromContainer(holder.GetResource().ToBaseContainer()));
386 }
387
388 if (!insectGroup)
389 {
390 Print("AMBIENT LIFE: SCR_AmbientInsectsComponent: Missing Ambience Sound Gropu Config", LogLevel.WARNING);
391 m_AmbientInsectsComponent.RemoveInsectEffect(this);
392
393 return;
394 }
395
396 m_aInsectGroup.Insert(insectGroup);
397
398 // ---
399 SCR_InsectSpawnDef spawnDef;
400 if (def.m_sSpawnDef != string.Empty)
401 {
402 Resource holder = BaseContainerTools.LoadContainer(def.m_sSpawnDef);
403 if (holder)
404 spawnDef = SCR_InsectSpawnDef.Cast(BaseContainerTools.CreateInstanceFromContainer(holder.GetResource().ToBaseContainer()));
405 }
406
407 if (!spawnDef)
408 {
409 Print("AMBIENT LIFE: SCR_AmbientInsectsComponent: Missing Spawn Definition Config", LogLevel.WARNING);
410 m_AmbientInsectsComponent.RemoveInsectEffect(this);
411
412 return;
413 }
414
415 m_aSpawnDef.Insert(spawnDef);
416 }
417
418 // ---
419 SCR_DayTimeCurveDefConfig ambientSoundsDayTimeCurveDefinitionConfig;
420 if (m_sDayTimeCurve != string.Empty)
421 {
422 Resource holder = BaseContainerTools.LoadContainer(m_sDayTimeCurve);
423 if (holder)
424 ambientSoundsDayTimeCurveDefinitionConfig = SCR_DayTimeCurveDefConfig.Cast(BaseContainerTools.CreateInstanceFromContainer(holder.GetResource().ToBaseContainer()));
425 }
426
427 if (!ambientSoundsDayTimeCurveDefinitionConfig)
428 {
429 Print("AMBIENT LIFE: SCR_AmbientInsectsComponent: Missing Daytime Curve Deffinition Config", LogLevel.WARNING);
430 m_AmbientInsectsComponent.RemoveInsectEffect(this);
431
432 return;
433 }
434
435 m_aDayTimeCurve = ambientSoundsDayTimeCurveDefinitionConfig.m_aDayTimeCurve;
436
437 // ---
438 SCR_WindCurveDefConfig ambientSoundsWindDefinitionConfig;
439 if (m_sWindCurve != string.Empty)
440 {
441 Resource holder = BaseContainerTools.LoadContainer(m_sWindCurve);
442 if (holder)
443 ambientSoundsWindDefinitionConfig = SCR_WindCurveDefConfig.Cast(BaseContainerTools.CreateInstanceFromContainer(holder.GetResource().ToBaseContainer()));
444 }
445
446 if (!ambientSoundsWindDefinitionConfig)
447 {
448 Print("AMBIENT LIFE: SCR_AmbientInsectsComponent: Missing Wind Curve Definition Config", LogLevel.WARNING);
449 m_AmbientInsectsComponent.RemoveInsectEffect(this);
450
451 return;
452 }
453
454 m_aWindModifier = ambientSoundsWindDefinitionConfig.m_aWindModifier;
455 }
456
457 //------------------------------------------------------------------------------------------------
458 // Called by SCR_AmbientSoundComponent in OnPostInit()
459 override void OnPostInit(SCR_AmbientSoundsComponent ambientSoundsComponent, SCR_AmbientInsectsComponent ambientInsectsComponent, SignalsManagerComponent signalsManagerComponent)
460 {
461 super.OnPostInit(ambientSoundsComponent, ambientInsectsComponent, signalsManagerComponent);
462
463 LoadConfigs();
464
465 int count = m_aSpawnDef.Count();
466 m_aDensity.Resize(count);
467 m_aAngleOffset.Resize(count);
468 m_aDensityModifier.Resize(count);
469 }
470}
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
EWaterSurfaceType
ArmaReforgerScripted GetGame()
Definition game.c:1398
int size
SCR_AIAnimation_Loitering BaseContainerProps
Commanding menu commanding element class.
enum EAudioSourceFlag m_AudioHandle
Stores valid Audio handle.
const int DAY_TIME_CURVE_COUNT
void ParticleEffectEntity(IEntitySource src, IEntity parent)
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
const int WIND_CURVE_COUNT
Diagnostic and developer menu system.
Definition DiagMenu.c:18
proto external Managed FindComponent(typename typeName)
proto external int SetVComponentFlags(VCFlags flags)
Sets component flags.
Definition Math.c:13
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
SCR_AmbientSoundsComponent m_AmbientSoundsComponent
SCR_AmbientInsectsComponent m_AmbientInsectsComponent
Array size has to have the same count as EDayTimeCurve.
Spawns Insect particles around camera based on define behaviour.
ref array< ref SCR_InsectGroup > m_aInsectGroup
ref array< ref SCR_RandomPositionalInsectsDef > m_aRandomPositionalInsectsDef
vector GenerateRandomPosition(int insectGroup, vector camPos)
ref array< ref SCR_InsectSpawnDef > m_aSpawnDef
int GetDensityMax(int insectGroup, int soundMapType)
float m_aWindCurveValue[WIND_CURVE_COUNT]
int GetSoundMapTypeFromTerrain(inout vector worldPos, vector camPos)
void LoadConfigs()
Loads configs where necessary values are stored.
float m_aDayTimeCurveValue[DAY_TIME_CURVE_COUNT]
void RemoveParticlesBasedOnTimeAndWeather(float timeOfDay, float rainIntensity)
ref array< ref SCR_InsectParticle > m_aParticles
void UpdateInsectGroup(float worldTime, vector camPos, int insectGroup)
ref array< ref SCR_WindCurveDef > m_aWindModifier
void UpdateDensity()
Updates insect density per group and active particles.
void RemoveOutOfRangeParticles(vector cameraPos)
override void OnPostInit(SCR_AmbientSoundsComponent ambientSoundsComponent, SCR_AmbientInsectsComponent ambientInsectsComponent, SignalsManagerComponent signalsManagerComponent)
ref array< ref SCR_DayTimeCurveDef > m_aDayTimeCurve
void UpdateGlobalModifiers(float timeOfDay, float rainIntensity)
SCR_InsectDef GetRandomInsectDef(SCR_InsectType insectType)
override void Update(float worldTime, vector cameraPos, float timeOfDay, float rainIntensity)
static bool IsEmptyOrWhiteSpace(string input)
Array has to have the same size as EWindCurve count.
Instance of created debug visualizer.
Definition Shape.c:14
void EntitySpawnParams()
Definition gameLib.c:130
const int COLOR_BLUE
Definition constants.c:23
const int COLOR_GREEN
Definition constants.c:22
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
ShapeFlags
Definition ShapeFlags.c:13
SCR_FieldOfViewSettings Attribute
VCFlags
VObjectComponent flags.
Definition VCFlags.c:14