2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-08-30 21:53:15 +00:00

refactor: streamline weapon dumping

This commit is contained in:
Jan Laupetin
2025-08-03 13:12:50 +02:00
parent 58de885ebe
commit 0546572ecf
68 changed files with 1380 additions and 1349 deletions

View File

@@ -0,0 +1,16 @@
#include "AttachmentCommon.h"
#include <format>
namespace attachment
{
std::string GetInfoStringFileNameForAssetName(const std::string& assetName)
{
return std::format("attachment/{}", assetName);
}
std::string GetJsonFileNameForAssetName(const std::string& assetName)
{
return std::format("attachment/{}.json", assetName);
}
} // namespace attachment

View File

@@ -0,0 +1,9 @@
#pragma once
#include <string>
namespace attachment
{
std::string GetInfoStringFileNameForAssetName(const std::string& assetName);
std::string GetJsonFileNameForAssetName(const std::string& assetName);
} // namespace attachment

View File

@@ -0,0 +1,11 @@
#include "AttachmentUniqueCommon.h"
#include <format>
namespace attachment_unique
{
std::string GetFileNameForAssetName(const std::string& assetName)
{
return std::format("attachmentunique/{}", assetName);
}
} // namespace attachment_unique

View File

@@ -0,0 +1,8 @@
#pragma once
#include <string>
namespace attachment_unique
{
std::string GetFileNameForAssetName(const std::string& assetName);
}

View File

@@ -0,0 +1,11 @@
#include "WeaponCommon.h"
#include <format>
namespace camo
{
std::string GetJsonFileNameForAssetName(const std::string& assetName)
{
return std::format("camo/{}.json", assetName);
}
} // namespace camo

View File

@@ -0,0 +1,8 @@
#pragma once
#include <string>
namespace camo
{
std::string GetJsonFileNameForAssetName(const std::string& assetName);
}

View File

@@ -0,0 +1,11 @@
#include "WeaponCommon.h"
#include <format>
namespace weapon
{
std::string GetFileNameForAssetName(const std::string& assetName)
{
return std::format("weapons/{}", assetName);
}
} // namespace weapon

View File

@@ -0,0 +1,8 @@
#pragma once
#include <string>
namespace weapon
{
std::string GetFileNameForAssetName(const std::string& assetName);
}

View File

@@ -32,13 +32,13 @@
#include "Tracer/RawLoaderTracerT6.h"
#include "Vehicle/GdtLoaderVehicleT6.h"
#include "Vehicle/RawLoaderVehicleT6.h"
#include "Weapon/GdtLoaderAttachmentT6.h"
#include "Weapon/GdtLoaderAttachmentUniqueT6.h"
#include "Weapon/GdtLoaderWeaponT6.h"
#include "Weapon/LoaderWeaponCamoT6.h"
#include "Weapon/RawLoaderAttachmentT6.h"
#include "Weapon/RawLoaderAttachmentUniqueT6.h"
#include "Weapon/RawLoaderWeaponT6.h"
#include "Weapon/AttachmentGdtLoaderT6.h"
#include "Weapon/AttachmentRawLoaderT6.h"
#include "Weapon/AttachmentUniqueGdtLoaderT6.h"
#include "Weapon/AttachmentUniqueRawLoaderT6.h"
#include "Weapon/CamoJsonLoaderT6.h"
#include "Weapon/WeaponGdtLoaderT6.h"
#include "Weapon/WeaponRawLoaderT6.h"
#include "ZBarrier/GdtLoaderZBarrierT6.h"
#include "ZBarrier/RawLoaderZBarrierT6.h"
@@ -418,13 +418,13 @@ namespace T6
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenuList>(memory));
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenu>(memory));
collection.AddAssetCreator(CreateLocalizeLoader(memory, searchPath, zone));
collection.AddAssetCreator(CreateRawWeaponLoader(memory, searchPath, zone));
collection.AddAssetCreator(CreateGdtWeaponLoader(memory, searchPath, gdt, zone));
collection.AddAssetCreator(CreateRawAttachmentLoader(memory, searchPath, zone));
collection.AddAssetCreator(CreateGdtAttachmentLoader(memory, searchPath, gdt, zone));
collection.AddAssetCreator(CreateRawAttachmentUniqueLoader(memory, searchPath, zone));
collection.AddAssetCreator(CreateGdtAttachmentUniqueLoader(memory, searchPath, gdt, zone));
collection.AddAssetCreator(CreateWeaponCamoLoader(memory, searchPath));
collection.AddAssetCreator(weapon::CreateRawLoader(memory, searchPath, zone));
collection.AddAssetCreator(weapon::CreateGdtLoader(memory, searchPath, gdt, zone));
collection.AddAssetCreator(attachment::CreateRawLoader(memory, searchPath, zone));
collection.AddAssetCreator(attachment::CreateGdtLoader(memory, searchPath, gdt, zone));
collection.AddAssetCreator(attachment_unique::CreateRawLoader(memory, searchPath, zone));
collection.AddAssetCreator(attachment_unique::CreateGdtLoader(memory, searchPath, gdt, zone));
collection.AddAssetCreator(camo::CreateJsonLoader(memory, searchPath));
// collection.AddAssetCreator(std::make_unique<AssetLoaderSoundDriverGlobals>(memory));
// collection.AddAssetCreator(std::make_unique<AssetLoaderFx>(memory));
// collection.AddAssetCreator(std::make_unique<AssetLoaderImpactFx>(memory));

View File

@@ -1,9 +1,9 @@
#include "GdtLoaderAttachmentT6.h"
#include "AttachmentGdtLoaderT6.h"
#include "AttachmentInfoStringLoaderT6.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/T6.h"
#include "InfoString/InfoString.h"
#include "InfoStringLoaderAttachmentT6.h"
#include <cstring>
#include <format>
@@ -40,14 +40,14 @@ namespace
private:
IGdtQueryable& m_gdt;
InfoStringLoaderAttachment m_info_string_loader;
T6::attachment::InfoStringLoader m_info_string_loader;
};
} // namespace
namespace T6
namespace T6::attachment
{
std::unique_ptr<AssetCreator<AssetAttachment>> CreateGdtAttachmentLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
std::unique_ptr<AssetCreator<AssetAttachment>> CreateGdtLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
{
return std::make_unique<GdtLoaderAttachment>(memory, searchPath, gdt, zone);
}
} // namespace T6
} // namespace T6::attachment

View File

@@ -0,0 +1,14 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T6/T6.h"
#include "Gdt/IGdtQueryable.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace T6::attachment
{
std::unique_ptr<AssetCreator<AssetAttachment>> CreateGdtLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
} // namespace T6::attachment

View File

@@ -1,4 +1,4 @@
#include "InfoStringLoaderAttachmentT6.h"
#include "AttachmentInfoStringLoaderT6.h"
#include "Game/T6/InfoString/InfoStringToStructConverter.h"
#include "Game/T6/T6.h"
@@ -93,29 +93,32 @@ namespace
}
} // namespace
InfoStringLoaderAttachment::InfoStringLoaderAttachment(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
: m_memory(memory),
m_search_path(searchPath),
m_zone(zone)
namespace T6::attachment
{
}
AssetCreationResult InfoStringLoaderAttachment::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
{
auto* attachment = m_memory.Alloc<WeaponAttachment>();
attachment->szInternalName = m_memory.Dup(assetName.c_str());
AssetRegistration<AssetAttachment> registration(assetName, attachment);
InfoStringToAttachmentConverter converter(
infoString, *attachment, m_zone.m_script_strings, m_memory, context, registration, attachment_fields, std::extent_v<decltype(attachment_fields)>);
if (!converter.Convert())
InfoStringLoader::InfoStringLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
: m_memory(memory),
m_search_path(searchPath),
m_zone(zone)
{
std::cerr << std::format("Failed to parse attachment: \"{}\"\n", assetName);
return AssetCreationResult::Failure();
}
CalculateAttachmentFields(*attachment);
AssetCreationResult InfoStringLoader::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
{
auto* attachment = m_memory.Alloc<WeaponAttachment>();
attachment->szInternalName = m_memory.Dup(assetName.c_str());
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
AssetRegistration<AssetAttachment> registration(assetName, attachment);
InfoStringToAttachmentConverter converter(
infoString, *attachment, m_zone.m_script_strings, m_memory, context, registration, attachment_fields, std::extent_v<decltype(attachment_fields)>);
if (!converter.Convert())
{
std::cerr << std::format("Failed to parse attachment: \"{}\"\n", assetName);
return AssetCreationResult::Failure();
}
CalculateAttachmentFields(*attachment);
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
} // namespace T6::attachment

View File

@@ -4,12 +4,12 @@
#include "Asset/AssetCreationResult.h"
#include "InfoString/InfoString.h"
namespace T6
namespace T6::attachment
{
class InfoStringLoaderAttachment
class InfoStringLoader
{
public:
InfoStringLoaderAttachment(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
InfoStringLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
AssetCreationResult CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context);
@@ -18,4 +18,4 @@ namespace T6
ISearchPath& m_search_path;
Zone& m_zone;
};
} // namespace T6
} // namespace T6::attachment

View File

@@ -1,15 +1,17 @@
#include "RawLoaderAttachmentT6.h"
#include "AttachmentRawLoaderT6.h"
#include "AttachmentInfoStringLoaderT6.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/T6.h"
#include "InfoString/InfoString.h"
#include "InfoStringLoaderAttachmentT6.h"
#include "Weapon/AttachmentCommon.h"
#include <cstring>
#include <format>
#include <iostream>
using namespace T6;
using namespace ::attachment;
namespace
{
@@ -24,7 +26,7 @@ namespace
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
const auto fileName = std::format("attachment/{}", assetName);
const auto fileName = GetInfoStringFileNameForAssetName(assetName);
const auto file = m_search_path.Open(fileName);
if (!file.IsOpen())
return AssetCreationResult::NoAction();
@@ -41,14 +43,14 @@ namespace
private:
ISearchPath& m_search_path;
InfoStringLoaderAttachment m_info_string_loader;
T6::attachment::InfoStringLoader m_info_string_loader;
};
} // namespace
namespace T6
namespace T6::attachment
{
std::unique_ptr<AssetCreator<AssetAttachment>> CreateRawAttachmentLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
std::unique_ptr<AssetCreator<AssetAttachment>> CreateRawLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
{
return std::make_unique<RawLoaderAttachment>(memory, searchPath, zone);
}
} // namespace T6
} // namespace T6::attachment

View File

@@ -0,0 +1,13 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T6/T6.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace T6::attachment
{
std::unique_ptr<AssetCreator<AssetAttachment>> CreateRawLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
} // namespace T6::attachment

View File

@@ -1,9 +1,9 @@
#include "GdtLoaderAttachmentUniqueT6.h"
#include "AttachmentUniqueGdtLoaderT6.h"
#include "AttachmentUniqueInfoStringLoaderT6.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/T6.h"
#include "InfoString/InfoString.h"
#include "InfoStringLoaderAttachmentUniqueT6.h"
#include <cstring>
#include <format>
@@ -40,15 +40,14 @@ namespace
private:
IGdtQueryable& m_gdt;
InfoStringLoaderAttachmentUnique m_info_string_loader;
T6::attachment_unique::InfoStringLoader m_info_string_loader;
};
} // namespace
namespace T6
namespace T6::attachment_unique
{
std::unique_ptr<AssetCreator<AssetAttachmentUnique>>
CreateGdtAttachmentUniqueLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
std::unique_ptr<AssetCreator<AssetAttachmentUnique>> CreateGdtLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
{
return std::make_unique<GdtLoaderAttachmentUnique>(memory, searchPath, gdt, zone);
}
} // namespace T6
} // namespace T6::attachment_unique

View File

@@ -0,0 +1,14 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T6/T6.h"
#include "Gdt/IGdtQueryable.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace T6::attachment_unique
{
std::unique_ptr<AssetCreator<AssetAttachmentUnique>> CreateGdtLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
} // namespace T6::attachment_unique

View File

@@ -1,4 +1,4 @@
#include "InfoStringLoaderAttachmentUniqueT6.h"
#include "AttachmentUniqueInfoStringLoaderT6.h"
#include "Game/T6/InfoString/InfoStringToStructConverter.h"
#include "Game/T6/T6.h"
@@ -141,7 +141,7 @@ namespace
{
// combinedAttachmentTypeMask
std::vector<eAttachment> attachmentsFromName;
if (!InfoStringLoaderAttachmentUnique::ExtractAttachmentsFromAssetName(assetName, attachmentsFromName))
if (!T6::attachment_unique::ExtractAttachmentsFromAssetName(assetName, attachmentsFromName))
{
std::cerr << std::format("Failed to determine attachments from attachment unique name \"{}\"\n", assetName);
return false;
@@ -159,86 +159,89 @@ namespace
}
} // namespace
bool InfoStringLoaderAttachmentUnique::ExtractAttachmentsFromAssetName(const std::string& assetName, std::vector<eAttachment>& attachmentList)
namespace T6::attachment_unique
{
std::vector<std::string> parts;
auto attachCount = 1u;
auto partStart = 0u;
for (auto ci = 0u; ci < assetName.size(); ci++)
bool ExtractAttachmentsFromAssetName(const std::string& assetName, std::vector<eAttachment>& attachmentList)
{
if (assetName[ci] == '_')
std::vector<std::string> parts;
auto attachCount = 1u;
auto partStart = 0u;
for (auto ci = 0u; ci < assetName.size(); ci++)
{
parts.emplace_back(assetName, partStart, ci - partStart);
partStart = ci + 1;
}
else if (assetName[ci] == '+')
{
attachCount++;
parts.emplace_back(assetName, partStart, ci - partStart);
partStart = ci + 1;
}
}
if (partStart < assetName.size())
parts.emplace_back(assetName, partStart, assetName.size() - partStart);
for (auto attachPartOffset = parts.size() - attachCount; attachPartOffset < parts.size(); attachPartOffset++)
{
auto& specifiedAttachName = parts[attachPartOffset];
for (auto& c : specifiedAttachName)
c = static_cast<char>(tolower(c));
auto foundAttachment = false;
for (auto attachIndex = 0u; attachIndex < std::extent_v<decltype(szAttachmentTypeNames)>; attachIndex++)
{
if (specifiedAttachName == szAttachmentTypeNames[attachIndex])
if (assetName[ci] == '_')
{
attachmentList.push_back(static_cast<eAttachment>(attachIndex));
foundAttachment = true;
break;
parts.emplace_back(assetName, partStart, ci - partStart);
partStart = ci + 1;
}
else if (assetName[ci] == '+')
{
attachCount++;
parts.emplace_back(assetName, partStart, ci - partStart);
partStart = ci + 1;
}
}
if (!foundAttachment)
return false;
if (partStart < assetName.size())
parts.emplace_back(assetName, partStart, assetName.size() - partStart);
for (auto attachPartOffset = parts.size() - attachCount; attachPartOffset < parts.size(); attachPartOffset++)
{
auto& specifiedAttachName = parts[attachPartOffset];
for (auto& c : specifiedAttachName)
c = static_cast<char>(tolower(c));
auto foundAttachment = false;
for (auto attachIndex = 0u; attachIndex < std::extent_v<decltype(szAttachmentTypeNames)>; attachIndex++)
{
if (specifiedAttachName == szAttachmentTypeNames[attachIndex])
{
attachmentList.push_back(static_cast<eAttachment>(attachIndex));
foundAttachment = true;
break;
}
}
if (!foundAttachment)
return false;
}
return true;
}
return true;
}
InfoStringLoaderAttachmentUnique::InfoStringLoaderAttachmentUnique(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
: m_memory(memory),
m_search_path(searchPath),
m_zone(zone)
{
}
AssetCreationResult InfoStringLoaderAttachmentUnique::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
{
auto* attachmentUniqueFull = m_memory.Alloc<WeaponAttachmentUniqueFull>();
attachmentUniqueFull->attachment.szInternalName = m_memory.Dup(assetName.c_str());
LinkAttachmentUniqueFullSubStructs(*attachmentUniqueFull);
AssetRegistration<AssetAttachmentUnique> registration(assetName, &attachmentUniqueFull->attachment);
InfoStringToAttachmentUniqueConverter converter(infoString,
*attachmentUniqueFull,
m_zone.m_script_strings,
m_memory,
context,
registration,
attachment_unique_fields,
std::extent_v<decltype(attachment_unique_fields)>);
if (!converter.Convert())
InfoStringLoader::InfoStringLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
: m_memory(memory),
m_search_path(searchPath),
m_zone(zone)
{
std::cerr << std::format("Failed to parse attachment unique: \"{}\"\n", assetName);
return AssetCreationResult::Failure();
}
CalculateAttachmentUniqueFields(assetName, *attachmentUniqueFull);
AssetCreationResult InfoStringLoader::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
{
auto* attachmentUniqueFull = m_memory.Alloc<WeaponAttachmentUniqueFull>();
attachmentUniqueFull->attachment.szInternalName = m_memory.Dup(assetName.c_str());
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
LinkAttachmentUniqueFullSubStructs(*attachmentUniqueFull);
AssetRegistration<AssetAttachmentUnique> registration(assetName, &attachmentUniqueFull->attachment);
InfoStringToAttachmentUniqueConverter converter(infoString,
*attachmentUniqueFull,
m_zone.m_script_strings,
m_memory,
context,
registration,
attachment_unique_fields,
std::extent_v<decltype(attachment_unique_fields)>);
if (!converter.Convert())
{
std::cerr << std::format("Failed to parse attachment unique: \"{}\"\n", assetName);
return AssetCreationResult::Failure();
}
CalculateAttachmentUniqueFields(assetName, *attachmentUniqueFull);
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
} // namespace T6::attachment_unique

View File

@@ -7,20 +7,20 @@
#include <vector>
namespace T6
namespace T6::attachment_unique
{
class InfoStringLoaderAttachmentUnique
bool ExtractAttachmentsFromAssetName(const std::string& assetName, std::vector<eAttachment>& attachmentList);
class InfoStringLoader
{
public:
InfoStringLoaderAttachmentUnique(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
InfoStringLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
AssetCreationResult CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context);
static bool ExtractAttachmentsFromAssetName(const std::string& assetName, std::vector<eAttachment>& attachmentList);
private:
MemoryManager& m_memory;
ISearchPath& m_search_path;
Zone& m_zone;
};
} // namespace T6
} // namespace T6::attachment_unique

View File

@@ -1,22 +1,24 @@
#include "RawLoaderAttachmentUniqueT6.h"
#include "AttachmentUniqueRawLoaderT6.h"
#include "AttachmentUniqueInfoStringLoaderT6.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/T6.h"
#include "InfoString/InfoString.h"
#include "InfoStringLoaderAttachmentUniqueT6.h"
#include "Weapon/AttachmentUniqueCommon.h"
#include <cstring>
#include <format>
#include <iostream>
using namespace T6;
using namespace ::attachment_unique;
namespace
{
class RawLoaderAttachmentUnique final : public AssetCreator<AssetAttachmentUnique>
class RawLoader final : public AssetCreator<AssetAttachmentUnique>
{
public:
RawLoaderAttachmentUnique(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
RawLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
: m_search_path(searchPath),
m_info_string_loader(memory, searchPath, zone)
{
@@ -24,7 +26,7 @@ namespace
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
const auto fileName = std::format("attachmentunique/{}", assetName);
const auto fileName = GetFileNameForAssetName(assetName);
const auto file = m_search_path.Open(fileName);
if (!file.IsOpen())
return AssetCreationResult::NoAction();
@@ -41,14 +43,14 @@ namespace
private:
ISearchPath& m_search_path;
InfoStringLoaderAttachmentUnique m_info_string_loader;
T6::attachment_unique::InfoStringLoader m_info_string_loader;
};
} // namespace
namespace T6
namespace T6::attachment_unique
{
std::unique_ptr<AssetCreator<AssetAttachmentUnique>> CreateRawAttachmentUniqueLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
std::unique_ptr<AssetCreator<AssetAttachmentUnique>> CreateRawLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
{
return std::make_unique<RawLoaderAttachmentUnique>(memory, searchPath, zone);
return std::make_unique<RawLoader>(memory, searchPath, zone);
}
} // namespace T6
} // namespace T6::attachment_unique

View File

@@ -7,7 +7,7 @@
#include <memory>
namespace T6
namespace T6::attachment_unique
{
std::unique_ptr<AssetCreator<AssetAttachmentUnique>> CreateRawAttachmentUniqueLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
} // namespace T6
std::unique_ptr<AssetCreator<AssetAttachmentUnique>> CreateRawLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
} // namespace T6::attachment_unique

View File

@@ -1,14 +1,18 @@
#include "JsonWeaponCamoLoaderT6.h"
#include "CamoJsonLoaderT6.h"
#include "Game/T6/CommonT6.h"
#include "Game/T6/Json/JsonWeaponCamo.h"
#include "Game/T6/T6.h"
#include "Pool/GlobalAssetPool.h"
#include "Weapon/CamoCommon.h"
#include <cstring>
#include <format>
#include <iostream>
#include <nlohmann/json.hpp>
using namespace nlohmann;
using namespace T6;
using namespace ::camo;
namespace
{
@@ -55,7 +59,7 @@ namespace
private:
static void PrintError(const WeaponCamo& weaponCamo, const std::string& message)
{
std::cerr << "Cannot load weapon camo \"" << weaponCamo.name << "\": " << message << "\n";
std::cerr << std::format("Cannot load weapon camo \"{}\": {}\n", weaponCamo.name, message);
}
bool CreateWeaponCamoSetFromJson(const JsonWeaponCamoSet& jWeaponCamoSet, WeaponCamoSet& weaponCamoSet, const WeaponCamo& weaponCamo) const
@@ -237,15 +241,46 @@ namespace
AssetCreationContext& m_context;
AssetRegistration<AssetWeaponCamo>& m_registration;
};
class WeaponCamoLoader final : public AssetCreator<AssetWeaponCamo>
{
public:
WeaponCamoLoader(MemoryManager& memory, ISearchPath& searchPath)
: m_memory(memory),
m_search_path(searchPath)
{
}
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
const auto file = m_search_path.Open(GetJsonFileNameForAssetName(assetName));
if (!file.IsOpen())
return AssetCreationResult::NoAction();
auto* weaponCamo = m_memory.Alloc<WeaponCamo>();
weaponCamo->name = m_memory.Dup(assetName.c_str());
AssetRegistration<AssetWeaponCamo> registration(assetName, weaponCamo);
const JsonLoader loader(*file.m_stream, m_memory, context, registration);
if (!loader.Load(*weaponCamo))
{
std::cerr << std::format("Failed to load weapon camo \"{}\"\n", assetName);
return AssetCreationResult::Failure();
}
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
private:
MemoryManager& m_memory;
ISearchPath& m_search_path;
};
} // namespace
namespace T6
namespace T6::camo
{
bool LoadWeaponCamoAsJson(
std::istream& stream, WeaponCamo& weaponCamo, MemoryManager& memory, AssetCreationContext& context, AssetRegistration<AssetWeaponCamo>& registration)
std::unique_ptr<AssetCreator<AssetWeaponCamo>> CreateJsonLoader(MemoryManager& memory, ISearchPath& searchPath)
{
const JsonLoader loader(stream, memory, context, registration);
return loader.Load(weaponCamo);
return std::make_unique<WeaponCamoLoader>(memory, searchPath);
}
} // namespace T6
} // namespace T6::camo

View File

@@ -7,7 +7,7 @@
#include <memory>
namespace T6
namespace T6::camo
{
std::unique_ptr<AssetCreator<AssetWeaponCamo>> CreateWeaponCamoLoader(MemoryManager& memory, ISearchPath& searchPath);
} // namespace T6
std::unique_ptr<AssetCreator<AssetWeaponCamo>> CreateJsonLoader(MemoryManager& memory, ISearchPath& searchPath);
} // namespace T6::camo

View File

@@ -1,14 +0,0 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T6/T6.h"
#include "Gdt/IGdtQueryable.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace T6
{
std::unique_ptr<AssetCreator<AssetAttachment>> CreateGdtAttachmentLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
} // namespace T6

View File

@@ -1,15 +0,0 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T6/T6.h"
#include "Gdt/IGdtQueryable.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace T6
{
std::unique_ptr<AssetCreator<AssetAttachmentUnique>>
CreateGdtAttachmentUniqueLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
} // namespace T6

View File

@@ -1,14 +0,0 @@
#pragma once
#include "Asset/AssetCreationContext.h"
#include "Asset/AssetRegistration.h"
#include "Game/T6/T6.h"
#include "Utils/MemoryManager.h"
#include <istream>
namespace T6
{
bool LoadWeaponCamoAsJson(
std::istream& stream, WeaponCamo& weaponCamo, MemoryManager& memory, AssetCreationContext& context, AssetRegistration<AssetWeaponCamo>& registration);
} // namespace T6

View File

@@ -1,55 +0,0 @@
#include "LoaderWeaponCamoT6.h"
#include "Game/T6/T6.h"
#include "JsonWeaponCamoLoaderT6.h"
#include "Pool/GlobalAssetPool.h"
#include <cstring>
#include <format>
#include <iostream>
using namespace T6;
namespace
{
class WeaponCamoLoader final : public AssetCreator<AssetWeaponCamo>
{
public:
WeaponCamoLoader(MemoryManager& memory, ISearchPath& searchPath)
: m_memory(memory),
m_search_path(searchPath)
{
}
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
const auto file = m_search_path.Open(std::format("camo/{}.json", assetName));
if (!file.IsOpen())
return AssetCreationResult::NoAction();
auto* weaponCamo = m_memory.Alloc<WeaponCamo>();
weaponCamo->name = m_memory.Dup(assetName.c_str());
AssetRegistration<AssetWeaponCamo> registration(assetName, weaponCamo);
if (!LoadWeaponCamoAsJson(*file.m_stream, *weaponCamo, m_memory, context, registration))
{
std::cerr << std::format("Failed to load weapon camo \"{}\"\n", assetName);
return AssetCreationResult::Failure();
}
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
private:
MemoryManager& m_memory;
ISearchPath& m_search_path;
};
} // namespace
namespace T6
{
std::unique_ptr<AssetCreator<AssetWeaponCamo>> CreateWeaponCamoLoader(MemoryManager& memory, ISearchPath& searchPath)
{
return std::make_unique<WeaponCamoLoader>(memory, searchPath);
}
} // namespace T6

View File

@@ -1,13 +0,0 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T6/T6.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace T6
{
std::unique_ptr<AssetCreator<AssetAttachment>> CreateRawAttachmentLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
} // namespace T6

View File

@@ -1,13 +0,0 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T6/T6.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace T6
{
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
} // namespace T6

View File

@@ -1,9 +1,9 @@
#include "GdtLoaderWeaponT6.h"
#include "WeaponGdtLoaderT6.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/T6.h"
#include "InfoString/InfoString.h"
#include "InfoStringLoaderWeaponT6.h"
#include "WeaponInfoStringLoaderT6.h"
#include <cstring>
#include <format>
@@ -40,14 +40,14 @@ namespace
private:
IGdtQueryable& m_gdt;
InfoStringLoaderWeapon m_info_string_loader;
T6::weapon::InfoStringLoader m_info_string_loader;
};
} // namespace
namespace T6
namespace T6::weapon
{
std::unique_ptr<AssetCreator<AssetWeapon>> CreateGdtWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
std::unique_ptr<AssetCreator<AssetWeapon>> CreateGdtLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
{
return std::make_unique<GdtLoaderWeapon>(memory, searchPath, gdt, zone);
}
} // namespace T6
} // namespace T6::weapon

View File

@@ -8,7 +8,7 @@
#include <memory>
namespace T6
namespace T6::weapon
{
std::unique_ptr<AssetCreator<AssetWeapon>> CreateGdtWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
} // namespace T6
std::unique_ptr<AssetCreator<AssetWeapon>> CreateGdtLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
} // namespace T6::weapon

View File

@@ -1,10 +1,10 @@
#include "InfoStringLoaderWeaponT6.h"
#include "WeaponInfoStringLoaderT6.h"
#include "AttachmentUniqueInfoStringLoaderT6.h"
#include "Game/T6/InfoString/InfoStringToStructConverter.h"
#include "Game/T6/T6.h"
#include "Game/T6/Weapon/WeaponFields.h"
#include "Game/T6/Weapon/WeaponStrings.h"
#include "InfoStringLoaderAttachmentUniqueT6.h"
#include "Weapon/AccuracyGraphLoader.h"
#include <cassert>
@@ -568,8 +568,7 @@ namespace
&& weapon.attachmentUniques[attachmentUniqueIndex]->attachmentType != attachmentUnique.attachmentType)
{
std::vector<eAttachment> attachments;
if (InfoStringLoaderAttachmentUnique::ExtractAttachmentsFromAssetName(weapon.attachmentUniques[attachmentUniqueIndex]->szInternalName,
attachments)
if (T6::attachment_unique::ExtractAttachmentsFromAssetName(weapon.attachmentUniques[attachmentUniqueIndex]->szInternalName, attachments)
&& attachments.front() == attachmentUnique.attachmentType)
{
if (lastSibling == nullptr)
@@ -600,34 +599,37 @@ namespace
}
} // namespace
InfoStringLoaderWeapon::InfoStringLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
: m_memory(memory),
m_search_path(searchPath),
m_zone(zone)
namespace T6::weapon
{
}
AssetCreationResult InfoStringLoaderWeapon::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
{
auto* weaponFullDef = m_memory.Alloc<WeaponFullDef>();
weaponFullDef->weapVariantDef.szInternalName = m_memory.Dup(assetName.c_str());
LinkWeaponFullDefSubStructs(*weaponFullDef);
AssetRegistration<AssetWeapon> registration(assetName, &weaponFullDef->weapVariantDef);
InfoStringToWeaponConverter converter(
infoString, *weaponFullDef, m_zone.m_script_strings, m_memory, context, registration, weapon_fields, std::extent_v<decltype(weapon_fields)>);
if (!converter.Convert())
InfoStringLoader::InfoStringLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
: m_memory(memory),
m_search_path(searchPath),
m_zone(zone)
{
std::cerr << std::format("Failed to parse weapon: \"{}\"\n", assetName);
return AssetCreationResult::Failure();
}
CalculateWeaponFields(*weaponFullDef);
CalculateAttachmentFields(*weaponFullDef);
AssetCreationResult InfoStringLoader::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
{
auto* weaponFullDef = m_memory.Alloc<WeaponFullDef>();
weaponFullDef->weapVariantDef.szInternalName = m_memory.Dup(assetName.c_str());
LoadAccuracyGraphs(*weaponFullDef, m_memory, m_search_path, context);
LinkWeaponFullDefSubStructs(*weaponFullDef);
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
AssetRegistration<AssetWeapon> registration(assetName, &weaponFullDef->weapVariantDef);
InfoStringToWeaponConverter converter(
infoString, *weaponFullDef, m_zone.m_script_strings, m_memory, context, registration, weapon_fields, std::extent_v<decltype(weapon_fields)>);
if (!converter.Convert())
{
std::cerr << std::format("Failed to parse weapon: \"{}\"\n", assetName);
return AssetCreationResult::Failure();
}
CalculateWeaponFields(*weaponFullDef);
CalculateAttachmentFields(*weaponFullDef);
LoadAccuracyGraphs(*weaponFullDef, m_memory, m_search_path, context);
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
} // namespace T6::weapon

View File

@@ -4,12 +4,12 @@
#include "Asset/AssetCreationResult.h"
#include "InfoString/InfoString.h"
namespace T6
namespace T6::weapon
{
class InfoStringLoaderWeapon
class InfoStringLoader
{
public:
InfoStringLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
InfoStringLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
AssetCreationResult CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context);
@@ -18,4 +18,4 @@ namespace T6
ISearchPath& m_search_path;
Zone& m_zone;
};
} // namespace T6
} // namespace T6::weapon

View File

@@ -1,22 +1,24 @@
#include "RawLoaderWeaponT6.h"
#include "WeaponRawLoaderT6.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/T6.h"
#include "InfoString/InfoString.h"
#include "InfoStringLoaderWeaponT6.h"
#include "Weapon/WeaponCommon.h"
#include "WeaponInfoStringLoaderT6.h"
#include <cstring>
#include <format>
#include <iostream>
using namespace T6;
using namespace ::weapon;
namespace
{
class RawLoaderWeapon final : public AssetCreator<AssetWeapon>
class RawLoader final : public AssetCreator<AssetWeapon>
{
public:
RawLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
RawLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
: m_search_path(searchPath),
m_info_string_loader(memory, searchPath, zone)
{
@@ -24,7 +26,7 @@ namespace
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
const auto fileName = std::format("weapons/{}", assetName);
const auto fileName = GetFileNameForAssetName(assetName);
const auto file = m_search_path.Open(fileName);
if (!file.IsOpen())
return AssetCreationResult::NoAction();
@@ -41,14 +43,14 @@ namespace
private:
ISearchPath& m_search_path;
InfoStringLoaderWeapon m_info_string_loader;
T6::weapon::InfoStringLoader m_info_string_loader;
};
} // namespace
namespace T6
namespace T6::weapon
{
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
{
return std::make_unique<RawLoaderWeapon>(memory, searchPath, zone);
return std::make_unique<RawLoader>(memory, searchPath, zone);
}
} // namespace T6
} // namespace T6::weapon

View File

@@ -0,0 +1,13 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T6/T6.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace T6::weapon
{
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
} // namespace T6::weapon

View File

@@ -10,7 +10,6 @@
#include "RawFile/RawFileDumperIW3.h"
#include "Sound/LoadedSoundDumperIW3.h"
#include "StringTable/StringTableDumperIW3.h"
#include "Weapon/AssetDumperWeapon.h"
using namespace IW3;

View File

@@ -24,7 +24,7 @@
#include "Techset/TechsetDumperIW4.h"
#include "Tracer/TracerDumperIW4.h"
#include "Vehicle/VehicleDumperIW4.h"
#include "Weapon/AssetDumperWeapon.h"
#include "Weapon/WeaponDumperIW4.h"
using namespace IW4;
@@ -66,7 +66,7 @@ bool ObjWriter::DumpZone(AssetDumpingContext& context) const
DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list, ASSET_TYPE_MENULIST)
DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def, ASSET_TYPE_MENU)
DUMP_ASSET_POOL(localize::Dumper, m_localize, ASSET_TYPE_LOCALIZE_ENTRY)
DUMP_ASSET_POOL(AssetDumperWeapon, m_weapon, ASSET_TYPE_WEAPON)
DUMP_ASSET_POOL(weapon::Dumper, m_weapon, ASSET_TYPE_WEAPON)
// DUMP_ASSET_POOL(AssetDumperSndDriverGlobals, m_snd_driver_globals, ASSET_TYPE_SNDDRIVER_GLOBALS)
// DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX)
// DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX)

View File

@@ -1,19 +0,0 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW4/IW4.h"
#include "InfoString/InfoString.h"
namespace IW4
{
class AssetDumperWeapon final : public AbstractAssetDumper<WeaponCompleteDef>
{
static void CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef);
static InfoString CreateInfoString(XAssetInfo<WeaponCompleteDef>* asset);
static void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset);
protected:
bool ShouldDump(XAssetInfo<WeaponCompleteDef>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset) override;
};
} // namespace IW4

View File

@@ -1,4 +1,4 @@
#include "AssetDumperWeapon.h"
#include "WeaponDumperIW4.h"
#include "Game/IW4/CommonIW4.h"
#include "Game/IW4/InfoString/EnumStrings.h"
@@ -6,6 +6,7 @@
#include "Game/IW4/ObjConstantsIW4.h"
#include "Game/IW4/Weapon/WeaponFields.h"
#include "Weapon/AccuracyGraphWriter.h"
#include "Weapon/WeaponCommon.h"
#include <cassert>
#include <cstring>
@@ -13,8 +14,9 @@
#include <type_traits>
using namespace IW4;
using namespace ::weapon;
namespace IW4
namespace
{
class InfoStringFromWeaponConverter final : public InfoStringFromStructConverter
{
@@ -237,195 +239,201 @@ namespace IW4
return graph;
}
} // namespace IW4
void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef)
{
fullDef->weapCompleteDef = *weapon;
if (weapon->weapDef)
void CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef)
{
fullDef->weapDef = *weapon->weapDef;
fullDef->weapCompleteDef.weapDef = &fullDef->weapDef;
fullDef->weapCompleteDef = *weapon;
if (weapon->weapDef)
{
fullDef->weapDef = *weapon->weapDef;
fullDef->weapCompleteDef.weapDef = &fullDef->weapDef;
}
if (weapon->hideTags)
{
assert(sizeof(WeaponFullDef::hideTags) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
memcpy(fullDef->hideTags, weapon->hideTags, sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
fullDef->weapCompleteDef.hideTags = fullDef->hideTags;
}
if (weapon->szXAnims)
{
assert(sizeof(WeaponFullDef::szXAnims) >= sizeof(void*) * NUM_WEAP_ANIMS);
memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * NUM_WEAP_ANIMS);
fullDef->weapCompleteDef.szXAnims = fullDef->szXAnims;
}
if (fullDef->weapDef.gunXModel)
{
assert(sizeof(WeaponFullDef::gunXModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
memcpy(fullDef->gunXModel, fullDef->weapDef.gunXModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
fullDef->weapDef.gunXModel = fullDef->gunXModel;
}
if (fullDef->weapDef.szXAnimsRightHanded)
{
assert(sizeof(WeaponFullDef::szXAnimsRightHanded) >= sizeof(void*) * NUM_WEAP_ANIMS);
memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * NUM_WEAP_ANIMS);
fullDef->weapDef.szXAnimsRightHanded = fullDef->szXAnimsRightHanded;
}
if (fullDef->weapDef.szXAnimsLeftHanded)
{
assert(sizeof(WeaponFullDef::szXAnimsLeftHanded) >= sizeof(void*) * NUM_WEAP_ANIMS);
memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * NUM_WEAP_ANIMS);
fullDef->weapDef.szXAnimsLeftHanded = fullDef->szXAnimsLeftHanded;
}
if (fullDef->weapDef.notetrackSoundMapKeys)
{
assert(sizeof(WeaponFullDef::notetrackSoundMapKeys) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
memcpy(fullDef->notetrackSoundMapKeys,
fullDef->weapDef.notetrackSoundMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
fullDef->weapDef.notetrackSoundMapKeys = fullDef->notetrackSoundMapKeys;
}
if (fullDef->weapDef.notetrackSoundMapValues)
{
assert(sizeof(WeaponFullDef::notetrackSoundMapValues) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
memcpy(fullDef->notetrackSoundMapValues,
fullDef->weapDef.notetrackSoundMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
fullDef->weapDef.notetrackSoundMapValues = fullDef->notetrackSoundMapValues;
}
if (fullDef->weapDef.notetrackRumbleMapKeys)
{
assert(sizeof(WeaponFullDef::notetrackRumbleMapKeys) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
memcpy(fullDef->notetrackRumbleMapKeys,
fullDef->weapDef.notetrackRumbleMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
fullDef->weapDef.notetrackRumbleMapKeys = fullDef->notetrackRumbleMapKeys;
}
if (fullDef->weapDef.notetrackRumbleMapValues)
{
assert(sizeof(WeaponFullDef::notetrackRumbleMapValues) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
memcpy(fullDef->notetrackRumbleMapValues,
fullDef->weapDef.notetrackRumbleMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
fullDef->weapDef.notetrackRumbleMapValues = fullDef->notetrackRumbleMapValues;
}
if (fullDef->weapDef.worldModel)
{
assert(sizeof(WeaponFullDef::worldModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
memcpy(fullDef->worldModel, fullDef->weapDef.worldModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
fullDef->weapDef.worldModel = fullDef->worldModel;
}
if (fullDef->weapDef.parallelBounce)
{
assert(sizeof(WeaponFullDef::parallelBounce) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::parallelBounce)>);
memcpy(fullDef->parallelBounce, fullDef->weapDef.parallelBounce, sizeof(float) * std::extent_v<decltype(WeaponFullDef::parallelBounce)>);
fullDef->weapDef.parallelBounce = fullDef->parallelBounce;
}
if (fullDef->weapDef.perpendicularBounce)
{
assert(sizeof(WeaponFullDef::perpendicularBounce) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::perpendicularBounce)>);
memcpy(fullDef->perpendicularBounce,
fullDef->weapDef.perpendicularBounce,
sizeof(float) * std::extent_v<decltype(WeaponFullDef::perpendicularBounce)>);
fullDef->weapDef.perpendicularBounce = fullDef->perpendicularBounce;
}
if (fullDef->weapDef.locationDamageMultipliers)
{
assert(sizeof(WeaponFullDef::locationDamageMultipliers) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)>);
memcpy(fullDef->locationDamageMultipliers,
fullDef->weapDef.locationDamageMultipliers,
sizeof(float) * std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)>);
fullDef->weapDef.locationDamageMultipliers = fullDef->locationDamageMultipliers;
}
}
if (weapon->hideTags)
InfoString CreateInfoString(XAssetInfo<WeaponCompleteDef>* asset)
{
assert(sizeof(WeaponFullDef::hideTags) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
memcpy(fullDef->hideTags, weapon->hideTags, sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
fullDef->weapCompleteDef.hideTags = fullDef->hideTags;
const auto fullDef = std::make_unique<WeaponFullDef>();
memset(fullDef.get(), 0, sizeof(WeaponFullDef));
CopyToFullDef(asset->Asset(), fullDef.get());
InfoStringFromWeaponConverter converter(fullDef.get(),
weapon_fields,
std::extent_v<decltype(weapon_fields)>,
[asset](const scr_string_t scrStr) -> std::string
{
assert(scrStr < asset->m_zone->m_script_strings.Count());
if (scrStr >= asset->m_zone->m_script_strings.Count())
return "";
return asset->m_zone->m_script_strings[scrStr];
});
return converter.Convert();
}
if (weapon->szXAnims)
void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset)
{
assert(sizeof(WeaponFullDef::szXAnims) >= sizeof(void*) * NUM_WEAP_ANIMS);
memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * NUM_WEAP_ANIMS);
fullDef->weapCompleteDef.szXAnims = fullDef->szXAnims;
}
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
const auto weapon = asset->Asset();
const auto* weapDef = weapon->weapDef;
if (fullDef->weapDef.gunXModel)
{
assert(sizeof(WeaponFullDef::gunXModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
memcpy(fullDef->gunXModel, fullDef->weapDef.gunXModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
fullDef->weapDef.gunXModel = fullDef->gunXModel;
}
if (fullDef->weapDef.szXAnimsRightHanded)
{
assert(sizeof(WeaponFullDef::szXAnimsRightHanded) >= sizeof(void*) * NUM_WEAP_ANIMS);
memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * NUM_WEAP_ANIMS);
fullDef->weapDef.szXAnimsRightHanded = fullDef->szXAnimsRightHanded;
}
if (fullDef->weapDef.szXAnimsLeftHanded)
{
assert(sizeof(WeaponFullDef::szXAnimsLeftHanded) >= sizeof(void*) * NUM_WEAP_ANIMS);
memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * NUM_WEAP_ANIMS);
fullDef->weapDef.szXAnimsLeftHanded = fullDef->szXAnimsLeftHanded;
}
if (fullDef->weapDef.notetrackSoundMapKeys)
{
assert(sizeof(WeaponFullDef::notetrackSoundMapKeys) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
memcpy(fullDef->notetrackSoundMapKeys,
fullDef->weapDef.notetrackSoundMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
fullDef->weapDef.notetrackSoundMapKeys = fullDef->notetrackSoundMapKeys;
}
if (fullDef->weapDef.notetrackSoundMapValues)
{
assert(sizeof(WeaponFullDef::notetrackSoundMapValues) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
memcpy(fullDef->notetrackSoundMapValues,
fullDef->weapDef.notetrackSoundMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
fullDef->weapDef.notetrackSoundMapValues = fullDef->notetrackSoundMapValues;
}
if (fullDef->weapDef.notetrackRumbleMapKeys)
{
assert(sizeof(WeaponFullDef::notetrackRumbleMapKeys) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
memcpy(fullDef->notetrackRumbleMapKeys,
fullDef->weapDef.notetrackRumbleMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
fullDef->weapDef.notetrackRumbleMapKeys = fullDef->notetrackRumbleMapKeys;
}
if (fullDef->weapDef.notetrackRumbleMapValues)
{
assert(sizeof(WeaponFullDef::notetrackRumbleMapValues) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
memcpy(fullDef->notetrackRumbleMapValues,
fullDef->weapDef.notetrackRumbleMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
fullDef->weapDef.notetrackRumbleMapValues = fullDef->notetrackRumbleMapValues;
}
if (fullDef->weapDef.worldModel)
{
assert(sizeof(WeaponFullDef::worldModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
memcpy(fullDef->worldModel, fullDef->weapDef.worldModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
fullDef->weapDef.worldModel = fullDef->worldModel;
}
if (fullDef->weapDef.parallelBounce)
{
assert(sizeof(WeaponFullDef::parallelBounce) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::parallelBounce)>);
memcpy(fullDef->parallelBounce, fullDef->weapDef.parallelBounce, sizeof(float) * std::extent_v<decltype(WeaponFullDef::parallelBounce)>);
fullDef->weapDef.parallelBounce = fullDef->parallelBounce;
}
if (fullDef->weapDef.perpendicularBounce)
{
assert(sizeof(WeaponFullDef::perpendicularBounce) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::perpendicularBounce)>);
memcpy(fullDef->perpendicularBounce, fullDef->weapDef.perpendicularBounce, sizeof(float) * std::extent_v<decltype(WeaponFullDef::perpendicularBounce)>);
fullDef->weapDef.perpendicularBounce = fullDef->perpendicularBounce;
}
if (fullDef->weapDef.locationDamageMultipliers)
{
assert(sizeof(WeaponFullDef::locationDamageMultipliers) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)>);
memcpy(fullDef->locationDamageMultipliers,
fullDef->weapDef.locationDamageMultipliers,
sizeof(float) * std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)>);
fullDef->weapDef.locationDamageMultipliers = fullDef->locationDamageMultipliers;
}
}
InfoString AssetDumperWeapon::CreateInfoString(XAssetInfo<WeaponCompleteDef>* asset)
{
const auto fullDef = std::make_unique<WeaponFullDef>();
memset(fullDef.get(), 0, sizeof(WeaponFullDef));
CopyToFullDef(asset->Asset(), fullDef.get());
InfoStringFromWeaponConverter converter(fullDef.get(),
weapon_fields,
std::extent_v<decltype(weapon_fields)>,
[asset](const scr_string_t scrStr) -> std::string
{
assert(scrStr < asset->m_zone->m_script_strings.Count());
if (scrStr >= asset->m_zone->m_script_strings.Count())
return "";
return asset->m_zone->m_script_strings[scrStr];
});
return converter.Convert();
}
void AssetDumperWeapon::DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset)
{
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
const auto weapon = asset->Asset();
const auto* weapDef = weapon->weapDef;
if (!weapDef)
return;
if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsAiGraph(
context,
ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName, weapDef->originalAiVsAiAccuracyGraphKnots, weapDef->originalAiVsAiAccuracyGraphKnotCount));
}
if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsPlayerGraph(context,
ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName,
weapDef->originalAiVsPlayerAccuracyGraphKnots,
weapDef->originalAiVsPlayerAccuracyGraphKnotCount));
}
}
bool AssetDumperWeapon::ShouldDump(XAssetInfo<WeaponCompleteDef>* asset)
{
return true;
}
void AssetDumperWeapon::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset)
{
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile("weapons/" + asset->m_name);
if (!assetFile)
if (!weapDef)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON);
stream.write(stringValue.c_str(), stringValue.size());
if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsAiGraph(context,
ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName,
weapDef->originalAiVsAiAccuracyGraphKnots,
weapDef->originalAiVsAiAccuracyGraphKnotCount));
}
if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsPlayerGraph(context,
ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName,
weapDef->originalAiVsPlayerAccuracyGraphKnots,
weapDef->originalAiVsPlayerAccuracyGraphKnotCount));
}
}
} // namespace
namespace IW4::weapon
{
bool Dumper::ShouldDump(XAssetInfo<WeaponCompleteDef>* asset)
{
return true;
}
DumpAccuracyGraphs(context, asset);
}
void Dumper::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset)
{
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name));
if (!assetFile)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON);
stream.write(stringValue.c_str(), stringValue.size());
}
DumpAccuracyGraphs(context, asset);
}
} // namespace IW4::weapon

View File

@@ -0,0 +1,15 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW4/IW4.h"
#include "InfoString/InfoString.h"
namespace IW4::weapon
{
class Dumper final : public AbstractAssetDumper<WeaponCompleteDef>
{
protected:
bool ShouldDump(XAssetInfo<WeaponCompleteDef>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset) override;
};
} // namespace IW4::weapon

View File

@@ -14,8 +14,8 @@
#include "Script/ScriptDumperIW5.h"
#include "Sound/LoadedSoundDumperIW5.h"
#include "StringTable/StringTableDumperIW5.h"
#include "Weapon/AssetDumperWeapon.h"
#include "Weapon/AssetDumperWeaponAttachment.h"
#include "Weapon/AttachmentJsonDumperIW5.h"
#include "Weapon/WeaponDumperIW5.h"
using namespace IW5;
@@ -56,8 +56,8 @@ bool ObjWriter::DumpZone(AssetDumpingContext& context) const
DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list, ASSET_TYPE_MENULIST)
DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def, ASSET_TYPE_MENU)
DUMP_ASSET_POOL(localize::Dumper, m_localize, ASSET_TYPE_LOCALIZE_ENTRY)
DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment, ASSET_TYPE_ATTACHMENT)
DUMP_ASSET_POOL(AssetDumperWeapon, m_weapon, ASSET_TYPE_WEAPON)
DUMP_ASSET_POOL(attachment::JsonDumper, m_attachment, ASSET_TYPE_ATTACHMENT)
DUMP_ASSET_POOL(weapon::Dumper, m_weapon, ASSET_TYPE_WEAPON)
// DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX)
// DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX)
// DUMP_ASSET_POOL(AssetDumperSurfaceFxTable, m_surface_fx_table, ASSET_TYPE_SURFACE_FX)

View File

@@ -1,19 +0,0 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
#include "InfoString/InfoString.h"
namespace IW5
{
class AssetDumperWeapon final : public AbstractAssetDumper<WeaponCompleteDef>
{
static void CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef);
static InfoString CreateInfoString(XAssetInfo<WeaponCompleteDef>* asset);
static void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset);
protected:
bool ShouldDump(XAssetInfo<WeaponCompleteDef>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset) override;
};
} // namespace IW5

View File

@@ -1,22 +0,0 @@
#include "AssetDumperWeaponAttachment.h"
#include "Game/IW5/Weapon/JsonWeaponAttachmentWriter.h"
#include <format>
using namespace IW5;
bool AssetDumperWeaponAttachment::ShouldDump(XAssetInfo<WeaponAttachment>* asset)
{
return true;
}
void AssetDumperWeaponAttachment::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachment>* asset)
{
const auto assetFile = context.OpenAssetFile(std::format("attachment/{}.json", asset->m_name));
if (!assetFile)
return;
DumpWeaponAttachmentAsJson(*assetFile, asset->Asset(), context);
}

View File

@@ -1,20 +1,22 @@
#include "JsonWeaponAttachmentWriter.h"
#include "AttachmentJsonDumperIW5.h"
#include "Game/IW5/CommonIW5.h"
#include "Game/IW5/Weapon/JsonWeaponAttachment.h"
#include "Weapon/AttachmentCommon.h"
#include <iomanip>
#include <nlohmann/json.hpp>
using namespace nlohmann;
using namespace IW5;
using namespace ::attachment;
namespace
{
class JsonDumper
class JsonDumperImpl
{
public:
JsonDumper(AssetDumpingContext& context, std::ostream& stream)
JsonDumperImpl(AssetDumpingContext& context, std::ostream& stream)
: m_stream(stream)
{
}
@@ -392,11 +394,21 @@ namespace
};
} // namespace
namespace IW5
namespace IW5::attachment
{
void DumpWeaponAttachmentAsJson(std::ostream& stream, const WeaponAttachment* attachment, AssetDumpingContext& context)
bool JsonDumper::ShouldDump(XAssetInfo<WeaponAttachment>* asset)
{
const JsonDumper dumper(context, stream);
dumper.Dump(attachment);
return true;
}
} // namespace IW5
void JsonDumper::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachment>* asset)
{
const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAssetName(asset->m_name));
if (!assetFile)
return;
const JsonDumperImpl dumper(context, *assetFile);
dumper.Dump(asset->Asset());
}
} // namespace IW5::attachment

View File

@@ -3,12 +3,12 @@
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
namespace IW5::attachment
{
class AssetDumperWeaponAttachment final : public AbstractAssetDumper<WeaponAttachment>
class JsonDumper final : public AbstractAssetDumper<WeaponAttachment>
{
protected:
bool ShouldDump(XAssetInfo<WeaponAttachment>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachment>* asset) override;
};
} // namespace IW5
} // namespace IW5::attachment

View File

@@ -1,11 +0,0 @@
#pragma once
#include "Dumping/AssetDumpingContext.h"
#include "Game/IW5/IW5.h"
#include <ostream>
namespace IW5
{
void DumpWeaponAttachmentAsJson(std::ostream& stream, const WeaponAttachment* attachment, AssetDumpingContext& context);
} // namespace IW5

View File

@@ -1,10 +1,11 @@
#include "AssetDumperWeapon.h"
#include "WeaponDumperIW5.h"
#include "Game/IW5/CommonIW5.h"
#include "Game/IW5/InfoString/InfoStringFromStructConverter.h"
#include "Game/IW5/ObjConstantsIW5.h"
#include "Game/IW5/Weapon/WeaponFields.h"
#include "Weapon/AccuracyGraphWriter.h"
#include "Weapon/WeaponCommon.h"
#include <bit>
#include <cassert>
@@ -14,8 +15,9 @@
#include <unordered_set>
using namespace IW5;
using namespace ::weapon;
namespace IW5
namespace
{
class InfoStringFromWeaponConverter final : public InfoStringFromStructConverter
{
@@ -551,211 +553,217 @@ namespace IW5
return graph;
}
} // namespace IW5
void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef)
{
fullDef->weapCompleteDef = *weapon;
if (weapon->weapDef)
void CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef)
{
fullDef->weapDef = *weapon->weapDef;
fullDef->weapCompleteDef.weapDef = &fullDef->weapDef;
fullDef->weapCompleteDef = *weapon;
if (weapon->weapDef)
{
fullDef->weapDef = *weapon->weapDef;
fullDef->weapCompleteDef.weapDef = &fullDef->weapDef;
}
if (weapon->hideTags)
{
memcpy(fullDef->hideTags, weapon->hideTags, sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
fullDef->weapCompleteDef.hideTags = fullDef->hideTags;
}
if (weapon->szXAnims)
{
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnims)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapCompleteDef.szXAnims = fullDef->szXAnims;
}
if (fullDef->weapDef.gunXModel)
{
memcpy(fullDef->gunXModel, fullDef->weapDef.gunXModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
fullDef->weapDef.gunXModel = fullDef->gunXModel;
}
if (fullDef->weapDef.szXAnimsRightHanded)
{
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnimsRightHanded)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapDef.szXAnimsRightHanded = fullDef->szXAnimsRightHanded;
}
if (fullDef->weapDef.szXAnimsLeftHanded)
{
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnimsLeftHanded)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapDef.szXAnimsLeftHanded = fullDef->szXAnimsLeftHanded;
}
if (fullDef->weapDef.notetrackSoundMapKeys)
{
memcpy(fullDef->notetrackSoundMapKeys,
fullDef->weapDef.notetrackSoundMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
fullDef->weapDef.notetrackSoundMapKeys = fullDef->notetrackSoundMapKeys;
}
if (fullDef->weapDef.notetrackSoundMapValues)
{
memcpy(fullDef->notetrackSoundMapValues,
fullDef->weapDef.notetrackSoundMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapValues)>);
fullDef->weapDef.notetrackSoundMapValues = fullDef->notetrackSoundMapValues;
}
if (fullDef->weapDef.notetrackRumbleMapKeys)
{
memcpy(fullDef->notetrackRumbleMapKeys,
fullDef->weapDef.notetrackRumbleMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
fullDef->weapDef.notetrackRumbleMapKeys = fullDef->notetrackRumbleMapKeys;
}
if (fullDef->weapDef.notetrackRumbleMapValues)
{
memcpy(fullDef->notetrackRumbleMapValues,
fullDef->weapDef.notetrackRumbleMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapValues)>);
fullDef->weapDef.notetrackRumbleMapValues = fullDef->notetrackRumbleMapValues;
}
if (fullDef->weapDef.worldModel)
{
memcpy(fullDef->worldModel, fullDef->weapDef.worldModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
fullDef->weapDef.worldModel = fullDef->worldModel;
}
if (fullDef->weapDef.parallelBounce)
{
static_assert(std::extent_v<decltype(WeaponFullDef::parallelBounce)> == SURF_TYPE_COUNT);
assert(sizeof(WeaponFullDef::parallelBounce) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::parallelBounce)>);
memcpy(fullDef->parallelBounce, fullDef->weapDef.parallelBounce, sizeof(float) * std::extent_v<decltype(WeaponFullDef::parallelBounce)>);
fullDef->weapDef.parallelBounce = fullDef->parallelBounce;
}
if (fullDef->weapDef.perpendicularBounce)
{
static_assert(std::extent_v<decltype(WeaponFullDef::perpendicularBounce)> == SURF_TYPE_COUNT);
assert(sizeof(WeaponFullDef::perpendicularBounce) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::perpendicularBounce)>);
memcpy(fullDef->perpendicularBounce,
fullDef->weapDef.perpendicularBounce,
sizeof(float) * std::extent_v<decltype(WeaponFullDef::perpendicularBounce)>);
fullDef->weapDef.perpendicularBounce = fullDef->perpendicularBounce;
}
if (fullDef->weapDef.locationDamageMultipliers)
{
static_assert(std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)> == HITLOC_COUNT);
assert(sizeof(WeaponFullDef::locationDamageMultipliers) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)>);
memcpy(fullDef->locationDamageMultipliers,
fullDef->weapDef.locationDamageMultipliers,
sizeof(float) * std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)>);
fullDef->weapDef.locationDamageMultipliers = fullDef->locationDamageMultipliers;
}
if (fullDef->weapCompleteDef.scopes)
{
memcpy(fullDef->scopes, fullDef->weapCompleteDef.scopes, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::scopes)>);
fullDef->weapCompleteDef.scopes = fullDef->scopes;
}
if (fullDef->weapCompleteDef.underBarrels)
{
memcpy(fullDef->underBarrels, fullDef->weapCompleteDef.underBarrels, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::underBarrels)>);
fullDef->weapCompleteDef.underBarrels = fullDef->underBarrels;
}
if (fullDef->weapCompleteDef.others)
{
memcpy(fullDef->others, fullDef->weapCompleteDef.others, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::others)>);
fullDef->weapCompleteDef.others = fullDef->others;
}
}
if (weapon->hideTags)
InfoString CreateInfoString(XAssetInfo<WeaponCompleteDef>* asset)
{
memcpy(fullDef->hideTags, weapon->hideTags, sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
fullDef->weapCompleteDef.hideTags = fullDef->hideTags;
const auto fullDef = std::make_unique<WeaponFullDef>();
memset(fullDef.get(), 0, sizeof(WeaponFullDef));
CopyToFullDef(asset->Asset(), fullDef.get());
InfoStringFromWeaponConverter converter(fullDef.get(),
weapon_fields,
std::extent_v<decltype(weapon_fields)>,
[asset](const scr_string_t scrStr) -> std::string
{
assert(scrStr < asset->m_zone->m_script_strings.Count());
if (scrStr >= asset->m_zone->m_script_strings.Count())
return "";
return asset->m_zone->m_script_strings[scrStr];
});
return converter.Convert();
}
if (weapon->szXAnims)
void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset)
{
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnims)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapCompleteDef.szXAnims = fullDef->szXAnims;
}
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
const auto weapon = asset->Asset();
const auto* weapDef = weapon->weapDef;
if (fullDef->weapDef.gunXModel)
{
memcpy(fullDef->gunXModel, fullDef->weapDef.gunXModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
fullDef->weapDef.gunXModel = fullDef->gunXModel;
}
if (fullDef->weapDef.szXAnimsRightHanded)
{
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnimsRightHanded)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapDef.szXAnimsRightHanded = fullDef->szXAnimsRightHanded;
}
if (fullDef->weapDef.szXAnimsLeftHanded)
{
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnimsLeftHanded)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapDef.szXAnimsLeftHanded = fullDef->szXAnimsLeftHanded;
}
if (fullDef->weapDef.notetrackSoundMapKeys)
{
memcpy(fullDef->notetrackSoundMapKeys,
fullDef->weapDef.notetrackSoundMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
fullDef->weapDef.notetrackSoundMapKeys = fullDef->notetrackSoundMapKeys;
}
if (fullDef->weapDef.notetrackSoundMapValues)
{
memcpy(fullDef->notetrackSoundMapValues,
fullDef->weapDef.notetrackSoundMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapValues)>);
fullDef->weapDef.notetrackSoundMapValues = fullDef->notetrackSoundMapValues;
}
if (fullDef->weapDef.notetrackRumbleMapKeys)
{
memcpy(fullDef->notetrackRumbleMapKeys,
fullDef->weapDef.notetrackRumbleMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
fullDef->weapDef.notetrackRumbleMapKeys = fullDef->notetrackRumbleMapKeys;
}
if (fullDef->weapDef.notetrackRumbleMapValues)
{
memcpy(fullDef->notetrackRumbleMapValues,
fullDef->weapDef.notetrackRumbleMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapValues)>);
fullDef->weapDef.notetrackRumbleMapValues = fullDef->notetrackRumbleMapValues;
}
if (fullDef->weapDef.worldModel)
{
memcpy(fullDef->worldModel, fullDef->weapDef.worldModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
fullDef->weapDef.worldModel = fullDef->worldModel;
}
if (fullDef->weapDef.parallelBounce)
{
static_assert(std::extent_v<decltype(WeaponFullDef::parallelBounce)> == SURF_TYPE_COUNT);
assert(sizeof(WeaponFullDef::parallelBounce) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::parallelBounce)>);
memcpy(fullDef->parallelBounce, fullDef->weapDef.parallelBounce, sizeof(float) * std::extent_v<decltype(WeaponFullDef::parallelBounce)>);
fullDef->weapDef.parallelBounce = fullDef->parallelBounce;
}
if (fullDef->weapDef.perpendicularBounce)
{
static_assert(std::extent_v<decltype(WeaponFullDef::perpendicularBounce)> == SURF_TYPE_COUNT);
assert(sizeof(WeaponFullDef::perpendicularBounce) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::perpendicularBounce)>);
memcpy(fullDef->perpendicularBounce, fullDef->weapDef.perpendicularBounce, sizeof(float) * std::extent_v<decltype(WeaponFullDef::perpendicularBounce)>);
fullDef->weapDef.perpendicularBounce = fullDef->perpendicularBounce;
}
if (fullDef->weapDef.locationDamageMultipliers)
{
static_assert(std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)> == HITLOC_COUNT);
assert(sizeof(WeaponFullDef::locationDamageMultipliers) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)>);
memcpy(fullDef->locationDamageMultipliers,
fullDef->weapDef.locationDamageMultipliers,
sizeof(float) * std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)>);
fullDef->weapDef.locationDamageMultipliers = fullDef->locationDamageMultipliers;
}
if (fullDef->weapCompleteDef.scopes)
{
memcpy(fullDef->scopes, fullDef->weapCompleteDef.scopes, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::scopes)>);
fullDef->weapCompleteDef.scopes = fullDef->scopes;
}
if (fullDef->weapCompleteDef.underBarrels)
{
memcpy(fullDef->underBarrels, fullDef->weapCompleteDef.underBarrels, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::underBarrels)>);
fullDef->weapCompleteDef.underBarrels = fullDef->underBarrels;
}
if (fullDef->weapCompleteDef.others)
{
memcpy(fullDef->others, fullDef->weapCompleteDef.others, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::others)>);
fullDef->weapCompleteDef.others = fullDef->others;
}
}
InfoString AssetDumperWeapon::CreateInfoString(XAssetInfo<WeaponCompleteDef>* asset)
{
const auto fullDef = std::make_unique<WeaponFullDef>();
memset(fullDef.get(), 0, sizeof(WeaponFullDef));
CopyToFullDef(asset->Asset(), fullDef.get());
InfoStringFromWeaponConverter converter(fullDef.get(),
weapon_fields,
std::extent_v<decltype(weapon_fields)>,
[asset](const scr_string_t scrStr) -> std::string
{
assert(scrStr < asset->m_zone->m_script_strings.Count());
if (scrStr >= asset->m_zone->m_script_strings.Count())
return "";
return asset->m_zone->m_script_strings[scrStr];
});
return converter.Convert();
}
void AssetDumperWeapon::DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset)
{
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
const auto weapon = asset->Asset();
const auto* weapDef = weapon->weapDef;
if (!weapDef)
return;
if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsAiGraph(
context,
ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName, weapDef->originalAiVsAiAccuracyGraphKnots, weapDef->originalAiVsAiAccuracyGraphKnotCount));
}
if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsPlayerGraph(context,
ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName,
weapDef->originalAiVsPlayerAccuracyGraphKnots,
weapDef->originalAiVsPlayerAccuracyGraphKnotCount));
}
}
bool AssetDumperWeapon::ShouldDump(XAssetInfo<WeaponCompleteDef>* asset)
{
return true;
}
void AssetDumperWeapon::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset)
{
// TODO: only dump infostring fields when non-default
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile("weapons/" + asset->m_name);
if (!assetFile)
if (!weapDef)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON);
stream.write(stringValue.c_str(), stringValue.size());
if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsAiGraph(context,
ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName,
weapDef->originalAiVsAiAccuracyGraphKnots,
weapDef->originalAiVsAiAccuracyGraphKnotCount));
}
if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsPlayerGraph(context,
ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName,
weapDef->originalAiVsPlayerAccuracyGraphKnots,
weapDef->originalAiVsPlayerAccuracyGraphKnotCount));
}
}
} // namespace
namespace IW5::weapon
{
bool Dumper::ShouldDump(XAssetInfo<WeaponCompleteDef>* asset)
{
return true;
}
DumpAccuracyGraphs(context, asset);
}
void Dumper::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset)
{
// TODO: only dump infostring fields when non-default
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name));
if (!assetFile)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON);
stream.write(stringValue.c_str(), stringValue.size());
}
DumpAccuracyGraphs(context, asset);
}
} // namespace IW5::weapon

View File

@@ -0,0 +1,15 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
#include "InfoString/InfoString.h"
namespace IW5::weapon
{
class Dumper final : public AbstractAssetDumper<WeaponCompleteDef>
{
protected:
bool ShouldDump(XAssetInfo<WeaponCompleteDef>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset) override;
};
} // namespace IW5::weapon

View File

@@ -8,7 +8,6 @@
#include "ObjWriting.h"
#include "RawFile/RawFileDumperT5.h"
#include "StringTable/StringTableDumperT5.h"
#include "Weapon/AssetDumperWeapon.h"
using namespace T5;

View File

@@ -21,10 +21,10 @@
#include "Techset/TechsetDumperT6.h"
#include "Tracer/TracerDumperT6.h"
#include "Vehicle/VehicleDumperT6.h"
#include "Weapon/AssetDumperWeapon.h"
#include "Weapon/AssetDumperWeaponAttachment.h"
#include "Weapon/AssetDumperWeaponAttachmentUnique.h"
#include "Weapon/AssetDumperWeaponCamo.h"
#include "Weapon/AttachmentDumperT6.h"
#include "Weapon/AttachmentUniqueDumperT6.h"
#include "Weapon/CamoJsonDumperT6.h"
#include "Weapon/WeaponDumperT6.h"
#include "ZBarrier/ZBarrierDumperT6.h"
using namespace T6;
@@ -68,10 +68,10 @@ bool ObjWriter::DumpZone(AssetDumpingContext& context) const
// DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list, ASSET_TYPE_MENULIST)
// DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def, ASSET_TYPE_MENU)
DUMP_ASSET_POOL(localize::Dumper, m_localize, ASSET_TYPE_LOCALIZE_ENTRY)
DUMP_ASSET_POOL(AssetDumperWeapon, m_weapon, ASSET_TYPE_WEAPON)
DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment, ASSET_TYPE_ATTACHMENT)
DUMP_ASSET_POOL(AssetDumperWeaponAttachmentUnique, m_attachment_unique, ASSET_TYPE_ATTACHMENT_UNIQUE)
DUMP_ASSET_POOL(AssetDumperWeaponCamo, m_camo, ASSET_TYPE_WEAPON_CAMO)
DUMP_ASSET_POOL(weapon::Dumper, m_weapon, ASSET_TYPE_WEAPON)
DUMP_ASSET_POOL(attachment::Dumper, m_attachment, ASSET_TYPE_ATTACHMENT)
DUMP_ASSET_POOL(attachment_unique::Dumper, m_attachment_unique, ASSET_TYPE_ATTACHMENT_UNIQUE)
DUMP_ASSET_POOL(camo::JsonDumper, m_camo, ASSET_TYPE_WEAPON_CAMO)
DUMP_ASSET_POOL(sound::SndDriverGlobalsDumper, m_snd_driver_globals, ASSET_TYPE_SNDDRIVER_GLOBALS)
// DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX)
// DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX)

View File

@@ -1,19 +0,0 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h"
#include "InfoString/InfoString.h"
namespace T6
{
class AssetDumperWeapon final : public AbstractAssetDumper<WeaponVariantDef>
{
static void CopyToFullDef(const WeaponVariantDef* weapon, WeaponFullDef* fullDef);
static InfoString CreateInfoString(XAssetInfo<WeaponVariantDef>* asset);
static void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo<WeaponVariantDef>* asset);
protected:
bool ShouldDump(XAssetInfo<WeaponVariantDef>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponVariantDef>* asset) override;
};
} // namespace T6

View File

@@ -1,94 +0,0 @@
#include "AssetDumperWeaponAttachment.h"
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/Weapon/AttachmentFields.h"
#include "Game/T6/Weapon/WeaponStrings.h"
#include <cassert>
#include <type_traits>
using namespace T6;
namespace T6
{
class InfoStringFromAttachmentConverter final : public InfoStringFromStructConverter
{
protected:
void FillFromExtensionField(const cspField_t& field) override
{
switch (static_cast<attachmentFieldType_t>(field.iFieldType))
{
case AFT_ATTACHMENTTYPE:
FillFromEnumInt(std::string(field.szName), field.iOffset, szAttachmentTypeNames, std::extent_v<decltype(szAttachmentTypeNames)>);
break;
case AFT_PENETRATE_TYPE:
FillFromEnumInt(std::string(field.szName), field.iOffset, penetrateTypeNames, std::extent_v<decltype(penetrateTypeNames)>);
break;
case AFT_FIRETYPE:
FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapFireTypeNames, std::extent_v<decltype(szWeapFireTypeNames)>);
break;
default:
break;
}
}
public:
InfoStringFromAttachmentConverter(const WeaponAttachment* structure,
const cspField_t* fields,
const size_t fieldCount,
std::function<std::string(scr_string_t)> scriptStringValueCallback)
: InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback))
{
}
};
} // namespace T6
InfoString AssetDumperWeaponAttachment::CreateInfoString(XAssetInfo<WeaponAttachment>* asset)
{
InfoStringFromAttachmentConverter converter(asset->Asset(),
attachment_fields,
std::extent_v<decltype(attachment_fields)>,
[asset](const scr_string_t scrStr) -> std::string
{
assert(scrStr < asset->m_zone->m_script_strings.Count());
if (scrStr >= asset->m_zone->m_script_strings.Count())
return "";
return asset->m_zone->m_script_strings[scrStr];
});
return converter.Convert();
}
bool AssetDumperWeaponAttachment::ShouldDump(XAssetInfo<WeaponAttachment>* asset)
{
return true;
}
void AssetDumperWeaponAttachment::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachment>* asset)
{
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON_ATTACHMENT);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON_ATTACHMENT, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile("attachment/" + asset->m_name);
if (!assetFile)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON_ATTACHMENT);
stream.write(stringValue.c_str(), stringValue.size());
}
}

View File

@@ -1,158 +0,0 @@
#include "AssetDumperWeaponAttachmentUnique.h"
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/Weapon/AttachmentUniqueFields.h"
#include "Game/T6/Weapon/WeaponStrings.h"
#include <cassert>
#include <cstring>
#include <sstream>
#include <type_traits>
using namespace T6;
namespace T6
{
class InfoStringFromWeaponAttachmentUniqueConverter final : public InfoStringFromStructConverter
{
protected:
void FillFromExtensionField(const cspField_t& field) override
{
switch (static_cast<attachmentUniqueFieldType_t>(field.iFieldType))
{
case AUFT_ATTACHMENTTYPE:
FillFromEnumInt(std::string(field.szName), field.iOffset, szAttachmentTypeNames, std::extent_v<decltype(szAttachmentTypeNames)>);
break;
case AUFT_HIDETAGS:
{
const auto* hideTags = reinterpret_cast<scr_string_t*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
std::stringstream ss;
auto first = true;
for (auto i = 0u; i < std::extent_v<decltype(WeaponFullDef::hideTags)>; i++)
{
const auto& str = m_get_scr_string(hideTags[i]);
if (!str.empty())
{
if (!first)
ss << "\n";
else
first = false;
ss << str;
}
}
m_info_string.SetValueForKey(std::string(field.szName), ss.str());
break;
}
case AUFT_OVERLAYRETICLE:
FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapOverlayReticleNames, std::extent_v<decltype(szWeapOverlayReticleNames)>);
break;
case AUFT_CAMO:
{
const auto* camo = *reinterpret_cast<WeaponCamo**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (camo)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(camo->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
default:
assert(false);
break;
}
}
public:
InfoStringFromWeaponAttachmentUniqueConverter(const WeaponAttachmentUniqueFull* structure,
const cspField_t* fields,
const size_t fieldCount,
std::function<std::string(scr_string_t)> scriptStringValueCallback)
: InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback))
{
}
};
} // namespace T6
void AssetDumperWeaponAttachmentUnique::CopyToFullDef(const WeaponAttachmentUnique* attachment, WeaponAttachmentUniqueFull* fullDef)
{
fullDef->attachment = *attachment;
if (attachment->szXAnims)
{
assert(sizeof(WeaponAttachmentUniqueFull::szXAnims) >= sizeof(void*) * NUM_WEAP_ANIMS);
memcpy(fullDef->szXAnims, attachment->szXAnims, sizeof(void*) * NUM_WEAP_ANIMS);
fullDef->attachment.szXAnims = fullDef->szXAnims;
}
if (attachment->hideTags)
{
assert(sizeof(WeaponAttachmentUniqueFull::hideTags) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponAttachmentUniqueFull::hideTags)>);
memcpy(fullDef->hideTags, attachment->hideTags, sizeof(scr_string_t) * std::extent_v<decltype(WeaponAttachmentUniqueFull::hideTags)>);
fullDef->attachment.hideTags = fullDef->hideTags;
}
if (attachment->locationDamageMultipliers)
{
assert(sizeof(WeaponAttachmentUniqueFull::locationDamageMultipliers) >= sizeof(float) * HITLOC_COUNT);
memcpy(fullDef->locationDamageMultipliers, attachment->locationDamageMultipliers, sizeof(float) * HITLOC_COUNT);
fullDef->attachment.locationDamageMultipliers = fullDef->locationDamageMultipliers;
}
}
InfoString AssetDumperWeaponAttachmentUnique::CreateInfoString(XAssetInfo<WeaponAttachmentUnique>* asset)
{
const auto fullDef = std::make_unique<WeaponAttachmentUniqueFull>();
memset(fullDef.get(), 0, sizeof(WeaponAttachmentUniqueFull));
CopyToFullDef(asset->Asset(), fullDef.get());
InfoStringFromWeaponAttachmentUniqueConverter converter(fullDef.get(),
attachment_unique_fields,
std::extent_v<decltype(attachment_unique_fields)>,
[asset](const scr_string_t scrStr) -> std::string
{
assert(scrStr < asset->m_zone->m_script_strings.Count());
if (scrStr >= asset->m_zone->m_script_strings.Count())
return "";
return asset->m_zone->m_script_strings[scrStr];
});
return converter.Convert();
}
bool AssetDumperWeaponAttachmentUnique::ShouldDump(XAssetInfo<WeaponAttachmentUnique>* asset)
{
return true;
}
void AssetDumperWeaponAttachmentUnique::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachmentUnique>* asset)
{
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON_ATTACHMENT_UNIQUE);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON_ATTACHMENT_UNIQUE, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile("attachmentunique/" + asset->m_name);
if (!assetFile)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON_ATTACHMENT_UNIQUE);
stream.write(stringValue.c_str(), stringValue.size());
}
}

View File

@@ -1,18 +0,0 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h"
#include "InfoString/InfoString.h"
namespace T6
{
class AssetDumperWeaponAttachmentUnique final : public AbstractAssetDumper<WeaponAttachmentUnique>
{
static void CopyToFullDef(const WeaponAttachmentUnique* attachment, WeaponAttachmentUniqueFull* fullDef);
static InfoString CreateInfoString(XAssetInfo<WeaponAttachmentUnique>* asset);
protected:
bool ShouldDump(XAssetInfo<WeaponAttachmentUnique>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachmentUnique>* asset) override;
};
} // namespace T6

View File

@@ -1,23 +0,0 @@
#include "AssetDumperWeaponCamo.h"
#include "JsonWeaponCamoWriter.h"
#include <format>
using namespace T6;
bool AssetDumperWeaponCamo::ShouldDump(XAssetInfo<WeaponCamo>* asset)
{
return true;
}
void AssetDumperWeaponCamo::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCamo>* asset)
{
const auto fileName = std::format("camo/{}.json", asset->m_name);
const auto assetFile = context.OpenAssetFile(fileName);
if (!assetFile)
return;
DumpWeaponCamoAsJson(*assetFile, asset->Asset());
}

View File

@@ -0,0 +1,99 @@
#include "AttachmentDumperT6.h"
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/Weapon/AttachmentFields.h"
#include "Game/T6/Weapon/WeaponStrings.h"
#include "Weapon/AttachmentCommon.h"
#include <cassert>
#include <type_traits>
using namespace T6;
using namespace ::attachment;
namespace
{
class InfoStringFromAttachmentConverter final : public InfoStringFromStructConverter
{
protected:
void FillFromExtensionField(const cspField_t& field) override
{
switch (static_cast<attachmentFieldType_t>(field.iFieldType))
{
case AFT_ATTACHMENTTYPE:
FillFromEnumInt(std::string(field.szName), field.iOffset, szAttachmentTypeNames, std::extent_v<decltype(szAttachmentTypeNames)>);
break;
case AFT_PENETRATE_TYPE:
FillFromEnumInt(std::string(field.szName), field.iOffset, penetrateTypeNames, std::extent_v<decltype(penetrateTypeNames)>);
break;
case AFT_FIRETYPE:
FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapFireTypeNames, std::extent_v<decltype(szWeapFireTypeNames)>);
break;
default:
break;
}
}
public:
InfoStringFromAttachmentConverter(const WeaponAttachment* structure,
const cspField_t* fields,
const size_t fieldCount,
std::function<std::string(scr_string_t)> scriptStringValueCallback)
: InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback))
{
}
};
InfoString CreateInfoString(XAssetInfo<WeaponAttachment>* asset)
{
InfoStringFromAttachmentConverter converter(asset->Asset(),
attachment_fields,
std::extent_v<decltype(attachment_fields)>,
[asset](const scr_string_t scrStr) -> std::string
{
assert(scrStr < asset->m_zone->m_script_strings.Count());
if (scrStr >= asset->m_zone->m_script_strings.Count())
return "";
return asset->m_zone->m_script_strings[scrStr];
});
return converter.Convert();
}
} // namespace
namespace T6::attachment
{
bool Dumper::ShouldDump(XAssetInfo<WeaponAttachment>* asset)
{
return true;
}
void Dumper::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachment>* asset)
{
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON_ATTACHMENT);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON_ATTACHMENT, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile(GetInfoStringFileNameForAssetName(asset->m_name));
if (!assetFile)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON_ATTACHMENT);
stream.write(stringValue.c_str(), stringValue.size());
}
}
} // namespace T6::attachment

View File

@@ -4,14 +4,12 @@
#include "Game/T6/T6.h"
#include "InfoString/InfoString.h"
namespace T6
namespace T6::attachment
{
class AssetDumperWeaponAttachment final : public AbstractAssetDumper<WeaponAttachment>
class Dumper final : public AbstractAssetDumper<WeaponAttachment>
{
static InfoString CreateInfoString(XAssetInfo<WeaponAttachment>* asset);
protected:
bool ShouldDump(XAssetInfo<WeaponAttachment>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachment>* asset) override;
};
} // namespace T6
} // namespace T6::attachment

View File

@@ -0,0 +1,163 @@
#include "AttachmentUniqueDumperT6.h"
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/Weapon/AttachmentUniqueFields.h"
#include "Game/T6/Weapon/WeaponStrings.h"
#include "Weapon/AttachmentUniqueCommon.h"
#include <cassert>
#include <cstring>
#include <sstream>
#include <type_traits>
using namespace T6;
using namespace ::attachment_unique;
namespace
{
class InfoStringFromWeaponAttachmentUniqueConverter final : public InfoStringFromStructConverter
{
protected:
void FillFromExtensionField(const cspField_t& field) override
{
switch (static_cast<attachmentUniqueFieldType_t>(field.iFieldType))
{
case AUFT_ATTACHMENTTYPE:
FillFromEnumInt(std::string(field.szName), field.iOffset, szAttachmentTypeNames, std::extent_v<decltype(szAttachmentTypeNames)>);
break;
case AUFT_HIDETAGS:
{
const auto* hideTags = reinterpret_cast<scr_string_t*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
std::stringstream ss;
auto first = true;
for (auto i = 0u; i < std::extent_v<decltype(WeaponFullDef::hideTags)>; i++)
{
const auto& str = m_get_scr_string(hideTags[i]);
if (!str.empty())
{
if (!first)
ss << "\n";
else
first = false;
ss << str;
}
}
m_info_string.SetValueForKey(std::string(field.szName), ss.str());
break;
}
case AUFT_OVERLAYRETICLE:
FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapOverlayReticleNames, std::extent_v<decltype(szWeapOverlayReticleNames)>);
break;
case AUFT_CAMO:
{
const auto* camo = *reinterpret_cast<WeaponCamo**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (camo)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(camo->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
default:
assert(false);
break;
}
}
public:
InfoStringFromWeaponAttachmentUniqueConverter(const WeaponAttachmentUniqueFull* structure,
const cspField_t* fields,
const size_t fieldCount,
std::function<std::string(scr_string_t)> scriptStringValueCallback)
: InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback))
{
}
};
void CopyToFullDef(const WeaponAttachmentUnique* attachment, WeaponAttachmentUniqueFull* fullDef)
{
fullDef->attachment = *attachment;
if (attachment->szXAnims)
{
assert(sizeof(WeaponAttachmentUniqueFull::szXAnims) >= sizeof(void*) * NUM_WEAP_ANIMS);
memcpy(fullDef->szXAnims, attachment->szXAnims, sizeof(void*) * NUM_WEAP_ANIMS);
fullDef->attachment.szXAnims = fullDef->szXAnims;
}
if (attachment->hideTags)
{
assert(sizeof(WeaponAttachmentUniqueFull::hideTags) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponAttachmentUniqueFull::hideTags)>);
memcpy(fullDef->hideTags, attachment->hideTags, sizeof(scr_string_t) * std::extent_v<decltype(WeaponAttachmentUniqueFull::hideTags)>);
fullDef->attachment.hideTags = fullDef->hideTags;
}
if (attachment->locationDamageMultipliers)
{
assert(sizeof(WeaponAttachmentUniqueFull::locationDamageMultipliers) >= sizeof(float) * HITLOC_COUNT);
memcpy(fullDef->locationDamageMultipliers, attachment->locationDamageMultipliers, sizeof(float) * HITLOC_COUNT);
fullDef->attachment.locationDamageMultipliers = fullDef->locationDamageMultipliers;
}
}
InfoString CreateInfoString(XAssetInfo<WeaponAttachmentUnique>* asset)
{
const auto fullDef = std::make_unique<WeaponAttachmentUniqueFull>();
memset(fullDef.get(), 0, sizeof(WeaponAttachmentUniqueFull));
CopyToFullDef(asset->Asset(), fullDef.get());
InfoStringFromWeaponAttachmentUniqueConverter converter(fullDef.get(),
attachment_unique_fields,
std::extent_v<decltype(attachment_unique_fields)>,
[asset](const scr_string_t scrStr) -> std::string
{
assert(scrStr < asset->m_zone->m_script_strings.Count());
if (scrStr >= asset->m_zone->m_script_strings.Count())
return "";
return asset->m_zone->m_script_strings[scrStr];
});
return converter.Convert();
}
} // namespace
namespace T6::attachment_unique
{
bool Dumper::ShouldDump(XAssetInfo<WeaponAttachmentUnique>* asset)
{
return true;
}
void Dumper::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachmentUnique>* asset)
{
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON_ATTACHMENT_UNIQUE);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON_ATTACHMENT_UNIQUE, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name));
if (!assetFile)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON_ATTACHMENT_UNIQUE);
stream.write(stringValue.c_str(), stringValue.size());
}
}
} // namespace T6::attachment_unique

View File

@@ -0,0 +1,15 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h"
#include "InfoString/InfoString.h"
namespace T6::attachment_unique
{
class Dumper final : public AbstractAssetDumper<WeaponAttachmentUnique>
{
protected:
bool ShouldDump(XAssetInfo<WeaponAttachmentUnique>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachmentUnique>* asset) override;
};
} // namespace T6::attachment_unique

View File

@@ -1,20 +1,22 @@
#include "JsonWeaponCamoWriter.h"
#include "CamoJsonDumperT6.h"
#include "Game/T6/CommonT6.h"
#include "Game/T6/Json/JsonWeaponCamo.h"
#include "Weapon/CamoCommon.h"
#include <iomanip>
#include <nlohmann/json.hpp>
using namespace nlohmann;
using namespace T6;
using namespace ::camo;
namespace
{
class JsonDumper
class JsonDumperImpl
{
public:
explicit JsonDumper(std::ostream& stream)
explicit JsonDumperImpl(std::ostream& stream)
: m_stream(stream)
{
}
@@ -101,11 +103,22 @@ namespace
};
} // namespace
namespace T6
namespace T6::camo
{
void DumpWeaponCamoAsJson(std::ostream& stream, const WeaponCamo* weaponCamo)
bool JsonDumper::ShouldDump(XAssetInfo<WeaponCamo>* asset)
{
const JsonDumper dumper(stream);
dumper.Dump(weaponCamo);
return true;
}
} // namespace T6
void JsonDumper::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCamo>* asset)
{
const auto fileName = GetJsonFileNameForAssetName(asset->m_name);
const auto assetFile = context.OpenAssetFile(fileName);
if (!assetFile)
return;
const JsonDumperImpl dumper(*assetFile);
dumper.Dump(asset->Asset());
}
} // namespace T6::camo

View File

@@ -3,12 +3,12 @@
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h"
namespace T6
namespace T6::camo
{
class AssetDumperWeaponCamo final : public AbstractAssetDumper<WeaponCamo>
class JsonDumper final : public AbstractAssetDumper<WeaponCamo>
{
protected:
bool ShouldDump(XAssetInfo<WeaponCamo>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCamo>* asset) override;
};
} // namespace T6
} // namespace T6::camo

View File

@@ -1,11 +0,0 @@
#pragma once
#include "Dumping/AssetDumpingContext.h"
#include "Game/T6/T6.h"
#include <ostream>
namespace T6
{
void DumpWeaponCamoAsJson(std::ostream& stream, const WeaponCamo* weaponCamo);
} // namespace T6

View File

@@ -1,10 +1,12 @@
#include "AssetDumperWeapon.h"
#include "WeaponDumperT6.h"
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
#include "Game/T6/ObjConstantsT6.h"
#include "Game/T6/Weapon/WeaponFields.h"
#include "Game/T6/Weapon/WeaponStrings.h"
#include "InfoString/InfoString.h"
#include "Weapon/AccuracyGraphWriter.h"
#include "Weapon/WeaponCommon.h"
#include <cassert>
#include <cstring>
@@ -12,8 +14,9 @@
#include <type_traits>
using namespace T6;
using namespace ::weapon;
namespace T6
namespace
{
class InfoStringFromWeaponConverter final : public InfoStringFromStructConverter
{
@@ -281,208 +284,212 @@ namespace T6
return graph;
}
} // namespace T6
void AssetDumperWeapon::CopyToFullDef(const WeaponVariantDef* weapon, WeaponFullDef* fullDef)
{
fullDef->weapVariantDef = *weapon;
if (weapon->weapDef)
void CopyToFullDef(const WeaponVariantDef* weapon, WeaponFullDef* fullDef)
{
fullDef->weapDef = *weapon->weapDef;
fullDef->weapVariantDef.weapDef = &fullDef->weapDef;
fullDef->weapVariantDef = *weapon;
if (weapon->weapDef)
{
fullDef->weapDef = *weapon->weapDef;
fullDef->weapVariantDef.weapDef = &fullDef->weapDef;
}
if (weapon->attachments)
{
assert(sizeof(WeaponFullDef::attachments) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachments)>);
memcpy(fullDef->attachments, weapon->attachments, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachments)>);
fullDef->weapVariantDef.attachments = fullDef->attachments;
}
if (weapon->attachmentUniques)
{
assert(sizeof(WeaponFullDef::attachmentUniques) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachmentUniques)>);
memcpy(fullDef->attachmentUniques, weapon->attachmentUniques, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachmentUniques)>);
fullDef->weapVariantDef.attachmentUniques = fullDef->attachmentUniques;
}
if (fullDef->weapDef.gunXModel)
{
assert(sizeof(WeaponFullDef::gunXModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
memcpy(fullDef->gunXModel, fullDef->weapDef.gunXModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
fullDef->weapDef.gunXModel = fullDef->gunXModel;
}
if (weapon->szXAnims)
{
assert(sizeof(WeaponFullDef::szXAnims) >= sizeof(void*) * NUM_WEAP_ANIMS);
memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * NUM_WEAP_ANIMS);
fullDef->weapVariantDef.szXAnims = fullDef->szXAnims;
}
if (weapon->hideTags)
{
assert(sizeof(WeaponFullDef::hideTags) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
memcpy(fullDef->hideTags, weapon->hideTags, sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
fullDef->weapVariantDef.hideTags = fullDef->hideTags;
}
if (fullDef->weapDef.notetrackSoundMapKeys)
{
assert(sizeof(WeaponFullDef::notetrackSoundMapKeys) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
memcpy(fullDef->notetrackSoundMapKeys,
fullDef->weapDef.notetrackSoundMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
fullDef->weapDef.notetrackSoundMapKeys = fullDef->notetrackSoundMapKeys;
}
if (fullDef->weapDef.notetrackSoundMapValues)
{
assert(sizeof(WeaponFullDef::notetrackSoundMapValues) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapValues)>);
memcpy(fullDef->notetrackSoundMapValues,
fullDef->weapDef.notetrackSoundMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapValues)>);
fullDef->weapDef.notetrackSoundMapValues = fullDef->notetrackSoundMapValues;
}
if (fullDef->weapDef.worldModel)
{
assert(sizeof(WeaponFullDef::worldModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
memcpy(fullDef->worldModel, fullDef->weapDef.worldModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
fullDef->weapDef.worldModel = fullDef->worldModel;
}
if (weapon->attachViewModel)
{
assert(sizeof(WeaponFullDef::attachViewModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachViewModel)>);
memcpy(fullDef->attachViewModel, weapon->attachViewModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachViewModel)>);
fullDef->weapVariantDef.attachViewModel = fullDef->attachViewModel;
}
if (weapon->attachWorldModel)
{
assert(sizeof(WeaponFullDef::attachWorldModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachWorldModel)>);
memcpy(fullDef->attachWorldModel, weapon->attachWorldModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachWorldModel)>);
fullDef->weapVariantDef.attachWorldModel = fullDef->attachWorldModel;
}
if (weapon->attachViewModelTag)
{
assert(sizeof(WeaponFullDef::attachViewModelTag) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachViewModelTag)>);
memcpy(fullDef->attachViewModelTag, weapon->attachViewModelTag, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachViewModelTag)>);
fullDef->weapVariantDef.attachViewModelTag = fullDef->attachViewModelTag;
}
if (weapon->attachWorldModelTag)
{
assert(sizeof(WeaponFullDef::attachWorldModelTag) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachWorldModelTag)>);
memcpy(fullDef->attachWorldModelTag, weapon->attachWorldModelTag, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachWorldModelTag)>);
fullDef->weapVariantDef.attachWorldModelTag = fullDef->attachWorldModelTag;
}
if (fullDef->weapDef.parallelBounce)
{
assert(sizeof(WeaponFullDef::parallelBounce) >= sizeof(float) * SURF_TYPE_NUM);
memcpy(fullDef->parallelBounce, fullDef->weapDef.parallelBounce, sizeof(float) * SURF_TYPE_NUM);
fullDef->weapDef.parallelBounce = fullDef->parallelBounce;
}
if (fullDef->weapDef.perpendicularBounce)
{
assert(sizeof(WeaponFullDef::perpendicularBounce) >= sizeof(float) * SURF_TYPE_NUM);
memcpy(fullDef->perpendicularBounce, fullDef->weapDef.perpendicularBounce, sizeof(float) * SURF_TYPE_NUM);
fullDef->weapDef.perpendicularBounce = fullDef->perpendicularBounce;
}
if (fullDef->weapDef.locationDamageMultipliers)
{
assert(sizeof(WeaponFullDef::locationDamageMultipliers) >= sizeof(float) * HITLOC_COUNT);
memcpy(fullDef->locationDamageMultipliers, fullDef->weapDef.locationDamageMultipliers, sizeof(float) * HITLOC_COUNT);
fullDef->weapDef.locationDamageMultipliers = fullDef->locationDamageMultipliers;
}
if (fullDef->weapDef.weaponCamo && fullDef->weapDef.weaponCamo->name)
{
strncpy(fullDef->weaponCamo, fullDef->weapDef.weaponCamo->name, std::extent_v<decltype(WeaponFullDef::weaponCamo)>);
}
}
if (weapon->attachments)
InfoString CreateInfoString(XAssetInfo<WeaponVariantDef>* asset)
{
assert(sizeof(WeaponFullDef::attachments) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachments)>);
memcpy(fullDef->attachments, weapon->attachments, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachments)>);
fullDef->weapVariantDef.attachments = fullDef->attachments;
const auto fullDef = std::make_unique<WeaponFullDef>();
memset(fullDef.get(), 0, sizeof(WeaponFullDef));
CopyToFullDef(asset->Asset(), fullDef.get());
InfoStringFromWeaponConverter converter(fullDef.get(),
weapon_fields,
std::extent_v<decltype(weapon_fields)>,
[asset](const scr_string_t scrStr) -> std::string
{
assert(scrStr < asset->m_zone->m_script_strings.Count());
if (scrStr >= asset->m_zone->m_script_strings.Count())
return "";
return asset->m_zone->m_script_strings[scrStr];
});
return converter.Convert();
}
if (weapon->attachmentUniques)
void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo<WeaponVariantDef>* asset)
{
assert(sizeof(WeaponFullDef::attachmentUniques) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachmentUniques)>);
memcpy(fullDef->attachmentUniques, weapon->attachmentUniques, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachmentUniques)>);
fullDef->weapVariantDef.attachmentUniques = fullDef->attachmentUniques;
}
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
const auto weapon = asset->Asset();
const auto* weapDef = weapon->weapDef;
if (fullDef->weapDef.gunXModel)
{
assert(sizeof(WeaponFullDef::gunXModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
memcpy(fullDef->gunXModel, fullDef->weapDef.gunXModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
fullDef->weapDef.gunXModel = fullDef->gunXModel;
}
if (weapon->szXAnims)
{
assert(sizeof(WeaponFullDef::szXAnims) >= sizeof(void*) * NUM_WEAP_ANIMS);
memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * NUM_WEAP_ANIMS);
fullDef->weapVariantDef.szXAnims = fullDef->szXAnims;
}
if (weapon->hideTags)
{
assert(sizeof(WeaponFullDef::hideTags) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
memcpy(fullDef->hideTags, weapon->hideTags, sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
fullDef->weapVariantDef.hideTags = fullDef->hideTags;
}
if (fullDef->weapDef.notetrackSoundMapKeys)
{
assert(sizeof(WeaponFullDef::notetrackSoundMapKeys) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
memcpy(fullDef->notetrackSoundMapKeys,
fullDef->weapDef.notetrackSoundMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
fullDef->weapDef.notetrackSoundMapKeys = fullDef->notetrackSoundMapKeys;
}
if (fullDef->weapDef.notetrackSoundMapValues)
{
assert(sizeof(WeaponFullDef::notetrackSoundMapValues) >= sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapValues)>);
memcpy(fullDef->notetrackSoundMapValues,
fullDef->weapDef.notetrackSoundMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapValues)>);
fullDef->weapDef.notetrackSoundMapValues = fullDef->notetrackSoundMapValues;
}
if (fullDef->weapDef.worldModel)
{
assert(sizeof(WeaponFullDef::worldModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
memcpy(fullDef->worldModel, fullDef->weapDef.worldModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
fullDef->weapDef.worldModel = fullDef->worldModel;
}
if (weapon->attachViewModel)
{
assert(sizeof(WeaponFullDef::attachViewModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachViewModel)>);
memcpy(fullDef->attachViewModel, weapon->attachViewModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachViewModel)>);
fullDef->weapVariantDef.attachViewModel = fullDef->attachViewModel;
}
if (weapon->attachWorldModel)
{
assert(sizeof(WeaponFullDef::attachWorldModel) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachWorldModel)>);
memcpy(fullDef->attachWorldModel, weapon->attachWorldModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachWorldModel)>);
fullDef->weapVariantDef.attachWorldModel = fullDef->attachWorldModel;
}
if (weapon->attachViewModelTag)
{
assert(sizeof(WeaponFullDef::attachViewModelTag) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachViewModelTag)>);
memcpy(fullDef->attachViewModelTag, weapon->attachViewModelTag, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachViewModelTag)>);
fullDef->weapVariantDef.attachViewModelTag = fullDef->attachViewModelTag;
}
if (weapon->attachWorldModelTag)
{
assert(sizeof(WeaponFullDef::attachWorldModelTag) >= sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachWorldModelTag)>);
memcpy(fullDef->attachWorldModelTag, weapon->attachWorldModelTag, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::attachWorldModelTag)>);
fullDef->weapVariantDef.attachWorldModelTag = fullDef->attachWorldModelTag;
}
if (fullDef->weapDef.parallelBounce)
{
assert(sizeof(WeaponFullDef::parallelBounce) >= sizeof(float) * SURF_TYPE_NUM);
memcpy(fullDef->parallelBounce, fullDef->weapDef.parallelBounce, sizeof(float) * SURF_TYPE_NUM);
fullDef->weapDef.parallelBounce = fullDef->parallelBounce;
}
if (fullDef->weapDef.perpendicularBounce)
{
assert(sizeof(WeaponFullDef::perpendicularBounce) >= sizeof(float) * SURF_TYPE_NUM);
memcpy(fullDef->perpendicularBounce, fullDef->weapDef.perpendicularBounce, sizeof(float) * SURF_TYPE_NUM);
fullDef->weapDef.perpendicularBounce = fullDef->perpendicularBounce;
}
if (fullDef->weapDef.locationDamageMultipliers)
{
assert(sizeof(WeaponFullDef::locationDamageMultipliers) >= sizeof(float) * HITLOC_COUNT);
memcpy(fullDef->locationDamageMultipliers, fullDef->weapDef.locationDamageMultipliers, sizeof(float) * HITLOC_COUNT);
fullDef->weapDef.locationDamageMultipliers = fullDef->locationDamageMultipliers;
}
if (fullDef->weapDef.weaponCamo && fullDef->weapDef.weaponCamo->name)
{
strncpy(fullDef->weaponCamo, fullDef->weapDef.weaponCamo->name, std::extent_v<decltype(WeaponFullDef::weaponCamo)>);
}
}
InfoString AssetDumperWeapon::CreateInfoString(XAssetInfo<WeaponVariantDef>* asset)
{
const auto fullDef = std::make_unique<WeaponFullDef>();
memset(fullDef.get(), 0, sizeof(WeaponFullDef));
CopyToFullDef(asset->Asset(), fullDef.get());
InfoStringFromWeaponConverter converter(fullDef.get(),
weapon_fields,
std::extent_v<decltype(weapon_fields)>,
[asset](const scr_string_t scrStr) -> std::string
{
assert(scrStr < asset->m_zone->m_script_strings.Count());
if (scrStr >= asset->m_zone->m_script_strings.Count())
return "";
return asset->m_zone->m_script_strings[scrStr];
});
return converter.Convert();
}
void AssetDumperWeapon::DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo<WeaponVariantDef>* asset)
{
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
const auto weapon = asset->Asset();
const auto* weapDef = weapon->weapDef;
if (!weapDef)
return;
if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsAiGraph(
context,
ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName, weapDef->originalAiVsAiAccuracyGraphKnots, weapDef->originalAiVsAiAccuracyGraphKnotCount));
}
if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsPlayerGraph(context,
ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName,
weapDef->originalAiVsPlayerAccuracyGraphKnots,
weapDef->originalAiVsPlayerAccuracyGraphKnotCount));
}
}
bool AssetDumperWeapon::ShouldDump(XAssetInfo<WeaponVariantDef>* asset)
{
return true;
}
void AssetDumperWeapon::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponVariantDef>* asset)
{
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile("weapons/" + asset->m_name);
if (!assetFile)
if (!weapDef)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON);
stream.write(stringValue.c_str(), stringValue.size());
if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsAiGraph(context,
ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName,
weapDef->originalAiVsAiAccuracyGraphKnots,
weapDef->originalAiVsAiAccuracyGraphKnotCount));
}
if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots
&& accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName))
{
AccuracyGraphWriter::DumpAiVsPlayerGraph(context,
ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName,
weapDef->originalAiVsPlayerAccuracyGraphKnots,
weapDef->originalAiVsPlayerAccuracyGraphKnotCount));
}
}
} // namespace
namespace T6::weapon
{
bool Dumper::ShouldDump(XAssetInfo<WeaponVariantDef>* asset)
{
return true;
}
DumpAccuracyGraphs(context, asset);
}
void Dumper::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponVariantDef>* asset)
{
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name));
if (!assetFile)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON);
stream.write(stringValue.c_str(), stringValue.size());
}
DumpAccuracyGraphs(context, asset);
}
} // namespace T6::weapon

View File

@@ -0,0 +1,14 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h"
namespace T6::weapon
{
class Dumper final : public AbstractAssetDumper<WeaponVariantDef>
{
protected:
bool ShouldDump(XAssetInfo<WeaponVariantDef>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponVariantDef>* asset) override;
};
} // namespace T6::weapon