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:
parent
a1fb2ae6d8
commit
ee69b3b0b9
@ -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();)
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user