mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-21 00:25:44 +00:00
Dump and read attachment and attachment uniques to and from weapon files
This commit is contained in:
parent
540e631fd5
commit
055dd5e840
@ -91,6 +91,8 @@ namespace T6
|
|||||||
WFT_EXPLOSION_TAG,
|
WFT_EXPLOSION_TAG,
|
||||||
WFT_NOTETRACKSOUNDMAP,
|
WFT_NOTETRACKSOUNDMAP,
|
||||||
WFT_WEAPON_CAMO,
|
WFT_WEAPON_CAMO,
|
||||||
|
WFT_ATTACHMENTS,
|
||||||
|
WFT_ATTACHMENT_UNIQUES,
|
||||||
|
|
||||||
WFT_NUM_FIELD_TYPES
|
WFT_NUM_FIELD_TYPES
|
||||||
};
|
};
|
||||||
|
@ -1031,5 +1031,7 @@ namespace T6
|
|||||||
{"customBool0", offsetof(WeaponFullDef, weapDef.customBool0), CSPFT_BOOL},
|
{"customBool0", offsetof(WeaponFullDef, weapDef.customBool0), CSPFT_BOOL},
|
||||||
{"customBool1", offsetof(WeaponFullDef, weapDef.customBool1), CSPFT_BOOL},
|
{"customBool1", offsetof(WeaponFullDef, weapDef.customBool1), CSPFT_BOOL},
|
||||||
{"customBool2", offsetof(WeaponFullDef, weapDef.customBool2), CSPFT_BOOL},
|
{"customBool2", offsetof(WeaponFullDef, weapDef.customBool2), CSPFT_BOOL},
|
||||||
|
{"attachments", offsetof(WeaponFullDef, attachments), WFT_ATTACHMENTS},
|
||||||
|
{"attachmentUniques", offsetof(WeaponFullDef, attachmentUniques), WFT_ATTACHMENT_UNIQUES}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -141,6 +141,115 @@ namespace T6
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_NODISCARD bool ConvertAttachments(const cspField_t& field, const std::string& value)
|
||||||
|
{
|
||||||
|
std::vector<std::string> valueArray;
|
||||||
|
if (!ParseAsArray(value, valueArray))
|
||||||
|
{
|
||||||
|
std::cout << "Failed to parse attachments as array" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto** attachments = reinterpret_cast<WeaponAttachment**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
|
||||||
|
for (const auto& attachmentName : valueArray)
|
||||||
|
{
|
||||||
|
auto* attachmentAssetInfo = m_loading_manager->LoadDependency(ASSET_TYPE_ATTACHMENT, attachmentName);
|
||||||
|
if (attachmentAssetInfo == nullptr)
|
||||||
|
{
|
||||||
|
std::cout << "Failed to load attachment asset \"" << attachmentName << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* attachmentAsset = static_cast<WeaponAttachment*>(attachmentAssetInfo->m_ptr);
|
||||||
|
|
||||||
|
if (static_cast<unsigned>(attachmentAsset->attachmentType) >= ATTACHMENT_TYPE_COUNT)
|
||||||
|
{
|
||||||
|
std::cout << "Invalid attachment type " << attachmentAsset->attachmentType << " for attachment asset \"" << attachmentName << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachments[attachmentAsset->attachmentType] != nullptr)
|
||||||
|
{
|
||||||
|
std::cout << "Already loaded attachment with same type " << attachmentAsset->attachmentType
|
||||||
|
<< ": \"" << attachments[attachmentAsset->attachmentType]->szInternalName << "\", \""
|
||||||
|
<< attachmentName << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
attachments[attachmentAsset->attachmentType] = attachmentAsset;
|
||||||
|
m_dependencies.emplace(attachmentAssetInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_NODISCARD static bool HasMoreThanOneAttachmentSetInMask(const int mask)
|
||||||
|
{
|
||||||
|
// Check if int has more than 1 bit set
|
||||||
|
return (mask & (mask - 1)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_NODISCARD bool ConvertAttachmentUniques(const cspField_t& field, const std::string& value)
|
||||||
|
{
|
||||||
|
std::vector<std::string> valueArray;
|
||||||
|
if (!ParseAsArray(value, valueArray))
|
||||||
|
{
|
||||||
|
std::cout << "Failed to parse attachment uniques as array" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto** attachmentUniques = reinterpret_cast<WeaponAttachmentUnique**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
auto attachmentCombinationIndex = std::extent<decltype(WeaponFullDef::attachments)>::value;
|
||||||
|
|
||||||
|
for (const auto& attachmentUniqueName : valueArray)
|
||||||
|
{
|
||||||
|
auto* attachmentUniqueAssetInfo = m_loading_manager->LoadDependency(ASSET_TYPE_ATTACHMENT_UNIQUE, attachmentUniqueName);
|
||||||
|
if (attachmentUniqueAssetInfo == nullptr)
|
||||||
|
{
|
||||||
|
std::cout << "Failed to load attachment unique asset \"" << attachmentUniqueName << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* attachmentUniqueAsset = static_cast<WeaponAttachmentUnique*>(attachmentUniqueAssetInfo->m_ptr);
|
||||||
|
|
||||||
|
if (HasMoreThanOneAttachmentSetInMask(attachmentUniqueAsset->combinedAttachmentTypeMask))
|
||||||
|
{
|
||||||
|
if (attachmentCombinationIndex >= std::extent<decltype(WeaponFullDef::attachmentUniques)>::value)
|
||||||
|
{
|
||||||
|
std::cout << "Cannot have more than "
|
||||||
|
<< (std::extent<decltype(WeaponFullDef::attachmentUniques)>::value - std::extent<decltype(WeaponFullDef::attachments)>::value)
|
||||||
|
<< " combined attachment attachment unique entries!" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
attachmentUniques[attachmentCombinationIndex++] = attachmentUniqueAsset;
|
||||||
|
m_dependencies.emplace(attachmentUniqueAssetInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (static_cast<unsigned>(attachmentUniqueAsset->attachmentType) >= ATTACHMENT_TYPE_COUNT)
|
||||||
|
{
|
||||||
|
std::cout << "Invalid attachment type " << attachmentUniqueAsset->attachmentType << " for attachment unique asset \"" << attachmentUniqueName << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachmentUniques[attachmentUniqueAsset->attachmentType] != nullptr)
|
||||||
|
{
|
||||||
|
std::cout << "Already loaded attachment unique with same type " << attachmentUniqueAsset->attachmentType
|
||||||
|
<< ": \"" << attachmentUniques[attachmentUniqueAsset->attachmentType]->szInternalName << "\", \""
|
||||||
|
<< attachmentUniqueName << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
attachmentUniques[attachmentUniqueAsset->attachmentType] = attachmentUniqueAsset;
|
||||||
|
m_dependencies.emplace(attachmentUniqueAssetInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ConvertExtensionField(const cspField_t& field, const std::string& value) override
|
bool ConvertExtensionField(const cspField_t& field, const std::string& value) override
|
||||||
{
|
{
|
||||||
@ -228,6 +337,12 @@ namespace T6
|
|||||||
case WFT_WEAPON_CAMO:
|
case WFT_WEAPON_CAMO:
|
||||||
return ConvertWeaponCamo(field, value);
|
return ConvertWeaponCamo(field, value);
|
||||||
|
|
||||||
|
case WFT_ATTACHMENTS:
|
||||||
|
return ConvertAttachments(field, value);
|
||||||
|
|
||||||
|
case WFT_ATTACHMENT_UNIQUES:
|
||||||
|
return ConvertAttachmentUniques(field, value);
|
||||||
|
|
||||||
case WFT_NUM_FIELD_TYPES:
|
case WFT_NUM_FIELD_TYPES:
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -214,6 +214,50 @@ namespace T6
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WFT_ATTACHMENTS:
|
||||||
|
{
|
||||||
|
const auto* attachments = reinterpret_cast<WeaponAttachment**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
std::stringstream ss;
|
||||||
|
auto first = true;
|
||||||
|
|
||||||
|
for (auto i = 0u; i < std::extent<decltype(WeaponFullDef::attachments)>::value; i++)
|
||||||
|
{
|
||||||
|
if (attachments[i])
|
||||||
|
{
|
||||||
|
if (!first)
|
||||||
|
ss << "\n";
|
||||||
|
else
|
||||||
|
first = false;
|
||||||
|
ss << AssetName(attachments[i]->szInternalName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), ss.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WFT_ATTACHMENT_UNIQUES:
|
||||||
|
{
|
||||||
|
const auto* attachmentUniques = reinterpret_cast<WeaponAttachmentUnique**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
std::stringstream ss;
|
||||||
|
auto first = true;
|
||||||
|
|
||||||
|
for (auto i = 0u; i < std::extent<decltype(WeaponFullDef::attachmentUniques)>::value; i++)
|
||||||
|
{
|
||||||
|
if (attachmentUniques[i])
|
||||||
|
{
|
||||||
|
if (!first)
|
||||||
|
ss << "\n";
|
||||||
|
else
|
||||||
|
first = false;
|
||||||
|
ss << AssetName(attachmentUniques[i]->szInternalName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), ss.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WFT_NUM_FIELD_TYPES:
|
case WFT_NUM_FIELD_TYPES:
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user