mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-21 00:25:44 +00:00
Split InfoString classes into multiple files depending on loading and writing code
This commit is contained in:
parent
9e00ad60e7
commit
abcce11b00
@ -1,171 +0,0 @@
|
|||||||
#include "InfoStringIW4.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
using namespace IW4;
|
|
||||||
|
|
||||||
void InfoStringToStructConverter::FillStructure()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString, void* structure,
|
|
||||||
const cspField_t* fields, const size_t fieldCount)
|
|
||||||
: InfoStringToStructConverterBase(infoString, structure),
|
|
||||||
m_fields(fields),
|
|
||||||
m_field_count(fieldCount)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
|
|
||||||
{
|
|
||||||
switch (static_cast<csParseFieldType_t>(field.iFieldType))
|
|
||||||
{
|
|
||||||
case CSPFT_STRING:
|
|
||||||
FillFromString(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_STRING_MAX_STRING_CHARS:
|
|
||||||
FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_STRING_MAX_QPATH:
|
|
||||||
FillFromStringBuffer(std::string(field.szName), field.iOffset, 64);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_STRING_MAX_OSPATH:
|
|
||||||
FillFromStringBuffer(std::string(field.szName), field.iOffset, 256);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_INT:
|
|
||||||
FillFromInt(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_QBOOLEAN:
|
|
||||||
FillFromQBoolean(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_BOOL:
|
|
||||||
FillFromBool(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_FLOAT:
|
|
||||||
FillFromFloat(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_MPH_TO_INCHES_PER_SEC:
|
|
||||||
{
|
|
||||||
const auto* num = reinterpret_cast<float*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::to_string(*num / 17.6f));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_MILLISECONDS:
|
|
||||||
FillFromMilliseconds(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_FX:
|
|
||||||
{
|
|
||||||
const auto* fx = *reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
|
||||||
|
|
||||||
if (fx)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(fx->name)));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_XMODEL:
|
|
||||||
{
|
|
||||||
const auto* model = *reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
|
||||||
|
|
||||||
if (model)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(model->name)));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_MATERIAL:
|
|
||||||
{
|
|
||||||
const auto* material = *reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
|
||||||
iOffset);
|
|
||||||
|
|
||||||
if (material)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(material->info.name)));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_PHYS_COLLMAP:
|
|
||||||
{
|
|
||||||
const auto* physCollMap = *reinterpret_cast<PhysCollmap**>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
|
||||||
iOffset);
|
|
||||||
|
|
||||||
if (physCollMap)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physCollMap->name)));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_SOUND:
|
|
||||||
{
|
|
||||||
const auto* sndAlias = reinterpret_cast<SndAliasCustom*>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
|
||||||
iOffset);
|
|
||||||
|
|
||||||
if (sndAlias->name)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(sndAlias->name->soundName));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_TRACER:
|
|
||||||
{
|
|
||||||
const auto* tracer = *reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
|
||||||
iOffset);
|
|
||||||
|
|
||||||
if (tracer)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(tracer->name)));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_NUM_BASE_FIELD_TYPES:
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoStringFromStructConverter::FillInfoString()
|
|
||||||
{
|
|
||||||
for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++)
|
|
||||||
{
|
|
||||||
const auto& field = m_fields[fieldIndex];
|
|
||||||
assert(field.iFieldType >= 0);
|
|
||||||
|
|
||||||
if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES)
|
|
||||||
FillFromBaseField(field);
|
|
||||||
else
|
|
||||||
FillFromExtensionField(field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields,
|
|
||||||
const size_t fieldCount)
|
|
||||||
: InfoStringFromStructConverterBase(structure),
|
|
||||||
m_fields(fields),
|
|
||||||
m_field_count(fieldCount)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, const size_t fieldCount,
|
|
||||||
std::function<std::string(scr_string_t)> scriptStringValueCallback)
|
|
||||||
: InfoStringFromStructConverterBase(structure, std::move(scriptStringValueCallback)),
|
|
||||||
m_fields(fields),
|
|
||||||
m_field_count(fieldCount)
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,168 +0,0 @@
|
|||||||
#include "InfoStringT6.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
using namespace T6;
|
|
||||||
|
|
||||||
void InfoStringToStructConverter::FillStructure()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString, void* structure,
|
|
||||||
const cspField_t* fields, const size_t fieldCount)
|
|
||||||
: InfoStringToStructConverterBase(infoString, structure),
|
|
||||||
m_fields(fields),
|
|
||||||
m_field_count(fieldCount)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
|
|
||||||
{
|
|
||||||
switch (static_cast<csParseFieldType_t>(field.iFieldType))
|
|
||||||
{
|
|
||||||
case CSPFT_STRING:
|
|
||||||
FillFromString(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_STRING_MAX_STRING_CHARS:
|
|
||||||
FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_STRING_MAX_QPATH:
|
|
||||||
FillFromStringBuffer(std::string(field.szName), field.iOffset, 64);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_STRING_MAX_OSPATH:
|
|
||||||
FillFromStringBuffer(std::string(field.szName), field.iOffset, 256);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_INT:
|
|
||||||
FillFromInt(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_UINT:
|
|
||||||
FillFromUint(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_BOOL:
|
|
||||||
FillFromBool(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_QBOOLEAN:
|
|
||||||
FillFromQBoolean(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_FLOAT:
|
|
||||||
FillFromFloat(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_MILLISECONDS:
|
|
||||||
FillFromMilliseconds(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_FX:
|
|
||||||
{
|
|
||||||
const auto* fx = *reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
|
||||||
|
|
||||||
if (fx)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(fx->name)));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_XMODEL:
|
|
||||||
{
|
|
||||||
const auto* model = *reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
|
||||||
|
|
||||||
if (model)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(model->name)));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_MATERIAL:
|
|
||||||
case CSPFT_MATERIAL_STREAM:
|
|
||||||
{
|
|
||||||
const auto* material = *reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
|
||||||
iOffset);
|
|
||||||
|
|
||||||
if (material)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(material->info.name)));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_PHYS_PRESET:
|
|
||||||
{
|
|
||||||
const auto* physPreset = *reinterpret_cast<PhysPreset**>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
|
||||||
iOffset);
|
|
||||||
|
|
||||||
if (physPreset)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physPreset->name)));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_SCRIPT_STRING:
|
|
||||||
FillFromScriptString(std::string(field.szName), field.iOffset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSPFT_TRACER:
|
|
||||||
{
|
|
||||||
const auto* tracer = *reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
|
||||||
|
|
||||||
if (tracer)
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(tracer->name)));
|
|
||||||
else
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_SOUND_ALIAS_ID:
|
|
||||||
{
|
|
||||||
// TODO: Search sound files for files matching the hash
|
|
||||||
const auto* hash = reinterpret_cast<unsigned*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
|
||||||
m_info_string.SetValueForKey(std::string(field.szName), "@" + std::to_string(*hash));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSPFT_NUM_BASE_FIELD_TYPES:
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoStringFromStructConverter::FillInfoString()
|
|
||||||
{
|
|
||||||
for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++)
|
|
||||||
{
|
|
||||||
const auto& field = m_fields[fieldIndex];
|
|
||||||
assert(field.iFieldType >= 0);
|
|
||||||
|
|
||||||
if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES)
|
|
||||||
FillFromBaseField(field);
|
|
||||||
else
|
|
||||||
FillFromExtensionField(field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields,
|
|
||||||
const size_t fieldCount)
|
|
||||||
: InfoStringFromStructConverterBase(structure),
|
|
||||||
m_fields(fields),
|
|
||||||
m_field_count(fieldCount)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, const size_t fieldCount,
|
|
||||||
std::function<std::string(scr_string_t)> scriptStringValueCallback)
|
|
||||||
: InfoStringFromStructConverterBase(structure, std::move(scriptStringValueCallback)),
|
|
||||||
m_fields(fields),
|
|
||||||
m_field_count(fieldCount)
|
|
||||||
{
|
|
||||||
}
|
|
105
src/ObjCommon/InfoString/InfoString.cpp
Normal file
105
src/ObjCommon/InfoString/InfoString.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#include "InfoString.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
const std::string InfoString::EMPTY_VALUE;
|
||||||
|
|
||||||
|
bool InfoString::HasKey(const std::string& key) const
|
||||||
|
{
|
||||||
|
return m_values.find(key) != m_values.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& InfoString::GetValueForKey(const std::string& key) const
|
||||||
|
{
|
||||||
|
const auto& value = m_values.find(key);
|
||||||
|
|
||||||
|
if (value == m_values.end())
|
||||||
|
return EMPTY_VALUE;
|
||||||
|
|
||||||
|
return value->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& InfoString::GetValueForKey(const std::string& key, bool* foundValue) const
|
||||||
|
{
|
||||||
|
const auto& value = m_values.find(key);
|
||||||
|
|
||||||
|
if (value == m_values.end())
|
||||||
|
{
|
||||||
|
if (foundValue)
|
||||||
|
*foundValue = false;
|
||||||
|
return EMPTY_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundValue)
|
||||||
|
*foundValue = true;
|
||||||
|
return value->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfoString::SetValueForKey(const std::string& key, std::string value)
|
||||||
|
{
|
||||||
|
if (!HasKey(key))
|
||||||
|
m_keys_by_insertion.push_back(key);
|
||||||
|
|
||||||
|
m_values[key] = std::move(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfoString::RemoveKey(const std::string& key)
|
||||||
|
{
|
||||||
|
const auto& value = m_values.find(key);
|
||||||
|
|
||||||
|
if (value != m_values.end())
|
||||||
|
m_values.erase(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InfoString::ToString() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (const auto& key : m_keys_by_insertion)
|
||||||
|
{
|
||||||
|
const auto value = m_values.find(key);
|
||||||
|
if (!first)
|
||||||
|
ss << '\\';
|
||||||
|
else
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
ss << key << '\\' << value->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InfoString::ToString(const std::string& prefix) const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << prefix;
|
||||||
|
|
||||||
|
for (const auto& key : m_keys_by_insertion)
|
||||||
|
{
|
||||||
|
const auto value = m_values.find(key);
|
||||||
|
ss << '\\' << key << '\\' << value->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfoString::ToGdtProperties(const std::string& prefix, GdtEntry& gdtEntry) const
|
||||||
|
{
|
||||||
|
for (const auto& key : m_keys_by_insertion)
|
||||||
|
{
|
||||||
|
const auto value = m_values.find(key);
|
||||||
|
gdtEntry.m_properties[key] = value->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdtEntry.m_properties["configstringFileType"] = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfoString::FromString()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfoString::FromString(const std::string& prefix)
|
||||||
|
{
|
||||||
|
}
|
28
src/ObjCommon/InfoString/InfoString.h
Normal file
28
src/ObjCommon/InfoString/InfoString.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Utils/ClassUtils.h"
|
||||||
|
#include "Obj/Gdt/GdtEntry.h"
|
||||||
|
|
||||||
|
class InfoString
|
||||||
|
{
|
||||||
|
static const std::string EMPTY_VALUE;
|
||||||
|
std::unordered_map<std::string, std::string> m_values;
|
||||||
|
std::vector<std::string> m_keys_by_insertion;
|
||||||
|
|
||||||
|
public:
|
||||||
|
_NODISCARD bool HasKey(const std::string& key) const;
|
||||||
|
_NODISCARD const std::string& GetValueForKey(const std::string& key) const;
|
||||||
|
const std::string& GetValueForKey(const std::string& key, bool* foundValue) const;
|
||||||
|
void SetValueForKey(const std::string& key, std::string value);
|
||||||
|
void RemoveKey(const std::string& key);
|
||||||
|
|
||||||
|
_NODISCARD std::string ToString() const;
|
||||||
|
_NODISCARD std::string ToString(const std::string& prefix) const;
|
||||||
|
void ToGdtProperties(const std::string& prefix, GdtEntry& gdtEntry) const;
|
||||||
|
|
||||||
|
void FromString();
|
||||||
|
void FromString(const std::string& prefix);
|
||||||
|
};
|
@ -0,0 +1,15 @@
|
|||||||
|
#include "InfoStringToStructConverter.h"
|
||||||
|
|
||||||
|
using namespace IW4;
|
||||||
|
|
||||||
|
void InfoStringToStructConverter::FillStructure()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString, void* structure,
|
||||||
|
const cspField_t* fields, const size_t fieldCount)
|
||||||
|
: InfoStringToStructConverterBase(infoString, structure),
|
||||||
|
m_fields(fields),
|
||||||
|
m_field_count(fieldCount)
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "InfoString/InfoStringToStructConverterBase.h"
|
||||||
|
#include "Game/IW4/IW4.h"
|
||||||
|
|
||||||
|
namespace IW4
|
||||||
|
{
|
||||||
|
class InfoStringToStructConverter : public InfoStringToStructConverterBase
|
||||||
|
{
|
||||||
|
const cspField_t* m_fields;
|
||||||
|
size_t m_field_count;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void FillStructure() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
InfoStringToStructConverter(const InfoString& infoString, void* structure, const cspField_t* fields, size_t fieldCount);
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
#include "InfoStringToStructConverter.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
void InfoStringToStructConverter::FillStructure()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString, void* structure,
|
||||||
|
const cspField_t* fields, const size_t fieldCount)
|
||||||
|
: InfoStringToStructConverterBase(infoString, structure),
|
||||||
|
m_fields(fields),
|
||||||
|
m_field_count(fieldCount)
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "InfoString/InfoStringToStructConverterBase.h"
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
|
||||||
|
namespace T6
|
||||||
|
{
|
||||||
|
class InfoStringToStructConverter : public InfoStringToStructConverterBase
|
||||||
|
{
|
||||||
|
const cspField_t* m_fields;
|
||||||
|
size_t m_field_count;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void FillStructure() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
InfoStringToStructConverter(const InfoString& infoString, void* structure, const cspField_t* fields, size_t fieldCount);
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
#include "InfoStringToStructConverterBase.h"
|
||||||
|
|
||||||
|
InfoStringToStructConverterBase::InfoStringToStructConverterBase(const InfoString& infoString, void* structure)
|
||||||
|
: m_info_string(infoString),
|
||||||
|
m_structure(structure)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoStringToStructConverterBase::~InfoStringToStructConverterBase()
|
||||||
|
= default;
|
||||||
|
|
||||||
|
void InfoStringToStructConverterBase::Convert()
|
||||||
|
{
|
||||||
|
FillStructure();
|
||||||
|
}
|
22
src/ObjLoading/InfoString/InfoStringToStructConverterBase.h
Normal file
22
src/ObjLoading/InfoString/InfoStringToStructConverterBase.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
|
class InfoStringToStructConverterBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const InfoString& m_info_string;
|
||||||
|
void* m_structure;
|
||||||
|
|
||||||
|
virtual void FillStructure() = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
InfoStringToStructConverterBase(const InfoString& infoString, void* structure);
|
||||||
|
virtual ~InfoStringToStructConverterBase();
|
||||||
|
InfoStringToStructConverterBase(const InfoStringToStructConverterBase& other) = delete;
|
||||||
|
InfoStringToStructConverterBase(InfoStringToStructConverterBase&& other) noexcept = delete;
|
||||||
|
InfoStringToStructConverterBase& operator=(const InfoStringToStructConverterBase& other) = delete;
|
||||||
|
InfoStringToStructConverterBase& operator=(InfoStringToStructConverterBase&& other) noexcept = delete;
|
||||||
|
|
||||||
|
void Convert();
|
||||||
|
};
|
@ -5,7 +5,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "Game/IW4/CommonIW4.h"
|
#include "Game/IW4/CommonIW4.h"
|
||||||
#include "Game/IW4/InfoStringIW4.h"
|
#include "Game/IW4/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
using namespace IW4;
|
using namespace IW4;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
namespace IW4
|
namespace IW4
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "Game/IW4/CommonIW4.h"
|
#include "Game/IW4/CommonIW4.h"
|
||||||
#include "Game/IW4/InfoStringIW4.h"
|
#include "Game/IW4/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
using namespace IW4;
|
using namespace IW4;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
namespace IW4
|
namespace IW4
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,159 @@
|
|||||||
|
#include "InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
using namespace IW4;
|
||||||
|
|
||||||
|
void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
|
||||||
|
{
|
||||||
|
switch (static_cast<csParseFieldType_t>(field.iFieldType))
|
||||||
|
{
|
||||||
|
case CSPFT_STRING:
|
||||||
|
FillFromString(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_STRING_MAX_STRING_CHARS:
|
||||||
|
FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_STRING_MAX_QPATH:
|
||||||
|
FillFromStringBuffer(std::string(field.szName), field.iOffset, 64);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_STRING_MAX_OSPATH:
|
||||||
|
FillFromStringBuffer(std::string(field.szName), field.iOffset, 256);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_INT:
|
||||||
|
FillFromInt(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_QBOOLEAN:
|
||||||
|
FillFromQBoolean(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_BOOL:
|
||||||
|
FillFromBool(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_FLOAT:
|
||||||
|
FillFromFloat(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_MPH_TO_INCHES_PER_SEC:
|
||||||
|
{
|
||||||
|
const auto* num = reinterpret_cast<float*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::to_string(*num / 17.6f));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_MILLISECONDS:
|
||||||
|
FillFromMilliseconds(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_FX:
|
||||||
|
{
|
||||||
|
const auto* fx = *reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
|
||||||
|
if (fx)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(fx->name)));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_XMODEL:
|
||||||
|
{
|
||||||
|
const auto* model = *reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
|
||||||
|
if (model)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(model->name)));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_MATERIAL:
|
||||||
|
{
|
||||||
|
const auto* material = *reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
||||||
|
iOffset);
|
||||||
|
|
||||||
|
if (material)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(material->info.name)));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_PHYS_COLLMAP:
|
||||||
|
{
|
||||||
|
const auto* physCollMap = *reinterpret_cast<PhysCollmap**>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
||||||
|
iOffset);
|
||||||
|
|
||||||
|
if (physCollMap)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physCollMap->name)));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_SOUND:
|
||||||
|
{
|
||||||
|
const auto* sndAlias = reinterpret_cast<SndAliasCustom*>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
||||||
|
iOffset);
|
||||||
|
|
||||||
|
if (sndAlias->name)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(sndAlias->name->soundName));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_TRACER:
|
||||||
|
{
|
||||||
|
const auto* tracer = *reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
||||||
|
iOffset);
|
||||||
|
|
||||||
|
if (tracer)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(tracer->name)));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_NUM_BASE_FIELD_TYPES:
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfoStringFromStructConverter::FillInfoString()
|
||||||
|
{
|
||||||
|
for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++)
|
||||||
|
{
|
||||||
|
const auto& field = m_fields[fieldIndex];
|
||||||
|
assert(field.iFieldType >= 0);
|
||||||
|
|
||||||
|
if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES)
|
||||||
|
FillFromBaseField(field);
|
||||||
|
else
|
||||||
|
FillFromExtensionField(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields,
|
||||||
|
const size_t fieldCount)
|
||||||
|
: InfoStringFromStructConverterBase(structure),
|
||||||
|
m_fields(fields),
|
||||||
|
m_field_count(fieldCount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, const size_t fieldCount,
|
||||||
|
std::function<std::string(scr_string_t)> scriptStringValueCallback)
|
||||||
|
: InfoStringFromStructConverterBase(structure, std::move(scriptStringValueCallback)),
|
||||||
|
m_fields(fields),
|
||||||
|
m_field_count(fieldCount)
|
||||||
|
{
|
||||||
|
}
|
@ -1,21 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoStringFromStructConverterBase.h"
|
||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
|
|
||||||
namespace IW4
|
namespace IW4
|
||||||
{
|
{
|
||||||
class InfoStringToStructConverter : public InfoStringToStructConverterBase
|
|
||||||
{
|
|
||||||
const cspField_t* m_fields;
|
|
||||||
size_t m_field_count;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void FillStructure() override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
InfoStringToStructConverter(const InfoString& infoString, void* structure, const cspField_t* fields, size_t fieldCount);
|
|
||||||
};
|
|
||||||
|
|
||||||
class InfoStringFromStructConverter : public InfoStringFromStructConverterBase
|
class InfoStringFromStructConverter : public InfoStringFromStructConverterBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -30,4 +18,4 @@ namespace IW4
|
|||||||
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount);
|
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount);
|
||||||
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount, std::function<std::string(scr_string_t)> scriptStringValueCallback);
|
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount, std::function<std::string(scr_string_t)> scriptStringValueCallback);
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Game/T6/CommonT6.h"
|
#include "Game/T6/CommonT6.h"
|
||||||
#include "Game/T6/InfoStringT6.h"
|
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "Game/T6/InfoStringT6.h"
|
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "Game/T6/CommonT6.h"
|
#include "Game/T6/CommonT6.h"
|
||||||
#include "Game/T6/InfoStringT6.h"
|
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Game/T6/CommonT6.h"
|
#include "Game/T6/CommonT6.h"
|
||||||
#include "Game/T6/InfoStringT6.h"
|
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Game/T6/CommonT6.h"
|
#include "Game/T6/CommonT6.h"
|
||||||
#include "Game/T6/InfoStringT6.h"
|
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Game/T6/CommonT6.h"
|
#include "Game/T6/CommonT6.h"
|
||||||
#include "Game/T6/InfoStringT6.h"
|
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Game/T6/CommonT6.h"
|
#include "Game/T6/CommonT6.h"
|
||||||
#include "Game/T6/InfoStringT6.h"
|
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "Game/T6/InfoStringT6.h"
|
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,156 @@
|
|||||||
|
#include "InfoStringFromStructConverter.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
|
||||||
|
{
|
||||||
|
switch (static_cast<csParseFieldType_t>(field.iFieldType))
|
||||||
|
{
|
||||||
|
case CSPFT_STRING:
|
||||||
|
FillFromString(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_STRING_MAX_STRING_CHARS:
|
||||||
|
FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_STRING_MAX_QPATH:
|
||||||
|
FillFromStringBuffer(std::string(field.szName), field.iOffset, 64);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_STRING_MAX_OSPATH:
|
||||||
|
FillFromStringBuffer(std::string(field.szName), field.iOffset, 256);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_INT:
|
||||||
|
FillFromInt(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_UINT:
|
||||||
|
FillFromUint(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_BOOL:
|
||||||
|
FillFromBool(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_QBOOLEAN:
|
||||||
|
FillFromQBoolean(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_FLOAT:
|
||||||
|
FillFromFloat(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_MILLISECONDS:
|
||||||
|
FillFromMilliseconds(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_FX:
|
||||||
|
{
|
||||||
|
const auto* fx = *reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
|
||||||
|
if (fx)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(fx->name)));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_XMODEL:
|
||||||
|
{
|
||||||
|
const auto* model = *reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
|
||||||
|
if (model)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(model->name)));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_MATERIAL:
|
||||||
|
case CSPFT_MATERIAL_STREAM:
|
||||||
|
{
|
||||||
|
const auto* material = *reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
||||||
|
iOffset);
|
||||||
|
|
||||||
|
if (material)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(material->info.name)));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_PHYS_PRESET:
|
||||||
|
{
|
||||||
|
const auto* physPreset = *reinterpret_cast<PhysPreset**>(reinterpret_cast<uintptr_t>(m_structure) + field.
|
||||||
|
iOffset);
|
||||||
|
|
||||||
|
if (physPreset)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physPreset->name)));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_SCRIPT_STRING:
|
||||||
|
FillFromScriptString(std::string(field.szName), field.iOffset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSPFT_TRACER:
|
||||||
|
{
|
||||||
|
const auto* tracer = *reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
|
||||||
|
if (tracer)
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(tracer->name)));
|
||||||
|
else
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_SOUND_ALIAS_ID:
|
||||||
|
{
|
||||||
|
// TODO: Search sound files for files matching the hash
|
||||||
|
const auto* hash = reinterpret_cast<unsigned*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
m_info_string.SetValueForKey(std::string(field.szName), "@" + std::to_string(*hash));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CSPFT_NUM_BASE_FIELD_TYPES:
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfoStringFromStructConverter::FillInfoString()
|
||||||
|
{
|
||||||
|
for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++)
|
||||||
|
{
|
||||||
|
const auto& field = m_fields[fieldIndex];
|
||||||
|
assert(field.iFieldType >= 0);
|
||||||
|
|
||||||
|
if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES)
|
||||||
|
FillFromBaseField(field);
|
||||||
|
else
|
||||||
|
FillFromExtensionField(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields,
|
||||||
|
const size_t fieldCount)
|
||||||
|
: InfoStringFromStructConverterBase(structure),
|
||||||
|
m_fields(fields),
|
||||||
|
m_field_count(fieldCount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, const size_t fieldCount,
|
||||||
|
std::function<std::string(scr_string_t)> scriptStringValueCallback)
|
||||||
|
: InfoStringFromStructConverterBase(structure, std::move(scriptStringValueCallback)),
|
||||||
|
m_fields(fields),
|
||||||
|
m_field_count(fieldCount)
|
||||||
|
{
|
||||||
|
}
|
@ -1,21 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Utils/InfoString.h"
|
#include "InfoString/InfoStringFromStructConverterBase.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
class InfoStringToStructConverter : public InfoStringToStructConverterBase
|
|
||||||
{
|
|
||||||
const cspField_t* m_fields;
|
|
||||||
size_t m_field_count;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void FillStructure() override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
InfoStringToStructConverter(const InfoString& infoString, void* structure, const cspField_t* fields, size_t fieldCount);
|
|
||||||
};
|
|
||||||
|
|
||||||
class InfoStringFromStructConverter : public InfoStringFromStructConverterBase
|
class InfoStringFromStructConverter : public InfoStringFromStructConverterBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -30,4 +18,4 @@ namespace T6
|
|||||||
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount);
|
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount);
|
||||||
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount, std::function<std::string(scr_string_t)> scriptStringValueCallback);
|
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount, std::function<std::string(scr_string_t)> scriptStringValueCallback);
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,123 +1,6 @@
|
|||||||
#include "InfoString.h"
|
#include "InfoStringFromStructConverterBase.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <sstream>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
const std::string InfoString::EMPTY_VALUE;
|
|
||||||
|
|
||||||
bool InfoString::HasKey(const std::string& key) const
|
|
||||||
{
|
|
||||||
return m_values.find(key) != m_values.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& InfoString::GetValueForKey(const std::string& key) const
|
|
||||||
{
|
|
||||||
const auto& value = m_values.find(key);
|
|
||||||
|
|
||||||
if (value == m_values.end())
|
|
||||||
return EMPTY_VALUE;
|
|
||||||
|
|
||||||
return value->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& InfoString::GetValueForKey(const std::string& key, bool* foundValue) const
|
|
||||||
{
|
|
||||||
const auto& value = m_values.find(key);
|
|
||||||
|
|
||||||
if (value == m_values.end())
|
|
||||||
{
|
|
||||||
if (foundValue)
|
|
||||||
*foundValue = false;
|
|
||||||
return EMPTY_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (foundValue)
|
|
||||||
*foundValue = true;
|
|
||||||
return value->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoString::SetValueForKey(const std::string& key, std::string value)
|
|
||||||
{
|
|
||||||
if (!HasKey(key))
|
|
||||||
m_keys_by_insertion.push_back(key);
|
|
||||||
|
|
||||||
m_values[key] = std::move(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoString::RemoveKey(const std::string& key)
|
|
||||||
{
|
|
||||||
const auto& value = m_values.find(key);
|
|
||||||
|
|
||||||
if (value != m_values.end())
|
|
||||||
m_values.erase(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string InfoString::ToString() const
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
for (const auto& key : m_keys_by_insertion)
|
|
||||||
{
|
|
||||||
const auto value = m_values.find(key);
|
|
||||||
if (!first)
|
|
||||||
ss << '\\';
|
|
||||||
else
|
|
||||||
first = false;
|
|
||||||
|
|
||||||
ss << key << '\\' << value->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string InfoString::ToString(const std::string& prefix) const
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << prefix;
|
|
||||||
|
|
||||||
for (const auto& key : m_keys_by_insertion)
|
|
||||||
{
|
|
||||||
const auto value = m_values.find(key);
|
|
||||||
ss << '\\' << key << '\\' << value->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoString::ToGdtProperties(const std::string& prefix, GdtEntry& gdtEntry) const
|
|
||||||
{
|
|
||||||
for (const auto& key : m_keys_by_insertion)
|
|
||||||
{
|
|
||||||
const auto value = m_values.find(key);
|
|
||||||
gdtEntry.m_properties[key] = value->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
gdtEntry.m_properties["configstringFileType"] = prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoString::FromString()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoString::FromString(const std::string& prefix)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoStringToStructConverterBase::InfoStringToStructConverterBase(const InfoString& infoString, void* structure)
|
|
||||||
: m_info_string(infoString),
|
|
||||||
m_structure(structure)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoStringToStructConverterBase::~InfoStringToStructConverterBase()
|
|
||||||
= default;
|
|
||||||
|
|
||||||
void InfoStringToStructConverterBase::Convert()
|
|
||||||
{
|
|
||||||
FillStructure();
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoStringFromStructConverterBase::InfoStringFromStructConverterBase(const void* structure)
|
InfoStringFromStructConverterBase::InfoStringFromStructConverterBase(const void* structure)
|
||||||
: m_structure(structure),
|
: m_structure(structure),
|
@ -1,52 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Obj/Gdt/GdtEntry.h"
|
#include "InfoString/InfoString.h"
|
||||||
#include "Zone/ZoneTypes.h"
|
#include "Zone/ZoneTypes.h"
|
||||||
|
|
||||||
class InfoString
|
|
||||||
{
|
|
||||||
static const std::string EMPTY_VALUE;
|
|
||||||
std::unordered_map<std::string, std::string> m_values;
|
|
||||||
std::vector<std::string> m_keys_by_insertion;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool HasKey(const std::string& key) const;
|
|
||||||
const std::string& GetValueForKey(const std::string& key) const;
|
|
||||||
const std::string& GetValueForKey(const std::string& key, bool* foundValue) const;
|
|
||||||
void SetValueForKey(const std::string& key, std::string value);
|
|
||||||
void RemoveKey(const std::string& key);
|
|
||||||
|
|
||||||
std::string ToString() const;
|
|
||||||
std::string ToString(const std::string& prefix) const;
|
|
||||||
void ToGdtProperties(const std::string& prefix, GdtEntry& gdtEntry) const;
|
|
||||||
|
|
||||||
void FromString();
|
|
||||||
void FromString(const std::string& prefix);
|
|
||||||
};
|
|
||||||
|
|
||||||
class InfoStringToStructConverterBase
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
const InfoString& m_info_string;
|
|
||||||
void* m_structure;
|
|
||||||
|
|
||||||
virtual void FillStructure() = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
InfoStringToStructConverterBase(const InfoString& infoString, void* structure);
|
|
||||||
virtual ~InfoStringToStructConverterBase();
|
|
||||||
InfoStringToStructConverterBase(const InfoStringToStructConverterBase& other) = delete;
|
|
||||||
InfoStringToStructConverterBase(InfoStringToStructConverterBase&& other) noexcept = delete;
|
|
||||||
InfoStringToStructConverterBase& operator=(const InfoStringToStructConverterBase& other) = delete;
|
|
||||||
InfoStringToStructConverterBase& operator=(InfoStringToStructConverterBase&& other) noexcept = delete;
|
|
||||||
|
|
||||||
void Convert();
|
|
||||||
};
|
|
||||||
|
|
||||||
class InfoStringFromStructConverterBase
|
class InfoStringFromStructConverterBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
Loading…
x
Reference in New Issue
Block a user