From 757d686b59af5f981670bf0b8957caf79803c0c0 Mon Sep 17 00:00:00 2001 From: Arthur <121949966+ShinyWasabi@users.noreply.github.com> Date: Mon, 2 Jun 2025 09:57:06 +0300 Subject: [PATCH 1/2] feat(weapons): Ammu-Nation Tab & Open Gun Locker (#355) --- src/game/features/self/GiveAllWeapons.cpp | 2 +- src/game/features/self/GiveMaxAmmo.cpp | 2 +- src/game/features/self/OpenGunLocker.cpp | 86 ++++++++ src/game/features/self/OpenGunLocker.hpp | 35 +++ src/game/frontend/submenus/Self.cpp | 21 +- src/game/frontend/submenus/Self/Weapons.cpp | 152 +++++++++++++ src/game/frontend/submenus/Self/Weapons.hpp | 8 + src/game/gta/data/Weapons.hpp | 232 ++++++++++---------- src/main.cpp | 2 + 9 files changed, 404 insertions(+), 136 deletions(-) create mode 100644 src/game/features/self/OpenGunLocker.cpp create mode 100644 src/game/features/self/OpenGunLocker.hpp create mode 100644 src/game/frontend/submenus/Self/Weapons.cpp create mode 100644 src/game/frontend/submenus/Self/Weapons.hpp diff --git a/src/game/features/self/GiveAllWeapons.cpp b/src/game/features/self/GiveAllWeapons.cpp index 807efcf..b1fc82f 100644 --- a/src/game/features/self/GiveAllWeapons.cpp +++ b/src/game/features/self/GiveAllWeapons.cpp @@ -10,7 +10,7 @@ namespace YimMenu::Features virtual void OnCall() override { - for (auto weapon : Data::Weapons) + for (auto weapon : g_WeaponHashes) Self::GetPed().GiveWeapon(weapon); } }; diff --git a/src/game/features/self/GiveMaxAmmo.cpp b/src/game/features/self/GiveMaxAmmo.cpp index 7f9587f..0d51134 100644 --- a/src/game/features/self/GiveMaxAmmo.cpp +++ b/src/game/features/self/GiveMaxAmmo.cpp @@ -10,7 +10,7 @@ namespace YimMenu::Features virtual void OnCall() override { - for (auto weapon : Data::Weapons) + for (auto weapon : g_WeaponHashes) { Self::GetPed().SetMaxAmmoForWeapon(weapon); } diff --git a/src/game/features/self/OpenGunLocker.cpp b/src/game/features/self/OpenGunLocker.cpp new file mode 100644 index 0000000..61e3d08 --- /dev/null +++ b/src/game/features/self/OpenGunLocker.cpp @@ -0,0 +1,86 @@ +#include "OpenGunLocker.hpp" +#include "core/commands/Command.hpp" +#include "core/backend/ScriptMgr.hpp" +#include "core/frontend/Notifications.hpp" +#include "game/backend/Self.hpp" +#include "game/backend/ScriptPatches.hpp" +#include "game/gta/Scripts.hpp" +#include "game/gta/ScriptFunction.hpp" +#include "game/gta/ScriptLocal.hpp" +#include "game/pointers/Pointers.hpp" +#include "types/script/scrThread.hpp" +#include "types/script/globals/GlobalPlayerBD.hpp" + +namespace YimMenu::Features +{ + static ScriptPatch skipGunLockerMenuChecksPatch{}; + + void OpenGunLocker::RunScriptImpl() + { + while (g_Running) + { + ScriptMgr::Yield(); + + if (!m_ShouldRunScript) + continue; + + if (!m_Thread) + { + int id = Scripts::StartScript("AM_MP_AUTO_SHOP"_J, eStackSizes::WAREHOUSE); + m_Thread = Scripts::FindScriptThreadByID(id); + if (m_Thread) + { + m_Thread->m_Context.m_State = rage::scrThread::State::PAUSED; + if (!skipGunLockerMenuChecksPatch) + { + skipGunLockerMenuChecksPatch = ScriptPatches::AddPatch("AM_MP_AUTO_SHOP"_J, ScriptPointer("SkipGunLockerMenuChecksPatch", "56 08 01 2C 01 03 A5"), {0x55, 0xB1, 0x00}); + } + skipGunLockerMenuChecksPatch->Enable(); + } + else + { + m_ShouldRunScript = false; + continue; + } + } + + static ScriptFunction runGunLockerMenu("AM_MP_AUTO_SHOP"_J, ScriptPointer("RunGunLockerMenu", "2D 06 08 00 00 38 03 5D ? ? ? 57 03 00")); + auto gunLockerData = ScriptLocal(m_Thread, 290).At(569); + + int unused; + runGunLockerMenu.Call(gunLockerData.As(), &unused, eSimpleInteriorIndex::SIMPLE_INTERIOR_AUTO_SHOP_MISSION_ROW, Self::GetPlayer().GetId(), false, true); + if (*gunLockerData.At(20).As() == 0) + { + skipGunLockerMenuChecksPatch->Disable(); + m_Thread->Kill(); + m_Thread->m_Context.m_State = rage::scrThread::State::KILLED; + m_Thread = nullptr; + m_ShouldRunScript = false; + } + } + } + + class _OpenGunLocker : public Command + { + using Command::Command; + + virtual void OnCall() override + { + if (!*Pointers.IsSessionStarted) + { + Notifications::Show("Open Gun Locker", "Please join GTA Online.", NotificationType::Error); + return; + } + + if (GlobalPlayerBD::Get()->Entries[Self::GetPlayer().GetId()].SimpleInteriorData.Index != eSimpleInteriorIndex::SIMPLE_INTERIOR_INVALID) + { + Notifications::Show("Open Gun Locker", "Cannot open gun locker while in an interior.", NotificationType::Error); + return; + } + + OpenGunLocker::SetShouldRunScript(true); + } + }; + + static _OpenGunLocker __OpenGunLocker{"opengunlocker", "Open Gun Locker", "Allows you to access gun locker remotely."}; +} \ No newline at end of file diff --git a/src/game/features/self/OpenGunLocker.hpp b/src/game/features/self/OpenGunLocker.hpp new file mode 100644 index 0000000..553eea6 --- /dev/null +++ b/src/game/features/self/OpenGunLocker.hpp @@ -0,0 +1,35 @@ +#pragma once + +namespace rage +{ + class scrThread; +} + +namespace YimMenu::Features +{ + class OpenGunLocker + { + static OpenGunLocker& GetInstance() + { + static OpenGunLocker instance; + return instance; + } + + rage::scrThread* m_Thread = nullptr; + bool m_ShouldRunScript = false; + + void RunScriptImpl(); + + public: + + static void RunScript() + { + GetInstance().RunScriptImpl(); + } + + static void SetShouldRunScript(bool run) + { + GetInstance().m_ShouldRunScript = run; + } + }; +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Self.cpp b/src/game/frontend/submenus/Self.cpp index c2fd0d9..b8b94e3 100644 --- a/src/game/frontend/submenus/Self.cpp +++ b/src/game/frontend/submenus/Self.cpp @@ -3,6 +3,7 @@ #include "core/util/Joaat.hpp" #include "game/frontend/items/Items.hpp" #include "OutfitEditor.hpp" +#include "game/frontend/submenus/Self/Weapons.hpp" namespace YimMenu::Submenus { @@ -61,25 +62,7 @@ namespace YimMenu::Submenus main->AddItem(movementGroup); AddCategory(std::move(main)); - auto weapons = std::make_shared("Weapons"); - auto weaponsGlobalsGroup = std::make_shared("Globals"); - auto weaponsAimbotGroup = std::make_shared("Aimbot", 1); - - weaponsGlobalsGroup->AddItem(std::make_shared("infiniteammo"_J)); - weaponsGlobalsGroup->AddItem(std::make_shared("infiniteclip"_J)); - weaponsGlobalsGroup->AddItem(std::make_shared("rapidfire"_J)); - weaponsGlobalsGroup->AddItem(std::make_shared("infiniteparachutes"_J)); - weaponsGlobalsGroup->AddItem(std::make_shared("ExplosiveAmmo"_J)); - weaponsGlobalsGroup->AddItem(std::make_shared("giveallweapons"_J)); - weaponsGlobalsGroup->AddItem(std::make_shared("givemaxammo"_J)); - - weaponsAimbotGroup->AddItem(std::make_shared("aimbot"_J)); - weaponsAimbotGroup->AddItem(std::make_shared("aimbot"_J, std::make_shared("aimbotaimforhead"_J))); - weaponsAimbotGroup->AddItem(std::make_shared("aimbot"_J, std::make_shared("aimbottargetdrivers"_J))); - - weapons->AddItem(weaponsGlobalsGroup); - weapons->AddItem(weaponsAimbotGroup); - AddCategory(std::move(weapons)); + AddCategory(BuildWeaponsMenu()); auto outfitEditorCategory = YimMenu::CreateOutfitsMenu(); AddCategory(std::move(outfitEditorCategory)); diff --git a/src/game/frontend/submenus/Self/Weapons.cpp b/src/game/frontend/submenus/Self/Weapons.cpp new file mode 100644 index 0000000..02fabc6 --- /dev/null +++ b/src/game/frontend/submenus/Self/Weapons.cpp @@ -0,0 +1,152 @@ +#include "Weapons.hpp" +#include "core/backend/FiberPool.hpp" +#include "game/backend/Self.hpp" +#include "game/gta/data/Weapons.hpp" +#include "game/gta/Natives.hpp" +#include "game/gta/Scripts.hpp" +#include "game/gta/ScriptFunction.hpp" +#include "types/script/scrThread.hpp" + +namespace YimMenu::Submenus +{ + struct WeaponDisplay + { + std::string name; + std::string desc; + joaat_t hash; + }; + + static void RenderAmmuNationMenu() + { + static std::vector weaponDisplays; + static std::string selectedWeapon{"Select"}; + static joaat_t selectedWeaponHash{}; + static char searchWeapon[64]; + + static bool init = [] { + FiberPool::Push([] { + if (auto id = Scripts::StartScript("mp_weapons"_J)) + { + if (auto thread = Scripts::FindScriptThreadByID(id)) + { + thread->m_Context.m_State = rage::scrThread::State::PAUSED; + + for (const auto& weap : g_WeaponHashes) + { + static ScriptFunction getWeaponNameLabel("mp_weapons"_J, ScriptPointer("GetWeaponNameLabel", "2D 02 2B 00 00")); + static ScriptFunction getWeaponDescLabel("mp_weapons"_J, ScriptPointer("GetWeaponDescLabel", "2D 02 A0 00 00")); + + std::string nameGxt = getWeaponNameLabel.Call(weap, false); // second arg is for uppercase + std::string descGxt = getWeaponDescLabel.Call(weap, false); + + std::string nameDisplay = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(nameGxt.c_str()); + std::string descDisplay = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(descGxt.c_str()); + + weaponDisplays.push_back({((nameDisplay.empty() || nameDisplay == "NULL" || nameDisplay == "Invalid") ? "" : nameDisplay), ((descDisplay.empty() || descDisplay == "NULL" || descDisplay == "Invalid") ? "" : descDisplay), weap}); + } + + thread->Kill(); + thread->m_Context.m_State = rage::scrThread::State::KILLED; + } + } + }); + return true; + }(); + + if (weaponDisplays.empty()) + return ImGui::TextDisabled("Loading..."); + + ImGui::BeginCombo("Weapons", selectedWeapon.c_str()); + if (ImGui::IsItemActive() && !ImGui::IsPopupOpen("##weaponspopup")) + { + ImGui::OpenPopup("##weaponspopup"); + memset(searchWeapon, 0, sizeof(searchWeapon)); + } + if (ImGui::BeginPopup("##weaponspopup", ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove)) + { + ImGui::Text("Search:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(250.f); + ImGui::InputText("##searchweapon", searchWeapon, sizeof(searchWeapon)); + + std::string searchLower = searchWeapon; + std::transform(searchLower.begin(), searchLower.end(), searchLower.begin(), ::tolower); + for (const auto& weap : weaponDisplays) + { + if (weap.name.empty()) + continue; + + std::string weaponLower = weap.name; + std::transform(weaponLower.begin(), weaponLower.end(), weaponLower.begin(), ::tolower); + + if (weaponLower.find(searchLower) != std::string::npos) + { + ImGui::PushID(weap.hash); + if (ImGui::Selectable(weap.name.c_str())) + { + selectedWeapon = weap.name; + selectedWeaponHash = weap.hash; + } + ImGui::PopID(); + if (ImGui::IsItemHovered() && !weap.desc.empty()) + { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35); + ImGui::TextUnformatted(weap.desc.c_str()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + } + } + ImGui::EndPopup(); + } + + if (ImGui::Button("Give Weapon")) + { + FiberPool::Push([] { + Self::GetPed().GiveWeapon(selectedWeaponHash, true); + }); + } + ImGui::SameLine(); + if (ImGui::Button("Remove Weapon")) + { + FiberPool::Push([] { + Self::GetPed().RemoveWeapon(selectedWeaponHash); + }); + } + } + + std::shared_ptr BuildWeaponsMenu() + { + auto weapons = std::make_shared("Weapons"); + + auto weaponsGlobalsGroup = std::make_shared("Globals"); + auto weaponsToolsGroup = std::make_shared("Tools", 1); + auto weaponsAmmuNationGroup = std::make_shared("Ammu-Nation"); + auto weaponsAimbotGroup = std::make_shared("Aimbot", 1); + + weaponsGlobalsGroup->AddItem(std::make_shared("infiniteammo"_J)); + weaponsGlobalsGroup->AddItem(std::make_shared("infiniteclip"_J)); + weaponsGlobalsGroup->AddItem(std::make_shared("rapidfire"_J)); + weaponsGlobalsGroup->AddItem(std::make_shared("infiniteparachutes"_J)); + weaponsGlobalsGroup->AddItem(std::make_shared("ExplosiveAmmo"_J)); + + weaponsToolsGroup->AddItem(std::make_shared("giveallweapons"_J)); + weaponsToolsGroup->AddItem(std::make_shared("givemaxammo"_J)); + weaponsToolsGroup->AddItem(std::make_shared("opengunlocker"_J)); + + weaponsAmmuNationGroup->AddItem(std::make_shared([] { + RenderAmmuNationMenu(); + })); + + weaponsAimbotGroup->AddItem(std::make_shared("aimbot"_J)); + weaponsAimbotGroup->AddItem(std::make_shared("aimbot"_J, std::make_shared("aimbotaimforhead"_J))); + weaponsAimbotGroup->AddItem(std::make_shared("aimbot"_J, std::make_shared("aimbottargetdrivers"_J))); + + weapons->AddItem(weaponsGlobalsGroup); + weapons->AddItem(weaponsToolsGroup); + weapons->AddItem(weaponsAmmuNationGroup); + weapons->AddItem(weaponsAimbotGroup); + return weapons; + } +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Self/Weapons.hpp b/src/game/frontend/submenus/Self/Weapons.hpp new file mode 100644 index 0000000..c30c44c --- /dev/null +++ b/src/game/frontend/submenus/Self/Weapons.hpp @@ -0,0 +1,8 @@ +#pragma once +#include "core/frontend/manager/Category.hpp" +#include "game/frontend/items/Items.hpp" + +namespace YimMenu::Submenus +{ + std::shared_ptr BuildWeaponsMenu(); +} \ No newline at end of file diff --git a/src/game/gta/data/Weapons.hpp b/src/game/gta/data/Weapons.hpp index 687b81a..8e48425 100644 --- a/src/game/gta/data/Weapons.hpp +++ b/src/game/gta/data/Weapons.hpp @@ -1,119 +1,121 @@ #pragma once #include "core/util/Joaat.hpp" -namespace Data +namespace YimMenu { - static inline constexpr auto Weapons = std::to_array({ - "weapon_dagger"_J, - "weapon_bat"_J, - "weapon_bottle"_J, - "weapon_crowbar"_J, - "weapon_unarmed"_J, - "weapon_flashlight"_J, - "weapon_golfclub"_J, - "weapon_hammer"_J, - "weapon_hatchet"_J, - "weapon_knuckle"_J, - "weapon_knife"_J, - "weapon_machete"_J, - "weapon_switchblade"_J, - "weapon_nightstick"_J, - "weapon_wrench"_J, - "weapon_battleaxe"_J, - "weapon_poolcue"_J, - "weapon_stone_hatchet"_J, - "weapon_pistol"_J, - "weapon_pistol_mk2"_J, - "weapon_combatpistol"_J, - "weapon_appistol"_J, - "weapon_stungun"_J, - "weapon_pistol50"_J, - "weapon_snspistol"_J, - "weapon_snspistol_mk2"_J, - "weapon_heavypistol"_J, - "weapon_vintagepistol"_J, - "weapon_flaregun"_J, - "weapon_marksmanpistol"_J, - "weapon_revolver"_J, - "weapon_revolver_mk2"_J, - "weapon_doubleaction"_J, - "weapon_raypistol"_J, - "weapon_ceramicpistol"_J, - "weapon_navyrevolver"_J, - "weapon_microsmg"_J, - "weapon_smg"_J, - "weapon_smg_mk2"_J, - "weapon_assaultsmg"_J, - "weapon_combatpdw"_J, - "weapon_machinepistol"_J, - "weapon_minismg"_J, - "weapon_raycarbine"_J, - "weapon_pumpshotgun"_J, - "weapon_pumpshotgun_mk2"_J, - "weapon_sawnoffshotgun"_J, - "weapon_assaultshotgun"_J, - "weapon_bullpupshotgun"_J, - "weapon_musket"_J, - "weapon_heavyshotgun"_J, - "weapon_dbshotgun"_J, - "weapon_autoshotgun"_J, - "weapon_assaultrifle"_J, - "weapon_assaultrifle_mk2"_J, - "weapon_carbinerifle"_J, - "weapon_carbinerifle_mk2"_J, - "weapon_advancedrifle"_J, - "weapon_specialcarbine"_J, - "weapon_specialcarbine_mk2"_J, - "weapon_bullpuprifle"_J, - "weapon_bullpuprifle_mk2"_J, - "weapon_compactrifle"_J, - "weapon_mg"_J, - "weapon_combatmg"_J, - "weapon_combatmg_mk2"_J, - "weapon_gusenberg"_J, - "weapon_sniperrifle"_J, - "weapon_heavysniper"_J, - "weapon_heavysniper_mk2"_J, - "weapon_marksmanrifle"_J, - "weapon_marksmanrifle_mk2"_J, - "weapon_rpg"_J, - "weapon_grenadelauncher"_J, - "weapon_grenadelauncher_smoke"_J, - "weapon_minigun"_J, - "weapon_firework"_J, - "weapon_railgun"_J, - "weapon_hominglauncher"_J, - "weapon_compactlauncher"_J, - "weapon_rayminigun"_J, - "weapon_grenade"_J, - "weapon_bzgas"_J, - "weapon_smokegrenade"_J, - "weapon_flare"_J, - "weapon_molotov"_J, - "weapon_stickybomb"_J, - "weapon_proxmine"_J, - "weapon_snowball"_J, - "weapon_pipebomb"_J, - "weapon_ball"_J, - "weapon_petrolcan"_J, - "weapon_fireextinguisher"_J, - "weapon_hazardcan"_J, - "weapon_militaryrifle"_J, - "weapon_combatshotgun"_J, - "weapon_gadgetpistol"_J, - "WEAPON_SNOWLAUNCHER"_J, - "WEAPON_BATTLERIFLE"_J, - "WEAPON_TECPISTOL"_J, - "WEAPON_CANDYCANE"_J, - "WEAPON_PISTOLXM3"_J, - "WEAPON_RAILGUNXM3"_J, - "WEAPON_PRECISIONRIFLE"_J, - "WEAPON_TACTICALRIFLE"_J, - "WEAPON_EMPLAUNCHER"_J, - "WEAPON_HEAVYRIFLE"_J, - "WEAPON_STUNROD"_J, - "weapon_acidpackage"_J, - "weapon_fertilizercan"_J, - "WEAPON_STRICKLER"_J, - }); -} + static inline constexpr auto g_WeaponHashes = std::to_array({ + "WEAPON_KNIFE"_J, + "WEAPON_NIGHTSTICK"_J, + "WEAPON_HAMMER"_J, + "WEAPON_BAT"_J, + "WEAPON_GOLFCLUB"_J, + "WEAPON_CROWBAR"_J, + "WEAPON_PISTOL"_J, + "WEAPON_COMBATPISTOL"_J, + "WEAPON_APPISTOL"_J, + "WEAPON_PISTOL50"_J, + "WEAPON_MICROSMG"_J, + "WEAPON_SMG"_J, + "WEAPON_ASSAULTSMG"_J, + "WEAPON_ASSAULTRIFLE"_J, + "WEAPON_CARBINERIFLE"_J, + "WEAPON_ADVANCEDRIFLE"_J, + "WEAPON_MG"_J, + "WEAPON_COMBATMG"_J, + "WEAPON_PUMPSHOTGUN"_J, + "WEAPON_SAWNOFFSHOTGUN"_J, + "WEAPON_ASSAULTSHOTGUN"_J, + "WEAPON_BULLPUPSHOTGUN"_J, + "WEAPON_STUNGUN"_J, + "WEAPON_SNIPERRIFLE"_J, + "WEAPON_HEAVYSNIPER"_J, + "WEAPON_REMOTESNIPER"_J, + "WEAPON_GRENADELAUNCHER"_J, + "WEAPON_GRENADELAUNCHER_SMOKE"_J, + "WEAPON_RPG"_J, + "WEAPON_MINIGUN"_J, + "WEAPON_GRENADE"_J, + "WEAPON_STICKYBOMB"_J, + "WEAPON_SMOKEGRENADE"_J, + "WEAPON_BZGAS"_J, + "WEAPON_MOLOTOV"_J, + "WEAPON_FIREEXTINGUISHER"_J, + "WEAPON_PETROLCAN"_J, + "WEAPON_BALL"_J, + "WEAPON_FLARE"_J, + "WEAPON_BOTTLE"_J, + "WEAPON_SNSPISTOL"_J, + "WEAPON_HEAVYPISTOL"_J, + "WEAPON_BULLPUPRIFLE"_J, + "WEAPON_SPECIALCARBINE"_J, + "WEAPON_SNSPISTOL_MK2"_J, + "WEAPON_SPECIALCARBINE_MK2"_J, + "WEAPON_PUMPSHOTGUN_MK2"_J, + "WEAPON_BULLPUPRIFLE_MK2"_J, + "WEAPON_MARKSMANRIFLE_MK2"_J, + "WEAPON_CANDYCANE"_J, + "WEAPON_PISTOLXM3"_J, + "WEAPON_RAILGUNXM3"_J, + "WEAPON_ACIDPACKAGE"_J, + "WEAPON_HOMINGLAUNCHER"_J, + "WEAPON_PROXMINE"_J, + "WEAPON_SNOWBALL"_J, + "WEAPON_DOUBLEACTION"_J, + "WEAPON_REVOLVER_MK2"_J, + "WEAPON_RAYPISTOL"_J, + "WEAPON_RAYCARBINE"_J, + "WEAPON_RAYMINIGUN"_J, + "WEAPON_GUSENBERG"_J, + "WEAPON_DAGGER"_J, + "WEAPON_VINTAGEPISTOL"_J, + "WEAPON_FIREWORK"_J, + "WEAPON_MUSKET"_J, + "WEAPON_HATCHET"_J, + "WEAPON_RAILGUN"_J, + "WEAPON_MARKSMANRIFLE"_J, + "WEAPON_HEAVYSHOTGUN"_J, + "WEAPON_CERAMICPISTOL"_J, + "WEAPON_MILITARYRIFLE"_J, + "WEAPON_GADGETPISTOL"_J, + "WEAPON_HAZARDCAN"_J, + "WEAPON_COMBATSHOTGUN"_J, + "WEAPON_NAVYREVOLVER"_J, + "WEAPON_FLAREGUN"_J, + "WEAPON_KNUCKLE"_J, + "WEAPON_COMBATPDW"_J, + "WEAPON_MARKSMANPISTOL"_J, + "WEAPON_DBSHOTGUN"_J, + "WEAPON_COMPACTRIFLE"_J, + "WEAPON_MACHINEPISTOL"_J, + "WEAPON_MACHETE"_J, + "WEAPON_FLASHLIGHT"_J, + "WEAPON_SWITCHBLADE"_J, + "WEAPON_REVOLVER"_J, + "WEAPON_WRENCH"_J, + "WEAPON_POOLCUE"_J, + "WEAPON_MINISMG"_J, + "WEAPON_BATTLEAXE"_J, + "WEAPON_AUTOSHOTGUN"_J, + "WEAPON_COMPACTLAUNCHER"_J, + "WEAPON_PIPEBOMB"_J, + "WEAPON_SMG_MK2"_J, + "WEAPON_COMBATMG_MK2"_J, + "WEAPON_CARBINERIFLE_MK2"_J, + "WEAPON_ASSAULTRIFLE_MK2"_J, + "WEAPON_HEAVYSNIPER_MK2"_J, + "WEAPON_PISTOL_MK2"_J, + "WEAPON_STONE_HATCHET"_J, + "WEAPON_TACTICALRIFLE"_J, + "WEAPON_PRECISIONRIFLE"_J, + "WEAPON_HEAVYRIFLE"_J, + "WEAPON_FERTILIZERCAN"_J, + "WEAPON_EMPLAUNCHER"_J, + "WEAPON_STUNGUN_MP"_J, + "WEAPON_TECPISTOL"_J, + "WEAPON_SNOWLAUNCHER"_J, + "WEAPON_HACKINGDEVICE"_J, + "WEAPON_BATTLERIFLE"_J, + "WEAPON_STUNROD"_J, + "WEAPON_STRICKLER"_J + }); +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 526031c..445c97e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,7 @@ #include "game/frontend/GUI.hpp" #include "game/pointers/Pointers.hpp" #include "game/features/vehicle/SavePersonalVehicle.hpp" +#include "game/features/self/OpenGunLocker.hpp" namespace YimMenu { @@ -67,6 +68,7 @@ namespace YimMenu ScriptMgr::AddScript(std::make_unique