Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_BIKIVehicleHelper.c
Go to the documentation of this file.
1#ifdef WORKBENCH
5class SCR_BIKIVehicleHelper
6{
7 static const float KW2HP = 1.34102; // mechanical horsepower
8 static const float HP2KW = 0.73549875;
9
10 static const float KW2PS = 1.3596216173039; // metric horsepower
11 static const float PS2KW = 0.7457;
12
13 static const float KW2NMRPM = 9549.296585513720; // metric units FTW
14 static const float NMRPM2KW = 0.000104719751;
15
16 //------------------------------------------------------------------------------------------------
19 static array<float> GetGearRatios(notnull BaseContainer vehicleContainer)
20 {
21 BaseContainer baseContainer = GetSimulationContainer(vehicleContainer);
22 if (!baseContainer)
23 return {};
24
25 baseContainer = baseContainer.GetObject("Gearbox");
26 if (!baseContainer)
27 return {};
28
29 array<float> result;
30 if (!baseContainer.Get("Forward", result))
31 result = {};
32
33 float reverse;
34 if (baseContainer.Get("Reverse", reverse))
35 result.InsertAt(-reverse, 0);
36
37 return result;
38 }
39
40 //------------------------------------------------------------------------------------------------
43 static bool GetAutomaticGearbox(notnull BaseContainer vehicleContainer)
44 {
45 array<IEntityComponentSource> componentSources = {};
46 if (SCR_BaseContainerTools.FindComponentSourcesOfClass(vehicleContainer, SCR_CarControllerComponent, true, componentSources) < 1)
47 return false;
48
49 IEntityComponentSource componentSource = componentSources[0];
50 if (!componentSource)
51 return false;
52
53 int gearboxMode;
54 if (!componentSource.Get("Type", gearboxMode))
55 return false;
56
57 return gearboxMode == 1; // 0 = manual, 1 = automatic
58 }
59
60 //------------------------------------------------------------------------------------------------
63 static float GetInitialFuelQuantity(notnull BaseContainer vehicleContainer)
64 {
65 IEntityComponentSource componentSource = SCR_BaseContainerTools.FindComponentSource(vehicleContainer, SCR_FuelManagerComponent);
66 if (!componentSource)
67 return 0;
68
69 BaseContainerList list = componentSource.GetObjectArray("FuelNodes");
70 if (!list)
71 return 0;
72
73 BaseContainer baseContainer;
74 float result;
75 for (int i, count = list.Count(); i < count; ++i)
76 {
77 float maxFuel;
78 list.Get(i).Get("m_fInitialFuelTankState", maxFuel);
79 result += maxFuel;
80 }
81
82 return result;
83 }
84
85 //------------------------------------------------------------------------------------------------
88 static float GetFuelCapacity(notnull BaseContainer vehicleContainer)
89 {
90 IEntityComponentSource componentSource = SCR_BaseContainerTools.FindComponentSource(vehicleContainer, SCR_FuelManagerComponent);
91 if (!componentSource)
92 return 0;
93
94 BaseContainerList list = componentSource.GetObjectArray("FuelNodes");
95 if (!list)
96 return 0;
97
98 BaseContainer baseContainer;
99 float result;
100 for (int i, count = list.Count(); i < count; ++i)
101 {
102 float maxFuel;
103 list.Get(i).Get("MaxFuel", maxFuel);
104 result += maxFuel;
105 }
106
107 return result;
108 }
109
110 //------------------------------------------------------------------------------------------------
113 static float GetFuelIdleConsumption(notnull BaseContainer vehicleContainer)
114 {
115 IEntityComponentSource componentSource = SCR_BaseContainerTools.FindComponentSource(vehicleContainer, SCR_FuelConsumptionComponent);
116 if (!componentSource)
117 return 0;
118
119 float result;
120 componentSource.Get("m_fFuelConsumptionIdle", result);
121 return result;
122 }
123
124 //------------------------------------------------------------------------------------------------
127 static float GetFuelMaxConsumption(notnull BaseContainer vehicleContainer)
128 {
129 IEntityComponentSource componentSource = SCR_BaseContainerTools.FindComponentSource(vehicleContainer, SCR_FuelConsumptionComponent);
130 if (!componentSource)
131 return 0;
132
133 float result;
134 componentSource.Get("m_fFuelConsumption", result);
135 return result;
136 }
137
138 //------------------------------------------------------------------------------------------------
141 static array<EFuelType> GetFuelTypes(notnull BaseContainer vehicleContainer)
142 {
143 IEntityComponentSource componentSource = SCR_BaseContainerTools.FindComponentSource(vehicleContainer, SCR_FuelManagerComponent);
144 if (!componentSource)
145 return {};
146
147 BaseContainerList list = componentSource.GetObjectArray("FuelNodes");
148 if (!list)
149 return {};
150
151 array<EFuelType> result = {};
152 BaseContainer baseContainer;
153 for (int i, count = list.Count(); i < count; ++i)
154 {
155 EFuelType fuelType;
156 list.Get(i).Get("FuelType", fuelType);
157 if (!result.Contains(fuelType))
158 result.Insert(fuelType);
159 }
160
161 return result;
162 }
163
164 //------------------------------------------------------------------------------------------------
167 static array<string> GetFuelTypesAsString(notnull BaseContainer vehicleContainer)
168 {
169 array<string> result = {};
170 foreach (EFuelType fuelType : GetFuelTypes(vehicleContainer))
171 {
172 result.Insert(SCR_StringHelper.FormatSnakeCaseToUserFriendly(typename.EnumToString(EFuelType, fuelType)));
173 }
174
175 return result;
176 }
177
178 //------------------------------------------------------------------------------------------------
181 static float GetMechanicalHorsePower(notnull BaseContainer vehicleContainer)
182 {
183 return GetEnginePowerKW(vehicleContainer) * KW2HP;
184 }
185
186 //------------------------------------------------------------------------------------------------
189 static float GetMetricHorsePower(notnull BaseContainer vehicleContainer)
190 {
191 return GetEnginePowerKW(vehicleContainer) * KW2PS;
192 }
193
194 //------------------------------------------------------------------------------------------------
197 static float GetEnginePowerKW(notnull BaseContainer vehicleContainer)
198 {
199 BaseContainer baseContainer = GetEngineContainer(vehicleContainer);
200 if (!baseContainer)
201 return 0;
202
203 float result;
204 if (baseContainer.Get("MaxPower", result)) // wheeled engine
205 return result;
206
207 // helicopter?
208 baseContainer = GetSimulationContainer(vehicleContainer);
209 BaseContainerList baseContainerList = baseContainer.GetObjectArray("Rotors");
210 if (!baseContainerList)
211 return 0;
212
213 if (baseContainerList.Count() < 1)
214 return 0;
215
216 baseContainer = baseContainerList.Get(0); // first rotor = main rotor, lessgo?
217
218 float rpm;
219 if (!baseContainer.Get("TargetRPM", rpm))
220 return 0;
221
222 vector torque;
223 if (!baseContainer.Get("TorqueForce", torque))
224 return 0;
225
226 return rpm * torque[1] * NMRPM2KW;
227 }
228
229 //------------------------------------------------------------------------------------------------
233 static float GetEnginePowerKWByGearAndRPM(notnull BaseContainer vehicleContainer, int gearIndex, float rpm)
234 {
235 array<float> gearRatios = GetGearRatios(vehicleContainer);
236 if (!gearRatios.IsIndexValid(gearIndex)) // covers empty gearRatios as well
237 return 0;
238
239 float gearRatio = gearRatios[gearIndex];
240
241 return 0;
242 }
243
244 //------------------------------------------------------------------------------------------------
247 static float GetIdleRPM(notnull BaseContainer vehicleContainer)
248 {
249 BaseContainer baseContainer = GetEngineContainer(vehicleContainer);
250 if (!baseContainer)
251 return 0;
252
253 float result;
254 if (baseContainer.Get("RpmIdle", result)) // VehicleWheeledSimulation
255 return result;
256
257 if (baseContainer.Get("RPMIdle", result)) // VehicleHelicopterSimulation
258 return result;
259
260 return 0;
261 }
262
263 //------------------------------------------------------------------------------------------------
266 static float GetRPMRedLine(notnull BaseContainer vehicleContainer)
267 {
268 BaseContainer baseContainer = GetEngineContainer(vehicleContainer);
269 if (!baseContainer)
270 return 0;
271
272 float result;
273 if (baseContainer.Get("RpmRedline", result)) // VehicleWheeledSimulation
274 return result;
275
276 return 0;
277 }
278
279 //------------------------------------------------------------------------------------------------
282 static float GetMaxRPM(notnull BaseContainer vehicleContainer)
283 {
284 BaseContainer baseContainer = GetEngineContainer(vehicleContainer);
285 if (!baseContainer)
286 return 0;
287
288 float result;
289 if (baseContainer.Get("RpmMax", result)) // VehicleWheeledSimulation
290 return result;
291
292 if (baseContainer.Get("RPMMax", result)) // VehicleWheeledSimulation
293 return result;
294
295 return 0;
296 }
297
298 //------------------------------------------------------------------------------------------------
301 static float GetDifferentialRatio(notnull BaseContainer vehicleContainer)
302 {
303 BaseContainer baseContainer = GetSimulationContainer(vehicleContainer);
304 if (!baseContainer)
305 return 0;
306
307 BaseContainerList baseContainerList = baseContainer.GetObjectArray("Differentials");
308 if (!baseContainerList || baseContainerList.Count() < 1)
309 return 0;
310
311 baseContainer = baseContainerList.Get(0);
312 if (!baseContainer)
313 return 0;
314
315 float result;
316 baseContainer.Get("Ratio", result);
317
318 return result;
319 }
320
321 //------------------------------------------------------------------------------------------------
324 static float GetAxleDifferentialRatio(notnull BaseContainer vehicleContainer)
325 {
326 BaseContainer baseContainer = GetSimulationContainer(vehicleContainer);
327 if (!baseContainer)
328 return 0;
329
330 BaseContainerList baseContainerList = baseContainer.GetObjectArray("Axles");
331 if (!baseContainerList)
332 return 0;
333
334 float result;
335 for (int i, count = baseContainerList.Count(); i < count; ++i)
336 {
337 baseContainer = baseContainerList.Get(i);
338 if (!baseContainer)
339 continue;
340
341 baseContainer = baseContainer.GetObject("Differential");
342 if (!baseContainer)
343 continue;
344
345 if (baseContainer.Get("Ratio", result))
346 return result;
347 }
348
349 return 0;
350 }
351
352 //------------------------------------------------------------------------------------------------
355 static float GetAxleCount(notnull BaseContainer vehicleContainer)
356 {
357 BaseContainer baseContainer = GetSimulationContainer(vehicleContainer);
358 if (!baseContainer)
359 return 0;
360
361 BaseContainerList baseContainerList = baseContainer.GetObjectArray("Axles");
362 if (!baseContainerList)
363 return 0;
364
365 return baseContainerList.Count();
366 }
367
368 //------------------------------------------------------------------------------------------------
371 static float GetWheelsCircumference(notnull BaseContainer vehicleContainer)
372 {
373 BaseContainer baseContainer = GetSimulationContainer(vehicleContainer);
374 if (!baseContainer)
375 return 0;
376
377 BaseContainerList baseContainerList = baseContainer.GetObjectArray("Axles");
378 if (!baseContainerList || baseContainerList.Count() < 1)
379 return 0;
380
381 baseContainer = baseContainerList.Get(0);
382 if (!baseContainer)
383 return 0;
384
385 baseContainer = baseContainer.GetObject("Wheel");
386
387 float result;
388 baseContainer.Get("Radius", result);
389
390 return 2 * Math.PI * result;
391 }
392
393 //------------------------------------------------------------------------------------------------
396 static float GetTheoreticalMaxSpeed(notnull BaseContainer vehicleContainer, bool useMaxRPM = false)
397 {
398 array<float> gearRatios = GetGearRatios(vehicleContainer);
399 if (gearRatios.Count() < 1)
400 return 0;
401
402 float engineRPM;
403 if (useMaxRPM)
404 engineRPM = GetMaxRPM(vehicleContainer);
405 else
406 engineRPM = GetRPMRedLine(vehicleContainer);
407
408 if (SCR_BIKIGeneralHelper.IsWheeled(vehicleContainer))
409 {
410 float axleDifferentialRatio = GetAxleDifferentialRatio(vehicleContainer);
411 float wheelCircumference = GetWheelsCircumference(vehicleContainer);
412 return GetTheoreticalSpeed(engineRPM, gearRatios[gearRatios.Count() - 1], axleDifferentialRatio, wheelCircumference);
413 }
414
415 if (SCR_BIKIGeneralHelper.IsTracked(vehicleContainer))
416 {
417 BaseContainer roadWheel = GetSimulationContainer(vehicleContainer).GetObject("RoadWheel");
418 if (!roadWheel)
419 return 0;
420
421 float wheelCircumference;
422 if (!roadWheel.Get("Radius", wheelCircumference))
423 return 0;
424
425 return GetTheoreticalSpeed(engineRPM, gearRatios[gearRatios.Count() - 1], 1, wheelCircumference);
426 }
427
428 return 0;
429 }
430
431 //------------------------------------------------------------------------------------------------
434 static array<float> GetTheoreticalMaxSpeedForAllGears(notnull BaseContainer vehicleContainer)
435 {
436 array<float> result = GetGearRatios(vehicleContainer);
437 if (result.IsEmpty())
438 return result;
439
440 float engineRPM = GetRPMRedLine(vehicleContainer);
441 float axleDifferentialRatio = GetAxleDifferentialRatio(vehicleContainer);
442 float wheelCircumference = GetWheelsCircumference(vehicleContainer);
443 foreach (int i, float gearRatio : result)
444 {
445 result[i] = GetTheoreticalSpeed(engineRPM, gearRatio, axleDifferentialRatio, wheelCircumference);
446 }
447
448 return result;
449 }
450
451 //------------------------------------------------------------------------------------------------
457 protected static float GetTheoreticalSpeed(float engineRPM, float gearRatio, float axleDifferentialRatio, float wheelCircumference)
458 {
459 if (engineRPM <= 0 || axleDifferentialRatio <= 0 || wheelCircumference <= 0 || gearRatio == 0)
460 return 0;
461
462 float axleRPM = engineRPM / (gearRatio * axleDifferentialRatio);
463 float groundSpeed = axleRPM * (wheelCircumference / 60) * 3.6;
464
465 return groundSpeed;
466 }
467
468 //------------------------------------------------------------------------------------------------
471 static float GetMaxSpeed(notnull BaseContainer vehicleContainer)
472 {
473return 0;
474 float theoreticalMaxSpeed = GetTheoreticalMaxSpeed(vehicleContainer);
475 if (theoreticalMaxSpeed == 0)
476 return 0;
477
478 // get air drag
479 // AirDrag we use 0.5f * air_density * dragCoef * frontArea * speed^2
480 // air_density = 1.225
481
482 // const float airDensity = 1.225;
483 // dragCoef = ?
484 // float airDrag = 0.5 * airDensity * dragCoef * frontArea * theoreticalMaxSpeed * theoreticalMaxSpeed;
485
486// return theoreticalMaxSpeed - airDrag;
487 }
488
489 //------------------------------------------------------------------------------------------------
492 static array<int> GetSeats(notnull BaseContainer baseCompartmentHolder)
493 {
494 array<int> result = { 0, 0, 0, 0 };
495
496 IEntityComponentSource componentSource = SCR_BaseContainerTools.FindComponentSource(baseCompartmentHolder, SCR_BaseCompartmentManagerComponent);
497 BaseContainerList baseContainerList;
498 BaseContainer baseContainer;
499 typename typeName;
500 if (componentSource)
501 {
502 baseContainerList = componentSource.GetObjectArray("CompartmentSlots");
503 if (baseContainerList)
504 {
505 for (int i, count = baseContainerList.Count(); i < count; ++i)
506 {
507 baseContainer = baseContainerList.Get(i);
508 typeName = baseContainer.GetClassName().ToType();
509 if (!typeName)
510 continue;
511
512 // commander
513 if (IsTurretCommanderSeat(baseContainer))
514 {
515 result[2] = result[2] + 1;
516 continue;
517 }
518
519 // gunner
520 if (typeName.IsInherited(TurretCompartmentSlot))
521 {
522 result[1] = result[1] + 1; // gunner
523 continue;
524 }
525
526 // driver / pilots
527 if (typeName.IsInherited(PilotCompartmentSlot))
528 {
529 result[0] = result[0] + 1;
530 continue;
531 }
532
533 // cargo
534 if (typeName.IsInherited(CargoCompartmentSlot))
535 {
536 result[3] = result[3] + 1;
537 continue;
538 }
539 }
540 }
541 }
542
543 componentSource = SCR_BaseContainerTools.FindComponentSource(baseCompartmentHolder, SlotManagerComponent);
544 if (componentSource)
545 {
546 baseContainerList = componentSource.GetObjectArray("Slots");
547 if (baseContainerList)
548 {
549 ResourceName resourceName;
550 Resource resource;
551 array<int> subResult;
552 for (int i, count = baseContainerList.Count(); i < count; ++i)
553 {
554 baseContainer = baseContainerList.Get(i);
555 if (!baseContainer.Get("Prefab", resourceName) || !resourceName) // .IsEmpty()
556 continue;
557
558 resource = Resource.Load(resourceName);
559 if (!resource.IsValid())
560 continue;
561
562 subResult = GetSeats(resource.GetResource().ToBaseContainer());
563 for (int j; j < 4; ++j)
564 {
565 result[j] = result[j] + subResult[j];
566 }
567 }
568 }
569 }
570
571 return result;
572 }
573
574 //------------------------------------------------------------------------------------------------
575 // This is the best detection we have for now
578 protected static bool IsTurretCommanderSeat(notnull BaseContainer compartmentContainer)
579 {
580 string commanderStr;
581 if (compartmentContainer.Get("CompartmentUniqueName", commanderStr))
582 {
583 commanderStr.ToLower();
584 if (commanderStr.Contains("commander"))
585 return true;
586 }
587
588 BaseContainer baseContainer = compartmentContainer.GetObject("UIInfo");
589 if (baseContainer)
590 {
591 if (baseContainer.Get("Name", commanderStr)) // eventually #AR-VehiclePosition_Commander
592 {
593 commanderStr.ToLower();
594 if (commanderStr.Contains("commander"))
595 return true;
596 }
597 }
598
599 return false;
600 }
601
602 //------------------------------------------------------------------------------------------------
603 // PROTECTED METHODS (helper's helpers)
604 //------------------------------------------------------------------------------------------------
605
606 //------------------------------------------------------------------------------------------------
607 protected static BaseContainer GetSimulationContainer(notnull BaseContainer vehicleContainer)
608 {
609 IEntityComponentSource componentSource = SCR_BaseContainerTools.FindComponentSource(vehicleContainer, VehicleBaseSimulation);
610 if (!componentSource)
611 return null;
612
613 return componentSource.GetObject("Simulation");
614 }
615
616 //------------------------------------------------------------------------------------------------
617 protected static BaseContainer GetEngineContainer(notnull BaseContainer vehicleContainer)
618 {
619 BaseContainer baseContainer = GetSimulationContainer(vehicleContainer);
620 if (!baseContainer)
621 return null;
622
623 return baseContainer.GetObject("Engine");
624 }
625
626 //------------------------------------------------------------------------------------------------
627 protected static BaseContainer GetGearboxContainer(notnull BaseContainer vehicleContainer)
628 {
629 BaseContainer baseContainer = GetSimulationContainer(vehicleContainer);
630 if (!baseContainer)
631 return null;
632
633 return baseContainer.GetObject("Gearbox");
634 }
635}
636#endif // WORKBENCH
EFuelType
Definition EFuelType.c:8
ResourceName resourceName
Definition SCR_AIGroup.c:66
void SCR_FuelManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)