Redesigned Vehicle Spawn menus to have consistent features. (#2063)

Closes #2053
This commit is contained in:
gir489
2023-08-31 09:43:55 -04:00
committed by GitHub
parent 4c6226d022
commit cf07cfec04
19 changed files with 1115 additions and 950 deletions

View File

@ -2,6 +2,7 @@
#include "fiber_pool.hpp"
#include "script.hpp"
#include "services/vehicle/persist_car_service.hpp"
#include "services/model_preview/model_preview_service.hpp"
#include "util/mobile.hpp"
#include "util/teleport.hpp"
#include "views/view.hpp"
@ -22,13 +23,15 @@ namespace big
{
if (!selected_vehicle_file.empty())
{
const auto vehicle = persist_car_service::load_vehicle(selected_vehicle_file, g.vehicle.persist_vehicle_sub_folder);
const auto vehicle = persist_car_service::load_vehicle(selected_vehicle_file, g.persist_car.persist_vehicle_sub_folder);
if (!vehicle)
{
g_notification_service->push_warning("PERSIST_CAR"_T.data(), "PERSIST_CAR_TO_MANY_SPAWNED"_T.data());
}
else if (g.spawn_vehicle.spawn_inside)
else if (g.persist_car.spawn_inside)
{
teleport::into_vehicle(vehicle);
}
selected_vehicle_file.clear();
}
@ -43,25 +46,47 @@ namespace big
static std::string selected_vehicle_file;
const auto vehicle_folders = persist_car_service::list_sub_folders();
const auto vehicle_files = persist_car_service::list_files(g.vehicle.persist_vehicle_sub_folder);
const auto vehicle_files = persist_car_service::list_files(g.persist_car.persist_vehicle_sub_folder);
if (ImGui::Checkbox("PREVIEW"_T.data(), &g.persist_car.preview_vehicle))
{
if (!g.persist_car.preview_vehicle)
{
g_model_preview_service->stop_preview();
}
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("PREVIEW_DESC"_T.data());
ImGui::SameLine();
ImGui::Checkbox("SPAWN_IN"_T.data(), &g.persist_car.spawn_inside);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("SPAWN_IN_DESC"_T.data());
auto folder_display = g.vehicle.persist_vehicle_sub_folder.empty() ? "ROOT"_T.data() : g.vehicle.persist_vehicle_sub_folder.c_str();
ImGui::SetNextItemWidth(300.f);
auto folder_display = g.persist_car.persist_vehicle_sub_folder.empty() ?
"ROOT"_T.data() :
g.persist_car.persist_vehicle_sub_folder.c_str();
if (ImGui::BeginCombo("FOLDER"_T.data(), folder_display))
{
if (ImGui::Selectable("ROOT"_T.data(), g.vehicle.persist_vehicle_sub_folder == ""))
g.vehicle.persist_vehicle_sub_folder = "";
if (ImGui::Selectable("ROOT"_T.data(), g.persist_car.persist_vehicle_sub_folder == ""))
g.persist_car.persist_vehicle_sub_folder.clear();
for (std::string folder_name : vehicle_folders)
{
if (ImGui::Selectable(folder_name.c_str(), g.vehicle.persist_vehicle_sub_folder == folder_name))
g.vehicle.persist_vehicle_sub_folder = folder_name;
if (ImGui::Selectable(folder_name.c_str(), g.persist_car.persist_vehicle_sub_folder == folder_name))
g.persist_car.persist_vehicle_sub_folder = folder_name;
}
ImGui::EndCombo();
}
ImGui::PushItemWidth(250);
static char search[64];
ImGui::SetNextItemWidth(300.f);
components::input_text_with_hint("FILE_NAME"_T, "SEARCH"_T, search, sizeof(search), ImGuiInputTextFlags_None);
std::string lower_search = search;
std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(), tolower);
ImGui::SetNextItemWidth(250);
ImGui::Text("SAVED_VEHICLES"_T.data());
static const auto over_30 = (30 * ImGui::GetTextLineHeightWithSpacing() + 2);
@ -70,12 +95,29 @@ namespace big
{
for (const auto& pair : vehicle_files)
{
if (ImGui::Selectable(pair.c_str(), selected_vehicle_file == pair))
std::string pair_lower = pair;
std::transform(pair_lower.begin(), pair_lower.end(), pair_lower.begin(), tolower);
if (pair_lower.contains(lower_search))
{
selected_vehicle_file = pair;
g_fiber_pool->queue_job([] {
load_vehicle(selected_vehicle_file);
});
if (ImGui::Selectable(pair.c_str(), selected_vehicle_file == pair))
{
selected_vehicle_file = pair;
g_fiber_pool->queue_job([] {
load_vehicle(selected_vehicle_file);
g_model_preview_service->stop_preview();
});
}
if (!g.persist_car.preview_vehicle || (g.persist_car.preview_vehicle && !ImGui::IsAnyItemHovered()))
{
g_model_preview_service->stop_preview();
}
else if (ImGui::IsItemHovered())
{
g_fiber_pool->queue_job([pair] {
g_model_preview_service->show_vehicle_persisted(pair);
});
}
}
}
@ -88,19 +130,17 @@ namespace big
static char vehicle_file_name_input[50]{};
components::small_text("VEHICLE_FILE_NAME"_T);
ImGui::PushItemWidth(250);
ImGui::SetNextItemWidth(250);
ImGui::InputText("##vehiclefilename", vehicle_file_name_input, IM_ARRAYSIZE(vehicle_file_name_input));
if (ImGui::IsItemHovered())
ImGui::SetTooltip("VEHICLE_FILE_NAME_EXAMPLE"_T.data());
ImGui::PopItemWidth();
static char save_folder[50]{};
components::small_text("VEHICLE_FOLDER_NAME"_T);
ImGui::PushItemWidth(250);
ImGui::SetNextItemWidth(250);
ImGui::InputText("##foldername", save_folder, IM_ARRAYSIZE(save_folder));
if (ImGui::IsItemHovered())
ImGui::SetTooltip("VEHICLE_FOLDER_NAME_EXAMPLE"_T.data());
ImGui::PopItemWidth();
components::button("SAVE_VEHICLE"_T, [] {
if (!self::veh)

View File

@ -19,27 +19,28 @@ namespace big
g_model_preview_service->stop_preview();
}
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("PREVIEW_DESC"_T.data());
ImGui::SameLine();
ImGui::Checkbox("SPAWN_IN"_T.data(), &g.clone_pv.spawn_inside);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("SPAWN_IN_DESC"_T.data());
ImGui::SameLine();
static char plate_buf[9] = {0};
int num_of_rows = 3;
ImGui::Checkbox("SPAWN_CLONE"_T.data(), &g.clone_pv.spawn_clone);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("SPAWN_CLONE_DESC"_T.data());
if (g.clone_pv.spawn_clone)
{
num_of_rows = 5;
ImGui::Checkbox("SPAWN_MAXED"_T.data(), &g.clone_pv.spawn_maxed);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("SPAWN_MAXED_DESC"_T.data());
ImGui::SameLine();
ImGui::Checkbox("CLONE_PV_PLATE"_T.data(), &g.clone_pv.clone_plate);
if (g.clone_pv.clone_plate)
{
num_of_rows = 4;
}
else
if (!g.clone_pv.clone_plate)
{
ImGui::SetNextItemWidth(300.f);
@ -86,7 +87,44 @@ namespace big
components::input_text_with_hint("MODEL_NAME"_T, "SEARCH"_T, search, sizeof(search), ImGuiInputTextFlags_None);
g_mobile_service->refresh_personal_vehicles();
if (ImGui::BeginListBox("###personal_veh_list", {300, static_cast<float>(*g_pointers->m_gta.m_resolution_y - 188 - 38 * num_of_rows)}))
auto num_of_rows = 0;
std::set<int> indexes_to_use;
if (!g_mobile_service->personal_vehicles().empty())
{
std::string lower_search = search;
std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(), tolower);
for (const auto& it : g_mobile_service->personal_vehicles())
{
const auto& label = it.first;
const auto& personal_veh = it.second;
const auto& item = g_gta_data_service->vehicle_by_hash(personal_veh->get_hash());
std::string vehicle_class = item.m_vehicle_class;
std::string display_name = label;
std::string display_manufacturer = item.m_display_manufacturer;
std::transform(display_name.begin(), display_name.end(), display_name.begin(), ::tolower);
std::transform(display_manufacturer.begin(), display_manufacturer.end(), display_manufacturer.begin(), ::tolower);
if ((selected_class == -1 || class_arr[selected_class] == vehicle_class)
&& (display_name.find(lower_search) != std::string::npos || display_manufacturer.find(lower_search) != std::string::npos))
{
indexes_to_use.insert(personal_veh->get_id());
}
}
num_of_rows = indexes_to_use.size();
}
else
{
num_of_rows = 2;
}
static const auto over_30 = (30 * ImGui::GetTextLineHeightWithSpacing() + 2);
const auto box_height = num_of_rows <= 30 ? (num_of_rows * ImGui::GetTextLineHeightWithSpacing() + 2) : over_30;
if (ImGui::BeginListBox("###personal_veh_list", {300, box_height}))
{
if (g_mobile_service->personal_vehicles().empty())
{
@ -99,19 +137,12 @@ namespace big
for (const auto& it : g_mobile_service->personal_vehicles())
{
const auto& label = it.first;
const auto& personal_veh = it.second;
const auto& item = g_gta_data_service->vehicle_by_hash(personal_veh->get_hash());
std::string vehicle_class = item.m_vehicle_class;
std::string display_name = label;
std::string display_manufacturer = item.m_display_manufacturer;
std::transform(display_name.begin(), display_name.end(), display_name.begin(), ::tolower);
std::transform(display_manufacturer.begin(), display_manufacturer.end(), display_manufacturer.begin(), ::tolower);
if ((selected_class == -1 || class_arr[selected_class] == vehicle_class)
&& (display_name.find(lower_search) != std::string::npos || display_manufacturer.find(lower_search) != std::string::npos))
if (indexes_to_use.contains(personal_veh->get_id()))
{
const auto& label = it.first;
ImGui::PushID('v' << 24 & personal_veh->get_id());
components::selectable(label, false, [&personal_veh] {
if (g.clone_pv.spawn_clone)

View File

@ -257,7 +257,7 @@ namespace big
});
}
ImGui::SameLine();
if (ImGui::Checkbox("TIRESMOKE"_T.data(), (bool*)&owned_mods[MOD_TYRE_SMOKE]))
if (ImGui::Checkbox("TIRE_SMOKE"_T.data(), (bool*)&owned_mods[MOD_TYRE_SMOKE]))
{
g_fiber_pool->queue_job([] {
VEHICLE::TOGGLE_VEHICLE_MOD(player_vehicle, MOD_TYRE_SMOKE, owned_mods[MOD_TYRE_SMOKE]);

View File

@ -9,8 +9,6 @@ namespace big
{
void render_spawn_new_vehicle()
{
ImGui::SetWindowSize({0.f, (float)*g_pointers->m_gta.m_resolution_y}, ImGuiCond_Always);
if (ImGui::Checkbox("PREVIEW"_T.data(), &g.spawn_vehicle.preview_vehicle))
{
if (!g.spawn_vehicle.preview_vehicle)
@ -18,6 +16,8 @@ namespace big
g_model_preview_service->stop_preview();
}
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("PREVIEW_DESC"_T.data());
ImGui::SameLine();
components::command_checkbox<"spawnin">();
ImGui::SameLine();
@ -64,7 +64,43 @@ namespace big
ImGui::SetNextItemWidth(300.f);
components::input_text_with_hint("MODEL_NAME"_T, "SEARCH"_T, search, sizeof(search), ImGuiInputTextFlags_None);
if (ImGui::BeginListBox("###vehicles", {300, static_cast<float>(*g_pointers->m_gta.m_resolution_y - 188 - 38 * 4)}))
vehicle_map calculated_map{};
if (g_gta_data_service->vehicles().size() > 0)
{
for (auto& item : g_gta_data_service->vehicles())
{
const auto& vehicle = item.second;
std::string display_name = vehicle.m_display_name;
std::string display_manufacturer = vehicle.m_display_manufacturer;
std::string clazz = vehicle.m_vehicle_class;
std::transform(display_name.begin(), display_name.end(), display_name.begin(), ::tolower);
std::transform(display_manufacturer.begin(), display_manufacturer.end(), display_manufacturer.begin(), ::tolower);
std::string lower_search = search;
std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(), tolower);
if ((selected_class == -1 || class_arr[selected_class] == clazz) && (display_name.find(lower_search) != std::string::npos || display_manufacturer.find(lower_search) != std::string::npos))
{
calculated_map.emplace(item);
}
}
}
static const auto over_30 = (30 * ImGui::GetTextLineHeightWithSpacing() + 2);
auto calculated_size = calculated_map.size();
if (calculated_map.size() == 0)
{
calculated_size++;
}
if (self::veh)
{
calculated_size++;
}
const auto box_height = calculated_size <= 30 ? (calculated_size * ImGui::GetTextLineHeightWithSpacing() + 2) : over_30;
if (ImGui::BeginListBox("###vehicles", {300, box_height}))
{
if (self::veh)
{
@ -125,66 +161,50 @@ namespace big
}
}
const auto& item_arr = g_gta_data_service->vehicles();
if (item_arr.size() > 0)
if (calculated_map.size() > 0)
{
std::string lower_search = search;
std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(), tolower);
for (auto& item : item_arr)
for (auto& item : calculated_map)
{
const auto& vehicle = item.second;
ImGui::PushID(vehicle.m_hash);
components::selectable(vehicle.m_display_name, false, [&vehicle] {
const auto spawn_location =
vehicle::get_spawn_location(g.spawn_vehicle.spawn_inside, vehicle.m_hash);
const auto spawn_heading = ENTITY::GET_ENTITY_HEADING(self::ped);
std::string display_name = vehicle.m_display_name;
std::string display_manufacturer = vehicle.m_display_manufacturer;
std::string clazz = vehicle.m_vehicle_class;
auto veh = vehicle::spawn(vehicle.m_hash, spawn_location, spawn_heading);
std::transform(display_name.begin(), display_name.end(), display_name.begin(), ::tolower);
std::transform(display_manufacturer.begin(), display_manufacturer.end(), display_manufacturer.begin(), ::tolower);
if (veh == 0)
{
g_notification_service->push_error("VEHICLE"_T.data(), "UNABLE_TO_SPAWN_VEHICLE"_T.data());
}
else
{
if (g.spawn_vehicle.spawn_maxed)
{
vehicle::max_vehicle(veh);
}
if ((selected_class == -1 || class_arr[selected_class] == clazz)
&& (display_name.find(lower_search) != std::string::npos || display_manufacturer.find(lower_search) != std::string::npos))
vehicle::set_plate(veh, plate_buf);
if (g.spawn_vehicle.spawn_inside)
{
vehicle::teleport_into_vehicle(veh);
}
}
g_model_preview_service->stop_preview();
ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&veh);
});
ImGui::PopID();
if (!g.spawn_vehicle.preview_vehicle || (g.spawn_vehicle.preview_vehicle && !ImGui::IsAnyItemHovered()))
{
ImGui::PushID(vehicle.m_hash);
components::selectable(vehicle.m_display_name, false, [&vehicle] {
const auto spawn_location =
vehicle::get_spawn_location(g.spawn_vehicle.spawn_inside, vehicle.m_hash);
const auto spawn_heading = ENTITY::GET_ENTITY_HEADING(self::ped);
auto veh = vehicle::spawn(vehicle.m_hash, spawn_location, spawn_heading);
if (veh == 0)
{
g_notification_service->push_error("VEHICLE"_T.data(), "UNABLE_TO_SPAWN_VEHICLE"_T.data());
}
else
{
if (g.spawn_vehicle.spawn_maxed)
{
vehicle::max_vehicle(veh);
}
vehicle::set_plate(veh, plate_buf);
if (g.spawn_vehicle.spawn_inside)
{
vehicle::teleport_into_vehicle(veh);
}
}
g_model_preview_service->stop_preview();
ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&veh);
});
ImGui::PopID();
if (!g.spawn_vehicle.preview_vehicle || (g.spawn_vehicle.preview_vehicle && !ImGui::IsAnyItemHovered()))
{
g_model_preview_service->stop_preview();
}
else if (ImGui::IsItemHovered())
{
g_model_preview_service->show_vehicle(vehicle.m_hash, g.spawn_vehicle.spawn_maxed);
}
g_model_preview_service->stop_preview();
}
else if (ImGui::IsItemHovered())
{
g_model_preview_service->show_vehicle(vehicle.m_hash, g.spawn_vehicle.spawn_maxed);
}
}
}
@ -198,16 +218,15 @@ namespace big
void view::spawn_vehicle()
{
static int spawn_type = 0;
ImGui::RadioButton("New", &spawn_type, 0);
ImGui::RadioButton("New", &g.spawn_vehicle.spawn_type, 0);
ImGui::SameLine();
ImGui::RadioButton("Personal", &spawn_type, 1);
ImGui::RadioButton("Personal", &g.spawn_vehicle.spawn_type, 1);
ImGui::SameLine();
ImGui::RadioButton("Persistent", &spawn_type, 2);
ImGui::RadioButton("Persistent", &g.spawn_vehicle.spawn_type, 2);
ImGui::SameLine();
ImGui::RadioButton("Xml", &spawn_type, 3);
ImGui::RadioButton("Xml", &g.spawn_vehicle.spawn_type, 3);
switch (spawn_type)
switch (g.spawn_vehicle.spawn_type)
{
case 0: render_spawn_new_vehicle(); break;
case 1: view::pv(); break;