mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-01 09:45:35 +00:00
Merge branch 'more_esm4_fields' into 'master'
Support ESM4 record FullName, CellFlags, X, Y fields by esmtool See merge request OpenMW/openmw!3299
This commit is contained in:
commit
6ff2bb8aeb
5 changed files with 144 additions and 31 deletions
|
@ -2,10 +2,12 @@
|
|||
#include "arguments.hpp"
|
||||
#include "labels.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
|
||||
#include <components/debug/writeflags.hpp>
|
||||
#include <components/esm/esmcommon.hpp>
|
||||
#include <components/esm/typetraits.hpp>
|
||||
#include <components/esm4/reader.hpp>
|
||||
|
@ -108,6 +110,29 @@ namespace EsmTool
|
|||
return stream;
|
||||
}
|
||||
|
||||
struct WriteCellFlags
|
||||
{
|
||||
std::uint16_t mValue;
|
||||
};
|
||||
|
||||
using CellFlagString = Debug::FlagString<std::uint16_t>;
|
||||
|
||||
constexpr std::array cellFlags{
|
||||
CellFlagString{ ESM4::CELL_Interior, "Interior" },
|
||||
CellFlagString{ ESM4::CELL_HasWater, "HasWater" },
|
||||
CellFlagString{ ESM4::CELL_NoTravel, "NoTravel" },
|
||||
CellFlagString{ ESM4::CELL_HideLand, "HideLand" },
|
||||
CellFlagString{ ESM4::CELL_Public, "Public" },
|
||||
CellFlagString{ ESM4::CELL_HandChgd, "HandChgd" },
|
||||
CellFlagString{ ESM4::CELL_QuasiExt, "QuasiExt" },
|
||||
CellFlagString{ ESM4::CELL_SkyLight, "SkyLight" },
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const WriteCellFlags& write)
|
||||
{
|
||||
return Debug::writeFlags(stream, write.mValue, cellFlags);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void readTypedRecord(const Params& params, ESM4::Reader& reader)
|
||||
{
|
||||
|
@ -137,6 +162,14 @@ namespace EsmTool
|
|||
std::cout << "\n Parent: " << value.mParent;
|
||||
if constexpr (ESM4::hasEditorId<T>)
|
||||
std::cout << "\n EditorId: " << value.mEditorId;
|
||||
if constexpr (ESM4::hasFullName<T>)
|
||||
std::cout << "\n FullName: " << value.mFullName;
|
||||
if constexpr (ESM4::hasCellFlags<T>)
|
||||
std::cout << "\n CellFlags: " << WriteCellFlags{ value.mCellFlags };
|
||||
if constexpr (ESM4::hasX<T>)
|
||||
std::cout << "\n X: " << value.mX;
|
||||
if constexpr (ESM4::hasY<T>)
|
||||
std::cout << "\n Y: " << value.mY;
|
||||
if constexpr (ESM::hasModel<T>)
|
||||
std::cout << "\n Model: " << value.mModel;
|
||||
if constexpr (ESM4::hasNif<T>)
|
||||
|
|
37
components/debug/writeflags.hpp
Normal file
37
components/debug/writeflags.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef OPENMW_COMPONENTS_DEBUG_WRITEFLAGS_H
|
||||
#define OPENMW_COMPONENTS_DEBUG_WRITEFLAGS_H
|
||||
|
||||
#include <iomanip>
|
||||
#include <ostream>
|
||||
#include <string_view>
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
template <class T>
|
||||
struct FlagString
|
||||
{
|
||||
T mValue;
|
||||
std::string_view mString;
|
||||
};
|
||||
|
||||
template <class T, class FlagStrings>
|
||||
std::ostream& writeFlags(std::ostream& stream, const T& value, const FlagStrings& flagStrings)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto& v : flagStrings)
|
||||
{
|
||||
if ((value & v.mValue) == 0)
|
||||
continue;
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
stream << " | ";
|
||||
stream << v.mString;
|
||||
}
|
||||
if (first)
|
||||
stream << "[None]";
|
||||
return stream << " (0x" << std::hex << value << std::resetiosflags(std::ios_base::hex) << ')';
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -6,6 +6,8 @@
|
|||
#include "tilespositionsrange.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
#include <components/debug/writeflags.hpp>
|
||||
|
||||
#include <DetourNavMesh.h>
|
||||
#include <DetourStatus.h>
|
||||
|
||||
|
@ -94,40 +96,25 @@ namespace DetourNavigator
|
|||
|
||||
namespace
|
||||
{
|
||||
struct StatusString
|
||||
{
|
||||
dtStatus mStatus;
|
||||
std::string_view mString;
|
||||
using StatusString = Debug::FlagString<unsigned int>;
|
||||
|
||||
constexpr std::array dtStatuses{
|
||||
StatusString{ DT_FAILURE, "DT_FAILURE" },
|
||||
StatusString{ DT_SUCCESS, "DT_SUCCESS" },
|
||||
StatusString{ DT_IN_PROGRESS, "DT_IN_PROGRESS" },
|
||||
StatusString{ DT_WRONG_MAGIC, "DT_WRONG_MAGIC" },
|
||||
StatusString{ DT_WRONG_VERSION, "DT_WRONG_VERSION" },
|
||||
StatusString{ DT_OUT_OF_MEMORY, "DT_OUT_OF_MEMORY" },
|
||||
StatusString{ DT_INVALID_PARAM, "DT_INVALID_PARAM" },
|
||||
StatusString{ DT_BUFFER_TOO_SMALL, "DT_BUFFER_TOO_SMALL" },
|
||||
StatusString{ DT_OUT_OF_NODES, "DT_OUT_OF_NODES" },
|
||||
StatusString{ DT_PARTIAL_RESULT, "DT_PARTIAL_RESULT" },
|
||||
};
|
||||
}
|
||||
|
||||
static constexpr std::array dtStatuses{
|
||||
StatusString{ DT_FAILURE, "DT_FAILURE" },
|
||||
StatusString{ DT_SUCCESS, "DT_SUCCESS" },
|
||||
StatusString{ DT_IN_PROGRESS, "DT_IN_PROGRESS" },
|
||||
StatusString{ DT_WRONG_MAGIC, "DT_WRONG_MAGIC" },
|
||||
StatusString{ DT_WRONG_VERSION, "DT_WRONG_VERSION" },
|
||||
StatusString{ DT_OUT_OF_MEMORY, "DT_OUT_OF_MEMORY" },
|
||||
StatusString{ DT_INVALID_PARAM, "DT_INVALID_PARAM" },
|
||||
StatusString{ DT_BUFFER_TOO_SMALL, "DT_BUFFER_TOO_SMALL" },
|
||||
StatusString{ DT_OUT_OF_NODES, "DT_OUT_OF_NODES" },
|
||||
StatusString{ DT_PARTIAL_RESULT, "DT_PARTIAL_RESULT" },
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const WriteDtStatus& value)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto& v : dtStatuses)
|
||||
{
|
||||
if ((value.mStatus & v.mStatus) == 0)
|
||||
continue;
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
stream << " | ";
|
||||
stream << v.mString;
|
||||
}
|
||||
return stream;
|
||||
return Debug::writeFlags(stream, value.mStatus, dtStatuses);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const Flag value)
|
||||
|
|
|
@ -136,11 +136,15 @@ void ESM4::Cell::load(ESM4::Reader& reader)
|
|||
{
|
||||
if (subHdr.dataSize != 1)
|
||||
throw std::runtime_error("CELL unexpected DATA flag size");
|
||||
reader.get(&mCellFlags, sizeof(std::uint8_t));
|
||||
std::uint8_t value = 0;
|
||||
reader.get(value);
|
||||
mCellFlags = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.get((std::uint8_t&)mCellFlags); // 8 bits in Obvlivion
|
||||
std::uint8_t value = 0;
|
||||
reader.get(value); // 8 bits in Obvlivion
|
||||
mCellFlags = value;
|
||||
}
|
||||
#if 0
|
||||
std::string padding;
|
||||
|
|
|
@ -70,6 +70,58 @@ namespace ESM4
|
|||
template <class T>
|
||||
inline constexpr bool hasEditorId = HasEditorId<T>::value;
|
||||
|
||||
template <class T, class = std::void_t<>>
|
||||
struct HasFullName : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct HasFullName<T, std::void_t<decltype(T::mFullName)>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline constexpr bool hasFullName = HasFullName<T>::value;
|
||||
|
||||
template <class T, class = std::void_t<>>
|
||||
struct HasCellFlags : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct HasCellFlags<T, std::void_t<decltype(T::mCellFlags)>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline constexpr bool hasCellFlags = HasCellFlags<T>::value;
|
||||
|
||||
template <class T, class = std::void_t<>>
|
||||
struct HasX : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct HasX<T, std::void_t<decltype(T::mX)>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline constexpr bool hasX = HasX<T>::value;
|
||||
|
||||
template <class T, class = std::void_t<>>
|
||||
struct HasY : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct HasY<T, std::void_t<decltype(T::mY)>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline constexpr bool hasY = HasY<T>::value;
|
||||
|
||||
template <class T, class = std::void_t<>>
|
||||
struct HasNif : std::false_type
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue