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;
9 protected ref array<ref SCR_RandomPositionalInsectsDef> m_aRandomPositionalInsectsDef;
11 [
Attribute(
"", UIWidgets.ResourceNamePicker,
desc:
"Daytime curves config",
params:
"conf")]
12 protected ResourceName m_sDayTimeCurve;
14 [
Attribute(
"", UIWidgets.ResourceNamePicker,
desc:
"Wind modifier curves config",
params:
"conf")]
15 protected ResourceName m_sWindCurve;
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 = {};
24 protected SoundWorld m_SoundWorld;
26 protected const int INVALID = -1;
27 protected int m_iUpdatedInsectGroupIdx;
28 protected ref array<int> m_aDensity = {};
29 protected ref array<float> m_aDensityModifier = {};
30 protected ref array<int> m_aAngleOffset = {};
34 protected ref array<ref SCR_InsectParticle> m_aParticles = {};
38 override void Update(
float worldTime, vector cameraPos,
float timeOfDay,
float rainIntensity)
41 RemoveOutOfRangeParticles(cameraPos);
42 RemoveParticlesBasedOnTimeAndWeather(timeOfDay, rainIntensity);
43 UpdateInsectGroup(worldTime, cameraPos, m_iUpdatedInsectGroupIdx);
45 m_iUpdatedInsectGroupIdx ++;
46 if (m_iUpdatedInsectGroupIdx < m_aInsectGroup.Count())
49 m_iUpdatedInsectGroupIdx = 0;
51 UpdateGlobalModifiers(timeOfDay, rainIntensity);
58 protected void UpdateGlobalModifiers(
float timeOfDay,
float rainIntensity)
71 int environmentType = m_AmbientInsectsComponent.GetEnvironmentType();
77 m_aDensityModifier[i] = modifier * m_aWindCurveValue[spawnDef.m_eWindModifier];
90 protected int GetDensityMax(
int insectGroup,
int soundMapType)
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;
107 return m_aSpawnDef[insectGroup].m_iCoastDensityMax;
113 protected void RemoveOutOfRangeParticles(vector cameraPos)
117 if (vector.DistanceSqXZ(
m_aParticles[i].m_vPosition, cameraPos) >= m_iDespawnDistanceSq)
131 protected void RemoveParticlesBasedOnTimeAndWeather(
float timeOfDay,
float rainIntensity)
137 if (dayTimeCurve <= 0 || rainIntensityCurve <= 0)
150 protected void RandomizeAnimation(IEntity entity)
152 AnimationPlayerComponent animComponent = AnimationPlayerComponent.Cast(entity.FindComponent(AnimationPlayerComponent));
156 SCR_AnimationResourceHolderComponent animResourceHolder = SCR_AnimationResourceHolderComponent.Cast(entity.FindComponent(SCR_AnimationResourceHolderComponent));
157 if (!animResourceHolder)
160 animComponent.Prepare(animResourceHolder.m_sAnimation, Math.RandomFloatInclusive(1, 5), 1,
true);
161 animComponent.Play();
169 protected void UpdateInsectGroup(
float worldTime, vector camPos,
int insectGroup)
174 vPos = GenerateRandomPosition(insectGroup, camPos);
175 insectType = GetSoundMapTypeFromTerrain(vPos, camPos);
181 if (m_aDensity[insectGroup] > GetDensityMax(insectGroup, insectType) * m_aDensityModifier[insectGroup])
186 if (m_aInsectGroup[insectGroup].m_aInsectType.IsIndexValid(insectType))
187 insectDef = GetRandomInsectDef(m_aInsectGroup[insectGroup].m_aInsectType[insectType]);
192 string particleName = insectDef.m_sParticleEffect;
193 string soundName = insectDef.m_sSoundName;
194 ResourceName prefabName = insectDef.m_sPrefabName;
196 ParticleEffectEntitySpawnParams spawnParams();
197 spawnParams.Transform[3] = vPos;
200 particle.m_iSoundGroup = insectGroup;
201 particle.m_vPosition = vPos;
202 if (Math.RandomIntInclusive(0, 100) <= m_aRandomPositionalInsectsDef[insectGroup].m_iSpawnChance)
204 if (!soundName.IsEmpty())
207 if (!prefabName.IsEmpty())
209 Resource resource = Resource.Load(insectDef.m_sPrefabName);
212 EntitySpawnParams entitySpawnParams =
new EntitySpawnParams;
213 entitySpawnParams.Transform = spawnParams.Transform;
214 entitySpawnParams.TransformMode = spawnParams.TransformMode;
216 particle.m_InsectEntity =
GetGame().SpawnEntityPrefab(resource,
GetGame().GetWorld(), entitySpawnParams);
217 if (particle.m_InsectEntity)
219 particle.m_InsectEntity.SetVComponentFlags(VCFlags.DYNAMICBBOX);
220 RandomizeAnimation(particle.m_InsectEntity);
224 else if (!particleName.IsEmpty())
226 particle.m_ParticleEffect = ParticleEffectEntity.SpawnParticleEffect(insectDef.m_sParticleEffect, spawnParams);
232 if (!soundName.IsEmpty())
233 particle.m_DebugShape = Shape.CreateSphere(COLOR_GREEN, ShapeFlags.NOZWRITE | ShapeFlags.WIREFRAME, spawnParams.Transform[3], 0.2);
235 particle.m_DebugShape = Shape.CreateSphere(COLOR_BLUE, ShapeFlags.NOZWRITE | ShapeFlags.WIREFRAME, spawnParams.Transform[3], 0.2);
248 protected vector GenerateRandomPosition(
int insectGroup, vector camPos)
251 float angle = m_aAngleOffset[insectGroup] * 40;
253 m_aAngleOffset[insectGroup] = m_aAngleOffset[insectGroup] + 1;
254 if (m_aAngleOffset[insectGroup] > 9)
255 m_aAngleOffset[insectGroup] = 0;
257 vector vPos = vector.FromYaw(angle) * Math.RandomFloat(10, 25);
259 return vPos + camPos;
270 int size = insectType.m_aInsectDef.Count();
274 int offset = Math.RandomIntInclusive(0, size - 1);
276 for (
int i = 0; i < size; i++)
278 int idx = i + offset;
282 if (m_aDayTimeCurveValue[insectType.m_aInsectDef[idx].m_eDayTimeCurve] > 0)
283 return insectType.m_aInsectDef[idx];
293 protected int GetSoundMapTypeFromTerrain(inout vector worldPos, vector camPos)
299 SoundWorld soundWorld = world.GetSoundWorld();
304 float seaCam, forestCam, cityCam, meadowCam;
305 soundWorld.GetMapValuesAtPos(camPos, seaCam, forestCam, cityCam, meadowCam);
307 float seaPos, forestPos, cityPos, meadowPos;
308 soundWorld.GetMapValuesAtPos(worldPos, seaPos, forestPos, cityPos, meadowPos);
310 float riverCam, riverSlopeCam, lakeCam, coastCam;
311 soundWorld.GetMapValuesAdvAtPos(camPos, riverCam, riverSlopeCam, lakeCam, coastCam);
313 float riverPos, riverSlopePos, lakePos, coastPos;
314 soundWorld.GetMapValuesAdvAtPos(worldPos, riverPos, riverSlopePos, lakePos, coastPos);
316 array<float> valuesPos = {seaPos, forestPos, cityPos, meadowPos, riverPos, riverSlopePos, lakePos, coastPos};
317 array<float> valuesCam = {seaCam, forestCam, cityCam, meadowCam, riverCam, riverSlopeCam, lakeCam, coastCam};
320 for (
int i; i < 8; i++)
322 if (valuesCam[i] > valuesPos[i])
323 valuesPos[i] = valuesCam[i];
327 float v = valuesPos[0];
332 if (valuesPos[i] >= v)
346 float surfaceHeight = world.GetSurfaceY(worldPos[0], worldPos[2]);
347 worldPos[1] = surfaceHeight;
353 if (valuesPos[6] >= 0.75)
356 worldPos[1] =
SCR_WorldTools.GetWaterSurfaceY(world, worldPos, waterSurfaceType, lakeArea);
364 protected void UpdateDensity()
367 m_aDensity.Resize(m_aSpawnDef.Count());
370 m_aDensity[particle.m_iSoundGroup] = m_aDensity[particle.m_iSoundGroup] + m_aSpawnDef[particle.m_iSoundGroup].m_iDensityConsumption;
376 protected void LoadConfigs()
381 if (def.m_sInsectGroup !=
string.Empty)
383 Resource holder = BaseContainerTools.LoadContainer(def.m_sInsectGroup);
385 insectGroup =
SCR_InsectGroup.Cast(BaseContainerTools.CreateInstanceFromContainer(holder.GetResource().ToBaseContainer()));
390 Print(
"AMBIENT LIFE: SCR_AmbientInsectsComponent: Missing Ambience Sound Gropu Config", LogLevel.WARNING);
391 m_AmbientInsectsComponent.RemoveInsectEffect(
this);
396 m_aInsectGroup.Insert(insectGroup);
400 if (def.m_sSpawnDef !=
string.Empty)
402 Resource holder = BaseContainerTools.LoadContainer(def.m_sSpawnDef);
404 spawnDef =
SCR_InsectSpawnDef.Cast(BaseContainerTools.CreateInstanceFromContainer(holder.GetResource().ToBaseContainer()));
409 Print(
"AMBIENT LIFE: SCR_AmbientInsectsComponent: Missing Spawn Definition Config", LogLevel.WARNING);
410 m_AmbientInsectsComponent.RemoveInsectEffect(
this);
415 m_aSpawnDef.Insert(spawnDef);
420 if (m_sDayTimeCurve !=
string.Empty)
422 Resource holder = BaseContainerTools.LoadContainer(m_sDayTimeCurve);
424 ambientSoundsDayTimeCurveDefinitionConfig =
SCR_DayTimeCurveDefConfig.Cast(BaseContainerTools.CreateInstanceFromContainer(holder.GetResource().ToBaseContainer()));
427 if (!ambientSoundsDayTimeCurveDefinitionConfig)
429 Print(
"AMBIENT LIFE: SCR_AmbientInsectsComponent: Missing Daytime Curve Deffinition Config", LogLevel.WARNING);
430 m_AmbientInsectsComponent.RemoveInsectEffect(
this);
435 m_aDayTimeCurve = ambientSoundsDayTimeCurveDefinitionConfig.m_aDayTimeCurve;
439 if (m_sWindCurve !=
string.Empty)
441 Resource holder = BaseContainerTools.LoadContainer(m_sWindCurve);
443 ambientSoundsWindDefinitionConfig =
SCR_WindCurveDefConfig.Cast(BaseContainerTools.CreateInstanceFromContainer(holder.GetResource().ToBaseContainer()));
446 if (!ambientSoundsWindDefinitionConfig)
448 Print(
"AMBIENT LIFE: SCR_AmbientInsectsComponent: Missing Wind Curve Definition Config", LogLevel.WARNING);
449 m_AmbientInsectsComponent.RemoveInsectEffect(
this);
454 m_aWindModifier = ambientSoundsWindDefinitionConfig.m_aWindModifier;
461 super.OnPostInit(ambientSoundsComponent, ambientInsectsComponent, signalsManagerComponent);
465 int count = m_aSpawnDef.Count();
466 m_aDensity.Resize(count);
467 m_aAngleOffset.Resize(count);
468 m_aDensityModifier.Resize(count);