Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_VehicleDustPerWheelComponent.c
Go to the documentation of this file.
1// Spawns dust particle effect that drags with the vehicle during ride
2
3[ComponentEditorProps(category: "GameScripted/Test", description:"SCR_VehicleDustPerWheel")]
5{
6 [Attribute("0", UIWidgets.Auto, "Vehicle index in ParticleEffectInfo")]
7 int m_iVehicleIndex;
8
9 [Attribute("", UIWidgets.Auto, "Simulation IDs of wheels to apply particle effects to")]
10 ref array<int> m_aWheels;
11
12 [Attribute("10", UIWidgets.Slider, "Minimal speed for 0% effect intensity interpolation\n[km/h]", "0 300 1")]
13 float m_fDustStartSpeed;
14
15 [Attribute("80", UIWidgets.Slider, "Maximal speed for 100% effect intensity interpolation\n[km/h]", "0 300 1")]
16 float m_fDustTopSpeed;
17
18 [Attribute("250", UIWidgets.Slider, "Maximal distance at which the effect is visible\n[m]", "0 2000 1")]
19 float m_fMaxDistanceVisible;
20
21 float m_fMaxDistanceVisibleSqr;
22
23 override static array<typename> Requires(IEntityComponentSource src)
24 {
25 array<typename> requires = new array<typename>;
26
27 requires.Insert(RplComponent);
28
29 return requires;
30 }
31};
32
35{
36 vector m_vLocalDustPos;
37 bool m_bWheelHasContact;
38 int m_iLastSwap;
39 GameMaterial m_Material;
40 ParticleEffectEntity m_pParticleEffectEntity;
41};
42
43class SCR_VehicleDustPerWheel : ScriptGameComponent
44{
45 protected static const float UPDATE_TIME = 1.0 / 30.0;
46 static const int UPDATE_TIMEOUT = 1000; //Minimal delay between two particle swaps.
47
50 protected ref array<ref VehicleDust> m_aVehicleDusts = {};
51 protected float m_fUpdateTime;
52 protected float m_fTime;
53 protected IEntity m_pOwner;
54
55 //------------------------------------------------------------------------------------------------
56 override void OnPostInit(IEntity owner)
57 {
58 m_pOwner = owner;
59
60 if (System.IsConsoleApp())
61 {
63 return;
64 }
65
67 if (!m_ComponentData || m_ComponentData.m_fDustStartSpeed > m_ComponentData.m_fDustTopSpeed || m_ComponentData.m_fMaxDistanceVisible <= 0)
68 {
70 return;
71 }
72
73 if (!m_ComponentData.m_fMaxDistanceVisibleSqr)
74 {
75 m_ComponentData.m_fMaxDistanceVisibleSqr = m_ComponentData.m_fMaxDistanceVisible * m_ComponentData.m_fMaxDistanceVisible;
76 }
77
79 if (!m_Simulation || !m_Simulation.IsValid())
80 {
82 return;
83 }
84
86 m_fTime = 0.0;
87
88 SetEventMask(owner, EntityEvent.INIT);
89 }
90
91 override void OnDelete(IEntity owner)
92 {
94
95 super.OnDelete(owner);
96 }
97
98 //------------------------------------------------------------------------------------------------
99 override bool OnTicksOnRemoteProxy()
100 {
101 return true;
102 }
103
104 //------------------------------------------------------------------------------------------------
105 override void EOnInit(IEntity owner)
106 {
107 super.EOnInit(owner);
108
110
111 int count = Math.Min(m_Simulation.WheelCount(), m_ComponentData.m_aWheels.Count());
112
113 m_aVehicleDusts.Resize(count);
114 for (int i = 0; i < count; ++i)
115 m_aVehicleDusts[i] = new VehicleDust();
116
117#ifdef ENABLE_DIAG
118 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_PARTICLES_VEHICLE_DUST, "", "Show dust materials", "Vehicles");
119#endif
120 }
121
123 {
124 World world = GetOwner().GetWorld();
125 VehiclesDustSystem updateSystem = VehiclesDustSystem.Cast(world.FindSystem(VehiclesDustSystem));
126 if (!updateSystem)
127 return;
128
129 updateSystem.Register(this);
130 }
131
133 {
134 World world = GetOwner().GetWorld();
135 VehiclesDustSystem updateSystem = VehiclesDustSystem.Cast(world.FindSystem(VehiclesDustSystem));
136 if (!updateSystem)
137 return;
138
139 updateSystem.Unregister(this);
140 }
141
142 //------------------------------------------------------------------------------------------------
143 void Update(float timeSlice)
144 {
145 if (m_Simulation.GetSpeedKmh() < m_ComponentData.m_fDustStartSpeed)
147 else
148 m_fUpdateTime = -1.0;
149
150 m_fTime += timeSlice;
152 {
153 m_fTime = 0.0;
154
155 UpdateBatch();
156 }
157 }
158
159 //------------------------------------------------------------------------------------------------
160 protected void UpdateBatch()
161 {
162 vector camMat[4];
163 m_pOwner.GetWorld().GetCurrentCamera(camMat);
164
165 float distanceFromCamera = vector.DistanceSq(m_pOwner.GetOrigin(), camMat[3]);
166 float speed = m_Simulation.GetSpeedKmh();
167
168 foreach (int index, VehicleDust vehicleDust : m_aVehicleDusts)
169 {
170 UpdateEffect(vehicleDust, index, speed, distanceFromCamera);
171 }
172 }
173
174 //------------------------------------------------------------------------------------------------
175 protected void UpdateEffect(VehicleDust vehicleDust, int index, float speed, float distanceFromCamera)
176 {
177 int wheelIdx = m_ComponentData.m_aWheels[index];
178
179 if (speed < m_ComponentData.m_fDustStartSpeed || distanceFromCamera >= m_ComponentData.m_fMaxDistanceVisibleSqr)
180 {
181 vehicleDust.m_Material = null;
182 if (vehicleDust.m_pParticleEffectEntity)
183 {
184 vehicleDust.m_pParticleEffectEntity.StopEmission();
185 UpdatePosition(vehicleDust, wheelIdx);
186 }
187 return;
188 }
189
190 int ticks = System.GetTickCount();
191 int dif = Math.AbsInt(ticks - vehicleDust.m_iLastSwap);
192
193 if (vehicleDust.m_pParticleEffectEntity && dif < UPDATE_TIMEOUT)
194 {
195 UpdateCurrent(vehicleDust, speed, wheelIdx);
196 return;
197 }
198
199 GameMaterial newMaterial;
200
201 if (m_Simulation.WheelGetContactLiquidState(wheelIdx) > 0)
202 newMaterial = m_Simulation.WheelGetContactLiquidMaterial(wheelIdx);
203 else
204 newMaterial = m_Simulation.WheelGetContactMaterial(wheelIdx);
205
206 bool wheelHasContact = m_Simulation.WheelHasContact(wheelIdx);
207
208 vehicleDust.m_bWheelHasContact = wheelHasContact;
209
210 GameMaterial currentMaterial = vehicleDust.m_Material;
211 ResourceName newResource;
212
213 if (newMaterial && newMaterial != currentMaterial) //different materials -> check resource
214 {
215 ParticleEffectInfo effectInfo = newMaterial.GetParticleEffectInfo();
216 if (effectInfo)
217 newResource = effectInfo.GetVehicleDustResource(m_ComponentData.m_iVehicleIndex);
218 }
219
220 //update current effect
221 if (currentMaterial && vehicleDust.m_pParticleEffectEntity && (newMaterial == currentMaterial || (currentMaterial.GetParticleEffectInfo() && currentMaterial.GetParticleEffectInfo().GetResourceName() == newResource)))
222 {
223 if (newMaterial != currentMaterial) //different GameMats, but resources are the same
224 {
225 vehicleDust.m_Material = newMaterial;
226 }
227
228 UpdateCurrent(vehicleDust, speed, wheelIdx);
229 return;
230 }
231
232 vehicleDust.m_Material = newMaterial;
233 if (vehicleDust.m_pParticleEffectEntity) // stop old effect
234 {
235 vehicleDust.m_pParticleEffectEntity.StopEmission();
236 vehicleDust.m_pParticleEffectEntity = null;
237 }
238
239 //Create new effect
240 if (newResource && newResource.Length() > 0)
241 {
243 spawnParams.TargetWorld = GetOwner().GetWorld();
244 spawnParams.Parent = GetOwner();
245 spawnParams.UseFrameEvent = true;
246 vehicleDust.m_pParticleEffectEntity = ParticleEffectEntity.SpawnParticleEffect(newResource, spawnParams);
247 vehicleDust.m_iLastSwap = ticks;
248 }
249
250 UpdateCurrent(vehicleDust, speed, wheelIdx);
251 }
252
253 //------------------------------------------------------------------------------------------------
254 protected void UpdateCurrent(VehicleDust vehicleDust, float speed, int wheelIdx)
255 {
256 if (!vehicleDust.m_pParticleEffectEntity)
257 return;
258
259 UpdatePosition(vehicleDust, wheelIdx);
260 UpdateVehicleDustEffect(vehicleDust, speed, wheelIdx);
261 }
262
263 //------------------------------------------------------------------------------------------------
264 protected void UpdatePosition(VehicleDust vehicleDust, int wheelIdx)
265 {
266 if(!m_Simulation.WheelHasContact(wheelIdx))
267 return;
268
269 vector position = m_Simulation.WheelGetContactPosition(wheelIdx);
270 vehicleDust.m_pParticleEffectEntity.SetOrigin(position);
271 }
272
273 //------------------------------------------------------------------------------------------------
274 protected void UpdateVehicleDustEffect(VehicleDust vehicleDust, float speed, int wheelIdx)
275 {
276 float endSpeed = m_ComponentData.m_fDustTopSpeed;
277 float speedCoef = 0;
278 float birthCoef = 0;
279 float gravityCoef = 0;
280
281 float longitudinalSlip = m_Simulation.WheelGetLongitudinalSlip(wheelIdx);
282 float lateralSlip = m_Simulation.WheelGetLateralSlip(wheelIdx);
283
284 float effectiveSlip = Math.Clamp(longitudinalSlip + lateralSlip, 0, 1);
285
286 if (vehicleDust.m_bWheelHasContact)
287 {
288 speedCoef = Math.AbsFloat(0.5 + speed * 0.5 / endSpeed + effectiveSlip);
289 birthCoef = Math.AbsFloat(0.5 + speed * 0.5 / endSpeed + effectiveSlip * 2);
290 gravityCoef = Math.AbsFloat(0.8 + speed * 0.2 / endSpeed);
291 }
292
293 Particles particles = vehicleDust.m_pParticleEffectEntity.GetParticles();
294 particles.MultParam(-1, EmitterParam.BIRTH_RATE, birthCoef);
295 particles.MultParam(-1, EmitterParam.GRAVITY_SCALE_RND, gravityCoef);
296 particles.MultParam(-1, EmitterParam.VELOCITY, speedCoef);
297 particles.MultParam(-1, EmitterParam.VELOCITY_RND, speedCoef);
298
299#ifdef ENABLE_DIAG
300 if (!DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_PARTICLES_VEHICLE_DUST))
301 return;
302
303 if (!vehicleDust.m_bWheelHasContact)
304 return;
305
306 if (!vehicleDust.m_Material)
307 return;
308
309 vector effectPosition = vehicleDust.m_pParticleEffectEntity.GetWorldTransformAxis(3);
310 DebugTextWorldSpace.Create(GetOwner().GetWorld(), vehicleDust.m_Material.GetName() + "\nlongSlip: " + longitudinalSlip.ToString(-1, 3) + " latSlip: " + lateralSlip.ToString(-1, 3), DebugTextFlags.CENTER | DebugTextFlags.ONCE, effectPosition[0], effectPosition[1] - 1, effectPosition[2]);
311#endif
312 }
313};
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
void Deactivate()
SCR_CharacterSoundComponentClass GetComponentData()
vector position
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
void UpdatePosition()
Update light position.
void ParticleEffectEntity(IEntitySource src, IEntity parent)
Diagnostic and developer menu system.
Definition DiagMenu.c:18
proto external BaseWorld GetWorld()
Definition Math.c:13
SCR_VehicleDustPerWheelClass m_ComponentData
void UpdateEffect(VehicleDust vehicleDust, int index, float speed, float distanceFromCamera)
void UpdatePosition(VehicleDust vehicleDust, int wheelIdx)
override void EOnInit(IEntity owner)
override void OnDelete(IEntity owner)
ref array< ref VehicleDust > m_aVehicleDusts
override void OnPostInit(IEntity owner)
void UpdateVehicleDustEffect(VehicleDust vehicleDust, float speed, int wheelIdx)
void UpdateCurrent(VehicleDust vehicleDust, float speed, int wheelIdx)
Vehicle dust per wheel data;.
void Register(SCR_VehicleDustPerWheel component)
void Unregister(SCR_VehicleDustPerWheel component)
Definition World.c:16
IEntity GetOwner()
Owner entity of the fuel tank.
DebugTextFlags
SCR_FieldOfViewSettings Attribute
EntityEvent
Various entity events.
Definition EntityEvent.c:14
EmitterParam