Refactor Weapons JSON parser to associate path with recentness (#3565)

* Added a RPF parse hierarchy to ensure the latest weapon file is loaded into the Weapons JSON.
* Fixed erroneous attachment descriptions being displayed and persisted to the Weapons JSON.
* Fix for components that had empty descriptions.
This commit is contained in:
gir489 2024-08-14 02:41:47 -04:00 committed by GitHub
parent eecd20beaf
commit d1e4b0830c
3 changed files with 63 additions and 10 deletions

View File

@ -218,6 +218,27 @@ namespace big
std::sort(m_weapon_types.begin(), m_weapon_types.end());
}
static RPFDatafileSource determine_file_type(std::string file_path, std::string_view rpf_filename)
{
if (file_path.contains("/dlc_patch/"))
{
return RPFDatafileSource::DLCUPDATE;
}
else if (rpf_filename == "dlc.rpf")
{
return RPFDatafileSource::DLC;
}
else if (rpf_filename == "update.rpf")
{
return RPFDatafileSource::UPDATE;
}
else if (rpf_filename == "common.rpf")
{
return RPFDatafileSource::BASE;
}
return RPFDatafileSource::UNKNOWN;
}
inline void parse_ped(std::vector<ped_item>& peds, std::vector<uint32_t>& mapped_peds, pugi::xml_document& doc)
{
const auto& items = doc.select_nodes("/CPedModelInfo__InitDataList/InitDatas/Item");
@ -261,7 +282,7 @@ namespace big
std::vector<ped_item> peds;
std::vector<vehicle_item> vehicles;
//std::vector<weapon_item> weapons;
std::unordered_map<Hash, weapon_item> weapons;
std::unordered_map<Hash, weapon_item_parsed> weapons;
std::vector<weapon_component> weapon_components;
constexpr auto exists = [](const hash_array& arr, uint32_t val) -> bool {
@ -377,6 +398,9 @@ namespace big
LocDesc = display_string;
}
if (LocDesc.ends_with("INVALID"))
LocDesc.clear();
weapon_component component;
component.m_name = name;
@ -388,9 +412,9 @@ namespace big
}
});
}
else if (const auto file_str = path.string(); file_str.find("weapon") != std::string::npos && path.extension() == ".meta")
else if (const auto file_str = path.string(); file_str.contains("weapon") && !file_str.contains("vehicle") && path.extension() == ".meta")
{
rpf_wrapper.read_xml_file(path, [&exists, &weapons, &mapped_weapons](pugi::xml_document& doc) {
rpf_wrapper.read_xml_file(path, [&exists, &weapons, &mapped_weapons, file_str, &rpf_wrapper](pugi::xml_document& doc) {
const auto& items = doc.select_nodes("/CWeaponInfoBlob/Infos/Item/Infos/Item[@type='CWeaponInfo']");
for (const auto& item_node : items)
{
@ -408,11 +432,11 @@ namespace big
if (std::strcmp(human_name_hash, "WT_INVALID") == 0 || std::strcmp(human_name_hash, "WT_VEHMINE") == 0)
continue;
auto weapon = weapon_item{};
auto weapon = weapon_item_parsed{};
weapon.m_name = name;
weapon.m_display_name = human_name_hash;
weapon.rpf_file_type = determine_file_type(file_str, rpf_wrapper.get_name());
auto weapon_flags = std::string(item.child("WeaponFlags").text().as_string());
@ -477,6 +501,14 @@ namespace big
weapon.m_hash = hash;
if (weapons.contains(hash))
{
if (weapons[hash].rpf_file_type > weapon.rpf_file_type)
{
continue;
}
}
weapons[hash] = weapon;
skip:
continue;
@ -540,7 +572,12 @@ namespace big
for (auto& item : weapon_components)
{
item.m_display_name = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(item.m_display_name.c_str());
item.m_display_desc = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(item.m_display_desc.c_str());
if (!item.m_display_desc.empty())
{
item.m_display_desc = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(item.m_display_desc.c_str());
if (item.m_display_desc == "NULL")
item.m_display_desc.clear();
}
}
for (auto it = peds.begin(); it != peds.end();)
{

View File

@ -2,7 +2,16 @@
namespace big
{
class weapon_item final
enum RPFDatafileSource : std::uint8_t
{
UNKNOWN,
BASE,
UPDATE,
DLC,
DLCUPDATE
};
class weapon_item
{
public:
std::string m_name;
@ -16,4 +25,10 @@ namespace big
NLOHMANN_DEFINE_TYPE_INTRUSIVE(weapon_item, m_name, m_display_name, m_weapon_type, m_hash, m_reward_hash, m_reward_ammo_hash, m_attachments, m_throwable)
};
class weapon_item_parsed : public weapon_item
{
public:
RPFDatafileSource rpf_file_type = RPFDatafileSource::UNKNOWN;
};
}

View File

@ -292,19 +292,20 @@ namespace big
{
continue;
}
ImGui::PushID(attachment_hash);
bool is_selected = attachment_hash == selected_weapon_attachment_hash;
std::string display_name = attachment_name.append("##").append(std::to_string(attachment_hash));
if (ImGui::Selectable(display_name.c_str(), is_selected, ImGuiSelectableFlags_None))
if (ImGui::Selectable(attachment_name.c_str(), is_selected, ImGuiSelectableFlags_None))
{
selected_weapon_attachment = attachment_name;
selected_weapon_attachment_hash = attachment_hash;
}
if (ImGui::IsItemHovered())
if (ImGui::IsItemHovered() && !attachment_component.m_display_desc.empty())
ImGui::SetTooltip(attachment_component.m_display_desc.c_str());
if (is_selected)
{
ImGui::SetItemDefaultFocus();
}
ImGui::PopID();
}
}