mirror of https://github.com/OpenMW/openmw.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
349 lines
9.2 KiB
C++
349 lines
9.2 KiB
C++
#include "columnimp.hpp"
|
|
|
|
#include <apps/opencs/model/world/columnbase.hpp>
|
|
#include <apps/opencs/model/world/columns.hpp>
|
|
#include <apps/opencs/model/world/disabletag.hpp>
|
|
#include <apps/opencs/model/world/land.hpp>
|
|
#include <apps/opencs/model/world/record.hpp>
|
|
|
|
#include <components/esm3/loadland.hpp>
|
|
#include <components/esm3/loadltex.hpp>
|
|
#include <components/esm3/loadmgef.hpp>
|
|
|
|
#include <algorithm>
|
|
#include <stdexcept>
|
|
|
|
namespace CSMWorld
|
|
{
|
|
namespace
|
|
{
|
|
struct GetStringId
|
|
{
|
|
std::string operator()(ESM::EmptyRefId /*value*/) const { return std::string(); }
|
|
|
|
std::string operator()(ESM::StringRefId value) const { return value.getValue(); }
|
|
|
|
std::string operator()(ESM::FormId value) const { return value.toString("FormId:"); }
|
|
|
|
std::string operator()(ESM::IndexRefId value) const
|
|
{
|
|
switch (value.getRecordType())
|
|
{
|
|
case ESM::REC_MGEF:
|
|
return std::string(ESM::MagicEffect::sIndexNames[value.getValue()]);
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return value.toDebugString();
|
|
}
|
|
|
|
template <class T>
|
|
std::string operator()(const T& value) const
|
|
{
|
|
return value.toDebugString();
|
|
}
|
|
};
|
|
}
|
|
|
|
/* LandTextureIndexColumn */
|
|
LandTextureIndexColumn::LandTextureIndexColumn()
|
|
: Column<ESM::LandTexture>(Columns::ColumnId_TextureIndex, ColumnBase::Display_Integer)
|
|
{
|
|
}
|
|
|
|
QVariant LandTextureIndexColumn::get(const Record<ESM::LandTexture>& record) const
|
|
{
|
|
return record.get().mIndex;
|
|
}
|
|
|
|
bool LandTextureIndexColumn::isEditable() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/* LandPluginIndexColumn */
|
|
LandPluginIndexColumn::LandPluginIndexColumn()
|
|
: Column<Land>(Columns::ColumnId_PluginIndex, ColumnBase::Display_Integer, 0)
|
|
{
|
|
}
|
|
|
|
QVariant LandPluginIndexColumn::get(const Record<Land>& record) const
|
|
{
|
|
return record.get().getPlugin();
|
|
}
|
|
|
|
bool LandPluginIndexColumn::isEditable() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/* LandNormalsColumn */
|
|
LandNormalsColumn::LandNormalsColumn()
|
|
: Column<Land>(Columns::ColumnId_LandNormalsIndex, ColumnBase::Display_String, 0)
|
|
{
|
|
}
|
|
|
|
QVariant LandNormalsColumn::get(const Record<Land>& record) const
|
|
{
|
|
const int Size = Land::LAND_NUM_VERTS * 3;
|
|
const Land& land = record.get();
|
|
|
|
DataType values(Size, 0);
|
|
|
|
if (land.isDataLoaded(Land::DATA_VNML))
|
|
{
|
|
for (int i = 0; i < Size; ++i)
|
|
values[i] = land.getLandData()->mNormals[i];
|
|
}
|
|
|
|
QVariant variant;
|
|
variant.setValue(values);
|
|
return variant;
|
|
}
|
|
|
|
void LandNormalsColumn::set(Record<Land>& record, const QVariant& data)
|
|
{
|
|
DataType values = data.value<DataType>();
|
|
|
|
if (values.size() != Land::LAND_NUM_VERTS * 3)
|
|
throw std::runtime_error("invalid land normals data");
|
|
|
|
Land copy = record.get();
|
|
copy.add(Land::DATA_VNML);
|
|
|
|
for (int i = 0; i < values.size(); ++i)
|
|
{
|
|
copy.getLandData()->mNormals[i] = values[i];
|
|
}
|
|
|
|
record.setModified(copy);
|
|
}
|
|
|
|
bool LandNormalsColumn::isEditable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/* LandHeightsColumn */
|
|
LandHeightsColumn::LandHeightsColumn()
|
|
: Column<Land>(Columns::ColumnId_LandHeightsIndex, ColumnBase::Display_String, 0)
|
|
{
|
|
}
|
|
|
|
QVariant LandHeightsColumn::get(const Record<Land>& record) const
|
|
{
|
|
const int Size = Land::LAND_NUM_VERTS;
|
|
const Land& land = record.get();
|
|
|
|
DataType values(Size, 0);
|
|
|
|
if (land.isDataLoaded(Land::DATA_VHGT))
|
|
{
|
|
for (int i = 0; i < Size; ++i)
|
|
values[i] = land.getLandData()->mHeights[i];
|
|
}
|
|
|
|
QVariant variant;
|
|
variant.setValue(values);
|
|
return variant;
|
|
}
|
|
|
|
void LandHeightsColumn::set(Record<Land>& record, const QVariant& data)
|
|
{
|
|
DataType values = data.value<DataType>();
|
|
|
|
if (values.size() != Land::LAND_NUM_VERTS)
|
|
throw std::runtime_error("invalid land heights data");
|
|
|
|
Land copy = record.get();
|
|
copy.add(Land::DATA_VHGT);
|
|
|
|
for (int i = 0; i < values.size(); ++i)
|
|
{
|
|
copy.getLandData()->mHeights[i] = values[i];
|
|
}
|
|
|
|
copy.mFlags |= Land::Flag_HeightsNormals;
|
|
|
|
record.setModified(copy);
|
|
}
|
|
|
|
bool LandHeightsColumn::isEditable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/* LandColoursColumn */
|
|
LandColoursColumn::LandColoursColumn()
|
|
: Column<Land>(Columns::ColumnId_LandColoursIndex, ColumnBase::Display_String, 0)
|
|
{
|
|
}
|
|
|
|
QVariant LandColoursColumn::get(const Record<Land>& record) const
|
|
{
|
|
const int Size = Land::LAND_NUM_VERTS * 3;
|
|
const Land& land = record.get();
|
|
|
|
DataType values(Size, 0);
|
|
|
|
if (land.isDataLoaded(Land::DATA_VCLR))
|
|
{
|
|
for (int i = 0; i < Size; ++i)
|
|
values[i] = land.getLandData()->mColours[i];
|
|
}
|
|
|
|
QVariant variant;
|
|
variant.setValue(values);
|
|
return variant;
|
|
}
|
|
|
|
void LandColoursColumn::set(Record<Land>& record, const QVariant& data)
|
|
{
|
|
DataType values = data.value<DataType>();
|
|
|
|
if (values.size() != Land::LAND_NUM_VERTS * 3)
|
|
throw std::runtime_error("invalid land colours data");
|
|
|
|
Land copy = record.get();
|
|
copy.add(Land::DATA_VCLR);
|
|
|
|
for (int i = 0; i < values.size(); ++i)
|
|
{
|
|
copy.getLandData()->mColours[i] = values[i];
|
|
}
|
|
|
|
copy.mFlags |= Land::Flag_Colors;
|
|
|
|
record.setModified(copy);
|
|
}
|
|
|
|
bool LandColoursColumn::isEditable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/* LandTexturesColumn */
|
|
LandTexturesColumn::LandTexturesColumn()
|
|
: Column<Land>(Columns::ColumnId_LandTexturesIndex, ColumnBase::Display_String, 0)
|
|
{
|
|
}
|
|
|
|
QVariant LandTexturesColumn::get(const Record<Land>& record) const
|
|
{
|
|
const int Size = Land::LAND_NUM_TEXTURES;
|
|
const Land& land = record.get();
|
|
|
|
DataType values(Size, 0);
|
|
|
|
if (land.isDataLoaded(Land::DATA_VTEX))
|
|
{
|
|
for (int i = 0; i < Size; ++i)
|
|
values[i] = land.getLandData()->mTextures[i];
|
|
}
|
|
|
|
QVariant variant;
|
|
variant.setValue(values);
|
|
return variant;
|
|
}
|
|
|
|
void LandTexturesColumn::set(Record<Land>& record, const QVariant& data)
|
|
{
|
|
DataType values = data.value<DataType>();
|
|
|
|
if (values.size() != Land::LAND_NUM_TEXTURES)
|
|
throw std::runtime_error("invalid land textures data");
|
|
|
|
Land copy = record.get();
|
|
copy.add(Land::DATA_VTEX);
|
|
|
|
for (int i = 0; i < values.size(); ++i)
|
|
{
|
|
copy.getLandData()->mTextures[i] = values[i];
|
|
}
|
|
|
|
copy.mFlags |= Land::Flag_Textures;
|
|
|
|
record.setModified(copy);
|
|
}
|
|
|
|
bool LandTexturesColumn::isEditable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/* BodyPartRaceColumn */
|
|
BodyPartRaceColumn::BodyPartRaceColumn(const MeshTypeColumn<ESM::BodyPart>* meshType)
|
|
: mMeshType(meshType)
|
|
{
|
|
}
|
|
|
|
QVariant BodyPartRaceColumn::get(const Record<ESM::BodyPart>& record) const
|
|
{
|
|
if (mMeshType != nullptr && mMeshType->get(record) == ESM::BodyPart::MT_Skin)
|
|
{
|
|
return QString::fromUtf8(record.get().mRace.getRefIdString().c_str());
|
|
}
|
|
|
|
return DisableTag::getVariant();
|
|
}
|
|
|
|
void BodyPartRaceColumn::set(Record<ESM::BodyPart>& record, const QVariant& data)
|
|
{
|
|
ESM::BodyPart record2 = record.get();
|
|
|
|
record2.mRace = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
|
|
|
|
record.setModified(record2);
|
|
}
|
|
|
|
bool BodyPartRaceColumn::isEditable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
SelectionGroupColumn::SelectionGroupColumn()
|
|
: Column<ESM::SelectionGroup>(Columns::ColumnId_SelectionGroupObjects, ColumnBase::Display_None)
|
|
{
|
|
}
|
|
|
|
QVariant SelectionGroupColumn::get(const Record<ESM::SelectionGroup>& record) const
|
|
{
|
|
QVariant data;
|
|
QStringList selectionInfo;
|
|
const std::vector<std::string>& instances = record.get().selectedInstances;
|
|
|
|
for (const std::string& instance : instances)
|
|
selectionInfo << QString::fromStdString(instance);
|
|
data.setValue(selectionInfo);
|
|
|
|
return data;
|
|
}
|
|
|
|
void SelectionGroupColumn::set(Record<ESM::SelectionGroup>& record, const QVariant& data)
|
|
{
|
|
ESM::SelectionGroup record2 = record.get();
|
|
for (const auto& item : data.toStringList())
|
|
record2.selectedInstances.push_back(item.toStdString());
|
|
record.setModified(record2);
|
|
}
|
|
|
|
bool SelectionGroupColumn::isEditable() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::optional<std::uint32_t> getSkillIndex(std::string_view value)
|
|
{
|
|
int index = ESM::Skill::refIdToIndex(ESM::RefId::stringRefId(value));
|
|
if (index < 0)
|
|
return std::nullopt;
|
|
return static_cast<std::uint32_t>(index);
|
|
}
|
|
|
|
std::string getStringId(ESM::RefId value)
|
|
{
|
|
return visit(GetStringId{}, value);
|
|
}
|
|
}
|