diff --git a/src/script_function.hpp b/src/script_function.hpp index 35226c22..059d172a 100644 --- a/src/script_function.hpp +++ b/src/script_function.hpp @@ -30,10 +30,18 @@ namespace big { auto thread = gta_util::find_script_thread(m_script); auto program = gta_util::find_script_program(m_script); - auto ip = get_ip(program); - if (!thread || !program || !ip) + if (!thread || !program) + { + LOG(FATAL) << m_name << " failed to find its associated script running."; return Ret(); + } + + auto ip = get_ip(program); + if (!ip) + { + return Ret(); + } auto tls_ctx = rage::tlsContext::get(); auto stack = (uint64_t*)thread->m_stack; @@ -70,5 +78,7 @@ namespace big inline script_function reset_session_data("RSD", "main_persistent"_J, "2D 02 7D 00 00"); inline script_function add_clan_logo_to_vehicle("ACLTV", "main_persistent"_J, "2D 02 04 00 00 5D ? ? ? 61"); inline script_function vehicle_cannot_accept_clan_logo("CVACL", "main_persistent"_J, "2D 01 03 00 00 2C 01 00 A1 06 ? 04"); + inline script_function get_component_name_string("GCNS", "mp_weapons"_J, "2D 02 43 00 00 38 01"); + inline script_function get_component_desc_string("GCDS", "mp_weapons"_J, "2D 02 43 00 00 38 00"); } } \ No newline at end of file diff --git a/src/services/gta_data/gta_data_service.cpp b/src/services/gta_data/gta_data_service.cpp index 53cf1dbb..6d31c432 100644 --- a/src/services/gta_data/gta_data_service.cpp +++ b/src/services/gta_data/gta_data_service.cpp @@ -256,9 +256,12 @@ namespace big hash_array mapped_weapons; hash_array mapped_components; + int mp_weapons_thread_id = 0; + std::vector peds; std::vector vehicles; - std::vector weapons; + //std::vector weapons; + std::unordered_map weapons; std::vector weapon_components; constexpr auto exists = [](const hash_array& arr, uint32_t val) -> bool { @@ -307,7 +310,7 @@ namespace big } else if (const auto file_str = path.string(); file_str.find("weaponcomponents") != std::string::npos && path.extension() == ".meta") { - rpf_wrapper.read_xml_file(path, [&exists, &weapon_components, &mapped_components](pugi::xml_document& doc) { + rpf_wrapper.read_xml_file(path, [&exists, &weapon_components, &mapped_components, &mp_weapons_thread_id](pugi::xml_document& doc) { const auto& items = doc.select_nodes("/CWeaponComponentInfoBlob/Infos/*[self::Item[@type='CWeaponComponentInfo'] or self::Item[@type='CWeaponComponentFlashLightInfo'] or self::Item[@type='CWeaponComponentScopeInfo'] or self::Item[@type='CWeaponComponentSuppressorInfo'] or self::Item[@type='CWeaponComponentVariantModelInfo'] or self::Item[@type='CWeaponComponentClipInfo']]"); for (const auto& item_node : items) { @@ -315,7 +318,7 @@ namespace big const std::string name = item.child("Name").text().as_string(); const auto hash = rage::joaat(name); - if (!name.starts_with("COMPONENT")) + if (!name.starts_with("COMPONENT") || name.ends_with("MK2_UPGRADE")) { continue; } @@ -329,9 +332,49 @@ namespace big std::string LocName = item.child("LocName").text().as_string(); std::string LocDesc = item.child("LocDesc").text().as_string(); - if (LocName.ends_with("INVALID") || LocName.ends_with("RAIL")) - { + if (LocName.ends_with("RAIL")) continue; + + if (LocName.ends_with("INVALID")) + { + constexpr Hash script_hash = "MP_Weapons"_J; + if (!SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(script_hash)) + { + while (!SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED(script_hash)) + { + SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH(script_hash); + script::get_current()->yield(10ms); + } + mp_weapons_thread_id = SYSTEM::START_NEW_SCRIPT_WITH_NAME_HASH(script_hash, 1424); + auto thread = gta_util::find_script_thread_by_id(mp_weapons_thread_id); + if (thread) + thread->m_context.m_state = rage::eThreadState::unk_3; + else + LOG(FATAL) << "Failed to find MP_Weapons script!"; + SCRIPT::SET_SCRIPT_WITH_NAME_HASH_AS_NO_LONGER_NEEDED(script_hash); + } + + Hash weapon_hash = 0; + if (name.starts_with("COMPONENT_KNIFE")) + weapon_hash = "WEAPON_KNIFE"_J; + else if (name.starts_with("COMPONENT_KNUCKLE")) + weapon_hash = "WEAPON_KNUCKLE"_J; + else if (name.starts_with("COMPONENT_BAT")) + weapon_hash = "WEAPON_BAT"_J; + const auto display_string = scr_functions::get_component_name_string.call(hash, weapon_hash); + if (display_string == nullptr) + continue; + LocName = display_string; + } + + if (LocName.ends_with("INVALID")) + continue; + + if (LocDesc.ends_with("INVALID")) + { + const auto display_string = scr_functions::get_component_desc_string.call(hash, 0); + if (display_string != nullptr) + LocDesc = display_string; } weapon_component component; @@ -358,9 +401,8 @@ namespace big if (hash == "WEAPON_BIRD_CRAP"_J) continue; - if (exists(mapped_weapons, hash)) - continue; - mapped_weapons.emplace_back(hash); + if (!exists(mapped_weapons, hash)) + mapped_weapons.emplace_back(hash); const auto human_name_hash = item.child("HumanNameHash").text().as_string(); if (std::strcmp(human_name_hash, "WT_INVALID") == 0 || std::strcmp(human_name_hash, "WT_VEHMINE") == 0) @@ -435,7 +477,7 @@ namespace big weapon.m_hash = hash; - weapons.emplace_back(std::move(weapon)); + weapons[hash] = weapon; skip: continue; } @@ -475,6 +517,11 @@ namespace big yim_fipackfile::for_each_fipackfile(); } + if (mp_weapons_thread_id != 0) + { + SCRIPT::TERMINATE_THREAD(mp_weapons_thread_id); + } + static bool translate_label = false; g_fiber_pool->queue_job([&] { @@ -488,7 +535,7 @@ namespace big } for (auto& item : weapons) { - item.m_display_name = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(item.m_display_name.c_str()); + item.second.m_display_name = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(item.second.m_display_name.c_str()); } for (auto& item : weapon_components) { @@ -555,8 +602,8 @@ namespace big m_weapons_cache.weapon_map.clear(); for (auto weapon : weapons) { - add_if_not_exists(m_weapon_types, weapon.m_weapon_type); - m_weapons_cache.weapon_map.insert({weapon.m_name, weapon}); + add_if_not_exists(m_weapon_types, weapon.second.m_weapon_type); + m_weapons_cache.weapon_map.insert({weapon.second.m_name, weapon.second}); } m_weapons_cache.weapon_components.clear(); diff --git a/src/views/self/view_weapons.cpp b/src/views/self/view_weapons.cpp index e8e66e78..b95f2103 100644 --- a/src/views/self/view_weapons.cpp +++ b/src/views/self/view_weapons.cpp @@ -290,8 +290,7 @@ namespace big Hash attachment_hash = attachment_component.m_hash; if (attachment_hash == NULL) { - attachment_name = attachment; - attachment_hash = rage::joaat(attachment); + continue; } bool is_selected = attachment_hash == selected_weapon_attachment_hash; std::string display_name = attachment_name.append("##").append(std::to_string(attachment_hash)); @@ -300,6 +299,8 @@ namespace big selected_weapon_attachment = attachment_name; selected_weapon_attachment_hash = attachment_hash; } + if (ImGui::IsItemHovered()) + ImGui::SetTooltip(attachment_component.m_display_desc.c_str()); if (is_selected) { ImGui::SetItemDefaultFocus();