2012-11-26 11:29:22 +00:00
|
|
|
|
|
|
|
#include "data.hpp"
|
|
|
|
|
|
|
|
#include <stdexcept>
|
2013-09-19 10:11:27 +00:00
|
|
|
#include <algorithm>
|
2012-11-26 11:29:22 +00:00
|
|
|
|
2013-03-21 09:07:25 +00:00
|
|
|
#include <QAbstractItemModel>
|
2012-11-26 11:29:22 +00:00
|
|
|
|
2013-02-07 11:52:01 +00:00
|
|
|
#include <components/esm/esmreader.hpp>
|
2013-03-05 07:02:27 +00:00
|
|
|
#include <components/esm/defs.hpp>
|
2012-11-26 11:29:22 +00:00
|
|
|
#include <components/esm/loadglob.hpp>
|
2013-09-22 08:43:09 +00:00
|
|
|
#include <components/esm/cellref.hpp>
|
2012-11-26 11:29:22 +00:00
|
|
|
|
2015-06-24 11:05:59 +00:00
|
|
|
#include <components/gameplay/autocalc.hpp>
|
|
|
|
#include <components/gameplay/autocalcspell.hpp>
|
|
|
|
#include <components/gameplay/store.hpp>
|
|
|
|
|
2012-11-26 11:29:22 +00:00
|
|
|
#include "idtable.hpp"
|
2015-04-02 09:19:15 +00:00
|
|
|
#include "idtree.hpp"
|
2013-08-02 08:42:52 +00:00
|
|
|
#include "columnimp.hpp"
|
2013-07-08 11:12:50 +00:00
|
|
|
#include "regionmap.hpp"
|
2013-08-07 07:36:05 +00:00
|
|
|
#include "columns.hpp"
|
2014-07-04 10:46:57 +00:00
|
|
|
#include "resourcesmanager.hpp"
|
2014-07-05 13:50:47 +00:00
|
|
|
#include "resourcetable.hpp"
|
2015-04-12 03:48:23 +00:00
|
|
|
#include "nestedcoladapterimp.hpp"
|
2015-06-24 11:05:59 +00:00
|
|
|
#include "npcstats.hpp"
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
class SpellStore : public GamePlay::CommonStore <ESM::Spell>
|
|
|
|
{
|
|
|
|
const CSMWorld::NestedIdCollection<ESM::Spell>& mSpells;
|
|
|
|
std::vector<ESM::Spell *> mLocal;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
SpellStore(const CSMWorld::NestedIdCollection<ESM::Spell>& spells)
|
|
|
|
: mSpells(spells)
|
|
|
|
{
|
|
|
|
// prepare data in a format used by OpenMW store
|
|
|
|
for (int index = 0; index < mSpells.getSize(); ++index)
|
|
|
|
{
|
|
|
|
ESM::Spell *spell = const_cast<ESM::Spell *>(&mSpells.getRecord(index).get());
|
|
|
|
mLocal.push_back(spell);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
~SpellStore() {}
|
|
|
|
|
|
|
|
typedef GamePlay::SharedIterator<ESM::Spell> iterator;
|
|
|
|
|
|
|
|
virtual iterator begin() const
|
|
|
|
{
|
|
|
|
return mLocal.begin();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual iterator end() const
|
|
|
|
{
|
|
|
|
return mLocal.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const ESM::Spell *find(const std::string &id) const
|
|
|
|
{
|
|
|
|
return &mSpells.getRecord(id).get();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual size_t getSize() const
|
|
|
|
{
|
|
|
|
return mSpells.getSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
// not used in OpenCS
|
|
|
|
virtual void load(ESM::ESMReader &esm, const std::string &id)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class CSStore : public GamePlay::StoreWrap
|
|
|
|
{
|
|
|
|
const CSMWorld::IdCollection<ESM::GameSetting>& mGmstTable;
|
|
|
|
const CSMWorld::IdCollection<ESM::Skill>& mSkillTable;
|
|
|
|
const CSMWorld::IdCollection<ESM::MagicEffect>& mMagicEffectTable;
|
|
|
|
const SpellStore mSpellStore;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
CSStore(const CSMWorld::IdCollection<ESM::GameSetting>& gmst,
|
|
|
|
const CSMWorld::IdCollection<ESM::Skill>& skills,
|
|
|
|
const CSMWorld::IdCollection<ESM::MagicEffect>& magicEffects,
|
|
|
|
const CSMWorld::NestedIdCollection<ESM::Spell>& spells)
|
|
|
|
: mGmstTable(gmst), mSkillTable(skills), mMagicEffectTable(magicEffects), mSpellStore(spells)
|
|
|
|
{ }
|
|
|
|
~CSStore() {}
|
|
|
|
|
|
|
|
virtual int findGmstInt(const std::string& name) const
|
|
|
|
{
|
|
|
|
return mGmstTable.getRecord(name).get().getInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual float findGmstFloat(const std::string& name) const
|
|
|
|
{
|
|
|
|
return mGmstTable.getRecord(name).get().getFloat();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const ESM::Skill *findSkill(int index) const
|
|
|
|
{
|
|
|
|
// if the skill does not exist, throws std::runtime_error ("invalid ID: " + id)
|
|
|
|
return &mSkillTable.getRecord(ESM::Skill::indexToId(index)).get();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const ESM::MagicEffect* findMagicEffect(int id) const
|
|
|
|
{
|
|
|
|
// if the magic effect does not exist, throws std::runtime_error ("invalid ID: " + id)
|
|
|
|
return &mMagicEffectTable.getRecord(ESM::MagicEffect::indexToId((short)id)).get();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const GamePlay::CommonStore<ESM::Spell>& getSpells() const
|
|
|
|
{
|
|
|
|
return mSpellStore;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
unsigned short autoCalculateMana(GamePlay::StatsBase& stats)
|
|
|
|
{
|
|
|
|
return stats.getBaseAttribute(ESM::Attribute::Intelligence) * 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned short autoCalculateFatigue(GamePlay::StatsBase& stats)
|
|
|
|
{
|
|
|
|
return stats.getBaseAttribute(ESM::Attribute::Strength)
|
|
|
|
+ stats.getBaseAttribute(ESM::Attribute::Willpower)
|
|
|
|
+ stats.getBaseAttribute(ESM::Attribute::Agility)
|
|
|
|
+ stats.getBaseAttribute(ESM::Attribute::Endurance);
|
|
|
|
}
|
|
|
|
}
|
2012-11-26 11:29:22 +00:00
|
|
|
|
2014-06-06 18:47:31 +00:00
|
|
|
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type, bool update)
|
2012-12-30 13:01:52 +00:00
|
|
|
{
|
|
|
|
mModels.push_back (model);
|
2014-06-06 18:47:31 +00:00
|
|
|
mModelIndex.insert (std::make_pair (type, model));
|
|
|
|
|
|
|
|
UniversalId::Type type2 = UniversalId::getParentType (type);
|
2012-12-30 13:01:52 +00:00
|
|
|
|
|
|
|
if (type2!=UniversalId::Type_None)
|
|
|
|
mModelIndex.insert (std::make_pair (type2, model));
|
2013-09-19 10:11:27 +00:00
|
|
|
|
|
|
|
if (update)
|
|
|
|
{
|
|
|
|
connect (model, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
|
|
|
this, SLOT (dataChanged (const QModelIndex&, const QModelIndex&)));
|
|
|
|
connect (model, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
|
|
|
this, SLOT (rowsChanged (const QModelIndex&, int, int)));
|
|
|
|
connect (model, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
|
|
|
|
this, SLOT (rowsChanged (const QModelIndex&, int, int)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-19 11:42:19 +00:00
|
|
|
void CSMWorld::Data::appendIds (std::vector<std::string>& ids, const CollectionBase& collection,
|
|
|
|
bool listDeleted)
|
2013-09-19 10:11:27 +00:00
|
|
|
{
|
2013-09-19 11:42:19 +00:00
|
|
|
std::vector<std::string> ids2 = collection.getIds (listDeleted);
|
2013-09-19 10:11:27 +00:00
|
|
|
|
|
|
|
ids.insert (ids.end(), ids2.begin(), ids2.end());
|
2012-12-30 13:01:52 +00:00
|
|
|
}
|
|
|
|
|
2013-09-24 15:08:24 +00:00
|
|
|
int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collection)
|
|
|
|
{
|
|
|
|
int number = 0;
|
|
|
|
|
|
|
|
for (int i=0; i<collection.getSize(); ++i)
|
|
|
|
if (collection.getRecord (i).mState==state)
|
|
|
|
++number;
|
|
|
|
|
|
|
|
return number;
|
|
|
|
}
|
|
|
|
|
2014-07-04 10:46:57 +00:00
|
|
|
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager)
|
2014-10-04 13:36:52 +00:00
|
|
|
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
|
2015-06-18 12:02:08 +00:00
|
|
|
mResourcesManager (resourcesManager), mReader (0), mDialogue (0), mReaderIndex(0),
|
|
|
|
mReferenceables(self())
|
2012-11-26 11:29:22 +00:00
|
|
|
{
|
2015-04-12 03:48:23 +00:00
|
|
|
int index = 0;
|
|
|
|
|
2012-11-29 17:56:28 +00:00
|
|
|
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
|
2012-12-01 12:42:12 +00:00
|
|
|
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
|
2012-12-13 12:35:08 +00:00
|
|
|
mGlobals.addColumn (new FixedRecordTypeColumn<ESM::Global> (UniversalId::Type_Global));
|
2013-03-05 10:37:13 +00:00
|
|
|
mGlobals.addColumn (new VarTypeColumn<ESM::Global> (ColumnBase::Display_GlobalVarType));
|
|
|
|
mGlobals.addColumn (new VarValueColumn<ESM::Global>);
|
2012-11-26 11:29:22 +00:00
|
|
|
|
2013-02-08 08:58:19 +00:00
|
|
|
mGmsts.addColumn (new StringIdColumn<ESM::GameSetting>);
|
|
|
|
mGmsts.addColumn (new RecordStateColumn<ESM::GameSetting>);
|
|
|
|
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
|
2013-03-05 10:37:13 +00:00
|
|
|
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType));
|
2013-02-08 13:48:38 +00:00
|
|
|
mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>);
|
2013-02-08 08:58:19 +00:00
|
|
|
|
2013-03-21 13:31:32 +00:00
|
|
|
mSkills.addColumn (new StringIdColumn<ESM::Skill>);
|
|
|
|
mSkills.addColumn (new RecordStateColumn<ESM::Skill>);
|
2013-04-09 12:27:32 +00:00
|
|
|
mSkills.addColumn (new FixedRecordTypeColumn<ESM::Skill> (UniversalId::Type_Skill));
|
2013-03-24 14:50:29 +00:00
|
|
|
mSkills.addColumn (new AttributeColumn<ESM::Skill>);
|
2013-03-23 12:13:53 +00:00
|
|
|
mSkills.addColumn (new SpecialisationColumn<ESM::Skill>);
|
2013-03-24 13:51:48 +00:00
|
|
|
for (int i=0; i<4; ++i)
|
|
|
|
mSkills.addColumn (new UseValueColumn<ESM::Skill> (i));
|
2013-03-21 13:38:06 +00:00
|
|
|
mSkills.addColumn (new DescriptionColumn<ESM::Skill>);
|
|
|
|
|
2013-03-25 12:22:06 +00:00
|
|
|
mClasses.addColumn (new StringIdColumn<ESM::Class>);
|
|
|
|
mClasses.addColumn (new RecordStateColumn<ESM::Class>);
|
2013-04-09 12:27:32 +00:00
|
|
|
mClasses.addColumn (new FixedRecordTypeColumn<ESM::Class> (UniversalId::Type_Class));
|
2013-03-25 13:31:46 +00:00
|
|
|
mClasses.addColumn (new NameColumn<ESM::Class>);
|
|
|
|
mClasses.addColumn (new AttributesColumn<ESM::Class> (0));
|
|
|
|
mClasses.addColumn (new AttributesColumn<ESM::Class> (1));
|
2013-03-25 12:22:06 +00:00
|
|
|
mClasses.addColumn (new SpecialisationColumn<ESM::Class>);
|
2013-03-26 08:43:13 +00:00
|
|
|
for (int i=0; i<5; ++i)
|
2013-04-02 12:04:13 +00:00
|
|
|
mClasses.addColumn (new SkillsColumn<ESM::Class> (i, true, true));
|
2013-03-26 08:43:13 +00:00
|
|
|
for (int i=0; i<5; ++i)
|
2013-04-02 12:04:13 +00:00
|
|
|
mClasses.addColumn (new SkillsColumn<ESM::Class> (i, true, false));
|
2013-03-26 08:51:39 +00:00
|
|
|
mClasses.addColumn (new PlayableColumn<ESM::Class>);
|
2013-03-25 12:22:06 +00:00
|
|
|
mClasses.addColumn (new DescriptionColumn<ESM::Class>);
|
|
|
|
|
2013-04-02 10:00:45 +00:00
|
|
|
mFactions.addColumn (new StringIdColumn<ESM::Faction>);
|
|
|
|
mFactions.addColumn (new RecordStateColumn<ESM::Faction>);
|
2013-04-09 12:27:32 +00:00
|
|
|
mFactions.addColumn (new FixedRecordTypeColumn<ESM::Faction> (UniversalId::Type_Faction));
|
2013-04-02 10:00:45 +00:00
|
|
|
mFactions.addColumn (new NameColumn<ESM::Faction>);
|
2013-04-04 08:58:53 +00:00
|
|
|
mFactions.addColumn (new AttributesColumn<ESM::Faction> (0));
|
|
|
|
mFactions.addColumn (new AttributesColumn<ESM::Faction> (1));
|
2013-04-02 12:20:51 +00:00
|
|
|
mFactions.addColumn (new HiddenColumn<ESM::Faction>);
|
2014-06-15 21:05:38 +00:00
|
|
|
for (int i=0; i<7; ++i)
|
2013-04-02 12:04:13 +00:00
|
|
|
mFactions.addColumn (new SkillsColumn<ESM::Faction> (i));
|
2015-04-11 07:51:30 +00:00
|
|
|
// Faction Reactions
|
2015-04-12 03:48:23 +00:00
|
|
|
mFactions.addColumn (new NestedParentColumn<ESM::Faction> (Columns::ColumnId_FactionReactions));
|
|
|
|
index = mFactions.getColumns()-1;
|
|
|
|
mFactions.addAdapter (std::make_pair(&mFactions.getColumn(index), new FactionReactionsAdapter ()));
|
|
|
|
mFactions.getNestableColumn(index)->addColumn(
|
2015-06-02 21:02:53 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_Faction));
|
2015-04-12 03:48:23 +00:00
|
|
|
mFactions.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_FactionReaction, ColumnBase::Display_Integer));
|
2013-04-02 10:00:45 +00:00
|
|
|
|
2013-04-04 12:34:39 +00:00
|
|
|
mRaces.addColumn (new StringIdColumn<ESM::Race>);
|
|
|
|
mRaces.addColumn (new RecordStateColumn<ESM::Race>);
|
2013-04-09 12:27:32 +00:00
|
|
|
mRaces.addColumn (new FixedRecordTypeColumn<ESM::Race> (UniversalId::Type_Race));
|
2013-04-04 12:34:39 +00:00
|
|
|
mRaces.addColumn (new NameColumn<ESM::Race>);
|
|
|
|
mRaces.addColumn (new DescriptionColumn<ESM::Race>);
|
2013-08-07 07:36:05 +00:00
|
|
|
mRaces.addColumn (new FlagColumn<ESM::Race> (Columns::ColumnId_Playable, 0x1));
|
|
|
|
mRaces.addColumn (new FlagColumn<ESM::Race> (Columns::ColumnId_BeastRace, 0x2));
|
2013-04-05 11:46:48 +00:00
|
|
|
mRaces.addColumn (new WeightHeightColumn<ESM::Race> (true, true));
|
|
|
|
mRaces.addColumn (new WeightHeightColumn<ESM::Race> (true, false));
|
|
|
|
mRaces.addColumn (new WeightHeightColumn<ESM::Race> (false, true));
|
|
|
|
mRaces.addColumn (new WeightHeightColumn<ESM::Race> (false, false));
|
2015-04-11 09:05:03 +00:00
|
|
|
// Race spells
|
2015-04-17 03:45:45 +00:00
|
|
|
mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_PowerList));
|
2015-04-12 03:48:23 +00:00
|
|
|
index = mRaces.getColumns()-1;
|
|
|
|
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new SpellListAdapter<ESM::Race> ()));
|
|
|
|
mRaces.getNestableColumn(index)->addColumn(
|
2015-06-02 21:02:53 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_Spell));
|
2015-05-18 20:56:38 +00:00
|
|
|
// Race attributes
|
|
|
|
mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceAttributes));
|
|
|
|
index = mRaces.getColumns()-1;
|
|
|
|
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new RaceAttributeAdapter()));
|
|
|
|
mRaces.getNestableColumn(index)->addColumn(
|
2015-05-26 03:35:10 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_RaceAttributes, ColumnBase::Display_String,
|
|
|
|
ColumnBase::Flag_Dialogue, false));
|
2015-05-18 20:56:38 +00:00
|
|
|
mRaces.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_RaceMaleValue, ColumnBase::Display_Integer));
|
|
|
|
mRaces.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_RaceFemaleValue, ColumnBase::Display_Integer));
|
|
|
|
// Race skill bonus
|
|
|
|
mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceSkillBonus));
|
|
|
|
index = mRaces.getColumns()-1;
|
|
|
|
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new RaceSkillsBonusAdapter()));
|
|
|
|
mRaces.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_RaceSkill, ColumnBase::Display_RaceSkill));
|
|
|
|
mRaces.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_RaceBonus, ColumnBase::Display_Integer));
|
2013-04-04 12:34:39 +00:00
|
|
|
|
2013-04-06 19:21:10 +00:00
|
|
|
mSounds.addColumn (new StringIdColumn<ESM::Sound>);
|
|
|
|
mSounds.addColumn (new RecordStateColumn<ESM::Sound>);
|
2013-04-09 12:27:32 +00:00
|
|
|
mSounds.addColumn (new FixedRecordTypeColumn<ESM::Sound> (UniversalId::Type_Sound));
|
2013-04-06 19:40:03 +00:00
|
|
|
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_Volume));
|
|
|
|
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MinRange));
|
|
|
|
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MaxRange));
|
2013-04-06 19:43:05 +00:00
|
|
|
mSounds.addColumn (new SoundFileColumn<ESM::Sound>);
|
2013-04-06 19:21:10 +00:00
|
|
|
|
2013-04-07 13:17:35 +00:00
|
|
|
mScripts.addColumn (new StringIdColumn<ESM::Script>);
|
|
|
|
mScripts.addColumn (new RecordStateColumn<ESM::Script>);
|
2013-04-09 12:27:32 +00:00
|
|
|
mScripts.addColumn (new FixedRecordTypeColumn<ESM::Script> (UniversalId::Type_Script));
|
2014-08-24 11:15:18 +00:00
|
|
|
mScripts.addColumn (new ScriptColumn<ESM::Script> (ScriptColumn<ESM::Script>::Type_File));
|
2013-04-07 13:17:35 +00:00
|
|
|
|
2013-04-07 14:32:06 +00:00
|
|
|
mRegions.addColumn (new StringIdColumn<ESM::Region>);
|
|
|
|
mRegions.addColumn (new RecordStateColumn<ESM::Region>);
|
2013-04-09 12:27:32 +00:00
|
|
|
mRegions.addColumn (new FixedRecordTypeColumn<ESM::Region> (UniversalId::Type_Region));
|
2013-04-07 14:32:06 +00:00
|
|
|
mRegions.addColumn (new NameColumn<ESM::Region>);
|
2013-04-07 14:56:21 +00:00
|
|
|
mRegions.addColumn (new MapColourColumn<ESM::Region>);
|
2013-04-07 17:29:15 +00:00
|
|
|
mRegions.addColumn (new SleepListColumn<ESM::Region>);
|
2015-04-11 07:51:30 +00:00
|
|
|
// Region Sounds
|
2015-04-12 03:48:23 +00:00
|
|
|
mRegions.addColumn (new NestedParentColumn<ESM::Region> (Columns::ColumnId_RegionSounds));
|
|
|
|
index = mRegions.getColumns()-1;
|
|
|
|
mRegions.addAdapter (std::make_pair(&mRegions.getColumn(index), new RegionSoundListAdapter ()));
|
|
|
|
mRegions.getNestableColumn(index)->addColumn(
|
2015-06-02 21:02:53 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_Sound));
|
2015-04-12 03:48:23 +00:00
|
|
|
mRegions.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_SoundChance, ColumnBase::Display_Integer));
|
2013-04-07 14:32:06 +00:00
|
|
|
|
2013-04-07 18:26:39 +00:00
|
|
|
mBirthsigns.addColumn (new StringIdColumn<ESM::BirthSign>);
|
|
|
|
mBirthsigns.addColumn (new RecordStateColumn<ESM::BirthSign>);
|
2013-04-09 12:27:32 +00:00
|
|
|
mBirthsigns.addColumn (new FixedRecordTypeColumn<ESM::BirthSign> (UniversalId::Type_Birthsign));
|
2013-04-07 18:26:39 +00:00
|
|
|
mBirthsigns.addColumn (new NameColumn<ESM::BirthSign>);
|
2013-04-07 18:46:04 +00:00
|
|
|
mBirthsigns.addColumn (new TextureColumn<ESM::BirthSign>);
|
2013-04-07 18:26:39 +00:00
|
|
|
mBirthsigns.addColumn (new DescriptionColumn<ESM::BirthSign>);
|
2015-04-11 09:17:17 +00:00
|
|
|
// Birthsign spells
|
2015-04-17 03:45:45 +00:00
|
|
|
mBirthsigns.addColumn (new NestedParentColumn<ESM::BirthSign> (Columns::ColumnId_PowerList));
|
2015-04-12 03:48:23 +00:00
|
|
|
index = mBirthsigns.getColumns()-1;
|
|
|
|
mBirthsigns.addAdapter (std::make_pair(&mBirthsigns.getColumn(index),
|
|
|
|
new SpellListAdapter<ESM::BirthSign> ()));
|
|
|
|
mBirthsigns.getNestableColumn(index)->addColumn(
|
2015-06-02 21:02:53 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_Spell));
|
2013-04-07 18:26:39 +00:00
|
|
|
|
2013-04-09 09:40:36 +00:00
|
|
|
mSpells.addColumn (new StringIdColumn<ESM::Spell>);
|
|
|
|
mSpells.addColumn (new RecordStateColumn<ESM::Spell>);
|
2013-04-09 12:27:32 +00:00
|
|
|
mSpells.addColumn (new FixedRecordTypeColumn<ESM::Spell> (UniversalId::Type_Spell));
|
2013-04-09 09:40:36 +00:00
|
|
|
mSpells.addColumn (new NameColumn<ESM::Spell>);
|
2015-06-24 11:05:59 +00:00
|
|
|
mSpells.addColumn (new SpellTypeColumn<ESM::Spell>); // ColumnId_SpellType
|
2013-04-09 09:53:47 +00:00
|
|
|
mSpells.addColumn (new CostColumn<ESM::Spell>);
|
2013-08-07 07:36:05 +00:00
|
|
|
mSpells.addColumn (new FlagColumn<ESM::Spell> (Columns::ColumnId_AutoCalc, 0x1));
|
|
|
|
mSpells.addColumn (new FlagColumn<ESM::Spell> (Columns::ColumnId_StarterSpell, 0x2));
|
|
|
|
mSpells.addColumn (new FlagColumn<ESM::Spell> (Columns::ColumnId_AlwaysSucceeds, 0x4));
|
2015-04-11 11:43:25 +00:00
|
|
|
// Spell effects
|
2015-04-12 03:48:23 +00:00
|
|
|
mSpells.addColumn (new NestedParentColumn<ESM::Spell> (Columns::ColumnId_EffectList));
|
|
|
|
index = mSpells.getColumns()-1;
|
|
|
|
mSpells.addAdapter (std::make_pair(&mSpells.getColumn(index), new EffectsListAdapter<ESM::Spell> ()));
|
|
|
|
mSpells.getNestableColumn(index)->addColumn(
|
2015-04-19 03:31:16 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId));
|
2015-04-12 03:48:23 +00:00
|
|
|
mSpells.getNestableColumn(index)->addColumn(
|
2015-04-17 21:15:40 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact));
|
2015-04-12 03:48:23 +00:00
|
|
|
mSpells.getNestableColumn(index)->addColumn(
|
2015-04-19 03:31:16 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute));
|
2015-04-12 03:48:23 +00:00
|
|
|
mSpells.getNestableColumn(index)->addColumn(
|
2015-04-17 22:09:14 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange));
|
2015-04-12 03:48:23 +00:00
|
|
|
mSpells.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String));
|
|
|
|
mSpells.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light
|
|
|
|
mSpells.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_MinRange, ColumnBase::Display_Integer)); // reuse from sound
|
|
|
|
mSpells.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_MaxRange, ColumnBase::Display_Integer)); // reuse from sound
|
2013-04-09 09:40:36 +00:00
|
|
|
|
2013-10-20 15:13:31 +00:00
|
|
|
mTopics.addColumn (new StringIdColumn<ESM::Dialogue>);
|
|
|
|
mTopics.addColumn (new RecordStateColumn<ESM::Dialogue>);
|
2014-01-23 14:13:37 +00:00
|
|
|
mTopics.addColumn (new FixedRecordTypeColumn<ESM::Dialogue> (UniversalId::Type_Topic));
|
2013-10-20 15:26:09 +00:00
|
|
|
mTopics.addColumn (new DialogueTypeColumn<ESM::Dialogue>);
|
2013-10-20 15:13:31 +00:00
|
|
|
|
|
|
|
mJournals.addColumn (new StringIdColumn<ESM::Dialogue>);
|
|
|
|
mJournals.addColumn (new RecordStateColumn<ESM::Dialogue>);
|
2014-01-23 14:13:37 +00:00
|
|
|
mJournals.addColumn (new FixedRecordTypeColumn<ESM::Dialogue> (UniversalId::Type_Journal));
|
2013-10-21 11:39:13 +00:00
|
|
|
mJournals.addColumn (new DialogueTypeColumn<ESM::Dialogue> (true));
|
2013-10-20 15:13:31 +00:00
|
|
|
|
2013-11-14 12:14:37 +00:00
|
|
|
mTopicInfos.addColumn (new StringIdColumn<Info> (true));
|
2013-11-01 16:43:45 +00:00
|
|
|
mTopicInfos.addColumn (new RecordStateColumn<Info>);
|
2014-01-27 11:23:03 +00:00
|
|
|
mTopicInfos.addColumn (new FixedRecordTypeColumn<Info> (UniversalId::Type_TopicInfo));
|
2013-11-03 09:48:50 +00:00
|
|
|
mTopicInfos.addColumn (new TopicColumn<Info> (false));
|
2013-11-05 10:41:48 +00:00
|
|
|
mTopicInfos.addColumn (new ActorColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new RaceColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new ClassColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new FactionColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new CellColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new DispositionColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new RankColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new GenderColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new PcFactionColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new PcRankColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new SoundFileColumn<Info>);
|
|
|
|
mTopicInfos.addColumn (new ResponseColumn<Info>);
|
2015-04-19 03:31:16 +00:00
|
|
|
// Result script
|
|
|
|
mTopicInfos.addColumn (new NestedParentColumn<Info> (Columns::ColumnId_InfoList,
|
|
|
|
ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List));
|
|
|
|
index = mTopicInfos.getColumns()-1;
|
|
|
|
mTopicInfos.addAdapter (std::make_pair(&mTopicInfos.getColumn(index), new InfoListAdapter ()));
|
|
|
|
mTopicInfos.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_ScriptText, ColumnBase::Display_ScriptLines));
|
2015-05-09 11:21:16 +00:00
|
|
|
// Special conditions
|
|
|
|
mTopicInfos.addColumn (new NestedParentColumn<Info> (Columns::ColumnId_InfoCondition));
|
|
|
|
index = mTopicInfos.getColumns()-1;
|
|
|
|
mTopicInfos.addAdapter (std::make_pair(&mTopicInfos.getColumn(index), new InfoConditionAdapter ()));
|
|
|
|
mTopicInfos.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_InfoCondFunc, ColumnBase::Display_InfoCondFunc));
|
|
|
|
// FIXME: don't have dynamic value enum delegate, use Display_String for now
|
|
|
|
mTopicInfos.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_InfoCondVar, ColumnBase::Display_String));
|
|
|
|
mTopicInfos.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_InfoCondComp, ColumnBase::Display_InfoCondComp));
|
|
|
|
mTopicInfos.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_Value, ColumnBase::Display_Var));
|
2013-11-01 16:43:45 +00:00
|
|
|
|
2013-11-14 12:14:37 +00:00
|
|
|
mJournalInfos.addColumn (new StringIdColumn<Info> (true));
|
2013-11-01 16:43:45 +00:00
|
|
|
mJournalInfos.addColumn (new RecordStateColumn<Info>);
|
2014-09-05 22:00:48 +00:00
|
|
|
mJournalInfos.addColumn (new FixedRecordTypeColumn<Info> (UniversalId::Type_JournalInfo));
|
2013-11-03 09:48:50 +00:00
|
|
|
mJournalInfos.addColumn (new TopicColumn<Info> (true));
|
2013-11-01 16:43:45 +00:00
|
|
|
mJournalInfos.addColumn (new QuestStatusTypeColumn<Info>);
|
|
|
|
mJournalInfos.addColumn (new QuestIndexColumn<Info>);
|
|
|
|
mJournalInfos.addColumn (new QuestDescriptionColumn<Info>);
|
2013-10-29 12:18:22 +00:00
|
|
|
|
2013-04-14 15:04:55 +00:00
|
|
|
mCells.addColumn (new StringIdColumn<Cell>);
|
|
|
|
mCells.addColumn (new RecordStateColumn<Cell>);
|
|
|
|
mCells.addColumn (new FixedRecordTypeColumn<Cell> (UniversalId::Type_Cell));
|
|
|
|
mCells.addColumn (new NameColumn<Cell>);
|
2013-08-07 07:36:05 +00:00
|
|
|
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_SleepForbidden, ESM::Cell::NoSleep));
|
2015-05-26 03:35:10 +00:00
|
|
|
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorWater, ESM::Cell::HasWater,
|
|
|
|
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
|
|
|
|
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorSky, ESM::Cell::QuasiEx,
|
|
|
|
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
|
2013-04-14 17:34:55 +00:00
|
|
|
mCells.addColumn (new RegionColumn<Cell>);
|
2014-09-16 10:30:17 +00:00
|
|
|
mCells.addColumn (new RefNumCounterColumn<Cell>);
|
2015-05-19 12:01:40 +00:00
|
|
|
// Misc Cell data
|
|
|
|
mCells.addColumn (new NestedParentColumn<Cell> (Columns::ColumnId_Cell,
|
|
|
|
ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List));
|
|
|
|
index = mCells.getColumns()-1;
|
|
|
|
mCells.addAdapter (std::make_pair(&mCells.getColumn(index), new CellListAdapter ()));
|
|
|
|
mCells.getNestableColumn(index)->addColumn(
|
2015-05-26 03:35:10 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_Interior, ColumnBase::Display_Boolean,
|
|
|
|
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
|
2015-05-19 12:01:40 +00:00
|
|
|
mCells.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_Ambient, ColumnBase::Display_Integer));
|
|
|
|
mCells.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_Sunlight, ColumnBase::Display_Integer));
|
|
|
|
mCells.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_Fog, ColumnBase::Display_Integer));
|
|
|
|
mCells.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_FogDensity, ColumnBase::Display_Float));
|
|
|
|
mCells.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_WaterLevel, ColumnBase::Display_Float));
|
|
|
|
mCells.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_MapColor, ColumnBase::Display_Integer));
|
2013-04-14 15:04:55 +00:00
|
|
|
|
2014-06-30 18:40:34 +00:00
|
|
|
mEnchantments.addColumn (new StringIdColumn<ESM::Enchantment>);
|
|
|
|
mEnchantments.addColumn (new RecordStateColumn<ESM::Enchantment>);
|
|
|
|
mEnchantments.addColumn (new FixedRecordTypeColumn<ESM::Enchantment> (UniversalId::Type_Enchantment));
|
2014-07-01 07:42:56 +00:00
|
|
|
mEnchantments.addColumn (new EnchantmentTypeColumn<ESM::Enchantment>);
|
2014-06-30 18:40:34 +00:00
|
|
|
mEnchantments.addColumn (new CostColumn<ESM::Enchantment>);
|
2014-07-01 07:50:43 +00:00
|
|
|
mEnchantments.addColumn (new ChargesColumn2<ESM::Enchantment>);
|
|
|
|
mEnchantments.addColumn (new AutoCalcColumn<ESM::Enchantment>);
|
2015-04-11 11:43:25 +00:00
|
|
|
// Enchantment effects
|
2015-04-12 03:48:23 +00:00
|
|
|
mEnchantments.addColumn (new NestedParentColumn<ESM::Enchantment> (Columns::ColumnId_EffectList));
|
|
|
|
index = mEnchantments.getColumns()-1;
|
|
|
|
mEnchantments.addAdapter (std::make_pair(&mEnchantments.getColumn(index),
|
|
|
|
new EffectsListAdapter<ESM::Enchantment> ()));
|
|
|
|
mEnchantments.getNestableColumn(index)->addColumn(
|
2015-04-17 22:09:14 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId));
|
2015-04-12 03:48:23 +00:00
|
|
|
mEnchantments.getNestableColumn(index)->addColumn(
|
2015-04-17 21:15:40 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact));
|
2015-04-12 03:48:23 +00:00
|
|
|
mEnchantments.getNestableColumn(index)->addColumn(
|
2015-04-19 03:31:16 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute));
|
2015-04-12 03:48:23 +00:00
|
|
|
mEnchantments.getNestableColumn(index)->addColumn(
|
2015-04-17 22:09:14 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange));
|
2015-04-12 03:48:23 +00:00
|
|
|
mEnchantments.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String));
|
|
|
|
mEnchantments.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light
|
|
|
|
mEnchantments.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_MinRange, ColumnBase::Display_Integer)); // reuse from sound
|
|
|
|
mEnchantments.getNestableColumn(index)->addColumn(
|
|
|
|
new NestedChildColumn (Columns::ColumnId_MaxRange, ColumnBase::Display_Integer)); // reuse from sound
|
2014-06-30 18:40:34 +00:00
|
|
|
|
2014-07-01 10:37:22 +00:00
|
|
|
mBodyParts.addColumn (new StringIdColumn<ESM::BodyPart>);
|
|
|
|
mBodyParts.addColumn (new RecordStateColumn<ESM::BodyPart>);
|
|
|
|
mBodyParts.addColumn (new FixedRecordTypeColumn<ESM::BodyPart> (UniversalId::Type_BodyPart));
|
2014-07-01 12:28:12 +00:00
|
|
|
mBodyParts.addColumn (new BodyPartTypeColumn<ESM::BodyPart>);
|
2014-07-01 10:37:22 +00:00
|
|
|
mBodyParts.addColumn (new VampireColumn<ESM::BodyPart>);
|
|
|
|
mBodyParts.addColumn (new FlagColumn<ESM::BodyPart> (Columns::ColumnId_Female, ESM::BodyPart::BPF_Female));
|
2015-05-26 03:35:10 +00:00
|
|
|
mBodyParts.addColumn (new FlagColumn<ESM::BodyPart> (Columns::ColumnId_Playable,
|
|
|
|
ESM::BodyPart::BPF_NotPlayable, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true));
|
2014-07-01 12:28:12 +00:00
|
|
|
mBodyParts.addColumn (new MeshTypeColumn<ESM::BodyPart>);
|
2014-07-01 10:37:22 +00:00
|
|
|
mBodyParts.addColumn (new ModelColumn<ESM::BodyPart>);
|
|
|
|
mBodyParts.addColumn (new RaceColumn<ESM::BodyPart>);
|
|
|
|
|
2014-09-23 11:21:54 +00:00
|
|
|
mSoundGens.addColumn (new StringIdColumn<ESM::SoundGenerator>);
|
|
|
|
mSoundGens.addColumn (new RecordStateColumn<ESM::SoundGenerator>);
|
|
|
|
mSoundGens.addColumn (new FixedRecordTypeColumn<ESM::SoundGenerator> (UniversalId::Type_SoundGen));
|
2014-09-25 09:40:45 +00:00
|
|
|
mSoundGens.addColumn (new CreatureColumn<ESM::SoundGenerator>);
|
|
|
|
mSoundGens.addColumn (new SoundColumn<ESM::SoundGenerator>);
|
|
|
|
mSoundGens.addColumn (new SoundGeneratorTypeColumn<ESM::SoundGenerator>);
|
2014-09-23 11:21:54 +00:00
|
|
|
|
2014-09-26 11:05:51 +00:00
|
|
|
mMagicEffects.addColumn (new StringIdColumn<ESM::MagicEffect>);
|
|
|
|
mMagicEffects.addColumn (new RecordStateColumn<ESM::MagicEffect>);
|
|
|
|
mMagicEffects.addColumn (new FixedRecordTypeColumn<ESM::MagicEffect> (UniversalId::Type_MagicEffect));
|
2014-09-30 10:33:48 +00:00
|
|
|
mMagicEffects.addColumn (new SchoolColumn<ESM::MagicEffect>);
|
|
|
|
mMagicEffects.addColumn (new BaseCostColumn<ESM::MagicEffect>);
|
|
|
|
mMagicEffects.addColumn (new EffectTextureColumn<ESM::MagicEffect> (Columns::ColumnId_Icon));
|
|
|
|
mMagicEffects.addColumn (new EffectTextureColumn<ESM::MagicEffect> (Columns::ColumnId_Particle));
|
|
|
|
mMagicEffects.addColumn (new EffectObjectColumn<ESM::MagicEffect> (Columns::ColumnId_CastingObject));
|
|
|
|
mMagicEffects.addColumn (new EffectObjectColumn<ESM::MagicEffect> (Columns::ColumnId_HitObject));
|
|
|
|
mMagicEffects.addColumn (new EffectObjectColumn<ESM::MagicEffect> (Columns::ColumnId_AreaObject));
|
|
|
|
mMagicEffects.addColumn (new EffectObjectColumn<ESM::MagicEffect> (Columns::ColumnId_BoltObject));
|
|
|
|
mMagicEffects.addColumn (new EffectSoundColumn<ESM::MagicEffect> (Columns::ColumnId_CastingSound));
|
|
|
|
mMagicEffects.addColumn (new EffectSoundColumn<ESM::MagicEffect> (Columns::ColumnId_HitSound));
|
|
|
|
mMagicEffects.addColumn (new EffectSoundColumn<ESM::MagicEffect> (Columns::ColumnId_AreaSound));
|
|
|
|
mMagicEffects.addColumn (new EffectSoundColumn<ESM::MagicEffect> (Columns::ColumnId_BoltSound));
|
2014-09-27 10:51:46 +00:00
|
|
|
mMagicEffects.addColumn (new FlagColumn<ESM::MagicEffect> (
|
|
|
|
Columns::ColumnId_AllowSpellmaking, ESM::MagicEffect::AllowSpellmaking));
|
|
|
|
mMagicEffects.addColumn (new FlagColumn<ESM::MagicEffect> (
|
|
|
|
Columns::ColumnId_AllowEnchanting, ESM::MagicEffect::AllowEnchanting));
|
|
|
|
mMagicEffects.addColumn (new FlagColumn<ESM::MagicEffect> (
|
|
|
|
Columns::ColumnId_NegativeLight, ESM::MagicEffect::NegativeLight));
|
|
|
|
mMagicEffects.addColumn (new DescriptionColumn<ESM::MagicEffect>);
|
|
|
|
|
2014-10-02 10:30:15 +00:00
|
|
|
mPathgrids.addColumn (new StringIdColumn<Pathgrid>);
|
|
|
|
mPathgrids.addColumn (new RecordStateColumn<Pathgrid>);
|
|
|
|
mPathgrids.addColumn (new FixedRecordTypeColumn<Pathgrid> (UniversalId::Type_Pathgrid));
|
|
|
|
|
2015-04-09 09:29:03 +00:00
|
|
|
// new object deleted in dtor of Collection<T,A>
|
2015-04-12 03:48:23 +00:00
|
|
|
mPathgrids.addColumn (new NestedParentColumn<Pathgrid> (Columns::ColumnId_PathgridPoints));
|
|
|
|
index = mPathgrids.getColumns()-1;
|
|
|
|
// new object deleted in dtor of NestedCollection<T,A>
|
|
|
|
mPathgrids.addAdapter (std::make_pair(&mPathgrids.getColumn(index), new PathgridPointListAdapter ()));
|
2015-04-09 09:29:03 +00:00
|
|
|
// new objects deleted in dtor of NestableColumn
|
2015-04-09 21:31:01 +00:00
|
|
|
// WARNING: The order of the columns below are assumed in PathgridPointListAdapter
|
2015-04-12 03:48:23 +00:00
|
|
|
mPathgrids.getNestableColumn(index)->addColumn(
|
2015-05-26 03:35:10 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_PathgridIndex, ColumnBase::Display_Integer,
|
|
|
|
ColumnBase::Flag_Dialogue, false));
|
2015-04-12 03:48:23 +00:00
|
|
|
mPathgrids.getNestableColumn(index)->addColumn(
|
2015-04-11 22:52:09 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_PathgridPosX, ColumnBase::Display_Integer));
|
2015-04-12 03:48:23 +00:00
|
|
|
mPathgrids.getNestableColumn(index)->addColumn(
|
2015-04-11 22:52:09 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_PathgridPosY, ColumnBase::Display_Integer));
|
2015-04-12 03:48:23 +00:00
|
|
|
mPathgrids.getNestableColumn(index)->addColumn(
|
2015-04-11 22:52:09 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_PathgridPosZ, ColumnBase::Display_Integer));
|
2015-04-11 11:43:25 +00:00
|
|
|
|
2015-04-12 03:48:23 +00:00
|
|
|
mPathgrids.addColumn (new NestedParentColumn<Pathgrid> (Columns::ColumnId_PathgridEdges));
|
|
|
|
index = mPathgrids.getColumns()-1;
|
|
|
|
mPathgrids.addAdapter (std::make_pair(&mPathgrids.getColumn(index), new PathgridEdgeListAdapter ()));
|
|
|
|
mPathgrids.getNestableColumn(index)->addColumn(
|
2015-05-26 03:35:10 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer,
|
|
|
|
ColumnBase::Flag_Dialogue, false));
|
2015-04-12 03:48:23 +00:00
|
|
|
mPathgrids.getNestableColumn(index)->addColumn(
|
2015-04-11 22:52:09 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_PathgridEdge0, ColumnBase::Display_Integer));
|
2015-04-12 03:48:23 +00:00
|
|
|
mPathgrids.getNestableColumn(index)->addColumn(
|
2015-04-11 22:52:09 +00:00
|
|
|
new NestedChildColumn (Columns::ColumnId_PathgridEdge1, ColumnBase::Display_Integer));
|
2015-04-09 09:29:03 +00:00
|
|
|
|
2015-03-03 12:52:36 +00:00
|
|
|
mStartScripts.addColumn (new StringIdColumn<ESM::StartScript>);
|
|
|
|
mStartScripts.addColumn (new RecordStateColumn<ESM::StartScript>);
|
|
|
|
mStartScripts.addColumn (new FixedRecordTypeColumn<ESM::StartScript> (UniversalId::Type_StartScript));
|
|
|
|
|
2013-07-06 16:34:14 +00:00
|
|
|
mRefs.addColumn (new StringIdColumn<CellRef> (true));
|
2013-07-06 15:03:18 +00:00
|
|
|
mRefs.addColumn (new RecordStateColumn<CellRef>);
|
2014-01-23 08:40:32 +00:00
|
|
|
mRefs.addColumn (new FixedRecordTypeColumn<CellRef> (UniversalId::Type_Reference));
|
2015-01-05 14:04:11 +00:00
|
|
|
mRefs.addColumn (new CellColumn<CellRef> (true));
|
2015-01-05 14:20:47 +00:00
|
|
|
mRefs.addColumn (new OriginalCellColumn<CellRef>);
|
2013-07-06 15:41:06 +00:00
|
|
|
mRefs.addColumn (new IdColumn<CellRef>);
|
2013-09-22 08:43:09 +00:00
|
|
|
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mPos, 0, false));
|
|
|
|
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mPos, 1, false));
|
|
|
|
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mPos, 2, false));
|
|
|
|
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mPos, 0, false));
|
|
|
|
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mPos, 1, false));
|
|
|
|
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mPos, 2, false));
|
2013-07-06 15:41:06 +00:00
|
|
|
mRefs.addColumn (new ScaleColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new OwnerColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new SoulColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new FactionColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new FactionIndexColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new ChargesColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new EnchantmentChargesColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new GoldValueColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new TeleportColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new TeleportCellColumn<CellRef>);
|
2013-09-22 08:43:09 +00:00
|
|
|
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mDoorDest, 0, true));
|
|
|
|
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mDoorDest, 1, true));
|
|
|
|
mRefs.addColumn (new PosColumn<CellRef> (&CellRef::mDoorDest, 2, true));
|
|
|
|
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mDoorDest, 0, true));
|
|
|
|
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mDoorDest, 1, true));
|
|
|
|
mRefs.addColumn (new RotColumn<CellRef> (&CellRef::mDoorDest, 2, true));
|
2013-07-06 15:41:06 +00:00
|
|
|
mRefs.addColumn (new LockLevelColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new KeyColumn<CellRef>);
|
|
|
|
mRefs.addColumn (new TrapColumn<CellRef>);
|
2014-08-30 08:13:34 +00:00
|
|
|
mRefs.addColumn (new OwnerGlobalColumn<CellRef>);
|
2014-09-16 10:48:10 +00:00
|
|
|
mRefs.addColumn (new RefNumColumn<CellRef>);
|
2013-07-06 15:03:18 +00:00
|
|
|
|
2014-08-10 19:03:45 +00:00
|
|
|
mFilters.addColumn (new StringIdColumn<ESM::Filter>);
|
|
|
|
mFilters.addColumn (new RecordStateColumn<ESM::Filter>);
|
|
|
|
mFilters.addColumn (new FixedRecordTypeColumn<ESM::Filter> (UniversalId::Type_Filter));
|
|
|
|
mFilters.addColumn (new FilterColumn<ESM::Filter>);
|
|
|
|
mFilters.addColumn (new DescriptionColumn<ESM::Filter>);
|
2013-07-22 19:18:47 +00:00
|
|
|
|
2014-08-04 11:36:01 +00:00
|
|
|
mDebugProfiles.addColumn (new StringIdColumn<ESM::DebugProfile>);
|
|
|
|
mDebugProfiles.addColumn (new RecordStateColumn<ESM::DebugProfile>);
|
|
|
|
mDebugProfiles.addColumn (new FixedRecordTypeColumn<ESM::DebugProfile> (UniversalId::Type_DebugProfile));
|
2014-08-15 11:22:20 +00:00
|
|
|
mDebugProfiles.addColumn (new FlagColumn2<ESM::DebugProfile> (
|
|
|
|
Columns::ColumnId_DefaultProfile, ESM::DebugProfile::Flag_Default));
|
|
|
|
mDebugProfiles.addColumn (new FlagColumn2<ESM::DebugProfile> (
|
|
|
|
Columns::ColumnId_BypassNewGame, ESM::DebugProfile::Flag_BypassNewGame));
|
|
|
|
mDebugProfiles.addColumn (new FlagColumn2<ESM::DebugProfile> (
|
|
|
|
Columns::ColumnId_GlobalProfile, ESM::DebugProfile::Flag_Global));
|
2014-08-04 11:36:01 +00:00
|
|
|
mDebugProfiles.addColumn (new DescriptionColumn<ESM::DebugProfile>);
|
2014-08-24 11:15:18 +00:00
|
|
|
mDebugProfiles.addColumn (new ScriptColumn<ESM::DebugProfile> (
|
|
|
|
ScriptColumn<ESM::DebugProfile>::Type_Lines));
|
2013-07-22 19:18:47 +00:00
|
|
|
|
2014-06-06 18:47:31 +00:00
|
|
|
addModel (new IdTable (&mGlobals), UniversalId::Type_Global);
|
|
|
|
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmst);
|
|
|
|
addModel (new IdTable (&mSkills), UniversalId::Type_Skill);
|
|
|
|
addModel (new IdTable (&mClasses), UniversalId::Type_Class);
|
2015-04-11 07:51:30 +00:00
|
|
|
addModel (new IdTree (&mFactions, &mFactions), UniversalId::Type_Faction);
|
2015-04-11 09:05:03 +00:00
|
|
|
addModel (new IdTree (&mRaces, &mRaces), UniversalId::Type_Race);
|
2014-06-06 18:47:31 +00:00
|
|
|
addModel (new IdTable (&mSounds), UniversalId::Type_Sound);
|
|
|
|
addModel (new IdTable (&mScripts), UniversalId::Type_Script);
|
2015-04-11 05:55:26 +00:00
|
|
|
addModel (new IdTree (&mRegions, &mRegions), UniversalId::Type_Region);
|
2015-04-11 09:17:17 +00:00
|
|
|
addModel (new IdTree (&mBirthsigns, &mBirthsigns), UniversalId::Type_Birthsign);
|
2015-04-11 11:43:25 +00:00
|
|
|
addModel (new IdTree (&mSpells, &mSpells), UniversalId::Type_Spell);
|
2014-06-06 18:47:31 +00:00
|
|
|
addModel (new IdTable (&mTopics), UniversalId::Type_Topic);
|
|
|
|
addModel (new IdTable (&mJournals), UniversalId::Type_Journal);
|
2015-04-19 03:31:16 +00:00
|
|
|
addModel (new IdTree (&mTopicInfos, &mTopicInfos, IdTable::Feature_ReorderWithinTopic),
|
|
|
|
UniversalId::Type_TopicInfo);
|
2014-06-06 18:47:31 +00:00
|
|
|
addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo);
|
2015-05-19 12:01:40 +00:00
|
|
|
addModel (new IdTree (&mCells, &mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell);
|
2015-04-11 11:43:25 +00:00
|
|
|
addModel (new IdTree (&mEnchantments, &mEnchantments), UniversalId::Type_Enchantment);
|
2014-07-01 10:37:22 +00:00
|
|
|
addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart);
|
2014-09-23 11:21:54 +00:00
|
|
|
addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen);
|
2014-09-26 11:05:51 +00:00
|
|
|
addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect);
|
2015-04-09 09:29:03 +00:00
|
|
|
addModel (new IdTree (&mPathgrids, &mPathgrids), UniversalId::Type_Pathgrid);
|
2015-03-03 12:52:36 +00:00
|
|
|
addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript);
|
2015-04-09 09:11:19 +00:00
|
|
|
addModel (new IdTree (&mReferenceables, &mReferenceables, IdTable::Feature_Preview),
|
2014-06-06 18:47:31 +00:00
|
|
|
UniversalId::Type_Referenceable);
|
|
|
|
addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference);
|
|
|
|
addModel (new IdTable (&mFilters), UniversalId::Type_Filter);
|
2014-08-04 11:36:01 +00:00
|
|
|
addModel (new IdTable (&mDebugProfiles), UniversalId::Type_DebugProfile);
|
2014-08-17 12:21:23 +00:00
|
|
|
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Meshes)),
|
2014-07-05 13:50:47 +00:00
|
|
|
UniversalId::Type_Mesh);
|
2014-08-17 12:21:23 +00:00
|
|
|
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Icons)),
|
2014-07-05 13:50:47 +00:00
|
|
|
UniversalId::Type_Icon);
|
2014-08-17 12:21:23 +00:00
|
|
|
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Musics)),
|
2014-07-05 13:50:47 +00:00
|
|
|
UniversalId::Type_Music);
|
2014-08-17 12:21:23 +00:00
|
|
|
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_SoundsRes)),
|
2014-07-05 13:50:47 +00:00
|
|
|
UniversalId::Type_SoundRes);
|
2014-08-17 12:21:23 +00:00
|
|
|
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Textures)),
|
2014-07-05 13:50:47 +00:00
|
|
|
UniversalId::Type_Texture);
|
2014-08-17 12:21:23 +00:00
|
|
|
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Videos)),
|
2014-07-05 13:50:47 +00:00
|
|
|
UniversalId::Type_Video);
|
2015-04-27 22:07:01 +00:00
|
|
|
|
2015-06-24 11:05:59 +00:00
|
|
|
// for autocalc updates when gmst/race/class/skils tables change
|
|
|
|
CSMWorld::IdTable *gmsts =
|
|
|
|
static_cast<CSMWorld::IdTable*>(getTableModel(UniversalId::Type_Gmst));
|
|
|
|
CSMWorld::IdTable *skills =
|
|
|
|
static_cast<CSMWorld::IdTable*>(getTableModel(UniversalId::Type_Skill));
|
|
|
|
CSMWorld::IdTable *classes =
|
|
|
|
static_cast<CSMWorld::IdTable*>(getTableModel(UniversalId::Type_Class));
|
|
|
|
CSMWorld::IdTree *races =
|
|
|
|
static_cast<CSMWorld::IdTree*>(getTableModel(UniversalId::Type_Race));
|
|
|
|
CSMWorld::IdTree *objects =
|
|
|
|
static_cast<CSMWorld::IdTree*>(getTableModel(UniversalId::Type_Referenceable));
|
|
|
|
|
|
|
|
connect (gmsts, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
|
|
|
this, SLOT (gmstDataChanged (const QModelIndex&, const QModelIndex&)));
|
|
|
|
connect (skills, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
|
|
|
this, SLOT (skillDataChanged (const QModelIndex&, const QModelIndex&)));
|
|
|
|
connect (classes, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
|
|
|
this, SLOT (classDataChanged (const QModelIndex&, const QModelIndex&)));
|
|
|
|
connect (races, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
|
|
|
this, SLOT (raceDataChanged (const QModelIndex&, const QModelIndex&)));
|
|
|
|
connect (objects, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
|
|
|
this, SLOT (npcDataChanged (const QModelIndex&, const QModelIndex&)));
|
|
|
|
connect (this, SIGNAL (updateNpcAutocalc (int, const std::string&)),
|
|
|
|
objects, SLOT (updateNpcAutocalc (int, const std::string&)));
|
|
|
|
connect (this, SIGNAL (cacheNpcStats (const std::string&, NpcStats*)),
|
|
|
|
this, SLOT (cacheNpcStatsEvent (const std::string&, NpcStats*)));
|
|
|
|
|
2015-04-27 22:07:01 +00:00
|
|
|
mRefLoadCache.clear(); // clear here rather than startLoading() and continueLoading() for multiple content files
|
2012-11-26 11:29:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::Data::~Data()
|
|
|
|
{
|
2015-06-24 11:05:59 +00:00
|
|
|
clearNpcStatsCache();
|
|
|
|
|
2013-03-21 09:07:25 +00:00
|
|
|
for (std::vector<QAbstractItemModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
|
2012-12-30 13:01:52 +00:00
|
|
|
delete *iter;
|
2014-05-03 13:05:02 +00:00
|
|
|
|
|
|
|
delete mReader;
|
2012-11-26 11:29:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const
|
|
|
|
{
|
|
|
|
return mGlobals;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals()
|
|
|
|
{
|
|
|
|
return mGlobals;
|
|
|
|
}
|
|
|
|
|
2013-02-17 19:03:39 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::GameSetting>& CSMWorld::Data::getGmsts() const
|
|
|
|
{
|
|
|
|
return mGmsts;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::GameSetting>& CSMWorld::Data::getGmsts()
|
|
|
|
{
|
|
|
|
return mGmsts;
|
|
|
|
}
|
|
|
|
|
2013-03-24 14:10:03 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Skill>& CSMWorld::Data::getSkills() const
|
|
|
|
{
|
|
|
|
return mSkills;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Skill>& CSMWorld::Data::getSkills()
|
|
|
|
{
|
|
|
|
return mSkills;
|
|
|
|
}
|
|
|
|
|
2013-04-04 08:10:26 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Class>& CSMWorld::Data::getClasses() const
|
|
|
|
{
|
|
|
|
return mClasses;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Class>& CSMWorld::Data::getClasses()
|
|
|
|
{
|
|
|
|
return mClasses;
|
|
|
|
}
|
|
|
|
|
2013-04-02 10:00:45 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Faction>& CSMWorld::Data::getFactions() const
|
|
|
|
{
|
|
|
|
return mFactions;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Faction>& CSMWorld::Data::getFactions()
|
|
|
|
{
|
|
|
|
return mFactions;
|
|
|
|
}
|
|
|
|
|
2013-04-04 12:34:39 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Race>& CSMWorld::Data::getRaces() const
|
|
|
|
{
|
|
|
|
return mRaces;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Race>& CSMWorld::Data::getRaces()
|
|
|
|
{
|
|
|
|
return mRaces;
|
|
|
|
}
|
|
|
|
|
2013-04-06 19:21:10 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Sound>& CSMWorld::Data::getSounds() const
|
|
|
|
{
|
|
|
|
return mSounds;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Sound>& CSMWorld::Data::getSounds()
|
|
|
|
{
|
|
|
|
return mSounds;
|
|
|
|
}
|
|
|
|
|
2013-04-07 13:17:35 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Script>& CSMWorld::Data::getScripts() const
|
|
|
|
{
|
|
|
|
return mScripts;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Script>& CSMWorld::Data::getScripts()
|
|
|
|
{
|
|
|
|
return mScripts;
|
|
|
|
}
|
|
|
|
|
2013-04-07 14:32:06 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Region>& CSMWorld::Data::getRegions() const
|
|
|
|
{
|
|
|
|
return mRegions;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Region>& CSMWorld::Data::getRegions()
|
|
|
|
{
|
|
|
|
return mRegions;
|
|
|
|
}
|
|
|
|
|
2013-04-07 18:26:39 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::BirthSign>& CSMWorld::Data::getBirthsigns() const
|
|
|
|
{
|
|
|
|
return mBirthsigns;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::BirthSign>& CSMWorld::Data::getBirthsigns()
|
|
|
|
{
|
|
|
|
return mBirthsigns;
|
|
|
|
}
|
|
|
|
|
2013-04-09 09:40:36 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Spell>& CSMWorld::Data::getSpells() const
|
|
|
|
{
|
|
|
|
return mSpells;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Spell>& CSMWorld::Data::getSpells()
|
|
|
|
{
|
|
|
|
return mSpells;
|
|
|
|
}
|
|
|
|
|
2013-10-20 15:13:31 +00:00
|
|
|
|
2013-10-21 12:26:54 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Dialogue>& CSMWorld::Data::getTopics() const
|
2013-10-20 15:13:31 +00:00
|
|
|
{
|
|
|
|
return mTopics;
|
|
|
|
}
|
|
|
|
|
2013-10-21 12:26:54 +00:00
|
|
|
CSMWorld::IdCollection<ESM::Dialogue>& CSMWorld::Data::getTopics()
|
2013-10-20 15:13:31 +00:00
|
|
|
{
|
|
|
|
return mTopics;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CSMWorld::IdCollection<ESM::Dialogue>& CSMWorld::Data::getJournals() const
|
|
|
|
{
|
|
|
|
return mJournals;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Dialogue>& CSMWorld::Data::getJournals()
|
|
|
|
{
|
|
|
|
return mJournals;
|
|
|
|
}
|
|
|
|
|
2013-10-29 12:18:22 +00:00
|
|
|
const CSMWorld::InfoCollection& CSMWorld::Data::getTopicInfos() const
|
|
|
|
{
|
|
|
|
return mTopicInfos;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::InfoCollection& CSMWorld::Data::getTopicInfos()
|
|
|
|
{
|
|
|
|
return mTopicInfos;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CSMWorld::InfoCollection& CSMWorld::Data::getJournalInfos() const
|
|
|
|
{
|
|
|
|
return mJournalInfos;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::InfoCollection& CSMWorld::Data::getJournalInfos()
|
|
|
|
{
|
|
|
|
return mJournalInfos;
|
|
|
|
}
|
2013-10-20 15:13:31 +00:00
|
|
|
|
2013-04-14 15:04:55 +00:00
|
|
|
const CSMWorld::IdCollection<CSMWorld::Cell>& CSMWorld::Data::getCells() const
|
|
|
|
{
|
|
|
|
return mCells;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<CSMWorld::Cell>& CSMWorld::Data::getCells()
|
|
|
|
{
|
|
|
|
return mCells;
|
|
|
|
}
|
|
|
|
|
2013-05-07 09:23:18 +00:00
|
|
|
const CSMWorld::RefIdCollection& CSMWorld::Data::getReferenceables() const
|
|
|
|
{
|
|
|
|
return mReferenceables;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::RefIdCollection& CSMWorld::Data::getReferenceables()
|
|
|
|
{
|
|
|
|
return mReferenceables;
|
|
|
|
}
|
|
|
|
|
2013-07-30 10:53:03 +00:00
|
|
|
const CSMWorld::RefCollection& CSMWorld::Data::getReferences() const
|
|
|
|
{
|
|
|
|
return mRefs;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::RefCollection& CSMWorld::Data::getReferences()
|
|
|
|
{
|
|
|
|
return mRefs;
|
|
|
|
}
|
|
|
|
|
2014-08-10 19:03:45 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Filter>& CSMWorld::Data::getFilters() const
|
2013-08-24 15:40:00 +00:00
|
|
|
{
|
|
|
|
return mFilters;
|
|
|
|
}
|
|
|
|
|
2014-08-10 19:03:45 +00:00
|
|
|
CSMWorld::IdCollection<ESM::Filter>& CSMWorld::Data::getFilters()
|
2013-08-24 15:40:00 +00:00
|
|
|
{
|
|
|
|
return mFilters;
|
|
|
|
}
|
|
|
|
|
2014-06-30 18:40:34 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::Enchantment>& CSMWorld::Data::getEnchantments() const
|
|
|
|
{
|
|
|
|
return mEnchantments;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::Enchantment>& CSMWorld::Data::getEnchantments()
|
|
|
|
{
|
|
|
|
return mEnchantments;
|
|
|
|
}
|
|
|
|
|
2014-07-01 10:37:22 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::BodyPart>& CSMWorld::Data::getBodyParts() const
|
|
|
|
{
|
|
|
|
return mBodyParts;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::BodyPart>& CSMWorld::Data::getBodyParts()
|
|
|
|
{
|
|
|
|
return mBodyParts;
|
|
|
|
}
|
|
|
|
|
2014-08-04 11:36:01 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::DebugProfile>& CSMWorld::Data::getDebugProfiles() const
|
|
|
|
{
|
|
|
|
return mDebugProfiles;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::DebugProfile>& CSMWorld::Data::getDebugProfiles()
|
|
|
|
{
|
|
|
|
return mDebugProfiles;
|
|
|
|
}
|
|
|
|
|
2014-10-08 15:17:31 +00:00
|
|
|
const CSMWorld::IdCollection<CSMWorld::Land>& CSMWorld::Data::getLand() const
|
|
|
|
{
|
|
|
|
return mLand;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CSMWorld::IdCollection<CSMWorld::LandTexture>& CSMWorld::Data::getLandTextures() const
|
|
|
|
{
|
|
|
|
return mLandTextures;
|
|
|
|
}
|
|
|
|
|
2014-09-23 10:18:18 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::SoundGenerator>& CSMWorld::Data::getSoundGens() const
|
|
|
|
{
|
|
|
|
return mSoundGens;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::SoundGenerator>& CSMWorld::Data::getSoundGens()
|
|
|
|
{
|
|
|
|
return mSoundGens;
|
|
|
|
}
|
|
|
|
|
2014-09-26 11:05:51 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::MagicEffect>& CSMWorld::Data::getMagicEffects() const
|
|
|
|
{
|
|
|
|
return mMagicEffects;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::MagicEffect>& CSMWorld::Data::getMagicEffects()
|
|
|
|
{
|
|
|
|
return mMagicEffects;
|
|
|
|
}
|
|
|
|
|
2014-10-04 13:36:52 +00:00
|
|
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& CSMWorld::Data::getPathgrids() const
|
2014-10-02 10:30:15 +00:00
|
|
|
{
|
|
|
|
return mPathgrids;
|
|
|
|
}
|
|
|
|
|
2014-10-04 13:36:52 +00:00
|
|
|
CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& CSMWorld::Data::getPathgrids()
|
2014-10-02 10:30:15 +00:00
|
|
|
{
|
|
|
|
return mPathgrids;
|
|
|
|
}
|
|
|
|
|
2015-03-03 12:52:36 +00:00
|
|
|
const CSMWorld::IdCollection<ESM::StartScript>& CSMWorld::Data::getStartScripts() const
|
|
|
|
{
|
|
|
|
return mStartScripts;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::IdCollection<ESM::StartScript>& CSMWorld::Data::getStartScripts()
|
|
|
|
{
|
|
|
|
return mStartScripts;
|
|
|
|
}
|
|
|
|
|
2014-07-04 10:46:57 +00:00
|
|
|
const CSMWorld::Resources& CSMWorld::Data::getResources (const UniversalId& id) const
|
|
|
|
{
|
2014-08-17 12:21:23 +00:00
|
|
|
return mResourcesManager.get (id.getType());
|
2014-07-04 10:46:57 +00:00
|
|
|
}
|
|
|
|
|
2014-05-01 16:25:28 +00:00
|
|
|
QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id)
|
2012-11-26 11:29:22 +00:00
|
|
|
{
|
2013-03-21 09:07:25 +00:00
|
|
|
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
|
2012-11-26 11:29:22 +00:00
|
|
|
|
2012-12-30 13:01:52 +00:00
|
|
|
if (iter==mModelIndex.end())
|
2013-07-08 14:53:08 +00:00
|
|
|
{
|
|
|
|
// try creating missing (secondary) tables on the fly
|
|
|
|
//
|
|
|
|
// Note: We create these tables here so we don't have to deal with them during load/initial
|
|
|
|
// construction of the ESX data where no update signals are available.
|
|
|
|
if (id.getType()==UniversalId::Type_RegionMap)
|
|
|
|
{
|
|
|
|
RegionMap *table = 0;
|
2014-06-06 18:47:31 +00:00
|
|
|
addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap, false);
|
2013-07-08 14:53:08 +00:00
|
|
|
return table;
|
|
|
|
}
|
2012-11-26 11:29:22 +00:00
|
|
|
throw std::logic_error ("No table model available for " + id.toString());
|
2013-07-08 14:53:08 +00:00
|
|
|
}
|
2012-11-26 11:29:22 +00:00
|
|
|
|
|
|
|
return iter->second;
|
2012-12-03 12:56:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSMWorld::Data::merge()
|
|
|
|
{
|
|
|
|
mGlobals.merge();
|
2013-02-07 10:33:08 +00:00
|
|
|
}
|
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base, bool project)
|
2013-02-07 10:33:08 +00:00
|
|
|
{
|
2014-10-08 15:17:31 +00:00
|
|
|
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading
|
|
|
|
boost::shared_ptr<ESM::ESMReader> ptr(mReader);
|
|
|
|
mReaders.push_back(ptr);
|
2014-05-03 13:05:02 +00:00
|
|
|
mReader = 0;
|
2014-10-08 15:17:31 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
mDialogue = 0;
|
|
|
|
|
|
|
|
mReader = new ESM::ESMReader;
|
|
|
|
mReader->setEncoder (&mEncoder);
|
2014-11-18 10:47:46 +00:00
|
|
|
mReader->setIndex(mReaderIndex++);
|
2014-05-03 13:05:02 +00:00
|
|
|
mReader->open (path.string());
|
2013-02-17 18:26:01 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
mBase = base;
|
|
|
|
mProject = project;
|
2013-02-17 18:26:01 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
mAuthor = mReader->getAuthor();
|
|
|
|
mDescription = mReader->getDesc();
|
2013-02-07 11:52:01 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
return mReader->getRecordCount();
|
|
|
|
}
|
2013-10-31 11:16:45 +00:00
|
|
|
|
2014-12-07 17:57:47 +00:00
|
|
|
bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
2014-05-03 13:05:02 +00:00
|
|
|
{
|
|
|
|
if (!mReader)
|
|
|
|
throw std::logic_error ("can't continue loading, because no load has been started");
|
2013-09-24 15:17:01 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
if (!mReader->hasMoreRecs())
|
2013-02-07 11:52:01 +00:00
|
|
|
{
|
2014-11-30 17:04:18 +00:00
|
|
|
if (mBase)
|
|
|
|
{
|
|
|
|
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading.
|
|
|
|
// We don't store non-base reader, because everything going into modified will be
|
|
|
|
// fully loaded during the initial loading process.
|
|
|
|
boost::shared_ptr<ESM::ESMReader> ptr(mReader);
|
|
|
|
mReaders.push_back(ptr);
|
|
|
|
}
|
2014-12-01 21:57:32 +00:00
|
|
|
else
|
|
|
|
delete mReader;
|
2014-11-30 17:04:18 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
mReader = 0;
|
2014-10-08 15:17:31 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
mDialogue = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
ESM::NAME n = mReader->getRecName();
|
|
|
|
mReader->getRecHeader();
|
2013-02-07 11:52:01 +00:00
|
|
|
|
2014-08-04 11:36:01 +00:00
|
|
|
bool unhandledRecord = false;
|
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
switch (n.val)
|
|
|
|
{
|
|
|
|
case ESM::REC_GLOB: mGlobals.load (*mReader, mBase); break;
|
|
|
|
case ESM::REC_GMST: mGmsts.load (*mReader, mBase); break;
|
|
|
|
case ESM::REC_SKIL: mSkills.load (*mReader, mBase); break;
|
|
|
|
case ESM::REC_CLAS: mClasses.load (*mReader, mBase); break;
|
|
|
|
case ESM::REC_FACT: mFactions.load (*mReader, mBase); break;
|
|
|
|
case ESM::REC_RACE: mRaces.load (*mReader, mBase); break;
|
|
|
|
case ESM::REC_SOUN: mSounds.load (*mReader, mBase); break;
|
|
|
|
case ESM::REC_SCPT: mScripts.load (*mReader, mBase); break;
|
|
|
|
case ESM::REC_REGN: mRegions.load (*mReader, mBase); break;
|
|
|
|
case ESM::REC_BSGN: mBirthsigns.load (*mReader, mBase); break;
|
|
|
|
case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break;
|
2014-06-30 18:40:34 +00:00
|
|
|
case ESM::REC_ENCH: mEnchantments.load (*mReader, mBase); break;
|
2014-07-01 10:37:22 +00:00
|
|
|
case ESM::REC_BODY: mBodyParts.load (*mReader, mBase); break;
|
2014-09-23 10:18:18 +00:00
|
|
|
case ESM::REC_SNDG: mSoundGens.load (*mReader, mBase); break;
|
2014-09-26 11:05:51 +00:00
|
|
|
case ESM::REC_MGEF: mMagicEffects.load (*mReader, mBase); break;
|
2014-10-02 10:30:15 +00:00
|
|
|
case ESM::REC_PGRD: mPathgrids.load (*mReader, mBase); break;
|
2015-03-03 12:52:36 +00:00
|
|
|
case ESM::REC_SSCR: mStartScripts.load (*mReader, mBase); break;
|
2014-05-03 13:05:02 +00:00
|
|
|
|
2014-10-08 15:17:31 +00:00
|
|
|
case ESM::REC_LTEX: mLandTextures.load (*mReader, mBase); break;
|
2014-11-30 13:33:39 +00:00
|
|
|
|
|
|
|
case ESM::REC_LAND:
|
|
|
|
{
|
|
|
|
int index = mLand.load(*mReader, mBase);
|
|
|
|
|
|
|
|
if (index!=-1 && !mBase)
|
|
|
|
mLand.getRecord (index).mModified.mLand->loadData (
|
|
|
|
ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR |
|
2015-03-13 11:06:55 +00:00
|
|
|
ESM::Land::DATA_VTEX | ESM::Land::DATA_WNAM);
|
2014-11-30 13:33:39 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2014-10-08 15:17:31 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
case ESM::REC_CELL:
|
2014-05-20 07:02:22 +00:00
|
|
|
{
|
2015-04-26 01:35:46 +00:00
|
|
|
int index = mCells.load (*mReader, mBase);
|
|
|
|
if (index < 0 || index >= mCells.getSize())
|
|
|
|
{
|
|
|
|
// log an error and continue loading the refs to the last loaded cell
|
2015-04-26 02:18:23 +00:00
|
|
|
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_None);
|
|
|
|
messages.add (id, "Logic error: cell index out of bounds");
|
2015-04-26 01:35:46 +00:00
|
|
|
index = mCells.getSize()-1;
|
|
|
|
}
|
|
|
|
std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (index));
|
2015-04-26 04:55:40 +00:00
|
|
|
mRefs.load (*mReader, index, mBase, mRefLoadCache[cellId], messages);
|
2014-05-03 13:05:02 +00:00
|
|
|
break;
|
2014-05-20 07:02:22 +00:00
|
|
|
}
|
2014-05-03 13:05:02 +00:00
|
|
|
|
|
|
|
case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); break;
|
|
|
|
case ESM::REC_ALCH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Potion); break;
|
|
|
|
case ESM::REC_APPA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Apparatus); break;
|
|
|
|
case ESM::REC_ARMO: mReferenceables.load (*mReader, mBase, UniversalId::Type_Armor); break;
|
|
|
|
case ESM::REC_BOOK: mReferenceables.load (*mReader, mBase, UniversalId::Type_Book); break;
|
|
|
|
case ESM::REC_CLOT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Clothing); break;
|
|
|
|
case ESM::REC_CONT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Container); break;
|
|
|
|
case ESM::REC_CREA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Creature); break;
|
|
|
|
case ESM::REC_DOOR: mReferenceables.load (*mReader, mBase, UniversalId::Type_Door); break;
|
|
|
|
case ESM::REC_INGR: mReferenceables.load (*mReader, mBase, UniversalId::Type_Ingredient); break;
|
|
|
|
case ESM::REC_LEVC:
|
|
|
|
mReferenceables.load (*mReader, mBase, UniversalId::Type_CreatureLevelledList); break;
|
|
|
|
case ESM::REC_LEVI:
|
|
|
|
mReferenceables.load (*mReader, mBase, UniversalId::Type_ItemLevelledList); break;
|
|
|
|
case ESM::REC_LIGH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Light); break;
|
|
|
|
case ESM::REC_LOCK: mReferenceables.load (*mReader, mBase, UniversalId::Type_Lockpick); break;
|
|
|
|
case ESM::REC_MISC:
|
|
|
|
mReferenceables.load (*mReader, mBase, UniversalId::Type_Miscellaneous); break;
|
|
|
|
case ESM::REC_NPC_: mReferenceables.load (*mReader, mBase, UniversalId::Type_Npc); break;
|
|
|
|
case ESM::REC_PROB: mReferenceables.load (*mReader, mBase, UniversalId::Type_Probe); break;
|
|
|
|
case ESM::REC_REPA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Repair); break;
|
|
|
|
case ESM::REC_STAT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Static); break;
|
|
|
|
case ESM::REC_WEAP: mReferenceables.load (*mReader, mBase, UniversalId::Type_Weapon); break;
|
|
|
|
|
|
|
|
case ESM::REC_DIAL:
|
2013-02-07 11:52:01 +00:00
|
|
|
{
|
2014-05-03 13:05:02 +00:00
|
|
|
std::string id = mReader->getHNOString ("NAME");
|
2013-02-07 11:52:01 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
ESM::Dialogue record;
|
|
|
|
record.mId = id;
|
|
|
|
record.load (*mReader);
|
2013-10-20 15:13:31 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
if (record.mType==ESM::Dialogue::Journal)
|
|
|
|
{
|
|
|
|
mJournals.load (record, mBase);
|
|
|
|
mDialogue = &mJournals.getRecord (id).get();
|
|
|
|
}
|
|
|
|
else if (record.mType==ESM::Dialogue::Deleted)
|
|
|
|
{
|
|
|
|
mDialogue = 0; // record vector can be shuffled around which would make pointer
|
|
|
|
// to record invalid
|
2013-10-20 15:13:31 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
if (mJournals.tryDelete (id))
|
2013-10-20 15:13:31 +00:00
|
|
|
{
|
2014-05-03 13:05:02 +00:00
|
|
|
/// \todo handle info records
|
2013-10-20 15:13:31 +00:00
|
|
|
}
|
2014-05-03 13:05:02 +00:00
|
|
|
else if (mTopics.tryDelete (id))
|
2013-10-20 15:13:31 +00:00
|
|
|
{
|
2014-05-03 13:05:02 +00:00
|
|
|
/// \todo handle info records
|
2013-10-20 15:13:31 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-12-07 17:57:47 +00:00
|
|
|
messages.add (UniversalId::Type_None,
|
|
|
|
"Trying to delete dialogue record " + id + " which does not exist");
|
2013-10-20 15:13:31 +00:00
|
|
|
}
|
|
|
|
}
|
2014-05-03 13:05:02 +00:00
|
|
|
else
|
2013-10-29 12:18:22 +00:00
|
|
|
{
|
2014-05-03 13:05:02 +00:00
|
|
|
mTopics.load (record, mBase);
|
|
|
|
mDialogue = &mTopics.getRecord (id).get();
|
|
|
|
}
|
2013-10-31 11:16:45 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-10-31 11:16:45 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
case ESM::REC_INFO:
|
|
|
|
{
|
|
|
|
if (!mDialogue)
|
|
|
|
{
|
2014-12-07 17:57:47 +00:00
|
|
|
messages.add (UniversalId::Type_None,
|
|
|
|
"Found info record not following a dialogue record");
|
2014-05-10 11:47:22 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
mReader->skipRecord();
|
2013-10-29 12:18:22 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
if (mDialogue->mType==ESM::Dialogue::Journal)
|
|
|
|
mJournalInfos.load (*mReader, mBase, *mDialogue);
|
|
|
|
else
|
|
|
|
mTopicInfos.load (*mReader, mBase, *mDialogue);
|
2013-09-27 13:04:30 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESM::REC_FILT:
|
|
|
|
|
2014-08-04 11:36:01 +00:00
|
|
|
if (!mProject)
|
2014-05-03 13:05:02 +00:00
|
|
|
{
|
2014-08-04 11:36:01 +00:00
|
|
|
unhandledRecord = true;
|
2014-05-03 13:05:02 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-09-27 13:04:30 +00:00
|
|
|
|
2014-08-04 11:36:01 +00:00
|
|
|
mFilters.load (*mReader, mBase);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ESM::REC_DBGP:
|
|
|
|
|
|
|
|
if (!mProject)
|
2014-05-03 13:05:02 +00:00
|
|
|
{
|
2014-08-04 11:36:01 +00:00
|
|
|
unhandledRecord = true;
|
2014-05-03 13:05:02 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-09-27 13:04:30 +00:00
|
|
|
|
2014-08-04 11:36:01 +00:00
|
|
|
mDebugProfiles.load (*mReader, mBase);
|
|
|
|
break;
|
2013-09-27 13:04:30 +00:00
|
|
|
|
2014-05-03 13:05:02 +00:00
|
|
|
default:
|
2013-02-07 11:52:01 +00:00
|
|
|
|
2014-08-04 11:36:01 +00:00
|
|
|
unhandledRecord = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unhandledRecord)
|
|
|
|
{
|
2014-12-07 17:57:47 +00:00
|
|
|
messages.add (UniversalId::Type_None, "Unsupported record type: " + n.toString());
|
2014-05-10 11:47:22 +00:00
|
|
|
|
2014-08-04 11:36:01 +00:00
|
|
|
mReader->skipRecord();
|
2013-02-07 11:52:01 +00:00
|
|
|
}
|
2014-05-03 13:05:02 +00:00
|
|
|
|
|
|
|
return false;
|
2013-07-28 13:27:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CSMWorld::Data::hasId (const std::string& id) const
|
|
|
|
{
|
|
|
|
return
|
|
|
|
getGlobals().searchId (id)!=-1 ||
|
|
|
|
getGmsts().searchId (id)!=-1 ||
|
|
|
|
getSkills().searchId (id)!=-1 ||
|
|
|
|
getClasses().searchId (id)!=-1 ||
|
|
|
|
getFactions().searchId (id)!=-1 ||
|
|
|
|
getRaces().searchId (id)!=-1 ||
|
|
|
|
getSounds().searchId (id)!=-1 ||
|
|
|
|
getScripts().searchId (id)!=-1 ||
|
|
|
|
getRegions().searchId (id)!=-1 ||
|
|
|
|
getBirthsigns().searchId (id)!=-1 ||
|
|
|
|
getSpells().searchId (id)!=-1 ||
|
2013-10-21 12:26:54 +00:00
|
|
|
getTopics().searchId (id)!=-1 ||
|
2013-10-20 15:13:31 +00:00
|
|
|
getJournals().searchId (id)!=-1 ||
|
2013-07-28 13:27:15 +00:00
|
|
|
getCells().searchId (id)!=-1 ||
|
2014-06-30 18:40:34 +00:00
|
|
|
getEnchantments().searchId (id)!=-1 ||
|
2014-07-03 08:56:05 +00:00
|
|
|
getBodyParts().searchId (id)!=-1 ||
|
2014-09-23 10:18:18 +00:00
|
|
|
getSoundGens().searchId (id)!=-1 ||
|
2014-09-26 11:05:51 +00:00
|
|
|
getMagicEffects().searchId (id)!=-1 ||
|
2013-07-28 13:27:15 +00:00
|
|
|
getReferenceables().searchId (id)!=-1;
|
|
|
|
}
|
2013-09-19 10:11:27 +00:00
|
|
|
|
2013-09-24 15:08:24 +00:00
|
|
|
int CSMWorld::Data::count (RecordBase::State state) const
|
|
|
|
{
|
|
|
|
return
|
|
|
|
count (state, mGlobals) +
|
|
|
|
count (state, mGmsts) +
|
|
|
|
count (state, mSkills) +
|
|
|
|
count (state, mClasses) +
|
|
|
|
count (state, mFactions) +
|
|
|
|
count (state, mRaces) +
|
|
|
|
count (state, mSounds) +
|
|
|
|
count (state, mScripts) +
|
|
|
|
count (state, mRegions) +
|
|
|
|
count (state, mBirthsigns) +
|
|
|
|
count (state, mSpells) +
|
|
|
|
count (state, mCells) +
|
2014-06-30 18:40:34 +00:00
|
|
|
count (state, mEnchantments) +
|
2014-07-03 08:56:05 +00:00
|
|
|
count (state, mBodyParts) +
|
2014-10-08 15:17:31 +00:00
|
|
|
count (state, mLand) +
|
2014-10-10 14:11:54 +00:00
|
|
|
count (state, mLandTextures) +
|
2014-09-23 10:18:18 +00:00
|
|
|
count (state, mSoundGens) +
|
2014-09-26 11:05:51 +00:00
|
|
|
count (state, mMagicEffects) +
|
2014-10-02 10:30:15 +00:00
|
|
|
count (state, mReferenceables) +
|
|
|
|
count (state, mPathgrids);
|
2013-09-24 15:08:24 +00:00
|
|
|
}
|
|
|
|
|
2013-09-24 15:17:01 +00:00
|
|
|
void CSMWorld::Data::setDescription (const std::string& description)
|
|
|
|
{
|
|
|
|
mDescription = description;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string CSMWorld::Data::getDescription() const
|
|
|
|
{
|
|
|
|
return mDescription;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSMWorld::Data::setAuthor (const std::string& author)
|
|
|
|
{
|
|
|
|
mAuthor = author;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string CSMWorld::Data::getAuthor() const
|
|
|
|
{
|
|
|
|
return mAuthor;
|
|
|
|
}
|
|
|
|
|
2013-09-19 11:42:19 +00:00
|
|
|
std::vector<std::string> CSMWorld::Data::getIds (bool listDeleted) const
|
2013-09-19 10:11:27 +00:00
|
|
|
{
|
|
|
|
std::vector<std::string> ids;
|
|
|
|
|
2013-09-19 11:42:19 +00:00
|
|
|
appendIds (ids, mGlobals, listDeleted);
|
|
|
|
appendIds (ids, mGmsts, listDeleted);
|
|
|
|
appendIds (ids, mClasses, listDeleted);
|
|
|
|
appendIds (ids, mFactions, listDeleted);
|
|
|
|
appendIds (ids, mRaces, listDeleted);
|
|
|
|
appendIds (ids, mSounds, listDeleted);
|
|
|
|
appendIds (ids, mScripts, listDeleted);
|
|
|
|
appendIds (ids, mRegions, listDeleted);
|
|
|
|
appendIds (ids, mBirthsigns, listDeleted);
|
|
|
|
appendIds (ids, mSpells, listDeleted);
|
2013-10-20 15:13:31 +00:00
|
|
|
appendIds (ids, mTopics, listDeleted);
|
|
|
|
appendIds (ids, mJournals, listDeleted);
|
2013-09-19 11:42:19 +00:00
|
|
|
appendIds (ids, mCells, listDeleted);
|
2014-06-30 18:40:34 +00:00
|
|
|
appendIds (ids, mEnchantments, listDeleted);
|
2014-07-03 08:56:05 +00:00
|
|
|
appendIds (ids, mBodyParts, listDeleted);
|
2014-09-23 10:18:18 +00:00
|
|
|
appendIds (ids, mSoundGens, listDeleted);
|
2014-09-26 11:05:51 +00:00
|
|
|
appendIds (ids, mMagicEffects, listDeleted);
|
2013-09-19 11:42:19 +00:00
|
|
|
appendIds (ids, mReferenceables, listDeleted);
|
2013-09-19 10:11:27 +00:00
|
|
|
|
|
|
|
std::sort (ids.begin(), ids.end());
|
|
|
|
|
|
|
|
return ids;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
|
|
|
{
|
2013-09-19 11:42:19 +00:00
|
|
|
if (topLeft.column()<=0)
|
|
|
|
emit idListChanged();
|
2013-09-19 10:11:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end)
|
|
|
|
{
|
|
|
|
emit idListChanged();
|
2014-06-15 21:05:38 +00:00
|
|
|
}
|
2015-06-18 12:02:08 +00:00
|
|
|
|
|
|
|
const CSMWorld::Data& CSMWorld::Data::self ()
|
|
|
|
{
|
|
|
|
return *this;
|
|
|
|
}
|
2015-06-24 11:05:59 +00:00
|
|
|
|
|
|
|
void CSMWorld::Data::skillDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
|
|
|
{
|
|
|
|
// mData.mAttribute (affects attributes skill bonus autocalc)
|
|
|
|
// mData.mSpecialization (affects skills autocalc)
|
|
|
|
CSMWorld::IdTable *skillModel =
|
|
|
|
static_cast<CSMWorld::IdTable*>(getTableModel(CSMWorld::UniversalId::Type_Skill));
|
|
|
|
|
|
|
|
int attributeColumn = skillModel->findColumnIndex(CSMWorld::Columns::ColumnId_Attribute);
|
|
|
|
int specialisationColumn = skillModel->findColumnIndex(CSMWorld::Columns::ColumnId_Specialisation);
|
|
|
|
|
|
|
|
if ((topLeft.column() <= attributeColumn && attributeColumn <= bottomRight.column())
|
|
|
|
|| (topLeft.column() <= specialisationColumn && specialisationColumn <= bottomRight.column()))
|
|
|
|
{
|
|
|
|
clearNpcStatsCache();
|
|
|
|
|
|
|
|
std::string empty;
|
|
|
|
emit updateNpcAutocalc(0/*all*/, empty);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSMWorld::Data::classDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
|
|
|
{
|
|
|
|
// update autocalculated attributes/skills of every NPC with matching class
|
|
|
|
// - mData.mAttribute[2]
|
|
|
|
// - mData.mSkills[5][2]
|
|
|
|
// - mData.mSpecialization
|
|
|
|
CSMWorld::IdTable *classModel =
|
|
|
|
static_cast<CSMWorld::IdTable*>(getTableModel(CSMWorld::UniversalId::Type_Class));
|
|
|
|
|
|
|
|
int attribute1Column = classModel->findColumnIndex(CSMWorld::Columns::ColumnId_Attribute1); // +1
|
|
|
|
int majorSkill1Column = classModel->findColumnIndex(CSMWorld::Columns::ColumnId_MajorSkill1); // +4
|
|
|
|
int minorSkill1Column = classModel->findColumnIndex(CSMWorld::Columns::ColumnId_MinorSkill1); // +4
|
|
|
|
int specialisationColumn = classModel->findColumnIndex(CSMWorld::Columns::ColumnId_Specialisation);
|
|
|
|
|
|
|
|
if ((topLeft.column() > attribute1Column+1 || attribute1Column > bottomRight.column())
|
|
|
|
&& (topLeft.column() > majorSkill1Column+4 || majorSkill1Column > bottomRight.column())
|
|
|
|
&& (topLeft.column() > minorSkill1Column+4 || minorSkill1Column > bottomRight.column())
|
|
|
|
&& (topLeft.column() > specialisationColumn || specialisationColumn > bottomRight.column()))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the affected class
|
|
|
|
int idColumn = classModel->findColumnIndex(CSMWorld::Columns::ColumnId_Id);
|
|
|
|
for (int classRow = topLeft.row(); classRow <= bottomRight.row(); ++classRow)
|
|
|
|
{
|
|
|
|
clearNpcStatsCache();
|
|
|
|
|
|
|
|
std::string classId =
|
|
|
|
classModel->data(classModel->index(classRow, idColumn)).toString().toUtf8().constData();
|
|
|
|
emit updateNpcAutocalc(1/*class*/, classId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSMWorld::Data::raceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
|
|
|
{
|
|
|
|
// affects racial bonus attributes & skills
|
|
|
|
// - mData.mAttributeValues[]
|
|
|
|
// - mData.mBonus[].mBonus
|
|
|
|
CSMWorld::IdTree *raceModel =
|
|
|
|
static_cast<CSMWorld::IdTree*>(getTableModel(CSMWorld::UniversalId::Type_Race));
|
|
|
|
|
|
|
|
int attrColumn = raceModel->findColumnIndex(CSMWorld::Columns::ColumnId_RaceAttributes);
|
|
|
|
int bonusColumn = raceModel->findColumnIndex(CSMWorld::Columns::ColumnId_RaceSkillBonus);
|
|
|
|
|
|
|
|
bool match = false;
|
|
|
|
if (topLeft.parent().isValid() && bottomRight.parent().isValid())
|
|
|
|
{
|
|
|
|
if ((topLeft.parent().column() <= attrColumn && attrColumn <= bottomRight.parent().column())
|
|
|
|
|| (topLeft.parent().column() <= bonusColumn && bonusColumn <= bottomRight.parent().column()))
|
|
|
|
{
|
|
|
|
match = true; // TODO: check for specific nested column?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((topLeft.column() <= attrColumn && attrColumn <= bottomRight.column())
|
|
|
|
|| (topLeft.column() <= bonusColumn && bonusColumn <= bottomRight.column()))
|
|
|
|
{
|
|
|
|
match = true; // maybe the whole table changed
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!match)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// update autocalculated attributes/skills of every NPC with matching race
|
|
|
|
int idColumn = raceModel->findColumnIndex(CSMWorld::Columns::ColumnId_Id);
|
|
|
|
for (int raceRow = topLeft.parent().row(); raceRow <= bottomRight.parent().row(); ++raceRow)
|
|
|
|
{
|
|
|
|
clearNpcStatsCache();
|
|
|
|
|
|
|
|
std::string raceId =
|
|
|
|
raceModel->data(raceModel->index(raceRow, idColumn)).toString().toUtf8().constData();
|
|
|
|
emit updateNpcAutocalc(2/*race*/, raceId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: currently ignoring level changes
|
|
|
|
void CSMWorld::Data::npcDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
|
|
|
{
|
|
|
|
clearNpcStatsCache();
|
|
|
|
|
|
|
|
// Either autoCalc flag changed or NPC level changed
|
|
|
|
CSMWorld::IdTree *objectModel =
|
|
|
|
static_cast<CSMWorld::IdTree*>(getTableModel(CSMWorld::UniversalId::Type_Referenceable));
|
|
|
|
|
|
|
|
int autoCalcColumn = objectModel->findColumnIndex(CSMWorld::Columns::ColumnId_AutoCalc);
|
|
|
|
int miscColumn = objectModel->findColumnIndex(CSMWorld::Columns::ColumnId_NpcMisc);
|
|
|
|
|
|
|
|
// first check for level
|
|
|
|
bool levelChanged = false;
|
|
|
|
if (topLeft.parent().isValid() && bottomRight.parent().isValid())
|
|
|
|
{
|
|
|
|
if (topLeft.parent().column() <= miscColumn && miscColumn <= bottomRight.parent().column())
|
|
|
|
{
|
|
|
|
for (int col = topLeft.column(); col <= bottomRight.column(); ++col)
|
|
|
|
{
|
|
|
|
int role = objectModel->nestedHeaderData(topLeft.parent().column(),
|
|
|
|
col, Qt::Horizontal, CSMWorld::ColumnBase::Role_ColumnId).toInt();
|
|
|
|
if (role == CSMWorld::Columns::ColumnId_NpcLevel)
|
|
|
|
{
|
|
|
|
levelChanged = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// next check for autocalc
|
|
|
|
bool autoCalcChanged = false;
|
|
|
|
if (!topLeft.parent().isValid() && !bottomRight.parent().isValid())
|
|
|
|
{
|
|
|
|
if ((topLeft.column() <= autoCalcColumn && autoCalcColumn <= bottomRight.column())
|
|
|
|
|| (topLeft.column() <= miscColumn && miscColumn <= bottomRight.column()))
|
|
|
|
{
|
|
|
|
autoCalcChanged = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!levelChanged && !autoCalcChanged)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int row = 0;
|
|
|
|
int end = 0;
|
|
|
|
if (topLeft.parent().isValid())
|
|
|
|
row = topLeft.parent().row();
|
|
|
|
else
|
|
|
|
row = topLeft.row();
|
|
|
|
|
|
|
|
if (bottomRight.parent().isValid())
|
|
|
|
end = bottomRight.parent().row();
|
|
|
|
else
|
|
|
|
end = bottomRight.row();
|
|
|
|
|
|
|
|
for (; row <= end; ++row)
|
|
|
|
{
|
|
|
|
Record<ESM::NPC> record =
|
|
|
|
static_cast<const Record<ESM::NPC>&>(mReferenceables.getRecord(row));
|
|
|
|
ESM::NPC &npc = record.get();
|
|
|
|
|
|
|
|
// If going from autocalc to non-autocalc, save the autocalc values
|
|
|
|
if (autoCalcChanged)
|
|
|
|
{
|
|
|
|
if (npc.mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
|
|
|
saveAutoCalcValues(npc); // update attributes and skills
|
|
|
|
else
|
|
|
|
npc.mNpdt12.mLevel = npc.mNpdt52.mLevel; // for NPC's loaded as non-autocalc
|
|
|
|
|
|
|
|
record.setModified(npc);
|
|
|
|
mReferenceables.replace(row, record);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSMWorld::Data::gmstDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
|
|
|
{
|
|
|
|
static const QStringList gmsts(QStringList()<< "fNPCbaseMagickaMult" << "fAutoSpellChance"
|
|
|
|
<< "fEffectCostMult" << "iAutoSpellAlterationMax" << "iAutoSpellConjurationMax"
|
|
|
|
<< "iAutoSpellDestructionMax" << "iAutoSpellIllusionMax" << "iAutoSpellMysticismMax"
|
|
|
|
<< "iAutoSpellRestorationMax" << "iAutoSpellTimesCanCast" << "iAutoSpellAttSkillMin");
|
|
|
|
|
|
|
|
bool match = false;
|
|
|
|
for (int row = topLeft.row(); row <= bottomRight.row(); ++row)
|
|
|
|
{
|
|
|
|
if (gmsts.contains(mGmsts.getRecord(row).get().mId.c_str()))
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!match)
|
|
|
|
return;
|
|
|
|
|
|
|
|
clearNpcStatsCache();
|
|
|
|
|
|
|
|
std::string empty;
|
|
|
|
emit updateNpcAutocalc(0/*all*/, empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: how to undo?
|
|
|
|
void CSMWorld::Data::saveAutoCalcValues(ESM::NPC& npc)
|
|
|
|
{
|
|
|
|
CSMWorld::NpcStats * cachedStats = getCachedNpcData (npc.mId);
|
|
|
|
if (!cachedStats)
|
|
|
|
return; // silently fail
|
|
|
|
|
|
|
|
CSMWorld::NpcStats* stats = npcAutoCalculate(npc);
|
|
|
|
|
|
|
|
// update npc
|
|
|
|
npc.mNpdt52.mLevel = npc.mNpdt12.mLevel;
|
|
|
|
|
|
|
|
npc.mNpdt52.mStrength = stats->getBaseAttribute(ESM::Attribute::Strength);
|
|
|
|
npc.mNpdt52.mIntelligence = stats->getBaseAttribute(ESM::Attribute::Intelligence);
|
|
|
|
npc.mNpdt52.mWillpower = stats->getBaseAttribute(ESM::Attribute::Willpower);
|
|
|
|
npc.mNpdt52.mAgility = stats->getBaseAttribute(ESM::Attribute::Agility);
|
|
|
|
npc.mNpdt52.mSpeed = stats->getBaseAttribute(ESM::Attribute::Speed);
|
|
|
|
npc.mNpdt52.mEndurance = stats->getBaseAttribute(ESM::Attribute::Endurance);
|
|
|
|
npc.mNpdt52.mPersonality = stats->getBaseAttribute(ESM::Attribute::Personality);
|
|
|
|
npc.mNpdt52.mLuck = stats->getBaseAttribute(ESM::Attribute::Luck);
|
|
|
|
|
|
|
|
for (int i = 0; i < ESM::Skill::Length; ++i)
|
|
|
|
{
|
|
|
|
npc.mNpdt52.mSkills[i] = stats->getBaseSkill(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
npc.mNpdt52.mHealth = stats->getHealth();
|
|
|
|
npc.mNpdt52.mMana = stats->getMana();
|
|
|
|
npc.mNpdt52.mFatigue = stats->getFatigue();
|
|
|
|
npc.mNpdt52.mDisposition = npc.mNpdt12.mDisposition;
|
|
|
|
npc.mNpdt52.mReputation = npc.mNpdt12.mReputation;
|
|
|
|
npc.mNpdt52.mRank = npc.mNpdt12.mRank;
|
|
|
|
npc.mNpdt52.mGold = npc.mNpdt12.mGold;
|
|
|
|
|
|
|
|
// TODO: add spells from autogenerated list like vanilla (but excluding any race powers or abilities)
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSMWorld::Data::clearNpcStatsCache ()
|
|
|
|
{
|
|
|
|
for (std::map<std::string, CSMWorld::NpcStats*>::iterator it (mNpcStatCache.begin());
|
|
|
|
it != mNpcStatCache.end(); ++it)
|
|
|
|
delete it->second;
|
|
|
|
|
|
|
|
mNpcStatCache.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::NpcStats* CSMWorld::Data::npcAutoCalculate(const ESM::NPC& npc) const
|
|
|
|
{
|
|
|
|
CSMWorld::NpcStats * cachedStats = getCachedNpcData (npc.mId);
|
|
|
|
if (cachedStats)
|
|
|
|
return cachedStats;
|
|
|
|
|
|
|
|
const ESM::Race *race = &mRaces.getRecord(npc.mRace).get();
|
|
|
|
const ESM::Class *class_ = &mClasses.getRecord(npc.mClass).get();
|
|
|
|
|
|
|
|
bool autoCalc = npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS;
|
|
|
|
short level = npc.mNpdt52.mLevel;
|
|
|
|
if (autoCalc)
|
|
|
|
level = npc.mNpdt12.mLevel;
|
|
|
|
|
|
|
|
CSMWorld::NpcStats *stats = new CSMWorld::NpcStats();
|
|
|
|
|
|
|
|
CSStore store(mGmsts, mSkills, mMagicEffects, mSpells);
|
|
|
|
|
|
|
|
if (autoCalc)
|
|
|
|
{
|
|
|
|
GamePlay::autoCalcAttributesImpl (&npc, race, class_, level, *stats, &store);
|
|
|
|
|
|
|
|
stats->setHealth(autoCalculateHealth(level, class_, *stats));
|
|
|
|
stats->setMana(autoCalculateMana(*stats));
|
|
|
|
stats->setFatigue(autoCalculateFatigue(*stats));
|
|
|
|
|
|
|
|
GamePlay::autoCalcSkillsImpl(&npc, race, class_, level, *stats, &store);
|
|
|
|
|
|
|
|
GamePlay::autoCalculateSpells(race, *stats, &store);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (std::vector<std::string>::const_iterator it = npc.mSpells.mList.begin();
|
|
|
|
it != npc.mSpells.mList.end(); ++it)
|
|
|
|
{
|
|
|
|
stats->addSpells(*it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// update spell info
|
|
|
|
const std::vector<std::string> &racePowers = race->mPowers.mList;
|
|
|
|
for (unsigned int i = 0; i < racePowers.size(); ++i)
|
|
|
|
{
|
|
|
|
int type = -1;
|
|
|
|
int spellIndex = mSpells.searchId(racePowers[i]);
|
|
|
|
if (spellIndex != -1)
|
|
|
|
type = mSpells.getRecord(spellIndex).get().mData.mType;
|
|
|
|
stats->addPowers(racePowers[i], type);
|
|
|
|
}
|
|
|
|
// cost/chance
|
|
|
|
int skills[ESM::Skill::Length];
|
|
|
|
if (autoCalc)
|
|
|
|
for (int i = 0; i< ESM::Skill::Length; ++i)
|
|
|
|
skills[i] = stats->getBaseSkill(i);
|
|
|
|
else
|
|
|
|
for (int i = 0; i< ESM::Skill::Length; ++i)
|
|
|
|
skills[i] = npc.mNpdt52.mSkills[i];
|
|
|
|
|
|
|
|
int attributes[ESM::Attribute::Length];
|
|
|
|
if (autoCalc)
|
|
|
|
for (int i = 0; i< ESM::Attribute::Length; ++i)
|
|
|
|
attributes[i] = stats->getBaseAttribute(i);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
attributes[ESM::Attribute::Strength] = npc.mNpdt52.mStrength;
|
|
|
|
attributes[ESM::Attribute::Willpower] = npc.mNpdt52.mWillpower;
|
|
|
|
attributes[ESM::Attribute::Agility] = npc.mNpdt52.mAgility;
|
|
|
|
attributes[ESM::Attribute::Speed] = npc.mNpdt52.mSpeed;
|
|
|
|
attributes[ESM::Attribute::Endurance] = npc.mNpdt52.mEndurance;
|
|
|
|
attributes[ESM::Attribute::Personality] = npc.mNpdt52.mPersonality;
|
|
|
|
attributes[ESM::Attribute::Luck] = npc.mNpdt52.mLuck;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::vector<CSMWorld::SpellInfo>& spells = stats->spells();
|
|
|
|
for (std::vector<SpellInfo>::const_iterator it = spells.begin(); it != spells.end(); ++it)
|
|
|
|
{
|
|
|
|
int cost = -1;
|
|
|
|
int spellIndex = mSpells.searchId((*it).mName);
|
|
|
|
const ESM::Spell* spell = 0;
|
|
|
|
if (spellIndex != -1)
|
|
|
|
{
|
|
|
|
spell = &mSpells.getRecord(spellIndex).get();
|
|
|
|
cost = spell->mData.mCost;
|
|
|
|
|
|
|
|
int school;
|
|
|
|
float skillTerm;
|
|
|
|
GamePlay::calcWeakestSchool(spell, skills, school, skillTerm, &store);
|
|
|
|
float chance = calcAutoCastChance(spell, skills, attributes, school, &store);
|
|
|
|
|
|
|
|
stats->addCostAndChance((*it).mName, cost, (int)ceil(chance)); // percent
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
emit cacheNpcStats (npc.mId, stats);
|
|
|
|
return stats;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSMWorld::Data::cacheNpcStatsEvent (const std::string& id, CSMWorld::NpcStats *stats)
|
|
|
|
{
|
|
|
|
mNpcStatCache[id] = stats;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::NpcStats* CSMWorld::Data::getCachedNpcData (const std::string& id) const
|
|
|
|
{
|
|
|
|
std::map<std::string, CSMWorld::NpcStats*>::const_iterator it = mNpcStatCache.find(id);
|
|
|
|
if (it != mNpcStatCache.end())
|
|
|
|
return it->second;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|