diff --git a/SilentPatch/SVF.cpp b/SilentPatch/SVF.cpp index a9e7849..181c5b6 100644 --- a/SilentPatch/SVF.cpp +++ b/SilentPatch/SVF.cpp @@ -11,6 +11,7 @@ namespace SVF constexpr std::pair< const char*, Feature > features[] = { #if _GTA_III || _GTA_VC { "TAXI_LIGHT", Feature::TAXI_LIGHT }, + { "SIT_IN_BOAT", Feature::SIT_IN_BOAT }, #endif #if _GTA_VC @@ -62,6 +63,7 @@ namespace SVF static std::multimap > specialVehFeatures = { #if _GTA_III _registerFeatureInternal( 110, Feature::TAXI_LIGHT ), + _registerFeatureInternal( 142, Feature::SIT_IN_BOAT ), #elif _GTA_VC _registerFeatureInternal( 147, Feature::FBI_WASHINGTON_SIREN ), _registerFeatureInternal( 150, Feature::TAXI_LIGHT ), diff --git a/SilentPatch/SVF.h b/SilentPatch/SVF.h index cc9e204..bb99708 100644 --- a/SilentPatch/SVF.h +++ b/SilentPatch/SVF.h @@ -10,6 +10,7 @@ namespace SVF #if _GTA_III || _GTA_VC TAXI_LIGHT, // Corrected light placement for Taxi + SIT_IN_BOAT, // Sitting animation in the boat, used in Speeder #endif #if _GTA_VC diff --git a/SilentPatchIII/SilentPatchIII.cpp b/SilentPatchIII/SilentPatchIII.cpp index 36dc328..0a2961b 100644 --- a/SilentPatchIII/SilentPatchIII.cpp +++ b/SilentPatchIII/SilentPatchIII.cpp @@ -8,6 +8,7 @@ #include "VehicleIII.h" #include "ModelInfoIII.h" #include "TheFLAUtils.h" +#include "SVF.h" #include #include @@ -766,6 +767,30 @@ namespace GenerateNewPickup_ReuseObjectFix } +// ============= Sitting in boat (Speeder), implemented as a special vehicle feature ============= +// Based off SitInBoat from Fire_Head +namespace SitInBoat +{ + static bool bSitInBoat = false; + static CVector* (*orgGetPositionToOpenCarDoor)(CVector*, CVehicle*, unsigned int); + static CVector* GetPositionToOpenCarDoor_CheckSitInBoat(CVector* out, CVehicle* vehicle, unsigned int type) + { + bSitInBoat = SVF::ModelHasFeature(vehicle->GetModelIndex(), SVF::Feature::SIT_IN_BOAT); + return orgGetPositionToOpenCarDoor(out, vehicle, type); + } + + static void* (*orgBlendAnimation)(void*, unsigned int, unsigned int, float); + static void* BlendAnimation_SitInBoat(void* clump, unsigned int groupId, unsigned int animationId, float factor) + { + if (bSitInBoat) + { + animationId = 0x6F; // ANIMATION_CAR_SIT + } + return orgBlendAnimation(clump, groupId, animationId, factor); + } +} + + void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModulePath ) { using namespace Memory; @@ -1638,6 +1663,19 @@ void Patch_III_Common() pPickupObject = *give_us_a_pick_up_object.get(7 + 2); InterceptCall(give_us_a_pick_up_object.get(2), orgGiveUsAPickUpObject, GiveUsAPickUpObject_CleanUpObject); } + + + // Sitting in boat (Speeder), implemented as a special vehicle feature + // Based off SitInBoat from Fire_Head + { + using namespace SitInBoat; + + auto get_position_to_open_car_door = get_pattern("E8 ? ? ? ? 8B 93 ? ? ? ? 83 C4 0C"); + auto blend_animation = get_pattern("6A 7A 6A 00 50 DD D8 E8 ? ? ? ? 83 C4 10", 7); + + InterceptCall(get_position_to_open_car_door, orgGetPositionToOpenCarDoor, GetPositionToOpenCarDoor_CheckSitInBoat); + InterceptCall(blend_animation, orgBlendAnimation, BlendAnimation_SitInBoat); + } } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)