2021-05-19 11:27:47 +02:00
|
|
|
#pragma once
|
2021-05-25 14:11:13 +02:00
|
|
|
#include "entity.hpp"
|
2021-05-19 11:27:47 +02:00
|
|
|
#include "gta/joaat.hpp"
|
2021-05-25 14:11:13 +02:00
|
|
|
#include "math.hpp"
|
2021-05-19 11:27:47 +02:00
|
|
|
#include "natives.hpp"
|
|
|
|
#include "pointers.hpp"
|
|
|
|
#include "script.hpp"
|
2021-09-21 13:39:15 +02:00
|
|
|
#include "teleport.hpp"
|
2022-05-09 22:58:53 +02:00
|
|
|
#include "script_global.hpp"
|
2022-12-08 13:35:41 +01:00
|
|
|
#include "gta/vehicle_values.hpp"
|
2022-07-17 04:36:05 +08:00
|
|
|
#include "services/vehicle_helper/vehicle_helper.hpp"
|
2022-11-21 15:42:12 +00:00
|
|
|
#include "core/scr_globals.hpp"
|
2021-05-19 11:27:47 +02:00
|
|
|
|
|
|
|
namespace big::vehicle
|
|
|
|
{
|
2022-07-14 22:16:30 +08:00
|
|
|
inline float mps_to_speed(float mps, SpeedUnit speed_unit)
|
|
|
|
{
|
|
|
|
switch (speed_unit)
|
|
|
|
{
|
|
|
|
case SpeedUnit::KMPH:
|
|
|
|
return mps * 3.6f;
|
|
|
|
break;
|
|
|
|
case SpeedUnit::MIPH:
|
|
|
|
return mps * 2.2369f;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mps;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float speed_to_mps(float speed, SpeedUnit speed_unit)
|
|
|
|
{
|
|
|
|
switch (speed_unit)
|
|
|
|
{
|
|
|
|
case SpeedUnit::KMPH:
|
|
|
|
return speed / 3.6f;
|
|
|
|
break;
|
|
|
|
case SpeedUnit::MIPH:
|
|
|
|
return speed / 2.2369f;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return speed;
|
|
|
|
}
|
|
|
|
|
2022-12-22 21:23:32 +00:00
|
|
|
inline Vector3 get_spawn_location(bool spawn_inside, Ped ped = self::ped)
|
2022-07-28 01:42:15 +08:00
|
|
|
{
|
|
|
|
float y_offset = 0;
|
|
|
|
|
|
|
|
if (self::veh != 0)
|
|
|
|
{
|
|
|
|
y_offset = 10.f;
|
|
|
|
}
|
|
|
|
else if (!spawn_inside)
|
|
|
|
{
|
|
|
|
y_offset = 5.f;
|
|
|
|
}
|
|
|
|
|
2022-12-22 21:23:32 +00:00
|
|
|
return ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(ped, 0.f, y_offset, 0.f);
|
2022-07-28 01:42:15 +08:00
|
|
|
}
|
|
|
|
|
2022-07-17 04:36:05 +08:00
|
|
|
inline void set_mp_bitset(Vehicle veh)
|
|
|
|
{
|
|
|
|
DECORATOR::DECOR_SET_INT(veh, "MPBitset", 0);
|
|
|
|
auto networkId = NETWORK::VEH_TO_NET(veh);
|
|
|
|
if (NETWORK::NETWORK_GET_ENTITY_IS_NETWORKED(veh))
|
|
|
|
NETWORK::SET_NETWORK_ID_EXISTS_ON_ALL_MACHINES(networkId, true);
|
|
|
|
VEHICLE::SET_VEHICLE_IS_STOLEN(veh, FALSE);
|
|
|
|
}
|
|
|
|
|
2022-07-12 22:42:07 +08:00
|
|
|
inline void bring(Vehicle veh, Vector3 location, bool put_in = true, int seatIdx = -1)
|
2021-05-21 14:09:28 +02:00
|
|
|
{
|
2022-06-27 15:45:26 +02:00
|
|
|
if (!ENTITY::IS_ENTITY_A_VEHICLE(veh)) return g_notification_service->push_error("Vehicle", "Invalid handle");
|
|
|
|
|
2022-07-10 06:33:14 +08:00
|
|
|
auto vecVehicleLocation = ENTITY::GET_ENTITY_COORDS(veh, true);
|
2021-09-21 13:39:15 +02:00
|
|
|
teleport::load_ground_at_3dcoord(vecVehicleLocation);
|
2021-05-25 14:11:13 +02:00
|
|
|
|
2021-09-21 13:39:15 +02:00
|
|
|
if (!entity::take_control_of(veh))
|
2022-03-02 00:21:29 +01:00
|
|
|
return g_notification_service->push_warning("Vehicle", "Failed to take control of remote vehicle.");
|
2022-07-10 06:33:14 +08:00
|
|
|
auto ped = self::ped;
|
2022-05-23 06:38:45 +08:00
|
|
|
|
2021-09-21 13:39:15 +02:00
|
|
|
ENTITY::SET_ENTITY_COORDS(veh, location.x, location.y, location.z + 1.f, 0, 0, 0, 0);
|
2022-05-23 06:38:45 +08:00
|
|
|
ENTITY::SET_ENTITY_HEADING(veh, ENTITY::GET_ENTITY_HEADING(ped));
|
2021-05-21 14:09:28 +02:00
|
|
|
|
|
|
|
if (put_in)
|
|
|
|
{
|
2021-05-25 14:11:13 +02:00
|
|
|
for (size_t i = 0; i < 100 && math::distance_between_vectors(location, ENTITY::GET_ENTITY_COORDS(veh, true)) > 10; i++)
|
|
|
|
script::get_current()->yield();
|
|
|
|
|
2022-07-12 22:42:07 +08:00
|
|
|
auto driver_ped = VEHICLE::GET_PED_IN_VEHICLE_SEAT(veh, -1, false);
|
|
|
|
|
|
|
|
if (driver_ped != 0)
|
|
|
|
{
|
|
|
|
if (PED::GET_PED_TYPE(driver_ped) == ePedType::PED_TYPE_NETWORK_PLAYER)
|
|
|
|
{
|
|
|
|
TASK::CLEAR_PED_TASKS_IMMEDIATELY(driver_ped);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
entity::delete_entity(driver_ped);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PED::SET_PED_INTO_VEHICLE(ped, veh, seatIdx);
|
2021-05-21 14:09:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-10 06:33:14 +08:00
|
|
|
inline Vehicle get_closest_to_location(Vector3 location, float range)
|
|
|
|
{
|
|
|
|
if (const auto replay = *g_pointers->m_replay_interface; replay)
|
|
|
|
{
|
|
|
|
if (const auto veh_interface = replay->m_vehicle_interface; veh_interface)
|
|
|
|
{
|
|
|
|
const auto veh_interface_size = veh_interface->m_max_vehicles;
|
|
|
|
|
2022-07-12 22:42:07 +08:00
|
|
|
float min_dist = FLT_MAX;
|
2022-07-10 06:33:14 +08:00
|
|
|
int32_t m_handle = 0;
|
|
|
|
|
|
|
|
for (int32_t i = 0; i < veh_interface_size; i++)
|
|
|
|
{
|
|
|
|
auto veh_entity = veh_interface->m_vehicle_list->m_vehicles[i];
|
|
|
|
auto veh_ptr = veh_entity.m_entity_ptr;
|
|
|
|
|
|
|
|
if (!veh_ptr || !veh_ptr->m_navigation)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-11-09 06:44:52 +08:00
|
|
|
auto veh_pos_arr = *veh_ptr->m_navigation->get_position();
|
2022-07-10 06:33:14 +08:00
|
|
|
Vector3 veh_pos(veh_pos_arr.x, veh_pos_arr.y, veh_pos_arr.z);
|
|
|
|
|
|
|
|
float dist = math::distance_between_vectors(veh_pos, location);
|
|
|
|
|
|
|
|
if (dist < min_dist)
|
|
|
|
{
|
2022-07-12 22:42:07 +08:00
|
|
|
int32_t tmp_handle = g_pointers->m_ptr_to_handle(veh_ptr);
|
|
|
|
|
|
|
|
if (entity::take_control_of(tmp_handle))
|
|
|
|
{
|
|
|
|
min_dist = dist;
|
|
|
|
m_handle = tmp_handle;
|
|
|
|
}
|
2022-07-10 06:33:14 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_handle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool set_plate(Vehicle veh, const char* plate)
|
2021-05-21 14:09:28 +02:00
|
|
|
{
|
2022-07-10 06:33:14 +08:00
|
|
|
if (!ENTITY::IS_ENTITY_A_VEHICLE(veh) || !entity::take_control_of(veh))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (plate != nullptr && plate[0] != 0)
|
|
|
|
{
|
|
|
|
VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT(veh, plate);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2021-05-21 14:09:28 +02:00
|
|
|
}
|
|
|
|
|
2021-07-23 11:58:43 +02:00
|
|
|
inline bool repair(Vehicle veh)
|
|
|
|
{
|
2022-07-10 06:33:14 +08:00
|
|
|
if (!ENTITY::IS_ENTITY_A_VEHICLE(veh) || !entity::take_control_of(veh))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2021-08-03 20:25:55 +02:00
|
|
|
|
2021-07-23 11:58:43 +02:00
|
|
|
VEHICLE::SET_VEHICLE_FIXED(veh);
|
|
|
|
VEHICLE::SET_VEHICLE_DEFORMATION_FIXED(veh);
|
|
|
|
VEHICLE::SET_VEHICLE_DIRT_LEVEL(veh, 0.f);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-12-06 16:12:02 +00:00
|
|
|
inline Vehicle spawn(Hash hash, Vector3 location, float heading, bool is_networked = true, bool script_veh = false)
|
2021-05-19 11:27:47 +02:00
|
|
|
{
|
2022-07-10 06:33:14 +08:00
|
|
|
for (uint8_t i = 0; !STREAMING::HAS_MODEL_LOADED(hash) && i < 100; i++)
|
2021-05-19 11:27:47 +02:00
|
|
|
{
|
2022-07-10 06:33:14 +08:00
|
|
|
STREAMING::REQUEST_MODEL(hash);
|
|
|
|
script::get_current()->yield();
|
|
|
|
}
|
2021-05-19 11:27:47 +02:00
|
|
|
|
2022-07-10 06:33:14 +08:00
|
|
|
if (!STREAMING::HAS_MODEL_LOADED(hash))
|
|
|
|
{
|
2022-07-28 01:42:15 +08:00
|
|
|
return 0;
|
2022-07-10 06:33:14 +08:00
|
|
|
}
|
2021-05-19 11:27:47 +02:00
|
|
|
|
2022-12-06 16:12:02 +00:00
|
|
|
auto veh = VEHICLE::CREATE_VEHICLE(hash, location.x, location.y, location.z, heading, is_networked, script_veh, false);
|
2021-05-19 11:27:47 +02:00
|
|
|
|
2022-07-10 06:33:14 +08:00
|
|
|
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
|
2021-05-19 11:27:47 +02:00
|
|
|
|
2022-07-10 06:33:14 +08:00
|
|
|
if (*g_pointers->m_is_session_started)
|
|
|
|
{
|
2022-07-17 04:36:05 +08:00
|
|
|
set_mp_bitset(veh);
|
2022-07-10 06:33:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return veh;
|
|
|
|
}
|
|
|
|
|
2022-07-17 04:36:05 +08:00
|
|
|
inline Vehicle clone_from_vehicle_data(std::map<int, int32_t>& data, Vector3 location, float heading)
|
2022-07-10 06:33:14 +08:00
|
|
|
{
|
|
|
|
Vector3 tmpLocation = { location.x, location.y, 1200.0f };
|
|
|
|
if (location.z > 1000.0f && location.z < 1400.0)
|
|
|
|
{
|
|
|
|
tmpLocation.z = 800.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
// vehicle data
|
|
|
|
for (const auto& [idx, val] : data)
|
|
|
|
{
|
|
|
|
if (idx >= 0 && idx < 142)
|
2021-05-19 11:27:47 +02:00
|
|
|
{
|
2022-11-21 15:42:12 +00:00
|
|
|
*scr_globals::spawn_global.at(27).at(idx).as<int32_t*>() = val;
|
2021-05-19 11:27:47 +02:00
|
|
|
}
|
2022-07-10 06:33:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// permission fix
|
2022-11-21 15:42:12 +00:00
|
|
|
*scr_globals::spawn_global.at(27).at(1).as<int32_t*>() = 0;
|
2022-07-10 06:33:14 +08:00
|
|
|
|
|
|
|
// personal car flag
|
2022-11-21 15:42:12 +00:00
|
|
|
*scr_globals::spawn_global.at(27).at(94).as<int32_t*>() = 14;
|
|
|
|
*scr_globals::spawn_global.at(27).at(95).as<int32_t*>() = 2;
|
2022-07-10 06:33:14 +08:00
|
|
|
|
|
|
|
// mmi
|
2022-11-21 15:42:12 +00:00
|
|
|
*scr_globals::spawn_global.at(27).at(103).as<int32_t*>() = 0;
|
2022-07-10 06:33:14 +08:00
|
|
|
|
|
|
|
// spawn location
|
2022-11-21 15:42:12 +00:00
|
|
|
*scr_globals::spawn_global.at(7).at(0).as<float*>() = tmpLocation.x;
|
|
|
|
*scr_globals::spawn_global.at(7).at(1).as<float*>() = tmpLocation.y;
|
|
|
|
*scr_globals::spawn_global.at(7).at(2).as<float*>() = tmpLocation.z;
|
2022-07-10 06:33:14 +08:00
|
|
|
|
|
|
|
// spawn non pegasus
|
2022-11-21 15:42:12 +00:00
|
|
|
*scr_globals::spawn_global.at(3).as<int*>() = 0;
|
2022-07-10 06:33:14 +08:00
|
|
|
|
|
|
|
// spawn signal
|
2022-11-21 15:42:12 +00:00
|
|
|
int* spawn_signal = scr_globals::spawn_global.at(2).as<int32_t*>();
|
|
|
|
*scr_globals::spawn_global.at(5).as<int32_t*>() = 1;
|
2022-07-10 06:33:14 +08:00
|
|
|
*spawn_signal = 1;
|
|
|
|
|
|
|
|
// wait until the vehicle is spawned
|
|
|
|
for (size_t retry = 0; *spawn_signal != 0 && retry < 200; retry++)
|
|
|
|
{
|
|
|
|
script::get_current()->yield(10ms);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*spawn_signal == 1)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto veh = vehicle::get_closest_to_location(tmpLocation, 200);
|
2022-07-28 01:42:15 +08:00
|
|
|
if (veh == 0)
|
2022-07-10 06:33:14 +08:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ENTITY::SET_ENTITY_COORDS(veh, location.x, location.y, location.z + 1.f, 0, 0, 0, 0);
|
|
|
|
ENTITY::SET_ENTITY_HEADING(veh, heading);
|
|
|
|
|
|
|
|
return veh;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::map<int, int32_t> get_vehicle_data_from_vehicle_idx(script_global vehicle_idx)
|
|
|
|
{
|
|
|
|
std::map<int, int32_t> veh_data;
|
2021-05-19 11:27:47 +02:00
|
|
|
|
2022-07-10 06:33:14 +08:00
|
|
|
for (int i = 0; i < 142; i++)
|
|
|
|
{
|
|
|
|
veh_data[i] = *vehicle_idx.at(i).as<int32_t*>();
|
2021-05-19 11:27:47 +02:00
|
|
|
}
|
|
|
|
|
2022-07-28 01:42:15 +08:00
|
|
|
veh_data.erase(1); veh_data.erase(94); veh_data.erase(95); veh_data.erase(103);
|
2022-07-10 06:33:14 +08:00
|
|
|
|
|
|
|
return veh_data;
|
2021-05-19 11:27:47 +02:00
|
|
|
}
|
2022-03-21 17:05:13 -04:00
|
|
|
|
2022-07-28 01:42:15 +08:00
|
|
|
inline std::map<int, int32_t> get_owned_mods_from_vehicle_idx(script_global vehicle_idx)
|
2022-07-17 04:36:05 +08:00
|
|
|
{
|
|
|
|
std::map<int, int32_t> owned_mods;
|
|
|
|
|
2022-07-28 01:42:15 +08:00
|
|
|
for (int i = MOD_SECONDARY_CUSTOM; i <= MOD_MODEL_HASH; i++)
|
|
|
|
{
|
|
|
|
owned_mods[i] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t val_32 = *vehicle_idx.at(32).as<int32_t*>();
|
|
|
|
int32_t val_77 = *vehicle_idx.at(77).as<int32_t*>();
|
|
|
|
int32_t val_102 = *vehicle_idx.at(102).as<int32_t*>();
|
|
|
|
|
|
|
|
|
|
|
|
owned_mods[MOD_MODEL_HASH] = *vehicle_idx.at(66).as<int32_t*>();
|
|
|
|
|
|
|
|
owned_mods[MOD_PLATE_STYLE] = *vehicle_idx.at(0).as<int32_t*>();
|
|
|
|
owned_mods[MOD_WINDOW_TINT] = *vehicle_idx.at(65).as<int32_t*>();
|
|
|
|
owned_mods[MOD_WHEEL_TYPE] = *vehicle_idx.at(69).as<int32_t*>();
|
|
|
|
|
|
|
|
|
|
|
|
owned_mods[MOD_PRIMARY_COL] = *vehicle_idx.at(5).as<int32_t*>();
|
|
|
|
owned_mods[MOD_SECONDARY_COL] = *vehicle_idx.at(6).as<int32_t*>();
|
|
|
|
owned_mods[MOD_PEARLESCENT_COL] = *vehicle_idx.at(7).as<int32_t*>();
|
|
|
|
owned_mods[MOD_WHEEL_COL] = *vehicle_idx.at(8).as<int32_t*>();
|
|
|
|
owned_mods[MOD_INTERIOR_COL] = *vehicle_idx.at(97).as<int32_t*>();
|
|
|
|
owned_mods[MOD_DASHBOARD_COL] = *vehicle_idx.at(99).as<int32_t*>();
|
|
|
|
|
|
|
|
|
|
|
|
//CUSTOM PRIMARY
|
|
|
|
owned_mods[MOD_PRIMARY_CUSTOM] = (val_77 & (1 << 13)) != 0;
|
|
|
|
if (owned_mods[MOD_PRIMARY_CUSTOM])
|
|
|
|
{
|
|
|
|
owned_mods[MOD_PRIMARY_COL_R] = *vehicle_idx.at(71).as<int32_t*>();
|
|
|
|
owned_mods[MOD_PRIMARY_COL_G] = *vehicle_idx.at(72).as<int32_t*>();
|
|
|
|
owned_mods[MOD_PRIMARY_COL_B] = *vehicle_idx.at(73).as<int32_t*>();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//CUSTOM SECONDARY
|
|
|
|
owned_mods[MOD_SECONDARY_CUSTOM] = (val_77 & (1 << 12)) != 0;
|
|
|
|
if (owned_mods[MOD_SECONDARY_CUSTOM])
|
|
|
|
{
|
|
|
|
owned_mods[MOD_SECONDARY_COL_R] = *vehicle_idx.at(71).as<int32_t*>();
|
|
|
|
owned_mods[MOD_SECONDARY_COL_G] = *vehicle_idx.at(72).as<int32_t*>();
|
|
|
|
owned_mods[MOD_SECONDARY_COL_B] = *vehicle_idx.at(73).as<int32_t*>();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TIRE SMOKE
|
|
|
|
owned_mods[MOD_TIRESMOKE_COL_R] = *vehicle_idx.at(62).as<int32_t*>();
|
|
|
|
owned_mods[MOD_TIRESMOKE_COL_G] = *vehicle_idx.at(63).as<int32_t*>();
|
|
|
|
owned_mods[MOD_TIRESMOKE_COL_B] = *vehicle_idx.at(64).as<int32_t*>();
|
|
|
|
owned_mods[MOD_TYRE_SMOKE] = !(
|
|
|
|
owned_mods[MOD_TIRESMOKE_COL_R] == 255 &&
|
|
|
|
owned_mods[MOD_TIRESMOKE_COL_G] == 255 &&
|
|
|
|
owned_mods[MOD_TIRESMOKE_COL_B] == 255
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// XENON
|
|
|
|
if (val_32 > 0)
|
|
|
|
{
|
|
|
|
owned_mods[MOD_XENON_LIGHTS] = 1;
|
|
|
|
owned_mods[MOD_XENON_COL] = val_32 - 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
owned_mods[MOD_XENON_LIGHTS] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NEON
|
|
|
|
owned_mods[MOD_NEON_LEFT_ON] = (val_77 & (1 << 30)) != 0;
|
|
|
|
owned_mods[MOD_NEON_RIGHT_ON] = (val_77 & (1 << 31)) != 0;
|
|
|
|
owned_mods[MOD_NEON_FRONT_ON] = (val_77 & (1 << 28)) != 0;
|
|
|
|
owned_mods[MOD_NEON_BACK_ON] = (val_77 & (1 << 29)) != 0;
|
|
|
|
owned_mods[MOD_NEON_COL_R] = *vehicle_idx.at(74).as<int32_t*>();
|
|
|
|
owned_mods[MOD_NEON_COL_G] = *vehicle_idx.at(75).as<int32_t*>();
|
|
|
|
owned_mods[MOD_NEON_COL_B] = *vehicle_idx.at(76).as<int32_t*>();
|
|
|
|
|
|
|
|
// TIRE OPTIONS
|
|
|
|
owned_mods[MOD_TIRE_CAN_BURST] = (val_77 & (1 << 9)) == 0;
|
|
|
|
if ((val_102 & 0b11) == 0b11)
|
|
|
|
{
|
|
|
|
owned_mods[MOD_DRIFT_TIRE] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
owned_mods[MOD_TURBO] = *vehicle_idx.at(28).as<int32_t*>() != 0;
|
|
|
|
|
|
|
|
owned_mods[MOD_FRONTWHEEL_VAR] = *vehicle_idx.at(60).as<int32_t*>() != 0;
|
|
|
|
owned_mods[MOD_REARWHEEL_VAR] = *vehicle_idx.at(61).as<int32_t*>() != 0;
|
|
|
|
|
|
|
|
|
|
|
|
// OTHER MODS
|
|
|
|
for (int slot = MOD_SPOILERS; slot <= MOD_LIGHTBAR; slot++)
|
|
|
|
{
|
|
|
|
if (slot == MOD_TURBO || slot == MOD_TYRE_SMOKE || slot == MOD_XENON_LIGHTS)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t val = *vehicle_idx.at(10 + slot).as<int32_t*>() - 1;
|
|
|
|
if (val != -1)
|
|
|
|
{
|
|
|
|
owned_mods[slot] = val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// EXTRA
|
|
|
|
for (int extra = MOD_EXTRA_9; extra <= MOD_EXTRA_1; extra++)
|
|
|
|
{
|
|
|
|
int gta_extra_id = (extra - MOD_EXTRA_0) * -1;
|
|
|
|
owned_mods[extra] = val_77 >> (gta_extra_id - 1) & 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return owned_mods;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline Vehicle clone_from_owned_mods(std::map<int, int32_t> owned_mods, Vector3 location, float heading, bool is_networked = true)
|
|
|
|
{
|
|
|
|
auto vehicle = spawn(owned_mods[MOD_MODEL_HASH], location, heading, is_networked);
|
|
|
|
if (vehicle == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2022-07-17 04:36:05 +08:00
|
|
|
|
|
|
|
for (int i = MOD_NEON_COL_B; i <= MOD_MODEL_HASH; i++)
|
|
|
|
{
|
2022-07-28 01:42:15 +08:00
|
|
|
if (owned_mods.count(i) == 0)
|
|
|
|
{
|
|
|
|
owned_mods[i] = 0;
|
|
|
|
}
|
2022-07-17 04:36:05 +08:00
|
|
|
}
|
|
|
|
|
2022-07-28 01:42:15 +08:00
|
|
|
VEHICLE::SET_VEHICLE_MOD_KIT(vehicle, 0);
|
|
|
|
script::get_current()->yield(10ms);
|
|
|
|
|
|
|
|
VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(vehicle, owned_mods[MOD_PLATE_STYLE]);
|
|
|
|
VEHICLE::SET_VEHICLE_WINDOW_TINT(vehicle, owned_mods[MOD_WINDOW_TINT]);
|
|
|
|
VEHICLE::SET_VEHICLE_WHEEL_TYPE(vehicle, owned_mods[MOD_WHEEL_TYPE]);
|
|
|
|
script::get_current()->yield(10ms);
|
|
|
|
|
|
|
|
VEHICLE::SET_VEHICLE_COLOURS(vehicle, owned_mods[MOD_PRIMARY_COL], owned_mods[MOD_SECONDARY_COL]);
|
|
|
|
VEHICLE::SET_VEHICLE_EXTRA_COLOURS(vehicle, owned_mods[MOD_PEARLESCENT_COL], owned_mods[MOD_WHEEL_COL]);
|
2022-09-20 14:03:19 +01:00
|
|
|
VEHICLE::SET_VEHICLE_EXTRA_COLOUR_5(vehicle, owned_mods[MOD_INTERIOR_COL]);
|
|
|
|
VEHICLE::SET_VEHICLE_EXTRA_COLOUR_6(vehicle, owned_mods[MOD_DASHBOARD_COL]);
|
2022-07-28 01:42:15 +08:00
|
|
|
|
|
|
|
if (owned_mods[MOD_PRIMARY_CUSTOM])
|
2022-07-17 04:36:05 +08:00
|
|
|
{
|
2022-07-28 01:42:15 +08:00
|
|
|
VEHICLE::SET_VEHICLE_CUSTOM_PRIMARY_COLOUR(
|
|
|
|
vehicle, owned_mods[MOD_PRIMARY_COL_R],
|
|
|
|
owned_mods[MOD_PRIMARY_COL_G], owned_mods[MOD_PRIMARY_COL_B]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (owned_mods[MOD_SECONDARY_CUSTOM])
|
|
|
|
{
|
|
|
|
VEHICLE::SET_VEHICLE_CUSTOM_SECONDARY_COLOUR(
|
|
|
|
vehicle, owned_mods[MOD_SECONDARY_COL_R],
|
|
|
|
owned_mods[MOD_SECONDARY_COL_G], owned_mods[MOD_SECONDARY_COL_B]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (owned_mods[MOD_TYRE_SMOKE])
|
|
|
|
{
|
|
|
|
VEHICLE::SET_VEHICLE_TYRE_SMOKE_COLOR(
|
|
|
|
vehicle, owned_mods[MOD_TIRESMOKE_COL_R],
|
|
|
|
owned_mods[MOD_TIRESMOKE_COL_G], owned_mods[MOD_TIRESMOKE_COL_B]
|
|
|
|
);
|
|
|
|
VEHICLE::TOGGLE_VEHICLE_MOD(vehicle, MOD_TYRE_SMOKE, owned_mods[MOD_TYRE_SMOKE]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (owned_mods[MOD_XENON_LIGHTS])
|
|
|
|
{
|
2022-09-20 14:03:19 +01:00
|
|
|
VEHICLE::SET_VEHICLE_XENON_LIGHT_COLOR_INDEX(vehicle, owned_mods[MOD_XENON_COL]);
|
2022-07-28 01:42:15 +08:00
|
|
|
VEHICLE::TOGGLE_VEHICLE_MOD(vehicle, MOD_XENON_LIGHTS, owned_mods[MOD_XENON_LIGHTS]);
|
|
|
|
}
|
|
|
|
|
2022-09-20 14:03:19 +01:00
|
|
|
VEHICLE::SET_VEHICLE_NEON_COLOUR(
|
2022-07-28 01:42:15 +08:00
|
|
|
vehicle, owned_mods[MOD_NEON_COL_R],
|
|
|
|
owned_mods[MOD_NEON_COL_G], owned_mods[MOD_NEON_COL_B]
|
|
|
|
);
|
2022-09-20 14:03:19 +01:00
|
|
|
VEHICLE::SET_VEHICLE_NEON_ENABLED(vehicle, NEON_LEFT, owned_mods[MOD_NEON_LEFT_ON]);
|
|
|
|
VEHICLE::SET_VEHICLE_NEON_ENABLED(vehicle, NEON_RIGHT, owned_mods[MOD_NEON_RIGHT_ON]);
|
|
|
|
VEHICLE::SET_VEHICLE_NEON_ENABLED(vehicle, NEON_FRONT, owned_mods[MOD_NEON_FRONT_ON]);
|
|
|
|
VEHICLE::SET_VEHICLE_NEON_ENABLED(vehicle, NEON_BACK, owned_mods[MOD_NEON_BACK_ON]);
|
2022-07-28 01:42:15 +08:00
|
|
|
|
|
|
|
|
|
|
|
VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(vehicle, owned_mods[MOD_TIRE_CAN_BURST]);
|
2022-09-20 14:03:19 +01:00
|
|
|
VEHICLE::SET_DRIFT_TYRES(vehicle, owned_mods[MOD_DRIFT_TIRE]);
|
2022-07-28 01:42:15 +08:00
|
|
|
VEHICLE::TOGGLE_VEHICLE_MOD(vehicle, MOD_TURBO, owned_mods[MOD_TURBO]);
|
|
|
|
|
|
|
|
for (int slot = MOD_SPOILERS; slot <= MOD_LIGHTBAR; slot++)
|
|
|
|
{
|
|
|
|
if (owned_mods.count(slot) && owned_mods[slot] != -1)
|
|
|
|
{
|
|
|
|
bool custom_tire = false;
|
|
|
|
|
|
|
|
if (slot == MOD_FRONTWHEEL)
|
|
|
|
{
|
|
|
|
custom_tire = owned_mods[MOD_FRONTWHEEL_VAR];
|
|
|
|
}
|
|
|
|
else if (slot == MOD_REARWHEEL)
|
|
|
|
{
|
|
|
|
custom_tire = owned_mods[MOD_REARWHEEL_VAR];
|
|
|
|
}
|
|
|
|
|
|
|
|
VEHICLE::SET_VEHICLE_MOD(vehicle, slot, owned_mods[slot], custom_tire);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int extra = MOD_EXTRA_14; extra <= MOD_EXTRA_1; extra++)
|
|
|
|
{
|
|
|
|
int gta_extra_id = (extra - MOD_EXTRA_0) * -1;
|
|
|
|
if (owned_mods.count(extra) && VEHICLE::DOES_EXTRA_EXIST(vehicle, gta_extra_id))
|
2022-07-17 04:36:05 +08:00
|
|
|
{
|
2022-07-28 01:42:15 +08:00
|
|
|
VEHICLE::SET_VEHICLE_EXTRA(vehicle, gta_extra_id, owned_mods[extra] == 0);
|
2022-07-17 04:36:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-28 01:42:15 +08:00
|
|
|
return vehicle;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::map<int, int32_t> get_owned_mods_from_vehicle(Vehicle vehicle)
|
|
|
|
{
|
|
|
|
std::map<int, int32_t> owned_mods;
|
|
|
|
|
|
|
|
for (int i = MOD_SECONDARY_CUSTOM; i <= MOD_MODEL_HASH; i++)
|
|
|
|
{
|
|
|
|
owned_mods[i] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
owned_mods[MOD_MODEL_HASH] = ENTITY::GET_ENTITY_MODEL(vehicle);
|
|
|
|
|
2022-07-17 04:36:05 +08:00
|
|
|
owned_mods[MOD_PLATE_STYLE] = VEHICLE::GET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(vehicle);
|
|
|
|
owned_mods[MOD_WINDOW_TINT] = VEHICLE::GET_VEHICLE_WINDOW_TINT(vehicle);
|
|
|
|
owned_mods[MOD_WHEEL_TYPE] = VEHICLE::GET_VEHICLE_WHEEL_TYPE(vehicle);
|
|
|
|
|
|
|
|
VEHICLE::GET_VEHICLE_COLOURS(vehicle, &owned_mods[MOD_PRIMARY_COL], &owned_mods[MOD_SECONDARY_COL]);
|
|
|
|
VEHICLE::GET_VEHICLE_EXTRA_COLOURS(vehicle, &owned_mods[MOD_PEARLESCENT_COL], &owned_mods[MOD_WHEEL_COL]);
|
2022-09-20 14:03:19 +01:00
|
|
|
VEHICLE::GET_VEHICLE_EXTRA_COLOUR_5(vehicle, &owned_mods[MOD_INTERIOR_COL]);
|
|
|
|
VEHICLE::GET_VEHICLE_EXTRA_COLOUR_6(vehicle, &owned_mods[MOD_DASHBOARD_COL]);
|
2022-07-17 04:36:05 +08:00
|
|
|
|
2022-07-28 01:42:15 +08:00
|
|
|
owned_mods[MOD_PRIMARY_CUSTOM] = VEHICLE::GET_IS_VEHICLE_PRIMARY_COLOUR_CUSTOM(vehicle);
|
|
|
|
if (owned_mods[MOD_PRIMARY_CUSTOM])
|
|
|
|
{
|
|
|
|
VEHICLE::GET_VEHICLE_CUSTOM_PRIMARY_COLOUR(
|
|
|
|
vehicle, &owned_mods[MOD_PRIMARY_COL_R],
|
|
|
|
&owned_mods[MOD_PRIMARY_COL_G], &owned_mods[MOD_PRIMARY_COL_B]
|
|
|
|
);
|
|
|
|
}
|
2022-07-17 04:36:05 +08:00
|
|
|
|
2022-07-28 01:42:15 +08:00
|
|
|
owned_mods[MOD_SECONDARY_CUSTOM] = VEHICLE::GET_IS_VEHICLE_SECONDARY_COLOUR_CUSTOM(vehicle);
|
|
|
|
if (owned_mods[MOD_SECONDARY_CUSTOM])
|
|
|
|
{
|
|
|
|
VEHICLE::GET_VEHICLE_CUSTOM_SECONDARY_COLOUR(
|
|
|
|
vehicle, &owned_mods[MOD_SECONDARY_COL_R],
|
|
|
|
&owned_mods[MOD_SECONDARY_COL_G], &owned_mods[MOD_SECONDARY_COL_B]
|
|
|
|
);
|
|
|
|
}
|
2022-07-17 04:36:05 +08:00
|
|
|
|
|
|
|
owned_mods[MOD_TYRE_SMOKE] = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, MOD_TYRE_SMOKE);
|
2022-07-28 01:42:15 +08:00
|
|
|
if (owned_mods[MOD_TYRE_SMOKE])
|
|
|
|
{
|
|
|
|
VEHICLE::GET_VEHICLE_TYRE_SMOKE_COLOR(
|
|
|
|
vehicle, &owned_mods[MOD_TIRESMOKE_COL_R],
|
|
|
|
&owned_mods[MOD_TIRESMOKE_COL_G], &owned_mods[MOD_TIRESMOKE_COL_B]
|
|
|
|
);
|
|
|
|
}
|
2022-07-17 04:36:05 +08:00
|
|
|
|
|
|
|
owned_mods[MOD_XENON_LIGHTS] = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, MOD_XENON_LIGHTS);
|
2022-07-28 01:42:15 +08:00
|
|
|
if (owned_mods[MOD_XENON_LIGHTS])
|
|
|
|
{
|
2022-09-20 14:03:19 +01:00
|
|
|
owned_mods[MOD_XENON_COL] = (int8_t)VEHICLE::GET_VEHICLE_XENON_LIGHT_COLOR_INDEX(vehicle);
|
2022-07-28 01:42:15 +08:00
|
|
|
}
|
|
|
|
|
2022-09-20 14:03:19 +01:00
|
|
|
owned_mods[MOD_NEON_LEFT_ON] = VEHICLE::GET_VEHICLE_NEON_ENABLED(vehicle, NEON_LEFT);
|
|
|
|
owned_mods[MOD_NEON_RIGHT_ON] = VEHICLE::GET_VEHICLE_NEON_ENABLED(vehicle, NEON_RIGHT);
|
|
|
|
owned_mods[MOD_NEON_FRONT_ON] = VEHICLE::GET_VEHICLE_NEON_ENABLED(vehicle, NEON_FRONT);
|
|
|
|
owned_mods[MOD_NEON_BACK_ON] = VEHICLE::GET_VEHICLE_NEON_ENABLED(vehicle, NEON_BACK);
|
|
|
|
VEHICLE::GET_VEHICLE_NEON_COLOUR(
|
2022-07-28 01:42:15 +08:00
|
|
|
vehicle, &owned_mods[MOD_NEON_COL_R],
|
|
|
|
&owned_mods[MOD_NEON_COL_G], &owned_mods[MOD_NEON_COL_B]
|
|
|
|
);
|
|
|
|
|
|
|
|
owned_mods[MOD_TIRE_CAN_BURST] = VEHICLE::GET_VEHICLE_TYRES_CAN_BURST(vehicle);
|
2022-09-20 14:03:19 +01:00
|
|
|
owned_mods[MOD_DRIFT_TIRE] = VEHICLE::GET_DRIFT_TYRES_SET(vehicle);
|
2022-07-28 01:42:15 +08:00
|
|
|
owned_mods[MOD_TURBO] = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, MOD_TURBO);
|
2022-07-17 04:36:05 +08:00
|
|
|
|
|
|
|
owned_mods[MOD_FRONTWHEEL_VAR] = VEHICLE::GET_VEHICLE_MOD_VARIATION(vehicle, MOD_FRONTWHEEL);
|
|
|
|
owned_mods[MOD_REARWHEEL_VAR] = VEHICLE::GET_VEHICLE_MOD_VARIATION(vehicle, MOD_REARWHEEL);
|
|
|
|
|
2022-07-28 01:42:15 +08:00
|
|
|
for (int slot = MOD_SPOILERS; slot <= MOD_LIGHTBAR; slot++)
|
|
|
|
{
|
|
|
|
int count = VEHICLE::GET_NUM_VEHICLE_MODS(vehicle, slot);
|
|
|
|
if (count > 0)
|
|
|
|
{
|
|
|
|
int32_t val = VEHICLE::GET_VEHICLE_MOD(vehicle, slot);
|
|
|
|
|
|
|
|
if (val != -1)
|
|
|
|
{
|
|
|
|
owned_mods[slot] = val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int extra = MOD_EXTRA_14; extra <= MOD_EXTRA_1; extra++)
|
|
|
|
{
|
|
|
|
int gta_extra_id = (extra - MOD_EXTRA_0) * -1;
|
|
|
|
if (VEHICLE::DOES_EXTRA_EXIST(vehicle, gta_extra_id))
|
|
|
|
{
|
|
|
|
owned_mods[extra] = VEHICLE::IS_VEHICLE_EXTRA_TURNED_ON(vehicle, gta_extra_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-17 04:36:05 +08:00
|
|
|
return owned_mods;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void teleport_into_vehicle(Vehicle veh)
|
2022-03-21 17:05:13 -04:00
|
|
|
{
|
2022-05-23 06:38:45 +08:00
|
|
|
PED::SET_PED_INTO_VEHICLE(self::ped, veh, -1);
|
2022-03-21 17:05:13 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
inline void max_vehicle(Vehicle veh)
|
|
|
|
{
|
2022-07-17 04:36:05 +08:00
|
|
|
Hash model = ENTITY::GET_ENTITY_MODEL(veh);
|
|
|
|
|
2022-03-21 17:05:13 -04:00
|
|
|
VEHICLE::SET_VEHICLE_MOD_KIT(veh, 0);
|
2022-07-28 01:42:15 +08:00
|
|
|
|
|
|
|
VEHICLE::TOGGLE_VEHICLE_MOD(veh, MOD_TURBO, TRUE);
|
|
|
|
VEHICLE::TOGGLE_VEHICLE_MOD(veh, MOD_TYRE_SMOKE, TRUE);
|
|
|
|
VEHICLE::TOGGLE_VEHICLE_MOD(veh, MOD_XENON_LIGHTS, TRUE);
|
2022-03-21 17:05:13 -04:00
|
|
|
VEHICLE::SET_VEHICLE_WINDOW_TINT(veh, 1);
|
2022-03-23 13:45:54 -04:00
|
|
|
VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(veh, false);
|
2022-07-10 06:33:14 +08:00
|
|
|
|
2022-07-28 01:42:15 +08:00
|
|
|
for (int slot = MOD_SPOILERS; slot <= MOD_LIGHTBAR; slot++)
|
2022-03-21 17:05:13 -04:00
|
|
|
{
|
2022-07-17 04:36:05 +08:00
|
|
|
if (slot == MOD_LIVERY) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int count = VEHICLE::GET_NUM_VEHICLE_MODS(veh, slot);
|
|
|
|
if (count > 0)
|
|
|
|
{
|
|
|
|
int selected_mod = -1;
|
|
|
|
|
|
|
|
for (int mod = count - 1; mod >= -1; mod--)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (vehicle_helper::check_mod_blacklist(model, slot, mod))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
selected_mod = mod;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected_mod != -1)
|
|
|
|
{
|
|
|
|
VEHICLE::SET_VEHICLE_MOD(veh, slot, selected_mod, true);
|
|
|
|
}
|
2022-07-10 06:33:14 +08:00
|
|
|
}
|
2022-03-21 17:05:13 -04:00
|
|
|
}
|
|
|
|
}
|
2022-11-11 11:51:40 -06:00
|
|
|
|
|
|
|
inline void set_engine_state(Vehicle current_vehicle, bool state, bool immediately, bool disable_auto_start)
|
|
|
|
{
|
|
|
|
if (current_vehicle)
|
|
|
|
VEHICLE::SET_VEHICLE_ENGINE_ON(current_vehicle, state, immediately, disable_auto_start);
|
|
|
|
else
|
|
|
|
return g_notification_service->push_warning("Vehicle", "Please be in a car first then try again.");
|
|
|
|
}
|
2022-11-21 15:42:12 +00:00
|
|
|
|
|
|
|
inline bool remote_control_vehicle(Vehicle veh)
|
|
|
|
{
|
|
|
|
if (!entity::take_control_of(veh, 4000))
|
|
|
|
{
|
|
|
|
g_notification_service->push_warning("Remote Control", "Failed to take control of remote vehicle");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-12-18 23:15:52 +01:00
|
|
|
if (g.m_remote_controlled_vehicle == veh)
|
2022-11-21 15:42:12 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Hash model = ENTITY::GET_ENTITY_MODEL(veh);
|
|
|
|
Vehicle spawned = vehicle::spawn(model, self::pos, 0.0f);
|
|
|
|
|
|
|
|
ENTITY::SET_ENTITY_ALPHA(spawned, 0, FALSE);
|
|
|
|
if (!VEHICLE::IS_THIS_MODEL_A_BIKE(model))
|
|
|
|
ENTITY::SET_ENTITY_VISIBLE(spawned, FALSE, FALSE);
|
|
|
|
ENTITY::SET_ENTITY_INVINCIBLE(spawned, TRUE);
|
|
|
|
|
|
|
|
float heading = ENTITY::GET_ENTITY_HEADING(veh);
|
|
|
|
Vector3 rotation = ENTITY::GET_ENTITY_ROTATION(veh, 2);
|
|
|
|
Vector3 coords = ENTITY::GET_ENTITY_COORDS(veh, FALSE);
|
|
|
|
Vector3 velocity = ENTITY::GET_ENTITY_VELOCITY(veh);
|
|
|
|
|
|
|
|
ENTITY::SET_ENTITY_COORDS_NO_OFFSET(spawned, coords.x, coords.y, coords.z, FALSE, FALSE, FALSE);
|
|
|
|
ENTITY::SET_ENTITY_HEADING(spawned, heading);
|
|
|
|
ENTITY::SET_ENTITY_ROTATION(spawned, rotation.x, rotation.y, rotation.z, 2, TRUE);
|
|
|
|
|
|
|
|
ENTITY::SET_ENTITY_VISIBLE(veh, TRUE, FALSE);
|
|
|
|
|
|
|
|
ENTITY::SET_ENTITY_COLLISION(veh, FALSE, FALSE);
|
|
|
|
ENTITY::SET_ENTITY_INVINCIBLE(veh, TRUE);
|
|
|
|
VEHICLE::SET_VEHICLE_DOORS_LOCKED(veh, 4);
|
|
|
|
VEHICLE::SET_VEHICLE_MAX_SPEED(veh, 0.0001f);
|
|
|
|
ENTITY::ATTACH_ENTITY_TO_ENTITY(veh, spawned, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, FALSE, FALSE, FALSE, FALSE, 0, TRUE, FALSE);
|
|
|
|
PED::SET_PED_INTO_VEHICLE(PLAYER::PLAYER_PED_ID(), spawned, -1);
|
|
|
|
|
|
|
|
VEHICLE::SET_VEHICLE_ENGINE_ON(spawned, TRUE, TRUE, FALSE);
|
|
|
|
ENTITY::SET_ENTITY_VELOCITY(spawned, velocity.x, velocity.y, velocity.z);
|
|
|
|
VEHICLE::COPY_VEHICLE_DAMAGES(veh, spawned);
|
|
|
|
|
2022-12-18 23:15:52 +01:00
|
|
|
g.m_remote_controller_vehicle = spawned;
|
|
|
|
g.m_remote_controlled_vehicle = veh;
|
2022-11-21 15:42:12 +00:00
|
|
|
return true;
|
|
|
|
}
|
2022-05-24 15:59:25 -04:00
|
|
|
}
|