diff --git a/resource/common/locale/English.toml b/resource/common/locale/English.toml index bf26d12..36a400c 100644 --- a/resource/common/locale/English.toml +++ b/resource/common/locale/English.toml @@ -377,7 +377,7 @@ PlayerFlags = "Player flags," PlayerRegen = "Player regeneration" PlayerRegenTip = "Player heals if not taken damage for 5 seconds" RemoveAll = "Remove all" -RemoveClothesTab = "Remove clothes" +RemoveClothesTab = "Remove" RespawnDieLoc = "Respawn die location" RespawnDieLocTip = "Respawn to the location you died from" Respect = "Respect" @@ -579,7 +579,9 @@ ReadMore = "Read more" RearLights = "Rear lights" RearWheelDrive = "Rear wheel drive" RemoveNeon = "Remove neon" -RemoveNeonMSG = "Neon removed successfully" +RemoveNeonMSG = "Neon removed" +RemoveTune = "Remove tunes" +RemoveTuneMSG = "Tunes removed" RemoveVeh = "Remove vehicles" RemoveVehRadius = "Remove vehicles in radius" ResetColor = "Reset color" @@ -599,8 +601,9 @@ SetSpeed = "Set speed" Siren = "Siren" SkidMarks = "Always skid marks" Small = "Small" -SpawnInAir = "Spawn aircraft in air" -SpawnInside = "Spawn as driver" +SpawnInAir = "Aircraft in air" +SpawnInside = "As driver" +SpawnWithTunes = "Add tunes" StayOnBike = "Don't fall off bike" SteeringLock = "Steering lock" SuspensionBias = "Suspension bias" diff --git a/src/custom/vehcustmzr.cpp b/src/custom/vehcustmzr.cpp index d0e0363..72b0ee9 100644 --- a/src/custom/vehcustmzr.cpp +++ b/src/custom/vehcustmzr.cpp @@ -516,6 +516,19 @@ void VehCustmzrMgr::Draw() } if (ImGui::BeginTabItem(TEXT("Vehicle.TuneTab"))) { + ImGui::Spacing(); + if (ImGui::Button(TEXT("Vehicle.RemoveTune"), ImVec2(Widget::CalcSize()))) + { + for (int i = 0; i != 15; ++i) + { + int compID = pVeh->GetUpgrade(i); + if (compID > -1) + { + pVeh->RemoveVehicleUpgrade(compID); + } + } + Util::SetMessage(TEXT("Vehicle.RemoveTuneMSG")); + } ImGui::Spacing(); Widget::ImageList(m_TuneData, [this](std::string& str) diff --git a/src/pages/player.cpp b/src/pages/player.cpp index 8dddb79..91045db 100644 --- a/src/pages/player.cpp +++ b/src/pages/player.cpp @@ -228,6 +228,46 @@ void PlayerPage::SetCloth(std::string& name) } CClothes::RebuildPlayer(player, false); } + +void PlayerPage::RemoveClothesTab() +{ + if (ImGui::BeginTabItem(TEXT("Player.RemoveClothesTab"))) + { + ImGui::TextWrapped(TEXT("Player.ClothesTip")); + ImGui::Spacing(); + + ImGui::BeginChild("ClothesRemove"); + if (ImGui::Button(TEXT("Player.RemoveAll"), ImVec2(Widget::CalcSize(2)))) + { + CPlayerPed* player = FindPlayerPed(); + for (uint i = 0; i < 18; i++) + { + player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(0u, 0u, i); + } + CClothes::RebuildPlayer(player, false); + } + ImGui::SameLine(); + size_t count = 0; + for (auto [k, v] : m_ClothData.m_pData->Items()) + { + if (ImGui::Button(std::string(k.str()).c_str(), ImVec2(Widget::CalcSize(2)))) + { + CPlayerPed* player = FindPlayerPed(); + player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(0u, 0u, std::stoi(v.value_or("0"))); + CClothes::RebuildPlayer(player, false); + } + + if (count % 2 != 0) + { + ImGui::SameLine(); + } + ++count; + } + + ImGui::EndChild(); + ImGui::EndTabItem(); + } +} #endif #ifdef GTASA @@ -774,7 +814,7 @@ void PlayerPage::Draw() getline(ss, temp, '$'); return temp; - }); + }, nullptr, nullptr, nullptr, fArgNoneWrapper(playerPage.RemoveClothesTab)); } else { @@ -789,43 +829,6 @@ void PlayerPage::Draw() } ImGui::EndTabItem(); } - if (pPlayer->m_nModelIndex == 0 - && ImGui::BeginTabItem(TEXT("Player.RemoveClothesTab"))) - { - ImGui::TextWrapped(TEXT("Player.ClothesTip")); - ImGui::Spacing(); - - ImGui::BeginChild("ClothesRemove"); - if (ImGui::Button(TEXT("Player.RemoveAll"), ImVec2(Widget::CalcSize(2)))) - { - CPlayerPed* player = FindPlayerPed(); - for (uint i = 0; i < 18; i++) - { - player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(0u, 0u, i); - } - CClothes::RebuildPlayer(player, false); - } - ImGui::SameLine(); - size_t count = 0; - for (auto [k, v] : m_ClothData.m_pData->Items()) - { - if (ImGui::Button(std::string(k.str()).c_str(), ImVec2(Widget::CalcSize(2)))) - { - CPlayerPed* player = FindPlayerPed(); - player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(0u, 0u, std::stoi(v.value_or("0"))); - CClothes::RebuildPlayer(player, false); - } - - if (count % 2 != 0) - { - ImGui::SameLine(); - } - ++count; - } - - ImGui::EndChild(); - ImGui::EndTabItem(); - } if (ImGui::BeginTabItem(TEXT("Player.PedSkinsTab"))) { Widget::ImageList(pedPage.m_PedData, fArgWrapper(playerPage.SetModel), diff --git a/src/pages/player.h b/src/pages/player.h index 17bbb75..3772316 100644 --- a/src/pages/player.h +++ b/src/pages/player.h @@ -26,6 +26,7 @@ private: ResourceStore m_ClothData { "clothes", eResourceType::TYPE_TEXT_IMAGE, ImVec2(70, 100)}; void SetCloth(str& id); + void RemoveClothesTab(); void SetModel(str& id); #else ResourceStore skinData { BY_GAME(NULL, "skins", "peds"), eResourceType::TYPE_TEXT }; diff --git a/src/pages/vehicle.cpp b/src/pages/vehicle.cpp index 6d91ef6..86e2969 100644 --- a/src/pages/vehicle.cpp +++ b/src/pages/vehicle.cpp @@ -19,6 +19,7 @@ VehiclePage::VehiclePage() { m_Spawner.m_bInAir = gConfig.Get("Features.SpawnAircraftInAir", true); m_Spawner.m_bAsDriver = gConfig.Get("Features.SpawnInsideVehicle", true); + m_Spawner.m_bWithTunes = gConfig.Get("Features.SpawnWithTunes", true); }; Events::processScriptsEvent += [this] @@ -368,7 +369,7 @@ void VehiclePage::SpawnVehicle(std::string& smodel) } // Add random tunes - if (pVeh->m_nVehicleSubClass <= VEHICLE_QUAD) + if (m_Spawner.m_bWithTunes && pVeh->m_nVehicleSubClass <= VEHICLE_QUAD) { for (int i = 0; i < 20; ++i) { @@ -999,19 +1000,6 @@ void VehiclePage::Draw() } if (ImGui::BeginTabItem(TEXT("Window.SpawnTab"))) { - ImGui::Spacing(); - ImGui::Columns(2, 0, false); - if (Widget::Checkbox(TEXT("Vehicle.SpawnInside"), &m_Spawner.m_bAsDriver)) - { - gConfig.Set("Features.SpawnInsideVehicle", m_Spawner.m_bAsDriver); - } - ImGui::NextColumn(); - if( Widget::Checkbox(TEXT("Vehicle.SpawnInAir"), &m_Spawner.m_bInAir)) - { - gConfig.Set("Features.SpawnAircraftInAir", m_Spawner.m_bInAir); - } - ImGui::Columns(1); - ImGui::Spacing(); int width = ImGui::GetWindowContentRegionWidth() - ImGui::GetStyle().ItemSpacing.x; @@ -1054,9 +1042,36 @@ void VehiclePage::Draw() Widget::ImageList(m_Spawner.m_VehData, fArgWrapper(vehiclePage.SpawnVehicle), [](std::string& str){ return Util::GetCarName(std::stoi(str)); - }, nullptr, fArgNoneWrapper(vehiclePage.AddNew)); + }, nullptr, fArgNoneWrapper(vehiclePage.AddNew), + []() + { + if (ImGui::MenuItem(TEXT("Vehicle.SpawnWithTunes"), NULL, &vehiclePage.m_Spawner.m_bWithTunes)) + { + gConfig.Set("Features.SpawnWithTunes", vehiclePage.m_Spawner.m_bWithTunes); + } + if (ImGui::MenuItem(TEXT("Vehicle.SpawnInAir"), NULL, &vehiclePage.m_Spawner.m_bInAir)) + { + gConfig.Set("Features.SpawnAircraftInAir", vehiclePage.m_Spawner.m_bInAir); + } + if (ImGui::MenuItem(TEXT("Vehicle.SpawnInside"), NULL, &vehiclePage.m_Spawner.m_bAsDriver)) + { + gConfig.Set("Features.SpawnInsideVehicle", vehiclePage.m_Spawner.m_bAsDriver); + } + }); #else - Widget::DataList(m_Spawner.m_VehData, fArg3Wrapper(vehiclePage.SpawnVehicle), fArgNoneWrapper(vehiclePage.AddNew)); + Widget::DataList(m_Spawner.m_VehData, fArg3Wrapper(vehiclePage.SpawnVehicle), fArgNoneWrapper(vehiclePage.AddNew), + false, + []() + { + if (ImGui::MenuItem(TEXT("Vehicle.SpawnInAir"), NULL, &vehiclePage.m_Spawner.m_bInAir)) + { + gConfig.Set("Features.SpawnAircraftInAir", vehiclePage.m_Spawner.m_bInAir); + } + if (ImGui::MenuItem(TEXT("Vehicle.SpawnInside"), NULL, &vehiclePage.m_Spawner.m_bAsDriver)) + { + gConfig.Set("Features.SpawnInsideVehicle", vehiclePage.m_Spawner.m_bAsDriver); + } + }); #endif ImGui::EndTabItem(); } diff --git a/src/pages/vehicle.h b/src/pages/vehicle.h index 3683fa1..fe5b605 100644 --- a/src/pages/vehicle.h +++ b/src/pages/vehicle.h @@ -28,6 +28,7 @@ private: eResourceType::TYPE_TEXT), ImVec2(100, 75)}; bool m_bAsDriver = true; bool m_bInAir = true; + bool m_bWithTunes = true; char m_nLicenseText[9]; } m_Spawner; diff --git a/src/utils/widget.cpp b/src/utils/widget.cpp index abc9c71..b04ca8f 100644 --- a/src/utils/widget.cpp +++ b/src/utils/widget.cpp @@ -75,7 +75,7 @@ bool Widget::Filter(const char* label, ImGuiTextFilter& filter, const char* hint return state; } -void DrawClippedList(ResourceStore& data, fArg3_t clickFunc, bool favourites, bool isEditItem) +void DrawClippedList(ResourceStore& data, fArg3_t clickFunc, bool favourites, bool isEditItem, fArgNone_t contextOptionsFunc) { // Category box ImGui::PushItemWidth(favourites ? ImGui::GetWindowContentRegionWidth() : @@ -166,6 +166,11 @@ void DrawClippedList(ResourceStore& data, fArg3_t clickFunc, bool favourites, bo data.UpdateSearchList(true); } + if (contextOptionsFunc) + { + contextOptionsFunc(); + } + if (ImGui::MenuItem(TEXT("Menu.Close"))) { contextMenu.show = false; @@ -176,7 +181,7 @@ void DrawClippedList(ResourceStore& data, fArg3_t clickFunc, bool favourites, bo ImGui::EndChild(); } -void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc, bool isEditItem) +void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc, bool isEditItem, fArgNone_t contextOptionsFunc, fArgNone_t tabsFunc) { if (ImGui::IsMouseClicked(1)) { @@ -189,7 +194,7 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc if (ImGui::BeginTabItem(TEXT("Window.Search"))) { ImGui::Spacing(); - DrawClippedList(data, clickFunc, false, isEditItem); + DrawClippedList(data, clickFunc, false, isEditItem, contextOptionsFunc); ImGui::EndTabItem(); } if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) @@ -199,7 +204,7 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc if (ImGui::BeginTabItem(TEXT("Window.FavouritesTab"))) { ImGui::Spacing(); - DrawClippedList(data, clickFunc, true, isEditItem); + DrawClippedList(data, clickFunc, true, isEditItem, contextOptionsFunc); ImGui::EndTabItem(); } if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) @@ -219,6 +224,10 @@ void Widget::DataList(ResourceStore& data, fArg3_t clickFunc, fArgNone_t addFunc ImGui::EndTabItem(); } } + if (tabsFunc) + { + tabsFunc(); + } ImGui::EndTabBar(); } } @@ -271,7 +280,7 @@ static bool RoundedImageButton(ImTextureID textureID, ImVec2& size, const char* } void DrawClippedImages(ResourceStore& data, ImVec2 imgSz, size_t imagesInRow, bool showImages, - bool favourites, fArg1_t clickFunc, fRtnArg1_t getNameFunc, fRtnBoolArg1_t verifyFunc) + bool favourites, fArg1_t clickFunc, fRtnArg1_t getNameFunc, fRtnBoolArg1_t verifyFunc, fArgNone_t contextOptionsFunc) { static IDirect3DTexture9 **pDefaultTex = BY_GAME(gTextureList.FindTextureByName("placeholder"), nullptr, nullptr); ImGuiStyle &style = ImGui::GetStyle(); @@ -366,6 +375,10 @@ void DrawClippedImages(ResourceStore& data, ImVec2 imgSz, size_t imagesInRow, bo data.m_pData->Save(); data.UpdateSearchList(true, getNameFunc, verifyFunc); } + if (contextOptionsFunc) + { + contextOptionsFunc(); + } if (ImGui::MenuItem(TEXT("Menu.Close"))) { contextMenu.show = false; @@ -381,7 +394,7 @@ void DrawClippedImages(ResourceStore& data, ImVec2 imgSz, size_t imagesInRow, bo This direly needs a refactor oof */ void Widget::ImageList(ResourceStore &store, fArg1_t clickFunc, fRtnArg1_t getNameFunc, - fRtnBoolArg1_t verifyFunc, fArgNone_t addFunc) + fRtnBoolArg1_t verifyFunc, fArgNone_t addFunc, fArgNone_t contextOptionsFunc, fArgNone_t tabsFunc) { ImGuiStyle& style = ImGui::GetStyle(); /* @@ -430,7 +443,7 @@ void Widget::ImageList(ResourceStore &store, fArg1_t clickFunc, fRtnArg1_t getNa if (ImGui::BeginTabItem(TEXT("Window.Search"))) { ImGui::Spacing(); - DrawClippedImages(store, m_ImageSize, imagesInRow, showImages, false, clickFunc, getNameFunc, verifyFunc); + DrawClippedImages(store, m_ImageSize, imagesInRow, showImages, false, clickFunc, getNameFunc, verifyFunc, contextOptionsFunc); ImGui::EndTabItem(); } if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) @@ -440,7 +453,7 @@ void Widget::ImageList(ResourceStore &store, fArg1_t clickFunc, fRtnArg1_t getNa if (ImGui::BeginTabItem(TEXT("Window.FavouritesTab"))) { ImGui::Spacing(); - DrawClippedImages(store, m_ImageSize, imagesInRow, showImages, true, clickFunc, getNameFunc, verifyFunc); + DrawClippedImages(store, m_ImageSize, imagesInRow, showImages, true, clickFunc, getNameFunc, verifyFunc, contextOptionsFunc); ImGui::EndTabItem(); } if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) @@ -475,6 +488,10 @@ void Widget::ImageList(ResourceStore &store, fArg1_t clickFunc, fRtnArg1_t getNa ImGui::EndTabItem(); } } + if (tabsFunc) + { + tabsFunc(); + } ImGui::EndTabBar(); } diff --git a/src/utils/widget.h b/src/utils/widget.h index 728a587..f93c70a 100644 --- a/src/utils/widget.h +++ b/src/utils/widget.h @@ -41,7 +41,8 @@ public: static bool ColorBtn(int colorId, std::vector& color, ImVec2 size); // Draws DataStore data in the interface - static void DataList(ResourceStore& data, fArg3_t clickFunc = nullptr, fArgNone_t addFunc = nullptr, bool isEditItem = false); + static void DataList(ResourceStore& data, fArg3_t clickFunc = nullptr, fArgNone_t addFunc = nullptr, + bool isEditItem = false, fArgNone_t contextOptionsFunc = nullptr, fArgNone_t tabsFunc = nullptr); // Draws a dropdown editor for memory address template @@ -70,7 +71,8 @@ public: // Draws ResourceStore images in the interface static void ImageList(ResourceStore &store, fArg1_t clickFunc, fRtnArg1_t getNameFunc, - fRtnBoolArg1_t verifyFunc = nullptr, fArgNone_t addFunc = nullptr); + fRtnBoolArg1_t verifyFunc = nullptr, fArgNone_t addFunc = nullptr, + fArgNone_t contextOptionsFunc = nullptr, fArgNone_t tabsFunc = nullptr); // Draws a dropdown listbox static bool ListBox(const char* label, VecStr& allItems, int& selected);