Branch data Line data Source code
1 : : #include "VehicleUtils.h"
2 : : #include <algorithm>
3 : : #include <string>
4 : :
5 : : // Helper: Parse car class from strings (v0.7.44 Refactor)
6 : : // Returns a ParsedVehicleClass enum for internal logic and categorization
7 : 162 : ParsedVehicleClass ParseVehicleClass(const char* className, const char* vehicleName) {
8 [ + + + - ]: 324 : std::string cls = className ? className : "";
9 [ + + + - ]: 162 : std::string name = vehicleName ? vehicleName : "";
10 : :
11 : : // Normalize for case-insensitive matching
12 : 162 : std::transform(cls.begin(), cls.end(), cls.begin(), ::toupper);
13 : 162 : std::transform(name.begin(), name.end(), name.begin(), ::toupper);
14 : :
15 : : // 1. Primary Identification via Class Name (Hierarchical)
16 [ + + + + : 162 : if (cls.find("HYPERCAR") != std::string::npos || cls.find("LMH") != std::string::npos || cls.find("LMDH") != std::string::npos) {
+ + + + ]
17 : 18 : return ParsedVehicleClass::HYPERCAR;
18 : : }
19 : :
20 [ + + ]: 144 : if (cls.find("LMP2") != std::string::npos) {
21 [ + + + + : 22 : if (cls.find("ELMS") != std::string::npos || name.find("DERESTRICTED") != std::string::npos) { return ParsedVehicleClass::LMP2_UNRESTRICTED; }
+ + ]
22 : 16 : volatile bool is_wec = (cls.find("WEC") != std::string::npos);
23 [ + + ]: 16 : if (is_wec) { return ParsedVehicleClass::LMP2_RESTRICTED; }
24 : 12 : return ParsedVehicleClass::LMP2_UNSPECIFIED;
25 : : }
26 : :
27 [ + + ]: 122 : if (cls.find("LMP3") != std::string::npos) return ParsedVehicleClass::LMP3;
28 [ + + ]: 121 : if (cls.find("GTE") != std::string::npos) return ParsedVehicleClass::GTE;
29 : : // NOTE: LMGT3 check is redundant here as GT3 would match it first.
30 [ + + - + : 114 : if (cls.find("GT3") != std::string::npos || cls.find("LMGT3") != std::string::npos) return ParsedVehicleClass::GT3;
+ + ]
31 : :
32 : : // 2. Secondary Identification via Vehicle Name Keywords (Fallback)
33 [ + + ]: 49 : if (!name.empty()) {
34 : : // Hypercars
35 [ + + + + ]: 133 : if (name.find("499P") != std::string::npos || name.find("GR010") != std::string::npos ||
36 [ + + + + ]: 126 : name.find("963") != std::string::npos || name.find("9X8") != std::string::npos ||
37 [ + + + + ]: 120 : name.find("V-SERIES.R") != std::string::npos || name.find("SCG 007") != std::string::npos ||
38 [ + + + + ]: 114 : name.find("GLICKENHAUS") != std::string::npos || name.find("VANWALL") != std::string::npos ||
39 [ + + + + ]: 108 : name.find("A424") != std::string::npos || name.find("SC63") != std::string::npos ||
40 [ + + + + ]: 102 : name.find("VALKYRIE") != std::string::npos || name.find("M HYBRID") != std::string::npos ||
41 [ + + + + : 123 : name.find("TIPO 6") != std::string::npos || name.find("680") != std::string::npos) {
+ + ]
42 : 15 : return ParsedVehicleClass::HYPERCAR;
43 : : }
44 : :
45 : : // LMP2
46 [ + + + + : 31 : if (name.find("ORECA") != std::string::npos || name.find("07") != std::string::npos) {
+ + ]
47 : 3 : return ParsedVehicleClass::LMP2_UNSPECIFIED;
48 : : }
49 : :
50 : : // LMP3
51 [ + + + + ]: 79 : if (name.find("LIGIER") != std::string::npos || name.find("GINETTA") != std::string::npos ||
52 [ + + + + ]: 72 : name.find("DUQUEINE") != std::string::npos || name.find("P320") != std::string::npos ||
53 [ + + + + : 98 : name.find("P325") != std::string::npos || name.find("G61") != std::string::npos ||
+ + + + ]
54 : 21 : name.find("D09") != std::string::npos) {
55 : 8 : return ParsedVehicleClass::LMP3;
56 : : }
57 : :
58 : : // GTE
59 [ + + + + ]: 57 : if (name.find("RSR-19") != std::string::npos || name.find("488 GTE") != std::string::npos ||
60 [ + + + + : 57 : name.find("C8.R") != std::string::npos || name.find("VANTAGE AMR") != std::string::npos) {
+ + ]
61 : 4 : return ParsedVehicleClass::GTE;
62 : : }
63 : :
64 : : // GT3
65 [ + + + + ]: 45 : if (name.find("LMGT3") != std::string::npos || name.find("296 GT3") != std::string::npos ||
66 [ + + + + ]: 39 : name.find("M4 GT3") != std::string::npos || name.find("Z06 GT3") != std::string::npos ||
67 [ + + + + ]: 33 : name.find("HURACAN") != std::string::npos || name.find("RC F") != std::string::npos ||
68 [ + + + + : 41 : name.find("720S") != std::string::npos || name.find("MUSTANG") != std::string::npos) {
+ + ]
69 : 8 : return ParsedVehicleClass::GT3;
70 : : }
71 : : }
72 : :
73 : 11 : return ParsedVehicleClass::UNKNOWN;
74 : 162 : }
75 : :
76 : : // Lookup table: Map ParsedVehicleClass to Seed Load (Newtons)
77 : 115 : double GetDefaultLoadForClass(ParsedVehicleClass vclass) {
78 [ + + + + : 115 : switch (vclass) {
+ + + + ]
79 : 16 : case ParsedVehicleClass::HYPERCAR: return 9500.0;
80 : 4 : case ParsedVehicleClass::LMP2_UNRESTRICTED: return 8500.0;
81 : 3 : case ParsedVehicleClass::LMP2_RESTRICTED: return 7500.0;
82 : 11 : case ParsedVehicleClass::LMP2_UNSPECIFIED: return 8000.0;
83 : 2 : case ParsedVehicleClass::LMP3: return 5800.0;
84 : 7 : case ParsedVehicleClass::GTE: return 5500.0;
85 : 61 : case ParsedVehicleClass::GT3: return 4800.0;
86 : 11 : default: return 4500.0;
87 : : }
88 : : }
89 : :
90 : : // Helper: String representation of parsed class for logging and UI
91 : 61 : const char* VehicleClassToString(ParsedVehicleClass vclass) {
92 [ + + + + : 61 : switch (vclass) {
+ + + + ]
93 : 9 : case ParsedVehicleClass::HYPERCAR: return "Hypercar";
94 : 3 : case ParsedVehicleClass::LMP2_UNRESTRICTED: return "LMP2 Unrestricted";
95 : 2 : case ParsedVehicleClass::LMP2_RESTRICTED: return "LMP2 Restricted";
96 : 6 : case ParsedVehicleClass::LMP2_UNSPECIFIED: return "LMP2 Unspecified";
97 : 2 : case ParsedVehicleClass::LMP3: return "LMP3";
98 : 5 : case ParsedVehicleClass::GTE: return "GTE";
99 : 30 : case ParsedVehicleClass::GT3: return "GT3";
100 : 4 : default: return "Unknown";
101 : : }
102 : : }
|