Refactor code, fixes

This commit is contained in:
Grinch_ 2022-01-07 14:18:00 +06:00
parent 6044deb156
commit 2b58d9488d
47 changed files with 7569 additions and 7495 deletions

27
.vscode/tasks.json vendored
View File

@ -246,5 +246,32 @@
} }
}, },
}, },
{
"label": "Format Code",
"type": "shell",
"command": "${workspaceFolder}/tools/FormatCode.bat",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": false,
"clear": true
},
"group": {
"kind": "build",
"isDefault": true
},
"windows": {
"options": {
"shell": {
"executable": "cmd.exe",
"args": [
"/d", "/c"
]
}
}
},
},
] ]
} }

View File

@ -18,23 +18,23 @@
#ifdef GTASA #ifdef GTASA
void Animation::PlayCutscene(std::string& rootKey, std::string& cutsceneId, std::string& interior) void Animation::PlayCutscene(std::string& rootKey, std::string& cutsceneId, std::string& interior)
{ {
if (Util::IsOnCutscene()) if (Util::IsOnCutscene())
{ {
SetHelpMessage("Another cutscene is running", false, false, false); SetHelpMessage("Another cutscene is running", false, false, false);
return; return;
} }
CPlayerPed* pPlayer = FindPlayerPed(); CPlayerPed* pPlayer = FindPlayerPed();
if (!pPlayer) if (!pPlayer)
{ {
return; return;
} }
m_Cutscene::m_SceneName = cutsceneId; m_Cutscene::m_SceneName = cutsceneId;
Command<Commands::LOAD_CUTSCENE>(cutsceneId.c_str()); Command<Commands::LOAD_CUTSCENE>(cutsceneId.c_str());
m_Cutscene::m_nInterior = pPlayer->m_nAreaCode; m_Cutscene::m_nInterior = pPlayer->m_nAreaCode;
pPlayer->m_nAreaCode = std::stoi(interior); pPlayer->m_nAreaCode = std::stoi(interior);
Command<Commands::SET_AREA_VISIBLE>(pPlayer->m_nAreaCode); Command<Commands::SET_AREA_VISIBLE>(pPlayer->m_nAreaCode);
} }
#elif GTAVC #elif GTAVC
@ -43,321 +43,321 @@ void Animation::PlayCutscene(std::string& rootKey, std::string& cutsceneId, std:
static auto OLD_CStreaming_RemoveModel = (bool(__cdecl*)(int))0x40D6E0; static auto OLD_CStreaming_RemoveModel = (bool(__cdecl*)(int))0x40D6E0;
static bool NEW_CStreaming_RemoveModel(int modelID) static bool NEW_CStreaming_RemoveModel(int modelID)
{ {
// Check if it's IFP animation block // Check if it's IFP animation block
if (modelID >= 7916 && modelID <= 7950) if (modelID >= 7916 && modelID <= 7950)
{ {
// Do not unload the animation block // Do not unload the animation block
return true; return true;
} }
return OLD_CStreaming_RemoveModel(modelID); return OLD_CStreaming_RemoveModel(modelID);
} }
void Animation::_PlayAnimation(RpClump* pClump, int animGroup, int animID, float blend) void Animation::_PlayAnimation(RpClump* pClump, int animGroup, int animID, float blend)
{ {
if (animGroup < CAnimManager::ms_numAnimAssocDefinitions) if (animGroup < CAnimManager::ms_numAnimAssocDefinitions)
{ {
CAnimationStyleDescriptor* pAnimDef = &CAnimManager::ms_aAnimAssocDefinitions[animGroup]; CAnimationStyleDescriptor* pAnimDef = &CAnimManager::ms_aAnimAssocDefinitions[animGroup];
if (pAnimDef) if (pAnimDef)
{ {
if (!_LoadAnimationBlock(pAnimDef->blockName)) if (!_LoadAnimationBlock(pAnimDef->blockName))
{ {
return; return;
} }
} }
} }
CAnimBlendAssociation* pAnimAssoc = RpAnimBlendClumpGetFirstAssociation(pClump); CAnimBlendAssociation* pAnimAssoc = RpAnimBlendClumpGetFirstAssociation(pClump);
while (pAnimAssoc) while (pAnimAssoc)
{ {
if (pAnimAssoc->m_nAnimId == animID && pAnimAssoc->m_nAnimGroup == animGroup) if (pAnimAssoc->m_nAnimId == animID && pAnimAssoc->m_nAnimGroup == animGroup)
{ {
// Destroy the animation // Destroy the animation
pAnimAssoc->~CAnimBlendAssociation(); pAnimAssoc->~CAnimBlendAssociation();
break; break;
} }
pAnimAssoc = RpAnimBlendGetNextAssociation(pAnimAssoc); pAnimAssoc = RpAnimBlendGetNextAssociation(pAnimAssoc);
} }
pAnimAssoc = CAnimManager::BlendAnimation(pClump, animGroup, animID, blend); pAnimAssoc = CAnimManager::BlendAnimation(pClump, animGroup, animID, blend);
pAnimAssoc->m_nFlags = ANIMATION_STARTED | ANIMATION_MOVEMENT; pAnimAssoc->m_nFlags = ANIMATION_STARTED | ANIMATION_MOVEMENT;
if (m_Loop)
{
pAnimAssoc->m_nFlags |= ANIMATION_LOOPED;
}
if (m_bSecondary) if (m_Loop)
{ {
pAnimAssoc->m_nFlags |= ANIMATION_PARTIAL; pAnimAssoc->m_nFlags |= ANIMATION_LOOPED;
} }
if (m_bSecondary)
{
pAnimAssoc->m_nFlags |= ANIMATION_PARTIAL;
}
} }
bool Animation::_LoadAnimationBlock(const char* szBlockName) bool Animation::_LoadAnimationBlock(const char* szBlockName)
{ {
CAnimBlock* pAnimBlock = CAnimManager::GetAnimationBlock(szBlockName); CAnimBlock* pAnimBlock = CAnimManager::GetAnimationBlock(szBlockName);
if (pAnimBlock) if (pAnimBlock)
{ {
if (!pAnimBlock->bLoaded) if (!pAnimBlock->bLoaded)
{ {
int animIndex = ((unsigned char*)pAnimBlock - (unsigned char*)CAnimManager::ms_aAnimBlocks) / 32; int animIndex = ((unsigned char*)pAnimBlock - (unsigned char*)CAnimManager::ms_aAnimBlocks) / 32;
CStreaming::RequestModel(7916 + animIndex, 0x20 | MISSION_REQUIRED | PRIORITY_REQUEST); CStreaming::RequestModel(7916 + animIndex, 0x20 | MISSION_REQUIRED | PRIORITY_REQUEST);
CStreaming::LoadAllRequestedModels(true); CStreaming::LoadAllRequestedModels(true);
if (pAnimBlock->bLoaded) if (pAnimBlock->bLoaded)
{ {
return true; return true;
} }
} }
else else
{ {
return true; return true;
} }
} }
return false; return false;
} }
#else // GTA III #else
void Animation::_PlayAnimation(RpClump* pClump, int animGroup, int animID, float blend) void Animation::_PlayAnimation(RpClump* pClump, int animGroup, int animID, float blend)
{ {
CAnimBlendAssociation* pAnimStaticAssoc = CAnimManager::GetAnimAssociation((AssocGroupId)animGroup, (AnimationId)animID); CAnimBlendAssociation* pAnimStaticAssoc = CAnimManager::GetAnimAssociation((AssocGroupId)animGroup, (AnimationId)animID);
CAnimBlendAssociation* pAnimAssoc = RpAnimBlendClumpGetFirstAssociation(pClump); CAnimBlendAssociation* pAnimAssoc = RpAnimBlendClumpGetFirstAssociation(pClump);
while (pAnimAssoc) while (pAnimAssoc)
{ {
if (pAnimAssoc->m_nAnimID == pAnimStaticAssoc->m_nAnimID && pAnimAssoc->m_pAnimBlendHierarchy == pAnimStaticAssoc->m_pAnimBlendHierarchy) if (pAnimAssoc->m_nAnimID == pAnimStaticAssoc->m_nAnimID && pAnimAssoc->m_pAnimBlendHierarchy == pAnimStaticAssoc->m_pAnimBlendHierarchy)
{ {
// Destroy the animation // Destroy the animation
pAnimAssoc->FreeAnimBlendNodeArray(); pAnimAssoc->FreeAnimBlendNodeArray();
break; break;
} }
pAnimAssoc = RpAnimBlendGetNextAssociation(pAnimAssoc); pAnimAssoc = RpAnimBlendGetNextAssociation(pAnimAssoc);
} }
pAnimAssoc = CAnimManager::BlendAnimation(pClump, (AssocGroupId)animGroup, (AnimationId)animID, blend); pAnimAssoc = CAnimManager::BlendAnimation(pClump, (AssocGroupId)animGroup, (AnimationId)animID, blend);
pAnimAssoc->m_nFlags = 0x1 | 0x20; pAnimAssoc->m_nFlags = 0x1 | 0x20;
if (m_Loop)
{
pAnimAssoc->m_nFlags |= 0x2;
}
if (m_bSecondary) if (m_Loop)
{ {
pAnimAssoc->m_nFlags |= 0x10; pAnimAssoc->m_nFlags |= 0x2;
} }
if (m_bSecondary)
{
pAnimAssoc->m_nFlags |= 0x10;
}
} }
#endif #endif
void Animation::PlayAnimation(std::string& ifp, std::string& anim, std::string& value) void Animation::PlayAnimation(std::string& ifp, std::string& anim, std::string& value)
{ {
CPlayerPed *pPlayer = FindPlayerPed(); CPlayerPed *pPlayer = FindPlayerPed();
if (!pPlayer) if (!pPlayer)
{ {
return; return;
} }
#ifdef GTASA #ifdef GTASA
int hplayer = CPools::GetPedRef(pPlayer); int hplayer = CPools::GetPedRef(pPlayer);
if (ifp != "PED") if (ifp != "PED")
{ {
Command<Commands::REQUEST_ANIMATION>(ifp.c_str()); Command<Commands::REQUEST_ANIMATION>(ifp.c_str());
Command<Commands::LOAD_ALL_MODELS_NOW>(); Command<Commands::LOAD_ALL_MODELS_NOW>();
} }
Command<Commands::CLEAR_CHAR_TASKS>(hplayer); Command<Commands::CLEAR_CHAR_TASKS>(hplayer);
if (m_bSecondary) if (m_bSecondary)
{ {
Command<Commands::TASK_PLAY_ANIM_SECONDARY>(hplayer, anim.c_str(), ifp.c_str(), 4.0, m_Loop, 0, 0, 0, -1); Command<Commands::TASK_PLAY_ANIM_SECONDARY>(hplayer, anim.c_str(), ifp.c_str(), 4.0, m_Loop, 0, 0, 0, -1);
} }
else else
{ {
Command<Commands::TASK_PLAY_ANIM>(hplayer, anim.c_str(), ifp.c_str(), 4.0, m_Loop, 0, 0, 0, -1); Command<Commands::TASK_PLAY_ANIM>(hplayer, anim.c_str(), ifp.c_str(), 4.0, m_Loop, 0, 0, 0, -1);
} }
if (ifp != "PED") if (ifp != "PED")
{ {
Command<Commands::REMOVE_ANIMATION>(ifp.c_str()); Command<Commands::REMOVE_ANIMATION>(ifp.c_str());
} }
#else // GTA VC & III #else
if (pPlayer) if (pPlayer)
{ {
int groupID, animID; int groupID, animID;
sscanf(value.c_str(), "%d$%d,", &groupID, &animID); sscanf(value.c_str(), "%d$%d,", &groupID, &animID);
_PlayAnimation(pPlayer->m_pRwClump, groupID, animID, 4.0f); _PlayAnimation(pPlayer->m_pRwClump, groupID, animID, 4.0f);
} }
#endif #endif
} }
Animation::Animation() Animation::Animation()
{ {
#ifdef GTASA #ifdef GTASA
Events::processScriptsEvent += [this] Events::processScriptsEvent += [this]
{ {
if (m_Cutscene::m_bRunning) if (m_Cutscene::m_bRunning)
{ {
if (Command<Commands::HAS_CUTSCENE_FINISHED>()) if (Command<Commands::HAS_CUTSCENE_FINISHED>())
{ {
CPlayerPed* pPlayer = FindPlayerPed(); CPlayerPed* pPlayer = FindPlayerPed();
if (!pPlayer) if (!pPlayer)
{ {
return; return;
} }
pPlayer->m_nAreaCode = m_Cutscene::m_nInterior; pPlayer->m_nAreaCode = m_Cutscene::m_nInterior;
Command<Commands::SET_AREA_VISIBLE>(pPlayer->m_nAreaCode); Command<Commands::SET_AREA_VISIBLE>(pPlayer->m_nAreaCode);
m_Cutscene::m_nInterior = 0; m_Cutscene::m_nInterior = 0;
TheCamera.Fade(0, 1); TheCamera.Fade(0, 1);
} }
} }
else else
{ {
if (m_Cutscene::m_SceneName != "" && Command<Commands::HAS_CUTSCENE_LOADED>()) if (m_Cutscene::m_SceneName != "" && Command<Commands::HAS_CUTSCENE_LOADED>())
{ {
Command<Commands::START_CUTSCENE>(); Command<Commands::START_CUTSCENE>();
m_Cutscene::m_bRunning = true; m_Cutscene::m_bRunning = true;
} }
} }
}; };
#elif GTAVC #elif GTAVC
// mov al, 01 // mov al, 01
// ret // ret
// nop (2x) // nop (2x)
patch::SetRaw(0x40C9C0, (void*)"\xB0\x01\xC3\x90\x90", 5); patch::SetRaw(0x40C9C0, (void*)"\xB0\x01\xC3\x90\x90", 5);
// // ret // // ret
// // nop (3x) // // nop (3x)
patch::SetRaw(0x404950, (void*)"\xC3\x90\x90\x90", 4); patch::SetRaw(0x404950, (void*)"\xC3\x90\x90\x90", 4);
MH_CreateHook((void*)0x40D6E0, NEW_CStreaming_RemoveModel, (void**)&OLD_CStreaming_RemoveModel); MH_CreateHook((void*)0x40D6E0, NEW_CStreaming_RemoveModel, (void**)&OLD_CStreaming_RemoveModel);
MH_EnableHook((void*)0x40D6E0); MH_EnableHook((void*)0x40D6E0);
#endif #endif
} }
void Animation::Draw() void Animation::Draw()
{ {
if (ImGui::BeginTabBar("Animation", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll)) if (ImGui::BeginTabBar("Animation", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
{ {
ImGui::Spacing(); ImGui::Spacing();
CPlayerPed* pPlayer = FindPlayerPed(); CPlayerPed* pPlayer = FindPlayerPed();
int hPlayer = CPools::GetPedRef(pPlayer); int hPlayer = CPools::GetPedRef(pPlayer);
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::BeginTabItem("Anims")) if (ImGui::BeginTabItem("Anims"))
{ {
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::Button("Stop animation", Ui::GetSize())) if (ImGui::Button("Stop animation", Ui::GetSize()))
{ {
if (hPlayer) if (hPlayer)
{ {
#ifdef GTASA #ifdef GTASA
Command<Commands::CLEAR_CHAR_TASKS>(hPlayer); Command<Commands::CLEAR_CHAR_TASKS>(hPlayer);
#else #else
_PlayAnimation(pPlayer->m_pRwClump, ANIM_GROUP_MAN, ANIM_MAN_IDLE_STANCE, 4.0f); _PlayAnimation(pPlayer->m_pRwClump, ANIM_GROUP_MAN, ANIM_MAN_IDLE_STANCE, 4.0f);
#endif #endif
} }
} }
ImGui::Spacing(); ImGui::Spacing();
ImGui::Columns(2, nullptr, false); ImGui::Columns(2, nullptr, false);
ImGui::Checkbox("Loop", &m_Loop); ImGui::Checkbox("Loop", &m_Loop);
Ui::ShowTooltip("Keep playing the animation on repeat"); Ui::ShowTooltip("Keep playing the animation on repeat");
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Checkbox("Secondary", &m_bSecondary); ImGui::Checkbox("Secondary", &m_bSecondary);
Ui::ShowTooltip("Player can move while playing the animation"); Ui::ShowTooltip("Player can move while playing the animation");
ImGui::Columns(1); ImGui::Columns(1);
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::BeginChild("Anims Child")) if (ImGui::BeginChild("Anims Child"))
{ {
ImGui::Spacing(); ImGui::Spacing();
Ui::DrawJSON(m_AnimData, PlayAnimation, RemoveAnimation); Ui::DrawJSON(m_AnimData, PlayAnimation, RemoveAnimation);
ImGui::EndChild(); ImGui::EndChild();
} }
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("Custom")) if (ImGui::BeginTabItem("Custom"))
{ {
ImGui::InputTextWithHint("IFP name", "ped", m_nIfpBuffer, INPUT_BUFFER_SIZE); ImGui::InputTextWithHint("IFP name", "ped", m_nIfpBuffer, INPUT_BUFFER_SIZE);
ImGui::InputTextWithHint("Anim name", "cower", m_nAnimBuffer, INPUT_BUFFER_SIZE); ImGui::InputTextWithHint("Anim name", "cower", m_nAnimBuffer, INPUT_BUFFER_SIZE);
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::Button("Add animation", Ui::GetSize())) if (ImGui::Button("Add animation", Ui::GetSize()))
{ {
m_AnimData.m_pJson->m_Data["Custom"][m_nAnimBuffer] = ("0, " + std::string(m_nIfpBuffer)); m_AnimData.m_pJson->m_Data["Custom"][m_nAnimBuffer] = ("0, " + std::string(m_nIfpBuffer));
m_AnimData.m_pJson->WriteToDisk(); m_AnimData.m_pJson->WriteToDisk();
} }
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
#ifdef GTASA #ifdef GTASA
if (ImGui::BeginTabItem("Misc")) if (ImGui::BeginTabItem("Misc"))
{ {
ImGui::Spacing(); ImGui::Spacing();
if (Ui::ListBox("Fighting style", m_FightingStyleList, m_nFightingStyle)) if (Ui::ListBox("Fighting style", m_FightingStyleList, m_nFightingStyle))
{ {
Command<Commands::GIVE_MELEE_ATTACK_TO_CHAR>(hPlayer, m_nFightingStyle + 4, 6); Command<Commands::GIVE_MELEE_ATTACK_TO_CHAR>(hPlayer, m_nFightingStyle + 4, 6);
SetHelpMessage("Fighting anim set", false, false, false); SetHelpMessage("Fighting anim set", false, false, false);
} }
if (Ui::ListBoxStr("Walking style", m_WalkingStyleList, m_nWalkingStyle)) if (Ui::ListBoxStr("Walking style", m_WalkingStyleList, m_nWalkingStyle))
{ {
if (m_nWalkingStyle == "default") if (m_nWalkingStyle == "default")
{ {
patch::Set<DWORD>(0x609A4E, 0x4D48689); patch::Set<DWORD>(0x609A4E, 0x4D48689);
patch::Set<WORD>(0x609A52, 0); patch::Set<WORD>(0x609A52, 0);
} }
else else
{ {
patch::Nop(0x609A4E, 6); patch::Nop(0x609A4E, 6);
Command<Commands::REQUEST_ANIMATION>(m_nWalkingStyle.c_str()); Command<Commands::REQUEST_ANIMATION>(m_nWalkingStyle.c_str());
Command<Commands::LOAD_ALL_MODELS_NOW>(); Command<Commands::LOAD_ALL_MODELS_NOW>();
Command<Commands::SET_ANIM_GROUP_FOR_CHAR>(hPlayer, m_nWalkingStyle.c_str()); Command<Commands::SET_ANIM_GROUP_FOR_CHAR>(hPlayer, m_nWalkingStyle.c_str());
Command<Commands::REMOVE_ANIMATION>(m_nWalkingStyle.c_str()); Command<Commands::REMOVE_ANIMATION>(m_nWalkingStyle.c_str());
} }
SetHelpMessage("Walking anim set", false, false, false); SetHelpMessage("Walking anim set", false, false, false);
} }
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("Cutscene")) if (ImGui::BeginTabItem("Cutscene"))
{ {
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::Button("Stop cutscene", Ui::GetSize())) if (ImGui::Button("Stop cutscene", Ui::GetSize()))
{ {
if (m_Cutscene::m_bRunning) if (m_Cutscene::m_bRunning)
{ {
Command<Commands::CLEAR_CUTSCENE>(); Command<Commands::CLEAR_CUTSCENE>();
m_Cutscene::m_bRunning = false; m_Cutscene::m_bRunning = false;
m_Cutscene::m_SceneName = ""; m_Cutscene::m_SceneName = "";
CPlayerPed* player = FindPlayerPed(); CPlayerPed* player = FindPlayerPed();
player->m_nAreaCode = m_Cutscene::m_nInterior; player->m_nAreaCode = m_Cutscene::m_nInterior;
Command<Commands::SET_AREA_VISIBLE>(player->m_nAreaCode); Command<Commands::SET_AREA_VISIBLE>(player->m_nAreaCode);
m_Cutscene::m_nInterior = 0; m_Cutscene::m_nInterior = 0;
TheCamera.Fade(0, 1); TheCamera.Fade(0, 1);
} }
} }
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::BeginChild("Cutscene Child")) if (ImGui::BeginChild("Cutscene Child"))
{ {
ImGui::Spacing(); ImGui::Spacing();
Ui::DrawJSON(m_Cutscene::m_Data, PlayCutscene, nullptr); Ui::DrawJSON(m_Cutscene::m_Data, PlayCutscene, nullptr);
ImGui::EndChild(); ImGui::EndChild();
} }
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
#endif #endif
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
} }
void Animation::RemoveAnimation(std::string& ifp, std::string& anim, std::string& ifpRepeat) void Animation::RemoveAnimation(std::string& ifp, std::string& anim, std::string& ifpRepeat)
{ {
if (ifp == "Custom") if (ifp == "Custom")
{ {
m_AnimData.m_pJson->m_Data["Custom"].erase(anim); m_AnimData.m_pJson->m_Data["Custom"].erase(anim);
m_AnimData.m_pJson->WriteToDisk(); m_AnimData.m_pJson->WriteToDisk();
SetHelpMessage("Animation removed", false, false, false); SetHelpMessage("Animation removed", false, false, false);
} }
else else
{ {
SetHelpMessage("You can only remove custom anims", false, false, false); SetHelpMessage("You can only remove custom anims", false, false, false);
} }
} }

View File

@ -5,50 +5,50 @@ class Animation
{ {
private: private:
// Animation player // Animation player
static inline ResourceStore m_AnimData{ "animation", eResourceType::TYPE_TEXT }; static inline ResourceStore m_AnimData{ "animation", eResourceType::TYPE_TEXT };
static inline char m_nAnimBuffer[INPUT_BUFFER_SIZE]; static inline char m_nAnimBuffer[INPUT_BUFFER_SIZE];
static inline char m_nIfpBuffer[INPUT_BUFFER_SIZE]; static inline char m_nIfpBuffer[INPUT_BUFFER_SIZE];
static inline bool m_Loop; // loop animation static inline bool m_Loop; // loop animation
static inline bool m_bSecondary; // play animation as secondary static inline bool m_bSecondary; // play animation as secondary
#ifdef GTASA #ifdef GTASA
// Cutscene player // Cutscene player
struct m_Cutscene struct m_Cutscene
{ {
static inline ResourceStore m_Data{ "cutscene", eResourceType::TYPE_TEXT }; static inline ResourceStore m_Data{ "cutscene", eResourceType::TYPE_TEXT };
static inline std::string m_SceneName; static inline std::string m_SceneName;
static inline int m_nInterior; // player interior backup static inline int m_nInterior; // player interior backup
static inline bool m_bRunning; static inline bool m_bRunning;
}; };
static inline int m_nFightingStyle; static inline int m_nFightingStyle;
static inline std::string m_nWalkingStyle = "default"; static inline std::string m_nWalkingStyle = "default";
static inline std::vector<std::string> m_FightingStyleList = static inline std::vector<std::string> m_FightingStyleList =
{ "Default", "Boxing", "Kung fu", "Kick Boxing", "Punch Kick" }; { "Default", "Boxing", "Kung fu", "Kick Boxing", "Punch Kick" };
static inline std::vector<std::string> m_WalkingStyleList = static inline std::vector<std::string> m_WalkingStyleList =
{ {
"default", "man", "shuffle", "oldman", "gang1", "gang2", "oldfatman", "default", "man", "shuffle", "oldman", "gang1", "gang2", "oldfatman",
"fatman", "jogger", "drunkman", "blindman", "swat", "woman", "shopping", "busywoman", "fatman", "jogger", "drunkman", "blindman", "swat", "woman", "shopping", "busywoman",
"sexywoman", "pro", "oldwoman", "fatwoman", "jogwoman", "oldfatwoman", "skate" "sexywoman", "pro", "oldwoman", "fatwoman", "jogwoman", "oldfatwoman", "skate"
}; };
#endif #endif
protected: protected:
Animation(); Animation();
public: public:
static void Draw(); static void Draw();
static void PlayAnimation(std::string& rootKey, std::string& anim, std::string& ifp); static void PlayAnimation(std::string& rootKey, std::string& anim, std::string& ifp);
static void RemoveAnimation(std::string& rootKey, std::string& anim, std::string& ifp); static void RemoveAnimation(std::string& rootKey, std::string& anim, std::string& ifp);
#ifdef GTASA #ifdef GTASA
static void PlayCutscene(std::string& rootKey, std::string& cutsceneId, std::string& interior); static void PlayCutscene(std::string& rootKey, std::string& cutsceneId, std::string& interior);
#elif GTAVC #elif GTAVC
static bool _LoadAnimationBlock(const char* szBlockName); static bool _LoadAnimationBlock(const char* szBlockName);
#endif #endif
#ifndef GTASA #ifndef GTASA
static void _PlayAnimation(RpClump* pClump, int animGroup, int animID, float blend); static void _PlayAnimation(RpClump* pClump, int animGroup, int animID, float blend);
#endif #endif
}; };

View File

@ -6,255 +6,255 @@
void CheatMenu::DrawWindow() void CheatMenu::DrawWindow()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
static bool bRunning = true; static bool bRunning = true;
if (BY_GAME(FrontEndMenuManager.m_bMenuActive, FrontendMenuManager.m_bMenuVisible, FrontEndMenuManager.m_bMenuActive)) if (BY_GAME(FrontEndMenuManager.m_bMenuActive, FrontendMenuManager.m_bMenuVisible, FrontEndMenuManager.m_bMenuActive))
{ {
if (bRunning) if (bRunning)
{ {
gConfig.WriteToDisk(); gConfig.WriteToDisk();
bRunning = false; bRunning = false;
m_bShowMouse = false; m_bShowMouse = false;
} }
} }
else else
{ {
bRunning = true; bRunning = true;
if (m_bShowMenu || BY_GAME(m_Commands::m_bShowMenu, true, true)) if (m_bShowMenu || BY_GAME(m_Commands::m_bShowMenu, true, true))
{ {
if (m_bShowMenu) if (m_bShowMenu)
{ {
ImGui::SetNextWindowSize(m_fMenuSize); ImGui::SetNextWindowSize(m_fMenuSize);
if (ImGui::Begin(MENU_TITLE, NULL, ImGuiWindowFlags_NoCollapse || ImGuiWindowFlags_NoTitleBar)) if (ImGui::Begin(MENU_TITLE, NULL, ImGuiWindowFlags_NoCollapse || ImGuiWindowFlags_NoTitleBar))
{ {
m_bShowMenu = !Ui::DrawTitleBar(); m_bShowMenu = !Ui::DrawTitleBar();
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(250, 350)); ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(250, 350));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,
ImVec2(ImGui::GetWindowWidth() / 85, ImGui::GetWindowHeight() / 200)); ImVec2(ImGui::GetWindowWidth() / 85, ImGui::GetWindowHeight() / 200));
if (Updater::IsUpdateAvailable()) if (Updater::IsUpdateAvailable())
{ {
ShowUpdateScreen(); ShowUpdateScreen();
} }
else else
{ {
Ui::DrawHeaders(header); Ui::DrawHeaders(header);
if (Ui::m_HeaderId == -1)
{
ShowWelcomeScreen();
}
}
if (m_bSizeChangedExternal) if (Ui::m_HeaderId == -1)
{ {
m_bSizeChangedExternal = false; ShowWelcomeScreen();
} }
else }
{
m_fMenuSize = ImGui::GetWindowSize();
}
gConfig.SetValue("window.sizeX", m_fMenuSize.x);
gConfig.SetValue("window.sizeY", m_fMenuSize.y);
ImGui::PopStyleVar(2); if (m_bSizeChangedExternal)
ImGui::End(); {
} m_bSizeChangedExternal = false;
} }
else
{
m_fMenuSize = ImGui::GetWindowSize();
}
gConfig.SetValue("window.sizeX", m_fMenuSize.x);
gConfig.SetValue("window.sizeY", m_fMenuSize.y);
ImGui::PopStyleVar(2);
ImGui::End();
}
}
#ifdef GTASA #ifdef GTASA
else else
{ {
DrawShortcutsWindow(); DrawShortcutsWindow();
} }
#endif #endif
} }
} }
DrawOverlay(); DrawOverlay();
} }
CheatMenu::CheatMenu() CheatMenu::CheatMenu()
{ {
ImGui::CreateContext(); ImGui::CreateContext();
ApplyStyle(); ApplyStyle();
pCallbackFunc = std::bind(&DrawWindow); pCallbackFunc = std::bind(&DrawWindow);
// Load menu settings // Load menu settings
Ui::m_HeaderId = gConfig.GetValue("window.idnum", -1); Ui::m_HeaderId = gConfig.GetValue("window.idnum", -1);
m_fMenuSize.x = gConfig.GetValue("window.sizeX", screen::GetScreenWidth() / 4.0f); m_fMenuSize.x = gConfig.GetValue("window.sizeX", screen::GetScreenWidth() / 4.0f);
m_fMenuSize.y = gConfig.GetValue("window.sizeY", screen::GetScreenHeight() / 1.2f); m_fMenuSize.y = gConfig.GetValue("window.sizeY", screen::GetScreenHeight() / 1.2f);
srand(CTimer::m_snTimeInMilliseconds); srand(CTimer::m_snTimeInMilliseconds);
Events::processScriptsEvent += []() Events::processScriptsEvent += []()
{ {
if (!BY_GAME(FrontEndMenuManager.m_bMenuActive, FrontendMenuManager.m_bMenuVisible, FrontEndMenuManager.m_bMenuActive)) if (!BY_GAME(FrontEndMenuManager.m_bMenuActive, FrontendMenuManager.m_bMenuVisible, FrontEndMenuManager.m_bMenuActive))
{ {
if (menuOpen.Pressed()) if (menuOpen.Pressed())
{ {
m_bShowMenu = !m_bShowMenu; m_bShowMenu = !m_bShowMenu;
} }
if (commandWindow.Pressed()) if (commandWindow.Pressed())
{ {
if (m_Commands::m_bShowMenu) if (m_Commands::m_bShowMenu)
{ {
ProcessCommands(); ProcessCommands();
strcpy(m_Commands::m_nInputBuffer, ""); strcpy(m_Commands::m_nInputBuffer, "");
} }
m_Commands::m_bShowMenu = !m_Commands::m_bShowMenu; m_Commands::m_bShowMenu = !m_Commands::m_bShowMenu;
} }
if (m_bShowMouse != m_bShowMenu) if (m_bShowMouse != m_bShowMenu)
{ {
if (m_bShowMouse) // Only write when the menu closes if (m_bShowMouse) // Only write when the menu closes
{ {
gConfig.WriteToDisk(); gConfig.WriteToDisk();
} }
m_bShowMouse = m_bShowMenu; m_bShowMouse = m_bShowMenu;
} }
} }
}; };
} }
void CheatMenu::ShowWelcomeScreen() void CheatMenu::ShowWelcomeScreen()
{ {
ImGui::BeginChild("WelcomeScreen"); ImGui::BeginChild("WelcomeScreen");
ImGui::NewLine(); ImGui::NewLine();
Ui::CenterdText("Welcome to Cheat Menu"); Ui::CenterdText("Welcome to Cheat Menu");
Ui::CenterdText("Author: Grinch_"); Ui::CenterdText("Author: Grinch_");
ImGui::NewLine(); ImGui::NewLine();
ImGui::TextWrapped("Please ensure you have the latest version from GitHub."); ImGui::TextWrapped("Please ensure you have the latest version from GitHub.");
ImGui::NewLine(); ImGui::NewLine();
if (ImGui::Button("Discord server", ImVec2(Ui::GetSize(2)))) if (ImGui::Button("Discord server", ImVec2(Ui::GetSize(2))))
{ {
ShellExecute(nullptr, "open", DISCORD_INVITE, nullptr, nullptr, SW_SHOWNORMAL); ShellExecute(nullptr, "open", DISCORD_INVITE, nullptr, nullptr, SW_SHOWNORMAL);
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("GitHub repo", ImVec2(Ui::GetSize(2)))) if (ImGui::Button("GitHub repo", ImVec2(Ui::GetSize(2))))
{ {
ShellExecute(nullptr, "open", GITHUB_LINK, nullptr, nullptr, SW_SHOWNORMAL); ShellExecute(nullptr, "open", GITHUB_LINK, nullptr, nullptr, SW_SHOWNORMAL);
} }
ImGui::NewLine(); ImGui::NewLine();
ImGui::TextWrapped("If you find bugs or have suggestions, you can let me know on discord :)"); ImGui::TextWrapped("If you find bugs or have suggestions, you can let me know on discord :)");
ImGui::Dummy(ImVec2(0, 30)); ImGui::Dummy(ImVec2(0, 30));
Ui::CenterdText("Copyright Grinch_ 2019-2022. All rights reserved."); Ui::CenterdText("Copyright Grinch_ 2019-2022. All rights reserved.");
ImGui::EndChild(); ImGui::EndChild();
} }
void CheatMenu::ShowUpdateScreen() void CheatMenu::ShowUpdateScreen()
{ {
ImGui::BeginChild("UPdateScreen"); ImGui::BeginChild("UPdateScreen");
std::string ver = Updater::GetUpdateVersion(); std::string ver = Updater::GetUpdateVersion();
ImGui::Dummy(ImVec2(0, 20)); ImGui::Dummy(ImVec2(0, 20));
Ui::CenterdText("A new version of the mod is available."); Ui::CenterdText("A new version of the mod is available.");
Ui::CenterdText(std::string("Current version: ") + MENU_VERSION); Ui::CenterdText(std::string("Current version: ") + MENU_VERSION);
Ui::CenterdText("Latest version: " + ver); Ui::CenterdText("Latest version: " + ver);
ImGui::Dummy(ImVec2(0, 10)); ImGui::Dummy(ImVec2(0, 10));
ImGui::TextWrapped("In order to keep using the menu, you need to update to the latest version." ImGui::TextWrapped("In order to keep using the menu, you need to update to the latest version."
" This is to ensure everything is using the most up-to-date version."); " This is to ensure everything is using the most up-to-date version.");
ImGui::Dummy(ImVec2(0, 10)); ImGui::Dummy(ImVec2(0, 10));
ImGui::TextWrapped("To know what changes are made or to download, click on the \"Download page\" button." ImGui::TextWrapped("To know what changes are made or to download, click on the \"Download page\" button."
" Follow the instructions there. If you're still having issues, let me know on discord."); " Follow the instructions there. If you're still having issues, let me know on discord.");
ImGui::Dummy(ImVec2(0, 5)); ImGui::Dummy(ImVec2(0, 5));
if (ImGui::Button("Discord server", ImVec2(Ui::GetSize(3)))) if (ImGui::Button("Discord server", ImVec2(Ui::GetSize(3))))
{ {
ShellExecute(NULL, "open", DISCORD_INVITE, NULL, NULL, SW_SHOWNORMAL); ShellExecute(NULL, "open", DISCORD_INVITE, NULL, NULL, SW_SHOWNORMAL);
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Download page", Ui::GetSize(3))) if (ImGui::Button("Download page", Ui::GetSize(3)))
{ {
ShellExecute(NULL, "open", std::string("https://github.com/user-grinch/Cheat-Menu/releases/tag/" + ShellExecute(NULL, "open", std::string("https://github.com/user-grinch/Cheat-Menu/releases/tag/" +
ver).c_str(), NULL, NULL, SW_SHOWNORMAL); ver).c_str(), NULL, NULL, SW_SHOWNORMAL);
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Hide page", Ui::GetSize(3))) if (ImGui::Button("Hide page", Ui::GetSize(3)))
{ {
Updater::ResetUpdaterState(); Updater::ResetUpdaterState();
} }
ImGui::EndChild(); ImGui::EndChild();
} }
void CheatMenu::ApplyStyle() void CheatMenu::ApplyStyle()
{ {
ImGuiStyle* style = &ImGui::GetStyle(); ImGuiStyle* style = &ImGui::GetStyle();
ImVec4* colors = style->Colors; ImVec4* colors = style->Colors;
style->WindowPadding = ImVec2(8, 8); style->WindowPadding = ImVec2(8, 8);
style->WindowRounding = 5.0f; style->WindowRounding = 5.0f;
style->FramePadding = ImVec2(8, 8); style->FramePadding = ImVec2(8, 8);
style->FrameRounding = 5.0f; style->FrameRounding = 5.0f;
style->PopupRounding = 5.0f; style->PopupRounding = 5.0f;
style->ItemSpacing = ImVec2(7, 7); style->ItemSpacing = ImVec2(7, 7);
style->ItemInnerSpacing = ImVec2(7, 7); style->ItemInnerSpacing = ImVec2(7, 7);
style->IndentSpacing = 25.0f; style->IndentSpacing = 25.0f;
style->ScrollbarSize = 12.0f; style->ScrollbarSize = 12.0f;
style->ScrollbarRounding = 10.0f; style->ScrollbarRounding = 10.0f;
style->GrabMinSize = 5.0f; style->GrabMinSize = 5.0f;
style->GrabRounding = 3.0f; style->GrabRounding = 3.0f;
style->ChildBorderSize = 0; style->ChildBorderSize = 0;
style->WindowBorderSize = 0; style->WindowBorderSize = 0;
style->FrameBorderSize = 0; style->FrameBorderSize = 0;
style->TabBorderSize = 0; style->TabBorderSize = 0;
style->PopupBorderSize = 0; style->PopupBorderSize = 0;
style->Colors[ImGuiCol_Text] = ImVec4(0.80f, 0.80f, 0.83f, 1.00f); style->Colors[ImGuiCol_Text] = ImVec4(0.80f, 0.80f, 0.83f, 1.00f);
style->Colors[ImGuiCol_TextDisabled] = ImVec4(0.35f, 0.33f, 0.3f, 1.00f); style->Colors[ImGuiCol_TextDisabled] = ImVec4(0.35f, 0.33f, 0.3f, 1.00f);
style->Colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.05f, 0.06f, 0.95f); style->Colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.05f, 0.06f, 0.95f);
style->Colors[ImGuiCol_ChildBg] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f); style->Colors[ImGuiCol_ChildBg] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
style->Colors[ImGuiCol_PopupBg] = ImVec4(0.06f, 0.05f, 0.06f, 0.95f); style->Colors[ImGuiCol_PopupBg] = ImVec4(0.06f, 0.05f, 0.06f, 0.95f);
style->Colors[ImGuiCol_Border] = ImVec4(0.12f, 0.12f, 0.12f, 1.0f); style->Colors[ImGuiCol_Border] = ImVec4(0.12f, 0.12f, 0.12f, 1.0f);
style->Colors[ImGuiCol_BorderShadow] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); style->Colors[ImGuiCol_BorderShadow] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
style->Colors[ImGuiCol_FrameBg] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f); style->Colors[ImGuiCol_FrameBg] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f);
style->Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f); style->Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
style->Colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); style->Colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
style->Colors[ImGuiCol_TitleBg] = ImVec4(0.12f, 0.12f, 0.12f, 0.94f); style->Colors[ImGuiCol_TitleBg] = ImVec4(0.12f, 0.12f, 0.12f, 0.94f);
style->Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 0.98f, 0.95f, 0.75f); style->Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 0.98f, 0.95f, 0.75f);
style->Colors[ImGuiCol_TitleBgActive] = ImVec4(0.07f, 0.07f, 0.09f, 1.00f); style->Colors[ImGuiCol_TitleBgActive] = ImVec4(0.07f, 0.07f, 0.09f, 1.00f);
style->Colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f); style->Colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f);
style->Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f); style->Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f);
style->Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.5f, 0.5f, 0.5f, 0.3f); style->Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.5f, 0.5f, 0.5f, 0.3f);
style->Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.7f, 0.7f, 0.7f, 0.3f); style->Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.7f, 0.7f, 0.7f, 0.3f);
style->Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.9f, 0.9f, 0.9f, 0.3f); style->Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.9f, 0.9f, 0.9f, 0.3f);
style->Colors[ImGuiCol_CheckMark] = ImVec4(0.80f, 0.80f, 0.83f, 0.31f); style->Colors[ImGuiCol_CheckMark] = ImVec4(0.80f, 0.80f, 0.83f, 0.31f);
style->Colors[ImGuiCol_SliderGrab] = ImVec4(0.80f, 0.80f, 0.83f, 0.31f); style->Colors[ImGuiCol_SliderGrab] = ImVec4(0.80f, 0.80f, 0.83f, 0.31f);
style->Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.80f, 0.83f, 0.31f); style->Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.80f, 0.83f, 0.31f);
style->Colors[ImGuiCol_Separator] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f); style->Colors[ImGuiCol_Separator] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f);
style->Colors[ImGuiCol_Button] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f); style->Colors[ImGuiCol_Button] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f);
style->Colors[ImGuiCol_ButtonHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f); style->Colors[ImGuiCol_ButtonHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
style->Colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); style->Colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
style->Colors[ImGuiCol_Tab] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f); style->Colors[ImGuiCol_Tab] = ImVec4(0.15f, 0.15f, 0.15f, 0.95f);
style->Colors[ImGuiCol_TabHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f); style->Colors[ImGuiCol_TabHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
style->Colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); style->Colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
style->Colors[ImGuiCol_Header] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f); style->Colors[ImGuiCol_Header] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
style->Colors[ImGuiCol_HeaderHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f); style->Colors[ImGuiCol_HeaderHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
style->Colors[ImGuiCol_HeaderActive] = ImVec4(0.06f, 0.05f, 0.07f, 1.00f); style->Colors[ImGuiCol_HeaderActive] = ImVec4(0.06f, 0.05f, 0.07f, 1.00f);
style->Colors[ImGuiCol_ResizeGrip] = ImVec4(0.12f, 0.12f, 0.12f, 0.00f); style->Colors[ImGuiCol_ResizeGrip] = ImVec4(0.12f, 0.12f, 0.12f, 0.00f);
style->Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f); style->Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
style->Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); style->Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
style->Colors[ImGuiCol_PlotLines] = ImVec4(0.40f, 0.39f, 0.38f, 0.63f); style->Colors[ImGuiCol_PlotLines] = ImVec4(0.40f, 0.39f, 0.38f, 0.63f);
style->Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.25f, 1.00f, 0.00f, 1.00f); style->Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.25f, 1.00f, 0.00f, 1.00f);
style->Colors[ImGuiCol_PlotHistogram] = ImVec4(0.40f, 0.39f, 0.38f, 0.63f); style->Colors[ImGuiCol_PlotHistogram] = ImVec4(0.40f, 0.39f, 0.38f, 0.63f);
style->Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(0.25f, 1.00f, 0.00f, 1.00f); style->Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(0.25f, 1.00f, 0.00f, 1.00f);
style->Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.06f, 0.05f, 0.06f, 0.95f); style->Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.06f, 0.05f, 0.06f, 0.95f);
style->Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.6f); style->Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.6f);
} }
void CheatMenu::ResetMenuSize() void CheatMenu::ResetMenuSize()
{ {
m_fMenuSize.x = screen::GetScreenWidth() / 4.0f; m_fMenuSize.x = screen::GetScreenWidth() / 4.0f;
m_fMenuSize.y = screen::GetScreenHeight() / 1.2f; m_fMenuSize.y = screen::GetScreenHeight() / 1.2f;
m_bSizeChangedExternal = true; m_bSizeChangedExternal = true;
} }

View File

@ -6,97 +6,97 @@
void MenuThread(void* param) void MenuThread(void* param)
{ {
static bool gameInit; static bool gameInit;
// Wait till game init // Wait till game init
Events::initRwEvent += [] Events::initRwEvent += []
{ {
gameInit = true; gameInit = true;
}; };
while (!gameInit) while (!gameInit)
{ {
Sleep(1000); Sleep(1000);
} }
/* /*
Had to put this in place since some people put the folder in root Had to put this in place since some people put the folder in root
directory and the asi in modloader. Why?? directory and the asi in modloader. Why??
*/ */
if (!std::filesystem::is_directory(PLUGIN_PATH((char*)"CheatMenu"))) if (!std::filesystem::is_directory(PLUGIN_PATH((char*)"CheatMenu")))
{ {
gLog << "Error: CheatMenu folder not found. You need to put both \"CheatMenu.asi\" & \"CheatMenu\" folder in the same directory" << std::endl; gLog << "Error: CheatMenu folder not found. You need to put both \"CheatMenu.asi\" & \"CheatMenu\" folder in the same directory" << std::endl;
MessageBox(RsGlobal.ps->window, "CheatMenu folder not found. You need to put both \"CheatMenu.asi\" & \"CheatMenu\" folder in the same directory", "CheatMenu", MB_ICONERROR); MessageBox(RsGlobal.ps->window, "CheatMenu folder not found. You need to put both \"CheatMenu.asi\" & \"CheatMenu\" folder in the same directory", "CheatMenu", MB_ICONERROR);
return; return;
} }
/* /*
Need SilentPatch since all gta games have issues with mouse input Need SilentPatch since all gta games have issues with mouse input
Implementing mouse fix is a headache anyway Implementing mouse fix is a headache anyway
*/ */
if (!GetModuleHandle(BY_GAME("SilentPatchSA.asi" ,"SilentPatchVC.asi" ,"SilentPatchIII.asi"))) if (!GetModuleHandle(BY_GAME("SilentPatchSA.asi","SilentPatchVC.asi","SilentPatchIII.asi")))
{ {
gLog << "Error: SilentPatch not found. Please install it from here https://gtaforums.com/topic/669045-silentpatch/" << std::endl; gLog << "Error: SilentPatch not found. Please install it from here https://gtaforums.com/topic/669045-silentpatch/" << std::endl;
int msgID = MessageBox(RsGlobal.ps->window, "SilentPatch not found. Do you want to install Silent Patch? (Game restart required)", "CheatMenu", MB_OKCANCEL | MB_DEFBUTTON1); int msgID = MessageBox(RsGlobal.ps->window, "SilentPatch not found. Do you want to install Silent Patch? (Game restart required)", "CheatMenu", MB_OKCANCEL | MB_DEFBUTTON1);
if (msgID == IDOK) if (msgID == IDOK)
{ {
ShellExecute(nullptr, "open", "https://gtaforums.com/topic/669045-silentpatch/", nullptr, nullptr, SW_SHOWNORMAL); ShellExecute(nullptr, "open", "https://gtaforums.com/topic/669045-silentpatch/", nullptr, nullptr, SW_SHOWNORMAL);
}; };
return; return;
} }
#ifdef GTASA #ifdef GTASA
/* /*
TODO: Find a better way TODO: Find a better way
Since you could still name it something else Since you could still name it something else
*/ */
if (GetModuleHandle("SAMP.dll") || GetModuleHandle("SAMP.asi")) if (GetModuleHandle("SAMP.dll") || GetModuleHandle("SAMP.asi"))
{ {
gLog << "Error: CheatMenu doesn't support SAMP" << std::endl; gLog << "Error: CheatMenu doesn't support SAMP" << std::endl;
MessageBox(RsGlobal.ps->window, "SAMP detected. Exiting CheatMenu.", "CheatMenu", MB_ICONERROR); MessageBox(RsGlobal.ps->window, "SAMP detected. Exiting CheatMenu.", "CheatMenu", MB_ICONERROR);
return; return;
} }
CFastman92limitAdjuster::Init(); CFastman92limitAdjuster::Init();
#endif #endif
gLog << "Starting...\nVersion: " MENU_TITLE "\nAuthor: Grinch_\nDiscord: " DISCORD_INVITE "\nMore Info: " gLog << "Starting...\nVersion: " MENU_TITLE "\nAuthor: Grinch_\nDiscord: " DISCORD_INVITE "\nMore Info: "
GITHUB_LINK "\n" << std::endl; GITHUB_LINK "\n" << std::endl;
CheatMenu menu; CheatMenu menu;
// Checking for updates once a day // Checking for updates once a day
time_t now = time(0); time_t now = time(0);
struct tm tstruct = *localtime(&now); struct tm tstruct = *localtime(&now);
int lastCheckDate = gConfig.GetValue("config.last_update_checked", 0); int lastCheckDate = gConfig.GetValue("config.last_update_checked", 0);
if (lastCheckDate != tstruct.tm_mday) if (lastCheckDate != tstruct.tm_mday)
{ {
Updater::CheckUpdate(); Updater::CheckUpdate();
gConfig.SetValue("config.last_update_checked", tstruct.tm_mday); gConfig.SetValue("config.last_update_checked", tstruct.tm_mday);
} }
while (true) while (true)
{ {
Sleep(5000); Sleep(5000);
Updater::Process(); Updater::Process();
} }
} }
BOOL WINAPI DllMain(HINSTANCE hDllHandle, DWORD nReason, LPVOID Reserved) BOOL WINAPI DllMain(HINSTANCE hDllHandle, DWORD nReason, LPVOID Reserved)
{ {
if (nReason == DLL_PROCESS_ATTACH) if (nReason == DLL_PROCESS_ATTACH)
{ {
if (GetGameVersion() == BY_GAME(GAME_10US_HOODLUM, GAME_10EN, GAME_10EN)) if (GetGameVersion() == BY_GAME(GAME_10US_HOODLUM, GAME_10EN, GAME_10EN))
{ {
CreateThread(nullptr, NULL, (LPTHREAD_START_ROUTINE)&MenuThread, nullptr, NULL, nullptr); CreateThread(nullptr, NULL, (LPTHREAD_START_ROUTINE)&MenuThread, nullptr, NULL, nullptr);
} }
else else
{ {
gLog << "Error: Unknown game version. GTA " << BY_GAME("SA v1.0 US Hoodlum", "VC v1.0 EN", "III v1.0 EN") << " is required." << std::endl; gLog << "Error: Unknown game version. GTA " << BY_GAME("SA v1.0 US Hoodlum", "VC v1.0 EN", "III v1.0 EN") << " is required." << std::endl;
MessageBox(HWND_DESKTOP, "Unknown game version. GTA " BY_GAME("SA v1.0 US Hoodlum", "VC v1.0 EN", "III v1.0 EN") " is required.", "CheatMenu", MB_ICONERROR); MessageBox(HWND_DESKTOP, "Unknown game version. GTA " BY_GAME("SA v1.0 US Hoodlum", "VC v1.0 EN", "III v1.0 EN") " is required.", "CheatMenu", MB_ICONERROR);
} }
} }
return TRUE; return TRUE;
} }

View File

@ -4,183 +4,183 @@
// TODO: Clean up this mess, use structures instead? // TODO: Clean up this mess, use structures instead?
void FileHandler::GenerateHandlingFile(int pHandling, std::map<int, std::string>& storeMap) void FileHandler::GenerateHandlingFile(int pHandling, std::map<int, std::string>& storeMap)
{ {
FILE* fp = fopen("handling.txt", "w"); FILE* fp = fopen("handling.txt", "w");
std::string handlingId = storeMap[FindPlayerPed()->m_pVehicle->m_nModelIndex]; std::string handlingId = storeMap[FindPlayerPed()->m_pVehicle->m_nModelIndex];
float fMass = patch::Get<float>(pHandling + 0x4); float fMass = patch::Get<float>(pHandling + 0x4);
float fTurnMass = patch::Get<float>(pHandling + 0xC); float fTurnMass = patch::Get<float>(pHandling + 0xC);
float fDragMult = patch::Get<float>(pHandling + 0x10); float fDragMult = patch::Get<float>(pHandling + 0x10);
float CentreOfMassX = patch::Get<float>(pHandling + 0x14); float CentreOfMassX = patch::Get<float>(pHandling + 0x14);
float CentreOfMassY = patch::Get<float>(pHandling + 0x18); float CentreOfMassY = patch::Get<float>(pHandling + 0x18);
float CentreOfMassZ = patch::Get<float>(pHandling + 0x1C); float CentreOfMassZ = patch::Get<float>(pHandling + 0x1C);
int nPercentSubmerged = patch::Get<int>(pHandling + 0x20); int nPercentSubmerged = patch::Get<int>(pHandling + 0x20);
float fTractionMultiplier = patch::Get<float>(pHandling + 0x28); float fTractionMultiplier = patch::Get<float>(pHandling + 0x28);
float fTractionLoss = patch::Get<float>(pHandling + 0xA4); float fTractionLoss = patch::Get<float>(pHandling + 0xA4);
float TractionBias = patch::Get<float>(pHandling + 0xA8); float TractionBias = patch::Get<float>(pHandling + 0xA8);
float fEngineAcceleration = patch::Get<float>(pHandling + 0x7C) * 12500; float fEngineAcceleration = patch::Get<float>(pHandling + 0x7C) * 12500;
float fEngineInertia = patch::Get<float>(pHandling + 0x80); float fEngineInertia = patch::Get<float>(pHandling + 0x80);
int nDriveType = patch::Get<BYTE>(pHandling + 0x74); int nDriveType = patch::Get<BYTE>(pHandling + 0x74);
int nEngineType = patch::Get<BYTE>(pHandling + 0x75); int nEngineType = patch::Get<BYTE>(pHandling + 0x75);
float BrakeDeceleration = patch::Get<float>(pHandling + 0x94) * 2500; float BrakeDeceleration = patch::Get<float>(pHandling + 0x94) * 2500;
float BrakeBias = patch::Get<float>(pHandling + 0x98); float BrakeBias = patch::Get<float>(pHandling + 0x98);
int ABS = patch::Get<BYTE>(pHandling + 0x9C); int ABS = patch::Get<BYTE>(pHandling + 0x9C);
float SteeringLock = patch::Get<float>(pHandling + 0xA0); float SteeringLock = patch::Get<float>(pHandling + 0xA0);
float SuspensionForceLevel = patch::Get<float>(pHandling + 0xAC); float SuspensionForceLevel = patch::Get<float>(pHandling + 0xAC);
float SuspensionDampingLevel = patch::Get<float>(pHandling + 0xB0); float SuspensionDampingLevel = patch::Get<float>(pHandling + 0xB0);
float SuspensionHighSpdComDamp = patch::Get<float>(pHandling + 0xB4); float SuspensionHighSpdComDamp = patch::Get<float>(pHandling + 0xB4);
float Suspension_upper_limit = patch::Get<float>(pHandling + 0xB8); float Suspension_upper_limit = patch::Get<float>(pHandling + 0xB8);
float Suspension_lower_limit = patch::Get<float>(pHandling + 0xBC); float Suspension_lower_limit = patch::Get<float>(pHandling + 0xBC);
float Suspension_bias = patch::Get<float>(pHandling + 0xC0); float Suspension_bias = patch::Get<float>(pHandling + 0xC0);
float Suspension_anti_dive_multiplier = patch::Get<float>(pHandling + 0xC4); float Suspension_anti_dive_multiplier = patch::Get<float>(pHandling + 0xC4);
float fCollisionDamageMultiplier = patch::Get<float>(pHandling + 0xC8) * 0.338; float fCollisionDamageMultiplier = patch::Get<float>(pHandling + 0xC8) * 0.338;
int nMonetaryValue = patch::Get<int>(pHandling + 0xD8); int nMonetaryValue = patch::Get<int>(pHandling + 0xD8);
int MaxVelocity = patch::Get<float>(pHandling + 0x84); int MaxVelocity = patch::Get<float>(pHandling + 0x84);
MaxVelocity = MaxVelocity * 206 + (MaxVelocity - 0.918668) * 1501; MaxVelocity = MaxVelocity * 206 + (MaxVelocity - 0.918668) * 1501;
int modelFlags = patch::Get<int>(pHandling + 0xCC); int modelFlags = patch::Get<int>(pHandling + 0xCC);
int handlingFlags = patch::Get<int>(pHandling + 0xD0); int handlingFlags = patch::Get<int>(pHandling + 0xD0);
int front_lights = patch::Get<BYTE>(pHandling + 0xDC); int front_lights = patch::Get<BYTE>(pHandling + 0xDC);
int rear_lights = patch::Get<BYTE>(pHandling + 0xDD); int rear_lights = patch::Get<BYTE>(pHandling + 0xDD);
int vehicle_anim_group = patch::Get<BYTE>(pHandling + 0xDE); int vehicle_anim_group = patch::Get<BYTE>(pHandling + 0xDE);
int nNumberOfGears = patch::Get<BYTE>(pHandling + 0x76); int nNumberOfGears = patch::Get<BYTE>(pHandling + 0x76);
float fSeatOffsetDistance = patch::Get<float>(pHandling + 0xD4); float fSeatOffsetDistance = patch::Get<float>(pHandling + 0xD4);
// TODO: make this more readable // TODO: make this more readable
fprintf( fprintf(
fp, fp,
"\n%s\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%d\t%.5g\t%.5g\t%.5g\t%d\t%d\t%.5g\t%.5g\t%c\t%c\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%d\t%d\t%d\t%d\t%d", "\n%s\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%d\t%.5g\t%.5g\t%.5g\t%d\t%d\t%.5g\t%.5g\t%c\t%c\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%d\t%d\t%d\t%d\t%d",
handlingId.c_str(), fMass, fTurnMass, fDragMult, CentreOfMassX, CentreOfMassY, CentreOfMassZ, nPercentSubmerged, handlingId.c_str(), fMass, fTurnMass, fDragMult, CentreOfMassX, CentreOfMassY, CentreOfMassZ, nPercentSubmerged,
fTractionMultiplier, fTractionLoss, TractionBias, nNumberOfGears, fTractionMultiplier, fTractionLoss, TractionBias, nNumberOfGears,
MaxVelocity, fEngineAcceleration, fEngineInertia, nDriveType, nEngineType, BrakeDeceleration, BrakeBias, ABS, MaxVelocity, fEngineAcceleration, fEngineInertia, nDriveType, nEngineType, BrakeDeceleration, BrakeBias, ABS,
SteeringLock, SuspensionForceLevel, SuspensionDampingLevel, SteeringLock, SuspensionForceLevel, SuspensionDampingLevel,
SuspensionHighSpdComDamp, Suspension_upper_limit, Suspension_lower_limit, Suspension_bias, SuspensionHighSpdComDamp, Suspension_upper_limit, Suspension_lower_limit, Suspension_bias,
Suspension_anti_dive_multiplier, fSeatOffsetDistance, Suspension_anti_dive_multiplier, fSeatOffsetDistance,
fCollisionDamageMultiplier, nMonetaryValue, modelFlags, handlingFlags, front_lights, rear_lights, fCollisionDamageMultiplier, nMonetaryValue, modelFlags, handlingFlags, front_lights, rear_lights,
vehicle_anim_group); vehicle_anim_group);
fclose(fp); fclose(fp);
} }
void FileHandler::FetchColorData(std::vector<std::vector<float>>& storeVec) void FileHandler::FetchColorData(std::vector<std::vector<float>>& storeVec)
{ {
std::string m_FilePath = GAME_PATH((char*)"/data/carcols.dat"); std::string m_FilePath = GAME_PATH((char*)"/data/carcols.dat");
if (!std::filesystem::exists(m_FilePath)) if (!std::filesystem::exists(m_FilePath))
{ {
gLog << "Carcols.dat not found"; gLog << "Carcols.dat not found";
return; return;
} }
std::ifstream file(m_FilePath); std::ifstream file(m_FilePath);
std::string line; std::string line;
bool isCar, isCol; bool isCar, isCol;
int count = 0; int count = 0;
while (getline(file, line)) while (getline(file, line))
{ {
// skip commented & empty lines // skip commented & empty lines
if (line[0] == '#' || line == "") if (line[0] == '#' || line == "")
{ {
continue; continue;
} }
// section blocks // section blocks
if (line[0] == 'c' && line[1] == 'a' && line[2] == 'r') if (line[0] == 'c' && line[1] == 'a' && line[2] == 'r')
{ {
isCar = true; isCar = true;
continue; continue;
} }
if (line[0] == 'c' && line[1] == 'o' && line[2] == 'l') if (line[0] == 'c' && line[1] == 'o' && line[2] == 'l')
{ {
isCol = true; isCol = true;
continue; continue;
} }
if (line[0] == 'e' && line[1] == 'n' && line[2] == 'd') if (line[0] == 'e' && line[1] == 'n' && line[2] == 'd')
{ {
isCar = false; isCar = false;
isCol = false; isCol = false;
continue; continue;
} }
if (isCol) if (isCol)
{ {
try try
{ {
std::string temp; std::string temp;
std::stringstream ss(line); std::stringstream ss(line);
// fix one instance where . is used instead of , // fix one instance where . is used instead of ,
std::replace(temp.begin(), temp.end(), '.', ','); std::replace(temp.begin(), temp.end(), '.', ',');
// Format: red, green, blue // Format: red, green, blue
int r,g,b; int r,g,b;
getline(ss, temp, ','); getline(ss, temp, ',');
r = std::stoi(temp); r = std::stoi(temp);
getline(ss, temp, ','); getline(ss, temp, ',');
g = std::stoi(temp); g = std::stoi(temp);
getline(ss, temp, ','); getline(ss, temp, ',');
b = std::stoi(temp); b = std::stoi(temp);
storeVec.push_back({r / 255.0f, g / 255.0f, b / 255.0f}); storeVec.push_back({r / 255.0f, g / 255.0f, b / 255.0f});
++count; ++count;
} }
catch (...) catch (...)
{ {
gLog << "Error parsing carcols.dat, " << line << std::endl; gLog << "Error parsing carcols.dat, " << line << std::endl;
} }
} }
} }
file.close(); file.close();
} }
void FileHandler::FetchHandlingID(std::map<int, std::string>& storeMap) void FileHandler::FetchHandlingID(std::map<int, std::string>& storeMap)
{ {
std::string m_FilePath = GAME_PATH((char*)"/data/vehicles.ide"); std::string m_FilePath = GAME_PATH((char*)"/data/vehicles.ide");
if (!std::filesystem::exists(m_FilePath)) if (!std::filesystem::exists(m_FilePath))
{ {
gLog << "Vehicle.ide not found"; gLog << "Vehicle.ide not found";
return; return;
} }
std::ifstream file(m_FilePath); std::ifstream file(m_FilePath);
std::string line; std::string line;
while (getline(file, line)) while (getline(file, line))
{ {
/* /*
Format: model, modelname, txdname, type, handlingId, ... Format: model, modelname, txdname, type, handlingId, ...
Skip if first thing isn't model id Skip if first thing isn't model id
*/ */
if (line[0] <= '0' || line[0] >= '9') if (line[0] <= '0' || line[0] >= '9')
{ {
continue; continue;
} }
// running inside try block to handle user errors, mostly commas // running inside try block to handle user errors, mostly commas
try try
{ {
std::string temp; std::string temp;
std::stringstream ss(line); std::stringstream ss(line);
// get model // get model
getline(ss, temp, ','); getline(ss, temp, ',');
int model = std::stoi(temp); int model = std::stoi(temp);
// get modelname, txd, type, handlingId // get modelname, txd, type, handlingId
getline(ss, temp, ','); getline(ss, temp, ',');
getline(ss, temp, ','); getline(ss, temp, ',');
getline(ss, temp, ','); getline(ss, temp, ',');
getline(ss, temp, ','); getline(ss, temp, ',');
temp.erase(std::remove_if(temp.begin(), temp.end(), isspace), temp.end()); temp.erase(std::remove_if(temp.begin(), temp.end(), isspace), temp.end());
storeMap[model] = temp; storeMap[model] = temp;
} }
catch (...) catch (...)
{ {
gLog << "Error parsing vehicles.ide, " << line << std::endl; gLog << "Error parsing vehicles.ide, " << line << std::endl;
} }
} }
file.close(); file.close();
} }

View File

@ -5,10 +5,10 @@ ImFont* FontMgr::GetFont(const char* fontName)
{ {
for (auto &data : m_vecFonts) for (auto &data : m_vecFonts)
{ {
if (data.m_path == std::string(fontName)) if (data.m_path == std::string(fontName))
{ {
return data.m_pFont; return data.m_pFont;
} }
} }
return nullptr; return nullptr;
@ -21,7 +21,7 @@ ImFont* FontMgr::LoadFont(const char* fontName, float fontMul)
std::string fullPath = std::string(PLUGIN_PATH((char*)"CheatMenu/fonts/")) + fontName + ".ttf"; std::string fullPath = std::string(PLUGIN_PATH((char*)"CheatMenu/fonts/")) + fontName + ".ttf";
m_vecFonts.push_back({io.Fonts->AddFontFromFileTTF(fullPath.c_str(), fontSize), fontSize, fontMul, m_vecFonts.push_back({io.Fonts->AddFontFromFileTTF(fullPath.c_str(), fontSize), fontSize, fontMul,
std::string(fontName)}); std::string(fontName)});
io.Fonts->Build(); io.Fonts->Build();
return m_vecFonts.back().m_pFont; return m_vecFonts.back().m_pFont;

View File

@ -22,7 +22,7 @@ public:
static ImFont* GetFont(const char* fontName); static ImFont* GetFont(const char* fontName);
static ImFont* LoadFont(const char* fontName, float fontMul = 1.0f); static ImFont* LoadFont(const char* fontName, float fontMul = 1.0f);
// ImGui::GetIO().Default font must be loaded after unloading all fonts // ImGui::GetIO().Default font must be loaded after unloading all fonts
static void UnloadFonts(); static void UnloadFonts();
static void ReloadFonts(); static void ReloadFonts();

File diff suppressed because it is too large Load Diff

View File

@ -4,65 +4,65 @@
class Game class Game
{ {
public: public:
static inline ResourceStore m_MissionData{ "mission", eResourceType::TYPE_TEXT }; static inline ResourceStore m_MissionData{ "mission", eResourceType::TYPE_TEXT };
static inline bool m_bDisableCheats; static inline bool m_bDisableCheats;
static inline bool m_bDisableReplay; static inline bool m_bDisableReplay;
static inline bool m_bMissionTimer; static inline bool m_bMissionTimer;
static inline bool m_bFreezeTime; static inline bool m_bFreezeTime;
static inline bool m_bSyncTime; static inline bool m_bSyncTime;
#ifdef GTASA #ifdef GTASA
static inline bool m_bForbiddenArea = true; // wanted level when going outside playable aea static inline bool m_bForbiddenArea = true; // wanted level when going outside playable aea
static inline bool m_bSolidWater; // walk on water hack static inline bool m_bSolidWater; // walk on water hack
static inline bool m_bScreenShot; static inline bool m_bScreenShot;
static inline bool m_bKeepStuff; static inline bool m_bKeepStuff;
static inline ResourceStore m_StatData{ "stat", eResourceType::TYPE_TEXT }; static inline ResourceStore m_StatData{ "stat", eResourceType::TYPE_TEXT };
static inline std::vector<std::string> m_DayNames = static inline std::vector<std::string> m_DayNames =
{ {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
}; };
struct m_RandomCheats
{
static inline bool m_bEnabled;
static inline bool m_bProgressBar = true;
static inline std::string m_EnabledCheats[92][2];
static inline int m_nInterval = 10;
static inline CJson m_Json = CJson("cheat name");
static inline uint m_nTimer;
};
struct m_Freecam
{
static inline bool m_bEnabled;
static inline int m_nMul = 1;
static inline float m_fFOV = 60.0f;
static inline bool m_bInitDone;
static inline CPed* m_pPed;
static inline int m_nPed = -1;
static inline CVector m_fMouse;
static inline CVector m_fTotalMouse;
static inline BYTE m_bHudState;
static inline BYTE m_bRadarState;
};
struct m_HardMode
{
static inline bool m_bEnabled;
static inline float m_fBacHealth = 0.0f;
static inline float m_fBacMaxHealth = 0.0f;
static inline float m_fBacArmour = 0.0f;
static inline float m_fBacStamina = 0.0f;
};
struct m_RandomCheats
{
static inline bool m_bEnabled;
static inline bool m_bProgressBar = true;
static inline std::string m_EnabledCheats[92][2];
static inline int m_nInterval = 10;
static inline CJson m_Json = CJson("cheat name");
static inline uint m_nTimer;
};
struct m_Freecam
{
static inline bool m_bEnabled;
static inline int m_nMul = 1;
static inline float m_fFOV = 60.0f;
static inline bool m_bInitDone;
static inline CPed* m_pPed;
static inline int m_nPed = -1;
static inline CVector m_fMouse;
static inline CVector m_fTotalMouse;
static inline BYTE m_bHudState;
static inline BYTE m_bRadarState;
};
struct m_HardMode
{
static inline bool m_bEnabled;
static inline float m_fBacHealth = 0.0f;
static inline float m_fBacMaxHealth = 0.0f;
static inline float m_fBacArmour = 0.0f;
static inline float m_fBacStamina = 0.0f;
};
#endif #endif
Game(); Game();
static void Draw(); static void Draw();
static void RealTimeClock(); static void RealTimeClock();
#ifdef GTASA #ifdef GTASA
// TODO: Update freecam with aap's code // TODO: Update freecam with aap's code
static void FreeCam(); static void FreeCam();
static void ClearFreecamStuff(); static void ClearFreecamStuff();
#endif #endif
}; };

View File

@ -11,252 +11,252 @@
LRESULT Hook::WndProc(const HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) LRESULT Hook::WndProc(const HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam); ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam);
if (ImGui::GetIO().WantTextInput) if (ImGui::GetIO().WantTextInput)
{ {
#ifdef GTASA #ifdef GTASA
Call<0x53F1E0>(); // CPad::ClearKeyboardHistory Call<0x53F1E0>(); // CPad::ClearKeyboardHistory
#endif #endif
return 1; return 1;
} }
return CallWindowProc(oWndProc, hWnd, uMsg, wParam, lParam); return CallWindowProc(oWndProc, hWnd, uMsg, wParam, lParam);
} }
HRESULT Hook::Reset(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters) HRESULT Hook::Reset(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters)
{ {
ImGui_ImplDX9_InvalidateDeviceObjects(); ImGui_ImplDX9_InvalidateDeviceObjects();
return oReset(pDevice, pPresentationParameters); return oReset(pDevice, pPresentationParameters);
} }
void Hook::RenderFrame(void* ptr) void Hook::RenderFrame(void* ptr)
{ {
if (!ImGui::GetCurrentContext()) if (!ImGui::GetCurrentContext())
{ {
ImGui::CreateContext(); ImGui::CreateContext();
} }
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
static bool bInit = false; static bool bInit = false;
if (bInit) if (bInit)
{ {
ShowMouse(m_bShowMouse); ShowMouse(m_bShowMouse);
// Scale the menu if game resolution changed // Scale the menu if game resolution changed
static ImVec2 fScreenSize = ImVec2(-1, -1); static ImVec2 fScreenSize = ImVec2(-1, -1);
ImVec2 size(screen::GetScreenWidth(), screen::GetScreenHeight()); ImVec2 size(screen::GetScreenWidth(), screen::GetScreenHeight());
if (fScreenSize.x != size.x && fScreenSize.y != size.y) if (fScreenSize.x != size.x && fScreenSize.y != size.y)
{ {
FontMgr::ReloadFonts(); FontMgr::ReloadFonts();
if (gRenderer == Render_DirectX9) if (gRenderer == Render_DirectX9)
{ {
ImGui_ImplDX9_InvalidateDeviceObjects(); ImGui_ImplDX9_InvalidateDeviceObjects();
} }
else else
{ {
ImGui_ImplDX11_InvalidateDeviceObjects(); ImGui_ImplDX11_InvalidateDeviceObjects();
} }
ImGuiStyle* style = &ImGui::GetStyle(); ImGuiStyle* style = &ImGui::GetStyle();
float scaleX = size.x / 1366.0f; float scaleX = size.x / 1366.0f;
float scaleY = size.y / 768.0f; float scaleY = size.y / 768.0f;
style->FramePadding = ImVec2(5 * scaleX, 5 * scaleY); style->FramePadding = ImVec2(5 * scaleX, 5 * scaleY);
style->ItemSpacing = ImVec2(8 * scaleX, 4 * scaleY); style->ItemSpacing = ImVec2(8 * scaleX, 4 * scaleY);
style->ScrollbarSize = 12 * scaleX; style->ScrollbarSize = 12 * scaleX;
style->IndentSpacing = 20 * scaleX; style->IndentSpacing = 20 * scaleX;
style->ItemInnerSpacing = ImVec2(5 * scaleX, 5 * scaleY); style->ItemInnerSpacing = ImVec2(5 * scaleX, 5 * scaleY);
fScreenSize = size; fScreenSize = size;
} }
ImGui_ImplWin32_NewFrame(); ImGui_ImplWin32_NewFrame();
if (gRenderer == Render_DirectX9) if (gRenderer == Render_DirectX9)
{ {
ImGui_ImplDX9_NewFrame(); ImGui_ImplDX9_NewFrame();
} }
else else
{ {
ImGui_ImplDX11_NewFrame(); ImGui_ImplDX11_NewFrame();
} }
ImGui::NewFrame(); ImGui::NewFrame();
if (pCallbackFunc != nullptr) if (pCallbackFunc != nullptr)
{ {
pCallbackFunc(); pCallbackFunc();
} }
ImGui::EndFrame(); ImGui::EndFrame();
ImGui::Render(); ImGui::Render();
if (gRenderer == Render_DirectX9) if (gRenderer == Render_DirectX9)
{ {
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
} }
else else
{ {
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
} }
} }
else else
{ {
bInit = true; bInit = true;
ImGui_ImplWin32_Init(RsGlobal.ps->window); ImGui_ImplWin32_Init(RsGlobal.ps->window);
#ifdef GTASA #ifdef GTASA
// shift trigger fix // shift trigger fix
patch::Nop(0x00531155, 5); patch::Nop(0x00531155, 5);
#endif #endif
if (gRenderer == Render_DirectX9) if (gRenderer == Render_DirectX9)
{ {
ImGui_ImplDX9_Init(reinterpret_cast<IDirect3DDevice9*>(ptr)); ImGui_ImplDX9_Init(reinterpret_cast<IDirect3DDevice9*>(ptr));
} }
else else
{ {
// for dx11 device ptr is swapchain // for dx11 device ptr is swapchain
reinterpret_cast<IDXGISwapChain*>(ptr)->GetDevice(__uuidof(ID3D11Device), &ptr); reinterpret_cast<IDXGISwapChain*>(ptr)->GetDevice(__uuidof(ID3D11Device), &ptr);
ID3D11DeviceContext* context; ID3D11DeviceContext* context;
reinterpret_cast<ID3D11Device*>(ptr)->GetImmediateContext(&context); reinterpret_cast<ID3D11Device*>(ptr)->GetImmediateContext(&context);
ImGui_ImplDX11_Init(reinterpret_cast<ID3D11Device*>(ptr), context); ImGui_ImplDX11_Init(reinterpret_cast<ID3D11Device*>(ptr), context);
} }
ImGui_ImplWin32_EnableDpiAwareness(); ImGui_ImplWin32_EnableDpiAwareness();
// Loading fonts // Loading fonts
io.FontDefault = FontMgr::LoadFont("text", 1.0f); io.FontDefault = FontMgr::LoadFont("text", 1.0f);
FontMgr::LoadFont("title", 2.0f); FontMgr::LoadFont("title", 2.0f);
FontMgr::LoadFont("header", 1.25f); FontMgr::LoadFont("header", 1.25f);
io.IniFilename = nullptr; io.IniFilename = nullptr;
io.LogFilename = nullptr; io.LogFilename = nullptr;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
oWndProc = (WNDPROC)SetWindowLongPtr(RsGlobal.ps->window, GWL_WNDPROC, (LRESULT)WndProc); oWndProc = (WNDPROC)SetWindowLongPtr(RsGlobal.ps->window, GWL_WNDPROC, (LRESULT)WndProc);
} }
} }
HRESULT Hook::Dx9Handler(IDirect3DDevice9* pDevice) HRESULT Hook::Dx9Handler(IDirect3DDevice9* pDevice)
{ {
RenderFrame(pDevice); RenderFrame(pDevice);
return oEndScene(pDevice); return oEndScene(pDevice);
} }
HRESULT Hook::Dx11Handler(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags) HRESULT Hook::Dx11Handler(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{ {
RenderFrame(pSwapChain); RenderFrame(pSwapChain);
return oPresent11(pSwapChain, SyncInterval, Flags); return oPresent11(pSwapChain, SyncInterval, Flags);
} }
void Hook::ShowMouse(bool state) void Hook::ShowMouse(bool state)
{ {
// Disable player controls for controllers // Disable player controls for controllers
bool bMouseDisabled = false; bool bMouseDisabled = false;
bool isController = patch::Get<BYTE>(BY_GAME(0xBA6818, 0x86968B, 0x5F03D8)); bool isController = patch::Get<BYTE>(BY_GAME(0xBA6818, 0x86968B, 0x5F03D8));
#ifdef GTA3 #ifdef GTA3
isController = !isController; isController = !isController;
#endif #endif
if (isController && (state || bMouseDisabled)) if (isController && (state || bMouseDisabled))
{ {
#ifdef GTASA #ifdef GTASA
CPlayerPed *player = FindPlayerPed(); CPlayerPed *player = FindPlayerPed();
CPad *pad = player ? player->GetPadFromPlayer() : NULL; CPad *pad = player ? player->GetPadFromPlayer() : NULL;
#else #else
CPad *pad = CPad::GetPad(0); CPad *pad = CPad::GetPad(0);
#endif #endif
if (pad) if (pad)
{ {
if (state) if (state)
{ {
bMouseDisabled = true; bMouseDisabled = true;
#ifdef GTA3 #ifdef GTA3
pad->m_bDisablePlayerControls = true; pad->m_bDisablePlayerControls = true;
#else //GTAVC & GTASA #else //GTAVC & GTASA
pad->DisablePlayerControls = true; pad->DisablePlayerControls = true;
#endif #endif
} }
else else
{ {
bMouseDisabled = false; bMouseDisabled = false;
#ifdef GTA3 #ifdef GTA3
pad->m_bDisablePlayerControls = false; pad->m_bDisablePlayerControls = false;
#else //GTAVC & GTASA #else //GTAVC & GTASA
pad->DisablePlayerControls = false; pad->DisablePlayerControls = false;
#endif #endif
} }
} }
} }
if (m_bMouseVisibility != state) if (m_bMouseVisibility != state)
{ {
ImGui::GetIO().MouseDrawCursor = state; ImGui::GetIO().MouseDrawCursor = state;
if (state) if (state)
{ {
patch::SetUChar(BY_GAME(0x6194A0, 0x6020A0, 0x580D20), 0xC3); // psSetMousePos patch::SetUChar(BY_GAME(0x6194A0, 0x6020A0, 0x580D20), 0xC3); // psSetMousePos
patch::Nop(BY_GAME(0x541DD7, 0x4AB6CA, 0x49272F), 5); // don't call CPad::UpdateMouse() patch::Nop(BY_GAME(0x541DD7, 0x4AB6CA, 0x49272F), 5); // don't call CPad::UpdateMouse()
} }
else else
{ {
patch::SetUChar(BY_GAME(0x6194A0, 0x6020A0, 0x580D20), BY_GAME(0xE9, 0x53, 0x53)); patch::SetUChar(BY_GAME(0x6194A0, 0x6020A0, 0x580D20), BY_GAME(0xE9, 0x53, 0x53));
#ifdef GTASA #ifdef GTASA
patch::SetRaw(0x541DD7, (char*)"\xE8\xE4\xD5\xFF\xFF", 5); patch::SetRaw(0x541DD7, (char*)"\xE8\xE4\xD5\xFF\xFF", 5);
#elif GTAVC #elif GTAVC
patch::SetRaw(0x4AB6CA, (char*)"\xE8\x51\x21\x00\x00", 5); patch::SetRaw(0x4AB6CA, (char*)"\xE8\x51\x21\x00\x00", 5);
#else // GTA3 #else
patch::SetRaw(0x49272F, (char*)"\xE8\x6C\xF5\xFF\xFF", 5); patch::SetRaw(0x49272F, (char*)"\xE8\x6C\xF5\xFF\xFF", 5);
#endif #endif
} }
CPad::NewMouseControllerState.X = 0; CPad::NewMouseControllerState.X = 0;
CPad::NewMouseControllerState.Y = 0; CPad::NewMouseControllerState.Y = 0;
#ifdef GTA3 #ifdef GTA3
CPad::GetPad(0)->ClearMouseHistory(); CPad::GetPad(0)->ClearMouseHistory();
#else // GTAVC & GTASA #else
CPad::ClearMouseHistory(); CPad::ClearMouseHistory();
#endif #endif
CPad::UpdatePads(); CPad::UpdatePads();
m_bMouseVisibility = state; m_bMouseVisibility = state;
} }
} }
Hook::Hook() Hook::Hook()
{ {
// Nvidia Overlay crash fix // Nvidia Overlay crash fix
if (init(kiero::RenderType::D3D9) == kiero::Status::Success) if (init(kiero::RenderType::D3D9) == kiero::Status::Success)
{ {
gRenderer = Render_DirectX9; gRenderer = Render_DirectX9;
kiero::bind(16, (void**)&oReset, Reset); kiero::bind(16, (void**)&oReset, Reset);
kiero::bind(42, (void**)&oEndScene, Dx9Handler); kiero::bind(42, (void**)&oEndScene, Dx9Handler);
} }
else else
{ {
// gtaRenderHook
if (init(kiero::RenderType::D3D11) == kiero::Status::Success) if (init(kiero::RenderType::D3D11) == kiero::Status::Success)
{ {
gRenderer = Render_DirectX11; gRenderer = Render_DirectX11;
kiero::bind(8, (void**)&oPresent11, Dx11Handler); kiero::bind(8, (void**)&oPresent11, Dx11Handler);
} }
} }
} }
Hook::~Hook() Hook::~Hook()
{ {
SetWindowLongPtr(RsGlobal.ps->window, GWL_WNDPROC, (LRESULT)oWndProc); SetWindowLongPtr(RsGlobal.ps->window, GWL_WNDPROC, (LRESULT)oWndProc);
ImGui_ImplDX9_Shutdown(); ImGui_ImplDX9_Shutdown();
ImGui_ImplWin32_Shutdown(); ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
kiero::shutdown(); kiero::shutdown();
} }

View File

@ -10,23 +10,23 @@ extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg
class Hook class Hook
{ {
private: private:
static inline WNDPROC oWndProc; static inline WNDPROC oWndProc;
static inline f_Present11 oPresent11; static inline f_Present11 oPresent11;
static inline f_EndScene oEndScene; static inline f_EndScene oEndScene;
static inline f_Reset oReset; static inline f_Reset oReset;
static inline bool m_bMouseVisibility; static inline bool m_bMouseVisibility;
static void CALLBACK RenderFrame(void* ptr); static void CALLBACK RenderFrame(void* ptr);
static HRESULT CALLBACK Dx9Handler(IDirect3DDevice9* pDevice); static HRESULT CALLBACK Dx9Handler(IDirect3DDevice9* pDevice);
static HRESULT CALLBACK Dx11Handler(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags); static HRESULT CALLBACK Dx11Handler(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
static HRESULT CALLBACK Reset(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters); static HRESULT CALLBACK Reset(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static void ShowMouse(bool state); static void ShowMouse(bool state);
public: public:
static inline bool m_bShowMouse = false; static inline bool m_bShowMouse = false;
static inline std::function<void()> pCallbackFunc = nullptr; static inline std::function<void()> pCallbackFunc = nullptr;
Hook(); Hook();
~Hook(); ~Hook();
}; };

View File

@ -17,124 +17,124 @@ Hotkey vehInstantStop;
bool Hotkey::DrawUI(const char* label) bool Hotkey::DrawUI(const char* label)
{ {
bool active = m_CurrentHotkey == label; bool active = m_CurrentHotkey == label;
bool state = false; bool state = false;
if (active) if (active)
{ {
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]); ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]);
for (int key = 3; key != 135; ++key) for (int key = 3; key != 135; ++key)
{ {
if (KeyPressed(key)) if (KeyPressed(key))
{ {
m_key1 = key; m_key1 = key;
break; break;
} }
} }
for (int key = 135; key != 3; --key) for (int key = 135; key != 3; --key)
{ {
if (KeyPressed(key)) if (KeyPressed(key))
{ {
m_key2 = key; m_key2 = key;
break; break;
} }
} }
} }
std::string text; std::string text;
if (m_key1 != VK_NONE) if (m_key1 != VK_NONE)
{ {
text = key_names[m_key1 - 1]; text = key_names[m_key1 - 1];
} }
else else
{ {
text = "None"; text = "None";
} }
if (m_key1 != m_key2) if (m_key1 != m_key2)
{ {
text += (" + " + key_names[m_key2 - 1]); text += (" + " + key_names[m_key2 - 1]);
} }
if (ImGui::Button((text + std::string("##") + std::string(label)).c_str(), if (ImGui::Button((text + std::string("##") + std::string(label)).c_str(),
ImVec2(ImGui::GetWindowContentRegionWidth() / 3.5, ImGui::GetFrameHeight()*1.35f))) ImVec2(ImGui::GetWindowContentRegionWidth() / 3.5, ImGui::GetFrameHeight()*1.35f)))
{ {
if (!active) if (!active)
{ {
m_CurrentHotkey = label; m_CurrentHotkey = label;
} }
} }
if (active && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) if (active && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{ {
m_CurrentHotkey = ""; m_CurrentHotkey = "";
state = true; state = true;
} }
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)) if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
{ {
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
{ {
m_key1 = VK_NONE; m_key1 = VK_NONE;
m_key2 = VK_NONE; m_key2 = VK_NONE;
} }
else else
{ {
m_CurrentHotkey = ""; m_CurrentHotkey = "";
} }
state = true; state = true;
} }
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(label); ImGui::Text(label);
if (active) if (active)
{ {
ImGui::PopStyleColor(2); ImGui::PopStyleColor(2);
} }
return state; return state;
} }
bool Hotkey::Pressed() bool Hotkey::Pressed()
{ {
if (KeyPressed(m_key1) && KeyPressed(m_key2)) if (KeyPressed(m_key1) && KeyPressed(m_key2))
{ {
m_bPressed = true; m_bPressed = true;
} }
else else
{ {
if (m_bPressed) if (m_bPressed)
{ {
m_bPressed = false; m_bPressed = false;
return (m_CurrentHotkey == ""); return (m_CurrentHotkey == "");
} }
} }
return false; return false;
} }
std::string Hotkey::GetNameString() std::string Hotkey::GetNameString()
{ {
std::string text; std::string text;
if (m_key1 != VK_NONE) if (m_key1 != VK_NONE)
{ {
text = key_names[m_key1 - 1]; text = key_names[m_key1 - 1];
} }
else else
{ {
text = "None"; text = "None";
} }
if (m_key1 != m_key2) if (m_key1 != m_key2)
{ {
text += (" + " + key_names[m_key2 - 1]); text += (" + " + key_names[m_key2 - 1]);
} }
return text; return text;
} }

View File

@ -14,9 +14,9 @@ private:
public: public:
int m_key1; int m_key1;
int m_key2; int m_key2;
Hotkey(int key1 = -1, int key2 = -1) Hotkey(int key1 = -1, int key2 = -1)
: m_key1(key1), m_key2(key2) : m_key1(key1), m_key2(key2)
{} {}
// Draws ui to change the hotkeys from frontend // Draws ui to change the hotkeys from frontend

View File

@ -3,45 +3,45 @@
CJson::CJson(const char* name) CJson::CJson(const char* name)
{ {
if (name == "" || !std::filesystem::is_directory(PLUGIN_PATH((char*)"CheatMenu"))) if (name == "" || !std::filesystem::is_directory(PLUGIN_PATH((char*)"CheatMenu")))
{ {
return; return;
} }
m_FilePath = PLUGIN_PATH((char*)"/CheatMenu/json/") + std::string(name) + ".json"; m_FilePath = PLUGIN_PATH((char*)"/CheatMenu/json/") + std::string(name) + ".json";
if (std::filesystem::exists(m_FilePath)) if (std::filesystem::exists(m_FilePath))
{ {
try try
{ {
std::ifstream file(m_FilePath); std::ifstream file(m_FilePath);
file >> m_Data; file >> m_Data;
file.close(); file.close();
} }
catch (...) catch (...)
{ {
gLog << "Error trying to read " << m_FilePath << std::endl; gLog << "Error trying to read " << m_FilePath << std::endl;
m_Data = "{}"_json; m_Data = "{}"_json;
} }
} }
else else
{ {
m_Data = "{}"_json; m_Data = "{}"_json;
if (m_FilePath.find("config")) if (m_FilePath.find("config"))
{ {
gLog << "Creating config.json file" << std::endl; gLog << "Creating config.json file" << std::endl;
} }
else else
{ {
gLog << "Failed to locate file " << m_FilePath << std::endl; gLog << "Failed to locate file " << m_FilePath << std::endl;
} }
} }
} }
void CJson::WriteToDisk() void CJson::WriteToDisk()
{ {
std::ofstream file(m_FilePath); std::ofstream file(m_FilePath);
file << m_Data.dump(4, ' ', false, nlohmann::json::error_handler_t::replace) << std::endl; file << m_Data.dump(4, ' ', false, nlohmann::json::error_handler_t::replace) << std::endl;
file.close(); file.close();
} }

View File

@ -3,121 +3,121 @@
/* /*
Wrapper class for nlohmann::json Wrapper class for nlohmann::json
Contains helper methods Contains helper methods
*/ */
class CJson class CJson
{ {
private: private:
std::string m_FilePath; std::string m_FilePath;
public: public:
nlohmann::json m_Data; nlohmann::json m_Data;
/* /*
Returns a value from json structure hierarchy using '.' Returns a value from json structure hierarchy using '.'
Example: "Menu.Window.X" Example: "Menu.Window.X"
*/ */
// specialize since typeid(std::string) doesn't work // specialize since typeid(std::string) doesn't work
template <typename T> template <typename T>
T GetValue(std::string&& key, T&& defaultVal) T GetValue(std::string&& key, T&& defaultVal)
{ {
try try
{ {
std::stringstream ss(key); std::stringstream ss(key);
std::string line; std::string line;
nlohmann::json* json = &m_Data; nlohmann::json* json = &m_Data;
while (getline(ss, line, '.')) while (getline(ss, line, '.'))
{ {
json = &((*json)[line]); json = &((*json)[line]);
} }
// json library bugs with bool, using int instead // json library bugs with bool, using int instead
if (typeid(T) == typeid(bool)) if (typeid(T) == typeid(bool))
{ {
return ((json->get<int>() == 1) ? true : false); return ((json->get<int>() == 1) ? true : false);
} }
return json->get<T>(); return json->get<T>();
} }
catch (...) catch (...)
{ {
return defaultVal; return defaultVal;
} }
} }
template <> template <>
std::string GetValue(std::string&& key, std::string&& defaultVal) std::string GetValue(std::string&& key, std::string&& defaultVal)
{ {
try try
{ {
std::stringstream ss(key); std::stringstream ss(key);
std::string line; std::string line;
nlohmann::json* json = &m_Data; nlohmann::json* json = &m_Data;
while (getline(ss, line, '.')) while (getline(ss, line, '.'))
{ {
json = &((*json)[line]); json = &((*json)[line]);
} }
return json->get<std::string>(); return json->get<std::string>();
} }
catch (...) catch (...)
{ {
return defaultVal; return defaultVal;
} }
} }
/* /*
Allows to save values in json hierarchy using '.' Allows to save values in json hierarchy using '.'
Example: "Menu.Window.X" Example: "Menu.Window.X"
*/ */
template <typename T> template <typename T>
void SetValue(std::string&& key, T& val) void SetValue(std::string&& key, T& val)
{ {
std::stringstream ss(key); std::stringstream ss(key);
std::string line; std::string line;
nlohmann::json* json = &m_Data; nlohmann::json* json = &m_Data;
while (getline(ss, line, '.')) while (getline(ss, line, '.'))
{ {
json = &((*json)[line]); json = &((*json)[line]);
} }
// json library bugs with bool, using int instead // json library bugs with bool, using int instead
if (typeid(T) == typeid(bool)) if (typeid(T) == typeid(bool))
{ {
*json = (val ? 1 : 0); *json = (val ? 1 : 0);
} }
else else
{ {
*json = val; *json = val;
} }
} }
template <> template <>
void SetValue(std::string&& key, std::string& val) void SetValue(std::string&& key, std::string& val)
{ {
std::stringstream ss(key); std::stringstream ss(key);
std::string line; std::string line;
nlohmann::json* json = &m_Data; nlohmann::json* json = &m_Data;
while (getline(ss, line, '.')) while (getline(ss, line, '.'))
{ {
json = &((*json)[line]); json = &((*json)[line]);
} }
*json = val; *json = val;
} }
/* /*
Saves json data to disk Saves json data to disk
*/ */
void WriteToDisk(); void WriteToDisk();
CJson(const char* text = ""); CJson(const char* text = "");
}; };

File diff suppressed because it is too large Load Diff

View File

@ -4,49 +4,49 @@ class Menu
{ {
private: private:
enum class DisplayPos enum DisplayPos
{ {
CUSTOM, CUSTOM,
TOP_LEFT, TOP_LEFT,
TOP_RIGHT, TOP_RIGHT,
BOTTOM_LEFT, BOTTOM_LEFT,
BOTTOM_RIGHT BOTTOM_RIGHT
}; };
struct m_Overlay struct m_Overlay
{ {
static inline bool bCoord; static inline bool bCoord;
static inline bool bFPS; static inline bool bFPS;
static inline int mFPS; static inline int mFPS;
static inline bool bLocName; static inline bool bLocName;
static inline bool bTransparent; static inline bool bTransparent;
static inline bool bVehHealth; static inline bool bVehHealth;
static inline bool bVehSpeed; static inline bool bVehSpeed;
static inline bool bCpuUsage; static inline bool bCpuUsage;
static inline float fCpuUsage; static inline float fCpuUsage;
static inline bool bMemUsage; static inline bool bMemUsage;
static inline float fMemUsage; static inline float fMemUsage;
static inline std::vector<std::string> posNames = static inline std::vector<std::string> posNames =
{ {
"Custom", "Top left", "Top right", "Bottom left", "Bottom right" "Custom", "Top left", "Top right", "Bottom left", "Bottom right"
}; };
static inline DisplayPos mSelectedPos = DisplayPos::BOTTOM_RIGHT; static inline DisplayPos mSelectedPos = DisplayPos::BOTTOM_RIGHT;
static inline float fPosX; static inline float fPosX;
static inline float fPosY; static inline float fPosY;
static inline int mTotalRam = 0; static inline int mTotalRam = 0;
static inline float textColor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; static inline float textColor[4] = {1.0f, 1.0f, 1.0f, 1.0f};
}; };
public: public:
struct m_Commands struct m_Commands
{ {
static inline bool m_bShowMenu; static inline bool m_bShowMenu;
static inline char m_nInputBuffer[INPUT_BUFFER_SIZE] = ""; static inline char m_nInputBuffer[INPUT_BUFFER_SIZE] = "";
}; };
Menu(); Menu();
static void Draw(); static void Draw();
static void DrawOverlay(); static void DrawOverlay();
static void DrawShortcutsWindow(); static void DrawShortcutsWindow();
static void ProcessCommands(); static void ProcessCommands();
}; };

View File

@ -4,275 +4,276 @@
// Neon sprite // Neon sprite
const unsigned char neon_mask[1689] = const unsigned char neon_mask[1689] =
{ {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00,
0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
0x00, 0x80, 0x08, 0x06, 0x00, 0x00, 0x00, 0xbb, 0x81, 0x6f, 0x6a, 0x00, 0x80, 0x08, 0x06, 0x00, 0x00, 0x00, 0xbb, 0x81, 0x6f, 0x6a,
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b,
0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00,
0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, 0x25, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, 0x25,
0x00, 0x00, 0x80, 0x83, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x83, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0x80,
0xe9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00,
0x3a, 0x98, 0x00, 0x00, 0x17, 0x6f, 0x92, 0x5f, 0xc5, 0x46, 0x00, 0x3a, 0x98, 0x00, 0x00, 0x17, 0x6f, 0x92, 0x5f, 0xc5, 0x46, 0x00,
0x00, 0x06, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xec, 0x5d, 0x00, 0x06, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xec, 0x5d,
0xdb, 0x8e, 0xe4, 0x2a, 0x0c, 0x64, 0xa3, 0xf3, 0x10, 0x45, 0x49, 0xdb, 0x8e, 0xe4, 0x2a, 0x0c, 0x64, 0xa3, 0xf3, 0x10, 0x45, 0x49,
0x2b, 0xe2, 0xff, 0xbf, 0x11, 0x45, 0x09, 0x42, 0x79, 0x9b, 0xf3, 0x2b, 0xe2, 0xff, 0xbf, 0x11, 0x45, 0x09, 0x42, 0x79, 0x9b, 0xf3,
0x34, 0xda, 0xde, 0x08, 0x70, 0xd9, 0x18, 0x42, 0x66, 0x1a, 0x69, 0x34, 0xda, 0xde, 0x08, 0x70, 0xd9, 0x18, 0x42, 0x66, 0x1a, 0x69,
0xb4, 0xdb, 0x37, 0x3a, 0x55, 0x2e, 0x97, 0x0d, 0xdd, 0x6a, 0xfe, 0xb4, 0xdb, 0x37, 0x3a, 0x55, 0x2e, 0x97, 0x0d, 0xdd, 0x6a, 0xfe,
0x7c, 0x7d, 0x7d, 0x99, 0x86, 0x63, 0x01, 0x9f, 0x77, 0xb4, 0xba, 0x7c, 0x7d, 0x7d, 0x99, 0x86, 0x63, 0x01, 0x9f, 0x77, 0xb4, 0xba,
0xa0, 0x3f, 0x95, 0x09, 0x58, 0x14, 0xe6, 0x38, 0x9e, 0x46, 0x00, 0xa0, 0x3f, 0x95, 0x09, 0x58, 0x14, 0xe6, 0x38, 0x9e, 0x46, 0x00,
0x02, 0xda, 0x26, 0xee, 0x77, 0xad, 0xc9, 0xd0, 0x24, 0x60, 0x11, 0x02, 0xda, 0x26, 0xee, 0x77, 0xad, 0xc9, 0xd0, 0x24, 0x60, 0x11,
0x82, 0x36, 0x02, 0x32, 0x8e, 0xde, 0x08, 0x58, 0x98, 0xa0, 0x2d, 0x82, 0x36, 0x02, 0x32, 0x8e, 0xde, 0x08, 0x58, 0x98, 0xa0, 0x2d,
0x03, 0xb0, 0xab, 0x49, 0x82, 0x06, 0x01, 0x4b, 0x21, 0x70, 0x14, 0x03, 0xb0, 0xab, 0x49, 0x82, 0x06, 0x01, 0x4b, 0x21, 0x70, 0x14,
0x74, 0x15, 0x22, 0x4a, 0x09, 0x40, 0xc1, 0x53, 0xf7, 0xa1, 0xd1, 0x74, 0x15, 0x22, 0x4a, 0x09, 0x40, 0xc1, 0x53, 0xf7, 0xa1, 0xd1,
0x77, 0xbd, 0x10, 0x80, 0x4a, 0xde, 0x0a, 0x14, 0xe0, 0x84, 0x6a, 0x77, 0xbd, 0x10, 0x80, 0x4a, 0xde, 0x0a, 0x14, 0xe0, 0x84, 0x6a,
0x38, 0x5a, 0x11, 0xa0, 0x01, 0x7e, 0x8d, 0xbc, 0x7e, 0x63, 0x12, 0x38, 0x5a, 0x11, 0xa0, 0x01, 0x7e, 0x8d, 0xbc, 0x7e, 0x63, 0x12,
0xa1, 0x42, 0x82, 0x16, 0x01, 0x96, 0x41, 0xc4, 0x9a, 0x99, 0xbb, 0xa1, 0x42, 0x82, 0x16, 0x01, 0x96, 0x41, 0xc4, 0x9a, 0x99, 0xbb,
0x39, 0x09, 0x5c, 0x02, 0x16, 0x66, 0xe4, 0x53, 0x51, 0x7f, 0x45, 0x39, 0x09, 0x5c, 0x02, 0x16, 0x66, 0xe4, 0x53, 0x51, 0x7f, 0x45,
0xe6, 0xd9, 0x41, 0x22, 0x9c, 0xa6, 0x31, 0x72, 0x08, 0xa8, 0x01, 0xe6, 0xd9, 0x41, 0x22, 0x9c, 0xa6, 0x31, 0x72, 0x08, 0xa8, 0x01,
0x7e, 0x36, 0xc6, 0x78, 0x90, 0x08, 0x0e, 0x09, 0x4d, 0x08, 0x48, 0x7e, 0x36, 0xc6, 0x78, 0x90, 0x08, 0x0e, 0x09, 0x4d, 0x08, 0x48,
0x81, 0x4f, 0x49, 0xfe, 0x0a, 0x3c, 0x36, 0x7c, 0x6b, 0x12, 0x50, 0x81, 0x4f, 0x49, 0xfe, 0x0a, 0x3c, 0x36, 0x7c, 0x6b, 0x12, 0x50,
0x02, 0x16, 0x41, 0xe4, 0x63, 0x51, 0x9f, 0x13, 0x24, 0x78, 0x06, 0x02, 0x16, 0x41, 0xe4, 0x63, 0x51, 0x9f, 0x13, 0x24, 0x78, 0x06,
0x11, 0xaa, 0x24, 0x0c, 0xca, 0x2d, 0xae, 0x04, 0xfc, 0xf7, 0xed, 0x11, 0xaa, 0x24, 0x0c, 0xca, 0x2d, 0xae, 0x04, 0xfc, 0xf7, 0xed,
0xd8, 0xe3, 0xaf, 0x88, 0x92, 0x2c, 0x68, 0xbe, 0xd0, 0x18, 0x04, 0xd8, 0xe3, 0xaf, 0x88, 0x92, 0x2c, 0x68, 0xbe, 0xd0, 0x18, 0x04,
0xaf, 0xb1, 0x05, 0xe0, 0xdf, 0x81, 0x4e, 0x97, 0xbf, 0xeb, 0xe3, 0xaf, 0xb1, 0x05, 0xe0, 0xdf, 0x81, 0x4e, 0x97, 0xbf, 0xeb, 0xe3,
0x73, 0xc6, 0x30, 0x45, 0x60, 0xb5, 0x08, 0x40, 0xc0, 0xbf, 0x12, 0x73, 0xc6, 0x30, 0x45, 0x60, 0xb5, 0x08, 0x40, 0xc0, 0xbf, 0x12,
0xe0, 0xcd, 0x05, 0xf0, 0xf4, 0x36, 0xc7, 0x14, 0x51, 0xc0, 0x95, 0xe0, 0xcd, 0x05, 0xf0, 0xf4, 0x36, 0xc7, 0x14, 0x51, 0xc0, 0x95,
0x84, 0x95, 0x59, 0x82, 0x97, 0x52, 0x02, 0x16, 0x01, 0xf3, 0xaf, 0x84, 0x95, 0x59, 0x82, 0x97, 0x52, 0x02, 0x16, 0x01, 0xf3, 0xaf,
0x4b, 0x34, 0xaf, 0x51, 0xbf, 0x02, 0x9e, 0x12, 0xff, 0xa7, 0x48, 0x4b, 0x34, 0xaf, 0x51, 0xbf, 0x02, 0x9e, 0x12, 0xff, 0xa7, 0x48,
0xb0, 0x77, 0x2a, 0x80, 0x92, 0x7e, 0xcc, 0xe5, 0x63, 0x20, 0x4d, 0xb0, 0x77, 0x2a, 0x80, 0x92, 0x7e, 0xcc, 0xe5, 0x63, 0x20, 0x4d,
0x42, 0x01, 0x14, 0x09, 0xb9, 0xca, 0xc3, 0x52, 0xc1, 0x50, 0x18, 0x42, 0x01, 0x14, 0x09, 0xb9, 0xca, 0xc3, 0x52, 0xc1, 0x50, 0x18,
0x7d, 0x4b, 0x94, 0xba, 0x58, 0xbe, 0x5f, 0x41, 0x4f, 0x89, 0xdb, 0x7d, 0x4b, 0x94, 0xba, 0x58, 0xbe, 0x5f, 0x41, 0x4f, 0x89, 0xdb,
0x29, 0x12, 0x90, 0x54, 0x68, 0xe2, 0x01, 0xa9, 0x31, 0x67, 0x22, 0x29, 0x12, 0x90, 0x54, 0x68, 0xe2, 0x01, 0xa9, 0x31, 0x67, 0x22,
0x9b, 0x03, 0x9e, 0x52, 0xcb, 0x75, 0x4e, 0x24, 0x15, 0xac, 0x36, 0x9b, 0x03, 0x9e, 0x52, 0xcb, 0x75, 0x4e, 0x24, 0x15, 0xac, 0x36,
0x01, 0x36, 0x23, 0xbb, 0xf7, 0xe8, 0xc7, 0x0c, 0xcf, 0x10, 0x60, 0x01, 0x36, 0x23, 0xbb, 0xf7, 0xe8, 0xc7, 0x0c, 0xcf, 0x10, 0x60,
0x29, 0x52, 0x26, 0xa2, 0x3c, 0x16, 0xed, 0x56, 0x0d, 0xc2, 0xda, 0x29, 0x52, 0x26, 0xa2, 0x3c, 0x16, 0xed, 0x56, 0x0d, 0xc2, 0xda,
0x9f, 0x32, 0x3e, 0x29, 0x78, 0x8e, 0xb2, 0xe6, 0x4c, 0x6f, 0xc0, 0x9f, 0x32, 0x3e, 0x29, 0x78, 0x8e, 0xb2, 0xe6, 0x4c, 0x6f, 0xc0,
0xee, 0x0b, 0xb8, 0x29, 0x60, 0x41, 0xe3, 0x2b, 0x01, 0x3f, 0x31, 0xee, 0x0b, 0xb8, 0x29, 0x60, 0x41, 0xe3, 0x2b, 0x01, 0x3f, 0x31,
0x53, 0xa1, 0x48, 0x05, 0x03, 0x53, 0xfe, 0x68, 0xf4, 0x0d, 0xe0, 0x53, 0xa1, 0x48, 0x05, 0x03, 0x53, 0xfe, 0x68, 0xf4, 0x0d, 0xe0,
0x03, 0xc6, 0x18, 0x33, 0x0a, 0x48, 0xa0, 0x54, 0x50, 0x6c, 0x82, 0x03, 0xc6, 0x18, 0x33, 0x0a, 0x48, 0xa0, 0x54, 0x50, 0x6c, 0x82,
0x4b, 0x85, 0xe8, 0xe7, 0xc0, 0x8f, 0x09, 0x22, 0x26, 0x66, 0xea, 0x4b, 0x85, 0xe8, 0xe7, 0xc0, 0x8f, 0x09, 0x22, 0x26, 0x66, 0xea,
0x89, 0xda, 0xe3, 0xd2, 0x2a, 0x50, 0x12, 0x7d, 0x54, 0x0d, 0x57, 0x89, 0xda, 0xe3, 0xd2, 0x2a, 0x50, 0x12, 0x7d, 0x54, 0x0d, 0x57,
0x52, 0x67, 0xe2, 0xfd, 0x6e, 0x2f, 0x83, 0x14, 0xe8, 0x31, 0x03, 0x52, 0x67, 0xe2, 0xfd, 0x6e, 0x2f, 0x83, 0x14, 0xe8, 0x31, 0x03,
0x76, 0x14, 0x92, 0xb7, 0x12, 0x4b, 0x72, 0x31, 0x01, 0x16, 0x94, 0x76, 0x14, 0x92, 0xb7, 0x12, 0x4b, 0x72, 0x31, 0x01, 0x16, 0x94,
0xff, 0x4c, 0xd4, 0x73, 0x24, 0xca, 0x1c, 0x52, 0xa5, 0x66, 0xb8, 0xff, 0x4c, 0xd4, 0x73, 0x24, 0xca, 0x1c, 0x52, 0xa5, 0x66, 0xb8,
0x68, 0x2a, 0xe0, 0x55, 0x49, 0x3d, 0x94, 0x0a, 0x28, 0x33, 0x64, 0x68, 0x2a, 0xe0, 0x55, 0x49, 0x3d, 0x94, 0x0a, 0x28, 0x33, 0x64,
0x99, 0xf8, 0x50, 0x58, 0xff, 0x73, 0xdd, 0x9b, 0x66, 0xf4, 0x29, 0x99, 0xf8, 0x50, 0x58, 0xff, 0x73, 0xdd, 0x9b, 0x66, 0xf4, 0x29,
0xf0, 0xc8, 0xce, 0x14, 0x3b, 0x05, 0x90, 0x09, 0x38, 0x46, 0x74, 0xf0, 0xc8, 0xce, 0x14, 0x3b, 0x05, 0x90, 0x09, 0x38, 0x46, 0x74,
0x2a, 0x7a, 0xca, 0xa4, 0xa5, 0x46, 0x4e, 0x1f, 0x60, 0x13, 0x52, 0x2a, 0x7a, 0xca, 0xa4, 0xa5, 0x46, 0x4e, 0x1f, 0x60, 0x13, 0x52,
0x9b, 0x19, 0xe6, 0x27, 0x4d, 0x83, 0x6a, 0x63, 0xa8, 0x94, 0xff, 0x9b, 0x19, 0xe6, 0x27, 0x4d, 0x83, 0x6a, 0x63, 0xa8, 0x94, 0xff,
0x1a, 0xf2, 0x47, 0x5f, 0xc3, 0xf5, 0x81, 0x25, 0x45, 0x00, 0x37, 0x1a, 0xf2, 0x47, 0x5f, 0xc3, 0xf5, 0x81, 0x25, 0x45, 0x00, 0x37,
0xff, 0x6b, 0x44, 0x9e, 0xe3, 0x31, 0x2a, 0x3e, 0xc0, 0x55, 0xc0, 0xff, 0x6b, 0x44, 0x9e, 0xe3, 0x31, 0x2a, 0x3e, 0xc0, 0x55, 0xc0,
0x5a, 0xe0, 0x01, 0xb5, 0x87, 0xa8, 0x1c, 0x0e, 0xcc, 0xfa, 0x2f, 0x5a, 0xe0, 0x01, 0xb5, 0x87, 0xa8, 0x1c, 0x0e, 0xcc, 0xfa, 0x2f,
0x6d, 0x7e, 0x6a, 0x37, 0x5b, 0x73, 0x4b, 0x0f, 0x78, 0x11, 0xf2, 0x6d, 0x7e, 0x6a, 0x37, 0x5b, 0x73, 0x4b, 0x0f, 0x78, 0x11, 0xf2,
0xd7, 0x24, 0x62, 0x14, 0x80, 0x5f, 0x6b, 0x11, 0xb0, 0x0a, 0xa2, 0xd7, 0x24, 0x62, 0x14, 0x80, 0x5f, 0x6b, 0x11, 0xb0, 0x0a, 0xa2,
0x3f, 0x56, 0x8c, 0x3a, 0x55, 0x0e, 0x21, 0x15, 0x0f, 0x40, 0xfd, 0x3f, 0x56, 0x8c, 0x3a, 0x55, 0x0e, 0x21, 0x15, 0x0f, 0x40, 0xfd,
0xb7, 0x8c, 0x1e, 0x60, 0x32, 0x0f, 0x1b, 0x43, 0xa6, 0x02, 0x58, 0xb7, 0x8c, 0x1e, 0x60, 0x32, 0x0f, 0x1b, 0x43, 0xa6, 0x02, 0x58,
0x81, 0xfc, 0x6b, 0x44, 0x7f, 0x04, 0xab, 0xc1, 0x2c, 0x49, 0x83, 0x81, 0xfc, 0x6b, 0x44, 0x7f, 0x04, 0xab, 0xc1, 0x2c, 0x49, 0x83,
0x5a, 0xab, 0xc1, 0xb1, 0x93, 0xf9, 0x48, 0x35, 0x7f, 0x13, 0x70, 0x5a, 0xab, 0xc1, 0xb1, 0x93, 0xf9, 0x48, 0x35, 0x7f, 0x13, 0x70,
0x30, 0xf3, 0x5f, 0xb2, 0x01, 0xd2, 0xaa, 0x1a, 0xb0, 0x3e, 0x4a, 0x30, 0xf3, 0x5f, 0xb2, 0x01, 0xd2, 0xaa, 0x1a, 0xb0, 0x3e, 0x4a,
0x1b, 0x88, 0x26, 0xc8, 0x66, 0xea, 0xac, 0xd4, 0xf8, 0x90, 0xcf, 0x1b, 0x88, 0x26, 0xc8, 0x66, 0xea, 0xac, 0xd4, 0xf8, 0x90, 0xcf,
0x07, 0xa8, 0x79, 0xd5, 0x48, 0xff, 0x8f, 0xb9, 0x10, 0x2a, 0xdd, 0x07, 0xa8, 0x79, 0xd5, 0x48, 0xff, 0x8f, 0xb9, 0x10, 0x2a, 0xdd,
0xf5, 0xa9, 0x65, 0x98, 0xdf, 0x73, 0xf9, 0x8b, 0x6a, 0x37, 0x29, 0xf5, 0xa9, 0x65, 0x98, 0xdf, 0x73, 0xf9, 0x8b, 0x6a, 0x37, 0x29,
0x01, 0x5c, 0xf9, 0x6b, 0x01, 0xbd, 0x3e, 0x37, 0x44, 0x54, 0x70, 0x01, 0x5c, 0xf9, 0x6b, 0x01, 0xbd, 0x3e, 0x37, 0x44, 0x54, 0x70,
0xbe, 0x3d, 0x37, 0x64, 0x7a, 0x95, 0x5d, 0x62, 0x82, 0xb6, 0x30, 0xbe, 0x3d, 0x37, 0x64, 0x7a, 0x95, 0x5d, 0x62, 0x82, 0xb6, 0x30,
0x7a, 0x31, 0xf9, 0x87, 0x4a, 0xb9, 0x1f, 0x12, 0xd7, 0x32, 0x97, 0x7a, 0x31, 0xf9, 0x87, 0x4a, 0xb9, 0x1f, 0x12, 0xd7, 0x32, 0x97,
0x6c, 0x88, 0xe4, 0xf2, 0x7f, 0x06, 0xca, 0x91, 0xb6, 0xd4, 0xa7, 0x6c, 0x88, 0xe4, 0xf2, 0x7f, 0x06, 0xca, 0x91, 0xb6, 0xd4, 0xa7,
0x0c, 0xc9, 0x31, 0x1f, 0x61, 0x77, 0x85, 0xdc, 0x32, 0x38, 0xdf, 0x0c, 0xc9, 0x31, 0x1f, 0x61, 0x77, 0x85, 0xdc, 0x32, 0x38, 0xdf,
0x98, 0xe7, 0xa5, 0xf3, 0x5b, 0x0d, 0x02, 0x24, 0x0d, 0x4b, 0x0d, 0x98, 0xe7, 0xa5, 0xf3, 0x5b, 0x0d, 0x02, 0x24, 0x0d, 0x4b, 0x0d,
0x90, 0xd4, 0x7b, 0xcd, 0xc0, 0xea, 0x70, 0x41, 0x5a, 0xe1, 0x95, 0x90, 0xd4, 0x7b, 0xcd, 0xc0, 0xea, 0x70, 0x41, 0x5a, 0xe1, 0x95,
0xb8, 0xa0, 0x1e, 0x5b, 0xdf, 0x99, 0xc0, 0x64, 0xb9, 0x0a, 0x78, 0xb8, 0xa0, 0x1e, 0x5b, 0xdf, 0x99, 0xc0, 0x64, 0xb9, 0x0a, 0x78,
0x01, 0x51, 0x19, 0xcd, 0x43, 0xc7, 0x60, 0xb0, 0x9d, 0xa0, 0xbb, 0x01, 0x51, 0x19, 0xcd, 0x43, 0xc7, 0x60, 0xb0, 0x9d, 0xa0, 0xbb,
0x73, 0x1f, 0x35, 0xc3, 0x89, 0xb9, 0x8a, 0x25, 0x37, 0x44, 0x7a, 0x73, 0x1f, 0x35, 0xc3, 0x89, 0xb9, 0x8a, 0x25, 0x37, 0x44, 0x7a,
0x5a, 0xed, 0x55, 0xa9, 0x36, 0x43, 0x06, 0xf4, 0x4a, 0xa8, 0x60, 0x5a, 0xed, 0x55, 0xa9, 0x36, 0x43, 0x06, 0xf4, 0x4a, 0xa8, 0x60,
0xea, 0x90, 0x24, 0xae, 0x11, 0x8a, 0xaa, 0x40, 0x4f, 0xf9, 0x3f, 0xea, 0x90, 0x24, 0xae, 0x11, 0x8a, 0xaa, 0x40, 0x4f, 0xf9, 0x3f,
0x82, 0xcd, 0x50, 0x76, 0x35, 0x78, 0x30, 0x0d, 0xb0, 0xf7, 0x31, 0x82, 0xcd, 0x50, 0x76, 0x35, 0x78, 0x30, 0x0d, 0xb0, 0xf7, 0x31,
0x49, 0x53, 0x40, 0xcb, 0x00, 0xbb, 0x01, 0xa7, 0xd9, 0x08, 0x3d, 0x49, 0x53, 0x40, 0xcb, 0x00, 0xbb, 0x01, 0xa7, 0xd9, 0x08, 0x3d,
0x25, 0xff, 0xd9, 0xef, 0xcf, 0x59, 0x0c, 0x21, 0x1d, 0x59, 0xaf, 0x25, 0xff, 0xd9, 0xef, 0xcf, 0x59, 0x0c, 0x21, 0x1d, 0x59, 0xaf,
0x2a, 0x58, 0x35, 0x4c, 0x30, 0x74, 0x92, 0x06, 0xaa, 0xd7, 0x31, 0x2a, 0x58, 0x35, 0x4c, 0x30, 0x74, 0x92, 0x06, 0xaa, 0xd7, 0x31,
0x34, 0xca, 0xbf, 0x3b, 0x15, 0xf0, 0xd2, 0x2e, 0x83, 0x3f, 0x6a, 0x34, 0xca, 0xbf, 0x3b, 0x15, 0xf0, 0xd2, 0x2e, 0x83, 0x3f, 0x6a,
0xfc, 0x74, 0x02, 0xe6, 0xdf, 0x4e, 0xc0, 0xaf, 0x57, 0x80, 0xff, 0xfc, 0x74, 0x02, 0xe6, 0xdf, 0x4e, 0xc0, 0xaf, 0x57, 0x80, 0xff,
0x28, 0x40, 0x91, 0x80, 0xa7, 0x96, 0xc1, 0xfd, 0xb7, 0x97, 0x41, 0x28, 0x40, 0x91, 0x80, 0xa7, 0x96, 0xc1, 0xfd, 0xb7, 0x97, 0x41,
0x96, 0x02, 0x1c, 0x93, 0xf9, 0xf3, 0x01, 0x0a, 0x30, 0x26, 0xf3, 0x96, 0x02, 0x1c, 0x93, 0xf9, 0xf3, 0x01, 0x0a, 0x30, 0x26, 0xf3,
0x01, 0x09, 0xaa, 0x00, 0x0f, 0x5e, 0x44, 0x78, 0x58, 0x7a, 0x40, 0x01, 0x09, 0xaa, 0x00, 0x0f, 0x5e, 0x44, 0x78, 0x58, 0x7a, 0x40,
0x04, 0x78, 0xd3, 0xcf, 0x28, 0x21, 0xd8, 0xa5, 0x08, 0x58, 0xa4, 0x04, 0x78, 0xd3, 0xcf, 0x28, 0x21, 0xd8, 0xa5, 0x08, 0x58, 0xa4,
0x06, 0xd2, 0xe9, 0x08, 0xda, 0x0a, 0xa0, 0xde, 0xe0, 0xbc, 0x11, 0x06, 0xd2, 0xe9, 0x08, 0xda, 0x0a, 0xa0, 0xde, 0xe0, 0xbc, 0x11,
0xec, 0x99, 0xb8, 0x26, 0x8f, 0xaa, 0x60, 0xc8, 0x3c, 0xb8, 0x3d, 0xec, 0x99, 0xb8, 0x26, 0x8f, 0xaa, 0x60, 0xc8, 0x3c, 0xb8, 0x3d,
0xd4, 0x07, 0xde, 0xaf, 0x77, 0x97, 0x2a, 0xc0, 0x75, 0x08, 0x2e, 0xd4, 0x07, 0xde, 0xaf, 0x77, 0x97, 0x2a, 0xc0, 0x75, 0x08, 0x2e,
0xd4, 0xf0, 0x07, 0x6a, 0x4f, 0x50, 0x6a, 0x84, 0xa1, 0x01, 0xf8, 0xd4, 0xf0, 0x07, 0x6a, 0x4f, 0x50, 0x6a, 0x84, 0xa1, 0x01, 0xf8,
0x98, 0xfc, 0x03, 0xa7, 0x04, 0xa2, 0x1e, 0xb0, 0x77, 0xee, 0x03, 0x98, 0xfc, 0x03, 0xa7, 0x04, 0xa2, 0x1e, 0xb0, 0x77, 0xee, 0x03,
0xea, 0xad, 0xb0, 0x23, 0xd8, 0x0b, 0x1d, 0xe6, 0x3b, 0xa5, 0xd6, 0xea, 0xad, 0xb0, 0x23, 0xd8, 0x0b, 0x1d, 0xe6, 0x3b, 0xa5, 0xd6,
0xe4, 0x0f, 0x2d, 0x68, 0x2e, 0x86, 0xce, 0x4a, 0x69, 0x10, 0x04, 0xe4, 0x0f, 0x2d, 0x68, 0x2e, 0x86, 0xce, 0x4a, 0x69, 0x10, 0x04,
0xef, 0x85, 0x18, 0xe0, 0x21, 0x21, 0xe0, 0x6e, 0x2f, 0x28, 0x99, 0xef, 0x85, 0x18, 0xe0, 0x21, 0x21, 0xe0, 0x6e, 0x2f, 0x28, 0x99,
0xdf, 0x71, 0x3d, 0xc0, 0x5d, 0x7c, 0x20, 0x55, 0x06, 0x43, 0x45, 0xdf, 0x71, 0x3d, 0xc0, 0x5d, 0x7c, 0x20, 0x55, 0x06, 0x43, 0x45,
0x12, 0x50, 0xf3, 0xfb, 0xbe, 0xed, 0x39, 0x06, 0xc8, 0x5d, 0x0c, 0x12, 0x50, 0xf3, 0xfb, 0xbe, 0xed, 0x39, 0x06, 0xc8, 0x5d, 0x0c,
0x21, 0xa0, 0xce, 0x86, 0xab, 0xc8, 0x09, 0x6c, 0x82, 0xb2, 0x98, 0x21, 0xa0, 0xce, 0x86, 0xab, 0xc8, 0x09, 0x6c, 0x82, 0xb2, 0x98,
0x90, 0x6f, 0x89, 0x6d, 0xe6, 0xdf, 0x7d, 0x75, 0x6f, 0xfe, 0xee, 0x90, 0x6f, 0x89, 0x6d, 0xe6, 0xdf, 0x7d, 0x75, 0x6f, 0xfe, 0xee,
0xb5, 0x05, 0x00, 0x60, 0x60, 0x10, 0x12, 0x18, 0x3e, 0x13, 0x34, 0xb5, 0x05, 0x00, 0x60, 0x60, 0x10, 0x12, 0x18, 0x3e, 0x13, 0x34,
0x5a, 0x78, 0x6e, 0x23, 0xe4, 0x15, 0x65, 0x1e, 0xde, 0xfe, 0x34, 0x5a, 0x78, 0x6e, 0x23, 0xe4, 0x15, 0x65, 0x1e, 0xde, 0xfe, 0x34,
0xbc, 0x80, 0x2d, 0xff, 0x77, 0x02, 0x0e, 0xd0, 0x07, 0xa4, 0x69, 0xbc, 0x80, 0x2d, 0xff, 0x77, 0x02, 0x0e, 0xd0, 0x07, 0xa4, 0x69,
0x10, 0x03, 0x4e, 0xdd, 0x87, 0x44, 0xbf, 0x98, 0x3c, 0xea, 0xab, 0x10, 0x03, 0x4e, 0xdd, 0x87, 0x44, 0xbf, 0x98, 0x3c, 0xea, 0xab,
0xb2, 0xc8, 0xba, 0x40, 0xed, 0x62, 0x14, 0x8c, 0x32, 0x55, 0xfe, 0xb2, 0xc8, 0xba, 0x40, 0xed, 0x62, 0x14, 0x8c, 0x32, 0x55, 0xfe,
0x9c, 0xe6, 0x6a, 0x50, 0xd2, 0x13, 0xdc, 0x35, 0x1f, 0xf9, 0xeb, 0x9c, 0xe6, 0x6a, 0x50, 0xd2, 0x13, 0xdc, 0x35, 0x1f, 0xf9, 0xeb,
0x73, 0xb9, 0x14, 0x70, 0x09, 0x73, 0xf1, 0x60, 0xee, 0x9f, 0x95, 0x73, 0xb9, 0x14, 0x70, 0x09, 0x73, 0xf1, 0x60, 0xee, 0x9f, 0x95,
0xc0, 0x87, 0x44, 0xe4, 0x3d, 0x37, 0xff, 0x91, 0x56, 0x98, 0x6b, 0xc0, 0x87, 0x44, 0xe4, 0x3d, 0x37, 0xff, 0x91, 0x56, 0x98, 0x6b,
0x88, 0x3d, 0xb6, 0xc6, 0x6a, 0x1b, 0x22, 0x9b, 0x52, 0x5f, 0xa0, 0x88, 0x3d, 0xb6, 0xc6, 0x6a, 0x1b, 0x22, 0x9b, 0x52, 0x5f, 0xa0,
0xd9, 0xf9, 0x85, 0x4c, 0xf9, 0x73, 0x89, 0x7f, 0x8b, 0x3d, 0x80, 0xd9, 0xf9, 0x85, 0x4c, 0xf9, 0x73, 0x89, 0x7f, 0x8b, 0x3d, 0x80,
0x4a, 0x83, 0xd0, 0x20, 0xf7, 0x43, 0x46, 0x89, 0x9b, 0x86, 0x02, 0x4a, 0x83, 0xd0, 0x20, 0xf7, 0x43, 0x46, 0x89, 0x9b, 0x86, 0x02,
0x20, 0xf6, 0x6e, 0x96, 0x7f, 0x28, 0x58, 0xa3, 0x88, 0x15, 0xb0, 0x20, 0xf6, 0x6e, 0x96, 0x7f, 0x28, 0x58, 0xa3, 0x88, 0x15, 0xb0,
0x15, 0x2e, 0x8e, 0x6a, 0x0e, 0xce, 0x06, 0xee, 0x11, 0x23, 0x80, 0x15, 0x2e, 0x8e, 0x6a, 0x0e, 0xce, 0x06, 0xee, 0x11, 0x23, 0x80,
0xfb, 0x8b, 0xac, 0xad, 0xab, 0x41, 0x60, 0x44, 0x1e, 0x56, 0xee, 0xfb, 0x8b, 0xac, 0xad, 0xab, 0x41, 0x60, 0x44, 0x1e, 0x56, 0xee,
0x50, 0x89, 0x6d, 0x8d, 0x1d, 0xa3, 0x53, 0x10, 0x88, 0x0d, 0xe8, 0x50, 0x89, 0x6d, 0x8d, 0x1d, 0xa3, 0x53, 0x10, 0x88, 0x0d, 0xe8,
0x07, 0x0e, 0x2e, 0x01, 0x57, 0x36, 0xb7, 0x06, 0x4a, 0x68, 0xb6, 0x07, 0x0e, 0x2e, 0x01, 0x57, 0x36, 0xb7, 0x06, 0x4a, 0x68, 0xb6,
0xc5, 0x86, 0xee, 0x07, 0x68, 0x6c, 0x90, 0x8c, 0x0a, 0xf2, 0x47, 0xc5, 0x86, 0xee, 0x07, 0x68, 0x6c, 0x90, 0x8c, 0x0a, 0xf2, 0x47,
0xca, 0x5f, 0x11, 0x01, 0x87, 0x62, 0x8e, 0xd6, 0xd8, 0x38, 0x55, 0xca, 0x5f, 0x11, 0x01, 0x87, 0x62, 0x8e, 0xd6, 0xd8, 0x38, 0x55,
0xcd, 0xff, 0xd2, 0xb5, 0x40, 0xad, 0x8f, 0xcd, 0x4e, 0x46, 0xf4, 0xcd, 0xff, 0xd2, 0xb5, 0x40, 0xad, 0x8f, 0xcd, 0x4e, 0x46, 0xf4,
0xb9, 0xf9, 0xcf, 0x26, 0xc0, 0x01, 0x3e, 0xf0, 0xde, 0x87, 0x53, 0xb9, 0xf9, 0xcf, 0x26, 0xc0, 0x01, 0x3e, 0xf0, 0xde, 0x87, 0x53,
0x52, 0x3d, 0x2b, 0x44, 0x5f, 0x54, 0xfe, 0x6a, 0xaf, 0x06, 0x29, 0x52, 0x3d, 0x2b, 0x44, 0x5f, 0x54, 0xfe, 0x6a, 0xaf, 0x06, 0x29,
0x33, 0x3c, 0x85, 0xd1, 0xa7, 0xfa, 0x13, 0x96, 0xfc, 0x35, 0x08, 0x33, 0x3c, 0x85, 0xd1, 0xa7, 0xfa, 0x13, 0x96, 0xfc, 0x35, 0x08,
0xd8, 0x81, 0x9c, 0x0c, 0x42, 0xe9, 0xa7, 0xfc, 0xc5, 0x6b, 0x36, 0xd8, 0x81, 0x9c, 0x0c, 0x42, 0xe9, 0xa7, 0xfc, 0xc5, 0x6b, 0x36,
0x61, 0x03, 0x22, 0x13, 0x30, 0x0d, 0xb8, 0x1b, 0x24, 0x27, 0xa1, 0x61, 0x03, 0x22, 0x13, 0x30, 0x0d, 0xb8, 0x1b, 0x24, 0x27, 0xa1,
0x88, 0x20, 0xf4, 0x21, 0x87, 0xe6, 0x3f, 0xb7, 0x0f, 0xa8, 0xa1, 0x88, 0x20, 0xf4, 0x21, 0x87, 0xe6, 0x3f, 0xb7, 0x0f, 0xa8, 0xa1,
0x02, 0x64, 0xb1, 0x43, 0x75, 0x80, 0x1b, 0x57, 0xf6, 0x25, 0x29, 0x02, 0x64, 0xb1, 0x43, 0x75, 0x80, 0x1b, 0x57, 0xf6, 0x25, 0x29,
0x50, 0xa2, 0x82, 0x20, 0xf0, 0x8f, 0xeb, 0x3c, 0x52, 0xf3, 0x4b, 0x50, 0xa2, 0x82, 0x20, 0xf0, 0x8f, 0xeb, 0x3c, 0x52, 0xf3, 0x4b,
0x2a, 0x7b, 0xe0, 0x3c, 0x99, 0xa9, 0x82, 0x12, 0x12, 0x72, 0x4d, 0x2a, 0x7b, 0xe0, 0x3c, 0x99, 0xa9, 0x82, 0x12, 0x12, 0x72, 0x4d,
0x97, 0x07, 0xcd, 0x4f, 0xb5, 0x0f, 0x70, 0x80, 0x0a, 0xf6, 0xc8, 0x97, 0x07, 0xcd, 0x4f, 0xb5, 0x0f, 0x70, 0x80, 0x0a, 0xf6, 0xc8,
0x45, 0x72, 0x48, 0x08, 0x0c, 0xe9, 0xab, 0x44, 0xbf, 0x56, 0x19, 0x45, 0x72, 0x48, 0x08, 0x0c, 0xe9, 0xab, 0x44, 0xbf, 0x56, 0x19,
0x44, 0xbe, 0x49, 0x12, 0x08, 0x52, 0x10, 0xe9, 0xe7, 0x72, 0x5f, 0x44, 0xbe, 0x49, 0x12, 0x08, 0x52, 0x10, 0xe9, 0xe7, 0x72, 0x5f,
0xa5, 0x0c, 0x1e, 0xc0, 0xa4, 0x31, 0x15, 0xa4, 0x1a, 0x24, 0xe4, 0xa5, 0x0c, 0x1e, 0xc0, 0xa4, 0x31, 0x15, 0xa4, 0x1a, 0x24, 0xe4,
0xf3, 0x80, 0x90, 0x01, 0x4f, 0x75, 0x7d, 0x4d, 0x4c, 0x30, 0x97, 0xf3, 0x80, 0x90, 0x01, 0x4f, 0x75, 0x7d, 0x4d, 0x4c, 0x30, 0x97,
0x12, 0x1b, 0x51, 0x0d, 0x42, 0x02, 0x74, 0xce, 0xfc, 0x3c, 0x21, 0x12, 0x1b, 0x51, 0x0d, 0x42, 0x02, 0x74, 0xce, 0xfc, 0x3c, 0x21,
0x7d, 0x24, 0xf7, 0x8f, 0x12, 0x02, 0x0e, 0x01, 0xcb, 0xfb, 0x45, 0x7d, 0x24, 0xf7, 0x8f, 0x12, 0x02, 0x0e, 0x01, 0xcb, 0xfb, 0x45,
0x01, 0xa9, 0x56, 0x39, 0x24, 0xa2, 0x4e, 0x81, 0x2f, 0x2a, 0x7b, 0x01, 0xa9, 0x56, 0x39, 0x24, 0xa2, 0x4e, 0x81, 0x2f, 0x2a, 0x7b,
0x9a, 0x1e, 0xe0, 0x88, 0x54, 0xd8, 0x13, 0x40, 0x02, 0x60, 0x8e, 0x9a, 0x1e, 0xe0, 0x88, 0x54, 0xd8, 0x13, 0x40, 0x02, 0x60, 0x8e,
0x14, 0x78, 0xb4, 0xf1, 0x39, 0x6a, 0x10, 0xe0, 0x18, 0xa9, 0x10, 0x14, 0x78, 0xb4, 0xf1, 0x39, 0x6a, 0x10, 0xe0, 0x18, 0xa9, 0x10,
0x23, 0x21, 0xe6, 0x0b, 0x21, 0xf2, 0xb8, 0x07, 0xbb, 0xbd, 0xea, 0x23, 0x21, 0xe6, 0x0b, 0x21, 0xf2, 0xb8, 0x07, 0xbb, 0xbd, 0xea,
0x0a, 0x38, 0x0a, 0xfd, 0x60, 0x8f, 0xf8, 0x42, 0xec, 0x50, 0x15, 0x0a, 0x38, 0x0a, 0xfd, 0x60, 0x8f, 0xf8, 0x42, 0xec, 0x50, 0x15,
0x4f, 0x94, 0xbb, 0x0d, 0x0c, 0x00, 0x6b, 0x7c, 0x8e, 0xd9, 0xf9, 0x4f, 0x94, 0xbb, 0x0d, 0x0c, 0x00, 0x6b, 0x7c, 0x8e, 0xd9, 0xf9,
0x1c, 0xb4, 0xf4, 0x39, 0x6a, 0xeb, 0x73, 0xd8, 0x9a, 0x06, 0x01, 0x1c, 0xb4, 0xf4, 0x39, 0x6a, 0xeb, 0x73, 0xd8, 0x9a, 0x06, 0x01,
0x08, 0xf0, 0x1f, 0x73, 0xdc, 0x9e, 0x16, 0x09, 0xe8, 0xfe, 0x43, 0x08, 0xf0, 0x1f, 0x73, 0xdc, 0x9e, 0x16, 0x09, 0xe8, 0xfe, 0x43,
0x77, 0x07, 0x2e, 0x72, 0x3d, 0x01, 0xb9, 0xef, 0x71, 0x47, 0x6e, 0x77, 0x07, 0x2e, 0x72, 0x3d, 0x01, 0xb9, 0xef, 0x71, 0x47, 0x6e,
0x4a, 0x48, 0x40, 0x15, 0xc0, 0x5d, 0xe1, 0xdd, 0x4e, 0x00, 0x27, 0x4a, 0x48, 0x40, 0x15, 0xc0, 0x5d, 0xe1, 0xdd, 0x4e, 0x00, 0x27,
0x25, 0x72, 0xf7, 0x3f, 0xf6, 0xd8, 0x5d, 0x8a, 0x04, 0x6e, 0xf4, 0x25, 0x72, 0xf7, 0x3f, 0xf6, 0xd8, 0x5d, 0x8a, 0x04, 0x6e, 0xf4,
0x91, 0xce, 0xae, 0xbb, 0x83, 0x97, 0x39, 0x44, 0xe4, 0xc8, 0x78, 0x91, 0xce, 0xae, 0xbb, 0x83, 0x97, 0x39, 0x44, 0xe4, 0xc8, 0x78,
0xf4, 0xd1, 0xdb, 0x52, 0x32, 0x4c, 0x6b, 0xd0, 0x2d, 0x09, 0x90, 0xf4, 0xd1, 0xdb, 0x52, 0x32, 0x4c, 0x6b, 0xd0, 0x2d, 0x09, 0x90,
0x12, 0x72, 0xb4, 0xba, 0xa0, 0xff, 0x07, 0x00, 0x48, 0x04, 0x71, 0x12, 0x72, 0xb4, 0xba, 0xa0, 0xff, 0x07, 0x00, 0x48, 0x04, 0x71,
0x83, 0x9e, 0xcc, 0x51, 0xce, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x83, 0x9e, 0xcc, 0x51, 0xce, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45,
0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
}; };
// Thanks DKPac22 // Thanks DKPac22
static RwTexture* LoadTextureFromMemory(char* data, unsigned int size) static RwTexture* LoadTextureFromMemory(char* data, unsigned int size)
{ {
patch::SetChar(0x7CF9CA, rwSTREAMMEMORY); patch::SetChar(0x7CF9CA, rwSTREAMMEMORY);
RwMemory memoryImage; RwMemory memoryImage;
RwInt32 width, height, depth, flags; RwInt32 width, height, depth, flags;
memoryImage.start = (RwUInt8*)data; memoryImage.start = (RwUInt8*)data;
memoryImage.length = size; memoryImage.length = size;
RwImage* image = RtPNGImageRead((char*)&memoryImage); RwImage* image = RtPNGImageRead((char*)&memoryImage);
RwImageFindRasterFormat(image, 4, &width, &height, &depth, &flags); RwImageFindRasterFormat(image, 4, &width, &height, &depth, &flags);
RwRaster* raster = RwRasterCreate(width, height, depth, flags); RwRaster* raster = RwRasterCreate(width, height, depth, flags);
RwRasterSetFromImage(raster, image); RwRasterSetFromImage(raster, image);
RwImageDestroy(image); RwImageDestroy(image);
patch::SetChar(0x7CF9CA, rwSTREAMFILENAME); patch::SetChar(0x7CF9CA, rwSTREAMFILENAME);
return RwTextureCreate(raster); return RwTextureCreate(raster);
} }
void Neon::InitHooks() void Neon::InitHooks()
{ {
if (m_bInit) static bool init;
{ if (init)
return; {
} return;
}
Events::processScriptsEvent += [] Events::processScriptsEvent += []
{ {
if (!m_pNeonTexture) if (!m_pNeonTexture)
{ {
m_pNeonTexture = LoadTextureFromMemory((char*)neon_mask, sizeof(neon_mask)); m_pNeonTexture = LoadTextureFromMemory((char*)neon_mask, sizeof(neon_mask));
} }
}; };
Events::vehicleRenderEvent += [](CVehicle* pVeh) Events::vehicleRenderEvent += [](CVehicle* pVeh)
{ {
NeonData* data = &m_VehNeon.Get(pVeh); NeonData* data = &m_VehNeon.Get(pVeh);
if (data->m_bNeonInstalled && !pVeh->IsUpsideDown()) if (data->m_bNeonInstalled && !pVeh->IsUpsideDown())
{ {
CVector Pos = CModelInfo::GetModelInfo(pVeh->m_nModelIndex)->m_pColModel->m_boundBox.m_vecMin; CVector Pos = CModelInfo::GetModelInfo(pVeh->m_nModelIndex)->m_pColModel->m_boundBox.m_vecMin;
CVector center = pVeh->TransformFromObjectSpace(CVector(0.0f, 0.0f, 0.0f)); CVector center = pVeh->TransformFromObjectSpace(CVector(0.0f, 0.0f, 0.0f));
CVector up = pVeh->TransformFromObjectSpace(CVector(0.0f, -Pos.y - data->m_fVal, 0.0f)) - center; CVector up = pVeh->TransformFromObjectSpace(CVector(0.0f, -Pos.y - data->m_fVal, 0.0f)) - center;
CVector right = pVeh->TransformFromObjectSpace(CVector(Pos.x + data->m_fVal, 0.0f, 0.0f)) - center; CVector right = pVeh->TransformFromObjectSpace(CVector(Pos.x + data->m_fVal, 0.0f, 0.0f)) - center;
CShadows::StoreShadowToBeRendered(5, m_pNeonTexture, &center, up.x, up.y, right.x, right.y, 180, data->m_Color.r, CShadows::StoreShadowToBeRendered(5, m_pNeonTexture, &center, up.x, up.y, right.x, right.y, 180, data->m_Color.r,
data->m_Color.g, data->m_Color.b, 2.0f, false, 1.0f, 0, true); data->m_Color.g, data->m_Color.b, 2.0f, false, 1.0f, 0, true);
if (data->m_bPulsing) if (data->m_bPulsing)
{ {
size_t delta = CTimer::m_snTimeInMilliseconds - CTimer::m_snPreviousTimeInMilliseconds; size_t delta = CTimer::m_snTimeInMilliseconds - CTimer::m_snPreviousTimeInMilliseconds;
if (data->m_fVal < 0.0f) if (data->m_fVal < 0.0f)
{ {
data->m_bIncrement = true; data->m_bIncrement = true;
} }
if (data->m_fVal > 0.3f) if (data->m_fVal > 0.3f)
{ {
data->m_bIncrement = false; data->m_bIncrement = false;
} }
if (data->m_bIncrement) if (data->m_bIncrement)
{ {
data->m_fVal += 0.0003f * delta; data->m_fVal += 0.0003f * delta;
} }
else else
{ {
data->m_fVal -= 0.0003f * delta; data->m_fVal -= 0.0003f * delta;
} }
} }
} }
}; };
m_bInit = true; init = true;
} }
void Neon::RemoveHooks() void Neon::RemoveHooks()
{ {
if (m_pNeonTexture) if (m_pNeonTexture)
{ {
RwTextureDestroy(m_pNeonTexture); RwTextureDestroy(m_pNeonTexture);
m_pNeonTexture = nullptr; m_pNeonTexture = nullptr;
} }
} }
bool Neon::IsInstalled(CVehicle* pVeh) bool Neon::IsInstalled(CVehicle* pVeh)
{ {
return m_VehNeon.Get(pVeh).m_bNeonInstalled; return m_VehNeon.Get(pVeh).m_bNeonInstalled;
} }
bool Neon::IsPulsingEnabled(CVehicle* pVeh) bool Neon::IsPulsingEnabled(CVehicle* pVeh)
{ {
return m_VehNeon.Get(pVeh).m_bPulsing; return m_VehNeon.Get(pVeh).m_bPulsing;
} }
void Neon::SetPulsing(CVehicle* pVeh, bool state) void Neon::SetPulsing(CVehicle* pVeh, bool state)
{ {
m_VehNeon.Get(pVeh).m_bPulsing = state; m_VehNeon.Get(pVeh).m_bPulsing = state;
} }
void Neon::Install(CVehicle* pVeh, int red, int green, int blue) void Neon::Install(CVehicle* pVeh, int red, int green, int blue)
{ {
CRGBA& color = m_VehNeon.Get(pVeh).m_Color; CRGBA& color = m_VehNeon.Get(pVeh).m_Color;
color.r = red; color.r = red;
color.g = green; color.g = green;
color.b = blue; color.b = blue;
color.a = 255; color.a = 255;
m_VehNeon.Get(pVeh).m_bNeonInstalled = true; m_VehNeon.Get(pVeh).m_bNeonInstalled = true;
} }
void Neon::Remove(CVehicle* pVeh) void Neon::Remove(CVehicle* pVeh)
{ {
m_VehNeon.Get(pVeh).m_bNeonInstalled = false; m_VehNeon.Get(pVeh).m_bNeonInstalled = false;
} }

View File

@ -11,36 +11,35 @@
class Neon class Neon
{ {
private: private:
class NeonData class NeonData
{ {
public: public:
CRGBA m_Color; CRGBA m_Color;
bool m_bNeonInstalled; bool m_bNeonInstalled;
float m_fVal; float m_fVal;
bool m_bIncrement; bool m_bIncrement;
bool m_bPulsing; bool m_bPulsing;
NeonData(CVehicle* pVeh) NeonData(CVehicle* pVeh)
{ {
m_bNeonInstalled = false; m_bNeonInstalled = false;
m_fVal = 0.0; m_fVal = 0.0;
m_bIncrement = true; m_bIncrement = true;
} }
}; };
static inline RwTexture* m_pNeonTexture = nullptr; // pointer to the neon mask texture static inline RwTexture* m_pNeonTexture = nullptr; // pointer to the neon mask texture
static inline VehicleExtendedData<NeonData> m_VehNeon; static inline VehicleExtendedData<NeonData> m_VehNeon;
static inline bool m_bInit;
public: public:
Neon() = delete; Neon() = delete;
Neon(Neon&) = delete; Neon(Neon&) = delete;
static void InitHooks(); static void InitHooks();
static void Install(CVehicle* veh, int red, int green, int blue); static void Install(CVehicle* veh, int red, int green, int blue);
static bool IsInstalled(CVehicle* veh); static bool IsInstalled(CVehicle* veh);
static bool IsPulsingEnabled(CVehicle* veh); static bool IsPulsingEnabled(CVehicle* veh);
static void SetPulsing(CVehicle* veh, bool state); static void SetPulsing(CVehicle* veh, bool state);
static void RemoveHooks(); static void RemoveHooks();
static void Remove(CVehicle* veh); static void Remove(CVehicle* veh);
}; };

View File

@ -29,272 +29,280 @@
void Paint::InitHooks() void Paint::InitHooks()
{ {
Events::vehicleRenderEvent.before += [](CVehicle* pVeh) static bool init;
{
VehData& data = m_VehData.Get(pVeh);
// reset custom color if color id changed if (init)
if (pVeh->m_nPrimaryColor != data.primary_color {
|| pVeh->m_nSecondaryColor != data.secondary_color) return;
{ }
for (auto& it : data.materialProperties)
data.resetMaterialColor(it.first);
data.primary_color = pVeh->m_nPrimaryColor; Events::vehicleRenderEvent.before += [](CVehicle* pVeh)
data.secondary_color = pVeh->m_nSecondaryColor; {
} VehData& data = m_VehData.Get(pVeh);
for (auto& it : data.materialProperties) // reset custom color if color id changed
{ if (pVeh->m_nPrimaryColor != data.primary_color
if (it.second._recolor) || pVeh->m_nSecondaryColor != data.secondary_color)
{ {
it.second._originalColor = it.first->color; for (auto& it : data.materialProperties)
it.first->color = it.second._color; data.resetMaterialColor(it.first);
it.second._originalGeometryFlags = it.second._geometry->flags;
it.second._geometry->flags |= rpGEOMETRYMODULATEMATERIALCOLOR; data.primary_color = pVeh->m_nPrimaryColor;
} data.secondary_color = pVeh->m_nSecondaryColor;
if (it.second._retexture) }
{
auto tex = it.second._texture; for (auto& it : data.materialProperties)
if (tex) {
{ if (it.second._recolor)
it.second._originalTexture = it.first->texture; {
it.first->texture = tex; it.second._originalColor = it.first->color;
} it.first->color = it.second._color;
else it.second._originalGeometryFlags = it.second._geometry->flags;
{ it.second._geometry->flags |= rpGEOMETRYMODULATEMATERIALCOLOR;
it.second._retexture = false; }
} if (it.second._retexture)
} {
} auto tex = it.second._texture;
}; if (tex)
{
ThiscallEvent<AddressList<0x55332A, H_CALL>, PRIORITY_BEFORE, ArgPickN<CVehicle*, 0>, void(CVehicle*)> vehicleResetAfterRender; it.second._originalTexture = it.first->texture;
vehicleResetAfterRender += [](CVehicle* pVeh) it.first->texture = tex;
{ }
for (auto& it : m_VehData.Get(pVeh).materialProperties) else
{ {
if (it.second._recolor) it.second._retexture = false;
{ }
it.first->color = it.second._originalColor; }
it.second._geometry->flags = it.second._originalGeometryFlags; }
} };
if (it.second._retexture)
{ ThiscallEvent<AddressList<0x55332A, H_CALL>, PRIORITY_BEFORE, ArgPickN<CVehicle*, 0>, void(CVehicle*)> vehicleResetAfterRender;
it.first->texture = it.second._originalTexture; vehicleResetAfterRender += [](CVehicle* pVeh)
} {
} for (auto& it : m_VehData.Get(pVeh).materialProperties)
}; {
if (it.second._recolor)
{
it.first->color = it.second._originalColor;
it.second._geometry->flags = it.second._originalGeometryFlags;
}
if (it.second._retexture)
{
it.first->texture = it.second._originalTexture;
}
}
};
init = true;
} }
void Paint::VehData::setMaterialColor(RpMaterial* material, RpGeometry* geometry, RwRGBA color, bool filter_mat) void Paint::VehData::setMaterialColor(RpMaterial* material, RpGeometry* geometry, RwRGBA color, bool filter_mat)
{ {
auto& matProps = materialProperties[material]; auto& matProps = materialProperties[material];
if (!filter_mat if (!filter_mat
|| (material->color.red == 0x3C && material->color.green == 0xFF && material->color.blue == 0x00) || (material->color.red == 0x3C && material->color.green == 0xFF && material->color.blue == 0x00)
|| (material->color.red == 0xFF && material->color.green == 0x00 && material->color.blue == 0xAF)) || (material->color.red == 0xFF && material->color.green == 0x00 && material->color.blue == 0xAF))
{ {
matProps._recolor = true; matProps._recolor = true;
matProps._color = color; matProps._color = color;
matProps._geometry = geometry; matProps._geometry = geometry;
} }
} }
void Paint::VehData::setMaterialTexture(RpMaterial* material, RwTexture* texture, bool filter_mat) void Paint::VehData::setMaterialTexture(RpMaterial* material, RwTexture* texture, bool filter_mat)
{ {
auto& matProps = materialProperties[material]; auto& matProps = materialProperties[material];
if (!filter_mat if (!filter_mat
|| (material->color.red == 0x3C && material->color.green == 0xFF && material->color.blue == 0x00) || (material->color.red == 0x3C && material->color.green == 0xFF && material->color.blue == 0x00)
|| (material->color.red == 0xFF && material->color.green == 0x00 && material->color.blue == 0xAF)) || (material->color.red == 0xFF && material->color.green == 0x00 && material->color.blue == 0xAF))
{ {
matProps._retexture = true; matProps._retexture = true;
matProps._texture = texture; matProps._texture = texture;
} }
} }
void Paint::VehData::resetMaterialColor(RpMaterial* material) void Paint::VehData::resetMaterialColor(RpMaterial* material)
{ {
auto& matProps = materialProperties[material]; auto& matProps = materialProperties[material];
matProps._recolor = false; matProps._recolor = false;
matProps._color = {0, 0, 0, 0}; matProps._color = {0, 0, 0, 0};
} }
void Paint::VehData::resetMaterialTexture(RpMaterial* material) void Paint::VehData::resetMaterialTexture(RpMaterial* material)
{ {
auto& matProps = materialProperties[material]; auto& matProps = materialProperties[material];
matProps._retexture = false; matProps._retexture = false;
matProps._texture = nullptr; matProps._texture = nullptr;
} }
void Paint::NodeWrapperRecursive(RwFrame* frame, CVehicle* pVeh, std::function<void(RwFrame*)> func) void Paint::NodeWrapperRecursive(RwFrame* frame, CVehicle* pVeh, std::function<void(RwFrame*)> func)
{ {
if (frame) if (frame)
{ {
func(frame); func(frame);
if (RwFrame* newFrame = frame->child) if (RwFrame* newFrame = frame->child)
NodeWrapperRecursive(newFrame, pVeh, func); NodeWrapperRecursive(newFrame, pVeh, func);
if (RwFrame* newFrame = frame->next) if (RwFrame* newFrame = frame->next)
NodeWrapperRecursive(newFrame, pVeh, func); NodeWrapperRecursive(newFrame, pVeh, func);
} }
return; return;
} }
void Paint::GenerateNodeList(CVehicle* pVeh, std::vector<std::string>& names_vec) void Paint::GenerateNodeList(CVehicle* pVeh, std::vector<std::string>& names_vec)
{ {
RwFrame* frame = (RwFrame*)pVeh->m_pRwClump->object.parent; RwFrame* frame = (RwFrame*)pVeh->m_pRwClump->object.parent;
NodeWrapperRecursive(frame, pVeh, [&](RwFrame* frame) NodeWrapperRecursive(frame, pVeh, [&](RwFrame* frame)
{ {
const std::string name = GetFrameNodeName(frame); const std::string name = GetFrameNodeName(frame);
if (!(std::find(names_vec.begin(), names_vec.end(), name) != names_vec.end())) if (!(std::find(names_vec.begin(), names_vec.end(), name) != names_vec.end()))
names_vec.push_back(name); names_vec.push_back(name);
}); });
} }
void Paint::SetNodeColor(CVehicle* pVeh, std::string node_name, CRGBA color, bool filter_mat) void Paint::SetNodeColor(CVehicle* pVeh, std::string node_name, CRGBA color, bool filter_mat)
{ {
RwFrame* frame = (RwFrame*)pVeh->m_pRwClump->object.parent; RwFrame* frame = (RwFrame*)pVeh->m_pRwClump->object.parent;
NodeWrapperRecursive(frame, pVeh, [&](RwFrame* frame) NodeWrapperRecursive(frame, pVeh, [&](RwFrame* frame)
{ {
const std::string name = GetFrameNodeName(frame); const std::string name = GetFrameNodeName(frame);
struct ST struct ST
{ {
CRGBA _color; CRGBA _color;
bool _filter; bool _filter;
} st; } st;
st._color = color; st._color = color;
st._filter = filter_mat; st._filter = filter_mat;
if (node_name == "Default" || node_name == name) if (node_name == "Default" || node_name == name)
{ {
RwFrameForAllObjects(frame, [](RwObject* object, void* data) -> RwObject* RwFrameForAllObjects(frame, [](RwObject* object, void* data) -> RwObject*
{ {
if (object->type == rpATOMIC) if (object->type == rpATOMIC)
{ {
RpAtomic* atomic = reinterpret_cast<RpAtomic*>(object); RpAtomic* atomic = reinterpret_cast<RpAtomic*>(object);
ST* st = reinterpret_cast<ST*>(data); ST* st = reinterpret_cast<ST*>(data);
CRGBA* color = &st->_color; CRGBA* color = &st->_color;
bool filter_mat = st->_filter; bool filter_mat = st->_filter;
VehData& data = m_VehData.Get(FindPlayerPed()->m_pVehicle); VehData& data = m_VehData.Get(FindPlayerPed()->m_pVehicle);
for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i) for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i)
data.setMaterialColor(atomic->geometry->matList.materials[i], atomic->geometry, data.setMaterialColor(atomic->geometry->matList.materials[i], atomic->geometry,
{color->r, color->g, color->b, 255}, filter_mat); {color->r, color->g, color->b, 255}, filter_mat);
} }
return object; return object;
}, &st); }, &st);
} }
}); });
} }
void Paint::SetNodeTexture(CVehicle* pVeh, std::string node_name, std::string texturename, bool filter_mat) void Paint::SetNodeTexture(CVehicle* pVeh, std::string node_name, std::string texturename, bool filter_mat)
{ {
RwFrame* frame = (RwFrame*)pVeh->m_pRwClump->object.parent; RwFrame* frame = (RwFrame*)pVeh->m_pRwClump->object.parent;
RwTexture* texture = nullptr; RwTexture* texture = nullptr;
for (auto const& tex : m_TextureData.m_ImagesList) for (auto const& tex : m_TextureData.m_ImagesList)
{ {
if (tex.get()->m_FileName == texturename) if (tex.get()->m_FileName == texturename)
{ {
texture = tex.get()->m_pRwTexture; texture = tex.get()->m_pRwTexture;
break; break;
} }
} }
NodeWrapperRecursive(frame, pVeh, [&](RwFrame* frame) NodeWrapperRecursive(frame, pVeh, [&](RwFrame* frame)
{ {
const std::string name = GetFrameNodeName(frame); const std::string name = GetFrameNodeName(frame);
struct ST struct ST
{ {
RwTexture* _tex; RwTexture* _tex;
bool _filter; bool _filter;
} st; } st;
st._tex = texture; st._tex = texture;
st._filter = filter_mat; st._filter = filter_mat;
if (node_name == "Default" || node_name == name) if (node_name == "Default" || node_name == name)
{ {
RwFrameForAllObjects(frame, [](RwObject* object, void* data) -> RwObject* RwFrameForAllObjects(frame, [](RwObject* object, void* data) -> RwObject*
{ {
if (object->type == rpATOMIC) if (object->type == rpATOMIC)
{ {
RpAtomic* atomic = reinterpret_cast<RpAtomic*>(object); RpAtomic* atomic = reinterpret_cast<RpAtomic*>(object);
ST* st = reinterpret_cast<ST*>(data); ST* st = reinterpret_cast<ST*>(data);
VehData& data = m_VehData.Get(FindPlayerPed()->m_pVehicle); VehData& data = m_VehData.Get(FindPlayerPed()->m_pVehicle);
for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i) for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i)
{ {
data.setMaterialTexture(atomic->geometry->matList.materials[i], st->_tex, data.setMaterialTexture(atomic->geometry->matList.materials[i], st->_tex,
st->_filter); st->_filter);
} }
} }
return object; return object;
}, &st); }, &st);
} }
}); });
} }
void Paint::ResetNodeColor(CVehicle* pVeh, std::string node_name) void Paint::ResetNodeColor(CVehicle* pVeh, std::string node_name)
{ {
RwFrame* frame = (RwFrame*)pVeh->m_pRwClump->object.parent; RwFrame* frame = (RwFrame*)pVeh->m_pRwClump->object.parent;
NodeWrapperRecursive(frame, pVeh, [&](RwFrame* frame) NodeWrapperRecursive(frame, pVeh, [&](RwFrame* frame)
{ {
const std::string name = GetFrameNodeName(frame); const std::string name = GetFrameNodeName(frame);
if (node_name == "Default" || node_name == name) if (node_name == "Default" || node_name == name)
{ {
RwFrameForAllObjects(frame, [](RwObject* object, void* data) -> RwObject* RwFrameForAllObjects(frame, [](RwObject* object, void* data) -> RwObject*
{ {
if (object->type == rpATOMIC) if (object->type == rpATOMIC)
{ {
RpAtomic* atomic = reinterpret_cast<RpAtomic*>(object); RpAtomic* atomic = reinterpret_cast<RpAtomic*>(object);
VehData& data = m_VehData.Get(FindPlayerPed()->m_pVehicle); VehData& data = m_VehData.Get(FindPlayerPed()->m_pVehicle);
for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i) for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i)
data.resetMaterialColor(atomic->geometry->matList.materials[i]); data.resetMaterialColor(atomic->geometry->matList.materials[i]);
} }
return object; return object;
}, nullptr); }, nullptr);
} }
}); });
} }
void Paint::ResetNodeTexture(CVehicle* pVeh, std::string node_name) void Paint::ResetNodeTexture(CVehicle* pVeh, std::string node_name)
{ {
RwFrame* frame = (RwFrame*)pVeh->m_pRwClump->object.parent; RwFrame* frame = (RwFrame*)pVeh->m_pRwClump->object.parent;
NodeWrapperRecursive(frame, pVeh, [&](RwFrame* frame) NodeWrapperRecursive(frame, pVeh, [&](RwFrame* frame)
{ {
const std::string name = GetFrameNodeName(frame); const std::string name = GetFrameNodeName(frame);
if (node_name == "Default" || node_name == name) if (node_name == "Default" || node_name == name)
{ {
RwFrameForAllObjects(frame, [](RwObject* object, void* data) -> RwObject* RwFrameForAllObjects(frame, [](RwObject* object, void* data) -> RwObject*
{ {
if (object->type == rpATOMIC) if (object->type == rpATOMIC)
{ {
RpAtomic* atomic = reinterpret_cast<RpAtomic*>(object); RpAtomic* atomic = reinterpret_cast<RpAtomic*>(object);
VehData& data = m_VehData.Get(FindPlayerPed()->m_pVehicle); VehData& data = m_VehData.Get(FindPlayerPed()->m_pVehicle);
for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i) for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i)
data.resetMaterialTexture(atomic->geometry->matList.materials[i]); data.resetMaterialTexture(atomic->geometry->matList.materials[i]);
} }
return object; return object;
}, nullptr); }, nullptr);
} }
}); });
} }

View File

@ -28,58 +28,58 @@
class Paint class Paint
{ {
private: private:
// store vehicle specific data // store vehicle specific data
struct VehData struct VehData
{ {
struct MaterialProperties struct MaterialProperties
{ {
MaterialProperties() : MaterialProperties() :
_color{0, 0, 0, 0}, _color{0, 0, 0, 0},
_recolor(false), _recolor(false),
_retexture(false), _retexture(false),
_geometry(nullptr), _geometry(nullptr),
_originalColor{0, 0, 0, 0}, _originalColor{0, 0, 0, 0},
_originalTexture(nullptr), _originalTexture(nullptr),
_originalGeometryFlags(0) _originalGeometryFlags(0)
{ {
} }
RwRGBA _color; RwRGBA _color;
RwTexture* _texture; RwTexture* _texture;
bool _recolor; bool _recolor;
bool _retexture; bool _retexture;
RpGeometry* _geometry; RpGeometry* _geometry;
RwRGBA _originalColor; RwRGBA _originalColor;
RwTexture* _originalTexture; RwTexture* _originalTexture;
RwInt32 _originalGeometryFlags; RwInt32 _originalGeometryFlags;
}; };
// carcols color id // carcols color id
uchar primary_color = 0; uchar primary_color = 0;
uchar secondary_color = 0; uchar secondary_color = 0;
std::unordered_map<RpMaterial*, MaterialProperties> materialProperties; std::unordered_map<RpMaterial*, MaterialProperties> materialProperties;
VehData(CVehicle* veh) VehData(CVehicle* veh)
{ {
primary_color = veh->m_nPrimaryColor; primary_color = veh->m_nPrimaryColor;
secondary_color = veh->m_nSecondaryColor; secondary_color = veh->m_nSecondaryColor;
} }
void setMaterialColor(RpMaterial* material, RpGeometry* geometry, RwRGBA color, bool filter_mat = false); void setMaterialColor(RpMaterial* material, RpGeometry* geometry, RwRGBA color, bool filter_mat = false);
void setMaterialTexture(RpMaterial* material, RwTexture* texture, bool filter_mat = false); void setMaterialTexture(RpMaterial* material, RwTexture* texture, bool filter_mat = false);
void resetMaterialColor(RpMaterial* material); void resetMaterialColor(RpMaterial* material);
void resetMaterialTexture(RpMaterial* material); void resetMaterialTexture(RpMaterial* material);
}; };
static inline VehicleExtendedData<VehData> m_VehData; static inline VehicleExtendedData<VehData> m_VehData;
static void NodeWrapperRecursive(RwFrame* frame, CVehicle* pVeh, std::function<void(RwFrame*)> func); static void NodeWrapperRecursive(RwFrame* frame, CVehicle* pVeh, std::function<void(RwFrame*)> func);
public: public:
static inline ResourceStore m_TextureData { "textures", eResourceType::TYPE_IMAGE, ImVec2(100, 80) }; static inline ResourceStore m_TextureData { "textures", eResourceType::TYPE_IMAGE, ImVec2(100, 80) };
static void InitHooks(); static void InitHooks();
static void GenerateNodeList(CVehicle* pVeh, std::vector<std::string>& names_vec); static void GenerateNodeList(CVehicle* pVeh, std::vector<std::string>& names_vec);
static void SetNodeColor(CVehicle* pVeh, std::string node_name, CRGBA color, bool filter_mat = false); static void SetNodeColor(CVehicle* pVeh, std::string node_name, CRGBA color, bool filter_mat = false);
static void SetNodeTexture(CVehicle* pVeh, std::string node_name, std::string texturename, bool filter_mat = false); static void SetNodeTexture(CVehicle* pVeh, std::string node_name, std::string texturename, bool filter_mat = false);
static void ResetNodeColor(CVehicle* veh, std::string node_name); static void ResetNodeColor(CVehicle* veh, std::string node_name);
static void ResetNodeTexture(CVehicle* pVeh, std::string node_name); static void ResetNodeTexture(CVehicle* pVeh, std::string node_name);
}; };

View File

@ -79,9 +79,9 @@ using namespace plugin;
enum eRenderer enum eRenderer
{ {
Render_DirectX9, Render_DirectX9,
Render_DirectX11, Render_DirectX11,
Render_Unknown Render_Unknown
}; };
static eRenderer gRenderer = Render_Unknown; static eRenderer gRenderer = Render_Unknown;
@ -94,14 +94,14 @@ extern CJson gConfig;
static void SetHelpMessage(const char *message, bool b1, bool b2, bool b3) static void SetHelpMessage(const char *message, bool b1, bool b2, bool b3)
{ {
#if GTASA #if GTASA
CHud::SetHelpMessage(message, b1, b2, b3); CHud::SetHelpMessage(message, b1, b2, b3);
#elif GTAVC #elif GTAVC
CHud::SetHelpMessage(message, b1, b2); CHud::SetHelpMessage(message, b1, b2);
#else // GTA3 #else
const size_t size = strlen(message)+1; const size_t size = strlen(message)+1;
wchar_t* wc = new wchar_t[size]; wchar_t* wc = new wchar_t[size];
mbstowcs(wc, message, size); mbstowcs(wc, message, size);
CHud::SetHelpMessage(wc, b1); CHud::SetHelpMessage(wc, b1);
delete wc; delete wc;
#endif #endif
} }

View File

@ -12,395 +12,406 @@
Ped::Ped() Ped::Ped()
{ {
#ifdef GTASA #ifdef GTASA
if (GetModuleHandle("ExGangWars.asi")) if (GetModuleHandle("ExGangWars.asi"))
{ {
m_bExGangWarsInstalled = true; m_bExGangWarsInstalled = true;
} }
/* /*
Taken from gta chaos mod by Lordmau5 Taken from gta chaos mod by Lordmau5
https://github.com/gta-chaos-mod/Trilogy-ASI-Script https://github.com/gta-chaos-mod/Trilogy-ASI-Script
TODO: Implement in VC too TODO: Implement in VC too
*/ */
Events::pedRenderEvent += [](CPed *ped) Events::pedRenderEvent += [](CPed *ped)
{ {
if (m_bBigHead || m_bThinBody) if (m_bBigHead || m_bThinBody)
{ {
auto animHier = GetAnimHierarchyFromSkinClump (ped->m_pRwClump); auto animHier = GetAnimHierarchyFromSkinClump (ped->m_pRwClump);
auto matrices = RpHAnimHierarchyGetMatrixArray (animHier); auto matrices = RpHAnimHierarchyGetMatrixArray (animHier);
RwV3d scale = {0.7f, 0.7f, 0.7f}; RwV3d scale = {0.7f, 0.7f, 0.7f};
if (m_bThinBody) if (m_bThinBody)
{ {
for (int i = 1; i <= 52; i++) for (int i = 1; i <= 52; i++)
{ {
RwMatrixScale (&matrices[RpHAnimIDGetIndex (animHier, i)], &scale, rwCOMBINEPRECONCAT); RwMatrixScale (&matrices[RpHAnimIDGetIndex (animHier, i)], &scale, rwCOMBINEPRECONCAT);
} }
} }
scale = {3.0f, 3.0f, 3.0f}; scale = {3.0f, 3.0f, 3.0f};
if (m_bBigHead) if (m_bBigHead)
{ {
for (int i = BONE_NECK; i <= BONE_HEAD; i++) for (int i = BONE_NECK; i <= BONE_HEAD; i++)
{ {
RwMatrixScale (&matrices[RpHAnimIDGetIndex (animHier, i)], &scale, rwCOMBINEPRECONCAT); RwMatrixScale (&matrices[RpHAnimIDGetIndex (animHier, i)], &scale, rwCOMBINEPRECONCAT);
} }
} }
} }
}; };
#endif #endif
} }
Ped::~Ped() Ped::~Ped()
{ {
for (CPed* ped : m_SpawnPed::m_List) for (CPed* ped : m_SpawnPed::m_List)
{ {
CWorld::Remove(ped); CWorld::Remove(ped);
ped->Remove(); ped->Remove();
} }
} }
#ifdef GTASA #ifdef GTASA
void Ped::SpawnPed(std::string& model) void Ped::SpawnPed(std::string& model)
#else // GTA3 & GTAVC #else
void Ped::SpawnPed(std::string& cat, std::string& name, std::string& model) void Ped::SpawnPed(std::string& cat, std::string& name, std::string& model)
#endif #endif
{ {
if (m_SpawnPed::m_List.size() == SPAWN_PED_LIMIT) if (m_SpawnPed::m_List.size() == SPAWN_PED_LIMIT)
{ {
SetHelpMessage("Max limit reached", false, false, false); SetHelpMessage("Max limit reached", false, false, false);
return; return;
} }
if (BY_GAME(m_PedData.m_pJson->m_Data.contains(model), true, true)) if (BY_GAME(m_PedData.m_pJson->m_Data.contains(model), true, true))
{ {
CPlayerPed* player = FindPlayerPed(); CPlayerPed* player = FindPlayerPed();
CVector pos = player->GetPosition(); CVector pos = player->GetPosition();
pos.y += 1; pos.y += 1;
CPed* ped; CPed* ped;
int hplayer; int hplayer;
static size_t currentSlot = 1; static size_t currentSlot = 1;
#ifdef GTASA #ifdef GTASA
if (m_SpecialPedJson.m_Data.contains(model)) if (m_SpecialPedJson.m_Data.contains(model))
{ {
std::string name; std::string name;
if (m_SpecialPedJson.m_Data.contains(model)) if (m_SpecialPedJson.m_Data.contains(model))
name = m_SpecialPedJson.m_Data[model].get<std::string>().c_str(); name = m_SpecialPedJson.m_Data[model].get<std::string>().c_str();
else else
name = model; name = model;
CStreaming::RequestSpecialChar(currentSlot, name.c_str(), PRIORITY_REQUEST); CStreaming::RequestSpecialChar(currentSlot, name.c_str(), PRIORITY_REQUEST);
CStreaming::LoadAllRequestedModels(true); CStreaming::LoadAllRequestedModels(true);
Command<Commands::CREATE_CHAR>(m_SpawnPed::m_nSelectedPedType + 4, 290 + currentSlot, pos.x, pos.y, pos.z + 1, &hplayer); Command<Commands::CREATE_CHAR>(m_SpawnPed::m_nSelectedPedType + 4, 290 + currentSlot, pos.x, pos.y, pos.z + 1, &hplayer);
CStreaming::SetSpecialCharIsDeletable(290 + currentSlot); CStreaming::SetSpecialCharIsDeletable(290 + currentSlot);
// SA has 10 slots // SA has 10 slots
++currentSlot; ++currentSlot;
if (currentSlot > 9) if (currentSlot > 9)
{ {
currentSlot = 1; currentSlot = 1;
} }
} }
#else // GTA3 & GTAVC
if (cat == "Special") // Special model
{
#ifdef GTA3
SetHelpMessage("Spawning special peds isn't implemented yet.", false, false, false);
return;
#else // GTAVC
Command<Commands::LOAD_SPECIAL_CHARACTER>(currentSlot, model.c_str());
Command<Commands::LOAD_ALL_MODELS_NOW>();
Command<Commands::CREATE_CHAR>(m_SpawnPed::m_nSelectedPedType + 4, 108+currentSlot, pos.x, pos.y, pos.z + 1, &hplayer);
Command<Commands::UNLOAD_SPECIAL_CHARACTER>(currentSlot);
++currentSlot;
if (currentSlot > 21)
{
currentSlot = 1;
}
#endif
}
#endif
else
{
int iModel = std::stoi(model);
CStreaming::RequestModel(iModel, eStreamingFlags::PRIORITY_REQUEST);
CStreaming::LoadAllRequestedModels(false);
Command<Commands::CREATE_CHAR>(m_SpawnPed::m_nSelectedPedType + 4, iModel, pos.x, pos.y, pos.z + 1, &hplayer);
CStreaming::SetModelIsDeletable(iModel);
}
ped = CPools::GetPed(hplayer);
if (m_SpawnPed::m_bPedMove)
{
m_SpawnPed::m_List.push_back(ped);
}
else
{
Command<Commands::MARK_CHAR_AS_NO_LONGER_NEEDED>(hplayer);
}
ped->m_nPedFlags.bPedIsBleeding = m_SpawnPed::m_bPedBleed;
#ifdef GTA3
ped->m_nWepAccuracy = m_SpawnPed::m_nAccuracy;
#else #else
ped->m_nWeaponAccuracy = m_SpawnPed::m_nAccuracy; if (cat == "Special") // Special model
{
#ifdef GTA3
SetHelpMessage("Spawning special peds isn't implemented yet.", false, false, false);
return;
#else
Command<Commands::LOAD_SPECIAL_CHARACTER>(currentSlot, model.c_str());
Command<Commands::LOAD_ALL_MODELS_NOW>();
Command<Commands::CREATE_CHAR>(m_SpawnPed::m_nSelectedPedType + 4, 108+currentSlot, pos.x, pos.y, pos.z + 1, &hplayer);
Command<Commands::UNLOAD_SPECIAL_CHARACTER>(currentSlot);
++currentSlot;
if (currentSlot > 21)
{
currentSlot = 1;
}
#endif #endif
ped->m_fHealth = m_SpawnPed::m_nPedHealth; }
#endif
else
{
int iModel = std::stoi(model);
CStreaming::RequestModel(iModel, eStreamingFlags::PRIORITY_REQUEST);
CStreaming::LoadAllRequestedModels(false);
Command<Commands::CREATE_CHAR>(m_SpawnPed::m_nSelectedPedType + 4, iModel, pos.x, pos.y, pos.z + 1, &hplayer);
CStreaming::SetModelIsDeletable(iModel);
}
ped = CPools::GetPed(hplayer);
if (m_SpawnPed::m_bPedMove)
{
m_SpawnPed::m_List.push_back(ped);
}
else
{
Command<Commands::MARK_CHAR_AS_NO_LONGER_NEEDED>(hplayer);
}
ped->m_nPedFlags.bPedIsBleeding = m_SpawnPed::m_bPedBleed;
#ifdef GTA3
ped->m_nWepAccuracy = m_SpawnPed::m_nAccuracy;
#else
ped->m_nWeaponAccuracy = m_SpawnPed::m_nAccuracy;
#endif
ped->m_fHealth = m_SpawnPed::m_nPedHealth;
#ifdef GTASA #ifdef GTASA
if (m_SpawnPed::m_nWeaponId != 0) if (m_SpawnPed::m_nWeaponId != 0)
{ {
int model = 0; int model = 0;
Command<Commands::GET_WEAPONTYPE_MODEL>(m_SpawnPed::m_nWeaponId, &model); Command<Commands::GET_WEAPONTYPE_MODEL>(m_SpawnPed::m_nWeaponId, &model);
CStreaming::RequestModel(model, PRIORITY_REQUEST); CStreaming::RequestModel(model, PRIORITY_REQUEST);
CStreaming::LoadAllRequestedModels(false); CStreaming::LoadAllRequestedModels(false);
Command<Commands::GIVE_WEAPON_TO_CHAR>(hplayer, m_SpawnPed::m_nWeaponId, 999); Command<Commands::GIVE_WEAPON_TO_CHAR>(hplayer, m_SpawnPed::m_nWeaponId, 999);
} }
#endif #endif
} }
} }
void Ped::Draw() void Ped::Draw()
{ {
if (ImGui::BeginTabBar("Ped", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll)) if (ImGui::BeginTabBar("Ped", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
{ {
if (ImGui::BeginTabItem("Checkboxes")) if (ImGui::BeginTabItem("Checkboxes"))
{ {
ImGui::Spacing(); ImGui::Spacing();
ImGui::BeginChild("CheckboxesChild"); ImGui::BeginChild("CheckboxesChild");
ImGui::Columns(2, 0, false); ImGui::Columns(2, 0, false);
#ifdef GTASA #ifdef GTASA
Ui::CheckboxWithHint("Big head effect", &m_bBigHead); Ui::CheckboxWithHint("Big head effect", &m_bBigHead);
Ui::CheckboxAddress("Elvis everywhere", 0x969157); Ui::CheckboxAddress("Elvis everywhere", 0x969157);
Ui::CheckboxAddress("Everyone is armed", 0x969140); Ui::CheckboxAddress("Everyone is armed", 0x969140);
Ui::CheckboxAddress("Gangs control streets", 0x96915B); Ui::CheckboxAddress("Gangs control streets", 0x96915B);
Ui::CheckboxAddress("Gangs everywhere", 0x96915A); Ui::CheckboxAddress("Gangs everywhere", 0x96915A);
Ui::CheckboxWithHint("Gang wars", &CGangWars::bGangWarsActive); Ui::CheckboxWithHint("Gang wars", &CGangWars::bGangWarsActive);
ImGui::NextColumn(); ImGui::NextColumn();
Ui::CheckboxAddress("Peds mayhem", 0x96913E); Ui::CheckboxAddress("Peds mayhem", 0x96913E);
Ui::CheckboxAddress("Peds attack with rockets", 0x969158); Ui::CheckboxAddress("Peds attack with rockets", 0x969158);
Ui::CheckboxAddress("Peds riot", 0x969175); Ui::CheckboxAddress("Peds riot", 0x969175);
Ui::CheckboxAddress("Slut magnet", 0x96915D); Ui::CheckboxAddress("Slut magnet", 0x96915D);
Ui::CheckboxWithHint("Thin body effect", &m_bThinBody); Ui::CheckboxWithHint("Thin body effect", &m_bThinBody);
#elif GTAVC #elif GTAVC
Ui::CheckboxAddress("No prostitutes", 0xA10B99); Ui::CheckboxAddress("No prostitutes", 0xA10B99);
Ui::CheckboxAddress("Slut magnet", 0xA10B5F); Ui::CheckboxAddress("Slut magnet", 0xA10B5F);
ImGui::NextColumn(); ImGui::NextColumn();
Ui::CheckboxAddress("Weapons for all", 0xA10AB3); Ui::CheckboxAddress("Weapons for all", 0xA10AB3);
#else // GTA3 #else
// Bad idea lol // Bad idea lol
static bool pedsMayhem; static bool pedsMayhem;
if (Ui::CheckboxWithHint("Peds mayhem", &pedsMayhem)) if (Ui::CheckboxWithHint("Peds mayhem", &pedsMayhem))
{ {
Call<0x4911C0>(); Call<0x4911C0>();
} }
static bool everyoneAttacksPlayer; static bool everyoneAttacksPlayer;
if (Ui::CheckboxWithHint("Everyone attacks players", &everyoneAttacksPlayer)) if (Ui::CheckboxWithHint("Everyone attacks players", &everyoneAttacksPlayer))
{ {
Call<0x491270>(); Call<0x491270>();
} }
ImGui::NextColumn(); ImGui::NextColumn();
Ui::CheckboxAddress("Nasty limbs", 0x95CD44); Ui::CheckboxAddress("Nasty limbs", 0x95CD44);
Ui::CheckboxAddress("Weapons for all", 0x95CCF6); Ui::CheckboxAddress("Weapons for all", 0x95CCF6);
#endif #endif
ImGui::Columns(1); ImGui::Columns(1);
ImGui::EndChild(); ImGui::EndChild();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("Menus")) if (ImGui::BeginTabItem("Menus"))
{ {
ImGui::Spacing(); ImGui::Spacing();
ImGui::BeginChild("MenusChild"); ImGui::BeginChild("MenusChild");
#ifdef GTASA #ifdef GTASA
if (ImGui::CollapsingHeader("Gang wars")) if (ImGui::CollapsingHeader("Gang wars"))
{ {
if (ImGui::Button("Start gang war", ImVec2(Ui::GetSize(2)))) if (ImGui::Button("Start gang war", ImVec2(Ui::GetSize(2))))
{ {
if (Util::GetLargestGangInZone() == 1) if (Util::GetLargestGangInZone() == 1)
{ {
CGangWars::StartDefensiveGangWar(); CGangWars::StartDefensiveGangWar();
} }
else else
{ {
CGangWars::StartOffensiveGangWar(); CGangWars::StartOffensiveGangWar();
} }
CGangWars::bGangWarsActive = true; CGangWars::bGangWarsActive = true;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("End gang war", ImVec2(Ui::GetSize(2)))) if (ImGui::Button("End gang war", ImVec2(Ui::GetSize(2))))
{ {
CGangWars::EndGangWar(true); CGangWars::EndGangWar(true);
} }
ImGui::Dummy(ImVec2(0, 20)); ImGui::Dummy(ImVec2(0, 20));
ImGui::TextWrapped("Gang zone density:"); ImGui::TextWrapped("Gang zone density:");
ImGui::Spacing(); ImGui::Spacing();
ImGui::PushItemWidth(ImGui::GetWindowContentRegionWidth() / 2); ImGui::PushItemWidth(ImGui::GetWindowContentRegionWidth() / 2);
for (int i = 0; i != 10; ++i) for (int i = 0; i != 10; ++i)
{ {
CVector pos = FindPlayerPed()->GetPosition(); CVector pos = FindPlayerPed()->GetPosition();
CZone szone = CZone(); CZone szone = CZone();
CZone* pZone = &szone; CZone* pZone = &szone;
CZoneInfo* zoneInfo = CTheZones::GetZoneInfo(&pos, &pZone); CZoneInfo* zoneInfo = CTheZones::GetZoneInfo(&pos, &pZone);
int density = zoneInfo->m_nGangDensity[i]; int density = zoneInfo->m_nGangDensity[i];
if (ImGui::SliderInt(m_GangNames[i].c_str(), &density, 0, 127)) if (ImGui::SliderInt(m_GangList[i].c_str(), &density, 0, 127))
{ {
zoneInfo->m_nGangDensity[i] = static_cast<char>(density); zoneInfo->m_nGangDensity[i] = static_cast<char>(density);
Command<Commands::CLEAR_SPECIFIC_ZONES_TO_TRIGGER_GANG_WAR>(); Command<Commands::CLEAR_SPECIFIC_ZONES_TO_TRIGGER_GANG_WAR>();
CGangWars::bGangWarsActive = true; CGangWars::bGangWarsActive = true;
} }
} }
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::Spacing(); ImGui::Spacing();
if (!m_bExGangWarsInstalled) if (!m_bExGangWarsInstalled)
{ {
ImGui::TextWrapped("You'll need ExGangWars plugin to display some turf colors"); ImGui::TextWrapped("You'll need ExGangWars plugin to display some turf colors");
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::Button("Download ExGangWars", Ui::GetSize(1))) if (ImGui::Button("Download ExGangWars", Ui::GetSize(1)))
{ {
ShellExecute(NULL, "open", "https://gtaforums.com/topic/682194-extended-gang-wars/", NULL, NULL, ShellExecute(NULL, "open", "https://gtaforums.com/topic/682194-extended-gang-wars/", NULL, NULL,
SW_SHOWNORMAL); SW_SHOWNORMAL);
} }
} }
ImGui::Spacing(); ImGui::Spacing();
ImGui::Separator(); ImGui::Separator();
} }
#endif #endif
Ui::EditReference<float>("Pedestrian density multiplier", CPopulation::PedDensityMultiplier, 0, 1, 10); Ui::EditReference<float>("Pedestrian density multiplier", CPopulation::PedDensityMultiplier, 0, 1, 10);
#ifdef GTASA #ifdef GTASA
if (ImGui::CollapsingHeader("Recruit anyone")) if (ImGui::CollapsingHeader("Recruit anyone"))
{ {
static std::vector<Ui::NamedMemory> selectWeapon{ static std::vector<Ui::NamedMemory> selectWeapon
{"9mm", 0x96917C}, {"AK47", 0x96917D}, {"Rockets", 0x96917E} {
}; {"9mm", 0x96917C}, {"AK47", 0x96917D}, {"Rockets", 0x96917E}
Ui::RadioButtonAddress("Select weapon", selectWeapon); };
ImGui::Spacing(); Ui::RadioButtonAddress("Select weapon", selectWeapon);
ImGui::Separator(); ImGui::Spacing();
} ImGui::Separator();
}
#endif #endif
if (ImGui::CollapsingHeader("Remove peds in radius")) if (ImGui::CollapsingHeader("Remove peds in radius"))
{ {
ImGui::InputInt("Radius", &m_nPedRemoveRadius); static int removeRadius = 5;
ImGui::Spacing(); ImGui::InputInt("Radius", &removeRadius);
if (ImGui::Button("Remove peds", Ui::GetSize(1))) ImGui::Spacing();
{ if (ImGui::Button("Remove peds", Ui::GetSize(1)))
CPlayerPed* player = FindPlayerPed(); {
for (CPed* ped : CPools::ms_pPedPool) CPlayerPed* player = FindPlayerPed();
{ for (CPed* ped : CPools::ms_pPedPool)
if (DistanceBetweenPoints(ped->GetPosition(), player->GetPosition()) < m_nPedRemoveRadius {
&& ped->m_pVehicle == nullptr && ped != player) if (DistanceBetweenPoints(ped->GetPosition(), player->GetPosition()) < removeRadius
{ && ped->m_pVehicle == nullptr && ped != player)
Command<Commands::DELETE_CHAR>(CPools::GetPedRef(ped)); {
} Command<Commands::DELETE_CHAR>(CPools::GetPedRef(ped));
} }
} }
ImGui::Spacing(); }
ImGui::Separator(); ImGui::Spacing();
} ImGui::Separator();
ImGui::EndChild(); }
ImGui::EndTabItem(); ImGui::EndChild();
} ImGui::EndTabItem();
if (ImGui::BeginTabItem("Spawn")) }
{ if (ImGui::BeginTabItem("Spawn"))
ImGui::Spacing(); {
if (ImGui::Button("Remove frozen peds", Ui::GetSize(1))) ImGui::Spacing();
{ if (ImGui::Button("Remove frozen peds", Ui::GetSize(1)))
for (CPed* ped : m_SpawnPed::m_List) {
{ for (CPed* ped : m_SpawnPed::m_List)
CWorld::Remove(ped); {
ped->Remove(); CWorld::Remove(ped);
} ped->Remove();
m_SpawnPed::m_List.clear(); }
} m_SpawnPed::m_List.clear();
ImGui::Spacing(); }
if (ImGui::BeginTabBar("SpawnPedBar")) ImGui::Spacing();
{ if (ImGui::BeginTabBar("SpawnPedBar"))
ImGui::Spacing(); {
ImGui::Spacing();
if (ImGui::BeginTabItem("Spawner")) if (ImGui::BeginTabItem("Spawner"))
{ {
ImGui::Spacing(); ImGui::Spacing();
#ifdef GTASA #ifdef GTASA
Ui::DrawImages(m_PedData, SpawnPed, nullptr, Ui::DrawImages(m_PedData, SpawnPed, nullptr,
[](std::string str) { return m_PedData.m_pJson->m_Data[str].get<std::string>(); }); [](std::string str)
#else // GTA3 & GTAVC {
Ui::DrawJSON(m_PedData, SpawnPed, nullptr); return m_PedData.m_pJson->m_Data[str].get<std::string>();
});
#else
Ui::DrawJSON(m_PedData, SpawnPed, nullptr);
#endif #endif
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("Config")) if (ImGui::BeginTabItem("Config"))
{ {
ImGui::Spacing(); ImGui::Spacing();
ImGui::BeginChild("PedCOnfig"); ImGui::BeginChild("PedCOnfig");
ImGui::Columns(2, 0, false); ImGui::Columns(2, 0, false);
Ui::CheckboxWithHint("Don't move", &m_SpawnPed::m_bPedMove); Ui::CheckboxWithHint("Don't move", &m_SpawnPed::m_bPedMove);
ImGui::NextColumn(); ImGui::NextColumn();
Ui::CheckboxWithHint("Ped bleed", &m_SpawnPed::m_bPedBleed); Ui::CheckboxWithHint("Ped bleed", &m_SpawnPed::m_bPedBleed);
ImGui::Columns(1); ImGui::Columns(1);
ImGui::Spacing(); ImGui::Spacing();
ImGui::SliderInt("Accuracy", &m_SpawnPed::m_nAccuracy, 0.0, 100.0); ImGui::SliderInt("Accuracy", &m_SpawnPed::m_nAccuracy, 0.0, 100.0);
if (ImGui::InputInt("Health", &m_SpawnPed::m_nPedHealth)) if (ImGui::InputInt("Health", &m_SpawnPed::m_nPedHealth))
{ {
if (m_SpawnPed::m_nPedHealth > 1000) if (m_SpawnPed::m_nPedHealth > 1000)
{ {
m_SpawnPed::m_nPedHealth = 1000; m_SpawnPed::m_nPedHealth = 1000;
} }
if (m_SpawnPed::m_nPedHealth < 0) if (m_SpawnPed::m_nPedHealth < 0)
{ {
m_SpawnPed::m_nPedHealth = 0; m_SpawnPed::m_nPedHealth = 0;
} }
} }
Ui::ListBox("Ped type", m_SpawnPed::m_PedTypeList, m_SpawnPed::m_nSelectedPedType); Ui::ListBox("Ped type", m_SpawnPed::m_PedTypeList, m_SpawnPed::m_nSelectedPedType);
ImGui::Spacing(); ImGui::Spacing();
ImGui::Text("Selected weapon: %s", m_SpawnPed::m_nWeaponName.c_str()); ImGui::Text("Selected weapon: %s", m_SpawnPed::m_nWeaponName.c_str());
ImGui::Spacing(); ImGui::Spacing();
#ifdef GTASA #ifdef GTASA
Ui::DrawImages(Weapon::m_WeaponData, Ui::DrawImages(Weapon::m_WeaponData,
[](std::string str) { m_SpawnPed::m_nWeaponId = std::stoi(str); }, [](std::string str)
nullptr, {
[](std::string str) m_SpawnPed::m_nWeaponId = std::stoi(str);
{ },
m_SpawnPed::m_nWeaponName = Weapon::m_WeaponData.m_pJson->m_Data[str].get<std::string>(); nullptr,
return m_SpawnPed::m_nWeaponName; [](std::string str)
}, {
[](std::string str) { return str != "-1"; /*Jetpack*/ } m_SpawnPed::m_nWeaponName = Weapon::m_WeaponData.m_pJson->m_Data[str].get<std::string>();
); return m_SpawnPed::m_nWeaponName;
#else // GTA3 & GTAVC },
Ui::DrawJSON(Weapon::m_WeaponData, [](std::string str)
[](std::string& root, std::string& key, std::string& id) {
{ return str != "-1"; /*Jetpack*/
m_SpawnPed::m_nWeaponId = std::stoi(id); }
m_SpawnPed::m_nWeaponName = key; );
}, #else
nullptr); Ui::DrawJSON(Weapon::m_WeaponData,
[](std::string& root, std::string& key, std::string& id)
{
m_SpawnPed::m_nWeaponId = std::stoi(id);
m_SpawnPed::m_nWeaponName = key;
},
nullptr);
#endif #endif
ImGui::Spacing(); ImGui::Spacing();
ImGui::EndChild(); ImGui::EndChild();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
} }

View File

@ -5,62 +5,59 @@ class Ped
{ {
private: private:
#ifdef GTASA #ifdef GTASA
static inline bool m_bBigHead; static inline bool m_bExGangWarsInstalled;
static inline bool m_bThinBody; static inline bool m_bBigHead;
static inline CJson m_SpecialPedJson = CJson("ped special"); static inline bool m_bThinBody;
static inline ResourceStore m_PedData{"ped", eResourceType::TYPE_BOTH, ImVec2(65, 110)}; static inline std::vector<std::string> m_GangList =
{
static inline std::vector<std::string> m_GangNames = "Ballas", "Grove street families", "Los santos vagos", "San fierro rifa",
{ "Da nang boys", "Mafia", "Mountain cloud triad", "Varrio los aztecas", "Gang9", "Gang10"
"Ballas", "Grove street families", "Los santos vagos", "San fierro rifa", };
"Da nang boys", "Mafia", "Mountain cloud triad", "Varrio los aztecas", "Gang9", "Gang10"
};
#else // GTA3 & GTAVC
static inline ResourceStore m_PedData{"ped", eResourceType::TYPE_TEXT};
#endif #endif
static inline bool m_bExGangWarsInstalled;
static inline int m_nPedRemoveRadius = 5; struct m_SpawnPed
struct m_SpawnPed {
{ static inline std::vector<CPed*> m_List;
static inline std::vector<CPed*> m_List; static inline int m_nAccuracy = 50;
static inline int m_nAccuracy = 50; static inline int m_nPedHealth = 100;
static inline int m_nPedHealth = 100; static inline bool m_bPedMove;
static inline bool m_bPedMove; static inline bool m_bPedBleed;
static inline bool m_bPedBleed; static inline int m_nSelectedPedType;
static inline int m_nSelectedPedType; static inline int m_nWeaponId;
static inline int m_nWeaponId; static inline std::string m_nWeaponName = "None";
static inline std::string m_nWeaponName = "None"; static inline std::vector<std::string> m_PedTypeList =
static inline std::vector<std::string> m_PedTypeList = {
{
#ifdef GTASA #ifdef GTASA
"Civ Male", "Civ Female", "Cop", "Ballas", "Grove Street Families", "Los Santos Vagos", "Civ Male", "Civ Female", "Cop", "Ballas", "Grove Street Families", "Los Santos Vagos",
"San Fierro Rifa", "Da Nang Boys", "Mafia", "Mountain Cloud Triads", "Varrio Los Aztecas", "San Fierro Rifa", "Da Nang Boys", "Mafia", "Mountain Cloud Triads", "Varrio Los Aztecas",
"Gang 9", "Medic", "Dealer", "Criminal", "Fireman", "Prostitute" "Gang 9", "Medic", "Dealer", "Criminal", "Fireman", "Prostitute"
#elif GTAVC #elif GTAVC
"Civ Male", "Civ Female", "Cop (crash)", "Cubans", "Haitians", "Streetwannabe's", "Diaz' Gang", "Civ Male", "Civ Female", "Cop (crash)", "Cubans", "Haitians", "Streetwannabe's", "Diaz' Gang",
"Security Guards", "Biker Gang", "Vercetti Gang", "Golfers", "Gang 9", "Emergency", "Security Guards", "Biker Gang", "Vercetti Gang", "Golfers", "Gang 9", "Emergency",
"Fireman", "Criminal", "Unused", "Prostitute", "Special" "Fireman", "Criminal", "Unused", "Prostitute", "Special"
#else // GTA3 #else
"Civ Male", "Civ Female", "Cop", "Leones", "Triads", "Diablos", "Yakuza", "Yardies", "Colombians", "Civ Male", "Civ Female", "Cop", "Leones", "Triads", "Diablos", "Yakuza", "Yardies", "Colombians",
"Hoods", "unused", "unused", "Emergency", "Fireman", "Criminal", "unused", "Prostitute", "Special" "Hoods", "unused", "unused", "Emergency", "Fireman", "Criminal", "unused", "Prostitute", "Special"
#endif #endif
}; };
}; };
friend class Player;
#ifdef GTASA
friend class Weapon;
#endif
public: public:
Ped();
~Ped();
static void Draw();
#ifdef GTASA #ifdef GTASA
static void SpawnPed(std::string& model); static inline CJson m_SpecialPedJson = CJson("ped special");
static void BigHeadEffect(CPed *ped); static inline ResourceStore m_PedData{"ped", eResourceType::TYPE_BOTH, ImVec2(65, 110)};
#else // GTA3 & GTAVC #else
static void SpawnPed(std::string& cat, std::string& name, std::string& model); static inline ResourceStore m_PedData {"ped", eResourceType::TYPE_TEXT};
#endif
Ped();
~Ped();
static void Draw();
#ifdef GTASA
static void SpawnPed(std::string& model);
static void BigHeadEffect(CPed *ped);
#else
static void SpawnPed(std::string& cat, std::string& name, std::string& model);
#endif #endif
}; };

File diff suppressed because it is too large Load Diff

View File

@ -4,46 +4,46 @@
class Player class Player
{ {
private: private:
static inline bool m_bAutoHeal; static inline bool m_bAutoHeal;
static inline bool m_bGodMode; static inline bool m_bGodMode;
static inline bool m_bModloaderInstalled; static inline bool m_bModloaderInstalled;
struct m_KeepPosition struct m_KeepPosition
{ {
static inline bool m_bEnabled = false; static inline bool m_bEnabled = false;
static inline CVector m_fPos; static inline CVector m_fPos;
}; };
#ifdef GTASA #ifdef GTASA
static inline bool m_bAimSkinChanger; static inline bool m_bAimSkinChanger;
static inline bool m_bDrunkEffect; static inline bool m_bDrunkEffect;
static inline bool m_bFastSprint; static inline bool m_bFastSprint;
static inline int m_nUiBodyState; static inline int m_nUiBodyState;
static inline ResourceStore m_ClothData { "clothes" , eResourceType::TYPE_IMAGE, ImVec2(70, 100)}; static inline ResourceStore m_ClothData { "clothes", eResourceType::TYPE_IMAGE, ImVec2(70, 100)};
struct m_CustomSkins struct m_CustomSkins
{ {
static inline std::string m_Path = paths::GetGameDirPathA() + std::string("\\modloader\\Custom Skins\\");; static inline std::string m_Path = paths::GetGameDirPathA() + std::string("\\modloader\\Custom Skins\\");;
static inline ImGuiTextFilter m_Filter; static inline ImGuiTextFilter m_Filter;
static inline std::vector<std::string> m_List; static inline std::vector<std::string> m_List;
}; };
struct m_TopDownCamera struct m_TopDownCamera
{ {
static inline bool m_bEnabled = false; static inline bool m_bEnabled = false;
static inline float m_fOffset = 40.0f; static inline float m_fOffset = 40.0f;
}; };
#else // GTA3 & GTAVC #else
static inline ResourceStore skinData{ BY_GAME(NULL, "skin", "ped"), eResourceType::TYPE_TEXT }; static inline ResourceStore skinData { BY_GAME(NULL, "skin", "ped"), eResourceType::TYPE_TEXT };
#endif #endif
public: public:
Player(); Player();
static void Draw(); static void Draw();
#ifdef GTASA #ifdef GTASA
static void ChangePlayerModel(std::string& model); static void ChangePlayerModel(std::string& model);
static void ChangePlayerCloth(std::string& model); static void ChangePlayerCloth(std::string& model);
static void TopDownCameraView(); static void TopDownCameraView();
#else // GTA3 & GTAVC #else
static void ChangePlayerModel(std::string& cat, std::string& name, std::string& id); static void ChangePlayerModel(std::string& cat, std::string& name, std::string& id);
#endif #endif
}; };

View File

@ -3,10 +3,10 @@
#include "extensions/Paths.h" #include "extensions/Paths.h"
ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageSize) ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageSize)
: m_ImageSize(imageSize) : m_ImageSize(imageSize)
{ {
if (type == eResourceType::TYPE_TEXT if (type == eResourceType::TYPE_TEXT
|| type == eResourceType::TYPE_BOTH) || type == eResourceType::TYPE_BOTH)
{ {
m_pJson = std::make_unique<CJson>(text); m_pJson = std::make_unique<CJson>(text);
@ -19,11 +19,11 @@ ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageS
} }
} }
} }
if (type == eResourceType::TYPE_IMAGE if (type == eResourceType::TYPE_IMAGE
|| type == eResourceType::TYPE_BOTH) || type == eResourceType::TYPE_BOTH)
{ {
/* /*
Textures need to be loaded from main thread Textures need to be loaded from main thread
Loading it directly here doesn't work Loading it directly here doesn't work
*/ */
@ -40,18 +40,18 @@ ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageS
static void* GetTextureFromRaster(RwTexture* pTexture) static void* GetTextureFromRaster(RwTexture* pTexture)
{ {
RwRasterEx* raster = (RwRasterEx*)(&pTexture->raster->parent); RwRasterEx* raster = (RwRasterEx*)(&pTexture->raster->parent);
return (&raster->m_pRenderResource->texture); return (&raster->m_pRenderResource->texture);
} }
void ResourceStore::LoadTextureResource(std::string&& name) void ResourceStore::LoadTextureResource(std::string&& name)
{ {
std::string fullPath = PLUGIN_PATH((char*)"CheatMenu\\") + name + ".txd"; std::string fullPath = PLUGIN_PATH((char*)"CheatMenu\\") + name + ".txd";
RwTexDictionary* pRwTexDictionary = CFileLoader::LoadTexDictionary(fullPath.c_str()); RwTexDictionary* pRwTexDictionary = CFileLoader::LoadTexDictionary(fullPath.c_str());
if (pRwTexDictionary) if (pRwTexDictionary)
{ {
RwLinkList *pRLL = (RwLinkList*)pRwTexDictionary->texturesInDict.link.next; RwLinkList *pRLL = (RwLinkList*)pRwTexDictionary->texturesInDict.link.next;
RwTexDictionary *pEndDic; RwTexDictionary *pEndDic;
do do
@ -61,7 +61,7 @@ void ResourceStore::LoadTextureResource(std::string&& name)
m_ImagesList.push_back(std::make_unique<TextureResource>()); m_ImagesList.push_back(std::make_unique<TextureResource>());
m_ImagesList.back().get()->m_pRwTexture = pTex; m_ImagesList.back().get()->m_pRwTexture = pTex;
// Fetch IDirec9Texture9* from RwTexture* // Fetch IDirec9Texture9* from RwTexture*
m_ImagesList.back().get()->m_pTexture = GetTextureFromRaster(pTex); m_ImagesList.back().get()->m_pTexture = GetTextureFromRaster(pTex);
@ -91,5 +91,5 @@ void ResourceStore::LoadTextureResource(std::string&& name)
pRLL = (RwLinkList*)pEndDic; pRLL = (RwLinkList*)pEndDic;
} }
while ( pEndDic != (RwTexDictionary*)&pRwTexDictionary->texturesInDict ); while ( pEndDic != (RwTexDictionary*)&pRwTexDictionary->texturesInDict );
} }
} }

View File

@ -10,41 +10,41 @@
*/ */
struct RwD3D9Raster struct RwD3D9Raster
{ {
union union
{ {
IDirect3DTexture9* texture; IDirect3DTexture9* texture;
IDirect3DSurface9* surface; IDirect3DSurface9* surface;
}; };
unsigned char* palette; unsigned char* palette;
unsigned char alpha; unsigned char alpha;
unsigned char cubeTextureFlags; /* 0x01 IS_CUBEMAP_TEX */ unsigned char cubeTextureFlags; /* 0x01 IS_CUBEMAP_TEX */
unsigned char textureFlags; /* 0x10 IS_COMPRESSED */ unsigned char textureFlags; /* 0x10 IS_COMPRESSED */
unsigned char lockedLevel; unsigned char lockedLevel;
IDirect3DSurface9* lockedSurface; IDirect3DSurface9* lockedSurface;
D3DLOCKED_RECT lockedRect; D3DLOCKED_RECT lockedRect;
D3DFORMAT format; D3DFORMAT format;
IDirect3DSwapChain9* swapChain; IDirect3DSwapChain9* swapChain;
HWND* hwnd; HWND* hwnd;
}; };
struct RwRasterEx : public RwRaster struct RwRasterEx : public RwRaster
{ {
RwD3D9Raster *m_pRenderResource; RwD3D9Raster *m_pRenderResource;
}; };
struct TextureResource struct TextureResource
{ {
std::string m_FileName; std::string m_FileName;
std::string m_CategoryName; std::string m_CategoryName;
RwTexture *m_pRwTexture = nullptr; RwTexture *m_pRwTexture = nullptr;
void *m_pTexture = nullptr; void *m_pTexture = nullptr;
}; };
enum eResourceType enum eResourceType
{ {
TYPE_IMAGE, TYPE_IMAGE,
TYPE_TEXT, TYPE_TEXT,
TYPE_BOTH, TYPE_BOTH,
}; };
using TextureResourceList = std::vector<std::unique_ptr<TextureResource>>; using TextureResourceList = std::vector<std::unique_ptr<TextureResource>>;
@ -54,13 +54,13 @@ private:
void LoadTextureResource(std::string&& path); void LoadTextureResource(std::string&& path);
public: public:
ImGuiTextFilter m_Filter = ""; ImGuiTextFilter m_Filter = "";
std::vector<std::string> m_Categories = {"All"}; std::vector<std::string> m_Categories = {"All"};
std::string m_Selected = "All"; std::string m_Selected = "All";
std::unique_ptr<CJson> m_pJson; std::unique_ptr<CJson> m_pJson;
TextureResourceList m_ImagesList; TextureResourceList m_ImagesList;
ImVec2 m_ImageSize; ImVec2 m_ImageSize;
bool m_bTexturesLoaded = false; bool m_bTexturesLoaded = false;
ResourceStore(const char* text, eResourceType type = TYPE_IMAGE, ImVec2 imageSize = ImVec2(64, 64)); ResourceStore(const char* text, eResourceType type = TYPE_IMAGE, ImVec2 imageSize = ImVec2(64, 64));
}; };

View File

@ -10,284 +10,284 @@ tRadarTrace* CRadar::ms_RadarTrace = reinterpret_cast<tRadarTrace*>(patch::GetPo
void Teleport::FetchRadarSpriteData() void Teleport::FetchRadarSpriteData()
{ {
uint cur_timer = CTimer::m_snTimeInMilliseconds; uint cur_timer = CTimer::m_snTimeInMilliseconds;
static uint timer = cur_timer; static uint timer = cur_timer;
// Update the radar list each 5 seconds // Update the radar list each 5 seconds
if (cur_timer - timer < 5000) if (cur_timer - timer < 5000)
{ {
return; return;
} }
m_tpData.m_pJson->m_Data.erase("Radar"); m_tpData.m_pJson->m_Data.erase("Radar");
// 175 is the max number of sprites, FLA can increase this limit, might need to update this // 175 is the max number of sprites, FLA can increase this limit, might need to update this
for (int i = 0; i != 175; ++i) for (int i = 0; i != 175; ++i)
{ {
CVector pos = CRadar::ms_RadarTrace[i].m_vPosition; CVector pos = CRadar::ms_RadarTrace[i].m_vPosition;
uchar sprite = CRadar::ms_RadarTrace[i].m_nBlipSprite; uchar sprite = CRadar::ms_RadarTrace[i].m_nBlipSprite;
auto sprite_name = m_SpriteJson.m_Data[std::to_string(sprite)].get<std::string>(); auto sprite_name = m_SpriteJson.m_Data[std::to_string(sprite)].get<std::string>();
std::string key_name = sprite_name + ", " + Util::GetLocationName(&pos); std::string key_name = sprite_name + ", " + Util::GetLocationName(&pos);
m_tpData.m_pJson->m_Data["Radar"][key_name] = "0, " + std::to_string(pos.x) + ", " + std::to_string(pos.y) + ", " + m_tpData.m_pJson->m_Data["Radar"][key_name] = "0, " + std::to_string(pos.x) + ", " + std::to_string(pos.y) + ", " +
std::to_string(pos.z); std::to_string(pos.z);
/* /*
"Radar" : { "Radar" : {
"key_name" : "0, x, y, z", "key_name" : "0, x, y, z",
} }
*/ */
} }
} }
#endif #endif
Teleport::Teleport() Teleport::Teleport()
{ {
m_bQuickTeleport = gConfig.GetValue("quick_teleport", false); m_bQuickTeleport = gConfig.GetValue("quick_teleport", false);
Events::processScriptsEvent += [] Events::processScriptsEvent += []
{ {
if ((m_Teleport::m_bEnabled == true) && ((CTimer::m_snTimeInMilliseconds - m_Teleport::m_nTimer) > 500)) if ((m_Teleport::m_bEnabled == true) && ((CTimer::m_snTimeInMilliseconds - m_Teleport::m_nTimer) > 500))
{ {
CPlayerPed* player = FindPlayerPed(); CPlayerPed* player = FindPlayerPed();
#ifdef GTASA #ifdef GTASA
CEntity* player_entity = FindPlayerEntity(-1); CEntity* player_entity = FindPlayerEntity(-1);
m_Teleport::m_fPos.z = CWorld::FindGroundZFor3DCoord(m_Teleport::m_fPos.x, m_Teleport::m_fPos.y, m_Teleport::m_fPos.z = CWorld::FindGroundZFor3DCoord(m_Teleport::m_fPos.x, m_Teleport::m_fPos.y,
m_Teleport::m_fPos.z + 100.0f, nullptr, &player_entity) + 1.0f; m_Teleport::m_fPos.z + 100.0f, nullptr, &player_entity) + 1.0f;
#else // GTA3 & GTAVC #else
m_Teleport::m_fPos.z = CWorld::FindGroundZFor3DCoord(m_Teleport::m_fPos.x, m_Teleport::m_fPos.y, m_Teleport::m_fPos.z = CWorld::FindGroundZFor3DCoord(m_Teleport::m_fPos.x, m_Teleport::m_fPos.y,
m_Teleport::m_fPos.z + 100.0f, nullptr) + 1.0f; m_Teleport::m_fPos.z + 100.0f, nullptr) + 1.0f;
#endif #endif
CVehicle* pVeh = player->m_pVehicle; CVehicle* pVeh = player->m_pVehicle;
if (pVeh && BY_GAME(player->m_nPedFlags.bInVehicle, player->m_pVehicle, player->m_pVehicle)) if (pVeh && BY_GAME(player->m_nPedFlags.bInVehicle, player->m_pVehicle, player->m_pVehicle))
{ {
BY_GAME(pVeh->Teleport(m_Teleport::m_fPos, false), pVeh->Teleport(m_Teleport::m_fPos), player->Teleport(m_Teleport::m_fPos)); BY_GAME(pVeh->Teleport(m_Teleport::m_fPos, false), pVeh->Teleport(m_Teleport::m_fPos), player->Teleport(m_Teleport::m_fPos));
} }
else else
{ {
BY_GAME(player->Teleport(m_Teleport::m_fPos, false), player->Teleport(m_Teleport::m_fPos), player->Teleport(m_Teleport::m_fPos)); BY_GAME(player->Teleport(m_Teleport::m_fPos, false), player->Teleport(m_Teleport::m_fPos), player->Teleport(m_Teleport::m_fPos));
} }
m_Teleport::m_bEnabled = false; m_Teleport::m_bEnabled = false;
Command<Commands::FREEZE_CHAR_POSITION_AND_DONT_LOAD_COLLISION>(CPools::GetPedRef(player), false); Command<Commands::FREEZE_CHAR_POSITION_AND_DONT_LOAD_COLLISION>(CPools::GetPedRef(player), false);
Command<Commands::RESTORE_CAMERA_JUMPCUT>(); Command<Commands::RESTORE_CAMERA_JUMPCUT>();
TheCamera.Fade(0, 1); TheCamera.Fade(0, 1);
} }
if (m_bQuickTeleport) if (m_bQuickTeleport)
{ {
if (quickTeleport.Pressed() if (quickTeleport.Pressed()
&& ((CTimer::m_snTimeInMilliseconds - m_nQuickTeleportTimer) > 500)) && ((CTimer::m_snTimeInMilliseconds - m_nQuickTeleportTimer) > 500))
{ {
m_nQuickTeleportTimer = CTimer::m_snTimeInMilliseconds; m_nQuickTeleportTimer = CTimer::m_snTimeInMilliseconds;
TeleportPlayer(true); TeleportPlayer(true);
} }
} }
}; };
} }
void Teleport::TeleportPlayer(bool get_marker, CVector pos, int interior_id) void Teleport::TeleportPlayer(bool get_marker, CVector pos, int interior_id)
{ {
CPlayerPed* pPlayer = FindPlayerPed(); CPlayerPed* pPlayer = FindPlayerPed();
CVehicle* pVeh = pPlayer->m_pVehicle; CVehicle* pVeh = pPlayer->m_pVehicle;
#ifdef GTASA #ifdef GTASA
if (get_marker) if (get_marker)
{ {
tRadarTrace targetBlip = CRadar::ms_RadarTrace[LOWORD(FrontEndMenuManager.m_nTargetBlipIndex)]; tRadarTrace targetBlip = CRadar::ms_RadarTrace[LOWORD(FrontEndMenuManager.m_nTargetBlipIndex)];
if (targetBlip.m_nBlipSprite != RADAR_SPRITE_WAYPOINT) if (targetBlip.m_nBlipSprite != RADAR_SPRITE_WAYPOINT)
{ {
SetHelpMessage("Target blip not found. You need to place it on the map first.", false, false, false); SetHelpMessage("Target blip not found. You need to place it on the map first.", false, false, false);
return; return;
} }
CEntity* pPlayerEntity = FindPlayerEntity(-1); CEntity* pPlayerEntity = FindPlayerEntity(-1);
pos = targetBlip.m_vPosition; pos = targetBlip.m_vPosition;
pos.z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, 1000, nullptr, &pPlayerEntity) + 50.f; pos.z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, 1000, nullptr, &pPlayerEntity) + 50.f;
m_Teleport::m_fPos = pos; m_Teleport::m_fPos = pos;
m_Teleport::m_nTimer = CTimer::m_snTimeInMilliseconds; m_Teleport::m_nTimer = CTimer::m_snTimeInMilliseconds;
m_Teleport::m_bEnabled = true; m_Teleport::m_bEnabled = true;
TheCamera.Fade(0, 0); TheCamera.Fade(0, 0);
Command<Commands::FREEZE_CHAR_POSITION_AND_DONT_LOAD_COLLISION>(CPools::GetPedRef(pPlayer), true); Command<Commands::FREEZE_CHAR_POSITION_AND_DONT_LOAD_COLLISION>(CPools::GetPedRef(pPlayer), true);
} }
#endif #endif
#ifdef GTA3 #ifdef GTA3
CStreaming::LoadScene(pos); CStreaming::LoadScene(pos);
#else #else
CStreaming::LoadScene(&pos); CStreaming::LoadScene(&pos);
CStreaming::LoadSceneCollision(&pos); CStreaming::LoadSceneCollision(&pos);
#endif #endif
CStreaming::LoadAllRequestedModels(false); CStreaming::LoadAllRequestedModels(false);
#ifdef GTASA #ifdef GTASA
if (pVeh && pPlayer->m_nPedFlags.bInVehicle) if (pVeh && pPlayer->m_nPedFlags.bInVehicle)
{ {
pVeh->Teleport(pos, false); pVeh->Teleport(pos, false);
if (pVeh->m_nVehicleClass == VEHICLE_BIKE)
reinterpret_cast<CBike*>(pVeh)->PlaceOnRoadProperly();
else if (pVeh->m_nVehicleClass != VEHICLE_BOAT)
reinterpret_cast<CAutomobile*>(pVeh)->PlaceOnRoadProperly();
BY_GAME(pVeh->m_nAreaCode, pVeh->m_nInterior, NULL) = interior_id; if (pVeh->m_nVehicleClass == VEHICLE_BIKE)
} reinterpret_cast<CBike*>(pVeh)->PlaceOnRoadProperly();
else else if (pVeh->m_nVehicleClass != VEHICLE_BOAT)
{ reinterpret_cast<CAutomobile*>(pVeh)->PlaceOnRoadProperly();
pPlayer->Teleport(pos, false);
} BY_GAME(pVeh->m_nAreaCode, pVeh->m_nInterior, NULL) = interior_id;
#else // GTA3 & GTAVC }
if (pVeh && pPlayer->m_pVehicle) else
{ {
pPlayer->Teleport(pos, false);
}
#else
if (pVeh && pPlayer->m_pVehicle)
{
#ifndef GTA3 #ifndef GTA3
BY_GAME(pPlayer->m_nAreaCode, pPlayer->m_nInterior, NULL) = interior_id; BY_GAME(pPlayer->m_nAreaCode, pPlayer->m_nInterior, NULL) = interior_id;
#endif #endif
pVeh->Teleport(pos); pVeh->Teleport(pos);
} }
else else
{ {
pPlayer->Teleport(pos); pPlayer->Teleport(pos);
} }
#endif #endif
#ifndef GTA3 #ifndef GTA3
BY_GAME(pPlayer->m_nAreaCode, pPlayer->m_nInterior, NULL) = interior_id; BY_GAME(pPlayer->m_nAreaCode, pPlayer->m_nInterior, NULL) = interior_id;
Command<Commands::SET_AREA_VISIBLE>(interior_id); Command<Commands::SET_AREA_VISIBLE>(interior_id);
#endif #endif
} }
void Teleport::TeleportToLocation(std::string& rootkey, std::string& bLocName, std::string& loc) void Teleport::TeleportToLocation(std::string& rootkey, std::string& bLocName, std::string& loc)
{ {
try try
{ {
int dimension = 0; int dimension = 0;
CVector pos; CVector pos;
sscanf(loc.c_str(), "%d,%f,%f,%f", &dimension, &pos.x, &pos.y, &pos.z); sscanf(loc.c_str(), "%d,%f,%f,%f", &dimension, &pos.x, &pos.y, &pos.z);
TeleportPlayer(false, pos, dimension); TeleportPlayer(false, pos, dimension);
} }
catch (...) catch (...)
{ {
SetHelpMessage("Invalid location", false, false, false); SetHelpMessage("Invalid location", false, false, false);
} }
} }
void Teleport::RemoveTeleportEntry(std::string& category, std::string& key, std::string& val) void Teleport::RemoveTeleportEntry(std::string& category, std::string& key, std::string& val)
{ {
if (category == "Custom") if (category == "Custom")
{ {
m_tpData.m_pJson->m_Data["Custom"].erase(key); m_tpData.m_pJson->m_Data["Custom"].erase(key);
SetHelpMessage("Location removed", false, false, false); SetHelpMessage("Location removed", false, false, false);
m_tpData.m_pJson->WriteToDisk(); m_tpData.m_pJson->WriteToDisk();
} }
else else
{ {
SetHelpMessage("You can only remove custom location", false, false, false); SetHelpMessage("You can only remove custom location", false, false, false);
} }
} }
void Teleport::Draw() void Teleport::Draw()
{ {
if (ImGui::BeginTabBar("Teleport", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll)) if (ImGui::BeginTabBar("Teleport", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
{ {
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::BeginTabItem("Teleport")) if (ImGui::BeginTabItem("Teleport"))
{ {
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::BeginChild("Teleport Child")) if (ImGui::BeginChild("Teleport Child"))
{ {
ImGui::Columns(2, nullptr, false); ImGui::Columns(2, nullptr, false);
ImGui::Checkbox("Insert coordinates", &m_bInsertCoord); ImGui::Checkbox("Insert coordinates", &m_bInsertCoord);
ImGui::NextColumn(); ImGui::NextColumn();
#ifdef GTASA #ifdef GTASA
if (Ui::CheckboxWithHint("Quick teleport", &m_bQuickTeleport, if (Ui::CheckboxWithHint("Quick teleport", &m_bQuickTeleport,
std::string(std::string("Teleport to the location of your radar\ntarget blip using ") std::string(std::string("Teleport to the location of your radar\ntarget blip using ")
+ quickTeleport.GetNameString()).c_str())) + quickTeleport.GetNameString()).c_str()))
{ {
gConfig.SetValue("quick_teleport", m_bQuickTeleport); gConfig.SetValue("quick_teleport", m_bQuickTeleport);
} }
#endif #endif
ImGui::Columns(1); ImGui::Columns(1);
ImGui::Spacing(); ImGui::Spacing();
if (m_bInsertCoord) if (m_bInsertCoord)
{ {
CVector pos = FindPlayerPed()->GetPosition(); CVector pos = FindPlayerPed()->GetPosition();
strcpy(m_nInputBuffer, strcpy(m_nInputBuffer,
(std::to_string(static_cast<int>(pos.x)) + ", " + std::to_string(static_cast<int>(pos.y)) + (std::to_string(static_cast<int>(pos.x)) + ", " + std::to_string(static_cast<int>(pos.y)) +
", " + std::to_string(static_cast<int>(pos.z))).c_str()); ", " + std::to_string(static_cast<int>(pos.z))).c_str());
} }
ImGui::InputTextWithHint("Coordinates", "x, y, z", m_nInputBuffer, IM_ARRAYSIZE(m_nInputBuffer)); ImGui::InputTextWithHint("Coordinates", "x, y, z", m_nInputBuffer, IM_ARRAYSIZE(m_nInputBuffer));
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::Button("Teleport to coord", Ui::GetSize(2))) if (ImGui::Button("Teleport to coord", Ui::GetSize(2)))
{ {
CVector pos{0, 0, 10}; CVector pos{0, 0, 10};
try try
{ {
sscanf(m_nInputBuffer,"%f,%f,%f", &pos.x, &pos.y, &pos.z); sscanf(m_nInputBuffer,"%f,%f,%f", &pos.x, &pos.y, &pos.z);
pos.z += 1.0f; pos.z += 1.0f;
TeleportPlayer(false, pos); TeleportPlayer(false, pos);
} }
catch (...) catch (...)
{ {
SetHelpMessage("Invalid coordinate", false, false, false); SetHelpMessage("Invalid coordinate", false, false, false);
} }
} }
ImGui::SameLine(); ImGui::SameLine();
#ifdef GTASA #ifdef GTASA
if (ImGui::Button("Teleport to marker", Ui::GetSize(2))) if (ImGui::Button("Teleport to marker", Ui::GetSize(2)))
{ {
TeleportPlayer(true); TeleportPlayer(true);
} }
#else #else
if (ImGui::Button("Teleport to map center", Ui::GetSize(2))) if (ImGui::Button("Teleport to map center", Ui::GetSize(2)))
{ {
TeleportPlayer(false, CVector(0, 0, 23)); TeleportPlayer(false, CVector(0, 0, 23));
} }
#endif #endif
ImGui::EndChild(); ImGui::EndChild();
} }
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("Search")) if (ImGui::BeginTabItem("Search"))
{ {
#ifdef GTASA #ifdef GTASA
FetchRadarSpriteData(); FetchRadarSpriteData();
#endif #endif
ImGui::Spacing(); ImGui::Spacing();
Ui::DrawJSON(m_tpData, TeleportToLocation,RemoveTeleportEntry); Ui::DrawJSON(m_tpData, TeleportToLocation,RemoveTeleportEntry);
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("Custom")) if (ImGui::BeginTabItem("Custom"))
{ {
ImGui::Spacing(); ImGui::Spacing();
ImGui::InputTextWithHint("Location", "Groove Street", m_nLocationBuffer, IM_ARRAYSIZE(m_nInputBuffer)); ImGui::InputTextWithHint("Location", "Groove Street", m_nLocationBuffer, IM_ARRAYSIZE(m_nInputBuffer));
ImGui::InputTextWithHint("Coordinates", "x, y, z", m_nInputBuffer, IM_ARRAYSIZE(m_nInputBuffer)); ImGui::InputTextWithHint("Coordinates", "x, y, z", m_nInputBuffer, IM_ARRAYSIZE(m_nInputBuffer));
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::Button("Add location", Ui::GetSize())) if (ImGui::Button("Add location", Ui::GetSize()))
{ {
m_tpData.m_pJson->m_Data["Custom"][m_nLocationBuffer] = ("0, " + std::string(m_nInputBuffer)); m_tpData.m_pJson->m_Data["Custom"][m_nLocationBuffer] = ("0, " + std::string(m_nInputBuffer));
#ifdef GTASA #ifdef GTASA
// Clear the Radar coordinates // Clear the Radar coordinates
m_tpData.m_pJson->m_Data.erase("Radar"); m_tpData.m_pJson->m_Data.erase("Radar");
m_tpData.m_pJson->m_Data["Radar"] = {}; m_tpData.m_pJson->m_Data["Radar"] = {};
#endif #endif
m_tpData.m_pJson->WriteToDisk(); m_tpData.m_pJson->WriteToDisk();
} }
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
} }

View File

@ -5,38 +5,38 @@
class Teleport class Teleport
{ {
private: private:
static inline bool m_bInsertCoord; static inline bool m_bInsertCoord;
static inline bool m_bQuickTeleport; static inline bool m_bQuickTeleport;
static inline char m_nInputBuffer[INPUT_BUFFER_SIZE]; static inline char m_nInputBuffer[INPUT_BUFFER_SIZE];
static inline ResourceStore m_tpData{ "teleport", eResourceType::TYPE_TEXT }; static inline ResourceStore m_tpData{ "teleport", eResourceType::TYPE_TEXT };
static inline char m_nLocationBuffer[INPUT_BUFFER_SIZE]; static inline char m_nLocationBuffer[INPUT_BUFFER_SIZE];
static inline uint m_nQuickTeleportTimer; static inline uint m_nQuickTeleportTimer;
#ifdef GTASA #ifdef GTASA
static inline CJson m_SpriteJson = CJson("radar sprite"); static inline CJson m_SpriteJson = CJson("radar sprite");
#endif #endif
struct m_Teleport struct m_Teleport
{ {
static inline bool m_bEnabled; static inline bool m_bEnabled;
static inline CVector m_fPos = { -1, -1, -1 }; static inline CVector m_fPos = { -1, -1, -1 };
static inline uint m_nTimer; static inline uint m_nTimer;
}; };
#ifdef GTASA #ifdef GTASA
/* /*
Generates radar sprite coordinates on the fly. Generates radar sprite coordinates on the fly.
Shouldn't get saved in 'teleport.json', needs to be cleared at game shutdown. Shouldn't get saved in 'teleport.json', needs to be cleared at game shutdown.
*/ */
static void FetchRadarSpriteData(); static void FetchRadarSpriteData();
#endif #endif
protected: protected:
Teleport(); Teleport();
public: public:
static void Draw(); static void Draw();
static void TeleportPlayer(bool get_marker = false, CVector pos = CVector(0, 0, 0), int interior_id = 0); static void TeleportPlayer(bool get_marker = false, CVector pos = CVector(0, 0, 0), int interior_id = 0);
static void TeleportToLocation(std::string& rootkey, std::string& bLocName, std::string& loc); static void TeleportToLocation(std::string& rootkey, std::string& bLocName, std::string& loc);
static void RemoveTeleportEntry(std::string& rootkey, std::string& key, std::string& val); static void RemoveTeleportEntry(std::string& rootkey, std::string& key, std::string& val);
}; };

View File

@ -130,7 +130,7 @@ uchar *m_nBlurRed = (uchar *)0x94B790;
uchar *m_nBlurGreen = (uchar *)0x8621A0; uchar *m_nBlurGreen = (uchar *)0x8621A0;
uchar *m_nBlurBlue = (uchar *)0x945728; uchar *m_nBlurBlue = (uchar *)0x945728;
#else // GTA3 #else
int *m_nAmbientRed = (int *)0x86AF78; int *m_nAmbientRed = (int *)0x86AF78;
int *m_nAmbientGreen = (int *)0x665308; int *m_nAmbientGreen = (int *)0x665308;

1404
src/ui.cpp

File diff suppressed because it is too large Load Diff

302
src/ui.h
View File

@ -5,205 +5,205 @@
class Ui class Ui
{ {
public: public:
struct NamedMemory struct NamedMemory
{ {
std::string name; std::string name;
int addr; int addr;
}; };
struct NamedValue struct NamedValue
{ {
std::string name; std::string name;
int value; int value;
}; };
struct JsonPopUpData struct JsonPopUpData
{ {
std::function<void(std::string&, std::string&, std::string&)> function; std::function<void(std::string&, std::string&, std::string&)> function;
std::string key; std::string key;
std::string root; std::string root;
std::string value; std::string value;
}; };
struct ImgPopUpData struct ImgPopUpData
{ {
std::function<void(std::string&)> function; std::function<void(std::string&)> function;
std::string value; std::string value;
}; };
static inline int m_HeaderId; static inline int m_HeaderId;
static inline JsonPopUpData jsonPopup; static inline JsonPopUpData jsonPopup;
static inline ImgPopUpData imgPopup; static inline ImgPopUpData imgPopup;
Ui() = delete; Ui() = delete;
Ui(Ui&) = delete; Ui(Ui&) = delete;
static void CenterdText(const std::string& text); static void CenterdText(const std::string& text);
static bool ColorButton(int color_id, std::vector<float>& color, ImVec2 size); static bool ColorButton(int color_id, std::vector<float>& color, ImVec2 size);
static bool CheckboxAddress(const char* label, int addr = NULL, const char* hint = nullptr); static bool CheckboxAddress(const char* label, int addr = NULL, const char* hint = nullptr);
static bool CheckboxAddressEx(const char* label, int addr = NULL, int enabled_val = 1, int disabled_val = 0, static bool CheckboxAddressEx(const char* label, int addr = NULL, int enabled_val = 1, int disabled_val = 0,
const char* hint = nullptr); const char* hint = nullptr);
static bool CheckboxAddressVar(const char* label, bool val, int addr, const char* hint = nullptr); static bool CheckboxAddressVar(const char* label, bool val, int addr, const char* hint = nullptr);
static bool CheckboxAddressVarEx(const char* label, bool val, int addr, int enabled_val, int disabled_val, static bool CheckboxAddressVarEx(const char* label, bool val, int addr, int enabled_val, int disabled_val,
const char* hint = nullptr); const char* hint = nullptr);
static bool CheckboxBitFlag(const char* label, uint flag, const char* hint = nullptr); static bool CheckboxBitFlag(const char* label, uint flag, const char* hint = nullptr);
static bool CheckboxWithHint(const char* label, bool* state, const char* hint = nullptr, bool is_disabled = false); static bool CheckboxWithHint(const char* label, bool* state, const char* hint = nullptr, bool is_disabled = false);
static void DrawHeaders(CallbackTable& data); static void DrawHeaders(CallbackTable& data);
static void DrawJSON(ResourceStore& data, static void DrawJSON(ResourceStore& data,
std::function<void(std::string&, std::string&, std::string&)> func_left_click, std::function<void(std::string&, std::string&, std::string&)> func_left_click,
std::function<void(std::string&, std::string&, std::string&)> func_right_click); std::function<void(std::string&, std::string&, std::string&)> func_right_click);
static void DrawImages(ResourceStore &store, std::function<void(std::string&)> on_left_click, static void DrawImages(ResourceStore &store, std::function<void(std::string&)> on_left_click,
std::function<void(std::string&)> on_right_click, std::function<void(std::string&)> on_right_click,
std::function<std::string(std::string&)> get_name_func, std::function<std::string(std::string&)> get_name_func,
std::function<bool(std::string&)> verify_func = nullptr, std::function<bool(std::string&)> verify_func = nullptr,
const char** custom_names = nullptr, size_t length = 0); const char** custom_names = nullptr, size_t length = 0);
static bool DrawTitleBar(); static bool DrawTitleBar();
template <typename T> template <typename T>
static void EditAddress(const char* label, int address, int min = 0, int def = 0, int max = 100); static void EditAddress(const char* label, int address, int min = 0, int def = 0, int max = 100);
static void EditBits(const char* label, int address, const std::vector<std::string>& names); static void EditBits(const char* label, int address, const std::vector<std::string>& names);
static void EditFloat(const char* label, int address, float min, float def, float max, float mul = 1, float change = 1.0f); static void EditFloat(const char* label, int address, float min, float def, float max, float mul = 1, float change = 1.0f);
template <typename T> template <typename T>
static void EditReference(const char* label, T& address, int min = 0, int def = 0, int max = 100); static void EditReference(const char* label, T& address, int min = 0, int def = 0, int max = 100);
static void EditRadioButtonAddress(const char* label, std::vector<NamedMemory>& named_mem); static void EditRadioButtonAddress(const char* label, std::vector<NamedMemory>& named_mem);
static void EditRadioButtonAddressEx(const char* label, int addr, std::vector<NamedValue>& named_val); static void EditRadioButtonAddressEx(const char* label, int addr, std::vector<NamedValue>& named_val);
#ifdef GTASA #ifdef GTASA
static void EditStat(const char* label, int stat_id, int min = 0, int def = 0, int max = 1000); static void EditStat(const char* label, int stat_id, int min = 0, int def = 0, int max = 1000);
#endif #endif
static void FilterWithHint(const char* label, ImGuiTextFilter& filter, const char* hint); static void FilterWithHint(const char* label, ImGuiTextFilter& filter, const char* hint);
static ImVec2 GetSize(short count = 1, bool spacing = true); static ImVec2 GetSize(short count = 1, bool spacing = true);
static bool ListBox(const char* label, std::vector<std::string>& all_items, int& selected); static bool ListBox(const char* label, std::vector<std::string>& all_items, int& selected);
static bool ListBoxStr(const char* label, std::vector<std::string>& all_items, std::string& selected); static bool ListBoxStr(const char* label, std::vector<std::string>& all_items, std::string& selected);
static bool ListBoxCustomNames(const char* label, std::vector<std::string>& all_items, std::string& selected, const char* custom_names[] = nullptr, size_t length = 0); static bool ListBoxCustomNames(const char* label, std::vector<std::string>& all_items, std::string& selected, const char* custom_names[] = nullptr, size_t length = 0);
static void RadioButtonAddress(const char* label, std::vector<NamedMemory>& named_mem); static void RadioButtonAddress(const char* label, std::vector<NamedMemory>& named_mem);
static void RadioButtonAddressEx(const char* label, int addr, std::vector<NamedValue>& named_val); static void RadioButtonAddressEx(const char* label, int addr, std::vector<NamedValue>& named_val);
static bool RoundedImageButton(ImTextureID user_texture_id, ImVec2& size, const char* hover_text, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col); static bool RoundedImageButton(ImTextureID user_texture_id, ImVec2& size, const char* hover_text, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col);
static void ColorPickerAddress(const char* label, int base_addr, ImVec4&& default_color); static void ColorPickerAddress(const char* label, int base_addr, ImVec4&& default_color);
static void ShowTooltip(const char* text); static void ShowTooltip(const char* text);
}; };
template <typename T> template <typename T>
void Ui::EditAddress(const char* label, const int address, const int min, const int def, const int max) void Ui::EditAddress(const char* label, const int address, const int min, const int def, const int max)
{ {
if (ImGui::CollapsingHeader(label)) if (ImGui::CollapsingHeader(label))
{ {
int val = patch::Get<T>(address, false); int val = patch::Get<T>(address, false);
int items = 3; int items = 3;
if (min == def) if (min == def)
{ {
items = 2; items = 2;
} }
ImGui::Columns(items, nullptr, false); ImGui::Columns(items, nullptr, false);
ImGui::Text(("Min: " + std::to_string(min)).c_str()); ImGui::Text(("Min: " + std::to_string(min)).c_str());
if (items == 3) if (items == 3)
{ {
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text(("Def: " + std::to_string(def)).c_str()); ImGui::Text(("Def: " + std::to_string(def)).c_str());
} }
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text(("Max: " + std::to_string(max)).c_str()); ImGui::Text(("Max: " + std::to_string(max)).c_str());
ImGui::Columns(1); ImGui::Columns(1);
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::InputInt(("Set value##" + std::string(label)).c_str(), &val)) if (ImGui::InputInt(("Set value##" + std::string(label)).c_str(), &val))
{ {
patch::Set<T>(address, val, false); patch::Set<T>(address, val, false);
} }
ImGui::Spacing(); ImGui::Spacing();
if (val < min) if (val < min)
{ {
val = min; val = min;
} }
if (val > max) if (val > max)
{ {
val = max; val = max;
} }
if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), GetSize(items))) if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), GetSize(items)))
{ {
patch::Set<T>(address, min, false); patch::Set<T>(address, min, false);
} }
if (items == 3) if (items == 3)
{ {
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(("Default##" + std::string(label)).c_str(), GetSize(3))) if (ImGui::Button(("Default##" + std::string(label)).c_str(), GetSize(3)))
{ {
patch::Set<T>(address, def, false); patch::Set<T>(address, def, false);
} }
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), GetSize(items))) if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), GetSize(items)))
{ {
patch::Set<T>(address, max, false); patch::Set<T>(address, max, false);
} }
ImGui::Spacing(); ImGui::Spacing();
ImGui::Separator(); ImGui::Separator();
} }
} }
template <typename T> template <typename T>
void Ui::EditReference(const char* label, T& address, const int min, const int def, const int max) void Ui::EditReference(const char* label, T& address, const int min, const int def, const int max)
{ {
if (ImGui::CollapsingHeader(label)) if (ImGui::CollapsingHeader(label))
{ {
int val = static_cast<int>(address); int val = static_cast<int>(address);
ImGui::Columns(3, nullptr, false); ImGui::Columns(3, nullptr, false);
ImGui::Text(("Min: " + std::to_string(min)).c_str()); ImGui::Text(("Min: " + std::to_string(min)).c_str());
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text(("Def: " + std::to_string(def)).c_str()); ImGui::Text(("Def: " + std::to_string(def)).c_str());
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text(("Max: " + std::to_string(max)).c_str()); ImGui::Text(("Max: " + std::to_string(max)).c_str());
ImGui::Columns(1); ImGui::Columns(1);
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::InputInt(("Set value##" + std::string(label)).c_str(), &val)) if (ImGui::InputInt(("Set value##" + std::string(label)).c_str(), &val))
{ {
address = static_cast<float>(val); address = static_cast<float>(val);
} }
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), GetSize(3))) if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), GetSize(3)))
{ {
address = static_cast<float>(min); address = static_cast<float>(min);
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(("Default##" + std::string(label)).c_str(), GetSize(3))) if (ImGui::Button(("Default##" + std::string(label)).c_str(), GetSize(3)))
{ {
address = static_cast<float>(def); address = static_cast<float>(def);
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), GetSize(3))) if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), GetSize(3)))
{ {
address = static_cast<float>(max); address = static_cast<float>(max);
} }
ImGui::Spacing(); ImGui::Spacing();
ImGui::Separator(); ImGui::Separator();
} }
} }

View File

@ -4,64 +4,64 @@
bool Updater::IsUpdateAvailable() bool Updater::IsUpdateAvailable()
{ {
return Updater::curState == States::FOUND; return Updater::curState == States::FOUND;
} }
void Updater::ResetUpdaterState() void Updater::ResetUpdaterState()
{ {
Updater::curState = States::IDLE; Updater::curState = States::IDLE;
} }
std::string Updater::GetUpdateVersion() std::string Updater::GetUpdateVersion()
{ {
return Updater::latestVer; return Updater::latestVer;
} }
void Updater::CheckUpdate() void Updater::CheckUpdate()
{ {
if (Updater::curState == States::IDLE) if (Updater::curState == States::IDLE)
{ {
Updater::curState = States::CHECKING; Updater::curState = States::CHECKING;
} }
} }
void Updater::Process() void Updater::Process()
{ {
if (Updater::curState != States::CHECKING) if (Updater::curState != States::CHECKING)
{ {
return; return;
} }
const char* link = "https://api.github.com/repos/user-grinch/Cheat-Menu/tags";
char* path = PLUGIN_PATH((char*)"CheatMenu/json/versioninfo.json");
HRESULT res = URLDownloadToFile(NULL, link, path, 0, NULL);
if (res == E_OUTOFMEMORY || res == INET_E_DOWNLOAD_FAILURE) const char* link = "https://api.github.com/repos/user-grinch/Cheat-Menu/tags";
{ char* path = PLUGIN_PATH((char*)"CheatMenu/json/versioninfo.json");
SetHelpMessage("Failed to check for updates", false, false, false); HRESULT res = URLDownloadToFile(NULL, link, path, 0, NULL);
return;
}
CJson verinfo = CJson("versioninfo");
// fetch the version number if (res == E_OUTOFMEMORY || res == INET_E_DOWNLOAD_FAILURE)
if (verinfo.m_Data.empty()) {
{ SetHelpMessage("Failed to check for updates", false, false, false);
latestVer = MENU_VERSION_NUMBER; return;
} }
else
{
latestVer = verinfo.m_Data.items().begin().value()["name"].get<std::string>();
}
if (latestVer > MENU_VERSION_NUMBER) CJson verinfo = CJson("versioninfo");
{
SetHelpMessage("Update found", false, false, false); // fetch the version number
curState = States::FOUND; if (verinfo.m_Data.empty())
} {
else latestVer = MENU_VERSION_NUMBER;
{ }
SetHelpMessage("No update found.", false, false, false); else
Updater::curState = States::IDLE; {
} latestVer = verinfo.m_Data.items().begin().value()["name"].get<std::string>();
}
if (latestVer > MENU_VERSION_NUMBER)
{
SetHelpMessage("Update found", false, false, false);
curState = States::FOUND;
}
else
{
SetHelpMessage("No update found.", false, false, false);
Updater::curState = States::IDLE;
}
} }

View File

@ -7,25 +7,25 @@
class Updater class Updater
{ {
private: private:
enum class States enum class States
{ {
IDLE, IDLE,
CHECKING, CHECKING,
FOUND FOUND
}; };
static inline States curState = States::IDLE; static inline States curState = States::IDLE;
static inline std::string latestVer; static inline std::string latestVer;
public: public:
Updater() = delete; Updater() = delete;
Updater(const Updater&) = delete; Updater(const Updater&) = delete;
static void CheckUpdate(); static void CheckUpdate();
static std::string GetUpdateVersion(); static std::string GetUpdateVersion();
static bool IsUpdateAvailable(); static bool IsUpdateAvailable();
// Needs to run in it's own thread to prevent the game from freezing // Needs to run in it's own thread to prevent the game from freezing
static void Process(); static void Process();
static void ResetUpdaterState(); static void ResetUpdaterState();
}; };

View File

@ -6,191 +6,191 @@ std::string Util::GetLocationName(CVector* pos)
{ {
#ifdef GTASA #ifdef GTASA
CPlayerPed *pPlayer = FindPlayerPed(); CPlayerPed *pPlayer = FindPlayerPed();
int hplayer = CPools::GetPedRef(pPlayer); int hplayer = CPools::GetPedRef(pPlayer);
int interior = 0; int interior = 0;
Command<Commands::GET_AREA_VISIBLE>(&interior); Command<Commands::GET_AREA_VISIBLE>(&interior);
std::string town = "San Andreas"; std::string town = "San Andreas";
int city; int city;
Command<Commands::GET_CITY_PLAYER_IS_IN>(&hplayer, &city); Command<Commands::GET_CITY_PLAYER_IS_IN>(&hplayer, &city);
switch (city) switch (city)
{ {
case 0: case 0:
town = "CS"; town = "CS";
break; break;
case 1: case 1:
town = "LS"; town = "LS";
break; break;
case 2: case 2:
town = "SF"; town = "SF";
break; break;
case 3: case 3:
town = "LV"; town = "LV";
break; break;
} }
if (interior == 0) if (interior == 0)
{ {
return CTheZones::FindSmallestZoneForPosition(*pos, true)->GetTranslatedName() + std::string(", ") + town; return CTheZones::FindSmallestZoneForPosition(*pos, true)->GetTranslatedName() + std::string(", ") + town;
} }
return std::string("Interior ") + std::to_string(interior) + ", " + town; return std::string("Interior ") + std::to_string(interior) + ", " + town;
#elif GTAVC #elif GTAVC
return "Vice City"; return "Vice City";
#else #else
return "Liberty City"; return "Liberty City";
#endif #endif
} }
#ifdef GTASA #ifdef GTASA
void Util::ClearCharTasksVehCheck(CPed* ped) void Util::ClearCharTasksVehCheck(CPed* ped)
{ {
uint hped = CPools::GetPedRef(ped); uint hped = CPools::GetPedRef(ped);
uint hveh = NULL; uint hveh = NULL;
bool veh_engine = true; bool veh_engine = true;
float speed; float speed;
if (ped->m_nPedFlags.bInVehicle) if (ped->m_nPedFlags.bInVehicle)
{ {
hveh = CPools::GetVehicleRef(ped->m_pVehicle); hveh = CPools::GetVehicleRef(ped->m_pVehicle);
veh_engine = ped->m_pVehicle->m_nVehicleFlags.bEngineOn; veh_engine = ped->m_pVehicle->m_nVehicleFlags.bEngineOn;
speed = ped->m_pVehicle->m_vecMoveSpeed.Magnitude() * 50.0f; speed = ped->m_pVehicle->m_vecMoveSpeed.Magnitude() * 50.0f;
} }
Command<Commands::CLEAR_CHAR_TASKS_IMMEDIATELY>(hped); Command<Commands::CLEAR_CHAR_TASKS_IMMEDIATELY>(hped);
if (hveh) if (hveh)
{ {
Command<Commands::TASK_WARP_CHAR_INTO_CAR_AS_DRIVER>(hped, hveh); Command<Commands::TASK_WARP_CHAR_INTO_CAR_AS_DRIVER>(hped, hveh);
ped->m_pVehicle->m_nVehicleFlags.bEngineOn = veh_engine; ped->m_pVehicle->m_nVehicleFlags.bEngineOn = veh_engine;
Command<Commands::SET_CAR_FORWARD_SPEED>(hveh, speed); Command<Commands::SET_CAR_FORWARD_SPEED>(hveh, speed);
} }
} }
bool Util::IsOnMission() bool Util::IsOnMission()
{ {
return FindPlayerPed()->CanPlayerStartMission() && !*(patch::Get<char*>(0x5D5380, false) + CTheScripts::OnAMissionFlag); return FindPlayerPed()->CanPlayerStartMission() && !*(patch::Get<char*>(0x5D5380, false) + CTheScripts::OnAMissionFlag);
} }
int Util::GetLargestGangInZone() int Util::GetLargestGangInZone()
{ {
int gang_id = 0, max_density = 0; int gang_id = 0, max_density = 0;
for (int i = 0; i != 10; ++i) for (int i = 0; i != 10; ++i)
{ {
CVector pos = FindPlayerPed()->GetPosition(); CVector pos = FindPlayerPed()->GetPosition();
CZoneInfo* zone_info = CTheZones::GetZoneInfo(&pos, nullptr); CZoneInfo* zone_info = CTheZones::GetZoneInfo(&pos, nullptr);
int density = zone_info->m_nGangDensity[i]; int density = zone_info->m_nGangDensity[i];
if (density > max_density) if (density > max_density)
{ {
max_density = density; max_density = density;
gang_id = i; gang_id = i;
} }
} }
return gang_id; return gang_id;
} }
#endif #endif
// implemention of opcode 0AB5 (STORE_CLOSEST_ENTITIES) // implemention of opcode 0AB5 (STORE_CLOSEST_ENTITIES)
// https://github.com/cleolibrary/CLEO4/blob/916d400f4a731ba1dd0ff16e52bdb056f42b7038/source/CCustomOpcodeSystem.cpp#L1671 // https://github.com/cleolibrary/CLEO4/blob/916d400f4a731ba1dd0ff16e52bdb056f42b7038/source/CCustomOpcodeSystem.cpp#L1671
CVehicle* Util::GetClosestVehicle() CVehicle* Util::GetClosestVehicle()
{ {
CPlayerPed* player = FindPlayerPed(); CPlayerPed* player = FindPlayerPed();
#ifdef GTASA #ifdef GTASA
CPedIntelligence* pedintel; CPedIntelligence* pedintel;
if (player && (pedintel = player->m_pIntelligence)) if (player && (pedintel = player->m_pIntelligence))
{ {
CVehicle* veh = nullptr; CVehicle* veh = nullptr;
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
veh = static_cast<CVehicle*>(pedintel->m_vehicleScanner.m_apEntities[i]); veh = static_cast<CVehicle*>(pedintel->m_vehicleScanner.m_apEntities[i]);
if (veh && !veh->m_nVehicleFlags.bFadeOut) if (veh && !veh->m_nVehicleFlags.bFadeOut)
break; break;
veh = nullptr; veh = nullptr;
} }
return veh; return veh;
} }
return nullptr; return nullptr;
#else // GTAVC & GTA3 #else
CVehicle *pClosestVeh = nullptr;
float distance = 999.0f;
CVector playerPos = player->GetPosition(); CVehicle *pClosestVeh = nullptr;
float distance = 999.0f;
for (CVehicle *pVeh : CPools::ms_pVehiclePool) CVector playerPos = player->GetPosition();
{
CVector pos = pVeh->GetPosition();
float dist = DistanceBetweenPoints(playerPos, pos);
if (dist < distance) for (CVehicle *pVeh : CPools::ms_pVehiclePool)
{ {
pClosestVeh = pVeh; CVector pos = pVeh->GetPosition();
distance = dist; float dist = DistanceBetweenPoints(playerPos, pos);
}
} if (dist < distance)
return pClosestVeh; {
pClosestVeh = pVeh;
distance = dist;
}
}
return pClosestVeh;
#endif #endif
} }
CPed* Util::GetClosestPed() CPed* Util::GetClosestPed()
{ {
CPlayerPed* player = FindPlayerPed(); CPlayerPed* player = FindPlayerPed();
#ifdef GTASA #ifdef GTASA
CPedIntelligence* pedintel; CPedIntelligence* pedintel;
if (player && (pedintel = player->m_pIntelligence)) if (player && (pedintel = player->m_pIntelligence))
{ {
CPed* ped = nullptr; CPed* ped = nullptr;
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
ped = static_cast<CPed*>(pedintel->m_pedScanner.m_apEntities[i]); ped = static_cast<CPed*>(pedintel->m_pedScanner.m_apEntities[i]);
if (ped && ped != player && (ped->m_nCreatedBy & 0xFF) == 1 && !ped->m_nPedFlags.bFadeOut) if (ped && ped != player && (ped->m_nCreatedBy & 0xFF) == 1 && !ped->m_nPedFlags.bFadeOut)
break; break;
ped = nullptr; ped = nullptr;
} }
return ped; return ped;
} }
return nullptr; return nullptr;
#else // GTA3 & GTAVC #else
return player->m_apNearPeds[0]; return player->m_apNearPeds[0];
#endif #endif
} }
bool Util::IsOnCutscene() bool Util::IsOnCutscene()
{ {
return BY_GAME(CCutsceneMgr::ms_running, *(bool*)0xA10AB2, *(bool*)0x95CCF5); return BY_GAME(CCutsceneMgr::ms_running, *(bool*)0xA10AB2, *(bool*)0x95CCF5);
} }
void Util::RainbowValues(int& r, int& g, int& b, float speed) void Util::RainbowValues(int& r, int& g, int& b, float speed)
{ {
int timer = CTimer::m_snTimeInMilliseconds / 150; int timer = CTimer::m_snTimeInMilliseconds / 150;
r = sin(timer * speed) * 127 + 128; r = sin(timer * speed) * 127 + 128;
g = sin(timer * speed + 2) * 127 + 128; g = sin(timer * speed + 2) * 127 + 128;
b = sin(timer * speed + 4) * 127 + 128; b = sin(timer * speed + 4) * 127 + 128;
} }
void Util::GetCPUUsageInit() void Util::GetCPUUsageInit()
{ {
PdhOpenQuery(nullptr, NULL, &cpuQuery); PdhOpenQuery(nullptr, NULL, &cpuQuery);
PdhAddEnglishCounter(cpuQuery, "\\Processor(_Total)\\% Processor Time", NULL, &cpuTotal); PdhAddEnglishCounter(cpuQuery, "\\Processor(_Total)\\% Processor Time", NULL, &cpuTotal);
PdhCollectQueryData(cpuQuery); PdhCollectQueryData(cpuQuery);
} }
double Util::GetCurrentCPUUsage() double Util::GetCurrentCPUUsage()
{ {
PDH_FMT_COUNTERVALUE counterVal; PDH_FMT_COUNTERVALUE counterVal;
PdhCollectQueryData(cpuQuery); PdhCollectQueryData(cpuQuery);
PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, nullptr, &counterVal); PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, nullptr, &counterVal);
return counterVal.doubleValue; return counterVal.doubleValue;
} }

View File

@ -5,27 +5,27 @@
class Util class Util
{ {
private: private:
static inline PDH_HQUERY cpuQuery; static inline PDH_HQUERY cpuQuery;
static inline PDH_HCOUNTER cpuTotal; static inline PDH_HCOUNTER cpuTotal;
static inline ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU; static inline ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU;
static inline int numProcessors; static inline int numProcessors;
static inline HANDLE self; static inline HANDLE self;
public: public:
Util() = delete; Util() = delete;
Util(Util&) = delete; Util(Util&) = delete;
#ifdef GTASA #ifdef GTASA
static void ClearCharTasksVehCheck(CPed* ped); static void ClearCharTasksVehCheck(CPed* ped);
static int GetLargestGangInZone(); static int GetLargestGangInZone();
#endif #endif
static CPed* GetClosestPed(); static CPed* GetClosestPed();
static CVehicle* GetClosestVehicle(); static CVehicle* GetClosestVehicle();
static void GetCPUUsageInit(); static void GetCPUUsageInit();
static double GetCurrentCPUUsage(); static double GetCurrentCPUUsage();
static std::string GetLocationName(CVector* pos); static std::string GetLocationName(CVector* pos);
static bool IsOnCutscene(); static bool IsOnCutscene();
static bool IsOnMission(); static bool IsOnMission();
static void RainbowValues(int& r, int& g, int& b, float speed); static void RainbowValues(int& r, int& g, int& b, float speed);
}; };

File diff suppressed because it is too large Load Diff

View File

@ -4,101 +4,101 @@
class Vehicle class Vehicle
{ {
private: private:
static inline bool m_bBikeFly; static inline bool m_bBikeFly;
static inline bool m_bDontFallBike; static inline bool m_bDontFallBike;
static inline bool m_bVehHeavy; static inline bool m_bVehHeavy;
static inline bool m_bVehWatertight; static inline bool m_bVehWatertight;
static inline bool m_bNoDamage; static inline bool m_bNoDamage;
static inline int m_nDoorMenuButton; static inline int m_nDoorMenuButton;
static inline std::string m_DoorNames[6] = static inline std::string m_DoorNames[6] =
{ "Hood", "Boot", "Front left door", "Front right door", "Rear left door", "Rear right door" }; { "Hood", "Boot", "Front left door", "Front right door", "Rear left door", "Rear right door" };
static inline int m_nVehRemoveRadius; static inline int m_nVehRemoveRadius;
static inline bool m_bLockSpeed; static inline bool m_bLockSpeed;
static inline float m_fLockSpeed; static inline float m_fLockSpeed;
static inline std::vector<std::vector<float>> m_CarcolsColorData; static inline std::vector<std::vector<float>> m_CarcolsColorData;
struct m_Paint struct m_Paint
{ {
static inline bool m_bMatFilter = true; static inline bool m_bMatFilter = true;
static inline int m_nRadioButton = 1; static inline int m_nRadioButton = 1;
static inline float m_fColorPicker[3]{ 0, 0, 0 }; static inline float m_fColorPicker[3] { 0, 0, 0 };
static inline std::vector<std::string> m_vecNames{"Default"}; static inline std::vector<std::string> m_vecNames{"Default"};
static inline std::string m_Selected = "Default"; static inline std::string m_Selected = "Default";
}; };
#ifdef GTASA
static inline bool m_bDisableColDetection;
static inline std::map<int, std::string> m_VehicleIDE;
struct m_Neon
{
static inline float m_fColorPicker[3]{ 0, 0, 0 };
static inline bool m_bRainbowEffect;
static inline uint m_nRainbowTimer;
static inline bool m_bApplyOnTraffic;
static inline uint m_bTrafficTimer;
};
static inline ResourceStore m_TuneData { "components", eResourceType::TYPE_IMAGE, ImVec2(100, 80) };
#endif
struct m_Spawner
{
#ifdef GTASA #ifdef GTASA
static inline ResourceStore m_VehData { "vehicles", eResourceType::TYPE_IMAGE, ImVec2(100, 75)}; static inline bool m_bDisableColDetection;
#else // GTA3 & GTAVC static inline std::map<int, std::string> m_VehicleIDE;
static inline ResourceStore m_VehData{"vehicle", eResourceType::TYPE_TEXT}; struct m_Neon
{
static inline float m_fColorPicker[3] { 0, 0, 0 };
static inline bool m_bRainbowEffect;
static inline uint m_nRainbowTimer;
static inline bool m_bApplyOnTraffic;
static inline uint m_bTrafficTimer;
};
static inline ResourceStore m_TuneData { "components", eResourceType::TYPE_IMAGE, ImVec2(100, 80) };
#endif #endif
static inline bool m_bSpawnInside = true;
static inline bool m_bSpawnInAir = true;
static inline char m_nLicenseText[9];
};
struct m_UnlimitedNitro
{
static inline bool m_bEnabled;
static inline bool m_bCompAdded;
};
#ifdef GTASA struct m_Spawner
static inline std::vector<std::string>(m_HandlingFlagNames) = // 32 flags {
{ #ifdef GTASA
"1G_BOOST", "2G_BOOST", "NPC_ANTI_ROLL", "NPC_NEUTRAL_HANDL", "NO_HANDBRAKE", "STEER_REARWHEELS", static inline ResourceStore m_VehData { "vehicles", eResourceType::TYPE_IMAGE, ImVec2(100, 75)};
"HB_REARWHEEL_STEER", "ALT_STEER_OPT", #else
"WHEEL_F_NARROW2", "WHEEL_F_NARROW", "WHEEL_F_WIDE", "WHEEL_F_WIDE2", "WHEEL_R_NARROW2", "WHEEL_R_NARROW", static inline ResourceStore m_VehData {"vehicle", eResourceType::TYPE_TEXT};
"WHEEL_R_WIDE", "WHEEL_R_WIDE2", #endif
"HYDRAULIC_GEOM", "HYDRAULIC_INST", "HYDRAULIC_NONE", "NOS_INST", "OFFROAD_ABILITY", "OFFROAD_ABILITY2", static inline bool m_bSpawnInside = true;
"HALOGEN_LIGHTS", "PROC_REARWHEEL_1ST", static inline bool m_bSpawnInAir = true;
"USE_MAXSP_LIMIT", "LOW_RIDER", "STREET_RACER", "SWINGING_CHASSIS", "Unused 1", "Unused 2", "Unused 3", static inline char m_nLicenseText[9];
"Unused 4" };
}; struct m_UnlimitedNitro
{
static inline bool m_bEnabled;
static inline bool m_bCompAdded;
};
static inline std::vector<std::string>(m_ModelFlagNames) = // 32 flags #ifdef GTASA
{ static inline std::vector<std::string>(m_HandlingFlagNames) = // 32 flags
"IS_VAN", "IS_BUS", "IS_LOW", "IS_BIG", "REVERSE_BONNET", "HANGING_BOOT", "TAILGATE_BOOT", "NOSWING_BOOT", {
"NO_DOORS", "TANDEM_SEATS", "1G_BOOST", "2G_BOOST", "NPC_ANTI_ROLL", "NPC_NEUTRAL_HANDL", "NO_HANDBRAKE", "STEER_REARWHEELS",
"SIT_IN_BOAT", "CONVERTIBLE", "NO_EXHAUST", "DOUBLE_EXHAUST", "NO1FPS_LOOK_BEHIND", "FORCE_DOOR_CHECK", "HB_REARWHEEL_STEER", "ALT_STEER_OPT",
"AXLE_F_NOTILT", "AXLE_F_SOLID", "AXLE_F_MCPHERSON", "WHEEL_F_NARROW2", "WHEEL_F_NARROW", "WHEEL_F_WIDE", "WHEEL_F_WIDE2", "WHEEL_R_NARROW2", "WHEEL_R_NARROW",
"AXLE_F_REVERSE", "AXLE_R_NOTILT", "AXLE_R_SOLID", "AXLE_R_MCPHERSON", "AXLE_R_REVERSE", "IS_BIKE", "IS_HELI", "WHEEL_R_WIDE", "WHEEL_R_WIDE2",
"IS_PLANE", "IS_BOAT", "BOUNCE_PANELS", "HYDRAULIC_GEOM", "HYDRAULIC_INST", "HYDRAULIC_NONE", "NOS_INST", "OFFROAD_ABILITY", "OFFROAD_ABILITY2",
"DOUBLE_RWHEELS", "FORCE_GROUND_CLEARANCE", "IS_HATCHBAC1K" "HALOGEN_LIGHTS", "PROC_REARWHEEL_1ST",
}; "USE_MAXSP_LIMIT", "LOW_RIDER", "STREET_RACER", "SWINGING_CHASSIS", "Unused 1", "Unused 2", "Unused 3",
"Unused 4"
};
static inline std::vector<std::string>(m_ModelFlagNames) = // 32 flags
{
"IS_VAN", "IS_BUS", "IS_LOW", "IS_BIG", "REVERSE_BONNET", "HANGING_BOOT", "TAILGATE_BOOT", "NOSWING_BOOT",
"NO_DOORS", "TANDEM_SEATS",
"SIT_IN_BOAT", "CONVERTIBLE", "NO_EXHAUST", "DOUBLE_EXHAUST", "NO1FPS_LOOK_BEHIND", "FORCE_DOOR_CHECK",
"AXLE_F_NOTILT", "AXLE_F_SOLID", "AXLE_F_MCPHERSON",
"AXLE_F_REVERSE", "AXLE_R_NOTILT", "AXLE_R_SOLID", "AXLE_R_MCPHERSON", "AXLE_R_REVERSE", "IS_BIKE", "IS_HELI",
"IS_PLANE", "IS_BOAT", "BOUNCE_PANELS",
"DOUBLE_RWHEELS", "FORCE_GROUND_CLEARANCE", "IS_HATCHBAC1K"
};
#endif #endif
private: private:
static void FixVehicle(CVehicle *pVeh); static void FixVehicle(CVehicle *pVeh);
#ifdef GTASA #ifdef GTASA
static void AddComponent(const std::string& component, bool display_message = true); static void AddComponent(const std::string& component, bool display_message = true);
static void RemoveComponent(const std::string& component, bool display_message = true); static void RemoveComponent(const std::string& component, bool display_message = true);
static int GetRandomTrainIdForModel(int model); static int GetRandomTrainIdForModel(int model);
static void GenerateHandlingDataFile(int phandling); static void GenerateHandlingDataFile(int phandling);
#endif #endif
public: public:
#ifdef GTASA #ifdef GTASA
static void SpawnVehicle(std::string& name); static void SpawnVehicle(std::string& name);
#else // GTA3 & GTAVC #else
static void SpawnVehicle(std::string& rootkey, std::string& vehName, std::string& model); static void SpawnVehicle(std::string& rootkey, std::string& vehName, std::string& model);
#endif #endif
static std::string GetNameFromModel(int model); static std::string GetNameFromModel(int model);
static int GetModelFromName(const char* name); static int GetModelFromName(const char* name);
static void Draw(); static void Draw();
Vehicle(); Vehicle();
~Vehicle(); ~Vehicle();
}; };

File diff suppressed because it is too large Load Diff

View File

@ -4,41 +4,41 @@
class Visual class Visual
{ {
private: private:
static inline bool m_bLockWeather; static inline bool m_bLockWeather;
#ifdef GTASA #ifdef GTASA
static inline bool m_bInvisibleWater; static inline bool m_bInvisibleWater;
static inline bool m_bNoWater; static inline bool m_bNoWater;
static inline bool m_bDisableHydrant; static inline bool m_bDisableHydrant;
#endif #endif
// Timecyc stuff // Timecyc stuff
static inline int m_nTimecycHour = 8; static inline int m_nTimecycHour = 8;
static inline std::vector<std::string> m_WeatherNames static inline std::vector<std::string> m_WeatherNames
{ {
#ifdef GTASA #ifdef GTASA
"EXTRASUNNY LA", "SUNNY LA", "EXTRASUNNY SMOG LA", "SUNNY SMOG LA", "CLOUDY LA", "SUNNY SF", "EXTRASUNNY SF", "EXTRASUNNY LA", "SUNNY LA", "EXTRASUNNY SMOG LA", "SUNNY SMOG LA", "CLOUDY LA", "SUNNY SF", "EXTRASUNNY SF",
"CLOUDY SF", "RAINY SF", "FOGGY SF", "CLOUDY SF", "RAINY SF", "FOGGY SF",
"SUNNY VEGAS", "EXTRASUNNY VEGAS", "CLOUDY VEGAS", "EXTRASUNNY COUNTRYSIDE", "SUNNY COUNTRYSIDE", "SUNNY VEGAS", "EXTRASUNNY VEGAS", "CLOUDY VEGAS", "EXTRASUNNY COUNTRYSIDE", "SUNNY COUNTRYSIDE",
"CLOUDY COUNTRYSIDE", "RAINY COUNTRYSIDE", "CLOUDY COUNTRYSIDE", "RAINY COUNTRYSIDE",
"EXTRASUNNY DESERT", "SUNNY DESERT", "SANDSTORM DESERT", "UNDERWATER", "EXTRACOLOURS 1", "EXTRACOLOURS 2" "EXTRASUNNY DESERT", "SUNNY DESERT", "SANDSTORM DESERT", "UNDERWATER", "EXTRACOLOURS 1", "EXTRACOLOURS 2"
#else #else
"SUNNY", "CLOUDY", "RAINY", "FOGGY" "SUNNY", "CLOUDY", "RAINY", "FOGGY"
#ifdef GTAVC #ifdef GTAVC
,"EXTRA_SUNNY", "HURRICANE", "EXTRACOLORS" ,"EXTRA_SUNNY", "HURRICANE", "EXTRACOLORS"
#endif #endif
#endif #endif
}; };
static void GenerateTimecycFile(); static void GenerateTimecycFile();
static int CalcArrayIndex(); static int CalcArrayIndex();
template<typename T> template<typename T>
static bool TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEditFlags flags = 0); static bool TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEditFlags flags = 0);
template <typename T> template <typename T>
static bool TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiColorEditFlags flags = 0); static bool TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiColorEditFlags flags = 0);
template <typename T> template <typename T>
static void TimecycSlider(const char* label, T* data, int min, int max); static void TimecycSlider(const char* label, T* data, int min, int max);
public: public:
Visual(); Visual();
static void Draw(); static void Draw();
}; };

View File

@ -41,170 +41,170 @@
static std::string key_names[] static std::string key_names[]
{ {
"LMB", "LMB",
"RMB", "RMB",
"Cancel", "Cancel",
"MMB", "MMB",
"X1MB", "X1MB",
"X2MB", "X2MB",
"Unknown1", "Unknown1",
"Back", "Back",
"Tab", "Tab",
"Reserved1", "Reserved1",
"Reserved2", "Reserved2",
"Clear", "Clear",
"Enter", "Enter",
"Unknown2", "Unknown2",
"Unknown3", "Unknown3",
"Shift", "Shift",
"Ctrl", "Ctrl",
"Alt", "Alt",
"Pause", "Pause",
"Capslock", "Capslock",
"IME", "IME",
"IME2", "IME2",
"IME3", "IME3",
"Unknown4", "Unknown4",
"IME4", "IME4",
"Unknown5", "Unknown5",
"Esc", "Esc",
"IME5" "IME5"
"IME6", "IME6",
"IME7", "IME7",
"IME8", "IME8",
"IME9", "IME9",
"Space", "Space",
"Pup", "Pup",
"Pdown", "Pdown",
"End", "End",
"Home", "Home",
"Left", "Left",
"Up", "Up",
"Right", "Right",
"Down", "Down",
"Select", "Select",
"Print", "Print",
"Execute", "Execute",
"Print Screen", "Print Screen",
"INS", "INS",
"Del", "Del",
"Help", "Help",
"0", "0",
"1", "1",
"2", "2",
"3", "3",
"4", "4",
"5", "5",
"6", "6",
"7", "7",
"8", "8",
"9", "9",
"Unknown6", "Unknown6",
"Unknown7", "Unknown7",
"Unknown8", "Unknown8",
"Unknown9", "Unknown9",
"Unknown10", "Unknown10",
"Unknown11", "Unknown11",
"Unknown12", "Unknown12",
"A", "A",
"B", "B",
"C", "C",
"D", "D",
"E", "E",
"F", "F",
"G", "G",
"H", "H",
"I", "I",
"J", "J",
"K", "K",
"L", "L",
"M", "M",
"N", "N",
"O", "O",
"P", "P",
"Q", "Q",
"R", "R",
"S", "S",
"T", "T",
"U", "U",
"V", "V",
"W", "W",
"X", "X",
"Y", "Y",
"Z", "Z",
"LWin", "LWin",
"RWin", "RWin",
"Apps", "Apps",
"Unknown11", "Unknown11",
"Sleep", "Sleep",
"Numpad 0", "Numpad 0",
"Numpad 1", "Numpad 1",
"Numpad 2", "Numpad 2",
"Numpad 3", "Numpad 3",
"Numpad 4", "Numpad 4",
"Numpad 5", "Numpad 5",
"Numpad 6", "Numpad 6",
"Numpad 7", "Numpad 7",
"Numpad 8", "Numpad 8",
"Numpad 9", "Numpad 9",
"Multiply", "Multiply",
"Add", "Add",
"Separator", "Separator",
"Substract", "Substract",
"Decimal", "Decimal",
"Divide", "Divide",
"F1", "F1",
"F2", "F2",
"F3", "F3",
"F4", "F4",
"F5", "F5",
"F6", "F6",
"F7", "F7",
"F8", "F8",
"F9", "F9",
"F10", "F10",
"F11", "F11",
"F12", "F12",
"F13", "F13",
"F14", "F14",
"F15", "F15",
"F16", "F16",
"F17", "F17",
"F18", "F18",
"F19", "F19",
"F20", "F20",
"F21", "F21",
"F22", "F22",
"F23", "F23",
"F24", "F24",
"Unknown12", "Unknown12",
"Unknown13", "Unknown13",
"Unknown14", "Unknown14",
"Unknown15", "Unknown15",
"Unknown16", "Unknown16",
"Unknown17", "Unknown17",
"Unknown18", "Unknown18",
"Numlock", "Numlock",
"Scroll", "Scroll",
"Unknown19", "Unknown19",
"Unknown20", "Unknown20",
"Unknown21", "Unknown21",
"Unknown22", "Unknown22",
"Unknown23", "Unknown23",
"Unknown24", "Unknown24",
"Unknown25", "Unknown25",
"Unknown26", "Unknown26",
"Unknown27", "Unknown27",
"Unknown28", "Unknown28",
"Unknown29", "Unknown29",
"Unknown30", "Unknown30",
"Unknown31", "Unknown31",
"Unknown32", "Unknown32",
"Unknown33", "Unknown33",
"LShift", "LShift",
"RShift", "RShift",
"LCtrl", "LCtrl",
"RCtrl", "RCtrl",
"LMenu", "LMenu",
"RMenu" "RMenu"
}; };

View File

@ -2,402 +2,413 @@
#include "weapon.h" #include "weapon.h"
#include "ui.h" #include "ui.h"
#include "util.h" #include "util.h"
#include "ped.h"
#include "CWeaponInfo.h" #include "CWeaponInfo.h"
Weapon::Weapon() Weapon::Weapon()
{ {
Events::processScriptsEvent += [] Events::processScriptsEvent += []
{ {
CPlayerPed* player = FindPlayerPed(); CPlayerPed* player = FindPlayerPed();
#ifdef GTASA #ifdef GTASA
if (m_bAutoAim) if (m_bAutoAim)
{ {
if (CPad::NewMouseControllerState.X == 0 && CPad::NewMouseControllerState.Y == 0) if (CPad::NewMouseControllerState.X == 0 && CPad::NewMouseControllerState.Y == 0)
{ {
if (KeyPressed(2)) if (KeyPressed(2))
{ {
CCamera::m_bUseMouse3rdPerson = false; CCamera::m_bUseMouse3rdPerson = false;
} }
} }
else else
{ {
CCamera::m_bUseMouse3rdPerson = true; CCamera::m_bUseMouse3rdPerson = true;
} }
} }
#endif #endif
uchar slot = BY_GAME(player->m_nActiveWeaponSlot, player->m_nActiveWeaponSlot, player->m_nCurrentWeapon); uchar slot = BY_GAME(player->m_nActiveWeaponSlot, player->m_nActiveWeaponSlot, player->m_nCurrentWeapon);
if (m_nCurrentWeaponSlot != slot) if (m_nCurrentWeaponSlot != slot)
{ {
#ifdef GTA3 #ifdef GTA3
eWeaponType weaponType = player->m_aWeapons[slot].m_eWeaponType; eWeaponType weaponType = player->m_aWeapons[slot].m_eWeaponType;
#else #else
eWeaponType weaponType = player->m_aWeapons[slot].m_nType; eWeaponType weaponType = player->m_aWeapons[slot].m_nType;
#endif #endif
#ifdef GTASA #ifdef GTASA
CWeaponInfo* pWeaponInfo = CWeaponInfo::GetWeaponInfo(weaponType, player->GetWeaponSkill(weaponType)); CWeaponInfo* pWeaponInfo = CWeaponInfo::GetWeaponInfo(weaponType, player->GetWeaponSkill(weaponType));
#else // GTA3 & GTAVC #else
CWeaponInfo* pWeaponInfo = CWeaponInfo::GetWeaponInfo(weaponType); CWeaponInfo* pWeaponInfo = CWeaponInfo::GetWeaponInfo(weaponType);
if(m_bInfiniteAmmo) if(m_bInfiniteAmmo)
{ {
Command<Commands::SET_PLAYER_AMMO>(0, weaponType, 999999); Command<Commands::SET_PLAYER_AMMO>(0, weaponType, 999999);
} }
#endif #endif
if (m_bHugeDamage) if (m_bHugeDamage)
{ {
pWeaponInfo->m_nDamage = 1000; pWeaponInfo->m_nDamage = 1000;
} }
if (m_bLongRange) if (m_bLongRange)
{ {
#ifdef GTASA #ifdef GTASA
pWeaponInfo->m_fTargetRange = 1000.0f; pWeaponInfo->m_fTargetRange = 1000.0f;
pWeaponInfo->m_fWeaponRange = 1000.0f; pWeaponInfo->m_fWeaponRange = 1000.0f;
pWeaponInfo->m_fAccuracy = 1.0f; pWeaponInfo->m_fAccuracy = 1.0f;
pWeaponInfo->m_nFlags.bReload2Start = true; pWeaponInfo->m_nFlags.bReload2Start = true;
#else // GTA3 & GTAVC #else
pWeaponInfo->m_fRange = 1000.0f; pWeaponInfo->m_fRange = 1000.0f;
#endif #endif
} }
#ifdef GTASA #ifdef GTASA
if (m_bRapidFire && weaponType != WEAPON_FTHROWER && weaponType != WEAPON_MINIGUN) // mingun & flamethrower doesn't work with rapidfire if (m_bRapidFire && weaponType != WEAPON_FTHROWER && weaponType != WEAPON_MINIGUN) // mingun & flamethrower doesn't work with rapidfire
{ {
pWeaponInfo->m_nFlags.bContinuosFire = true; pWeaponInfo->m_nFlags.bContinuosFire = true;
} }
if (m_bDualWeild && (weaponType == WEAPON_PISTOL || weaponType == WEAPON_MICRO_UZI || weaponType == if (m_bDualWeild && (weaponType == WEAPON_PISTOL || weaponType == WEAPON_MICRO_UZI || weaponType ==
WEAPON_TEC9 || weaponType == WEAPON_SAWNOFF)) WEAPON_TEC9 || weaponType == WEAPON_SAWNOFF))
{ {
pWeaponInfo->m_nFlags.bTwinPistol = true; pWeaponInfo->m_nFlags.bTwinPistol = true;
} }
if (m_bMoveAim) if (m_bMoveAim)
{ {
pWeaponInfo->m_nFlags.bMoveAim = true; pWeaponInfo->m_nFlags.bMoveAim = true;
} }
if (m_bMoveFire) if (m_bMoveFire)
{ {
pWeaponInfo->m_nFlags.bMoveFire = true; pWeaponInfo->m_nFlags.bMoveFire = true;
} }
#endif #endif
m_nCurrentWeaponSlot = slot; m_nCurrentWeaponSlot = slot;
} }
}; };
} }
#ifdef GTASA #ifdef GTASA
void Weapon::SetGangWeapon(std::string& weapon_type) void Weapon::SetGangWeapon(std::string& weapon_type)
{ {
m_nGangWeaponList[m_nSelectedGang][m_nSelectedWeapon] = std::stoi(weapon_type); m_nGangWeaponList[m_nSelectedGang][m_nSelectedWeapon] = std::stoi(weapon_type);
CGangs::SetGangWeapons(m_nSelectedGang, m_nGangWeaponList[m_nSelectedGang][0], m_nGangWeaponList[m_nSelectedGang][1], CGangs::SetGangWeapons(m_nSelectedGang, m_nGangWeaponList[m_nSelectedGang][0], m_nGangWeaponList[m_nSelectedGang][1],
m_nGangWeaponList[m_nSelectedGang][2]); m_nGangWeaponList[m_nSelectedGang][2]);
} }
#else // GTA3 & GTAVC #else
// Implementation of SA opcode 0x555 // Implementation of SA opcode 0x555
static void ClearPlayerWeapon(eWeaponType weaponType) static void ClearPlayerWeapon(eWeaponType weaponType)
{ {
CPlayerPed *pPlayer = FindPlayerPed(); CPlayerPed *pPlayer = FindPlayerPed();
#ifdef GTA3 #ifdef GTA3
int weaponSlot = pPlayer->GetWeaponSlot(weaponType); int weaponSlot = pPlayer->GetWeaponSlot(weaponType);
#else #else
int weaponSlot = CWeaponInfo::GetWeaponInfo(weaponType)->m_WeaponSlot; int weaponSlot = CWeaponInfo::GetWeaponInfo(weaponType)->m_WeaponSlot;
#endif #endif
if ( weaponSlot != -1 ) if ( weaponSlot != -1 )
{ {
CWeapon *pWeapon = &pPlayer->m_aWeapons[weaponSlot]; CWeapon *pWeapon = &pPlayer->m_aWeapons[weaponSlot];
#ifdef GTA3 #ifdef GTA3
if (pWeapon->m_eWeaponType == weaponType) if (pWeapon->m_eWeaponType == weaponType)
{ {
if (pPlayer->m_nCurrentWeapon == weaponSlot) if (pPlayer->m_nCurrentWeapon == weaponSlot)
{ {
Command<Commands::SET_CURRENT_PLAYER_WEAPON>(0, WEAPONTYPE_UNARMED); Command<Commands::SET_CURRENT_PLAYER_WEAPON>(0, WEAPONTYPE_UNARMED);
} }
// This doesn't work for melee weapons aka bats, chainsaw etc // This doesn't work for melee weapons aka bats, chainsaw etc
pWeapon->m_eWeaponState = WEAPONSTATE_OUT_OF_AMMO; pWeapon->m_eWeaponState = WEAPONSTATE_OUT_OF_AMMO;
pWeapon->m_nAmmoTotal = 0; pWeapon->m_nAmmoTotal = 0;
pWeapon->m_nAmmoInClip = 0; pWeapon->m_nAmmoInClip = 0;
} }
#else #else
if (pWeapon->m_nType == weaponType) if (pWeapon->m_nType == weaponType)
{ {
if (pPlayer->m_nActiveWeaponSlot == weaponSlot) if (pPlayer->m_nActiveWeaponSlot == weaponSlot)
{ {
CWeaponInfo *pWeaponInfo = CWeaponInfo::GetWeaponInfo(WEAPONTYPE_UNARMED); CWeaponInfo *pWeaponInfo = CWeaponInfo::GetWeaponInfo(WEAPONTYPE_UNARMED);
pPlayer->SetCurrentWeapon(pWeaponInfo->m_WeaponSlot); pPlayer->SetCurrentWeapon(pWeaponInfo->m_WeaponSlot);
} }
pWeapon->Shutdown(); pWeapon->Shutdown();
} }
#endif #endif
} }
} }
// Implementation of opcode 0x605 (CLEO) // Implementation of opcode 0x605 (CLEO)
static eWeaponType GetWeaponTypeFromModel(int model) static eWeaponType GetWeaponTypeFromModel(int model)
{ {
eWeaponType weaponType = WEAPONTYPE_UNARMED; eWeaponType weaponType = WEAPONTYPE_UNARMED;
for (size_t i = 0; i < 37; i++) for (size_t i = 0; i < 37; i++)
{ {
int temp = CallAndReturn<int, BY_GAME(NULL, 0x4418B0, 0x430690)>(i); // int __cdecl CPickups::ModelForWeapon(int a1)
if (temp == model) int temp = CallAndReturn<int, BY_GAME(NULL, 0x4418B0, 0x430690)>(i); // int __cdecl CPickups::ModelForWeapon(int a1)
{
weaponType = (eWeaponType)i;
break;
}
}
return weaponType; if (temp == model)
{
weaponType = (eWeaponType)i;
break;
}
}
return weaponType;
} }
#endif #endif
#ifdef GTASA #ifdef GTASA
void Weapon::GiveWeaponToPlayer(std::string& weapon_type) void Weapon::GiveWeaponToPlayer(std::string& weapon_type)
{ {
CPlayerPed* player = FindPlayerPed(); CPlayerPed* player = FindPlayerPed();
int hplayer = CPools::GetPedRef(player); int hplayer = CPools::GetPedRef(player);
if (weapon_type == "-1") // Jetpack if (weapon_type == "-1") // Jetpack
{ {
Command<Commands::TASK_JETPACK>(hplayer); Command<Commands::TASK_JETPACK>(hplayer);
} }
else if (weapon_type == "-2") // CellPhone else if (weapon_type == "-2") // CellPhone
{ {
CStreaming::RequestModel(330, PRIORITY_REQUEST); CStreaming::RequestModel(330, PRIORITY_REQUEST);
CStreaming::LoadAllRequestedModels(false); CStreaming::LoadAllRequestedModels(false);
player->ClearWeaponTarget(); player->ClearWeaponTarget();
player->SetCurrentWeapon(WEAPON_UNARMED); player->SetCurrentWeapon(WEAPON_UNARMED);
player->AddWeaponModel(330); player->AddWeaponModel(330);
Command<Commands::MARK_MODEL_AS_NO_LONGER_NEEDED>(330); Command<Commands::MARK_MODEL_AS_NO_LONGER_NEEDED>(330);
} }
else else
{ {
int iweapon_type = std::stoi(weapon_type); int iweapon_type = std::stoi(weapon_type);
int model = NULL; int model = NULL;
Command<Commands::GET_WEAPONTYPE_MODEL>(iweapon_type, &model); Command<Commands::GET_WEAPONTYPE_MODEL>(iweapon_type, &model);
CStreaming::RequestModel(model, PRIORITY_REQUEST); CStreaming::RequestModel(model, PRIORITY_REQUEST);
if (model == 363) // remote bomb if (model == 363) // remote bomb
{ {
CStreaming::RequestModel(364, PRIORITY_REQUEST); // detonator CStreaming::RequestModel(364, PRIORITY_REQUEST); // detonator
} }
CStreaming::LoadAllRequestedModels(false); CStreaming::LoadAllRequestedModels(false);
Command<Commands::GIVE_WEAPON_TO_CHAR>(hplayer, iweapon_type, m_nAmmoCount); Command<Commands::GIVE_WEAPON_TO_CHAR>(hplayer, iweapon_type, m_nAmmoCount);
if (model == 363) // remote bomb if (model == 363) // remote bomb
{ {
Command<Commands::MARK_MODEL_AS_NO_LONGER_NEEDED>(364); // detonator Command<Commands::MARK_MODEL_AS_NO_LONGER_NEEDED>(364); // detonator
} }
Command<Commands::MARK_MODEL_AS_NO_LONGER_NEEDED>(model); Command<Commands::MARK_MODEL_AS_NO_LONGER_NEEDED>(model);
} }
} }
#else // GTA3 & GTAVC #else
void Weapon::GiveWeaponToPlayer(std::string& rootkey, std::string& name, std::string& model) void Weapon::GiveWeaponToPlayer(std::string& rootkey, std::string& name, std::string& model)
{ {
CPlayerPed* player = FindPlayerPed(); CPlayerPed* player = FindPlayerPed();
int hplayer = CPools::GetPedRef(player); int hplayer = CPools::GetPedRef(player);
int iModel = std::stoi(model); int iModel = std::stoi(model);
CStreaming::RequestModel(iModel, PRIORITY_REQUEST); CStreaming::RequestModel(iModel, PRIORITY_REQUEST);
CStreaming::LoadAllRequestedModels(false); CStreaming::LoadAllRequestedModels(false);
eWeaponType weaponType = GetWeaponTypeFromModel(iModel); eWeaponType weaponType = GetWeaponTypeFromModel(iModel);
Command<Commands::GIVE_WEAPON_TO_CHAR>(hplayer, weaponType, m_nAmmoCount); Command<Commands::GIVE_WEAPON_TO_CHAR>(hplayer, weaponType, m_nAmmoCount);
Command<Commands::MARK_MODEL_AS_NO_LONGER_NEEDED>(iModel); Command<Commands::MARK_MODEL_AS_NO_LONGER_NEEDED>(iModel);
#ifdef GTA3 #ifdef GTA3
Command<Commands::SET_CURRENT_PLAYER_WEAPON>(0, weaponType); Command<Commands::SET_CURRENT_PLAYER_WEAPON>(0, weaponType);
#endif #endif
} }
#endif #endif
void Weapon::Draw() void Weapon::Draw()
{ {
CPlayerPed* pPlayer = FindPlayerPed(); CPlayerPed* pPlayer = FindPlayerPed();
uint hplayer = CPools::GetPedRef(pPlayer); uint hplayer = CPools::GetPedRef(pPlayer);
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::Button("Drop weapon", Ui::GetSize(3))) if (ImGui::Button("Drop weapon", Ui::GetSize(3)))
{ {
float x, y, z; float x, y, z;
Command<Commands::GET_OFFSET_FROM_CHAR_IN_WORLD_COORDS>(hplayer, 0.0, 3.0, 0.0, &x, &y, &z); Command<Commands::GET_OFFSET_FROM_CHAR_IN_WORLD_COORDS>(hplayer, 0.0, 3.0, 0.0, &x, &y, &z);
#ifdef GTA3 #ifdef GTA3
eWeaponType weaponType = pPlayer->m_aWeapons[pPlayer->m_nCurrentWeapon].m_eWeaponType; eWeaponType weaponType = pPlayer->m_aWeapons[pPlayer->m_nCurrentWeapon].m_eWeaponType;
#else #else
eWeaponType weaponType = pPlayer->m_aWeapons[pPlayer->m_nActiveWeaponSlot].m_nType; eWeaponType weaponType = pPlayer->m_aWeapons[pPlayer->m_nActiveWeaponSlot].m_nType;
#endif #endif
if (weaponType) if (weaponType)
{ {
int model = 0, pickup = 0; int model = 0, pickup = 0;
#ifdef GTASA #ifdef GTASA
Command<Commands::GET_WEAPONTYPE_MODEL>(weaponType, &model); Command<Commands::GET_WEAPONTYPE_MODEL>(weaponType, &model);
#else // GTA3 & GTAVC #else
model = CallAndReturn<int, BY_GAME(NULL, 0x4418B0, 0x430690)>(weaponType); // int __cdecl CPickups::ModelForWeapon(int a1) model = CallAndReturn<int, BY_GAME(NULL, 0x4418B0, 0x430690)>(weaponType); // int __cdecl CPickups::ModelForWeapon(int a1)
#endif #endif
Command<Commands::CREATE_PICKUP_WITH_AMMO>(model, 3, 999, x, y, z, &pickup); Command<Commands::CREATE_PICKUP_WITH_AMMO>(model, 3, 999, x, y, z, &pickup);
#ifdef GTASA #ifdef GTASA
Command<Commands::REMOVE_WEAPON_FROM_CHAR>(hplayer, weaponType); Command<Commands::REMOVE_WEAPON_FROM_CHAR>(hplayer, weaponType);
#else // GTA3 & GTAVC #else
ClearPlayerWeapon(weaponType); ClearPlayerWeapon(weaponType);
#endif #endif
} }
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Remove all", Ui::GetSize(3))) if (ImGui::Button("Remove all", Ui::GetSize(3)))
{ {
pPlayer->ClearWeapons(); pPlayer->ClearWeapons();
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Remove current", Ui::GetSize(3))) if (ImGui::Button("Remove current", Ui::GetSize(3)))
{ {
#ifdef GTASA #ifdef GTASA
Command<Commands::REMOVE_WEAPON_FROM_CHAR>(hplayer, pPlayer->m_aWeapons[pPlayer->m_nActiveWeaponSlot].m_nType); Command<Commands::REMOVE_WEAPON_FROM_CHAR>(hplayer, pPlayer->m_aWeapons[pPlayer->m_nActiveWeaponSlot].m_nType);
#elif GTAVC #elif GTAVC
ClearPlayerWeapon(pPlayer->m_aWeapons[pPlayer->m_nActiveWeaponSlot].m_nType); ClearPlayerWeapon(pPlayer->m_aWeapons[pPlayer->m_nActiveWeaponSlot].m_nType);
#else // GTA3
ClearPlayerWeapon(pPlayer->m_aWeapons[pPlayer->m_nCurrentWeapon].m_eWeaponType);
#endif
}
ImGui::Spacing();
if (ImGui::BeginTabBar("Ped", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
{
if (ImGui::BeginTabItem("Checkboxes"))
{
ImGui::Spacing();
ImGui::BeginChild("CheckboxesChild");
ImGui::Spacing();
ImGui::SameLine();
ImGui::Text("Info");
Ui::ShowTooltip("Weapon tweaks apply globally\nto every ped weapon type");
ImGui::Columns(2, 0, false);
#ifdef GTASA
Ui::CheckboxWithHint("Fast aim", &m_bAutoAim, "Enables aim assist on keyboard\n\nQ = left E = right\n\nPress Q and E to switch targets.\nMoving mouse removes the target!");
if (Ui::CheckboxWithHint("Dual wield", &m_bDualWeild,
"Dual wield pistol, shawoff, uzi, tec9\n(Other weapons don't work)"))
{
if (!m_bDualWeild)
{
CWeaponInfo::LoadWeaponData();
}
}
#endif
if (Ui::CheckboxWithHint("Huge damage", &m_bHugeDamage, "Also enable 'Long range' if weapon range is short"))
{
if (!m_bHugeDamage)
{
CWeaponInfo::LoadWeaponData();
}
}
if (Ui::CheckboxWithHint("Fast reload", &m_bFastReload))
{
Command<Commands::SET_PLAYER_FAST_RELOAD>(hplayer, m_bFastReload);
}
#ifdef GTASA
Ui::CheckboxAddress("Infinite ammo", 0x969178);
ImGui::NextColumn();
#else #else
ImGui::NextColumn(); ClearPlayerWeapon(pPlayer->m_aWeapons[pPlayer->m_nCurrentWeapon].m_eWeaponType);
Ui::CheckboxWithHint("Infinite ammo", &m_bInfiniteAmmo);
#endif #endif
if (Ui::CheckboxWithHint("Long range", &m_bLongRange)) }
{ ImGui::Spacing();
if (!m_bLongRange)
{
CWeaponInfo::LoadWeaponData();
}
}
#ifdef GTASA
if (Ui::CheckboxWithHint("Move when aiming", &m_bMoveAim))
{
if (!m_bMoveAim)
{
CWeaponInfo::LoadWeaponData();
}
}
if (Ui::CheckboxWithHint("Move when firing", &m_bMoveFire))
{
if (!m_bMoveFire)
{
CWeaponInfo::LoadWeaponData();
}
}
if (Ui::CheckboxWithHint("Rapid fire", &m_bRapidFire))
{
if (!m_bRapidFire)
{
CWeaponInfo::LoadWeaponData();
}
}
#endif
ImGui::Columns(1, 0, false);
ImGui::EndChild();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Spawn"))
{
ImGui::Spacing();
if (ImGui::InputInt("Ammo", &m_nAmmoCount))
{
m_nAmmoCount = (m_nAmmoCount < 0) ? 0 : m_nAmmoCount;
m_nAmmoCount = (m_nAmmoCount > 99999) ? 99999 : m_nAmmoCount;
}
#ifdef GTASA
Ui::DrawImages(m_WeaponData, GiveWeaponToPlayer, nullptr,
[](std::string str) { return m_WeaponData.m_pJson->m_Data[str].get<std::string>(); },
[](std::string str) { return str != "0"; /*Unarmed*/ }
);
#else // GTA3 & GTAVC
Ui::DrawJSON(m_WeaponData, GiveWeaponToPlayer, nullptr);
#endif
ImGui::EndTabItem();
}
#ifdef GTASA
if (ImGui::BeginTabItem("Gang weapon editor"))
{
ImGui::Spacing();
Ui::ListBox("Select gang", Ped::m_GangNames, m_nSelectedGang);
ImGui::Columns(3, 0, false); if (ImGui::BeginTabBar("Ped", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
ImGui::RadioButton("Weap 1", &m_nSelectedWeapon, 0); {
ImGui::NextColumn(); if (ImGui::BeginTabItem("Checkboxes"))
ImGui::RadioButton("Weap 2", &m_nSelectedWeapon, 1); {
ImGui::NextColumn(); ImGui::Spacing();
ImGui::RadioButton("Weap 3", &m_nSelectedWeapon, 2); ImGui::BeginChild("CheckboxesChild");
ImGui::Columns(1); ImGui::Spacing();
ImGui::SameLine();
ImGui::Spacing(); ImGui::Text("Info");
ImGui::Text("Current weapon: %s", Ui::ShowTooltip("Weapon tweaks apply globally\nto every ped weapon type");
m_WeaponData.m_pJson->m_Data[std::to_string(m_nGangWeaponList[m_nSelectedGang][m_nSelectedWeapon])].get< ImGui::Columns(2, 0, false);
std::string>().c_str()); #ifdef GTASA
ImGui::Spacing(); Ui::CheckboxWithHint("Fast aim", &m_bAutoAim, "Enables aim assist on keyboard\n\nQ = left E = right\n\nPress Q and E to switch targets.\nMoving mouse removes the target!");
Ui::DrawImages(m_WeaponData, SetGangWeapon, nullptr, if (Ui::CheckboxWithHint("Dual wield", &m_bDualWeild,
[](std::string str) { return m_WeaponData.m_pJson->m_Data[str].get<std::string>(); }, "Dual wield pistol, shawoff, uzi, tec9\n(Other weapons don't work)"))
[](std::string str) { return str != "-1"; /*Jetpack*/ } {
); if (!m_bDualWeild)
ImGui::EndTabItem(); {
} CWeaponInfo::LoadWeaponData();
}
}
#endif #endif
ImGui::EndTabBar(); if (Ui::CheckboxWithHint("Huge damage", &m_bHugeDamage, "Also enable 'Long range' if weapon range is short"))
} {
if (!m_bHugeDamage)
{
CWeaponInfo::LoadWeaponData();
}
}
if (Ui::CheckboxWithHint("Fast reload", &m_bFastReload))
{
Command<Commands::SET_PLAYER_FAST_RELOAD>(hplayer, m_bFastReload);
}
#ifdef GTASA
Ui::CheckboxAddress("Infinite ammo", 0x969178);
ImGui::NextColumn();
#else
ImGui::NextColumn();
Ui::CheckboxWithHint("Infinite ammo", &m_bInfiniteAmmo);
#endif
if (Ui::CheckboxWithHint("Long range", &m_bLongRange))
{
if (!m_bLongRange)
{
CWeaponInfo::LoadWeaponData();
}
}
#ifdef GTASA
if (Ui::CheckboxWithHint("Move when aiming", &m_bMoveAim))
{
if (!m_bMoveAim)
{
CWeaponInfo::LoadWeaponData();
}
}
if (Ui::CheckboxWithHint("Move when firing", &m_bMoveFire))
{
if (!m_bMoveFire)
{
CWeaponInfo::LoadWeaponData();
}
}
if (Ui::CheckboxWithHint("Rapid fire", &m_bRapidFire))
{
if (!m_bRapidFire)
{
CWeaponInfo::LoadWeaponData();
}
}
#endif
ImGui::Columns(1, 0, false);
ImGui::EndChild();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Spawn"))
{
ImGui::Spacing();
if (ImGui::InputInt("Ammo", &m_nAmmoCount))
{
m_nAmmoCount = (m_nAmmoCount < 0) ? 0 : m_nAmmoCount;
m_nAmmoCount = (m_nAmmoCount > 99999) ? 99999 : m_nAmmoCount;
}
#ifdef GTASA
Ui::DrawImages(m_WeaponData, GiveWeaponToPlayer, nullptr,
[](std::string str)
{
return m_WeaponData.m_pJson->m_Data[str].get<std::string>();
},
[](std::string str)
{
return str != "0"; /*Unarmed*/
}
);
#else
Ui::DrawJSON(m_WeaponData, GiveWeaponToPlayer, nullptr);
#endif
ImGui::EndTabItem();
}
#ifdef GTASA
if (ImGui::BeginTabItem("Gang weapon editor"))
{
ImGui::Spacing();
Ui::ListBox("Select gang", m_GangList, m_nSelectedGang);
ImGui::Columns(3, 0, false);
ImGui::RadioButton("Weap 1", &m_nSelectedWeapon, 0);
ImGui::NextColumn();
ImGui::RadioButton("Weap 2", &m_nSelectedWeapon, 1);
ImGui::NextColumn();
ImGui::RadioButton("Weap 3", &m_nSelectedWeapon, 2);
ImGui::Columns(1);
ImGui::Spacing();
ImGui::Text("Current weapon: %s",
m_WeaponData.m_pJson->m_Data[std::to_string(m_nGangWeaponList[m_nSelectedGang][m_nSelectedWeapon])].get<
std::string>().c_str());
ImGui::Spacing();
Ui::DrawImages(m_WeaponData, SetGangWeapon, nullptr,
[](std::string str)
{
return m_WeaponData.m_pJson->m_Data[str].get<std::string>();
},
[](std::string str)
{
return str != "-1"; /*Jetpack*/
}
);
ImGui::EndTabItem();
}
#endif
ImGui::EndTabBar();
}
} }

View File

@ -1,49 +1,55 @@
#pragma once #pragma once
#include "CWeapon.h" #include "pch.h"
class Weapon class Weapon
{ {
public: public:
#ifdef GTASA #ifdef GTASA
static inline ResourceStore m_WeaponData{ "weapon", eResourceType::TYPE_BOTH, ImVec2(65, 65) }; static inline ResourceStore m_WeaponData { "weapon", eResourceType::TYPE_BOTH, ImVec2(65, 65) };
static inline bool m_bAutoAim; static inline bool m_bAutoAim;
static inline bool m_bRapidFire; static inline bool m_bRapidFire;
static inline bool m_bDualWeild; static inline bool m_bDualWeild;
static inline bool m_bMoveAim; static inline bool m_bMoveAim;
static inline bool m_bMoveFire; static inline bool m_bMoveFire;
static inline int m_nSelectedGang; static inline int m_nSelectedGang;
static inline int m_nGangWeaponList[10][3] = static inline int m_nGangWeaponList[10][3] =
{ {
{WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Ballas {WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Ballas
{WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Grove {WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Grove
{WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Vagos {WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Vagos
{WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // SF Rifa {WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // SF Rifa
{WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Da Nang Boys {WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Da Nang Boys
{WEAPON_DESERT_EAGLE, WEAPON_UNARMED, WEAPON_UNARMED}, // Mafia {WEAPON_DESERT_EAGLE, WEAPON_UNARMED, WEAPON_UNARMED}, // Mafia
{WEAPON_PISTOL, WEAPON_AK47, WEAPON_UNARMED}, // Triads {WEAPON_PISTOL, WEAPON_AK47, WEAPON_UNARMED}, // Triads
{WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // VLA {WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // VLA
{WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // Gang 9 {WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // Gang 9
{WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // Gang 10 {WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // Gang 10
}; };
#else // GTA3 & GTAVC
static inline ResourceStore m_WeaponData{ "weapon", eResourceType::TYPE_TEXT }; static inline std::vector<std::string> m_GangList =
static inline bool m_bInfiniteAmmo; {
"Ballas", "Grove street families", "Los santos vagos", "San fierro rifa",
"Da nang boys", "Mafia", "Mountain cloud triad", "Varrio los aztecas", "Gang9", "Gang10"
};
#else
static inline ResourceStore m_WeaponData { "weapon", eResourceType::TYPE_TEXT };
static inline bool m_bInfiniteAmmo;
#endif #endif
static inline bool m_bFastReload; static inline bool m_bFastReload;
static inline bool m_bHugeDamage; static inline bool m_bHugeDamage;
static inline bool m_bLongRange; static inline bool m_bLongRange;
static inline int m_nAmmoCount = 99999; static inline int m_nAmmoCount = 99999;
static inline uchar m_nCurrentWeaponSlot = -1; static inline uchar m_nCurrentWeaponSlot = -1;
static inline int m_nSelectedWeapon; static inline int m_nSelectedWeapon;
Weapon(); Weapon();
static void Draw(); static void Draw();
#ifdef GTASA #ifdef GTASA
static void GiveWeaponToPlayer(std::string& weapon_type); static void GiveWeaponToPlayer(std::string& weapon_type);
static void SetGangWeapon(std::string& weapon_type); static void SetGangWeapon(std::string& weapon_type);
#else // GTA3 & GTAVC #else
static void GiveWeaponToPlayer(std::string& rootkey, std::string& model, std::string& name); static void GiveWeaponToPlayer(std::string& rootkey, std::string& model, std::string& name);
#endif #endif
}; };

BIN
tools/AStyle.exe Normal file

Binary file not shown.

2
tools/FormatCode.bat Normal file
View File

@ -0,0 +1,2 @@
start tools/AStyle.exe --style=allman -n --recursive src/*.cpp src/*.h