feat: Vehicle control & Summon (#1175)

This commit is contained in:
DayibBaba 2023-04-05 19:54:29 +02:00 committed by GitHub
parent 24955f9019
commit 96d1c26242
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 2106 additions and 49 deletions

View File

@ -17,8 +17,8 @@ if(NOT imgui_POPULATED)
"${imgui_SOURCE_DIR}/misc/cpp/imgui_stdlib.cpp"
)
add_library(imgui STATIC ${SRC_IMGUI})
source_group(TREE ${imgui_SOURCE_DIR} PREFIX "imgui" FILES ${SRC_IMGUI} )
add_library(imgui STATIC ${SRC_IMGUI} )
source_group(TREE ${imgui_SOURCE_DIR} PREFIX "imgui" FILES ${SRC_IMGUI})
target_include_directories(imgui PRIVATE
"${imgui_SOURCE_DIR}"
"${imgui_SOURCE_DIR}/backends"

View File

@ -6,6 +6,7 @@
#include "script_patches.hpp"
#include "services/context_menu/context_menu_service.hpp"
#include "services/orbital_drone/orbital_drone.hpp"
#include "services/vehicle/vehicle_control_service.hpp"
#include "thread_pool.hpp"
@ -206,4 +207,15 @@ namespace big
script::get_current()->yield();
}
}
void backend::vehicle_control()
{
while (true)
{
g_vehicle_control_service.tick();
script::get_current()->yield();
}
}
}

View File

@ -19,5 +19,6 @@ namespace big
static void disable_control_action_loop();
static void world_loop();
static void orbital_drone();
static void vehicle_control();
};
}

View File

@ -394,8 +394,9 @@ namespace big
int fast_quit = 0;
int cmd_excecutor = 0x55;
int repairpv = 0;
int open_vehicle_controller = 0;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(hotkeys, editing_menu_toggle, menu_toggle, teleport_waypoint, teleport_objective, noclip, bringvehicle, invis, heal, fill_inventory, skip_cutscene, freecam, superrun, superjump, beastjump, invisveh, localinvisveh, fill_ammo, fast_quit, cmd_excecutor, repairpv)
NLOHMANN_DEFINE_TYPE_INTRUSIVE(hotkeys, editing_menu_toggle, menu_toggle, teleport_waypoint, teleport_objective, noclip, bringvehicle, invis, heal, fill_inventory, skip_cutscene, freecam, superrun, superjump, beastjump, invisveh, localinvisveh, fill_ammo, fast_quit, cmd_excecutor, repairpv, open_vehicle_controller)
} hotkeys{};
bool dev_dlc = false;
@ -711,7 +712,17 @@ namespace big
NLOHMANN_DEFINE_TYPE_INTRUSIVE(ingame_overlay, opened, show_with_menu_opened, show_fps, show_players, show_time, show_replay_interface, show_game_versions)
} ingame_overlay{};
NLOHMANN_DEFINE_TYPE_INTRUSIVE(window, color, gui_scale, switched_view, ingame_overlay)
struct vehicle_control
{
bool opened = false;
bool operation_animation = true;
bool render_distance_on_veh = false;
float max_summon_range = 200.f;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(vehicle_control, operation_animation, max_summon_range, render_distance_on_veh)
} vehicle_control{};
NLOHMANN_DEFINE_TYPE_INTRUSIVE(window, color, gui_scale, switched_view, ingame_overlay, vehicle_control)
} window{};
struct context_menu

View File

@ -1447,3 +1447,475 @@ enum class PedBones : std::uint32_t
FB_R_Lip_Bot_001 = 0xC33B,
FB_Tongue_001 = 0xB987
};
enum class eVehicleLockState
{
VEHICLELOCK_NONE,
VEHICLELOCK_UNLOCKED,
VEHICLELOCK_LOCKED,
VEHICLELOCK_LOCKOUT_PLAYER_ONLY,
VEHICLELOCK_LOCKED_PLAYER_INSIDE,
VEHICLELOCK_LOCKED_INITIALLY,
VEHICLELOCK_FORCE_SHUT_DOORS,
VEHICLELOCK_LOCKED_BUT_CAN_BE_DAMAGED,
VEHICLELOCK_LOCKED_BUT_BOOT_UNLOCKED,
VEHICLELOCK_LOCKED_NO_PASSENGERS,
VEHICLELOCK_CANNOT_ENTER
};
enum class eTaskTypeIndex
{
CTaskHandsUp = 0,
CTaskClimbLadder = 1,
CTaskExitVehicle = 2,
CTaskCombatRoll = 3,
CTaskAimGunOnFoot = 4,
CTaskMovePlayer = 5,
CTaskPlayerOnFoot = 6,
CTaskWeapon = 8,
CTaskPlayerWeapon = 9,
CTaskPlayerIdles = 10,
CTaskAimGun = 12,
CTaskComplex = 12,
CTaskFSMClone = 12,
CTaskMotionBase = 12,
CTaskMove = 12,
CTaskMoveBase = 12,
CTaskNMBehaviour = 12,
CTaskNavBase = 12,
CTaskScenario = 12,
CTaskSearchBase = 12,
CTaskSearchInVehicleBase = 12,
CTaskShockingEvent = 12,
CTaskTrainBase = 12,
CTaskVehicleFSM = 12,
CTaskVehicleGoTo = 12,
CTaskVehicleMissionBase = 12,
CTaskVehicleTempAction = 12,
CTaskPause = 14,
CTaskDoNothing = 15,
CTaskGetUp = 16,
CTaskGetUpAndStandStill = 17,
CTaskFallOver = 18,
CTaskFallAndGetUp = 19,
CTaskCrawl = 20,
CTaskComplexOnFire = 25,
CTaskDamageElectric = 26,
CTaskTriggerLookAt = 28,
CTaskClearLookAt = 29,
CTaskSetCharDecisionMaker = 30,
CTaskSetPedDefensiveArea = 31,
CTaskUseSequence = 32,
CTaskMoveStandStill = 34,
CTaskComplexControlMovement = 35,
CTaskMoveSequence = 36,
CTaskAmbientClips = 38,
CTaskMoveInAir = 39,
CTaskNetworkClone = 40,
CTaskUseClimbOnRoute = 41,
CTaskUseDropDownOnRoute = 42,
CTaskUseLadderOnRoute = 43,
CTaskSetBlockingOfNonTemporaryEvents = 44,
CTaskForceMotionState = 45,
CTaskSlopeScramble = 46,
CTaskGoToAndClimbLadder = 47,
CTaskClimbLadderFully = 48,
CTaskRappel = 49,
CTaskVault = 50,
CTaskDropDown = 51,
CTaskAffectSecondaryBehaviour = 52,
CTaskAmbientLookAtEvent = 53,
CTaskOpenDoor = 54,
CTaskShovePed = 55,
CTaskSwapWeapon = 56,
CTaskGeneralSweep = 57,
CTaskPolice = 58,
CTaskPoliceOrderResponse = 59,
CTaskPursueCriminal = 60,
CTaskArrestPed = 62,
CTaskArrestPed2 = 63,
CTaskBusted = 64,
CTaskFirePatrol = 65,
CTaskHeliOrderResponse = 66,
CTaskHeliPassengerRappel = 67,
CTaskAmbulancePatrol = 68,
CTaskPoliceWantedResponse = 69,
CTaskSwat = 70,
CTaskSwatWantedResponse = 72,
CTaskSwatOrderResponse = 73,
CTaskSwatGoToStagingArea = 74,
CTaskSwatFollowInLine = 75,
CTaskWitness = 76,
CTaskGangPatrol = 77,
CTaskArmy = 78,
CTaskShockingEventWatch = 80,
CTaskShockingEventGoto = 82,
CTaskShockingEventHurryAway = 83,
CTaskShockingEventReactToAircraft = 84,
CTaskShockingEventReact = 85,
CTaskShockingEventBackAway = 86,
CTaskShockingPoliceInvestigate = 87,
CTaskShockingEventStopAndStare = 88,
CTaskShockingNiceCarPicture = 89,
CTaskShockingEventThreatResponse = 90,
CTaskTakeOffHelmet = 92,
CTaskCarReactToVehicleCollision = 93,
CTaskCarReactToVehicleCollisionGetOut = 95,
CTaskDyingDead = 97,
CTaskWanderingScenario = 100,
CTaskWanderingInRadiusScenario = 101,
CTaskMoveBetweenPointsScenario = 103,
CTaskChatScenario = 104,
CTaskCowerScenario = 106,
CTaskDeadBodyScenario = 107,
CTaskSayAudio = 114,
CTaskWaitForSteppingOut = 116,
CTaskCoupleScenario = 117,
CTaskUseScenario = 118,
CTaskUseVehicleScenario = 119,
CTaskUnalerted = 120,
CTaskStealVehicle = 121,
CTaskReactToPursuit = 122,
CTaskHitWall = 125,
CTaskCower = 126,
CTaskCrouch = 127,
CTaskMelee = 128,
CTaskMoveMeleeMovement = 129,
CTaskMeleeActionResult = 130,
CTaskMeleeUpperbodyAnims = 131,
CTaskMoVEScripted = 133,
CTaskScriptedAnimation = 134,
CTaskSynchronizedScene = 135,
CTaskComplexEvasiveStep = 137,
CTaskWalkRoundCarWhileWandering = 138,
CTaskComplexStuckInAir = 140,
CTaskWalkRoundEntity = 141,
CTaskMoveWalkRoundVehicle = 142,
CTaskReactToGunAimedAt = 144,
CTaskDuckAndCover = 146,
CTaskAggressiveRubberneck = 147,
CTaskInVehicleBasic = 150,
CTaskCarDriveWander = 151,
CTaskLeaveAnyCar = 152,
CTaskComplexGetOffBoat = 153,
CTaskCarSetTempAction = 155,
CTaskBringVehicleToHalt = 156,
CTaskCarDrive = 157,
CTaskPlayerDrive = 159,
CTaskEnterVehicle = 160,
CTaskEnterVehicleAlign = 161,
CTaskOpenVehicleDoorFromOutside = 162,
CTaskEnterVehicleSeat = 163,
CTaskCloseVehicleDoorFromInside = 164,
CTaskInVehicleSeatShuffle = 165,
CTaskExitVehicleSeat = 167,
CTaskCloseVehicleDoorFromOutside = 168,
CTaskControlVehicle = 169,
CTaskMotionInAutomobile = 170,
CTaskMotionOnBicycle = 171,
CTaskMotionOnBicycleController = 172,
CTaskMotionInVehicle = 173,
CTaskMotionInTurret = 174,
CTaskReactToBeingJacked = 175,
CTaskReactToBeingAskedToLeaveVehicle = 176,
CTaskTryToGrabVehicleDoor = 177,
CTaskGetOnTrain = 178,
CTaskGetOffTrain = 179,
CTaskRideTrain = 180,
CTaskMountThrowProjectile = 190,
CTaskGoToCarDoorAndStandStill = 195,
CTaskMoveGoToVehicleDoor = 196,
CTaskSetPedInVehicle = 197,
CTaskSetPedOutOfVehicle = 198,
CTaskVehicleMountedWeapon = 199,
CTaskVehicleGun = 200,
CTaskVehicleProjectile = 201,
CTaskSmashCarWindow = 204,
CTaskMoveGoToPoint = 205,
CTaskMoveAchieveHeading = 206,
CTaskMoveFaceTarget = 207,
CTaskComplexGoToPointAndStandStillTimed = 208,
CTaskMoveGoToPointAndStandStill = 208,
CTaskMoveFollowPointRoute = 209,
CTaskMoveSeekEntity_CEntitySeekPosCalculatorStandard = 210,
CTaskMoveSeekEntity_CEntitySeekPosCalculatorLastNavMeshIntersection = 211,
CTaskMoveSeekEntity_CEntitySeekPosCalculatorLastNavMeshIntersection2 = 212,
CTaskMoveSeekEntity_CEntitySeekPosCalculatorXYOffsetFixed = 213,
CTaskMoveSeekEntity_CEntitySeekPosCalculatorXYOffsetFixed2 = 214,
CTaskExhaustedFlee = 215,
CTaskGrowlAndFlee = 216,
CTaskScenarioFlee = 217,
CTaskSmartFlee = 218,
CTaskFlyAway = 219,
CTaskWalkAway = 220,
CTaskWander = 221,
CTaskWanderInArea = 222,
CTaskFollowLeaderInFormation = 223,
CTaskGoToPointAnyMeans = 224,
CTaskTurnToFaceEntityOrCoord = 225,
CTaskFollowLeaderAnyMeans = 226,
CTaskFlyToPoint = 228,
CTaskFlyingWander = 229,
CTaskGoToPointAiming = 230,
CTaskGoToScenario = 231,
CTaskSeekEntityAiming = 233,
CTaskSlideToCoord = 234,
CTaskSwimmingWander = 235,
CTaskMoveTrackingEntity = 237,
CTaskMoveFollowNavMesh = 238,
CTaskMoveGoToPointOnRoute = 239,
CTaskEscapeBlast = 240,
CTaskMoveWander = 241,
CTaskMoveBeInFormation = 242,
CTaskMoveCrowdAroundLocation = 243,
CTaskMoveCrossRoadAtTrafficLights = 244,
CTaskMoveWaitForTraffic = 245,
CTaskMoveGoToPointStandStillAchieveHeading = 246,
CTaskMoveGetOntoMainNavMesh = 251,
CTaskMoveSlideToCoord = 252,
CTaskMoveGoToPointRelativeToEntityAndStandStill = 253,
CTaskHelicopterStrafe = 254,
CTaskGetOutOfWater = 256,
CTaskMoveFollowEntityOffset = 259,
CTaskFollowWaypointRecording = 261,
CTaskMotionPed = 264,
CTaskMotionPedLowLod = 265,
CTaskHumanLocomotion = 268,
CTaskMotionBasicLocomotionLowLod = 269,
CTaskMotionStrafing = 270,
CTaskMotionTennis = 271,
CTaskMotionAiming = 272,
CTaskBirdLocomotion = 273,
CTaskFlightlessBirdLocomotion = 274,
CTaskFishLocomotion = 278,
CTaskQuadLocomotion = 279,
CTaskMotionDiving = 280,
CTaskMotionSwimming = 281,
CTaskMotionParachuting = 282,
CTaskMotionDrunk = 283,
CTaskRepositionMove = 284,
CTaskMotionAimingTransition = 285,
CTaskThrowProjectile = 286,
CTaskCover = 287,
CTaskMotionInCover = 288,
CTaskAimAndThrowProjectile = 289,
CTaskGun = 290,
CTaskAimFromGround = 291,
CTaskAimGunVehicleDriveBy = 295,
CTaskAimGunScripted = 296,
CTaskReloadGun = 298,
CTaskWeaponBlocked = 299,
CTaskEnterCover = 300,
CTaskExitCover = 301,
CTaskAimGunFromCoverIntro = 302,
CTaskAimGunFromCoverOutro = 303,
CTaskAimGunBlindFire = 304,
CTaskCombatClosestTargetInArea = 307,
CTaskCombatAdditionalTask = 308,
CTaskInCover = 309,
CTaskAimSweep = 313,
CTaskSharkCircle = 319,
CTaskSharkAttack = 320,
CTaskAgitated = 321,
CTaskAgitatedAction = 322,
CTaskConfront = 323,
CTaskIntimidate = 324,
CTaskShove = 325,
CTaskShoved = 326,
CTaskCrouchToggle = 328,
CTaskRevive = 329,
CTaskParachute = 335,
CTaskParachuteObject = 336,
CTaskTakeOffPedVariation = 337,
CTaskCombatSeekCover = 340,
CTaskCombatFlank = 342,
CTaskCombat = 343,
CTaskCombatMounted = 344,
CTaskMoveCircle = 345,
CTaskMoveCombatMounted = 346,
CTaskSearch = 347,
CTaskSearchOnFoot = 348,
CTaskSearchInAutomobile = 349,
CTaskSearchInBoat = 350,
CTaskSearchInHeli = 351,
CTaskThreatResponse = 352,
CTaskInvestigate = 353,
CTaskStandGuardFSM = 354,
CTaskPatrol = 355,
CTaskShootAtTarget = 356,
CTaskSetAndGuardArea = 357,
CTaskStandGuard = 358,
CTaskSeparate = 359,
CTaskStayInCover = 360,
CTaskVehicleCombat = 361,
CTaskVehiclePersuit = 362,
CTaskVehicleChase = 363,
CTaskDraggingToSafety = 364,
CTaskDraggedToSafety = 365,
CTaskVariedAimPose = 366,
CTaskMoveWithinAttackWindow = 367,
CTaskMoveWithinDefensiveArea = 368,
CTaskShootOutTire = 369,
CTaskShellShocked = 370,
CTaskBoatChase = 371,
CTaskBoatCombat = 372,
CTaskBoatStrafe = 373,
CTaskHeliChase = 374,
CTaskHeliCombat = 375,
CTaskSubmarineCombat = 376,
CTaskSubmarineChase = 377,
CTaskPlaneChase = 378,
CTaskTargetUnreachable = 379,
CTaskTargetUnreachableInInterior = 380,
CTaskTargetUnreachableInExterior = 381,
CTaskStealthKill = 382,
CTaskWrithe = 383,
CTaskAdvance = 384,
CTaskCharge = 385,
CTaskMoveToTacticalPoint = 386,
CTaskToHurtTransit = 387,
CTaskAnimatedHitByExplosion = 388,
CTaskNMRelax = 389,
CTaskNMPose = 391,
CTaskNMBrace = 392,
CTaskNMBuoyancy = 393,
CTaskNMInjuredOnGround = 394,
CTaskNMShot = 395,
CTaskNMHighFall = 396,
CTaskNMBalance = 397,
CTaskNMElectrocute = 398,
CTaskNMPrototype = 399,
CTaskNMExplosion = 400,
CTaskNMOnFire = 401,
CTaskNMScriptControl = 402,
CTaskNMJumpRollFromRoadVehicle = 403,
CTaskNMFlinch = 404,
CTaskNMSit = 405,
CTaskNMFallDown = 406,
CTaskBlendFromNM = 407,
CTaskNMControl = 408,
CTaskNMDangle = 409,
CTaskNMGenericAttach = 412,
CTaskNMDraggingToSafety = 414,
CTaskNMThroughWindscreen = 415,
CTaskNMRiverRapids = 416,
CTaskNMSimple = 417,
CTaskRageRagdoll = 418,
CTaskJumpVault = 421,
CTaskJump = 422,
CTaskFall = 423,
CTaskReactAimWeapon = 425,
CTaskChat = 426,
CTaskMobilePhone = 427,
CTaskReactToDeadPed = 428,
CTaskSearchForUnknownThreat = 430,
CTaskBomb = 432,
CTaskDetonator = 433,
CTaskAnimatedAttach = 435,
CTaskCutScene = 441,
CTaskReactToExplosion = 442,
CTaskReactToImminentExplosion = 443,
CTaskDiveToGround = 444,
CTaskReactAndFlee = 445,
CTaskSidestep = 446,
CTaskCallPolice = 447,
CTaskReactInDirection = 448,
CTaskReactToBuddyShot = 449,
CTaskVehicleGoToAutomobileNew = 454,
CTaskVehicleGoToPlane = 455,
CTaskVehicleGoToHelicopter = 456,
CTaskVehicleGoToSubmarine = 457,
CTaskVehicleGoToBoat = 458,
CTaskVehicleGoToPointAutomobile = 459,
CTaskVehicleGoToPointWithAvoidanceAutomobile = 460,
CTaskVehiclePursue = 461,
CTaskVehicleRam = 462,
CTaskVehicleSpinOut = 463,
CTaskVehicleApproach = 464,
CTaskVehicleThreePointTurn = 465,
CTaskVehicleDeadDriver = 466,
CTaskVehicleCruiseNew = 467,
CTaskVehicleCruiseBoat = 468,
CTaskVehicleStop = 469,
CTaskVehiclePullOver = 470,
CTaskVehiclePassengerExit = 471,
CTaskVehicleFlee = 472,
CTaskVehicleFleeAirborne = 473,
CTaskVehicleFleeBoat = 474,
CTaskVehicleFollowRecording = 475,
CTaskVehicleFollow = 476,
CTaskVehicleBlock = 477,
CTaskVehicleBlockCruiseInFront = 478,
CTaskVehicleBlockBrakeInFront = 479,
CTaskVehicleBlockBackAndForth = 478,
CTaskVehicleCrash = 481,
CTaskVehicleLand = 482,
CTaskVehicleLandPlane = 483,
CTaskVehicleHover = 484,
CTaskVehicleAttack = 485,
CTaskVehicleAttackTank = 486,
CTaskVehicleCircle = 487,
CTaskVehiclePoliceBehaviour = 488,
CTaskVehiclePoliceBehaviourHelicopter = 489,
CTaskVehiclePoliceBehaviourBoat = 490,
CTaskVehicleEscort = 491,
CTaskVehicleHeliProtect = 492,
CTaskVehiclePlayerDriveAutomobile = 494,
CTaskVehiclePlayerDriveBike = 495,
CTaskVehiclePlayerDriveBoat = 496,
CTaskVehiclePlayerDriveSubmarine = 497,
CTaskVehiclePlayerDriveSubmarineCar = 498,
CTaskVehiclePlayerDriveAmphibiousAutomobile = 499,
CTaskVehiclePlayerDrivePlane = 500,
CTaskVehiclePlayerDriveHeli = 501,
CTaskVehiclePlayerDriveAutogyro = 502,
CTaskVehiclePlayerDriveDiggerArm = 503,
CTaskVehiclePlayerDriveTrain = 504,
CTaskVehiclePlaneChase = 505,
CTaskVehicleNoDriver = 506,
CTaskVehicleAnimation = 507,
CTaskVehicleConvertibleRoof = 508,
CTaskVehicleParkNew = 509,
CTaskVehicleFollowWaypointRecording = 510,
CTaskVehicleGoToNavmesh = 511,
CTaskVehicleReactToCopSiren = 512,
CTaskVehicleGotoLongRange = 513,
CTaskVehicleWait = 514,
CTaskVehicleReverse = 515,
CTaskVehicleBrake = 516,
CTaskVehicleHandBrake = 517,
CTaskVehicleTurn = 518,
CTaskVehicleGoForward = 519,
CTaskVehicleSwerve = 520,
CTaskVehicleFlyDirection = 521,
CTaskVehicleHeadonCollision = 522,
CTaskVehicleBoostUseSteeringAngle = 523,
CTaskVehicleShotTire = 524,
CTaskVehicleBurnout = 525,
CTaskVehicleRevEngine = 526,
CTaskVehicleSurfaceInSubmarine = 527,
CTaskVehiclePullAlongside = 528,
CTaskVehicleTransformToSubmarine = 529,
CTaskAnimatedFallback = 530
};
enum class eDoorId
{
VEH_EXT_DOOR_INVALID_ID = -1,
VEH_EXT_DOOR_DSIDE_F,
VEH_EXT_DOOR_DSIDE_R,
VEH_EXT_DOOR_PSIDE_F,
VEH_EXT_DOOR_PSIDE_R,
VEH_EXT_BONNET,
VEH_EXT_BOOT
};
enum class eVehicleSeats
{
DRIVER = -1,
PASSENGER,
LEFT_BACK,
RIGHT_BACK,
OUTSIDE_LEFT,
OUTSIDE_RIGHT,
};

View File

@ -12,7 +12,8 @@
namespace big
{
gui::gui() :
m_is_open(false)
m_is_open(false),
m_override_mouse(false)
{
g_renderer->add_dx_callback(view::gta_data, -1);
g_renderer->add_dx_callback(view::notifications, -2);
@ -28,9 +29,11 @@ namespace big
wndproc(hwnd, msg, wparam, lparam);
});
g_renderer->add_dx_callback(view::vehicle_control, 3);
g_renderer->add_dx_callback(esp::draw, 2); // TODO: move to ESP service
g_renderer->add_dx_callback(view::context_menu, 1);
dx_init();
g_gui = this;
@ -54,6 +57,13 @@ namespace big
toggle_mouse();
}
void gui::override_mouse(bool override)
{
m_override_mouse = override;
toggle_mouse();
}
void gui::dx_init()
{
static auto bgColor = ImVec4(0.09f, 0.094f, 0.129f, .9f);
@ -133,7 +143,7 @@ namespace big
void gui::script_on_tick()
{
if (g_gui->m_is_open)
if (g_gui->m_is_open || g_gui->m_override_mouse)
{
for (uint8_t i = 0; i <= 6; i++)
PAD::DISABLE_CONTROL_ACTION(2, i, true);
@ -212,7 +222,7 @@ namespace big
void gui::toggle_mouse()
{
if (m_is_open)
if (m_is_open || g_gui->m_override_mouse)
{
ImGui::GetIO().MouseDrawCursor = true;
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouse;

View File

@ -1,38 +1,48 @@
#pragma once
#include "common.hpp"
namespace big
{
class gui
{
public:
gui();
virtual ~gui();
gui(const gui&) = delete;
gui(gui&&) noexcept = delete;
gui& operator=(const gui&) = delete;
gui& operator=(gui&&) noexcept = delete;
bool is_open();
void toggle(bool toggle);
void dx_init();
void dx_on_tick();
void restore_default_style();
void script_on_tick();
static void script_func();
void wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
private:
void toggle_mouse();
private:
bool m_is_open;
ImGuiStyle m_default_config;
};
inline gui* g_gui;
}
#pragma once
#include "common.hpp"
namespace big
{
class gui
{
public:
gui();
virtual ~gui();
gui(const gui&) = delete;
gui(gui&&) noexcept = delete;
gui& operator=(const gui&) = delete;
gui& operator=(gui&&) noexcept = delete;
bool is_open();
void toggle(bool toggle);
bool mouse_override() const
{ return m_override_mouse; }
/**
* @brief Forces the mouse to draw and disable camera controls of the game
* This function works for now but might start causing issues when more features start relying on it.
*/
void override_mouse(bool override);
void dx_init();
void dx_on_tick();
void restore_default_style();
void script_on_tick();
static void script_func();
void wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
private:
void toggle_mouse();
private:
bool m_is_open;
bool m_override_mouse;
ImGuiStyle m_default_config;
};
inline gui* g_gui;
}

View File

@ -11,6 +11,8 @@
#include "script_mgr.hpp"
#include "services/api/api_service.hpp"
#include "services/context_menu/context_menu_service.hpp"
#include "services/orbital_drone/orbital_drone.hpp"
#include "services/vehicle/vehicle_control_service.hpp"
#include "services/custom_text/custom_text_service.hpp"
#include "services/globals/globals_service.hpp"
#include "services/gta_data/gta_data_service.hpp"
@ -115,6 +117,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
g_script_mgr.add_script(std::make_unique<script>(&backend::disable_control_action_loop, "Disable Controls"));
g_script_mgr.add_script(std::make_unique<script>(&backend::world_loop, "World"));
g_script_mgr.add_script(std::make_unique<script>(&backend::orbital_drone, "Orbital Drone"));
g_script_mgr.add_script(std::make_unique<script>(&backend::vehicle_control, "Vehicle control"));
g_script_mgr.add_script(std::make_unique<script>(&context_menu_service::context_menu, "Context Menu"));
LOG(INFO) << "Scripts registered.";

View File

@ -1,10 +1,23 @@
#pragma once
#include "script_function.hpp"
#include "services/vehicle/vehicle_control_service.hpp"
namespace big
{
namespace freemode
{
void STAT_GET_INT(rage::scrNativeCallContext* src)
{
if (g_vehicle_control_service.m_driver_performing_task && (src->get_arg<Hash>(0) == RAGE_JOAAT("MP0_PERSONAL_VEHICLE_ACCESS") ||
src->get_arg<Hash>(0) == RAGE_JOAAT("MP1_PERSONAL_VEHICLE_ACCESS")))
{
src->set_return_value<int>(0);
return;
}
src->set_return_value(STATS::STAT_GET_INT(src->get_arg<Hash>(0), src->get_arg<int*>(1), src->get_arg<int>(2)));
}
inline void NETWORK_BAIL(rage::scrNativeCallContext* src)
{
LOG(INFO) << "NETWORK_BAIL prevented";

View File

@ -112,15 +112,15 @@ namespace big
add_native_detour(0xFE99B66D079CF6BC, all_scripts::DISABLE_CONTROL_ACTION);
add_native_detour(0xEB354E5376BC81A7, all_scripts::HUD_FORCE_WEAPON_WHEEL);
add_native_detour(0x158C16F5E4CF41F8, all_scripts::RETURN_TRUE); //bypass casino country restrictions
add_native_detour(RAGE_JOAAT("shop_controller"), 0x34616828CD07F1A1, all_scripts::RETURN_FALSE); // prevent exploit reports
add_native_detour(RAGE_JOAAT("shop_controller"), 0x34616828CD07F1A1, all_scripts::RETURN_FALSE); // prevent exploit reports
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x06843DA7060A026B, carmod_shop::SET_ENTITY_COORDS);
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x8E2530AA8ADA980E, carmod_shop::SET_ENTITY_HEADING);
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x34E710FF01247C5A, carmod_shop::SET_VEHICLE_LIGHTS);
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x767FBC2AC802EF3D, carmod_shop::STAT_GET_INT);
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x5F4B6931816E599B, carmod_shop::DISABLE_ALL_CONTROL_ACTIONS);
add_native_detour(RAGE_JOAAT("freemode"), 0x767FBC2AC802EF3D, freemode::STAT_GET_INT);
add_native_detour(RAGE_JOAAT("freemode"), 0x95914459A87EBA28, freemode::NETWORK_BAIL);
add_native_detour(RAGE_JOAAT("freemode"), 0x5E9564D8246B909A, freemode::IS_PLAYER_PLAYING);
add_native_detour(RAGE_JOAAT("freemode"), 0xEA1C610A04DB6BBB, freemode::SET_ENTITY_VISIBLE);

View File

@ -27,6 +27,7 @@ namespace big
register_hotkey("fillammo", g.settings.hotkeys.fill_ammo, RAGE_JOAAT("fillammo"));
register_hotkey("quicksearch", g.settings.hotkeys.cmd_excecutor, RAGE_JOAAT("cmdexecutor"));
register_hotkey("repairpv", g.settings.hotkeys.repairpv, RAGE_JOAAT("repairpv"));
register_hotkey("vehiclecontroller", g.settings.hotkeys.open_vehicle_controller, RAGE_JOAAT("vehiclecontrol"));
g_renderer->add_wndproc_callback([this](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
wndproc(static_cast<eKeyState>(msg), wparam);

View File

@ -0,0 +1,403 @@
#include "vehicle_control_service.hpp"
#include "backend/looped_command.hpp"
#include "gui.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/pathfind.hpp"
#include "util/ped.hpp"
#include "util/vehicle.hpp"
namespace big
{
class vehicle_control_command : looped_command
{
using looped_command::looped_command;
virtual void on_enable() override
{
g_gui->override_mouse(true);
}
virtual void on_tick() override
{
if (!g_gui->mouse_override())
{
g_gui->override_mouse(true);
}
}
virtual void on_disable() override
{
g_gui->override_mouse(false);
}
};
vehicle_control_command g_vehicle_control("vehiclecontrol", "Vehicle controller", "Enables/Disables the vehicle controller.",
g.window.vehicle_control.opened);
void update_controlled_vehicle_doors(controlled_vehicle& veh)
{
vehicle_door veh_door{};
for (int i = 0; i < MAX_VEHICLE_DOORS; i++)
{
if (!VEHICLE::GET_IS_DOOR_VALID(veh.handle, i))
{
veh.doors[i].valid = false;
continue;
}
veh_door.valid = true;
veh_door.id = (eDoorId)i;
veh_door.lockstate = (eVehicleLockState)VEHICLE::GET_VEHICLE_INDIVIDUAL_DOOR_LOCK_STATUS(veh.handle, i);
veh_door.open = VEHICLE::GET_VEHICLE_DOOR_ANGLE_RATIO(veh.handle, i) > 0;
veh_door.doorAngle = VEHICLE::GET_VEHICLE_DOOR_ANGLE_RATIO(veh.handle, i);
veh.doors[i] = veh_door;
}
veh.lockstate = (eVehicleLockState)VEHICLE::GET_VEHICLE_DOOR_LOCK_STATUS(veh.handle);
}
void update_controlled_vehicle_lights(controlled_vehicle& veh)
{
VEHICLE::GET_VEHICLE_LIGHTS_STATE(veh.handle, &veh.headlights, &veh.highbeams);
for (int i = 0; i < 4; i++)
veh.neons[i] = VEHICLE::GET_VEHICLE_NEON_ENABLED(veh.handle, i);
}
controlled_vehicle vehicle_control::update_vehicle(Vehicle veh)
{
controlled_vehicle new_veh{};
new_veh.handle = veh;
new_veh.ptr = (CVehicle*)g_pointers->m_handle_to_ptr(veh);
strcpy(new_veh.model_name, HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(VEHICLE::GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(ENTITY::GET_ENTITY_MODEL(veh))));
new_veh.doorCount = VEHICLE::GET_NUMBER_OF_VEHICLE_DOORS(veh);
new_veh.lockstate = (eVehicleLockState)VEHICLE::GET_VEHICLE_DOOR_LOCK_STATUS(veh);
new_veh.isconvertible = VEHICLE::IS_VEHICLE_A_CONVERTIBLE(veh, 0);
update_controlled_vehicle_doors(new_veh);
update_controlled_vehicle_lights(new_veh);
return new_veh;
}
void vehicle_control::keep_controlled_vehicle_data_updated(controlled_vehicle& veh)
{
if (!m_controlled_vehicle_exists)
return;
update_controlled_vehicle_doors(veh);
update_controlled_vehicle_lights(veh);
veh.convertibelstate = VEHICLE::GET_CONVERTIBLE_ROOF_STATE(veh.handle);
veh.engine = VEHICLE::GET_IS_VEHICLE_ENGINE_RUNNING(veh.handle);
veh.radio = AUDIO::IS_VEHICLE_RADIO_ON(veh.handle);
veh.radiochannel = AUDIO::GET_PLAYER_RADIO_STATION_INDEX();
if (g.window.vehicle_control.render_distance_on_veh
&& math::distance_between_vectors(self::pos, ENTITY::GET_ENTITY_COORDS(m_controlled_vehicle.handle, true)) > 10.f)
vehicle_control::render_distance_on_vehicle();
}
/*
* Imitated from freemode.c script, findable by searching for MISC::GET_HASH_KEY("BONEMASK_HEAD_NECK_AND_R_ARM");
* Script uses TASK::TASK_SCRIPTED_ANIMATION but can be dissected to use as follows
*/
void vehicle_control::animated_vehicle_operation(Ped ped)
{
ped::ped_play_animation(ped, VEH_OP_ANIM_DICT, VEH_OP_ANIM, 4, -4, -1, 48, 0, false);
AUDIO::PLAY_SOUND_FROM_ENTITY(-1, "Remote_Control_Fob", self::ped, "PI_Menu_Sounds", true, 0);
script::get_current()->yield(100ms);
for (int i = 0; i < 35 && ENTITY::IS_ENTITY_PLAYING_ANIM(self::ped, VEH_OP_ANIM_DICT, VEH_OP_ANIM, 3); i++)
{
script::get_current()->yield(10ms);
}
}
void vehicle_control::operate_door(eDoorId door, bool open)
{
if (g.window.vehicle_control.operation_animation)
animated_vehicle_operation(self::ped);
vehicle::operate_vehicle_door(m_controlled_vehicle.handle, door, open);
}
void vehicle_control::operate_lights(bool headlights, bool highbeams)
{
if (g.window.vehicle_control.operation_animation)
animated_vehicle_operation(self::ped);
vehicle::operate_vehicle_headlights(m_controlled_vehicle.handle, headlights, highbeams);
}
void vehicle_control::operate_neons(int index, bool toggle)
{
if (g.window.vehicle_control.operation_animation)
animated_vehicle_operation(self::ped);
vehicle::operate_vehicle_neons(m_controlled_vehicle.handle, index, toggle);
}
void vehicle_control::driver_tick()
{
if (!m_controlled_vehicle_exists)
return;
if (ENTITY::DOES_ENTITY_EXIST(m_driver))
{
int task = 0;
for (int i = 0; i < ped::task_names.size(); i++)
{
if (TASK::GET_IS_TASK_ACTIVE(m_driver, i))
task = i;
}
strcpy(m_currentask, ped::task_names.at(task));
if (!m_driver_performing_task)
{
if (entity::take_control_of(m_driver))
{
pathfind::remove_navmesh_required_areas();
entity::delete_entity(m_driver);
}
}
else
{
if (math::distance_between_vectors(m_destination, ENTITY::GET_ENTITY_COORDS(m_driver, true)) < 10.f || math::distance_between_vectors(self::pos, ENTITY::GET_ENTITY_COORDS(m_driver, true)) < 10.f)
{
m_driver_performing_task = false;
VEHICLE::BRING_VEHICLE_TO_HALT(m_controlled_vehicle.handle, 6.f, 5, false);
pathfind::remove_navmesh_required_areas();
}
if (strcmp(m_currentask, "CTaskInVehicleBasic") == 0)
{
TASK::TASK_VEHICLE_DRIVE_TO_COORD(m_driver,
m_controlled_vehicle.handle,
m_destination.x,
m_destination.y,
m_destination.z,
100.f,
0,
0,
786468,
4.f,
5.f);
//LOG(INFO) << "Navmesh probably failed, issiuing regular task ";
g_notification_service->push_warning("Vehicle controller", "Your vehicle could not assess an accurate path, it will try something else");
script::get_current()->yield(500ms);
}
m_distance_to_destination =
math::distance_between_vectors(m_destination, ENTITY::GET_ENTITY_COORDS(m_controlled_vehicle.handle, true));
}
}
}
bool vehicle_control::ensure_driver()
{
if (!m_controlled_vehicle_exists)
{
if (ENTITY::DOES_ENTITY_EXIST(m_driver) && entity::take_control_of(m_driver))
{
entity::delete_entity(m_driver);
}
return false;
}
if (!ENTITY::DOES_ENTITY_EXIST(m_driver))
{
//LOG(INFO) << "Driver didnt exist, creating one";
m_driver = ped::spawn(PED_TYPE_CIVMALE,
RAGE_JOAAT("s_m_y_devinsec_01"),
-1,
ENTITY::GET_ENTITY_COORDS(m_controlled_vehicle.handle, 1),
0,
true);
}
if (entity::take_control_of(m_driver))
{
if (VEHICLE::GET_PED_IN_VEHICLE_SEAT(m_controlled_vehicle.handle, (int)eVehicleSeats::DRIVER, true) != m_driver)
{
//LOG(INFO) << "Driver wasnt in the driver seat";
PED::SET_PED_INTO_VEHICLE(m_driver, m_controlled_vehicle.handle, (int)eVehicleSeats::DRIVER);
}
//LOG(INFO) << "Changing driver attributes";
ENTITY::SET_ENTITY_INVINCIBLE(m_driver, true);
ENTITY::SET_ENTITY_VISIBLE(m_driver, false, false);
PED::SET_PED_COMBAT_ATTRIBUTES(m_driver, 3, false);
PED::SET_PED_COMBAT_ATTRIBUTES(m_driver, 1, true);
PED::SET_PED_COMBAT_ATTRIBUTES(m_driver, 58, true);
PED::SET_PED_CONFIG_FLAG(m_driver, 294, true);
PED::SET_PED_CONFIG_FLAG(m_driver, 208, true);
PED::SET_PED_CONFIG_FLAG(m_driver, 229, true);
PED::SET_PED_CONFIG_FLAG(m_driver, 422, true);
PED::SET_PED_CONFIG_FLAG(m_driver, 123, true);
PED::SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(m_driver, true);
PED::SET_PED_CAN_BE_DRAGGED_OUT(m_driver, false);
PED::SET_PED_CAN_BE_SHOT_IN_VEHICLE(m_driver, false);
PED::SET_DRIVER_ABILITY(m_driver, 1);
PED::SET_DRIVER_RACING_MODIFIER(m_driver, 1);
PED::CLEAR_RELATIONSHIP_BETWEEN_GROUPS(0, PED::GET_PED_RELATIONSHIP_GROUP_HASH(m_driver), PED::GET_PED_RELATIONSHIP_GROUP_HASH(self::ped));
PED::SET_RELATIONSHIP_BETWEEN_GROUPS(0, PED::GET_PED_GROUP_INDEX(m_driver), PED::GET_PED_GROUP_INDEX(self::ped));
PED::SET_RELATIONSHIP_BETWEEN_GROUPS(0, PED::GET_PED_GROUP_INDEX(self::ped), PED::GET_PED_GROUP_INDEX(m_driver));
PED::SET_PED_AS_GROUP_MEMBER(m_driver, PED::GET_PED_GROUP_INDEX(self::ped));
}
return ENTITY::DOES_ENTITY_EXIST(m_driver);
}
void vehicle_control::render_distance_on_vehicle()
{
if (ENTITY::DOES_ENTITY_EXIST(m_controlled_vehicle.handle))
{
Vector3 veh_pos = ENTITY::GET_ENTITY_COORDS(m_controlled_vehicle.handle, true);
Vector2 screen_pos{};
GRAPHICS::GET_SCREEN_COORD_FROM_WORLD_COORD(veh_pos.x, veh_pos.y, veh_pos.z, &screen_pos.x, &screen_pos.y);
HUD::BEGIN_TEXT_COMMAND_DISPLAY_TEXT("STRING");
HUD::SET_TEXT_FONT(4);
HUD::SET_TEXT_SCALE(0.3f, 0.463);
HUD::SET_TEXT_COLOUR(0, 150, 0, 255);
HUD::ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(
std::to_string(math::distance_between_vectors(self::pos, veh_pos)).data());
HUD::END_TEXT_COMMAND_DISPLAY_TEXT(screen_pos.x, screen_pos.y, 0);
}
}
bool vehicle_control::find_suitable_destination_near_player(Vector3& outcoords, float& heading)
{
Vector3 original_coords = outcoords;
float original_heading = heading;
pathfind::find_closest_vehicle_node(self::pos, outcoords, heading, 0);
for (int i = 0; i < 10 && math::distance_between_vectors(self::pos, outcoords) < 3.f; i++)
{
pathfind::find_closest_vehicle_node(self::pos, outcoords, heading, 0, i);
//LOG(INFO) << "Node too close to player, iterating next closest";
}
//LOG(INFO) << "Searched for closest vehicle node";
if (math::distance_between_vectors(self::pos, outcoords) > 7.f)
{
//LOG(INFO) << "Node was too far, trying to find safe ped pos";
if (!pathfind::find_safe_pos_ped(self::pos, outcoords, true, 8) || math::distance_between_vectors(self::pos, outcoords) > 30.f)
{
//LOG(INFO) << "Couldnt find a safe ped pos";
outcoords = original_coords;
heading = original_heading;
return false;
}
}
return true;
}
void vehicle_control::summon_vehicle()
{
if (!m_controlled_vehicle_exists
|| math::distance_between_vectors(self::pos, ENTITY::GET_ENTITY_COORDS(m_controlled_vehicle.handle, true)) < 13.f)
return;
Vector3 behind_pos = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(self::ped, 0.f, -4.f, 0.f);
if (ensure_driver() && ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY_IN_FRONT(self::ped, m_driver))
{
behind_pos = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(self::ped, 0.f, 4.f, 0.f);
}
if (math::distance_between_vectors(self::pos, ENTITY::GET_ENTITY_COORDS(m_controlled_vehicle.handle, true))
> g.window.vehicle_control.max_summon_range)
{
//LOG(INFO) << "Vehicle is too far, teleporting";
m_destination = behind_pos;
ENTITY::SET_ENTITY_COORDS(m_controlled_vehicle.handle, behind_pos.x, behind_pos.y, behind_pos.z, 0, 0, 0, false);
return;
}
m_driver_performing_task = true;
if (ensure_driver())
{
Vector3 destination{};
float heading{};
if (vehicle_control::find_suitable_destination_near_player(destination, heading))
{
//LOG(INFO) << "Suitable destination found";
g_notification_service->push_warning("Vehicle controller", "Found a nice spot, your vehicle is on its way");
}
else
{
//LOG(INFO) << "Couldn't find suitable destionation, defaulting to offset of player\nThis might go wrong";
g_notification_service->push_warning("Vehicle controller", "Couldn't locate an accurate spot, your vehicle is on its way regardless");
destination = behind_pos;
}
m_destination = destination;
Vector3 nav_mesh_region = ENTITY::GET_ENTITY_COORDS(m_driver, true);
if (pathfind::load_navmesh_area(nav_mesh_region, m_distance_to_destination))
{
TASK::TASK_VEHICLE_GOTO_NAVMESH(m_driver,
m_controlled_vehicle.handle,
destination.x,
destination.y,
destination.z,
100.f,
786468,
4.f);
PED::SET_PED_KEEP_TASK(m_driver, true);
}
else
{
//LOG(INFO) << "Navmesh load failed";
g_notification_service->push_error("Nav mesh", "Failed loading the navmesh");
m_driver_performing_task = false;
}
}
}
void vehicle_control::tick()
{
if (!*g_pointers->m_is_session_started)
return;
m_controlled_vehicle_exists = m_controlled_vehicle.ptr && ENTITY::DOES_ENTITY_EXIST(m_controlled_vehicle.handle)
&& VEHICLE::IS_THIS_MODEL_A_CAR(ENTITY::GET_ENTITY_MODEL(m_controlled_vehicle.handle));
driver_tick();
//Check in memory for vehicle
if (g_local_player)
{
if (g_local_player->m_vehicle)
{
if (m_controlled_vehicle.handle != g_pointers->m_ptr_to_handle(g_local_player->m_vehicle))
m_controlled_vehicle = vehicle_control::update_vehicle(self::veh);
}
}
//Manually check if vehicle has changed
if (ENTITY::DOES_ENTITY_EXIST(self::veh) && self::veh != m_controlled_vehicle.handle)
{
m_controlled_vehicle = vehicle_control::update_vehicle(self::veh);
}
if (!g.window.vehicle_control.opened)
return;
//Manual check if there is a last driven vehicle
if (!m_controlled_vehicle_exists && ENTITY::DOES_ENTITY_EXIST(VEHICLE::GET_LAST_DRIVEN_VEHICLE()))
m_controlled_vehicle = vehicle_control::update_vehicle(VEHICLE::GET_LAST_DRIVEN_VEHICLE());
keep_controlled_vehicle_data_updated(m_controlled_vehicle);
}
}

View File

@ -0,0 +1,73 @@
#pragma once
#include "gta/enums.hpp"
namespace big
{
constexpr auto MAX_VEHICLE_DOORS = 6;
constexpr auto MAX_VEHICLE_LOCK_STATES = 11;
constexpr auto VEH_OP_ANIM_DICT = "ANIM@MP_PLAYER_INTMENU@KEY_FOB@";
constexpr auto VEH_OP_ANIM = "FOB_CLICK";
struct vehicle_door
{
eDoorId id;
eVehicleLockState lockstate;
bool open;
float doorAngle;
bool valid;
};
struct controlled_vehicle
{
Vehicle handle;
CVehicle* ptr;
char model_name[100];
vehicle_door doors[6];
int doorCount;
eVehicleLockState lockstate;
bool engine;
bool neons[4];
bool isconvertible;
bool radio;
int radiochannel;
int convertibelstate;
int headlights,
highbeams;
};
class vehicle_control
{
private:
controlled_vehicle update_vehicle(Vehicle veh);
void keep_controlled_vehicle_data_updated(controlled_vehicle& veh);
//Autonomy
void driver_tick();
bool ensure_driver();
void render_distance_on_vehicle();
bool find_suitable_destination_near_player(Vector3& outcoords, float& heading);
Vector3 m_destination;
Ped m_driver;
public:
controlled_vehicle m_controlled_vehicle;
bool m_controlled_vehicle_exists;
//Autonomy
bool m_driver_performing_task;
int m_distance_to_destination;
char m_currentask[100];
void animated_vehicle_operation(Ped ped);
void operate_door(eDoorId, bool);
void operate_lights(bool headlights, bool highbeams);
void operate_neons(int index, bool toggle);
void summon_vehicle();
void tick();
};
inline vehicle_control g_vehicle_control_service;
}

107
src/util/pathfind.hpp Normal file
View File

@ -0,0 +1,107 @@
#pragma once
#include "natives.hpp"
#include "pointers.hpp"
#include "math.hpp"
#include "script.hpp"
#include "gta/enums.hpp"
namespace big::pathfind
{
inline bool load_path_nodes(Vector3 coords)
{
if(PATHFIND::ARE_NODES_LOADED_FOR_AREA(coords.x, coords.y, coords.z, coords.y)) return true;
PATHFIND::REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(coords.x, coords.y, coords.z, coords.y);
for (int i = 0; i < 35 && !PATHFIND::ARE_NODES_LOADED_FOR_AREA(coords.x, coords.y, coords.z, coords.y); i++)
{
PATHFIND::REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(coords.x, coords.y, coords.z, coords.y);
script::get_current()->yield(10ms);
}
return PATHFIND::ARE_NODES_LOADED_FOR_AREA(coords.x, coords.y, coords.z, coords.y);
}
inline bool load_navmesh_area(Vector3 coords, float radius)
{
if(PATHFIND::ARE_ALL_NAVMESH_REGIONS_LOADED()) return true;
PATHFIND::ADD_NAVMESH_REQUIRED_REGION(coords.x, coords.z, radius);
for (int i = 0; i < 35 && !PATHFIND::ARE_ALL_NAVMESH_REGIONS_LOADED(); i++)
{
script::get_current()->yield(10ms);
}
return PATHFIND::ARE_ALL_NAVMESH_REGIONS_LOADED();
}
/*
Be sure to call this after having added a required region to free up memory since the game files suggest it is rather demanding to load navmesh
*/
inline void remove_navmesh_required_areas()
{
PATHFIND::REMOVE_NAVMESH_REQUIRED_REGIONS();
}
inline bool find_safe_pos_ped(Vector3 coords, Vector3& outcoords, bool onGround, int flag)
{
if (load_path_nodes(coords))
return PATHFIND::GET_SAFE_COORD_FOR_PED(coords.x, coords.y, coords.z, onGround, &outcoords, flag);
else
return false;
}
/*
zMeasureMult: how strongly should the difference in Z direction be weighted?
0.0 = ignored completely, 1.0 = the same as 2d distance. Default is 3.0 since we tend to care about
height differences more than 2d distance.
zTolerance: how far apart to the Z coords have to be before zMeasureMult kicks in?
nth: Which coords are returned, 1 being closest, 2 being second closesst and so on
*/
inline bool find_closest_vehicle_node(Vector3 coords, Vector3& outcoords, float& outheading, int flag, int nth = 1, float zMeasureMult = 3.f, float zTolerance = 0.f)
{
int lanes;
if (load_path_nodes(coords))
return PATHFIND::GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING(coords.x, coords.y, coords.z, nth, &outcoords, &outheading, &lanes, flag, zMeasureMult, zTolerance);
else
return false;
}
inline bool find_random_location_in_vicinity(Vector3 coords, Vector3& outcoords, float& outheading, int flag, int vicinity)
{
int rand1 = rand() % 4;
Vector3 changedcoords = coords;
switch (rand1)
{
case 1: changedcoords.x += rand() % vicinity + vicinity / 2; break;
case 2: changedcoords.x -= rand() % vicinity + vicinity / 2; break;
case 3: changedcoords.y += rand() % vicinity + vicinity / 2; break;
case 4: changedcoords.y -= rand() % vicinity + vicinity / 2; break;
}
find_closest_vehicle_node(changedcoords, outcoords, outheading, flag);
if (math::distance_between_vectors(outcoords, changedcoords) > vicinity)
{
if (find_safe_pos_ped(changedcoords, outcoords, true, flag))
return true;
else
{
outcoords = coords;
return false;
}
}
else
return true;
return false;
}
}

View File

@ -4,9 +4,446 @@
#include "pointers.hpp"
#include "outfit.hpp"
#include "services/players/player_service.hpp"
#include "math.hpp"
#include "gta/enums.hpp"
namespace big::ped
{
inline const std::map<int, const char*> task_names{
{0, "CTaskHandsUp"},
{1, "CTaskClimbLadder"},
{2, "CTaskExitVehicle"},
{3, "CTaskCombatRoll"},
{4, "CTaskAimGunOnFoot"},
{5, "CTaskMovePlayer"},
{6, "CTaskPlayerOnFoot"},
{8, "CTaskWeapon"},
{9, "CTaskPlayerWeapon"},
{10, "CTaskPlayerIdles"},
{12, "CTaskAimGun"},
{12, "CTaskComplex"},
{12, "CTaskFSMClone"},
{12, "CTaskMotionBase"},
{12, "CTaskMove"},
{12, "CTaskMoveBase"},
{12, "CTaskNMBehaviour"},
{12, "CTaskNavBase"},
{12, "CTaskScenario"},
{12, "CTaskSearchBase"},
{12, "CTaskSearchInVehicleBase"},
{12, "CTaskShockingEvent"},
{12, "CTaskTrainBase"},
{12, "CTaskVehicleFSM"},
{12, "CTaskVehicleGoTo"},
{12, "CTaskVehicleMissionBase"},
{12, "CTaskVehicleTempAction"},
{14, "CTaskPause"},
{15, "CTaskDoNothing"},
{16, "CTaskGetUp"},
{17, "CTaskGetUpAndStandStill"},
{18, "CTaskFallOver"},
{19, "CTaskFallAndGetUp"},
{20, "CTaskCrawl"},
{25, "CTaskComplexOnFire"},
{26, "CTaskDamageElectric"},
{28, "CTaskTriggerLookAt"},
{29, "CTaskClearLookAt"},
{30, "CTaskSetCharDecisionMaker"},
{31, "CTaskSetPedDefensiveArea"},
{32, "CTaskUseSequence"},
{34, "CTaskMoveStandStill"},
{35, "CTaskComplexControlMovement"},
{36, "CTaskMoveSequence"},
{38, "CTaskAmbientClips"},
{39, "CTaskMoveInAir"},
{40, "CTaskNetworkClone"},
{41, "CTaskUseClimbOnRoute"},
{42, "CTaskUseDropDownOnRoute"},
{43, "CTaskUseLadderOnRoute"},
{44, "CTaskSetBlockingOfNonTemporaryEvents"},
{45, "CTaskForceMotionState"},
{46, "CTaskSlopeScramble"},
{47, "CTaskGoToAndClimbLadder"},
{48, "CTaskClimbLadderFully"},
{49, "CTaskRappel"},
{50, "CTaskVault"},
{51, "CTaskDropDown"},
{52, "CTaskAffectSecondaryBehaviour"},
{53, "CTaskAmbientLookAtEvent"},
{54, "CTaskOpenDoor"},
{55, "CTaskShovePed"},
{56, "CTaskSwapWeapon"},
{57, "CTaskGeneralSweep"},
{58, "CTaskPolice"},
{59, "CTaskPoliceOrderResponse"},
{60, "CTaskPursueCriminal"},
{62, "CTaskArrestPed"},
{63, "CTaskArrestPed2"},
{64, "CTaskBusted"},
{65, "CTaskFirePatrol"},
{66, "CTaskHeliOrderResponse"},
{67, "CTaskHeliPassengerRappel"},
{68, "CTaskAmbulancePatrol"},
{69, "CTaskPoliceWantedResponse"},
{70, "CTaskSwat"},
{72, "CTaskSwatWantedResponse"},
{73, "CTaskSwatOrderResponse"},
{74, "CTaskSwatGoToStagingArea"},
{75, "CTaskSwatFollowInLine"},
{76, "CTaskWitness"},
{77, "CTaskGangPatrol"},
{78, "CTaskArmy"},
{80, "CTaskShockingEventWatch"},
{82, "CTaskShockingEventGoto"},
{83, "CTaskShockingEventHurryAway"},
{84, "CTaskShockingEventReactToAircraft"},
{85, "CTaskShockingEventReact"},
{86, "CTaskShockingEventBackAway"},
{87, "CTaskShockingPoliceInvestigate"},
{88, "CTaskShockingEventStopAndStare"},
{89, "CTaskShockingNiceCarPicture"},
{90, "CTaskShockingEventThreatResponse"},
{92, "CTaskTakeOffHelmet"},
{93, "CTaskCarReactToVehicleCollision"},
{95, "CTaskCarReactToVehicleCollisionGetOut"},
{97, "CTaskDyingDead"},
{100, "CTaskWanderingScenario"},
{101, "CTaskWanderingInRadiusScenario"},
{103, "CTaskMoveBetweenPointsScenario"},
{104, "CTaskChatScenario"},
{106, "CTaskCowerScenario"},
{107, "CTaskDeadBodyScenario"},
{114, "CTaskSayAudio"},
{116, "CTaskWaitForSteppingOut"},
{117, "CTaskCoupleScenario"},
{118, "CTaskUseScenario"},
{119, "CTaskUseVehicleScenario"},
{120, "CTaskUnalerted"},
{121, "CTaskStealVehicle"},
{122, "CTaskReactToPursuit"},
{125, "CTaskHitWall"},
{126, "CTaskCower"},
{127, "CTaskCrouch"},
{128, "CTaskMelee"},
{129, "CTaskMoveMeleeMovement"},
{130, "CTaskMeleeActionResult"},
{131, "CTaskMeleeUpperbodyAnims"},
{133, "CTaskMoVEScripted"},
{134, "CTaskScriptedAnimation"},
{135, "CTaskSynchronizedScene"},
{137, "CTaskComplexEvasiveStep"},
{138, "CTaskWalkRoundCarWhileWandering"},
{140, "CTaskComplexStuckInAir"},
{141, "CTaskWalkRoundEntity"},
{142, "CTaskMoveWalkRoundVehicle"},
{144, "CTaskReactToGunAimedAt"},
{146, "CTaskDuckAndCover"},
{147, "CTaskAggressiveRubberneck"},
{150, "CTaskInVehicleBasic"},
{151, "CTaskCarDriveWander"},
{152, "CTaskLeaveAnyCar"},
{153, "CTaskComplexGetOffBoat"},
{155, "CTaskCarSetTempAction"},
{156, "CTaskBringVehicleToHalt"},
{157, "CTaskCarDrive"},
{159, "CTaskPlayerDrive"},
{160, "CTaskEnterVehicle"},
{161, "CTaskEnterVehicleAlign"},
{162, "CTaskOpenVehicleDoorFromOutside"},
{163, "CTaskEnterVehicleSeat"},
{164, "CTaskCloseVehicleDoorFromInside"},
{165, "CTaskInVehicleSeatShuffle"},
{167, "CTaskExitVehicleSeat"},
{168, "CTaskCloseVehicleDoorFromOutside"},
{169, "CTaskControlVehicle"},
{170, "CTaskMotionInAutomobile"},
{171, "CTaskMotionOnBicycle"},
{172, "CTaskMotionOnBicycleController"},
{173, "CTaskMotionInVehicle"},
{174, "CTaskMotionInTurret"},
{175, "CTaskReactToBeingJacked"},
{176, "CTaskReactToBeingAskedToLeaveVehicle"},
{177, "CTaskTryToGrabVehicleDoor"},
{178, "CTaskGetOnTrain"},
{179, "CTaskGetOffTrain"},
{180, "CTaskRideTrain"},
{190, "CTaskMountThrowProjectile"},
{195, "CTaskGoToCarDoorAndStandStill"},
{196, "CTaskMoveGoToVehicleDoor"},
{197, "CTaskSetPedInVehicle"},
{198, "CTaskSetPedOutOfVehicle"},
{199, "CTaskVehicleMountedWeapon"},
{200, "CTaskVehicleGun"},
{201, "CTaskVehicleProjectile"},
{204, "CTaskSmashCarWindow"},
{205, "CTaskMoveGoToPoint"},
{206, "CTaskMoveAchieveHeading"},
{207, "CTaskMoveFaceTarget"},
{208, "CTaskComplexGoToPointAndStandStillTimed"},
{208, "CTaskMoveGoToPointAndStandStill"},
{209, "CTaskMoveFollowPointRoute"},
{210, "CTaskMoveSeekEntity_CEntitySeekPosCalculatorStandard"},
{211, "CTaskMoveSeekEntity_CEntitySeekPosCalculatorLastNavMeshIntersection"},
{212, "CTaskMoveSeekEntity_CEntitySeekPosCalculatorLastNavMeshIntersection2"},
{213, "CTaskMoveSeekEntity_CEntitySeekPosCalculatorXYOffsetFixed"},
{214, "CTaskMoveSeekEntity_CEntitySeekPosCalculatorXYOffsetFixed2"},
{215, "CTaskExhaustedFlee"},
{216, "CTaskGrowlAndFlee"},
{217, "CTaskScenarioFlee"},
{218, "CTaskSmartFlee"},
{219, "CTaskFlyAway"},
{220, "CTaskWalkAway"},
{221, "CTaskWander"},
{222, "CTaskWanderInArea"},
{223, "CTaskFollowLeaderInFormation"},
{224, "CTaskGoToPointAnyMeans"},
{225, "CTaskTurnToFaceEntityOrCoord"},
{226, "CTaskFollowLeaderAnyMeans"},
{228, "CTaskFlyToPoint"},
{229, "CTaskFlyingWander"},
{230, "CTaskGoToPointAiming"},
{231, "CTaskGoToScenario"},
{233, "CTaskSeekEntityAiming"},
{234, "CTaskSlideToCoord"},
{235, "CTaskSwimmingWander"},
{237, "CTaskMoveTrackingEntity"},
{238, "CTaskMoveFollowNavMesh"},
{239, "CTaskMoveGoToPointOnRoute"},
{240, "CTaskEscapeBlast"},
{241, "CTaskMoveWander"},
{242, "CTaskMoveBeInFormation"},
{243, "CTaskMoveCrowdAroundLocation"},
{244, "CTaskMoveCrossRoadAtTrafficLights"},
{245, "CTaskMoveWaitForTraffic"},
{246, "CTaskMoveGoToPointStandStillAchieveHeading"},
{251, "CTaskMoveGetOntoMainNavMesh"},
{252, "CTaskMoveSlideToCoord"},
{253, "CTaskMoveGoToPointRelativeToEntityAndStandStill"},
{254, "CTaskHelicopterStrafe"},
{256, "CTaskGetOutOfWater"},
{259, "CTaskMoveFollowEntityOffset"},
{261, "CTaskFollowWaypointRecording"},
{264, "CTaskMotionPed"},
{265, "CTaskMotionPedLowLod"},
{268, "CTaskHumanLocomotion"},
{269, "CTaskMotionBasicLocomotionLowLod"},
{270, "CTaskMotionStrafing"},
{271, "CTaskMotionTennis"},
{272, "CTaskMotionAiming"},
{273, "CTaskBirdLocomotion"},
{274, "CTaskFlightlessBirdLocomotion"},
{278, "CTaskFishLocomotion"},
{279, "CTaskQuadLocomotion"},
{280, "CTaskMotionDiving"},
{281, "CTaskMotionSwimming"},
{282, "CTaskMotionParachuting"},
{283, "CTaskMotionDrunk"},
{284, "CTaskRepositionMove"},
{285, "CTaskMotionAimingTransition"},
{286, "CTaskThrowProjectile"},
{287, "CTaskCover"},
{288, "CTaskMotionInCover"},
{289, "CTaskAimAndThrowProjectile"},
{290, "CTaskGun"},
{291, "CTaskAimFromGround"},
{295, "CTaskAimGunVehicleDriveBy"},
{296, "CTaskAimGunScripted"},
{298, "CTaskReloadGun"},
{299, "CTaskWeaponBlocked"},
{300, "CTaskEnterCover"},
{301, "CTaskExitCover"},
{302, "CTaskAimGunFromCoverIntro"},
{303, "CTaskAimGunFromCoverOutro"},
{304, "CTaskAimGunBlindFire"},
{307, "CTaskCombatClosestTargetInArea"},
{308, "CTaskCombatAdditionalTask"},
{309, "CTaskInCover"},
{313, "CTaskAimSweep"},
{318, "CTaskSharkCircle"},
{319, "CTaskSharkAttack"},
{320, "CTaskAgitated"},
{321, "CTaskAgitatedAction"},
{322, "CTaskConfront"},
{323, "CTaskIntimidate"},
{324, "CTaskShove"},
{325, "CTaskShoved"},
{327, "CTaskCrouchToggle"},
{328, "CTaskRevive"},
{334, "CTaskParachute"},
{335, "CTaskParachuteObject"},
{336, "CTaskTakeOffPedVariation"},
{339, "CTaskCombatSeekCover"},
{341, "CTaskCombatFlank"},
{342, "CTaskCombat"},
{343, "CTaskCombatMounted"},
{344, "CTaskMoveCircle"},
{345, "CTaskMoveCombatMounted"},
{346, "CTaskSearch"},
{347, "CTaskSearchOnFoot"},
{348, "CTaskSearchInAutomobile"},
{349, "CTaskSearchInBoat"},
{350, "CTaskSearchInHeli"},
{351, "CTaskThreatResponse"},
{352, "CTaskInvestigate"},
{353, "CTaskStandGuardFSM"},
{354, "CTaskPatrol"},
{355, "CTaskShootAtTarget"},
{356, "CTaskSetAndGuardArea"},
{357, "CTaskStandGuard"},
{358, "CTaskSeparate"},
{359, "CTaskStayInCover"},
{360, "CTaskVehicleCombat"},
{361, "CTaskVehiclePersuit"},
{362, "CTaskVehicleChase"},
{363, "CTaskDraggingToSafety"},
{364, "CTaskDraggedToSafety"},
{365, "CTaskVariedAimPose"},
{366, "CTaskMoveWithinAttackWindow"},
{367, "CTaskMoveWithinDefensiveArea"},
{368, "CTaskShootOutTire"},
{369, "CTaskShellShocked"},
{370, "CTaskBoatChase"},
{371, "CTaskBoatCombat"},
{372, "CTaskBoatStrafe"},
{373, "CTaskHeliChase"},
{374, "CTaskHeliCombat"},
{375, "CTaskSubmarineCombat"},
{376, "CTaskSubmarineChase"},
{377, "CTaskPlaneChase"},
{378, "CTaskTargetUnreachable"},
{379, "CTaskTargetUnreachableInInterior"},
{380, "CTaskTargetUnreachableInExterior"},
{381, "CTaskStealthKill"},
{382, "CTaskWrithe"},
{383, "CTaskAdvance"},
{384, "CTaskCharge"},
{385, "CTaskMoveToTacticalPoint"},
{386, "CTaskToHurtTransit"},
{387, "CTaskAnimatedHitByExplosion"},
{388, "CTaskNMRelax"},
{390, "CTaskNMPose"},
{391, "CTaskNMBrace"},
{392, "CTaskNMBuoyancy"},
{393, "CTaskNMInjuredOnGround"},
{394, "CTaskNMShot"},
{395, "CTaskNMHighFall"},
{396, "CTaskNMBalance"},
{397, "CTaskNMElectrocute"},
{398, "CTaskNMPrototype"},
{399, "CTaskNMExplosion"},
{400, "CTaskNMOnFire"},
{401, "CTaskNMScriptControl"},
{402, "CTaskNMJumpRollFromRoadVehicle"},
{403, "CTaskNMFlinch"},
{404, "CTaskNMSit"},
{405, "CTaskNMFallDown"},
{406, "CTaskBlendFromNM"},
{407, "CTaskNMControl"},
{408, "CTaskNMDangle"},
{411, "CTaskNMGenericAttach"},
{412, "CTaskNMDrunk"},
{413, "CTaskNMDraggingToSafety"},
{414, "CTaskNMThroughWindscreen"},
{415, "CTaskNMRiverRapids"},
{416, "CTaskNMSimple"},
{417, "CTaskRageRagdoll"},
{420, "CTaskJumpVault"},
{421, "CTaskJump"},
{422, "CTaskFall"},
{424, "CTaskReactAimWeapon"},
{425, "CTaskChat"},
{426, "CTaskMobilePhone"},
{427, "CTaskReactToDeadPed"},
{429, "CTaskSearchForUnknownThreat"},
{431, "CTaskBomb"},
{432, "CTaskDetonator"},
{434, "CTaskAnimatedAttach"},
{440, "CTaskCutScene"},
{441, "CTaskReactToExplosion"},
{442, "CTaskReactToImminentExplosion"},
{443, "CTaskDiveToGround"},
{444, "CTaskReactAndFlee"},
{445, "CTaskSidestep"},
{446, "CTaskCallPolice"},
{447, "CTaskReactInDirection"},
{448, "CTaskReactToBuddyShot"},
{453, "CTaskVehicleGoToAutomobileNew"},
{454, "CTaskVehicleGoToPlane"},
{455, "CTaskVehicleGoToHelicopter"},
{456, "CTaskVehicleGoToSubmarine"},
{457, "CTaskVehicleGoToBoat"},
{458, "CTaskVehicleGoToPointAutomobile"},
{459, "CTaskVehicleGoToPointWithAvoidanceAutomobile"},
{460, "CTaskVehiclePursue"},
{461, "CTaskVehicleRam"},
{462, "CTaskVehicleSpinOut"},
{463, "CTaskVehicleApproach"},
{464, "CTaskVehicleThreePointTurn"},
{465, "CTaskVehicleDeadDriver"},
{466, "CTaskVehicleCruiseNew"},
{467, "CTaskVehicleCruiseBoat"},
{468, "CTaskVehicleStop"},
{469, "CTaskVehiclePullOver"},
{470, "CTaskVehiclePassengerExit"},
{471, "CTaskVehicleFlee"},
{472, "CTaskVehicleFleeAirborne"},
{473, "CTaskVehicleFleeBoat"},
{474, "CTaskVehicleFollowRecording"},
{475, "CTaskVehicleFollow"},
{476, "CTaskVehicleBlock"},
{477, "CTaskVehicleBlockCruiseInFront"},
{478, "CTaskVehicleBlockBrakeInFront"},
{479, "CTaskVehicleBlockBackAndForth"},
{480, "CTaskVehicleCrash"},
{481, "CTaskVehicleLand"},
{482, "CTaskVehicleLandPlane"},
{483, "CTaskVehicleHover"},
{484, "CTaskVehicleAttack"},
{485, "CTaskVehicleAttackTank"},
{486, "CTaskVehicleCircle"},
{487, "CTaskVehiclePoliceBehaviour"},
{488, "CTaskVehiclePoliceBehaviourHelicopter"},
{489, "CTaskVehiclePoliceBehaviourBoat"},
{490, "CTaskVehicleEscort"},
{491, "CTaskVehicleHeliProtect"},
{493, "CTaskVehiclePlayerDriveAutomobile"},
{494, "CTaskVehiclePlayerDriveBike"},
{495, "CTaskVehiclePlayerDriveBoat"},
{496, "CTaskVehiclePlayerDriveSubmarine"},
{497, "CTaskVehiclePlayerDriveSubmarineCar"},
{498, "CTaskVehiclePlayerDrivePlane"},
{499, "CTaskVehiclePlayerDriveHeli"},
{500, "CTaskVehiclePlayerDriveAutogyro"},
{501, "CTaskVehiclePlayerDriveDiggerArm"},
{502, "CTaskVehiclePlayerDriveTrain"},
{503, "CTaskVehiclePlaneChase"},
{504, "CTaskVehicleNoDriver"},
{505, "CTaskVehicleAnimation"},
{506, "CTaskVehicleConvertibleRoof"},
{507, "CTaskVehicleParkNew"},
{508, "CTaskVehicleFollowWaypointRecording"},
{509, "CTaskVehicleGoToNavmesh"},
{510, "CTaskVehicleReactToCopSiren"},
{511, "CTaskVehicleGotoLongRange"},
{512, "CTaskVehicleWait"},
{513, "CTaskVehicleReverse"},
{514, "CTaskVehicleBrake"},
{515, "CTaskVehicleHandBrake"},
{516, "CTaskVehicleTurn"},
{517, "CTaskVehicleGoForward"},
{518, "CTaskVehicleSwerve"},
{519, "CTaskVehicleFlyDirection"},
{520, "CTaskVehicleHeadonCollision"},
{521, "CTaskVehicleBoostUseSteeringAngle"},
{522, "CTaskVehicleShotTire"},
{523, "CTaskVehicleBurnout"},
{524, "CTaskVehicleRevEngine"},
{525, "CTaskVehicleSurfaceInSubmarine"},
{526, "CTaskVehiclePullAlongside"},
{527, "CTaskVehicleTransformToSubmarine"},
{528, "CTaskAnimatedFallback"},
};
inline bool change_player_model(const Hash hash)
{
for (uint8_t i = 0; !STREAMING::HAS_MODEL_LOADED(hash) && i < 100; i++)
@ -145,10 +582,27 @@ namespace big::ped
return STREAMING::HAS_ANIM_DICT_LOADED(dict);
}
inline void ped_play_animation(Ped ped, const std::string_view& animDict, const std::string_view& animName, float speed = 4.f, float speedMultiplier = -4.f, int duration = -1, int flag = 1, float playbackRate = 0, bool lockPos = false)
inline void ped_play_animation(Ped ped, const std::string_view& animDict, const std::string_view& animName, float speed = 4.f, float speedMultiplier = -4.f, int duration = -1, int flag = 0, float playbackRate = 0, bool lockPos = false)
{
if (load_animation_dict(animDict.data()))
TASK::TASK_PLAY_ANIM(ped, animDict.data(), animName.data(), speed, speedMultiplier, duration, flag, playbackRate, lockPos, lockPos, lockPos);
}
/*
* Will make the ped enter the vehicle with animation if vehicle is in vicinity
* Param movespeed: 1 = walk, 2 = run, 3 = sprint
*/
inline void ped_enter_vehicle_animated(Ped ped, Vehicle veh, eVehicleSeats seat, int movespeed)
{
if (entity::take_control_of(ped))
{
if (ENTITY::DOES_ENTITY_EXIST(veh)) {
if (math::distance_between_vectors(ENTITY::GET_ENTITY_COORDS(ped, 0), ENTITY::GET_ENTITY_COORDS(veh, 0)) < 15.f)
TASK::TASK_ENTER_VEHICLE(ped, veh, 10000, (int)seat, movespeed, 8, NULL);
else
PED::SET_PED_INTO_VEHICLE(ped, veh, (int)seat);
}
}
}
}

View File

@ -9,6 +9,7 @@
#include "script.hpp"
#include "script_global.hpp"
#include "services/vehicle_helper/vehicle_helper.hpp"
#include "gta/enums.hpp"
namespace big::vehicle
{
@ -676,4 +677,95 @@ namespace big::vehicle
g.m_remote_controlled_vehicle = veh;
return true;
}
}
/*
Set doorId to eDoorId::VEH_EXT_DOOR_INVALID_ID or simply -1 to apply to all vehicle doors.
*/
inline bool change_vehicle_door_lock_state(Vehicle veh, eDoorId doorId, eVehicleLockState state)
{
if (ENTITY::DOES_ENTITY_EXIST(veh))
{
if (doorId == eDoorId::VEH_EXT_DOOR_INVALID_ID)
{
VEHICLE::SET_VEHICLE_DOORS_LOCKED(veh, (int)state);
for (int i = 0; i < 6; i++)
VEHICLE::SET_VEHICLE_INDIVIDUAL_DOORS_LOCKED(veh, i, (int)state);
return VEHICLE::GET_VEHICLE_DOOR_LOCK_STATUS(veh) == (int)state;
}
else
{
if (VEHICLE::GET_IS_DOOR_VALID(veh, (int)doorId))
VEHICLE::SET_VEHICLE_INDIVIDUAL_DOORS_LOCKED(veh, (int)doorId, (int)state);
return VEHICLE::GET_VEHICLE_INDIVIDUAL_DOOR_LOCK_STATUS(veh, (int) doorId) == (int)state;
}
}
return false;
}
/*
* Set 'open' to false to close the door.
* Set doorId to eDoorId::VEH_EXT_DOOR_INVALID_ID or simply -1 to apply to all doors.
*/
inline bool operate_vehicle_door(Vehicle veh, eDoorId doorId, bool open)
{
bool success = false;
if (ENTITY::DOES_ENTITY_EXIST(veh))
{
for (int i = 0; i < 6; i++)
{
if (doorId == eDoorId::VEH_EXT_DOOR_INVALID_ID || (int)doorId == i)
{
if (VEHICLE::GET_IS_DOOR_VALID(veh, i))
{
if (open)
VEHICLE::SET_VEHICLE_DOOR_OPEN(veh, i, false, false);
else
VEHICLE::SET_VEHICLE_DOOR_SHUT(veh, i, false);
}
success = true;
}
}
}
return success;
}
inline bool operate_vehicle_headlights(Vehicle veh, bool lights, bool highbeams)
{
if (ENTITY::DOES_ENTITY_EXIST(veh))
{
VEHICLE::SET_VEHICLE_FULLBEAM(veh, highbeams);
VEHICLE::SET_VEHICLE_LIGHTS(veh, lights ? 3 : 4);
int regular, highbeam;
VEHICLE::GET_VEHICLE_LIGHTS_STATE(veh, &regular, &highbeam);
return regular == (int)lights && (int)highbeams == highbeam;
}
return false;
}
/*
* Input index -1 to apply to all neons.
*/
inline bool operate_vehicle_neons(Vehicle veh, int index, bool toggle)
{
bool success = false;
if (ENTITY::DOES_ENTITY_EXIST(veh))
{
VEHICLE::SET_VEHICLE_MOD_KIT(veh, 0);
for (int i = 0; i < 4; i++)
{
if (index == -1 || index == i)
{
VEHICLE::SET_VEHICLE_NEON_ENABLED(veh, index, toggle);
success = true;
}
}
}
return success;
}
}

View File

@ -8,6 +8,8 @@
#include "util/misc.hpp"
#include "util/system.hpp"
#include "view_debug.hpp"
#include "util/ped.hpp"
#include "util/pathfind.hpp"
namespace big
{
@ -65,6 +67,16 @@ namespace big
NETWORK::SHUTDOWN_AND_LOAD_MOST_RECENT_SAVE();
});
components::button("Tp To Safe Pos", [] {
Vector3 safepos{};
float heading;
if (pathfind::find_closest_vehicle_node(self::pos, safepos, heading, 0))
ENTITY::SET_ENTITY_COORDS(self::ped, safepos.x, safepos.y, safepos.z, 0, 0, 0, false);
else
g_notification_service->push_error("Find safe pos", "Failed to find a safe position");
});
components::command_button<"fastquit">();
if (ImGui::TreeNode("Addresses"))
@ -108,6 +120,21 @@ namespace big
ImGui::TreePop();
}
if (ImGui::TreeNode("Animation player"))
{
static char dict[100], anim[100];
ImGui::PushItemWidth(200);
components::input_text_with_hint("##dictionary", "Dict", dict, IM_ARRAYSIZE(dict));
components::input_text_with_hint("##animation", "Animation", anim, IM_ARRAYSIZE(anim));
if (ImGui::Button("Play animation"))
g_fiber_pool->queue_job([=] {
ped::ped_play_animation(self::ped, dict, anim);
});
ImGui::PopItemWidth();
ImGui::TreePop();
}
ImGui::EndTabItem();
}
}

View File

@ -48,6 +48,8 @@ namespace big
g_hotkey_service->update_hotkey("cmdexecutor", g.settings.hotkeys.cmd_excecutor);
if (ImGui::Hotkey("Repair PV", &g.settings.hotkeys.repairpv))
g_hotkey_service->update_hotkey("repairpv", g.settings.hotkeys.repairpv);
if (ImGui::Hotkey("Vehicle controller", &g.settings.hotkeys.open_vehicle_controller))
g_hotkey_service->update_hotkey("vehiclecontroller", g.settings.hotkeys.open_vehicle_controller);
ImGui::PopItemWidth();
}

View File

@ -77,6 +77,8 @@ namespace big
components::command_checkbox<"instantbrake">();
components::command_checkbox<"blockhoming">();
components::command_checkbox<"driveonwater">();
components::command_checkbox<"vehiclecontrol">();
ImGui::EndGroup();
ImGui::SameLine();

View File

@ -45,6 +45,7 @@ namespace big
static void pv();
static void persist_car();
static void fun_vehicle();
static void vehicle_control();
static void spawn_ped();
static void time_and_weather();
static void spoofing();

View File

@ -0,0 +1,363 @@
#include "gta_util.hpp"
#include "gui.hpp"
#include "pointers.hpp"
#include "services/vehicle/vehicle_control_service.hpp"
#include "util/ped.hpp"
#include "util/vehicle.hpp"
#include "views/view.hpp"
namespace big
{
void render_doors_tab()
{
const char* const doornames[MAX_VEHICLE_DOORS]{
"Front left",
"Front right",
"Back left",
"Back right",
"Bonnet",
"Trunk",
};
const char* const locknames[MAX_VEHICLE_LOCK_STATES]{
"None",
"Unlocked",
"Locked",
"Lockout player only",
"Locked player inside",
"Locked initially",
"Force shut doors",
"Locked but damageable",
"Locked but boot unlocked",
"Locked no passengers",
"Cannot enter",
};
ImGui::BeginGroup();
ImGui::SetNextItemWidth(200);
if (ImGui::BeginCombo("##alldoorslock", "All doors"))
{
for (int lockindex = 0; lockindex < MAX_VEHICLE_LOCK_STATES; lockindex++)
{
if (ImGui::Selectable(locknames[lockindex]))
{
g_fiber_pool->queue_job([=] {
vehicle::change_vehicle_door_lock_state(g_vehicle_control_service.m_controlled_vehicle.handle, eDoorId::VEH_EXT_DOOR_INVALID_ID, (eVehicleLockState)lockindex);
});
};
}
ImGui::EndCombo();
}
ImGui::SameLine();
if (ImGui::Button("Open all"))
{
g_fiber_pool->queue_job([=] {
g_vehicle_control_service.operate_door(eDoorId::VEH_EXT_DOOR_INVALID_ID, true);
});
}
ImGui::SameLine();
if (ImGui::Button("Close all"))
{
g_fiber_pool->queue_job([=] {
g_vehicle_control_service.operate_door(eDoorId::VEH_EXT_DOOR_INVALID_ID, false);
});
}
ImGui::EndGroup();
ImGui::Separator();
ImGui::BeginGroup();
for (int i = 0; i < MAX_VEHICLE_DOORS; i++)
{
if (!g_vehicle_control_service.m_controlled_vehicle.doors[i].valid)
continue;
ImGui::SetNextItemWidth(200);
if (ImGui::BeginCombo(doornames[i], locknames[(int)g_vehicle_control_service.m_controlled_vehicle.doors[i].lockstate]))
{
for (int lockindex = 0; lockindex < MAX_VEHICLE_LOCK_STATES; lockindex++)
{
if (ImGui::Selectable(locknames[lockindex]))
{
g_fiber_pool->queue_job([=] {
vehicle::change_vehicle_door_lock_state(g_vehicle_control_service.m_controlled_vehicle.handle, (eDoorId)i, (eVehicleLockState)lockindex);
});
};
}
ImGui::EndCombo();
}
ImGui::SameLine(300);
std::string buttonlabel = g_vehicle_control_service.m_controlled_vehicle.doors[i].open ? "Close" : "Open";
buttonlabel.append("##").append(std::to_string(i));
if (ImGui::Button(buttonlabel.data()))
{
g_fiber_pool->queue_job([=] {
g_vehicle_control_service.operate_door((eDoorId)i,
!g_vehicle_control_service.m_controlled_vehicle.doors[i].open);
});
}
}
ImGui::EndGroup();
}
void render_lights_tab()
{
const char* const neonnames[4]{
"Left",
"Right",
"Front",
"Rear",
};
if (ImGui::Button("Toggle lights"))
{
g_fiber_pool->queue_job([=] {
g_vehicle_control_service.operate_lights(!g_vehicle_control_service.m_controlled_vehicle.headlights, false);
});
}
ImGui::SameLine();
if (ImGui::Button("Toggle High beams"))
{
g_fiber_pool->queue_job([=] {
g_vehicle_control_service.operate_lights(g_vehicle_control_service.m_controlled_vehicle.headlights,
!g_vehicle_control_service.m_controlled_vehicle.highbeams);
});
}
if (ImGui::Button("Interior lights on"))
{
g_fiber_pool->queue_job([=] {
if (g.window.vehicle_control.operation_animation)
g_vehicle_control_service.animated_vehicle_operation(self::ped);
VEHICLE::SET_VEHICLE_INTERIORLIGHT(g_vehicle_control_service.m_controlled_vehicle.handle, true);
});
}
ImGui::SameLine();
if (ImGui::Button("Interior lights off"))
{
g_fiber_pool->queue_job([=] {
if (g.window.vehicle_control.operation_animation)
g_vehicle_control_service.animated_vehicle_operation(self::ped);
VEHICLE::SET_VEHICLE_INTERIORLIGHT(g_vehicle_control_service.m_controlled_vehicle.handle, false);
});
}
ImGui::Text("Neon lights");
ImGui::Separator();
for (int i = 0; i < 4; i++)
{
if (ImGui::Checkbox(neonnames[i], &g_vehicle_control_service.m_controlled_vehicle.neons[i]))
{
g_fiber_pool->queue_job([=] {
g_vehicle_control_service.operate_neons(i, g_vehicle_control_service.m_controlled_vehicle.neons[i]);
});
}
}
}
void render_seats_tab()
{
/*
* Seats start at index -1, compensate accordingly
*/
const char* const seatnames[6]{
"Driver",
"Passenger",
"Left rear",
"Right rear",
"Outside Left",
"Outside Right",
};
static int movespeed = 1;
if (ImGui::RadioButton("Walk", movespeed == 1))
movespeed = 1;
ImGui::SameLine();
if (ImGui::RadioButton("Run", movespeed == 2))
movespeed = 2;
ImGui::SameLine();
if (ImGui::RadioButton("Sprint", movespeed == 3))
movespeed = 3;
for (int i = 0; i < 6; i++)
{
if (ImGui::Button(seatnames[i]))
{
g_fiber_pool->queue_job([=] {
if (g.window.vehicle_control.operation_animation)
ped::ped_enter_vehicle_animated(self::ped, g_vehicle_control_service.m_controlled_vehicle.handle, (eVehicleSeats)(i - 1), movespeed);
else
PED::SET_PED_INTO_VEHICLE(self::ped, g_vehicle_control_service.m_controlled_vehicle.handle, (i - 1));
});
}
}
}
void render_misc_tab()
{
const char* const convertiblestates[4]{
"Up",
"Lowering",
"Down",
"Raising",
};
if (g_vehicle_control_service.m_controlled_vehicle.isconvertible)
{
if (ImGui::Button(g_vehicle_control_service.m_controlled_vehicle.convertibelstate ? "Raise" : "Lower"))
{
g_fiber_pool->queue_job([=] {
if (g.window.vehicle_control.operation_animation)
g_vehicle_control_service.animated_vehicle_operation(self::ped);
if (g_vehicle_control_service.m_controlled_vehicle.convertibelstate > 0)
VEHICLE::RAISE_CONVERTIBLE_ROOF(g_vehicle_control_service.m_controlled_vehicle.handle, false);
else
VEHICLE::LOWER_CONVERTIBLE_ROOF(g_vehicle_control_service.m_controlled_vehicle.handle, false);
});
}
ImGui::SameLine();
ImGui::Text("Convertible state: %s", convertiblestates[g_vehicle_control_service.m_controlled_vehicle.convertibelstate]);
}
if (ImGui::Checkbox(g_vehicle_control_service.m_controlled_vehicle.engine ? "Stop" : "Start",
&g_vehicle_control_service.m_controlled_vehicle.engine))
{
g_fiber_pool->queue_job([=] {
if (g.window.vehicle_control.operation_animation)
g_vehicle_control_service.animated_vehicle_operation(self::ped);
if (entity::take_control_of(g_vehicle_control_service.m_controlled_vehicle.handle))
VEHICLE::SET_VEHICLE_ENGINE_ON(g_vehicle_control_service.m_controlled_vehicle.handle,
!g_vehicle_control_service.m_controlled_vehicle.engine,
true,
false);
});
}
ImGui::SameLine();
ImGui::Text("Engine: %s", g_vehicle_control_service.m_controlled_vehicle.engine ? "Running" : "Off");
components::button(g_vehicle_control_service.m_driver_performing_task ? "Cancel" : "Summon", [] {
if (!g_vehicle_control_service.m_driver_performing_task)
{
if (g.window.vehicle_control.operation_animation)
g_vehicle_control_service.animated_vehicle_operation(self::ped);
g_vehicle_control_service.summon_vehicle();
}
else
g_vehicle_control_service.m_driver_performing_task = false;
});
if (g_vehicle_control_service.m_driver_performing_task)
{
ImGui::SameLine();
ImGui::Text("Distance: %d", g_vehicle_control_service.m_distance_to_destination);
ImGui::Text("Task: %s", g_vehicle_control_service.m_currentask);
}
}
void render_settings_tab()
{
ImGui::Checkbox("Use animations", &g.window.vehicle_control.operation_animation);
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("Will use animations for several vehicle operations such as:\ntoggling lights, opening/closing doors and entering seats");
ImGui::EndTooltip();
}
ImGui::Checkbox("Render distance on vehicle", &g.window.vehicle_control.render_distance_on_veh);
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("Will display the distance on the controlled vehicle");
ImGui::EndTooltip();
}
ImGui::SliderFloat("Max summon distance", &g.window.vehicle_control.max_summon_range, 10.f, 250.f);
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("At what range the vehicle will drive towards the summoned location as oposed to being teleported");
ImGui::EndTooltip();
}
}
void view::vehicle_control()
{
if (!g.window.vehicle_control.opened || !*g_pointers->m_is_session_started)
return;
ImGui::SetNextWindowPos(ImVec2(500.0f, 10.0f), ImGuiCond_FirstUseEver, ImVec2(0.0f, 0.0f));
ImGui::SetNextWindowBgAlpha(0.5f);
if (ImGui::Begin("Vehicle controller", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav))
{
if (g_vehicle_control_service.m_controlled_vehicle_exists)
{
ImGui::Text(g_vehicle_control_service.m_controlled_vehicle.model_name);
ImGui::Separator();
ImGui::Spacing();
if (ImGui::BeginTabBar("##vehiclecontroltabbar"))
{
if (ImGui::BeginTabItem("Doors"))
{
render_doors_tab();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Lights"))
{
render_lights_tab();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Seats"))
{
render_seats_tab();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Misc"))
{
render_misc_tab();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Settings"))
{
render_settings_tab();
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}
}
else
{
ImGui::Text("No vehicle available");
}
}
ImGui::End();
}
}