461 lines
20 KiB
Lua
461 lines
20 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.tplayer =
|
|
{
|
|
aimSkinChanger = imgui.new.bool(fconfig.Get('tplayer.aimSkinChanger',false)),
|
|
cjBody = imgui.new.int(fconfig.Get('tplayer.cjBody',0)),
|
|
clothes =
|
|
{
|
|
images = {},
|
|
path = tcheatmenu.dir .. "clothes\\",
|
|
},
|
|
custom_skins =
|
|
{
|
|
filter = imgui.ImGuiTextFilter(),
|
|
is_modloader_installed = false,
|
|
names = {},
|
|
path = string.format("%s\\modloader\\Custom Skins",getGameDirectory())
|
|
},
|
|
enable_saving = imgui.new.bool(fconfig.Get('tplayer.enable_saving',false)),
|
|
save_data = fconfig.Get('tplayer.save_data',{["clothes"] = {}}),
|
|
god = imgui.new.bool(fconfig.Get('tplayer.god',false)),
|
|
health_regeneration = {
|
|
bool = imgui.new.bool(fconfig.Get('tplayer.health_regeneration.bool',false)),
|
|
increment_value = imgui.new.int(fconfig.Get('tplayer.health_regeneration.increment_value',2)),
|
|
interval = imgui.new.int(fconfig.Get('tplayer.health_regeneration.interval',5000)),
|
|
},
|
|
invisible = imgui.new.bool(fconfig.Get('tplayer.invisible',false)),
|
|
keep_position = imgui.new.bool(fconfig.Get('tplayer.keep_position',false)),
|
|
never_wanted = imgui.new.bool(false),
|
|
}
|
|
|
|
function module.CustomSkinsSetup()
|
|
local hmodloader = getModuleHandle("modloader.asi")
|
|
if hmodloader ~= 0 then
|
|
local dir = fplayer.tplayer.custom_skins.path
|
|
|
|
module.tplayer.custom_skins.is_modloader_installed = true
|
|
|
|
if not doesDirectoryExist(dir) then
|
|
createDirectory(dir)
|
|
end
|
|
|
|
fcommon.IndexFiles(dir,fplayer.tplayer.custom_skins.names,"dff")
|
|
|
|
end
|
|
end
|
|
|
|
function module.KeepPosition()
|
|
while module.tplayer.keep_position[0] do
|
|
if isPlayerDead(PLAYER_HANDLE) then
|
|
local x,y,z = getCharCoordinates(PLAYER_PED)
|
|
wait(1000)
|
|
setCharCoordinates(PLAYER_PED,x,y,z)
|
|
end
|
|
wait(0)
|
|
end
|
|
end
|
|
|
|
function module.SetPlayerInvisible(bool)
|
|
local pplayer = getCharPointer(PLAYER_PED)
|
|
|
|
if pplayer == nil then return end
|
|
if bool then
|
|
casts.CEntity.SetRwObjectAlpha(pplayer,0)
|
|
else
|
|
casts.CEntity.SetRwObjectAlpha(pplayer,255)
|
|
end
|
|
end
|
|
|
|
function module.ChangePlayerModel(model,dont_show_msg)
|
|
dont_show_msg = dont_show_msg or false
|
|
local modeldff = (model .. ".dff")
|
|
|
|
if fped.tped.names[model] ~= nil or fplayer.tplayer.custom_skins.names[modeldff] ~= nil then
|
|
if fped.tped.special[model] == nil and fplayer.tplayer.custom_skins.names[modeldff] == nil then
|
|
model = tonumber(model)
|
|
if isModelAvailable(model) then
|
|
requestModel(model)
|
|
loadAllModelsNow()
|
|
setPlayerModel(PLAYER_HANDLE,model)
|
|
markModelAsNoLongerNeeded(model)
|
|
|
|
if module.tplayer.enable_saving[0] then
|
|
module.tplayer.save_data["player_skin"] = model
|
|
end
|
|
end
|
|
else
|
|
if fped.tped.special[model] ~= nil then
|
|
model = fped.tped.special[model]
|
|
end
|
|
|
|
loadSpecialCharacter(model,1)
|
|
loadAllModelsNow()
|
|
setPlayerModel(PLAYER_HANDLE,290)
|
|
|
|
if module.tplayer.enable_saving[0] then
|
|
module.tplayer.save_data["player_skin"] = model
|
|
end
|
|
|
|
unloadSpecialCharacter(290)
|
|
end
|
|
|
|
local hveh = nil
|
|
if isCharInAnyCar(PLAYER_PED) then
|
|
hveh = getCarCharIsUsing(PLAYER_PED)
|
|
speed = getCarSpeed(hveh)
|
|
end
|
|
clearCharTasksImmediately(PLAYER_PED)
|
|
if hveh ~= nil then
|
|
taskWarpCharIntoCarAsDriver(PLAYER_PED,hveh)
|
|
setCarForwardSpeed(hveh,speed)
|
|
end
|
|
|
|
if not dont_show_msg then
|
|
printHelpString("~g~Skin~w~ changed")
|
|
end
|
|
end
|
|
end
|
|
|
|
function WantedLevelMenu()
|
|
|
|
fcommon.DropDownMenu("Wanted level",function()
|
|
local _,wl = storeWantedLevel(PLAYER_HANDLE)
|
|
local wanted_level = imgui.new.int(wl)
|
|
local max_wanted_level = imgui.new.int(readMemory(0x58DFE4,1,false))
|
|
|
|
imgui.Columns(2,nil,false)
|
|
imgui.Text("Minimum" .. " = " .. tostring(0))
|
|
imgui.NextColumn()
|
|
imgui.Text("Maximum" .. " = " .. tostring(6))
|
|
imgui.Columns(1)
|
|
|
|
imgui.Spacing()
|
|
|
|
imgui.PushItemWidth(imgui.GetWindowWidth()-50)
|
|
|
|
if imgui.InputInt("Set",wanted_level) then
|
|
callFunction(0x4396F0,1,0,false)
|
|
alterWantedLevel(PLAYER_HANDLE,wanted_level[0])
|
|
end
|
|
imgui.PopItemWidth()
|
|
|
|
imgui.Spacing()
|
|
if imgui.Button("Minimum",imgui.ImVec2(fcommon.GetSize(3))) then
|
|
callFunction(0x4396F0,1,0,false)
|
|
alterWantedLevel(PLAYER_HANDLE,0)
|
|
end
|
|
imgui.SameLine()
|
|
if imgui.Button("Default",imgui.ImVec2(fcommon.GetSize(3))) then
|
|
callFunction(0x4396F0,1,0,false)
|
|
alterWantedLevel(PLAYER_HANDLE,0)
|
|
end
|
|
imgui.SameLine()
|
|
if imgui.Button("Maximum",imgui.ImVec2(fcommon.GetSize(3))) then
|
|
callFunction(0x4396F0,1,0,false)
|
|
alterWantedLevel(PLAYER_HANDLE,max_wanted_level[0])
|
|
end
|
|
end)
|
|
end
|
|
|
|
|
|
function module.RegenerateHealth()
|
|
while module.tplayer.health_regeneration.bool[0] do
|
|
local max_health = math.floor(mad.get_char_max_health(PLAYER_PED))
|
|
local health = getCharHealth(PLAYER_PED)
|
|
|
|
if max_health > health then
|
|
setCharHealth(PLAYER_PED,health+module.tplayer.health_regeneration.increment_value[0])
|
|
end
|
|
|
|
wait(module.tplayer.health_regeneration.interval[0])
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------
|
|
-- Cloth functions
|
|
|
|
function module.ChangePlayerCloth(name,dont_show_msg)
|
|
dont_show_msg = dont_show_msg or false
|
|
local body_part, model, texture = name:match("([^$]+)$([^$]+)$([^$]+)")
|
|
|
|
if getCharModel(PLAYER_PED) ~= 0 then
|
|
setPlayerModel(PLAYER_HANDLE,0)
|
|
end
|
|
|
|
if texture == "cutoffchinosblue" then
|
|
givePlayerClothes(PLAYER_HANDLE,-697413025,744365350,body_part)
|
|
else
|
|
if texture == "sneakerbincblue" then
|
|
givePlayerClothes(PLAYER_HANDLE,-915574819,-2099005073,body_part)
|
|
else
|
|
if texture == "12myfac" then
|
|
givePlayerClothes(PLAYER_HANDLE,-1750049245,1393983095,body_part)
|
|
else
|
|
givePlayerClothes(PLAYER_HANDLE,getHashKey(texture),getHashKey(model),body_part)
|
|
end
|
|
end
|
|
end
|
|
|
|
if module.tplayer.enable_saving[0] then
|
|
module.tplayer.save_data["clothes"][body_part] = name
|
|
end
|
|
|
|
buildPlayerModel(PLAYER_HANDLE)
|
|
|
|
if not dont_show_msg then
|
|
printHelpString("Clothes changed")
|
|
end
|
|
|
|
local veh = nil
|
|
local speed = 0
|
|
if isCharInAnyCar(PLAYER_PED) then
|
|
veh = getCarCharIsUsing(PLAYER_PED)
|
|
speed = getCarSpeed(veh)
|
|
end
|
|
clearCharTasksImmediately(PLAYER_PED)
|
|
if veh ~= nil then
|
|
taskWarpCharIntoCarAsDriver(PLAYER_PED,veh)
|
|
setCarForwardSpeed(veh,speed)
|
|
end
|
|
end
|
|
|
|
function module.RemoveThisCloth(name)
|
|
if imgui.MenuItemBool("Remove cloth") then
|
|
local body_part, model, texture = name:match("([^$]+)$([^$]+)$([^$]+)")
|
|
|
|
if module.tplayer.enable_saving[0] then
|
|
module.tplayer.save_data["clothes"][body_part] = "none"
|
|
end
|
|
|
|
givePlayerClothes(PLAYER_HANDLE,0,0,body_part)
|
|
buildPlayerModel(PLAYER_HANDLE)
|
|
printHelpString("Cloth ~r~removed")
|
|
end
|
|
end
|
|
--------------------------------------------------
|
|
|
|
-- Main function
|
|
function module.PlayerMain()
|
|
|
|
if imgui.Button("Copy coordinates",imgui.ImVec2(fcommon.GetSize(2))) then
|
|
local x,y,z = getCharCoordinates(PLAYER_PED)
|
|
setClipboardText(string.format( "%d,%d,%d",x,y,z))
|
|
printHelpString("Coordinates copied")
|
|
end
|
|
imgui.SameLine()
|
|
if imgui.Button("Suicide",imgui.ImVec2(fcommon.GetSize(2))) then
|
|
setCharHealth(PLAYER_PED,0)
|
|
end
|
|
|
|
if fcommon.BeginTabBar("PlayerBar") then
|
|
if fcommon.BeginTabItem("Checkboxes") then
|
|
imgui.Columns(2,nil,false)
|
|
if fcommon.CheckBoxVar("God mode",module.tplayer.god) then
|
|
if not module.tplayer.god[0] then
|
|
writeMemory(0x96916D,1,0,false)
|
|
setCharProofs(PLAYER_PED,false,false,false,false,false)
|
|
end
|
|
end
|
|
fcommon.CheckBoxValue("Have bounty on head",0x96913F)
|
|
if fcommon.CheckBoxVar("Health regeneration",module.tplayer.health_regeneration.bool,nil,
|
|
function()
|
|
imgui.SliderInt("Increment value", module.tplayer.health_regeneration.increment_value, 0, 25)
|
|
imgui.SliderInt("Interval", module.tplayer.health_regeneration.interval, 0, 10000)
|
|
fcommon.InformationTooltip("The wait time between increment\nin milliseconds")
|
|
end) then
|
|
fcommon.CreateThread(module.RegenerateHealth)
|
|
end
|
|
fcommon.CheckBoxValue("Higher cycle jumps",0x969161)
|
|
fcommon.CheckBoxValue("Infinite oxygen",0x96916E)
|
|
fcommon.CheckBoxValue("Infinite run",0xB7CEE4)
|
|
if fcommon.CheckBoxVar("Invisible player",module.tplayer.invisible) then
|
|
module.SetPlayerInvisible(module.tplayer.invisible[0])
|
|
end
|
|
imgui.NextColumn()
|
|
if fcommon.CheckBoxVar("Keep position",module.tplayer.keep_position,"Auto teleport to the position you died from") then
|
|
fcommon.CreateThread(module.KeepPosition)
|
|
end
|
|
fcommon.CheckBoxValue("Lock player control",getCharPointer(PLAYER_PED)+0x598)
|
|
fcommon.CheckBoxValue("Mega jump",0x96916C)
|
|
fcommon.CheckBoxValue("Mega punch",0x969173)
|
|
fcommon.CheckBoxValue("Never get hungry",0x969174)
|
|
|
|
module.tplayer.never_wanted[0] = readMemory(0x969171 ,1,false)
|
|
if fcommon.CheckBoxVar("Never wanted",module.tplayer.never_wanted) then
|
|
callFunction(0x4396C0,1,0,false)
|
|
if module.tplayer.never_wanted[0] then
|
|
fcommon.CheatActivated()
|
|
else
|
|
fcommon.CheatDeactivated()
|
|
end
|
|
fconfig.Set(fconfig.tconfig.misc_data,"Never Wanted",module.tplayer.never_wanted[0])
|
|
end
|
|
|
|
imgui.Columns(1)
|
|
end
|
|
if fcommon.BeginTabItem("Menus") then
|
|
local pChar = getCharPointer(PLAYER_PED)
|
|
fcommon.UpdateAddress({name = "Armour",address = pChar+0x548,size = 4,min = 0,default =0,max = 150, is_float = true})
|
|
fcommon.DropDownMenu("Body",function()
|
|
if getCharModel(PLAYER_PED) == 0 then
|
|
if imgui.RadioButtonIntPtr("Fat",module.tplayer.cjBody,1) then
|
|
callFunction(0x439110,1,1,false)
|
|
fconfig.Set(fconfig.tconfig.misc_data,"Body",1)
|
|
fcommon.CheatActivated()
|
|
end
|
|
if imgui.RadioButtonIntPtr("Muscle",module.tplayer.cjBody,2) then
|
|
-- body not changing to muscular after changing to fat fix
|
|
callFunction(0x439190,1,1,false)
|
|
callFunction(0x439150,1,1,false)
|
|
fconfig.Set(fconfig.tconfig.misc_data,"Body",2)
|
|
fcommon.CheatActivated()
|
|
end
|
|
if imgui.RadioButtonIntPtr("Skinny",module.tplayer.cjBody,3) then
|
|
callFunction(0x439190,1,1,false)
|
|
fconfig.Set(fconfig.tconfig.misc_data,"Body",3)
|
|
fcommon.CheatActivated()
|
|
end
|
|
if imgui.RadioButtonIntPtr("None",module.tplayer.cjBody,0) then
|
|
fconfig.Set(fconfig.tconfig.misc_data,"Body",0)
|
|
fcommon.CheatActivated()
|
|
end
|
|
else
|
|
imgui.TextWrapped("You need to be in CJ skin.")
|
|
imgui.Spacing()
|
|
if imgui.Button("Change to CJ skin",imgui.ImVec2(fcommon.GetSize(1))) then
|
|
setPlayerModel(PLAYER_HANDLE,0)
|
|
|
|
local veh = nil
|
|
local speed = 0
|
|
if isCharInAnyCar(PLAYER_PED) then
|
|
veh = getCarCharIsUsing(PLAYER_PED)
|
|
speed = getCarSpeed(veh)
|
|
end
|
|
clearCharTasksImmediately(PLAYER_PED)
|
|
if veh ~= nil then
|
|
taskWarpCharIntoCarAsDriver(PLAYER_PED,veh)
|
|
setCarForwardSpeed(veh,speed)
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
fcommon.UpdateStat({ name = "Energy",stat = 165})
|
|
fcommon.UpdateStat({ name = "Fat",stat = 21})
|
|
fcommon.UpdateAddress({name = "Health",address = pChar+0x540,size = 4,min = 0,default =100,max = math.floor(mad.get_char_max_health(PLAYER_PED)), is_float = true})
|
|
fcommon.UpdateStat({ name = "Lung capacity",stat = 225})
|
|
fcommon.UpdateStat({ name = "Max health",stat = 24,min = 0,default = 569,max = 1450})
|
|
fcommon.UpdateAddress({name = "Money",address = 0xB7CE50,size = 4,min = -9999999,default = 0,max = 9999999})
|
|
fcommon.UpdateStat({ name = "Muscle",stat = 23})
|
|
fcommon.UpdateStat({ name = "Respect",stat = 68,max = 2450})
|
|
fcommon.UpdateStat({ name = "Stamina",stat = 22})
|
|
|
|
WantedLevelMenu()
|
|
end
|
|
if fcommon.BeginTabItem("Appearance") then
|
|
imgui.Columns(2,nil,false)
|
|
fcommon.CheckBoxVar("Aim skin changer", module.tplayer.aimSkinChanger,"Activate using, Aim ped +".. fcommon.GetHotKeyNames(fmenu.tmenu.hot_keys.asc_key))
|
|
imgui.NextColumn()
|
|
fcommon.CheckBoxVar("Enable saving", module.tplayer.enable_saving,"Save & load clothes & ped skins.\n(Clothes only work with CJ skin)")
|
|
imgui.Columns(1)
|
|
if fcommon.BeginTabBar('Appearance') then
|
|
if fcommon.BeginTabItem('Clothes') then
|
|
if getCharModel(PLAYER_PED) == 0 then
|
|
if imgui.Button("Remove clothes",imgui.ImVec2(fcommon.GetSize(1))) then
|
|
for i=0, 18 do
|
|
givePlayerClothes(PLAYER_HANDLE,0,0,i)
|
|
if module.tplayer.enable_saving[0] then
|
|
module.tplayer.save_data["clothes"][tostring(i)] = "none"
|
|
end
|
|
end
|
|
buildPlayerModel(PLAYER_HANDLE)
|
|
printHelpString("Clothes ~r~removed")
|
|
end
|
|
|
|
imgui.Dummy(imgui.ImVec2(0,10))
|
|
fcommon.DrawEntries(fconst.IDENTIFIER.CLOTHES,fconst.DRAW_TYPE.IMAGE,module.ChangePlayerCloth,module.RemoveThisCloth,function() return "" end,module.tplayer.clothes.images,fconst.CLOTH.IMAGE_HEIGHT,fconst.CLOTH.IMAGE_WIDTH)
|
|
else
|
|
imgui.TextWrapped("You need to be in CJ skin to change clothes.")
|
|
imgui.Spacing()
|
|
if imgui.Button("Change to CJ skin",imgui.ImVec2(fcommon.GetSize(1))) then
|
|
|
|
if module.tplayer.enable_saving[0] then
|
|
module.tplayer.save_data["player_skin"] = nil
|
|
end
|
|
|
|
setPlayerModel(PLAYER_HANDLE,0)
|
|
|
|
local veh = nil
|
|
local speed = 0
|
|
if isCharInAnyCar(PLAYER_PED) then
|
|
veh = getCarCharIsUsing(PLAYER_PED)
|
|
speed = getCarSpeed(veh)
|
|
end
|
|
clearCharTasksImmediately(PLAYER_PED)
|
|
if veh ~= nil then
|
|
taskWarpCharIntoCarAsDriver(PLAYER_PED,veh)
|
|
setCarForwardSpeed(veh,speed)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if fcommon.BeginTabItem('Ped skins') then
|
|
fcommon.DrawEntries(fconst.IDENTIFIER.PED,fconst.DRAW_TYPE.IMAGE,module.ChangePlayerModel,nil,fped.GetModelName,fped.tped.images,fconst.PED.IMAGE_HEIGHT,fconst.PED.IMAGE_WIDTH)
|
|
end
|
|
if fcommon.BeginTabItem('Custom skins') then
|
|
if module.tplayer.custom_skins.is_modloader_installed then
|
|
module.tplayer.custom_skins.filter:Draw("Search")
|
|
if module.tplayer.custom_skins.filter:PassFilter('') then
|
|
local min = imgui.GetItemRectMin()
|
|
local drawlist = imgui.GetWindowDrawList()
|
|
drawlist:AddText(imgui.ImVec2(min.x+imgui.GetStyle().ItemInnerSpacing.x,min.y+imgui.GetStyle().FramePadding.y), imgui.GetColorU32(imgui.Col.TextDisabled),string.format("Total skins: %d",fcommon.CalcTableSize(fplayer.tplayer.custom_skins.names)))
|
|
end
|
|
fcommon.InformationTooltip(string.format("Place your dff & txd files inside,\n'%s'\n\
|
|
Note:\nFile names can't exceed 8 characters.\nDon't change names while the game is running",fplayer.tplayer.custom_skins.path))
|
|
imgui.Spacing()
|
|
|
|
if imgui.BeginChild("Custom skins") then
|
|
for model_name,_ in pairs(fplayer.tplayer.custom_skins.names) do
|
|
if module.tplayer.custom_skins.filter:PassFilter(model_name) then
|
|
model_name = string.sub(model_name,1,-5)
|
|
if #model_name < 9 and imgui.MenuItemBool(model_name) then
|
|
fplayer.ChangePlayerModel(model_name)
|
|
print(model_name)
|
|
end
|
|
end
|
|
end
|
|
imgui.EndChild()
|
|
end
|
|
else
|
|
imgui.TextWrapped("Modloader is not installed. Please install modloader.")
|
|
imgui.Spacing()
|
|
if imgui.Button("Download Modloader",imgui.ImVec2(fcommon.GetSize(1))) then
|
|
os.execute('explorer "https://gtaforums.com/topic/669520-mod-loader/"')
|
|
end
|
|
end
|
|
end
|
|
fcommon.EndTabBar()
|
|
end
|
|
end
|
|
fcommon.EndTabBar()
|
|
end
|
|
end
|
|
|
|
return module
|