mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +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_NOTETRACKSOUNDMAP,
|
||||
WFT_WEAPON_CAMO,
|
||||
WFT_ATTACHMENTS,
|
||||
WFT_ATTACHMENT_UNIQUES,
|
||||
|
||||
WFT_NUM_FIELD_TYPES
|
||||
};
|
||||
|
@ -1031,5 +1031,7 @@ namespace T6
|
||||
{"customBool0", offsetof(WeaponFullDef, weapDef.customBool0), CSPFT_BOOL},
|
||||
{"customBool1", offsetof(WeaponFullDef, weapDef.customBool1), 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;
|
||||
}
|
||||
|
||||
_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:
|
||||
bool ConvertExtensionField(const cspField_t& field, const std::string& value) override
|
||||
{
|
||||
@ -228,6 +337,12 @@ namespace T6
|
||||
case WFT_WEAPON_CAMO:
|
||||
return ConvertWeaponCamo(field, value);
|
||||
|
||||
case WFT_ATTACHMENTS:
|
||||
return ConvertAttachments(field, value);
|
||||
|
||||
case WFT_ATTACHMENT_UNIQUES:
|
||||
return ConvertAttachmentUniques(field, value);
|
||||
|
||||
case WFT_NUM_FIELD_TYPES:
|
||||
default:
|
||||
assert(false);
|
||||
|
@ -214,6 +214,50 @@ namespace T6
|
||||
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:
|
||||
default:
|
||||
assert(false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user