diff --git a/code/components/gta-net-five/src/netSyncTree.cpp b/code/components/gta-net-five/src/netSyncTree.cpp index c8a17505be..66662d71ca 100644 --- a/code/components/gta-net-five/src/netSyncTree.cpp +++ b/code/components/gta-net-five/src/netSyncTree.cpp @@ -6,6 +6,27 @@ #include #include +// PatchVehicleHoodCamera.cpp +enum eVehicleType : uint32_t +{ + VEHICLE_TYPE_CAR = 0, + VEHICLE_TYPE_PLANE, + VEHICLE_TYPE_TRAILER, + VEHICLE_TYPE_QUADBIKE, + VEHICLE_TYPE_DRAFT, + VEHICLE_TYPE_SUBMARINECAR, + VEHICLE_TYPE_AMPHIBIOUS_AUTOMOBILE, + VEHICLE_TYPE_AMPHIBIOUS_QUADBIKE, + VEHICLE_TYPE_HELI, + VEHICLE_TYPE_BLIMP, + VEHICLE_TYPE_AUTOGYRO, + VEHICLE_TYPE_BIKE, + VEHICLE_TYPE_BICYCLE, + VEHICLE_TYPE_BOAT, + VEHICLE_TYPE_TRAIN, + VEHICLE_TYPE_SUBMARINE, +}; + static hook::cdecl_stub getSyncTreeForType([]() { return hook::get_pattern("0F B7 CA 83 F9 07 7F 5E"); @@ -51,36 +72,96 @@ static bool (*g_origVehicleCreationDataNode__CanApply)(void*, rage::netObject*); typedef void* (*GetArchetypeForHashFn)(uint32_t, int*); static GetArchetypeForHashFn g_getArcheTypeForHash; -static bool CVehicleCreationDataNode__CanApply(void* thisptr, rage::netObject* netObj /*Hidden argument*/) +// basically a reconstruction of IS_THIS_MODEL_A_XXXX +static uint32_t GetModelType(uint32_t hash) { - // Crashfix for de-sync between helicopter netobj type and vehicle hash - if (netObj->GetObjectType() == (uint16_t)NetObjEntityType::Heli) + int flags = 0xFFFF; + void* archetype = g_getArcheTypeForHash(hash, &flags); + if (archetype) { - uint32_t hash = *(uint32_t*)(uintptr_t(thisptr) + 200); - - // basically a reconstruction of IS_THIS_MODEL_A_XXXX - int flags = 0xFFFF; - bool modelTypeOK = false; - void* archetype = g_getArcheTypeForHash(hash, &flags); - if (archetype) + uint8_t* pType = (((uint8_t*)archetype) + 157); + if ((*pType & 0x1F) == 5) { - uint8_t* pType = (((uint8_t*)archetype) + 157); - if ((*pType & 0x1F) == 5) - { - uint32_t vehicleType = *(uint32_t*)(((uint8_t*)archetype) + 0x340); - if (vehicleType == 8 /*Heli*/ || vehicleType == 9 /*Blimp*/) - { - modelTypeOK = true; - } - } + uint32_t vehicleType = *(uint32_t*)(((uint8_t*)archetype) + 0x340); + return vehicleType; } - if (!modelTypeOK) + } + return -1; +} +static bool CVehicleCreationDataNode__CanApply(void* thisptr, rage::netObject* netObj /*Hidden argument*/) +{ + uint32_t hash = *(uint32_t*)(uintptr_t(thisptr) + 200); + uint32_t modelType = GetModelType(hash); + // Various Crashfixes for de-sync between netobj type and model hash + if (netObj->GetObjectType() == (uint16_t)NetObjEntityType::Heli) + { + if (modelType != VEHICLE_TYPE_HELI && modelType != VEHICLE_TYPE_BLIMP) { // Force hash to a Buzzard2, or it will cause crashes down the line(ropemanager, damagestatus, etc.) // better than returning false (makes them invisible) *(uint32_t*)(uintptr_t(thisptr) + 200) = 0x2C75F0DD; } } + if (netObj->GetObjectType() == (uint16_t)NetObjEntityType::Boat) + { + if (modelType != VEHICLE_TYPE_BOAT) + { + // force to dinghy2 + *(uint32_t*)(uintptr_t(thisptr) + 200) = 0x107F392C; + } + } + if (netObj->GetObjectType() == (uint16_t)NetObjEntityType::Automobile) + { + if (modelType != VEHICLE_TYPE_CAR + && modelType != VEHICLE_TYPE_SUBMARINECAR + && modelType != VEHICLE_TYPE_QUADBIKE + && modelType != VEHICLE_TYPE_AMPHIBIOUS_AUTOMOBILE + && modelType != VEHICLE_TYPE_AMPHIBIOUS_QUADBIKE) + { + // force to stromberg + *(uint32_t*)(uintptr_t(thisptr) + 200) = 0x34DBA661; + } + } + if (netObj->GetObjectType() == (uint16_t)NetObjEntityType::Train) + { + if (modelType != VEHICLE_TYPE_TRAIN) + { + // freight + *(uint32_t*)(uintptr_t(thisptr) + 200) = 0x3D6AAA9B; + } + } + if (netObj->GetObjectType() == (uint16_t)NetObjEntityType::Bike) + { + if (modelType != VEHICLE_TYPE_BICYCLE && modelType != VEHICLE_TYPE_BIKE) + { + // sanchez + *(uint32_t*)(uintptr_t(thisptr) + 200) = 0x2EF89E46; + } + } + if (netObj->GetObjectType() == (uint16_t)NetObjEntityType::Submarine) + { + if (modelType != VEHICLE_TYPE_SUBMARINE) + { + // submersible + *(uint32_t*)(uintptr_t(thisptr) + 200) = 0x2DFF622F; + } + } + if (netObj->GetObjectType() == (uint16_t)NetObjEntityType::Trailer) + { + if (modelType != VEHICLE_TYPE_TRAILER) + { + // tanker + *(uint32_t*)(uintptr_t(thisptr) + 200) = 0xD46F4737; + } + } + if (netObj->GetObjectType() == (uint16_t)NetObjEntityType::Plane) + { + if (modelType != VEHICLE_TYPE_PLANE) + { + // cargoplane + *(uint32_t*)(uintptr_t(thisptr) + 200) = 0x15F27762; + } + } return g_origVehicleCreationDataNode__CanApply(thisptr, netObj); }