Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_VehicleDustComponent.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_VehicleDust")]
7
9{
10 // LIST OF PARTICLE SOURCES
11 static string particle_attribute_descriptions = "Select particle effect for driving on this surface type.";
12 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
13 ResourceName m_Grass;
14 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
15 ResourceName m_Gravel;
16 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
17 ResourceName m_Dirt;
18 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
19 ResourceName m_Default;
20 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
21 ResourceName m_Wood;
22 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
23 ResourceName m_Asphalt;
24 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
25 ResourceName m_Snow;
26 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
27 ResourceName m_Sand;
28 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
29 ResourceName m_Metal;
30 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
31 ResourceName m_Concrete;
32 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
33 ResourceName m_Soil;
34 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
35 ResourceName m_Stone;
36 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
37 ResourceName m_Rubber;
38 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
39 ResourceName m_Flesh;
40 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
41 ResourceName m_Glass;
42 [Attribute( "", UIWidgets.ResourceNamePicker, particle_attribute_descriptions )]
43 ResourceName m_Plastic;
44
45 [Attribute( "", UIWidgets.Coords, "Orientation of the effect relative to the vehicle" )]
46 vector m_vLocalOrientation; // Local rotation of the particle
47
48 [Attribute( "", UIWidgets.Coords, "Position of the effect relative to the object" )]
49 vector m_vLocalOffset; // Local offset of the particle
50
51 [Attribute( "", UIWidgets.EditBox, "Minimal speed (km/h) which triggers the dust effect and its interpolation from 0%" )]
52 float m_fDustStartSpeed;
53
54 [Attribute( "", UIWidgets.EditBox, "Speed (km/h) which tops the effect's interpolation at 100% values" )]
55 float m_fDustTopSpeed;
56 VehicleWheeledSimulation m_VehicleWheeledSimulation;
57 VehicleBodyEffectBase m_Effect;
58 SignalsManagerComponent m_SignalManagerComp;
59 ref map<int, ResourceName> surface_particles = new map<int, ResourceName>();
60 int m_iCurrentSurfaceID;
61 int m_iSurfaceSignalID = -1;
62
63 // Optimization timers
64 float m_fUpdateDelay; // Desired delay between each particle calculations in seconds. 0 means per frame.
65 float m_fCurrentUpdateDelay; // The time of current delay
66 const float TICK_TIME_DELAY_MAX = 2; // Max acceptable delay in seconds
67 const float TICK_DELAY_RANGE_START = 15; // Starting range at which the delay begins to increase (from 0 to TICK_TIME_DELAY_MAX)
68 const float TICK_DELAY_RANGE_END = 100; // End range at which delay reaches its maximum (TICK_TIME_DELAY_MAX)
69
70 override void OnPostInit(IEntity owner)
71 {
72 super.OnPostInit(owner);
73
74 // Don't run this component on console app
75 if (System.IsConsoleApp())
76 {
77 Deactivate(owner);
78 return;
79 }
80 SetEventMask(owner, EntityEvent.INIT | EntityEvent.FRAME);
81 }
82
83 //------------------------------------------------------------------------------------------------
84 override void EOnInit(IEntity owner)
85 {
86 super.EOnInit(owner);
87
88 // Initialize the list of surface types, but only once.
89 if (surface_particles.Count() == 0)
90 RegisterSurfaceTypes();
91
92 // Get data
93 GenericEntity generic_entity = GenericEntity.Cast(owner);
94
95 if (generic_entity)
96 {
97 m_SignalManagerComp = SignalsManagerComponent.Cast(generic_entity.FindComponent(SignalsManagerComponent));
98 m_VehicleWheeledSimulation = VehicleWheeledSimulation.Cast(generic_entity.FindComponent(VehicleWheeledSimulation));
99 }
100
101 // Prep eff
102 if (!m_Effect)
103 {
105 if (m_Effect)
106 {
107 vector mat[4];
108 owner.GetTransform(mat);
109 m_Effect.SetTransform(mat);
110 owner.AddChild(m_Effect, 0);
111 }
112
113 }
114 }
115
116 // Assigns particle files to surface IDs. This should be called only once
117 void RegisterSurfaceTypes()
118 {
119 // DO NOT CHANGE ORDER OF THESE SURFACE TYPES! THEY ARE DEFINED IN THE ENGINE!
120 surface_particles.Insert(0, m_Default);
121 surface_particles.Insert(31, m_Grass);
122 surface_particles.Insert(21, m_Dirt);
123 surface_particles.Insert(25, m_Gravel);
124 surface_particles.Insert(51, m_Wood);
125 surface_particles.Insert(11, m_Asphalt);
126 surface_particles.Insert(41, m_Snow);
127 surface_particles.Insert(28, m_Sand);
128 surface_particles.Insert(61, m_Metal);
129 surface_particles.Insert(12, m_Concrete);
130 surface_particles.Insert(23, m_Soil);
131 surface_particles.Insert(15, m_Stone);
132 surface_particles.Insert(27, m_Stone);
133 surface_particles.Insert(72, m_Rubber);
134 surface_particles.Insert(91, m_Flesh);
135 surface_particles.Insert(71, m_Glass);
136 surface_particles.Insert(73, m_Plastic);
137 }
138
139 override void EOnFrame(IEntity owner, float timeSlice)
140 {
141 m_fCurrentUpdateDelay += timeSlice;
142
143 // Calculate distance between owner and camera
144 vector camera_transform[4];
145 GetGame().GetWorld().GetCurrentCamera(camera_transform);
146 vector camera_world_pos = camera_transform[3];
147 vector relative_pos = camera_world_pos - owner.GetOrigin();
148 float distance = relative_pos.Length();
149
150 // Prolong update interval based on the distance between camera and effect
151 if (distance > TICK_DELAY_RANGE_START)
152 {
153 m_fUpdateDelay = TICK_TIME_DELAY_MAX * ( Math.Clamp( (distance - TICK_DELAY_RANGE_START) / TICK_DELAY_RANGE_END , 0, 1) );
154 }
155 else
156 {
157 m_fUpdateDelay = 0;
158 }
159
160 // Check if delay treshold was crossed. This prevents calling intense calculations per frame for vehicles which are far away from camera as they have low priority
161 if (m_fCurrentUpdateDelay > m_fUpdateDelay)
162 {
163 m_fCurrentUpdateDelay = 0;
164 UpdateEffect(owner);
165 }
166 }
167
168 // Called when the effects needs to be updated. This happens per frame if the camera is close to it, but much slower if further away fr optimization purposes.
169 void UpdateEffect(IEntity owner)
170 {
171 Physics physics = owner.GetPhysics();
172
173 if (physics && m_SignalManagerComp) // Makre sure that data exists
174 {
175 float speed = physics.GetVelocity().Length();
176
177 // Activate particle effect only within the desired speed
178 if (speed >= m_fDustStartSpeed && m_fDustStartSpeed > 0 && m_fDustTopSpeed >= m_fDustStartSpeed)
179 {
180 int previousSurfaceID = m_iCurrentSurfaceID;
181
182 // Only create the signal when it's necessary, otherwise use the ID
183 if (m_iSurfaceSignalID < 0)
184 m_iSurfaceSignalID = m_SignalManagerComp.AddOrFindSignal("surface");
185
186 m_iCurrentSurfaceID = m_SignalManagerComp.GetSignalValue(m_iSurfaceSignalID);
187
188 if (!surface_particles)
189 RegisterSurfaceTypes();
190
191
192 // get and set surface material
193 ResourceName surface_type = m_Default;
194 m_iCurrentSurfaceID = m_iCurrentSurfaceID/100;
195 if (m_iCurrentSurfaceID >= 0 && surface_particles.Contains(m_iCurrentSurfaceID))
196 surface_type = surface_particles.Get(m_iCurrentSurfaceID);
197
198
199 // Vehicle is moving fast enough to generate dust
200 if (m_Effect && previousSurfaceID == m_iCurrentSurfaceID)
201 {
202 m_Effect.Play();
203 m_Effect.UpdateVehicleDustEffect(speed, m_fDustStartSpeed, m_fDustTopSpeed);
204 }
205 else
206 {
207 if (m_Effect)
208 m_Effect.StopEmission();
209
210 if (surface_type.Length() > 0)
211 {
213 spawnParams.Type = VehicleBodyEffectBase;
214 Math3D.AnglesToMatrix(m_vLocalOrientation, spawnParams.Transform);
215 spawnParams.Transform[3] = m_vLocalOffset;
216 spawnParams.Parent = owner;
217 spawnParams.UseFrameEvent = true;
218
219 m_Effect = VehicleBodyEffectBase.Cast(ParticleEffectEntity.SpawnParticleEffect(surface_type, spawnParams));
220 m_Effect.UpdateVehicleDustEffect(speed, m_fDustStartSpeed*3.6, m_fDustTopSpeed);
221 }
222 }
223 }
224 // Vehicle is NOT moving fast enough to generate dust
225 else if (m_Effect)
226 {
227 m_Effect.StopEmission(); // Stop dust effect
228 }
229 }
230 }
231
232 //------------------------------------------------------------------------------------------------
233 void ~SCR_VehicleDust()
234 {
235 if (m_Effect)
236 m_Effect.Stop(); // Clean up
237 }
238};
ArmaReforgerScripted GetGame()
Definition game.c:1398
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
void Deactivate()
IEntity SpawnEntity(ResourceName entityResourceName, notnull IEntity slotOwner)
float distance
void ParticleEffectEntity(IEntitySource src, IEntity parent)
proto external int SetEventMask(notnull IEntity owner, int mask)
proto external Managed FindComponent(typename typeName)
proto external vector GetOrigin()
proto external Physics GetPhysics()
proto external int AddChild(notnull IEntity child, TNodeId pivot, EAddChildFlags flags=EAddChildFlags.AUTO_TRANSFORM)
Add Entity to hierarchy. Pivot is pivot index, or -1 for center of parent.
proto external BaseWorld GetWorld()
proto external void GetTransform(out vector mat[])
Definition Math.c:13
Definition Types.c:486
SCR_FieldOfViewSettings Attribute
EntityEvent
Various entity events.
Definition EntityEvent.c:14