Fixed Weapons JSON not properly using the most recent meta file. (#3550)
* Added ability to resolve WCT_INVALID attachments at runtime from the achievement_controller script, such as the game does. * Improved component information extraction to also retrieve the descriptions from the scripts. Redesigned Ammunation to now only display proper components. Added a tooltip of the component description to Ammunation. * Refactored script_function::call to fail gracefully if called out of lockstep when the scripts are running.
This commit is contained in:
parent
555331ff1d
commit
8c11a1ebb0
@ -30,10 +30,18 @@ namespace big
|
|||||||
{
|
{
|
||||||
auto thread = gta_util::find_script_thread(m_script);
|
auto thread = gta_util::find_script_thread(m_script);
|
||||||
auto program = gta_util::find_script_program(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();
|
return Ret();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ip = get_ip(program);
|
||||||
|
if (!ip)
|
||||||
|
{
|
||||||
|
return Ret();
|
||||||
|
}
|
||||||
|
|
||||||
auto tls_ctx = rage::tlsContext::get();
|
auto tls_ctx = rage::tlsContext::get();
|
||||||
auto stack = (uint64_t*)thread->m_stack;
|
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 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 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 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");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -256,9 +256,12 @@ namespace big
|
|||||||
hash_array mapped_weapons;
|
hash_array mapped_weapons;
|
||||||
hash_array mapped_components;
|
hash_array mapped_components;
|
||||||
|
|
||||||
|
int mp_weapons_thread_id = 0;
|
||||||
|
|
||||||
std::vector<ped_item> peds;
|
std::vector<ped_item> peds;
|
||||||
std::vector<vehicle_item> vehicles;
|
std::vector<vehicle_item> vehicles;
|
||||||
std::vector<weapon_item> weapons;
|
//std::vector<weapon_item> weapons;
|
||||||
|
std::unordered_map<Hash, weapon_item> weapons;
|
||||||
std::vector<weapon_component> weapon_components;
|
std::vector<weapon_component> weapon_components;
|
||||||
|
|
||||||
constexpr auto exists = [](const hash_array& arr, uint32_t val) -> bool {
|
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")
|
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']]");
|
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)
|
for (const auto& item_node : items)
|
||||||
{
|
{
|
||||||
@ -315,7 +318,7 @@ namespace big
|
|||||||
const std::string name = item.child("Name").text().as_string();
|
const std::string name = item.child("Name").text().as_string();
|
||||||
const auto hash = rage::joaat(name);
|
const auto hash = rage::joaat(name);
|
||||||
|
|
||||||
if (!name.starts_with("COMPONENT"))
|
if (!name.starts_with("COMPONENT") || name.ends_with("MK2_UPGRADE"))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -329,9 +332,49 @@ namespace big
|
|||||||
std::string LocName = item.child("LocName").text().as_string();
|
std::string LocName = item.child("LocName").text().as_string();
|
||||||
std::string LocDesc = item.child("LocDesc").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;
|
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<const char*>(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<const char*>(hash, 0);
|
||||||
|
if (display_string != nullptr)
|
||||||
|
LocDesc = display_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
weapon_component component;
|
weapon_component component;
|
||||||
@ -358,8 +401,7 @@ namespace big
|
|||||||
if (hash == "WEAPON_BIRD_CRAP"_J)
|
if (hash == "WEAPON_BIRD_CRAP"_J)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (exists(mapped_weapons, hash))
|
if (!exists(mapped_weapons, hash))
|
||||||
continue;
|
|
||||||
mapped_weapons.emplace_back(hash);
|
mapped_weapons.emplace_back(hash);
|
||||||
|
|
||||||
const auto human_name_hash = item.child("HumanNameHash").text().as_string();
|
const auto human_name_hash = item.child("HumanNameHash").text().as_string();
|
||||||
@ -435,7 +477,7 @@ namespace big
|
|||||||
|
|
||||||
weapon.m_hash = hash;
|
weapon.m_hash = hash;
|
||||||
|
|
||||||
weapons.emplace_back(std::move(weapon));
|
weapons[hash] = weapon;
|
||||||
skip:
|
skip:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -475,6 +517,11 @@ namespace big
|
|||||||
yim_fipackfile::for_each_fipackfile();
|
yim_fipackfile::for_each_fipackfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mp_weapons_thread_id != 0)
|
||||||
|
{
|
||||||
|
SCRIPT::TERMINATE_THREAD(mp_weapons_thread_id);
|
||||||
|
}
|
||||||
|
|
||||||
static bool translate_label = false;
|
static bool translate_label = false;
|
||||||
|
|
||||||
g_fiber_pool->queue_job([&] {
|
g_fiber_pool->queue_job([&] {
|
||||||
@ -488,7 +535,7 @@ namespace big
|
|||||||
}
|
}
|
||||||
for (auto& item : weapons)
|
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)
|
for (auto& item : weapon_components)
|
||||||
{
|
{
|
||||||
@ -555,8 +602,8 @@ namespace big
|
|||||||
m_weapons_cache.weapon_map.clear();
|
m_weapons_cache.weapon_map.clear();
|
||||||
for (auto weapon : weapons)
|
for (auto weapon : weapons)
|
||||||
{
|
{
|
||||||
add_if_not_exists(m_weapon_types, weapon.m_weapon_type);
|
add_if_not_exists(m_weapon_types, weapon.second.m_weapon_type);
|
||||||
m_weapons_cache.weapon_map.insert({weapon.m_name, weapon});
|
m_weapons_cache.weapon_map.insert({weapon.second.m_name, weapon.second});
|
||||||
}
|
}
|
||||||
|
|
||||||
m_weapons_cache.weapon_components.clear();
|
m_weapons_cache.weapon_components.clear();
|
||||||
|
@ -290,8 +290,7 @@ namespace big
|
|||||||
Hash attachment_hash = attachment_component.m_hash;
|
Hash attachment_hash = attachment_component.m_hash;
|
||||||
if (attachment_hash == NULL)
|
if (attachment_hash == NULL)
|
||||||
{
|
{
|
||||||
attachment_name = attachment;
|
continue;
|
||||||
attachment_hash = rage::joaat(attachment);
|
|
||||||
}
|
}
|
||||||
bool is_selected = attachment_hash == selected_weapon_attachment_hash;
|
bool is_selected = attachment_hash == selected_weapon_attachment_hash;
|
||||||
std::string display_name = attachment_name.append("##").append(std::to_string(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 = attachment_name;
|
||||||
selected_weapon_attachment_hash = attachment_hash;
|
selected_weapon_attachment_hash = attachment_hash;
|
||||||
}
|
}
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
ImGui::SetTooltip(attachment_component.m_display_desc.c_str());
|
||||||
if (is_selected)
|
if (is_selected)
|
||||||
{
|
{
|
||||||
ImGui::SetItemDefaultFocus();
|
ImGui::SetItemDefaultFocus();
|
||||||
|
Reference in New Issue
Block a user