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.
openmw/apps/opencs/model/world/nestedcoladapterimp.hpp

583 lines
21 KiB
C++

#ifndef CSM_WOLRD_NESTEDCOLADAPTERIMP_H
#define CSM_WOLRD_NESTEDCOLADAPTERIMP_H
#include <QString>
#include <QVariant>
#include <algorithm>
#include <stdexcept>
#include <string>
#include <vector>
#include <components/esm3/effectlist.hpp>
#include <components/esm3/loadmgef.hpp> // for converting magic effect id to string & back
#include "nestedcolumnadapter.hpp"
#include "nestedtablewrapper.hpp"
namespace ESM
{
struct Faction;
struct Region;
struct Race;
}
namespace CSMWorld
{
struct Pathgrid;
struct Info;
struct Cell;
template <typename ESXRecordT>
struct Record;
class PathgridPointListAdapter : public NestedColumnAdapter<Pathgrid>
{
public:
PathgridPointListAdapter() = default;
void addRow(Record<Pathgrid>& record, int position) const override;
void removeRow(Record<Pathgrid>& record, int rowToRemove) const override;
void setTable(Record<Pathgrid>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<Pathgrid>& record) const override;
QVariant getData(const Record<Pathgrid>& record, int subRowIndex, int subColIndex) const override;
void setData(Record<Pathgrid>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<Pathgrid>& record) const override;
int getRowsCount(const Record<Pathgrid>& record) const override;
};
class PathgridEdgeListAdapter : public NestedColumnAdapter<Pathgrid>
{
public:
PathgridEdgeListAdapter() = default;
void addRow(Record<Pathgrid>& record, int position) const override;
void removeRow(Record<Pathgrid>& record, int rowToRemove) const override;
void setTable(Record<Pathgrid>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<Pathgrid>& record) const override;
QVariant getData(const Record<Pathgrid>& record, int subRowIndex, int subColIndex) const override;
void setData(Record<Pathgrid>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<Pathgrid>& record) const override;
int getRowsCount(const Record<Pathgrid>& record) const override;
};
class FactionReactionsAdapter : public NestedColumnAdapter<ESM::Faction>
{
public:
FactionReactionsAdapter() = default;
void addRow(Record<ESM::Faction>& record, int position) const override;
void removeRow(Record<ESM::Faction>& record, int rowToRemove) const override;
void setTable(Record<ESM::Faction>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<ESM::Faction>& record) const override;
QVariant getData(const Record<ESM::Faction>& record, int subRowIndex, int subColIndex) const override;
void setData(
Record<ESM::Faction>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<ESM::Faction>& record) const override;
int getRowsCount(const Record<ESM::Faction>& record) const override;
};
class FactionRanksAdapter : public NestedColumnAdapter<ESM::Faction>
{
public:
FactionRanksAdapter() = default;
void addRow(Record<ESM::Faction>& record, int position) const override;
void removeRow(Record<ESM::Faction>& record, int rowToRemove) const override;
void setTable(Record<ESM::Faction>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<ESM::Faction>& record) const override;
QVariant getData(const Record<ESM::Faction>& record, int subRowIndex, int subColIndex) const override;
void setData(
Record<ESM::Faction>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<ESM::Faction>& record) const override;
int getRowsCount(const Record<ESM::Faction>& record) const override;
};
class RegionSoundListAdapter : public NestedColumnAdapter<ESM::Region>
{
public:
RegionSoundListAdapter() = default;
void addRow(Record<ESM::Region>& record, int position) const override;
void removeRow(Record<ESM::Region>& record, int rowToRemove) const override;
void setTable(Record<ESM::Region>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<ESM::Region>& record) const override;
QVariant getData(const Record<ESM::Region>& record, int subRowIndex, int subColIndex) const override;
void setData(
Record<ESM::Region>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<ESM::Region>& record) const override;
int getRowsCount(const Record<ESM::Region>& record) const override;
};
template <typename ESXRecordT>
class SpellListAdapter : public NestedColumnAdapter<ESXRecordT>
{
public:
SpellListAdapter() = default;
void addRow(Record<ESXRecordT>& record, int position) const override
{
ESXRecordT raceOrBthSgn = record.get();
std::vector<ESM::RefId>& spells = raceOrBthSgn.mPowers.mList;
// blank row
ESM::RefId spell;
spells.insert(spells.begin() + position, spell);
record.setModified(raceOrBthSgn);
}
void removeRow(Record<ESXRecordT>& record, int rowToRemove) const override
{
ESXRecordT raceOrBthSgn = record.get();
std::vector<ESM::RefId>& spells = raceOrBthSgn.mPowers.mList;
if (rowToRemove < 0 || rowToRemove >= static_cast<int>(spells.size()))
throw std::runtime_error("index out of range");
spells.erase(spells.begin() + rowToRemove);
record.setModified(raceOrBthSgn);
}
void setTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) const override
{
ESXRecordT raceOrBthSgn = record.get();
raceOrBthSgn.mPowers.mList
= static_cast<const NestedTableWrapper<std::vector<ESM::RefId>>&>(nestedTable).mNestedTable;
record.setModified(raceOrBthSgn);
}
NestedTableWrapperBase* table(const Record<ESXRecordT>& record) const override
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<ESM::RefId>>(record.get().mPowers.mList);
}
QVariant getData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const override
{
ESXRecordT raceOrBthSgn = record.get();
std::vector<ESM::RefId>& spells = raceOrBthSgn.mPowers.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(spells.size()))
throw std::runtime_error("index out of range");
ESM::RefId spell = spells[subRowIndex];
switch (subColIndex)
{
case 0:
return QString(spell.getRefIdString().c_str());
default:
throw std::runtime_error("Spells subcolumn index out of range");
}
}
void setData(Record<ESXRecordT>& record, const QVariant& value, int subRowIndex, int subColIndex) const override
{
ESXRecordT raceOrBthSgn = record.get();
std::vector<ESM::RefId>& spells = raceOrBthSgn.mPowers.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(spells.size()))
throw std::runtime_error("index out of range");
ESM::RefId spell = spells[subRowIndex];
switch (subColIndex)
{
case 0:
spell = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
break;
default:
throw std::runtime_error("Spells subcolumn index out of range");
}
raceOrBthSgn.mPowers.mList[subRowIndex] = spell;
record.setModified(raceOrBthSgn);
}
int getColumnsCount(const Record<ESXRecordT>& record) const override { return 1; }
int getRowsCount(const Record<ESXRecordT>& record) const override
{
return static_cast<int>(record.get().mPowers.mList.size());
}
};
template <typename ESXRecordT>
class EffectsListAdapter : public NestedColumnAdapter<ESXRecordT>
{
public:
EffectsListAdapter() = default;
void addRow(Record<ESXRecordT>& record, int position) const override
{
ESXRecordT magic = record.get();
std::vector<ESM::IndexedENAMstruct>& effectsList = magic.mEffects.mList;
// blank row
ESM::IndexedENAMstruct effect;
effect.mIndex = position;
effect.mData.mEffectID = 0;
effect.mData.mSkill = -1;
effect.mData.mAttribute = -1;
effect.mData.mRange = 0;
effect.mData.mArea = 0;
effect.mData.mDuration = 0;
effect.mData.mMagnMin = 0;
effect.mData.mMagnMax = 0;
effectsList.insert(effectsList.begin() + position, effect);
magic.mEffects.updateIndexes();
record.setModified(magic);
}
void removeRow(Record<ESXRecordT>& record, int rowToRemove) const override
{
ESXRecordT magic = record.get();
std::vector<ESM::IndexedENAMstruct>& effectsList = magic.mEffects.mList;
if (rowToRemove < 0 || rowToRemove >= static_cast<int>(effectsList.size()))
throw std::runtime_error("index out of range");
effectsList.erase(effectsList.begin() + rowToRemove);
magic.mEffects.updateIndexes();
record.setModified(magic);
}
void setTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) const override
{
ESXRecordT magic = record.get();
magic.mEffects.mList
= static_cast<const NestedTableWrapper<std::vector<ESM::IndexedENAMstruct>>&>(nestedTable).mNestedTable;
record.setModified(magic);
}
NestedTableWrapperBase* table(const Record<ESXRecordT>& record) const override
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<ESM::IndexedENAMstruct>>(record.get().mEffects.mList);
}
QVariant getData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const override
{
ESXRecordT magic = record.get();
std::vector<ESM::IndexedENAMstruct>& effectsList = magic.mEffects.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(effectsList.size()))
throw std::runtime_error("index out of range");
ESM::ENAMstruct effect = effectsList[subRowIndex].mData;
switch (subColIndex)
{
case 0:
return effect.mEffectID;
case 1:
{
switch (effect.mEffectID)
{
case ESM::MagicEffect::DrainSkill:
case ESM::MagicEffect::DamageSkill:
case ESM::MagicEffect::RestoreSkill:
case ESM::MagicEffect::FortifySkill:
case ESM::MagicEffect::AbsorbSkill:
return effect.mSkill;
default:
return QVariant();
}
}
case 2:
{
switch (effect.mEffectID)
{
case ESM::MagicEffect::DrainAttribute:
case ESM::MagicEffect::DamageAttribute:
case ESM::MagicEffect::RestoreAttribute:
case ESM::MagicEffect::FortifyAttribute:
case ESM::MagicEffect::AbsorbAttribute:
return effect.mAttribute;
default:
return QVariant();
}
}
case 3:
return effect.mRange;
case 4:
return effect.mArea;
case 5:
return effect.mDuration;
case 6:
return effect.mMagnMin;
case 7:
return effect.mMagnMax;
default:
throw std::runtime_error("Magic Effects subcolumn index out of range");
}
}
void setData(Record<ESXRecordT>& record, const QVariant& value, int subRowIndex, int subColIndex) const override
{
ESXRecordT magic = record.get();
std::vector<ESM::IndexedENAMstruct>& effectsList = magic.mEffects.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(effectsList.size()))
throw std::runtime_error("index out of range");
ESM::ENAMstruct effect = effectsList[subRowIndex].mData;
switch (subColIndex)
{
case 0:
{
effect.mEffectID = static_cast<short>(value.toInt());
switch (effect.mEffectID)
{
case ESM::MagicEffect::DrainSkill:
case ESM::MagicEffect::DamageSkill:
case ESM::MagicEffect::RestoreSkill:
case ESM::MagicEffect::FortifySkill:
case ESM::MagicEffect::AbsorbSkill:
effect.mAttribute = -1;
break;
case ESM::MagicEffect::DrainAttribute:
case ESM::MagicEffect::DamageAttribute:
case ESM::MagicEffect::RestoreAttribute:
case ESM::MagicEffect::FortifyAttribute:
case ESM::MagicEffect::AbsorbAttribute:
effect.mSkill = -1;
break;
default:
effect.mSkill = -1;
effect.mAttribute = -1;
}
break;
}
case 1:
{
effect.mSkill = static_cast<signed char>(value.toInt());
break;
}
case 2:
{
effect.mAttribute = static_cast<signed char>(value.toInt());
break;
}
case 3:
{
effect.mRange = value.toInt();
break;
}
case 4:
effect.mArea = value.toInt();
break;
case 5:
effect.mDuration = value.toInt();
break;
case 6:
effect.mMagnMin = value.toInt();
break;
case 7:
effect.mMagnMax = value.toInt();
break;
default:
throw std::runtime_error("Magic Effects subcolumn index out of range");
}
magic.mEffects.mList[subRowIndex].mData = effect;
record.setModified(magic);
}
int getColumnsCount(const Record<ESXRecordT>& record) const override { return 8; }
int getRowsCount(const Record<ESXRecordT>& record) const override
{
return static_cast<int>(record.get().mEffects.mList.size());
}
};
class InfoListAdapter : public NestedColumnAdapter<Info>
{
public:
InfoListAdapter() = default;
void addRow(Record<Info>& record, int position) const override;
void removeRow(Record<Info>& record, int rowToRemove) const override;
void setTable(Record<Info>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<Info>& record) const override;
QVariant getData(const Record<Info>& record, int subRowIndex, int subColIndex) const override;
void setData(Record<Info>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<Info>& record) const override;
int getRowsCount(const Record<Info>& record) const override;
};
class InfoConditionAdapter : public NestedColumnAdapter<Info>
{
public:
InfoConditionAdapter() = default;
void addRow(Record<Info>& record, int position) const override;
void removeRow(Record<Info>& record, int rowToRemove) const override;
void setTable(Record<Info>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<Info>& record) const override;
QVariant getData(const Record<Info>& record, int subRowIndex, int subColIndex) const override;
void setData(Record<Info>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<Info>& record) const override;
int getRowsCount(const Record<Info>& record) const override;
};
class RaceAttributeAdapter : public NestedColumnAdapter<ESM::Race>
{
public:
RaceAttributeAdapter() = default;
void addRow(Record<ESM::Race>& record, int position) const override;
void removeRow(Record<ESM::Race>& record, int rowToRemove) const override;
void setTable(Record<ESM::Race>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<ESM::Race>& record) const override;
QVariant getData(const Record<ESM::Race>& record, int subRowIndex, int subColIndex) const override;
void setData(Record<ESM::Race>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<ESM::Race>& record) const override;
int getRowsCount(const Record<ESM::Race>& record) const override;
};
class RaceSkillsBonusAdapter : public NestedColumnAdapter<ESM::Race>
{
public:
RaceSkillsBonusAdapter() = default;
void addRow(Record<ESM::Race>& record, int position) const override;
void removeRow(Record<ESM::Race>& record, int rowToRemove) const override;
void setTable(Record<ESM::Race>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<ESM::Race>& record) const override;
QVariant getData(const Record<ESM::Race>& record, int subRowIndex, int subColIndex) const override;
void setData(Record<ESM::Race>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<ESM::Race>& record) const override;
int getRowsCount(const Record<ESM::Race>& record) const override;
};
class CellListAdapter : public NestedColumnAdapter<CSMWorld::Cell>
{
public:
CellListAdapter() = default;
void addRow(Record<CSMWorld::Cell>& record, int position) const override;
void removeRow(Record<CSMWorld::Cell>& record, int rowToRemove) const override;
void setTable(Record<CSMWorld::Cell>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<CSMWorld::Cell>& record) const override;
QVariant getData(const Record<CSMWorld::Cell>& record, int subRowIndex, int subColIndex) const override;
void setData(
Record<CSMWorld::Cell>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<CSMWorld::Cell>& record) const override;
int getRowsCount(const Record<CSMWorld::Cell>& record) const override;
};
class RegionWeatherAdapter : public NestedColumnAdapter<ESM::Region>
{
public:
RegionWeatherAdapter() = default;
void addRow(Record<ESM::Region>& record, int position) const override;
void removeRow(Record<ESM::Region>& record, int rowToRemove) const override;
void setTable(Record<ESM::Region>& record, const NestedTableWrapperBase& nestedTable) const override;
NestedTableWrapperBase* table(const Record<ESM::Region>& record) const override;
QVariant getData(const Record<ESM::Region>& record, int subRowIndex, int subColIndex) const override;
void setData(
Record<ESM::Region>& record, const QVariant& value, int subRowIndex, int subColIndex) const override;
int getColumnsCount(const Record<ESM::Region>& record) const override;
int getRowsCount(const Record<ESM::Region>& record) const override;
};
}
#endif // CSM_WOLRD_NESTEDCOLADAPTERIMP_H