433 lines
12 KiB
C++
433 lines
12 KiB
C++
|
#include "pch.h"
|
||
|
#include "Player.h"
|
||
|
#include "Ped.h"
|
||
|
#include "CCheat.h"
|
||
|
#include "Menu.h"
|
||
|
|
||
|
bool Player::keep_position::state = false;
|
||
|
CVector Player::keep_position::pos = CVector();
|
||
|
bool Player::god_mode = false;
|
||
|
int Player::body = 0;
|
||
|
bool Player::aim_skin_changer = false;
|
||
|
|
||
|
ImGuiTextFilter Player::filter = "";
|
||
|
std::vector<std::string> Player::search_categories;
|
||
|
std::vector<std::unique_ptr<TextureStructure>> Player::clothes_vec;
|
||
|
std::string Player::selected_item = "All";
|
||
|
|
||
|
std::string Player::custom_skins::dir = paths::GetGameDirPathA() + std::string("\\modloader\\Custom Skins\\");
|
||
|
std::vector<std::string> Player::custom_skins::store_vec;
|
||
|
ImGuiTextFilter Player::custom_skins::filter = "";
|
||
|
|
||
|
bool Player::modloader_installed = false;
|
||
|
|
||
|
Player::Player()
|
||
|
{
|
||
|
Events::initGameEvent += []
|
||
|
{
|
||
|
std::string dir_path = (std::string(".\\CheatMenu\\clothes\\")).c_str();
|
||
|
aim_skin_changer = config.GetValue("aim_skin_changer", false);
|
||
|
Util::LoadTexturesInDirRecursive(dir_path.c_str(), ".jpg", search_categories, clothes_vec);
|
||
|
|
||
|
// Custom skins setup
|
||
|
if (LoadLibraryW(L"modloader.asi"))
|
||
|
{
|
||
|
if (std::experimental::filesystem::is_directory(custom_skins::dir))
|
||
|
{
|
||
|
for (auto &p : std::experimental::filesystem::recursive_directory_iterator(custom_skins::dir))
|
||
|
{
|
||
|
if (p.path().extension() == ".dff")
|
||
|
{
|
||
|
std::string file_name = p.path().stem().string();
|
||
|
|
||
|
if (file_name.size() < 9)
|
||
|
custom_skins::store_vec.push_back(file_name);
|
||
|
else
|
||
|
flog << "Custom Skin '" << file_name << "' longer than 8 characters" << std::endl;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else std::experimental::filesystem::create_directory(custom_skins::dir);
|
||
|
|
||
|
modloader_installed = true;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Events::shutdownRwEvent += []
|
||
|
{
|
||
|
config.SetValue("aim_skin_changer", aim_skin_changer);
|
||
|
};
|
||
|
|
||
|
Events::processScriptsEvent += []
|
||
|
{
|
||
|
uint timer = CTimer::m_snTimeInMilliseconds;
|
||
|
static CPlayerPed* player = FindPlayerPed();
|
||
|
|
||
|
if (keep_position::state)
|
||
|
{
|
||
|
if (!player->IsAlive())
|
||
|
{
|
||
|
keep_position::pos = player->GetPosition();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CVector cur_pos = player->GetPosition();
|
||
|
|
||
|
if (keep_position::pos.x != 0 && keep_position::pos.x != cur_pos.x
|
||
|
&& keep_position::pos.y != 0 && keep_position::pos.y != cur_pos.y)
|
||
|
{
|
||
|
player->Teleport(keep_position::pos, false);
|
||
|
keep_position::pos = CVector(0, 0, 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (god_mode)
|
||
|
{
|
||
|
patch::Set<bool>(0x96916D, 1, false);
|
||
|
player->m_nPhysicalFlags.bBulletProof = 1;
|
||
|
player->m_nPhysicalFlags.bCollisionProof = 1;
|
||
|
player->m_nPhysicalFlags.bExplosionProof = 1;
|
||
|
player->m_nPhysicalFlags.bFireProof = 1;
|
||
|
player->m_nPhysicalFlags.bMeeleProof = 1;
|
||
|
}
|
||
|
|
||
|
if (aim_skin_changer && Ui::HotKeyPressed(Menu::hotkey::aim_skin_changer))
|
||
|
{
|
||
|
CPed *target_ped = player->m_pPlayerTargettedPed;
|
||
|
if (target_ped)
|
||
|
{
|
||
|
player->SetModelIndex(target_ped->m_nModelIndex);
|
||
|
Util::ClearCharTasksVehCheck(player);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
|
||
|
Player::~Player()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void Player::ChangePlayerCloth(std::string &name)
|
||
|
{
|
||
|
std::stringstream ss(name);
|
||
|
std::string temp;
|
||
|
|
||
|
getline(ss, temp, '$');
|
||
|
int body_part = std::stoi(temp);
|
||
|
|
||
|
getline(ss, temp, '$');
|
||
|
std::string model = temp.c_str();
|
||
|
|
||
|
getline(ss, temp, '$');
|
||
|
std::string texture9 = temp.c_str();
|
||
|
|
||
|
CPlayerPed *player = FindPlayerPed();
|
||
|
|
||
|
if (texture9 == "cutoffchinosblue")
|
||
|
{
|
||
|
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(-697413025, 744365350, body_part);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (texture9 == "sneakerbincblue")
|
||
|
{
|
||
|
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(-915574819, 2099005073, body_part);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (texture9 == "12myfac")
|
||
|
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(-1750049245, 1393983095, body_part);
|
||
|
else
|
||
|
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(texture9.c_str(), model.c_str(), body_part);
|
||
|
}
|
||
|
}
|
||
|
CClothes::RebuildPlayer(player, false);
|
||
|
}
|
||
|
|
||
|
void Player::ChangePlayerModel(std::string& model)
|
||
|
{
|
||
|
bool custom_skin = std::find(custom_skins::store_vec.begin(), custom_skins::store_vec.end(), model) != custom_skins::store_vec.end();
|
||
|
if (Ped::ped_json.data.contains(model) || custom_skin)
|
||
|
{
|
||
|
CPlayerPed *player = FindPlayerPed();
|
||
|
if (Ped::pedspecial_json.data.contains(model) || custom_skin)
|
||
|
{
|
||
|
std::string name;
|
||
|
if (Ped::pedspecial_json.data.contains(model))
|
||
|
name = Ped::pedspecial_json.data[model].get<std::string>().c_str();
|
||
|
else
|
||
|
name = model;
|
||
|
|
||
|
CStreaming::RequestSpecialChar(1, name.c_str(), PRIORITY_REQUEST);
|
||
|
CStreaming::LoadAllRequestedModels(true);
|
||
|
|
||
|
player->SetModelIndex(291);
|
||
|
|
||
|
CStreaming::SetSpecialCharIsDeletable(291);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int imodel = std::stoi(model);
|
||
|
|
||
|
CStreaming::RequestModel(imodel,eStreamingFlags::PRIORITY_REQUEST);
|
||
|
CStreaming::LoadAllRequestedModels(false);
|
||
|
player->SetModelIndex(imodel);
|
||
|
CStreaming::SetModelIsDeletable(imodel);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Player::Main()
|
||
|
{
|
||
|
static CPlayerPed* player = FindPlayerPed();
|
||
|
static int hplayer = CPools::GetPedRef(player);
|
||
|
static CPad* pad = player->GetPadFromPlayer();
|
||
|
|
||
|
if (ImGui::Button("Copy coordinates", ImVec2(Ui::GetSize(2))))
|
||
|
{
|
||
|
CVector pos = player->GetPosition();
|
||
|
std::string text = std::to_string(pos.x) + ", " + std::to_string(pos.y) + ", " + std::to_string(pos.z);
|
||
|
|
||
|
ImGui::SetClipboardText(text.c_str());
|
||
|
CHud::SetHelpMessage("Coordinates copied", false, false, false);
|
||
|
}
|
||
|
ImGui::SameLine();
|
||
|
if (ImGui::Button("Suicide", ImVec2(Ui::GetSize(2))))
|
||
|
player->m_fHealth = 0.0;
|
||
|
|
||
|
ImGui::Spacing();
|
||
|
|
||
|
if (ImGui::BeginTabBar("Player", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
|
||
|
{
|
||
|
if (ImGui::BeginTabItem("Checkboxes"))
|
||
|
{
|
||
|
ImGui::Spacing();
|
||
|
|
||
|
ImGui::BeginChild("CheckboxesChild");
|
||
|
|
||
|
ImGui::Columns(2, 0, false);
|
||
|
|
||
|
Ui::CheckboxAddress("Bounty on yourself", 0x96913F);
|
||
|
if (Ui::CheckboxWithHint("God mode", &god_mode))
|
||
|
{
|
||
|
patch::Set<bool>(0x96916D, god_mode, false);
|
||
|
player->m_nPhysicalFlags.bBulletProof = god_mode;
|
||
|
player->m_nPhysicalFlags.bCollisionProof = god_mode;
|
||
|
player->m_nPhysicalFlags.bExplosionProof = god_mode;
|
||
|
player->m_nPhysicalFlags.bFireProof = god_mode;
|
||
|
player->m_nPhysicalFlags.bMeeleProof = god_mode;
|
||
|
}
|
||
|
|
||
|
Ui::CheckboxAddress("Higher cycle jumps", 0x969161);
|
||
|
Ui::CheckboxAddress("Infinite oxygen", 0x96916E);
|
||
|
Ui::CheckboxAddress("Infinite run", 0xB7CEE4);
|
||
|
if (Ui::CheckboxBitFlag("Invisible player", player->m_nPedFlags.bDontRender))
|
||
|
player->m_nPedFlags.bDontRender = (player->m_nPedFlags.bDontRender == 1) ? 0 : 1;
|
||
|
|
||
|
ImGui::NextColumn();
|
||
|
|
||
|
Ui::CheckboxWithHint("Keep position", &keep_position::state, "Teleport to the position you died from");
|
||
|
if (Ui::CheckboxBitFlag("Lock control", pad->bPlayerSafe))
|
||
|
pad->bPlayerSafe = (pad->bPlayerSafe == 1) ? 0 : 1;
|
||
|
|
||
|
Ui::CheckboxAddress("Mega jump", 0x96916C);
|
||
|
Ui::CheckboxAddress("Mega punch", 0x969173);
|
||
|
Ui::CheckboxAddress("Never get hungry", 0x969174);
|
||
|
|
||
|
bool never_wanted = patch::Get<bool>(0x969171, false);
|
||
|
if (Ui::CheckboxWithHint("Never wanted", &never_wanted))
|
||
|
CCheat::NotWantedCheat();
|
||
|
|
||
|
ImGui::Columns(1);
|
||
|
|
||
|
ImGui::EndChild();
|
||
|
ImGui::EndTabItem();
|
||
|
}
|
||
|
|
||
|
if (ImGui::BeginTabItem("Menus"))
|
||
|
{
|
||
|
ImGui::BeginChild("PlayerMenus");
|
||
|
|
||
|
Ui::EditReference("Armour", player->m_fArmour, 0, 100, 150);
|
||
|
if (ImGui::CollapsingHeader("Body"))
|
||
|
{
|
||
|
if (player->m_nModelIndex == 0)
|
||
|
{
|
||
|
ImGui::Columns(3, 0, false);
|
||
|
if (ImGui::RadioButton("Fat", &body, 2))
|
||
|
CCheat::FatCheat();
|
||
|
|
||
|
ImGui::NextColumn();
|
||
|
|
||
|
if (ImGui::RadioButton("Muscle", &body, 1))
|
||
|
CCheat::MuscleCheat();
|
||
|
|
||
|
ImGui::NextColumn();
|
||
|
|
||
|
if (ImGui::RadioButton("Skinny", &body, 0))
|
||
|
CCheat::SkinnyCheat();
|
||
|
|
||
|
ImGui::Columns(1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ImGui::TextWrapped("You need to be in CJ skin.");
|
||
|
ImGui::Spacing();
|
||
|
|
||
|
if (ImGui::Button("Change to CJ skin", ImVec2(Ui::GetSize(1))))
|
||
|
{
|
||
|
player->SetModelIndex(0);
|
||
|
Util::ClearCharTasksVehCheck(player);
|
||
|
}
|
||
|
}
|
||
|
ImGui::Spacing();
|
||
|
ImGui::Separator();
|
||
|
}
|
||
|
|
||
|
Ui::EditStat("Energy", STAT_ENERGY);
|
||
|
Ui::EditStat("Fat", STAT_FAT);
|
||
|
Ui::EditReference("Health", player->m_fHealth, 0, 100, static_cast<int>(player->m_fMaxHealth));
|
||
|
Ui::EditStat("Lung capacity", STAT_LUNG_CAPACITY);
|
||
|
Ui::EditStat("Max health", STAT_MAX_HEALTH,0,569,1450);
|
||
|
Ui::EditAddress<int>("Money", 0xB7CE50, -99999999, 0, 99999999);
|
||
|
Ui::EditStat("Muscle", STAT_MUSCLE);
|
||
|
Ui::EditStat("Respect", STAT_RESPECT);
|
||
|
Ui::EditStat("Stamina", STAT_STAMINA);
|
||
|
if (ImGui::CollapsingHeader("Wanted level"))
|
||
|
{
|
||
|
int val = player->m_pPlayerData->m_pWanted->m_nWantedLevel;
|
||
|
|
||
|
ImGui::Columns(3, 0, false);
|
||
|
ImGui::Text("Min: 0");
|
||
|
ImGui::NextColumn();
|
||
|
ImGui::Text("Def: 0");
|
||
|
ImGui::NextColumn();
|
||
|
ImGui::Text("Max: 6");
|
||
|
ImGui::Columns(1);
|
||
|
|
||
|
ImGui::Spacing();
|
||
|
|
||
|
if (ImGui::InputInt("Set value##Wanted level", &val))
|
||
|
player->CheatWantedLevel(val);
|
||
|
|
||
|
ImGui::Spacing();
|
||
|
|
||
|
if (ImGui::Button("Minimum##Wanted level", Ui::GetSize(3)))
|
||
|
player->CheatWantedLevel(0);
|
||
|
|
||
|
ImGui::SameLine();
|
||
|
|
||
|
if (ImGui::Button("Default##Wanted level", Ui::GetSize(3)))
|
||
|
player->CheatWantedLevel(0);
|
||
|
|
||
|
ImGui::SameLine();
|
||
|
|
||
|
if (ImGui::Button("Maximum##Wanted level", Ui::GetSize(3)))
|
||
|
player->CheatWantedLevel(6);
|
||
|
|
||
|
ImGui::Spacing();
|
||
|
ImGui::Separator();
|
||
|
}
|
||
|
|
||
|
ImGui::EndChild();
|
||
|
ImGui::EndTabItem();
|
||
|
}
|
||
|
|
||
|
if (ImGui::BeginTabItem("Appearance"))
|
||
|
{
|
||
|
ImGui::Spacing();
|
||
|
Ui::CheckboxWithHint("Aim skin changer", &aim_skin_changer,
|
||
|
(("Activate using Aim ped + ") + Ui::GetHotKeyNameString(Menu::hotkey::aim_skin_changer)).c_str());
|
||
|
|
||
|
if (ImGui::BeginTabBar("AppearanceTabBar"))
|
||
|
{
|
||
|
if (ImGui::BeginTabItem("Clothes"))
|
||
|
{
|
||
|
ImGui::Spacing();
|
||
|
|
||
|
if (player->m_nModelIndex == 0)
|
||
|
{
|
||
|
if (ImGui::Button("Remove clothes", ImVec2(Ui::GetSize())))
|
||
|
{
|
||
|
CPlayerPed *player = FindPlayerPed();
|
||
|
|
||
|
int temp = 0;
|
||
|
for (uint i = 0; i < 18; i++)
|
||
|
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(temp, temp, i);
|
||
|
|
||
|
CClothes::RebuildPlayer(player, false);
|
||
|
}
|
||
|
ImGui::Spacing();
|
||
|
|
||
|
Ui::DrawImages(clothes_vec, ImVec2(70, 100), search_categories, selected_item, filter, ChangePlayerCloth, nullptr,
|
||
|
[](std::string str)
|
||
|
{
|
||
|
std::stringstream ss(str);
|
||
|
std::string temp;
|
||
|
|
||
|
getline(ss, temp, '$');
|
||
|
getline(ss, temp, '$');
|
||
|
|
||
|
return temp;
|
||
|
});
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ImGui::TextWrapped("You need to be in CJ skin.");
|
||
|
ImGui::Spacing();
|
||
|
|
||
|
if (ImGui::Button("Change to CJ skin", ImVec2(Ui::GetSize(1))))
|
||
|
{
|
||
|
player->SetModelIndex(0);
|
||
|
Util::ClearCharTasksVehCheck(player);
|
||
|
}
|
||
|
}
|
||
|
ImGui::EndTabItem();
|
||
|
}
|
||
|
if (ImGui::BeginTabItem("Ped skins"))
|
||
|
{
|
||
|
Ui::DrawImages(Ped::peds_vec, ImVec2(65, 110), Ped::search_categories, Ped::selected_item, Ped::filter, ChangePlayerModel, nullptr,
|
||
|
[](std::string str) {return Ped::ped_json.data[str].get<std::string>(); });
|
||
|
ImGui::EndTabItem();
|
||
|
}
|
||
|
if (ImGui::BeginTabItem("Custom skins"))
|
||
|
{
|
||
|
ImGui::Spacing();
|
||
|
Ui::FilterWithHint("Search", filter, std::string("Total skins: " + std::to_string(custom_skins::store_vec.size())).c_str());
|
||
|
Ui::ShowTooltip("Place your dff & txd files inside 'modloader/Custom Skins'");
|
||
|
ImGui::Spacing();
|
||
|
ImGui::TextWrapped("Note: Your txd & dff names can't exceed 8 characters. Don't change names while the game is running.");
|
||
|
ImGui::Spacing();
|
||
|
if (modloader_installed)
|
||
|
{
|
||
|
for (std::string name : custom_skins::store_vec)
|
||
|
{
|
||
|
if (custom_skins::filter.PassFilter(name.c_str()))
|
||
|
{
|
||
|
if (ImGui::MenuItem(name.c_str()))
|
||
|
{
|
||
|
ChangePlayerModel(name);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ImGui::TextWrapped("Modloader is not installed. Please install modloader.");
|
||
|
ImGui::Spacing();
|
||
|
if (ImGui::Button("Download Modloader", ImVec2(Ui::GetSize(1))))
|
||
|
ShellExecute(NULL, "open", "https://gtaforums.com/topic/669520-mod-loader/", NULL, NULL, SW_SHOWNORMAL);
|
||
|
}
|
||
|
ImGui::EndTabItem();
|
||
|
}
|
||
|
ImGui::EndTabBar();
|
||
|
}
|
||
|
ImGui::EndTabItem();
|
||
|
}
|
||
|
|
||
|
ImGui::EndTabBar();
|
||
|
}
|
||
|
}
|