feat(handling-loader): Add support for SubHandlingData for GetVehicleHandlingFloat/SetVehicleHandlingFloat
Originally #1254 Adds support for CCarHandlingData fields for GetVehicleHandlingFloat and SetVehicleHandlingFloat
2 might be CSpecialFlightHandlingData and 4 CSeaPlaneHandlingData
2 might be CSpecialFlightHandlingData and 4 CSeaPlaneHandlingData
Do you know which vehicles have these fields so I can test?
CSpecialFlightHandlingData used for DELUXO and OPPRESSOR2 (see handling.meta of mpchristmas2017/mpbattle).
CSeaPlaneHandlingData is used for SEAPLANE (spupgrade), SEASPARROW (mpassault), TULA and SEABREEZE (mpsmuggler).
Added CSpecialFlightHandlingData and CSeaPlaneHandlingData, still missing what 2 is.
The only thing I can find is possibly CBaseSubHandlingData from here: https://gtamods.com/wiki/Handling.meta#CBaseSubHandlingData but it has no fields, so it doesn't really matter.
You got it working, congratz! I would opt for some changes.
- using an std::map to map strings to indices, this can be replaced by a str(i)cmp on the CBaseSubHandlingData* class names (more generic).
- the std::map is being traversed (::find) several times, with the same key, through-out the whole code, this means there are multiple O(log n) calls where we could've just cached the first.
I’m not sure I understand your first bullet.
- using an std::map to map strings to indices, this can be replaced by a str(i)cmp on the CBaseSubHandlingData* class names (more generic).
Are you suggesting doing if else branching and using strcmp for to find the indices? That seems way less performant.
No, literally comparing the class name to the given name, something like this:
CBaseSubHandlingData* sub = subHandlingData.Get(i);
if (sub && _stricmp(handlingClass, typeid(*sub).name() + 6) == 0)
...
also for performance reasons use an unordered map, not the ordered std::map, unless you need to have them ordered ;)
Commenting this here in case anyone needs to reference it in the future for any research or something. That is, if GitHub search indexes this correctly.
static std::map<std::string, std::uint32_t> subHandlingTypeIndex{
{ "CBikeHandlingData", 0 },
{ "CFlyingHandlingData", 1 },
{ "CBoatHandlingData", 3 },
{ "CSeaPlaneHandlingData", 4 },
{ "CSubmarineHandlingData", 5 },
{ "CTrailerHandlingData", 7 },
{ "CCarHandlingData", 8 },
{ "CVehicleWeaponHandlingData", 9 },
{ "CSpecialFlightHandlingData", 10 }
};
No, literally comparing the class name to the given name, something like this:
CBaseSubHandlingData* sub = subHandlingData.Get(i); if (sub && _stricmp(handlingClass, typeid(*sub).name() + 6) == 0) ...
Thanks @Fortahr! I didn't realize the typeid(*ptr).name() was a thing. This is what I was originally looking for when doing this but couldn't figure out how to get the name. I've made the change to do the comparison as you suggested.
My pleasure! Your PR made it look like it was possible. Also note that this typeid data isn't always compiled so you'll have to test it.
Instead of typeid stuff the RAGE parser structures may also be a good option, though I'm not sure if it's trivial to get the vtable (and therefore the index) from their definitions that include hashes of their names.
(do a hex search in IDA for the case sensitive Jenkins hash of these class names to find them)
I tested with the current code and it works, so unless you really want it changed, then I’m going to leave it as is.
Is there any further work that needs to be done for this PR?
if this request is accepted there is a toolkit that can help other people link: https://adam10603.github.io/GTA5VehicleFlagTool/
implement please. with sub-handling data becoming more used by rockstar this would be very useful.
With #1688 merged this can be closed.
I guess it's time to update vstancer and handling-editor