CheatMenuSA/moonloader/lib/cheat-menu/modules/vehicle.lua
2020-12-03 03:18:34 +06:00

1459 lines
68 KiB
Lua

-- Cheat Menu - Cheat menu for Grand Theft Auto SanAndreas
-- Copyright (C) 2019-2020 Grinch_
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local module = {}
module.tvehicle =
{
aircraft =
{
camera = imgui.new.bool(fconfig.Get('tvehicle.aircraft.camera',false)),
index = fconfig.Get('tvehicle.aircraft.index',2),
spawn_in_air = imgui.new.bool(fconfig.Get('tvehicle.aircraft.spawn_in_air',true)),
zoom = { -5.0,-15.0,-20.0,-30.0,-40.0},
},
apply_material_filter = imgui.new.bool(fconfig.Get('tvehicle.apply_material_filter',true)),
car_engine = imgui.new.int(fconfig.Get('tvehicle.car_engine',fconst.CHECKBOX_STATE.NOT_CONFIGURED)),
color =
{
car_data_table = {},
col_data_table = {},
default = -1,
radio_btn = imgui.new.int(1),
rgb = imgui.new.float[3](0.0,0.0,0.0),
show_all = imgui.new.bool(fconfig.Get('tvehicle.color.show_all',false))
},
components =
{
enable_saving = imgui.new.bool(fconfig.Get('tvehicle.components.enable_saving',false)),
save_data = fconfig.Get('tvehicle.components.save_data',{}),
images = {},
list = {},
names = {},
path = tcheatmenu.dir .. "vehicles\\components\\",
saved = false,
selected = imgui.new.int(0),
value = imgui.new.int(0),
},
doors = {"Hood","Boot","Front left door","Front right door","Rear left door","Rear right door","All"},
door_menu_button = imgui.new.int(0),
first_person_camera =
{
bool = imgui.new.bool(fconfig.Get('tvehicle.first_person_camera.bool',false)),
offsets = fcommon.LoadJson("first person camera offsets"),
offset_x_var = imgui.new.float(0),
offset_y_var = imgui.new.float(0),
offset_z_var = imgui.new.float(0),
},
gxt_name = imgui.new.char[32](""),
gxt_name_table = fconfig.Get('tvehicle.gxt_name_table',{}),
handling_flags = fcommon.LoadJson("handling flags"),
handling_name = {},
heavy = imgui.new.bool(fconfig.Get('tvehicle.heavy',false)),
images = {},
invisible_car = imgui.new.bool(fconfig.Get('tvehicle.invisible_car',false)),
license_plate_text = imgui.new.char[9](fconfig.Get('tvehicle.license_plate_text',"GTA__SAN")),
lights = imgui.new.bool(fconfig.Get('tvehicle.lights',false)),
lock_doors = imgui.new.bool(false),
lock_speed = imgui.new.bool(fconfig.Get('tvehicle.lock_speed',false)),
max_velocity_temp = imgui.new.int(-1),
model_flags = fcommon.LoadJson("model flags"),
names = fcommon.LoadJson("vehicle"),
paintjobs =
{
cache_images = {},
current_paintjob = imgui.new.int(-1);
enable_saving = imgui.new.bool(fconfig.Get('tvehicle.paintjobs.enable_saving',false)),
save_data = fconfig.Get('tvehicle.paintjobs.save_data',{}),
names = 0,
path = tcheatmenu.dir .. "vehicles\\paintjobs",
paintjobs_count = 0,
images = {},
texture = nil
},
neon =
{
checkbox = imgui.new.bool(fconfig.Get('tvehicle.neon.checkbox',false)),
data = fcommon.LoadJson("neon data"),
rgb = imgui.new.float[3](0.0,0.0,0.0),
rb_value = imgui.new.int(-1),
},
no_vehicles = imgui.new.bool(fconfig.Get('tvehicle.no_vehicles',false)),
no_damage = imgui.new.bool(fconfig.Get('tvehicle.no_damage',false)),
path = tcheatmenu.dir .. "vehicles\\images",
rainbow_colors =
{
bool = imgui.new.bool(fconfig.Get('tvehicle.rainbow_colors.bool',false)),
traffic = imgui.new.bool(fconfig.Get('tvehicle.rainbow_colors.traffic',false)),
speed = imgui.new.float(fconfig.Get('tvehicle.rainbow_colors.speed',0.5)),
},
rainbow_neons =
{
bool = imgui.new.bool(fconfig.Get('tvehicle.rainbow_neons.bool',false)),
traffic = imgui.new.bool(fconfig.Get('tvehicle.rainbow_neons.traffic',false)),
speed = imgui.new.float(fconfig.Get('tvehicle.rainbow_neons.speed',0.5)),
},
spawn_inside = imgui.new.bool(fconfig.Get('tvehicle.spawn_inside',true)),
speed = imgui.new.int(fconfig.Get('tvehicle.speed',0)),
stay_on_bike = imgui.new.bool(fconfig.Get('tvehicle.stay_on_bike',false)),
trains =
{
["449"] = {8,9},
["537"] = {0,3,6,10,12,13},
["538"] = {1,5,15},
},
unlimited_nitro = imgui.new.bool(fconfig.Get('tvehicle.unlimited_nitro',false)),
visual_damage = imgui.new.bool(fconfig.Get('tvehicle.visual_damage',false)),
watertight_car = imgui.new.bool(fconfig.Get('tvehicle.watertight_car',false)),
}
--------------------------------------------------
-- Neon
result, handle = loadDynamicLibrary("neon_api.asi")
module.tvehicle.neon["Handle"] = handle
if module.tvehicle.neon["Handle"] ~= 0 then
result, proc = getDynamicLibraryProcedure("SetFlag",module.tvehicle.neon["Handle"])
module.tvehicle.neon["SetFlag"] = proc
result, proc = getDynamicLibraryProcedure("GetFlag",module.tvehicle.neon["Handle"])
module.tvehicle.neon["GetFlag"] = proc
result, proc = getDynamicLibraryProcedure("SetX",module.tvehicle.neon["Handle"])
module.tvehicle.neon["SetX"] = proc
result, proc = getDynamicLibraryProcedure("SetY",module.tvehicle.neon["Handle"])
module.tvehicle.neon["SetY"] = proc
result, proc = getDynamicLibraryProcedure("InstallNeon",module.tvehicle.neon["Handle"])
module.tvehicle.neon["InstallNeon"] = proc
result, proc = getDynamicLibraryProcedure("SetRed",module.tvehicle.neon["Handle"])
module.tvehicle.neon["SetRed"] = proc
result, proc = getDynamicLibraryProcedure("SetGreen",module.tvehicle.neon["Handle"])
module.tvehicle.neon["SetGreen"] = proc
result, proc = getDynamicLibraryProcedure("SetBlue",module.tvehicle.neon["Handle"])
module.tvehicle.neon["SetBlue"] = proc
end
function InstallNeon(car,color)
car = car or getCarCharIsUsing(PLAYER_PED)
local pveh = getCarPointer(car)
if module.tvehicle.neon["Handle"] ~= 0 then
if module.tvehicle.neon["InstallNeon"] and module.tvehicle.neon["SetX"] and module.tvehicle.neon["SetY"] then
callFunction(module.tvehicle.neon["InstallNeon"],3,3,pveh,0,0)
local data = module.tvehicle.neon.data[casts.CModelInfo.GetNameFromModel(getCarModel(car))] or { X = 0.0, Y = 0.0}
callFunction(module.tvehicle.neon["SetX"],2,2,pveh,data.X)
callFunction(module.tvehicle.neon["SetY"],2,2,pveh,data.Y)
callFunction(module.tvehicle.neon["SetRed"],2,2,pveh,color[1])
callFunction(module.tvehicle.neon["SetGreen"],2,2,pveh,color[2])
callFunction(module.tvehicle.neon["SetBlue"],2,2,pveh,color[3])
if module.tvehicle.paintjobs.enable_saving[0] then
fconfig.Set(module.tvehicle.paintjobs.save_data,string.format("%d.neon.red",getCarModel(car)),color[1])
fconfig.Set(module.tvehicle.paintjobs.save_data,string.format("%d.neon.green",getCarModel(car)),color[2])
fconfig.Set(module.tvehicle.paintjobs.save_data,string.format("%d.neon.blue",getCarModel(car)),color[3])
end
end
end
end
function module.TrafficNeons()
while module.tvehicle.neon.checkbox[0] and module.tvehicle.neon["Handle"] ~= 0 do
for hveh in fcommon.pool("veh") do
local temp = 0
if getVehicleClass(hveh) == fconst.VEHICLE_CLASS.NORMAL then
temp = math.random(1,20) -- 5%
end
if getVehicleClass(hveh) == fconst.VEHICLE_CLASS.RICH_FAMILY then
temp = math.random(1,5) -- 20%
end
if getVehicleClass(hveh) == fconst.VEHICLE_CLASS.EXECUTIVE then
temp = math.random(1,3) -- 30%
end
if temp == 1 and callFunction(module.tvehicle.neon["GetFlag"],1,1,hveh) ~= 0x10 then
if getCarCharIsUsing(PLAYER_PED) ~= hveh then
InstallNeon(hveh,{math.random(0,255),math.random(0,255),math.random(0,255)})
end
end
callFunction(module.tvehicle.neon["SetFlag"],2,2,hveh,0x10)
end
wait(100)
end
end
--------------------------------------------------
function module.GiveVehicleToPlayer(model)
model = tonumber(model)
local vehicle = nil
local interior = getCharActiveInterior(PLAYER_PED)
if isModelAvailable(model) then
local x,y,z = getCharCoordinates(PLAYER_PED)
local speed = 0
if isCharInAnyCar(PLAYER_PED) and module.tvehicle.spawn_inside[0] then
local hveh = getCarCharIsUsing(PLAYER_PED)
speed = getCarSpeed(hveh)
warpCharFromCarToCoord(PLAYER_PED,x,y,z)
if casts.CModelInfo.IsTrainModel(model) then
deleteMissionTrain(hveh)
else
deleteCar(hveh)
end
end
if interior == 0 then
if (module.tvehicle.aircraft.spawn_in_air[0]) and (isThisModelAHeli(model) or isThisModelAPlane(model)) then
z = 400
end
else
z = z - 5
end
if casts.CModelInfo.IsTrainModel(model) then
local train_id_table = module.tvehicle.trains[tostring(model)]
local train_id = train_id_table[math.random(1,#train_id_table)]
-- Loading all train related models
requestModel(590)
requestModel(538)
requestModel(570)
requestModel(569)
requestModel(537)
requestModel(449)
loadAllModelsNow()
if math.random(0,1) == 0 then
vehicle = createMissionTrain(train_id,x,y,z)
else
vehicle = createMissionTrain(train_id,x,y,z,true)
end
deleteChar(getDriverOfCar(vehicle))
if module.tvehicle.spawn_inside[0] then
warpCharIntoCar(PLAYER_PED,vehicle)
setTrainCruiseSpeed(vehicle,speed)
end
markMissionTrainAsNoLongerNeeded(vehicle)
markModelAsNoLongerNeeded(590)
markModelAsNoLongerNeeded(538)
markModelAsNoLongerNeeded(570)
markModelAsNoLongerNeeded(569)
markModelAsNoLongerNeeded(537)
markModelAsNoLongerNeeded(449)
else
requestModel(model)
loadAllModelsNow()
customPlateForNextCar(model,ffi.string(module.tvehicle.license_plate_text))
if not module.tvehicle.spawn_inside[0] then
vehicle = spawnVehicleByCheating(model)
else
vehicle = createCar(model,x,y,z)
setCarHeading(vehicle,getCharHeading(PLAYER_PED))
warpCharIntoCar(PLAYER_PED,vehicle)
setCarForwardSpeed(vehicle,speed)
end
markCarAsNoLongerNeeded(vehicle)
markModelAsNoLongerNeeded(model)
end
if doesVehicleExist(vehicle) then
setVehicleInterior(vehicle,interior)
end
fcommon.CheatActivated()
end
end
--------------------------------------------------
-- Camera
function module.AircraftCamera()
if module.tvehicle.aircraft.camera[0] then
if isCharInAnyHeli(PLAYER_PED)
or isCharInAnyPlane(PLAYER_PED) then
while isCharInAnyHeli(PLAYER_PED)
or isCharInAnyPlane(PLAYER_PED) do
-- FirstPersonCamera controls the camera if its enabled
if module.tvehicle.aircraft.camera[0] == false or module.tvehicle.first_person_camera.bool[0] then break end
local vehicle = getCarCharIsUsing(PLAYER_PED)
local roll = getCarRoll(vehicle)
attachCameraToVehicle(vehicle,0.0,module.tvehicle.aircraft.zoom[module.tvehicle.aircraft.index],2.5,0.0,0.0,0.0,(roll*-1),2)
if isKeyDown(0x56) then
while isKeyDown(0x56) do
wait(0)
end
module.tvehicle.aircraft.index = module.tvehicle.aircraft.index + 1
if module.tvehicle.aircraft.index > #module.tvehicle.aircraft.zoom then
module.tvehicle.aircraft.index = 0
end
end
wait(0)
end
restoreCameraJumpcut()
end
end
end
function module.FirstPersonCamera()
local total_x = 0
local total_y = 0
if module.tvehicle.first_person_camera.bool[0] and not isCharOnFoot(PLAYER_PED) and not fgame.tgame.camera.bool[0] then
while module.tvehicle.first_person_camera.bool[0] and not isCharOnFoot(PLAYER_PED) and not fgame.tgame.camera.bool[0] do
local hveh = getCarCharIsUsing(PLAYER_PED)
x,y = getPcMouseMovement()
total_x = total_x + x
total_y = total_y + y
local roll = 0.0
if module.tvehicle.aircraft.camera[0] == true then -- check if new aircraft camera is enabled
roll = getCarRoll(hveh)
end
if fgame.tgame.camera.bool[0] then
break
end
attachCameraToChar(PLAYER_PED,module.tvehicle.first_person_camera.offset_x_var[0], module.tvehicle.first_person_camera.offset_y_var[0], module.tvehicle.first_person_camera.offset_z_var[0], total_x, 180, total_y, (roll*-1), 2)
wait(0)
end
restoreCameraJumpcut()
end
end
--------------------------------------------------
-- Color/ paintjob
function module.ForEachCarComponent(func,skip,car)
car = car or getCarCharIsUsing(PLAYER_PED)
if car ~= nil then
for _, comp in ipairs(mad.get_all_vehicle_components(car)) do
for _, obj in ipairs(comp:get_objects()) do
for _, mat in ipairs(obj:get_materials()) do
func(mat,comp,car)
if skip == true then
goto _skip
end
end
end
::_skip::
end
else
printHelpString("Player ~r~not ~w~in car")
end
end
function module.GetTextureName(name)
if name == nil then
return ""
else
return name
end
end
function module.ParseCarcols()
local file_path = string.format("%s/data/carcols.dat",getGameDirectory())
local col_data = false
local car_data = false
if doesFileExist(file_path) then
for line in io.lines(file_path) do
if line == "col" then
col_data = true
goto continue
end
if line == "car" or line == "car4" then
car_data = true
goto continue
end
if line == "end" then
if col_data then col_data = false end
if car_data then car_data = false end
goto continue
end
if col_data then
local r, g, b = string.match(line,"(%d+).(%d+).(%d+)")
if r and g and b then
table.insert(module.tvehicle.color.col_data_table,string.format("%d %d %d",r,g,b))
end
end
if car_data then
local name = nil
for x in string.gmatch(line,"[^,]+") do
if type(tonumber(x)) == "nil" then
name = string.upper(x)
module.tvehicle.color.car_data_table[name] = {}
end
if type(tonumber(x)) == "number" then
table.insert(module.tvehicle.color.car_data_table[name],tonumber(x))
end
end
end
::continue::
end
end
end
function module.ParseVehiclesIDE()
local file_path = string.format("%s/data/vehicles.ide",getGameDirectory())
local cars_data = false
local tt = module.tvehicle.handling_name
if doesFileExist(file_path) then
for line in io.lines(file_path) do
if line == "cars" then
cars_data = true
end
if line == "end" then
if cars_data then cars_data = false end
goto continue
end
if cars_data then
local name = nil
local t = {}
for x in string.gmatch(line,"[^,]+") do
x = x:gsub(".",{["\t"] ="",[","] = "",[" "] = ""})
table.insert(t,x)
end
t[1] = tonumber(t[1])
if t[1] ~= nil then
tt[t[1]] = t[5]
end
end
end
::continue::
end
end
function ApplyColor(load_saved_color,car)
module.ForEachCarComponent(function(mat,comp,car)
local r, g, b, old_a = mat:get_color()
local model = getCarModel(car)
if load_saved_color then
module.tvehicle.color.rgb[0] = fconfig.Get(string.format("%d.%s.red",model,comp.name),-1,module.tvehicle.paintjobs.save_data)
module.tvehicle.color.rgb[1] = fconfig.Get(string.format("%d.%s.green",model,comp.name),-1,module.tvehicle.paintjobs.save_data)
module.tvehicle.color.rgb[2] = fconfig.Get(string.format("%d.%s.blue",model,comp.name),-1,module.tvehicle.paintjobs.save_data)
end
if (module.tvehicle.color.rgb[0] ~= -1.0 and module.tvehicle.color.rgb[1] ~= -1.0 and module.tvehicle.color.rgb[2] ~= -1.0)
and (not module.tvehicle.apply_material_filter[0] or (r == 0x3C and g == 0xFF and b == 0x00) or (r == 0xFF and g == 0x00 and b == 0xAF)) then
local save_data = false
if module.tvehicle.components.selected[0] == 0 and not load_saved_color then
mat:set_color(module.tvehicle.color.rgb[0]*255, module.tvehicle.color.rgb[1]*255, module.tvehicle.color.rgb[2]*255, 255.0)
save_data = true
end
if comp.name == module.tvehicle.components.names[module.tvehicle.components.selected[0]+1] or load_saved_color then
mat:set_color(module.tvehicle.color.rgb[0]*255, module.tvehicle.color.rgb[1]*255, module.tvehicle.color.rgb[2]*255, 255.0)
save_data = true
end
if save_data and module.tvehicle.paintjobs.enable_saving[0] then
fconfig.Set(module.tvehicle.paintjobs.save_data,string.format("%d.%s.red",model,comp.name),module.tvehicle.color.rgb[0])
fconfig.Set(module.tvehicle.paintjobs.save_data,string.format("%d.%s.green",model,comp.name),module.tvehicle.color.rgb[1])
fconfig.Set(module.tvehicle.paintjobs.save_data,string.format("%d.%s.blue",model,comp.name),module.tvehicle.color.rgb[2])
end
end
module.tvehicle.color.default = getCarColours(car)
end,false,car)
end
function ApplyTexture(filename,load_saved_texture,car)
module.ForEachCarComponent(function(mat,comp,car)
local r, g, b, old_a = mat:get_color()
local model = getCarModel(car)
if load_saved_texture then
filename = fconfig.Get(string.format("%d.%s.texture",model,comp.name),nil,module.tvehicle.paintjobs.save_data)
end
if filename ~= nil then
local fullpath = module.tvehicle.paintjobs.path .. "\\" .. filename .. ".png"
if doesFileExist(fullpath) then
if module.tvehicle.paintjobs.cache_images[filename] == nil then
module.tvehicle.paintjobs.cache_images[filename] = mad.load_png_texture(fullpath)
end
module.tvehicle.paintjobs.texture = module.tvehicle.paintjobs.cache_images[filename]
if not module.tvehicle.apply_material_filter[0] or (r == 0x3C and g == 0xFF and b == 0x00) or (r == 0xFF and g == 0x00 and b == 0xAF) then
local save_data = false
if module.tvehicle.components.selected[0] == 0 and not load_saved_texture then
mat:set_texture(module.tvehicle.paintjobs.texture)
save_data = true
end
if comp.name == module.tvehicle.components.names[module.tvehicle.components.selected[0]+1] or load_saved_texture then
mat:set_texture(module.tvehicle.paintjobs.texture)
save_data = true
end
if save_data and module.tvehicle.paintjobs.enable_saving[0] then
fconfig.Set(module.tvehicle.paintjobs.save_data,string.format("%d.%s.texture",model,comp.name),filename)
end
end
end
end
module.tvehicle.color.default = getCarColours(car)
end,false,car)
end
function Rainbow(speed)
local r = math.floor(math.sin(os.clock() * speed) * 127 + 128)
local g = math.floor(math.sin(os.clock() * speed + 2) * 127 + 128)
local b = math.floor(math.sin(os.clock() * speed + 4) * 127 + 128)
return r,g,b
end
function RainbowVehicleColor(hveh)
module.ForEachCarComponent(function(mat,comp,hveh)
local r,g,b = mat:get_color()
if not module.tvehicle.apply_material_filter[0]
or (r == 0x3C and g == 0xFF and b == 0x00) or (r == 0xFF and g == 0x00 and b == 0xAF) then
r,g,b = Rainbow(module.tvehicle.rainbow_colors.speed[0])
mat:set_color(r,g,b,255)
end
end,false,hveh)
end
function module.RainbowColors()
while module.tvehicle.rainbow_colors.bool[0] do
if module.tvehicle.rainbow_colors.traffic[0] then -- Player + Traffic
for hveh in fcommon.pool("veh") do
RainbowVehicleColor(hveh)
end
else -- Only Player
if isCharInAnyCar(PLAYER_PED) then
local hveh = getCarCharIsUsing(PLAYER_PED)
RainbowVehicleColor(hveh)
else -- function not needed at this time
break
end
end
wait(0)
end
end
function module.RainbowNeons()
while module.tvehicle.rainbow_neons.bool[0] do
if module.tvehicle.rainbow_neons.traffic[0] then -- Player + Traffic
for hveh in fcommon.pool("veh") do
InstallNeon(hveh,{Rainbow(module.tvehicle.rainbow_neons.speed[0])})
end
else -- Only Player
if isCharInAnyCar(PLAYER_PED) then
local hveh = getCarCharIsUsing(PLAYER_PED)
InstallNeon(hveh,{Rainbow(module.tvehicle.rainbow_neons.speed[0])})
else -- function not needed at this time
break
end
end
wait(0)
end
end
--------------------------------------------------
-- Component/ tune
function StoreComponentData(hveh)
if module.tvehicle.components.enable_saving[0] then
local model = tostring(getCarModel(hveh))
module.tvehicle.components.save_data[model] = {}
for x=1,14,1 do
local comp_model = getCurrentCarMod(hveh,x)
if comp_model ~= -1 then
table.insert(module.tvehicle.components.save_data[model],comp_model)
end
end
end
end
function module.AddComponentToVehicle(component,car,hide_msg)
component = tonumber(component)
if isCharInAnyCar(PLAYER_PED) then
if car == nil then
car = getCarCharIsUsing(PLAYER_PED)
end
if isModelAvailable(component) and doesVehicleExist(car) then
requestVehicleMod(component)
loadAllModelsNow()
addVehicleMod(car,component)
StoreComponentData(car)
if hide_msg ~= true then
printHelpString("Component ~g~added")
end
markModelAsNoLongerNeeded(component)
end
end
end
function module.RemoveComponentFromVehicle(component,car,hide_msg)
component = tonumber(component)
if car == nil then
car = getCarCharIsUsing(PLAYER_PED)
end
if doesVehicleExist(car) then
removeVehicleMod(car,component)
StoreComponentData(car)
if hide_msg ~= true then
printHelpString("Component ~r~removed")
end
end
end
--------------------------------------------------
-- Misc
function module.OnEnterVehicle()
while true do
if isCharInAnyCar(PLAYER_PED) then
local hveh = getCarCharIsUsing(PLAYER_PED)
local pVeh = getCarPointer(hveh)
local model = getCarModel(hveh)
local model_name = module.tvehicle.gxt_name_table[casts.CModelInfo.GetNameFromModel(model)] or getGxtText(casts.CModelInfo.GetNameFromModel(model))
-- Get vehicle components
module.tvehicle.components.names = {"default"}
module.ForEachCarComponent(function(mat,comp,hveh)
table.insert(module.tvehicle.components.names,comp.name)
end,true)
module.tvehicle.components.list = imgui.new['const char*'][#module.tvehicle.components.names](module.tvehicle.components.names)
imgui.StrCopy(module.tvehicle.gxt_name,model_name)
if module.tvehicle.first_person_camera.offsets[tostring(model)] == nil then
module.tvehicle.first_person_camera.offsets[tostring(model)] =
{
["x"] = 0,
["y"] = 0.1,
["z"] = 0.6,
}
end
module.tvehicle.first_person_camera.offset_x_var[0] = module.tvehicle.first_person_camera.offsets[tostring(model)]["x"]
module.tvehicle.first_person_camera.offset_y_var[0] = module.tvehicle.first_person_camera.offsets[tostring(model)]["y"]
module.tvehicle.first_person_camera.offset_z_var[0] = module.tvehicle.first_person_camera.offsets[tostring(model)]["z"]
fcommon.CreateThread(module.AircraftCamera)
fcommon.CreateThread(module.FirstPersonCamera)
fcommon.CreateThread(module.RainbowColors)
fcommon.CreateThread(module.UnlimitedNitro)
module.tvehicle.paintjobs.current_paintjob[0] = fconfig.Get(string.format("%d.paintjob",model),nil,module.tvehicle.paintjobs.save_data) or getCurrentVehiclePaintjob(hveh)
module.tvehicle.paintjobs.paintjobs_count = getNumAvailablePaintjobs(hveh)
module.tvehicle.paintjobs.names = {"None"}
for i=1,module.tvehicle.paintjobs.paintjobs_count,1 do
table.insert(module.tvehicle.paintjobs.names, string.format("Paintjob %d",i))
end
if module.tvehicle.paintjobs.enable_saving[0] then
ApplyColor(true)
ApplyTexture(nil,true)
if getNumAvailablePaintjobs(hveh) >= module.tvehicle.paintjobs.current_paintjob[0] then
giveVehiclePaintjob(hveh,module.tvehicle.paintjobs.current_paintjob[0])
end
local color =
{
fconfig.Get(string.format("tvehicle.paintjobs.save_data.%d.neon.red",model),0),
fconfig.Get(string.format("tvehicle.paintjobs.save_data.%d.neon.green",model),0),
fconfig.Get(string.format("tvehicle.paintjobs.save_data.%d.neon.blue",model),0)
}
InstallNeon(hveh,color)
end
if module.tvehicle.components.enable_saving[0] then
for tmodel,table in pairs(module.tvehicle.components.save_data) do
if tmodel == tostring(model) then
for _,component in ipairs(table) do
module.AddComponentToVehicle(component,car,true)
end
break
end
end
end
while isCharInCar(PLAYER_PED,hveh) do
wait(0)
end
module.tvehicle.first_person_camera.offsets[tostring(model)].x = module.tvehicle.first_person_camera.offset_x_var[0]
module.tvehicle.first_person_camera.offsets[tostring(model)].y = module.tvehicle.first_person_camera.offset_y_var[0]
module.tvehicle.first_person_camera.offsets[tostring(model)].z = module.tvehicle.first_person_camera.offset_z_var[0]
module.tvehicle.max_velocity_temp[0] = -1
end
wait(0)
end
end
function DoorMenu(func)
local vehicle = getCarCharIsUsing(PLAYER_PED)
local seats = getMaximumNumberOfPassengers(vehicle) + 1 -- passenger + driver
if seats == 4 then
doors = 5
else
doors = 3
end
if imgui.Button(module.tvehicle.doors[7],imgui.ImVec2(fcommon.GetSize(1))) then
for i=0,doors,1 do
func(vehicle,i)
end
end
for i=0,doors,1 do
if imgui.Button(module.tvehicle.doors[i+1],imgui.ImVec2(fcommon.GetSize(2))) then
func(vehicle,i)
end
if i%2 ~= 1 then
imgui.SameLine()
end
end
end
function module.UnlimitedNitro()
writeMemory(0x969165,1,0,true) -- ALl cars have nitro
writeMemory(0x96918B,1,0,true) -- All taxis have nitro
local hveh = getCarCharIsUsing(PLAYER_PED)
while isCharInCar(PLAYER_PED,hveh) and module.tvehicle.unlimited_nitro[0] and isThisModelACar(getCarModel(hveh)) do
if isKeyDown(vkeys.VK_LBUTTON) then
module.AddComponentToVehicle(1010,hveh,true)
while isKeyDown(vkeys.VK_LBUTTON) do
wait(0)
end
module.RemoveComponentFromVehicle(1010,hveh,true)
end
wait(0)
end
end
--------------------------------------------------
-- Main
function module.VehicleMain()
if imgui.Button("Blow up cars",imgui.ImVec2(fcommon.GetSize(3))) then
callFunction(0x439D80,0,0)
fcommon.CheatActivated()
end
imgui.SameLine()
if imgui.Button("Fix vehicle",imgui.ImVec2(fcommon.GetSize(3))) then
if isCharInAnyCar(PLAYER_PED) then
local car = getCarCharIsUsing(PLAYER_PED)
fixCar(car)
fcommon.CheatActivated()
else
printHelpString("Player not in vehicle")
end
end
imgui.SameLine()
if imgui.Button("Flip vehicle",imgui.ImVec2(fcommon.GetSize(3))) then
if isCharInAnyCar(PLAYER_PED) then
local car = getCarCharIsUsing(PLAYER_PED)
setCarRoll(car,getCarRoll(car) + 180)
setCarRoll(car,getCarRoll(car)) -- rotation fix
fcommon.CheatActivated()
else
printHelpString("Player not in vehicle")
end
end
if fcommon.BeginTabBar('VehiclesBar') then
if fcommon.BeginTabItem('Checkboxes') then
imgui.Columns(2,nil,false)
fcommon.CheckBoxValue("Aggressive drivers",0x96914F)
fcommon.CheckBoxValue("Aim while driving",0x969179)
fcommon.CheckBoxValue("All cars have nitro",0x969165)
fcommon.CheckBoxValue("All taxis have nitro",0x96918B)
fcommon.CheckBoxValue("Boats fly",0x969153)
fcommon.CheckBox3Var("Car engine",module.tvehicle.car_engine,"Set to 'No changes' if you're using\
mods which involve fuel systems")
fcommon.CheckBoxValue("Cars fly",0x969160)
fcommon.CheckBoxVar("Car heavy",module.tvehicle.heavy)
fcommon.CheckBoxValue("Decreased traffic",0x96917A)
fcommon.CheckBoxVar("Don't fall off bike",module.tvehicle.stay_on_bike)
fcommon.CheckBoxValue("Drive on water",0x969152)
if fcommon.CheckBoxVar("First person camera",module.tvehicle.first_person_camera.bool,nil,
function()
fcommon.InputFloat("Offset X", module.tvehicle.first_person_camera.offset_x_var,nil,-5,5,0.02)
fcommon.InputFloat("Offset Y", module.tvehicle.first_person_camera.offset_y_var,nil,-5,5,0.02)
fcommon.InputFloat("Offset Z", module.tvehicle.first_person_camera.offset_z_var,nil,-5,5,0.02)
end) then
fcommon.CreateThread(module.FirstPersonCamera)
end
if fcommon.CheckBoxVar("Fixed aircraft camera",module.tvehicle.aircraft.camera) then
fcommon.CreateThread(module.AircraftCamera)
end
fcommon.CheckBoxValue("Fixed train camera",5416239,nil,fconst.TRAIN_CAM_FIX.ON,fconst.TRAIN_CAM_FIX.OFF)
imgui.NextColumn()
fcommon.CheckBoxValue("Float away when hit",0x969166)
fcommon.CheckBoxValue("Green traffic lights",0x96914E)
if fcommon.CheckBoxVar("Invisible car",module.tvehicle.invisible_car) then
if isCharInAnyCar(PLAYER_PED) then
local car = getCarCharIsUsing(PLAYER_PED)
setCarVisible(car,not module.tvehicle.invisible_car[0])
end
end
if fcommon.CheckBoxVar("Lights on",module.tvehicle.lights,nil,nil,false) then
if isCharInAnyCar(PLAYER_PED) then
local hveh = getCarCharIsUsing(PLAYER_PED)
if module.tvehicle.lights[0] then
forceCarLights(hveh,2)
addOneOffSound(x,y,z,1052)
fcommon.CheatActivated()
else
forceCarLights(hveh,1)
addOneOffSound(x,y,z,1053)
fcommon.CheatDeactivated()
end
else
printHelpString("Player ~r~not~w~ in car")
end
end
if fcommon.CheckBoxVar("Lock doors",module.tvehicle.lock_doors,nil,nil,false) then
if isCharInAnyCar(PLAYER_PED) then
local car = getCarCharIsUsing(PLAYER_PED)
if getCarDoorLockStatus(car) == 4 then
lockCarDoors(car,1)
fcommon.CheatDeactivated()
else
lockCarDoors(car,4)
fcommon.CheatActivated()
end
else
printHelpString("Player ~r~not~w~ in car")
end
end
fcommon.CheckBoxVar("No damage",module.tvehicle.no_damage)
if fcommon.CheckBoxVar("No traffic vehicles",module.tvehicle.no_vehicles) then
if module.tvehicle.no_vehicles[0] then
writeMemory(0x434237,1,0x73,false) -- change condition to unsigned (0-255)
writeMemory(0x434224,1,0,false)
writeMemory(0x484D19,1,0x83,false) -- change condition to unsigned (0-255)
writeMemory(0x484D17,1,0,false)
else
writeMemory(0x434237,1,-1063242627,false) -- change condition to unsigned (0-255)
writeMemory(0x434224,1,940431405,false)
writeMemory(0x484D19,1,292493,false) -- change condition to unsigned (0-255)
writeMemory(0x484D17,1,1988955949,false)
end
end
fcommon.CheckBoxVar("No visual damage",module.tvehicle.visual_damage)
fcommon.CheckBoxValue("Perfect handling",0x96914C)
fcommon.CheckBoxValue("Tank mode",0x969164)
if fcommon.CheckBoxVar("Traffic neons",module.tvehicle.neon.checkbox,"Adds neon lights to traffic vehicles.\nOnly some vehicles will have them.") then
fcommon.CreateThread(fvehicle.TrafficNeons)
end
if fcommon.CheckBoxVar("Unlimited nitro",module.tvehicle.unlimited_nitro,"Nitro will activate when left clicked\n\nEnabling this would disable\nAll cars have nitro\nAll taxis have nitro") then
fcommon.CreateThread(module.UnlimitedNitro)
end
if fcommon.CheckBoxVar("Watertight car",module.tvehicle.watertight_car) then
if isCharInAnyCar(PLAYER_PED) then
local car = getCarCharIsUsing(PLAYER_PED)
setCarWatertight(car,module.tvehicle.watertight_car[0])
end
end
fcommon.CheckBoxValue("Wheels only",0x96914B)
imgui.Columns(1)
end
if fcommon.BeginTabItem('Menus') then
fcommon.DropDownMenu("Enter nearest vehicle as",function()
local vehicle = storeClosestEntities(PLAYER_PED)
if vehicle ~= -1 then
local seats = getMaximumNumberOfPassengers(vehicle)
imgui.Spacing()
imgui.Columns(2,nil,false)
imgui.Text(casts.CModelInfo.GetNameFromModel(getCarModel(vehicle)))
imgui.NextColumn()
imgui.Text(string.format("Total seats: %d",seats+1))
imgui.Columns(1)
imgui.Spacing()
if imgui.Button("Driver",imgui.ImVec2(fcommon.GetSize(2))) then
warpCharIntoCar(PLAYER_PED,vehicle)
end
for i=0,seats-1,1 do
if i%2 ~= 1 then
imgui.SameLine()
end
if imgui.Button("Passenger " .. tostring(i+1),imgui.ImVec2(fcommon.GetSize(2))) then
warpCharIntoCarAsPassenger(PLAYER_PED,vehicle,i)
end
end
else
imgui.Text("No near by vehicles")
end
end)
fcommon.DropDownMenu("License plate text",function()
imgui.InputText("Text", module.tvehicle.license_plate_text,ffi.sizeof(module.tvehicle.license_plate_text))
fcommon.InformationTooltip("The text of vehicle license plate\nwhich you spawn using cheat-menu")
end)
fcommon.DropDownMenu("Traffic options",function()
fcommon.RadioButtonAddress("Color",{"Black","Pink"},{0x969151,0x969150})
imgui.Spacing()
fcommon.RadioButtonAddress("Type",{"Cheap","Country","Fast"},{0x96915E,0x96917B,0x96915F})
end)
if isCharInAnyCar(PLAYER_PED) then
local car = getCarCharIsUsing(PLAYER_PED)
local pCar = getCarPointer(car)
local model = getCarModel(car)
fcommon.UpdateAddress({name = 'Density multiplier',address = 0x8A5B20,size = 4,min = 0,max = 10, default = 1,is_float = true})
fcommon.UpdateAddress({name = 'Dirt level',address = pCar + 1200 ,size = 4,min = 0,max = 15, default = 7.5,is_float = true})
fcommon.DropDownMenu("Doors",function()
if isCharInAnyCar(PLAYER_PED) and not (isCharOnAnyBike(PLAYER_PED) or isCharInAnyBoat(PLAYER_PED)
or isCharInAnyHeli(PLAYER_PED) or isCharInAnyPlane(PLAYER_PED)) then
imgui.Columns(2,nil,false)
imgui.RadioButtonIntPtr("Damage", module.tvehicle.door_menu_button,0)
imgui.RadioButtonIntPtr("Fix", module.tvehicle.door_menu_button,1)
imgui.NextColumn()
imgui.RadioButtonIntPtr("Open", module.tvehicle.door_menu_button,2)
imgui.RadioButtonIntPtr("Pop", module.tvehicle.door_menu_button,3)
imgui.Columns(1)
imgui.Spacing()
if module.tvehicle.door_menu_button[0] == 0 then
if module.tvehicle.visual_damage[0] == false then
DoorMenu(function(vehicle,door)
damageCarDoor(vehicle,door)
end)
else
imgui.Text("No visual damage enabled")
end
end
if module.tvehicle.door_menu_button[0] == 1 then
DoorMenu(function(vehicle,door)
fixCarDoor(vehicle,door)
end)
end
if module.tvehicle.door_menu_button[0] == 2 then
DoorMenu(function(vehicle,door)
openCarDoor(vehicle,door)
end)
end
if module.tvehicle.door_menu_button[0] == 3 then
DoorMenu(function(vehicle,door)
popCarDoor(vehicle,door,true)
end)
end
else
imgui.Text("Player not in car")
end
end)
fcommon.DropDownMenu("Set name",function()
imgui.Text(string.format( "Model name = %s",casts.CModelInfo.GetNameFromModel(getCarModel(car))))
imgui.Spacing()
imgui.InputText("Name", module.tvehicle.gxt_name,ffi.sizeof(module.tvehicle.gxt_name))
imgui.Spacing()
if imgui.Button("Set",imgui.ImVec2(fcommon.GetSize(3))) then
setGxtEntry(casts.CModelInfo.GetNameFromModel(getCarModel(car)),ffi.string(module.tvehicle.gxt_name))
fcommon.CheatActivated()
end
imgui.SameLine()
if imgui.Button("Save",imgui.ImVec2(fcommon.GetSize(3))) then
module.tvehicle.gxt_name_table[casts.CModelInfo.GetNameFromModel(getCarModel(car))] = ffi.string(module.tvehicle.gxt_name)
end
imgui.SameLine()
if imgui.Button("Clear all",imgui.ImVec2(fcommon.GetSize(3))) then
module.tvehicle.gxt_name_table = {}
end
end)
fcommon.DropDownMenu("Set speed",function()
fcommon.CheckBoxVar("Lock speed",module.tvehicle.lock_speed)
imgui.Spacing()
imgui.InputInt("Set",module.tvehicle.speed)
imgui.Spacing()
if imgui.Button("Set speed##brn",imgui.ImVec2(fcommon.GetSize(2))) then
if isCharInAnyCar(PLAYER_PED) then
car = getCarCharIsUsing(PLAYER_PED)
setCarForwardSpeed(car,module.tvehicle.speed[0])
end
end
imgui.SameLine()
if imgui.Button("Instant stop",imgui.ImVec2(fcommon.GetSize(2))) then
if isCharInAnyCar(PLAYER_PED) then
car = getCarCharIsUsing(PLAYER_PED)
setCarForwardSpeed(car,0.0)
end
end
if module.tvehicle.speed[0] > 500 then
module.tvehicle.speed[0] = 500
end
if module.tvehicle.speed[0] < 0 then
module.tvehicle.speed[0] = 0
end
end)
fcommon.UpdateAddress({name = 'Wheel scale',address = pCar+0x458,size = 4,min = 0,max = 10, default = 1,is_float = true})
end
end
if fcommon.BeginTabItem('Spawn') then
imgui.Columns(2,nil,false)
fcommon.CheckBoxVar("Spawn inside",module.tvehicle.spawn_inside,"Spawn inside vehicle as driver")
imgui.NextColumn()
fcommon.CheckBoxVar("Spawn aircraft in air",module.tvehicle.aircraft.spawn_in_air)
imgui.Columns(1)
imgui.Dummy(imgui.ImVec2(0,10))
fcommon.DrawEntries(fconst.IDENTIFIER.VEHICLE,fconst.DRAW_TYPE.IMAGE,module.GiveVehicleToPlayer,nil,casts.CModelInfo.GetNameFromModel,module.tvehicle.images,fconst.VEHICLE.IMAGE_HEIGHT,fconst.VEHICLE.IMAGE_WIDTH)
end
if fcommon.BeginTabItem('Paint') then
if isCharInAnyCar(PLAYER_PED) then
local car = getCarCharIsUsing(PLAYER_PED)
local model = getCarModel(car)
if imgui.Button("Reset color",imgui.ImVec2(fcommon.GetSize(2))) then
module.ForEachCarComponent(function(mat,comp,car)
mat:reset_color()
end)
module.tvehicle.color.default = -1
printHelpString("Color reset")
end
imgui.SameLine()
if imgui.Button("Reset texture",imgui.ImVec2(fcommon.GetSize(2))) then
fconfig.tconfig.temp_texture_name = nil
module.ForEachCarComponent(function(mat,comp,car)
mat:reset_texture()
end)
module.tvehicle.paintjobs.texture = nil
printHelpString("Texture reset")
end
imgui.Spacing()
imgui.Columns(2,nil,false)
if fcommon.CheckBoxVar("Enable saving",module.tvehicle.paintjobs.enable_saving,"Save and load vehicle paint data.\nApplies for all vehicles of this model.") then
if module.tvehicle.paintjobs.enable_saving[0] then
ApplyColor(true)
end
end
fcommon.CheckBoxVar("Material filter",module.tvehicle.apply_material_filter,"Filters material while applying color/ texture\nDisable if something doesn't work properly")
imgui.NextColumn()
if fcommon.CheckBoxVar("Rainbow colors",module.tvehicle.rainbow_colors.bool,"Rainbow color effect on players vehicle",
function()
if fcommon.CheckBoxVar("Apply for traffic",module.tvehicle.rainbow_colors.traffic,"Rainbow color effect on traffic vehicles") then
fcommon.CreateThread(module.RainbowColors)
end
imgui.Dummy(imgui.ImVec2(0,20))
imgui.SliderFloat("Speed",module.tvehicle.rainbow_colors.speed,0,2)
end) then
fcommon.CreateThread(module.RainbowColors)
end
if fcommon.CheckBoxVar("Rainbow neons",module.tvehicle.rainbow_neons.bool,"Rainbow neon effect on players vehicle",
function()
fcommon.CheckBoxVar("Apply for traffic",module.tvehicle.rainbow_neons.traffic,"Rainbow neon effect on traffic vehicles",
function()
fcommon.CreateThread(module.RainbowNeons)
end)
imgui.Dummy(imgui.ImVec2(0,20))
imgui.SliderFloat("Speed",module.tvehicle.rainbow_neons.speed,0,2)
end) then
fcommon.CreateThread(module.RainbowNeons)
end
imgui.Columns(1)
imgui.Spacing()
if imgui.ColorEdit3("Color",module.tvehicle.color.rgb) then
ApplyColor()
end
fcommon.ConfigPanel("Color",function()
if isCharInAnyCar(PLAYER_PED) then
fcommon.CheckBoxVar("Show all carcol colors", module.tvehicle.color.show_all)
imgui.Spacing()
local car = getCarCharIsUsing(PLAYER_PED)
local name = casts.CModelInfo.GetNameFromModel(getCarModel(car))
local shown_colors = {}
imgui.Text("Color:")
imgui.Spacing()
imgui.Columns(2,nil,false)
imgui.RadioButtonIntPtr("Primary", module.tvehicle.color.radio_btn, 1)
imgui.RadioButtonIntPtr("Secondary", module.tvehicle.color.radio_btn, 2)
imgui.NextColumn()
imgui.RadioButtonIntPtr("Tertiary", module.tvehicle.color.radio_btn, 3)
imgui.RadioButtonIntPtr("Quaternary", module.tvehicle.color.radio_btn, 4)
imgui.Spacing()
imgui.Columns(1)
imgui.Text("Select color preset:")
imgui.Spacing()
if imgui.BeginChild("Colors") then
local x,y = fcommon.GetSize(1)
local btns_in_row = math.floor(imgui.GetWindowContentRegionWidth()/(y*2))
local btn_size = (imgui.GetWindowContentRegionWidth() - imgui.StyleVar.ItemSpacing*(btns_in_row-0.75*btns_in_row))/btns_in_row
local btn_count = 1
func = function(v)
if not shown_colors[v] then
local t = {}
local k = 1
for i in string.gmatch(module.tvehicle.color.col_data_table[v+1],"%w+") do
table.insert( t,tonumber(i))
end
if imgui.ColorButton("Color " .. tostring(v),imgui.ImVec4(t[1]/255,t[2]/255,t[3]/255,255),0,imgui.ImVec2(btn_size,btn_size)) then
writeMemory(getCarPointer(car) + 1075 + module.tvehicle.color.radio_btn[0],1,tonumber(v),false)
module.ForEachCarComponent(function(mat,comp,car)
mat:reset_color()
end)
end
if imgui.IsItemHovered() then
local drawlist = imgui.GetWindowDrawList()
drawlist:AddRectFilled(imgui.GetItemRectMin(), imgui.GetItemRectMax(), imgui.GetColorU32(imgui.Col.ModalWindowDimBg))
end
shown_colors[v] = true
if btn_count % btns_in_row ~= 0 then
imgui.SameLine(0.0,4.0)
end
btn_count = btn_count + 1
end
end
if module.tvehicle.color.show_all[0] then
for v=0,(#module.tvehicle.color.col_data_table-1),1 do
func(v)
end
else
if module.tvehicle.color.car_data_table[name] ~= nil then
for k,v in ipairs(module.tvehicle.color.car_data_table[name]) do
func(v)
end
end
end
imgui.EndChild()
end
end
end)
imgui.Combo("Component",module.tvehicle.components.selected,module.tvehicle.components.list,#module.tvehicle.components.names)
if imgui.ColorEdit3("Neons",module.tvehicle.neon.rgb) then
InstallNeon(car,{module.tvehicle.neon.rgb[0]*255,module.tvehicle.neon.rgb[1]*255,module.tvehicle.neon.rgb[2]*255})
end
if module.tvehicle.paintjobs.paintjobs_count > 0 then
if fcommon.HorizontalSelector("Paintjob",module.tvehicle.paintjobs.current_paintjob,
module.tvehicle.paintjobs.names) then
if module.tvehicle.paintjobs.current_paintjob[0] >= -1 and module.tvehicle.paintjobs.current_paintjob[0] <= module.tvehicle.paintjobs.paintjobs_count then
giveVehiclePaintjob(car,module.tvehicle.paintjobs.current_paintjob[0])
if module.tvehicle.paintjobs.enable_saving[0] then
fconfig.Set(module.tvehicle.paintjobs.save_data,string.format("%d.paintjob",model),module.tvehicle.paintjobs.current_paintjob[0])
end
end
end
end
fcommon.DrawEntries(fconst.IDENTIFIER.PAINTJOB,fconst.DRAW_TYPE.IMAGE,ApplyTexture,nil,module.GetTextureName,module.tvehicle.paintjobs.images,fconst.VEHICLE.IMAGE_HEIGHT,fconst.VEHICLE.IMAGE_WIDTH)
else
imgui.TextWrapped("Player needs to be inside a vehicle for options to show up here.")
end
end
if fcommon.BeginTabItem('Tune') then
if isCharInAnyCar(PLAYER_PED) then
local car = getCarCharIsUsing(PLAYER_PED)
local model = getCarModel(car)
if imgui.Button("Reset vehicle components",imgui.ImVec2(fcommon.GetSize(1))) then
for x=1,fconst.COMPONENT.TOTAL_SLOTS,1 do
local comp_model = getCurrentCarMod(car,x)
if comp_model ~= -1 then
module.RemoveComponentFromVehicle(comp_model,car,true)
end
end
printHelpString("Vehicle components reset")
end
if fcommon.CheckBoxVar("Enable saving",module.tvehicle.components.enable_saving,"Save and load vehicle tune data.\nApplies for all vehicles of this model.") then
if module.tvehicle.components.enable_saving[0] then
for tmodel,table in pairs(module.tvehicle.components.save_data) do
if tmodel == tostring(model) then
for _,component in ipairs(table) do
module.AddComponentToVehicle(component,car,true)
end
break
end
end
end
end
imgui.Dummy(imgui.ImVec2(0,10))
fcommon.DrawEntries(fconst.IDENTIFIER.COMPONENT,fconst.DRAW_TYPE.IMAGE,module.AddComponentToVehicle,
function(component)
if imgui.MenuItemBool("Remove component") then
module.RemoveComponentFromVehicle(component)
end
end,function(a) return a end,module.tvehicle.components.images,fconst.COMPONENT.IMAGE_HEIGHT,fconst.COMPONENT.IMAGE_WIDTH)
else
imgui.TextWrapped("Player needs to be inside a vehicle for options to show up here.")
end
end
if fcommon.BeginTabItem('Handling') then
if isCharInAnyCar(PLAYER_PED) then
local car = getCarCharIsUsing(PLAYER_PED)
local model = getCarModel(car)
-------------------------------------------------------
local phandling = readMemory((casts.CModelInfo.ms_modelInfoPtrs[model] + 0x4A),2,false) --m_nHandlingId
phandling = phandling * 0xE0
phandling = phandling + 0xC2B9DC
if module.tvehicle.max_velocity_temp[0] == -1 then
local velocity = memory.getfloat(phandling + 0x84)
velocity = velocity*206 + (velocity-0.918668)*1501
module.tvehicle.max_velocity_temp[0] = velocity
end
if imgui.Button("Reset handling",imgui.ImVec2(fcommon.GetSize(3))) then
local cHandlingDataMgr = readMemory(0x05BFA96,4,false)
callMethod(0x5BD830,cHandlingDataMgr,0,0)
printHelpString("Handling reset")
end
imgui.SameLine()
if imgui.Button("Save to file",imgui.ImVec2(fcommon.GetSize(3))) then
local name = module.tvehicle.handling_name[model]
local fMass = memory.getfloat(phandling + 0x4)
local fTurnMass = memory.getfloat(phandling + 0xC)
local fDragMult = memory.getfloat(phandling + 0x10)
local CentreOfMassX = memory.getfloat(phandling + 0x14)
local CentreOfMassY = memory.getfloat(phandling + 0x18)
local CentreOfMassZ = memory.getfloat(phandling + 0x1C)
local nPercentSubmerged = memory.read(phandling + 0x20,4)
local fTractionMultiplier = memory.getfloat(phandling + 0x28)
local fTractionLoss = memory.getfloat(phandling + 0xA4)
local TractionBias = memory.getfloat(phandling + 0xA8)
local nNumberOfGears= memory.read(phandling + 0x76,1)
local fMaxVelocity = module.tvehicle.max_velocity_temp[0] --memory.getfloat(phandling + 0x84)
--fMaxVelocity = fMaxVelocity*206 + (fMaxVelocity-0.918668)*1501
local fEngineAcceleration = memory.getfloat(phandling + 0x7C)*12500
local fEngineInertia = memory.getfloat(phandling + 0x80)
local nDriveType = memory.tostring(phandling + 0x74,1)
local nEngineType = memory.tostring(phandling + 0x75,1)
local BrakeDeceleration = memory.getfloat(phandling + 0x94)*2500
local BrakeBias = memory.getfloat(phandling + 0x98)
local ABS = memory.read(phandling + 0x9C,1)
local SteeringLock = memory.getfloat(phandling + 0xA0)
local SuspensionForceLevel = memory.getfloat(phandling + 0xAC)
local SuspensionDampingLevel = memory.getfloat(phandling + 0xB0)
local SuspensionHighSpdComDamp = memory.getfloat(phandling + 0xB4)
local Suspension_upper_limit = memory.getfloat(phandling + 0xB8)
local Suspension_lower_limit = memory.getfloat(phandling + 0xBC)
local Suspension_bias = memory.getfloat(phandling + 0xC0)
local Suspension_anti_dive_multiplier = memory.getfloat(phandling + 0xC4)
local fSeatOffsetDistance = memory.getfloat(phandling + 0xD4)
local fCollisionDamageMultiplier = memory.getfloat(phandling + 0xC8)*0.338
local nMonetaryValue = memory.read(phandling + 0xD8,4)
local modelFlags = string.format('%x',memory.read(phandling + 0xCC,4))
local handlingFlags = string.format('%x',memory.read(phandling + 0xD0,4))
local front_lights = memory.read(phandling + 0xDC,1)
local rear_lights = memory.read(phandling + 0xDD,1)
local vehicle_anim_group = memory.read(phandling + 0xDE,1)
local file = io.open(getGameDirectory() .. "/handling.txt","a+")
local data = string.format("\n%s\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%d\t%d\t%.5g\t%.5g\t%s\t%s\t%.5g\t%.5g\t%d\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%d\t%s\t%s\t%d\t%d\t%d",
name,fMass,fTurnMass,fDragMult,CentreOfMassX,CentreOfMassY,CentreOfMassZ,nPercentSubmerged,fTractionMultiplier,fTractionLoss,TractionBias,nNumberOfGears,
fMaxVelocity,fEngineAcceleration,fEngineInertia,tostring(nDriveType),nEngineType,BrakeDeceleration,BrakeBias,ABS,SteeringLock,SuspensionForceLevel,SuspensionDampingLevel,
SuspensionHighSpdComDamp,Suspension_upper_limit,Suspension_lower_limit,Suspension_bias,Suspension_anti_dive_multiplier,fSeatOffsetDistance,
fCollisionDamageMultiplier,nMonetaryValue,tostring(modelFlags),tostring(handlingFlags),front_lights,rear_lights,vehicle_anim_group)
file:write(data)
file:close()
printHelpString("Data saved")
end
imgui.SameLine()
if imgui.Button("Read more",imgui.ImVec2(fcommon.GetSize(3))) then
os.execute('explorer "https://projectcerbera.com/gta/sa/tutorials/handling"')
end
imgui.Spacing()
if imgui.BeginChild("Handling") then
fcommon.RadioButtonAddressEx("ABS",{"On","Off"},{1.0,0.0},phandling + 0x9C,false)
fcommon.UpdateAddress({name = 'Anti dive multiplier',address = phandling + 0xC4 ,size = 4,min = 0,max = 1,is_float = true,cvalue = 0.01, save = false})
fcommon.UpdateAddress({name = 'Brake bias',address = phandling + 0x98 ,size = 4,min = 0,max = 1,is_float = true,cvalue = 0.01, save = false})
fcommon.UpdateAddress({name = 'Brake deceleration',address = phandling + 0x94 ,size = 4,min = 0.1,max = 20,is_float = true,mul = 2500,cvalue = 0.1, save = false})
fcommon.UpdateAddress({name = 'Centre of mass X',address = phandling + 0x14 ,size = 1,min = -10.0,max = 10.0,is_float = true,cvalue = 0.05, save = false})
fcommon.UpdateAddress({name = 'Centre of mass Y',address = phandling + 0x18 ,size = 1,min = -10.0,max = 10.0,is_float = true,cvalue = 0.05, save = false})
fcommon.UpdateAddress({name = 'Centre of mass Z',address = phandling + 0x1C ,size = 1,min = -10.0,max = 10.0,is_float = true,cvalue = 0.05, save = false})
fcommon.UpdateAddress({name = 'Collision damage multiplier',address = phandling + 0xC8,size = 4,min = 0,max = 1,is_float = true,cvalue = 0.01,mul = 0.3381, save = false})
fcommon.UpdateAddress({name = 'Damping level',address = phandling + 0xB0 ,size = 4,is_float = true,cvalue = 0.01, save = false})
fcommon.UpdateAddress({name = 'Drag mult',address = phandling + 0x10 ,size = 4,min = 0,max = 30.0,is_float = true, save = false})
fcommon.RadioButtonAddressEx("Drive type",{"Front wheel drive","Rear wheel drive","Four wheel drive"},{70,82,52},phandling + 0x74,false)
fcommon.UpdateAddress({name = 'Engine acceleration',address = phandling + 0x7C ,size = 4,min = 0,max = 49,is_float = true,mul = 12500, save = false})
fcommon.UpdateAddress({name = 'Engine inertia',address = phandling + 0x80 ,size = 4,min = 0,max = 400,is_float = true, save = false})
fcommon.RadioButtonAddressEx("Engine type",{"Petrol","Diseal","Electric"},{80,68,69},phandling + 0x75,false)
fcommon.RadioButtonAddressEx("Front lights",{"Long","Small","Big","Tall"},{0,1,2,3},phandling + 0xDC,false)
fcommon.UpdateAddress({name = 'Force level',address = phandling + 0xAC ,size = 4,is_float = true,cvalue = 0.1, save = false})
fcommon.UpdateBits("Handling flags",module.tvehicle.handling_flags,phandling + 0xD0,4)
fcommon.UpdateAddress({name = 'High speed damping',address = phandling + 0xB4 ,size = 4,is_float = true,cvalue = 0.1, save = false})
fcommon.UpdateAddress({name = 'Lower limit',address = phandling + 0xBC ,size = 4,min = -1,max = 1,is_float = true,cvalue = 0.01, save = false})
fcommon.UpdateAddress({name = 'Mass',address = phandling + 0x4 ,size = 4,min = 1,max = 50000,is_float = true, save = false})
-- fcommon.UpdateAddress({name = 'Max velocity',address = phandling + 0x84 ,size = 4,min = 0,max = 2,is_float = true,cvalue = 0.01 , save = false})
fcommon.DropDownMenu("Max velocity",function()
imgui.Text("Info")
fcommon.InformationTooltip("Due to an issue, any changes made here won't\nbe applied in game. You can still generate your\
data file with these values changed here")
imgui.Columns(2,nil,false)
imgui.Text("Minimum = 0")
imgui.NextColumn()
imgui.Text("Maximum = 500")
imgui.Columns(1)
imgui.Spacing()
imgui.InputInt("Set##MaxVelocity",module.tvehicle.max_velocity_temp)
if imgui.Button("Minimum##MaxVelocity",imgui.ImVec2(fcommon.GetSize(3))) then
module.tvehicle.max_velocity_temp[0] = 0
end
imgui.SameLine()
if imgui.Button("Default##MaxVelocity",imgui.ImVec2(fcommon.GetSize(3))) then
local fMaxVelocity = memory.getfloat(phandling + 0x84)
fMaxVelocity = fMaxVelocity*206 + (fMaxVelocity-0.918668)*1501
module.tvehicle.max_velocity_temp[0] = math.floor(fMaxVelocity)
end
imgui.SameLine()
if imgui.Button("Maximum##MaxVelocity",imgui.ImVec2(fcommon.GetSize(3))) then
module.tvehicle.max_velocity_temp[0] = 500
end
if module.tvehicle.max_velocity_temp[0] > 500 then
module.tvehicle.max_velocity_temp[0] = 500
end
if module.tvehicle.max_velocity_temp[0] < 0 then
module.tvehicle.max_velocity_temp[0] = 0
end
end)
fcommon.UpdateBits("Model flags",module.tvehicle.model_flags,phandling + 0xCC,4)
fcommon.UpdateAddress({name = 'Monetary value',address = phandling + 0xD8 ,size = 4, save = false})
fcommon.UpdateAddress({name = 'Number of gears',address = phandling + 0x76 ,size = 1,min = 1,max = 10, save = false})
fcommon.UpdateAddress({name = 'Percent submerged',address = phandling + 0x20 ,size = 1,min = 10,max = 120, save = false})
fcommon.RadioButtonAddressEx("Rear lights",{"Long","Small","Big","Tall"},{0,1,2,3},phandling + 0xDD,false)
fcommon.UpdateAddress({name = 'Seat offset distance',address = phandling + 0xD4 ,size = 4,min = 0,max = 1,is_float = true,cvalue = 0.01, save = false})
fcommon.UpdateAddress({name = 'Steering lock',address = phandling + 0xA0 ,size = 4,min = 10,max = 50,is_float = true, save = false})
fcommon.UpdateAddress({name = 'Suspension bias',address = phandling + 0xC0 ,size = 4,min = 0,max = 1,is_float = true,cvalue = 0.01, save = false})
fcommon.UpdateAddress({name = 'Traction bias',address = phandling + 0xA8 ,size = 4,min = 0,max = 1,is_float = true,cvalue = 0.01, save = false})
fcommon.UpdateAddress({name = 'Traction loss',address = phandling + 0xA4 ,size = 4,min = 0,max = 1,is_float = true,cvalue = 0.01, save = false})
fcommon.UpdateAddress({name = 'Traction multiplier',address = phandling + 0x28 ,size = 4,min = 0.5,max = 2,is_float = true,cvalue = 0.05, save = false})
fcommon.UpdateAddress({name = 'Turn mass',address = phandling + 0xC ,size = 4,min = 20,is_float = true, save = false})
fcommon.UpdateAddress({name = 'Upper limit',address = phandling + 0xB8 ,size = 4,min = -1,max = 1,is_float = true,cvalue = 0.01, save = false})
fcommon.UpdateAddress({name = 'Vehicle anim group',address = phandling + 0xDE ,size = 1, save = false})
imgui.EndChild()
end
else
imgui.TextWrapped("Player needs to be inside a vehicle for options to show up here.")
end
end
fcommon.EndTabBar()
end
end
return module