Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879#include "refidcollection.hpp"
#include <algorithm>#include <memory>#include <stdexcept>#include <string_view>#include <type_traits>
#include <apps/opencs/model/world/columnbase.hpp>#include <apps/opencs/model/world/record.hpp>#include <apps/opencs/model/world/refiddata.hpp>
#include <components/esm3/loadacti.hpp>#include <components/esm3/loadalch.hpp>#include <components/esm3/loadarmo.hpp>#include <components/esm3/loadclot.hpp>#include <components/esm3/loadcont.hpp>#include <components/esm3/loadcrea.hpp>#include <components/esm3/loadlevlist.hpp>#include <components/esm3/loadligh.hpp>#include <components/esm3/loadlock.hpp>#include <components/esm3/loadnpc.hpp>#include <components/esm3/loadprob.hpp>#include <components/esm3/loadrepa.hpp>#include <components/esm3/loadstat.hpp>#include <components/esm3/loadweap.hpp>
#include "columns.hpp"#include "nestedcoladapterimp.hpp"#include "nestedtablewrapper.hpp"#include "refidadapter.hpp"#include "refidadapterimp.hpp"
CSMWorld::RefIdColumn::RefIdColumn(int columnId, Display displayType, int flag, bool editable, bool userEditable) : NestableColumn(columnId, displayType, flag) , mEditable(editable) , mUserEditable(userEditable){}
bool CSMWorld::RefIdColumn::isEditable() const{ return mEditable;}
bool CSMWorld::RefIdColumn::isUserEditable() const{ return mUserEditable;}
const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter(UniversalId::Type type) const{ std::map<UniversalId::Type, RefIdAdapter*>::const_iterator iter = mAdapters.find(type);
if (iter == mAdapters.end()) throw std::logic_error("unsupported type in RefIdCollection");
return *iter->second;}
CSMWorld::RefIdCollection::RefIdCollection(const IdCollection<ESM::MagicEffect>& magicEffects){ BaseColumns baseColumns;
mColumns.emplace_back( Columns::ColumnId_Id, ColumnBase::Display_Id, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false); baseColumns.mId = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Modification, ColumnBase::Display_RecordState, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true, false); baseColumns.mModified = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_RecordType, ColumnBase::Display_RefRecordType, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false); baseColumns.mType = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Blocked, ColumnBase::Display_Boolean, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh); baseColumns.mBlocked = &mColumns.back();
ModelColumns modelColumns(baseColumns);
mColumns.emplace_back(Columns::ColumnId_Persistent, ColumnBase::Display_Boolean); modelColumns.mPersistence = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Model, ColumnBase::Display_Mesh); modelColumns.mModel = &mColumns.back();
NameColumns nameColumns(modelColumns);
// Only items that can be placed in a container have the 32 character limit, but enforce // that for all referenceable types for now. mColumns.emplace_back(Columns::ColumnId_Name, ColumnBase::Display_String32); nameColumns.mName = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Script, ColumnBase::Display_Script); nameColumns.mScript = &mColumns.back();
InventoryColumns inventoryColumns(nameColumns);
mColumns.emplace_back(Columns::ColumnId_Icon, ColumnBase::Display_Icon); inventoryColumns.mIcon = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Weight, ColumnBase::Display_Float); inventoryColumns.mWeight = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_GoldValue, ColumnBase::Display_Integer); inventoryColumns.mValue = &mColumns.back();
IngredientColumns ingredientColumns(inventoryColumns); mColumns.emplace_back(Columns::ColumnId_EffectList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); ingredientColumns.mEffects = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> ingredientEffectsMap; ingredientEffectsMap.insert( std::make_pair(UniversalId::Type_Ingredient, new IngredEffectRefIdAdapter(magicEffects))); mNestedAdapters.emplace_back(&mColumns.back(), ingredientEffectsMap); mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_EffectId, ColumnBase::Display_IngredEffectId)); mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill)); mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute));
// nested table PotionColumns potionColumns(inventoryColumns); mColumns.emplace_back(Columns::ColumnId_EffectList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); potionColumns.mEffects = &mColumns.back(); // see refidadapterimp.hpp std::map<UniversalId::Type, NestedRefIdAdapterBase*> effectsMap; effectsMap.insert(std::make_pair( UniversalId::Type_Potion, new EffectsRefIdAdapter<ESM::Potion>(UniversalId::Type_Potion, magicEffects))); mNestedAdapters.emplace_back(&mColumns.back(), effectsMap); mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill)); mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute)); mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_EffectArea, ColumnBase::Display_String)); mColumns.back().addColumn( new NestedChildColumn(Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_MinMagnitude, ColumnBase::Display_Integer)); mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_MaxMagnitude, ColumnBase::Display_Integer));
EnchantableColumns enchantableColumns(inventoryColumns);
mColumns.emplace_back(Columns::ColumnId_Enchantment, ColumnBase::Display_Enchantment); enchantableColumns.mEnchantment = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_EnchantmentPoints, ColumnBase::Display_Integer); enchantableColumns.mEnchantmentPoints = &mColumns.back();
ToolColumns toolsColumns(inventoryColumns);
mColumns.emplace_back(Columns::ColumnId_Quality, ColumnBase::Display_Float); toolsColumns.mQuality = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Charges, ColumnBase::Display_Integer); toolsColumns.mUses = &mColumns.back();
ActorColumns actorsColumns(nameColumns);
mColumns.emplace_back(Columns::ColumnId_AiHello, ColumnBase::Display_UnsignedInteger16); actorsColumns.mHello = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_AiFlee, ColumnBase::Display_UnsignedInteger8); actorsColumns.mFlee = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_AiFight, ColumnBase::Display_UnsignedInteger8); actorsColumns.mFight = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_AiAlarm, ColumnBase::Display_UnsignedInteger8); actorsColumns.mAlarm = &mColumns.back();
// Nested table mColumns.emplace_back( Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mInventory = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> inventoryMap; inventoryMap.insert( std::make_pair(UniversalId::Type_Npc, new NestedInventoryRefIdAdapter<ESM::NPC>(UniversalId::Type_Npc))); inventoryMap.insert(std::make_pair( UniversalId::Type_Creature, new NestedInventoryRefIdAdapter<ESM::Creature>(UniversalId::Type_Creature))); mNestedAdapters.emplace_back(&mColumns.back(), inventoryMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer));
// Nested table mColumns.emplace_back(Columns::ColumnId_SpellList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mSpells = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> spellsMap; spellsMap.insert( std::make_pair(UniversalId::Type_Npc, new NestedSpellRefIdAdapter<ESM::NPC>(UniversalId::Type_Npc))); spellsMap.insert(std::make_pair( UniversalId::Type_Creature, new NestedSpellRefIdAdapter<ESM::Creature>(UniversalId::Type_Creature))); mNestedAdapters.emplace_back(&mColumns.back(), spellsMap); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_Spell));
// Nested table mColumns.emplace_back( Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mDestinations = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> destMap; destMap.insert( std::make_pair(UniversalId::Type_Npc, new NestedTravelRefIdAdapter<ESM::NPC>(UniversalId::Type_Npc))); destMap.insert(std::make_pair( UniversalId::Type_Creature, new NestedTravelRefIdAdapter<ESM::Creature>(UniversalId::Type_Creature))); mNestedAdapters.emplace_back(&mColumns.back(), destMap); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_Cell)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Double)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Double)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Double));
// Nested table mColumns.emplace_back(Columns::ColumnId_AiPackageList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mAiPackages = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> aiMap; aiMap.insert(std::make_pair(UniversalId::Type_Npc, new ActorAiRefIdAdapter<ESM::NPC>(UniversalId::Type_Npc))); aiMap.insert( std::make_pair(UniversalId::Type_Creature, new ActorAiRefIdAdapter<ESM::Creature>(UniversalId::Type_Creature))); mNestedAdapters.emplace_back(&mColumns.back(), aiMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_AiPackageType, CSMWorld::ColumnBase::Display_AiPackageType)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiWanderDist, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiDuration, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiWanderToD, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle2, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle3, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle4, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle5, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle6, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle7, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle8, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle9, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiWanderRepeat, CSMWorld::ColumnBase::Display_Boolean)); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_AiActivateName, CSMWorld::ColumnBase::Display_String32)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiTargetId, CSMWorld::ColumnBase::Display_String32)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiTargetCell, CSMWorld::ColumnBase::Display_String)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float));
static const struct { int mName; unsigned int mFlag; } sServiceTable[] = { { Columns::ColumnId_BuysWeapons, ESM::NPC::Weapon }, { Columns::ColumnId_BuysArmor, ESM::NPC::Armor }, { Columns::ColumnId_BuysClothing, ESM::NPC::Clothing }, { Columns::ColumnId_BuysBooks, ESM::NPC::Books }, { Columns::ColumnId_BuysIngredients, ESM::NPC::Ingredients }, { Columns::ColumnId_BuysLockpicks, ESM::NPC::Picks }, { Columns::ColumnId_BuysProbes, ESM::NPC::Probes }, { Columns::ColumnId_BuysLights, ESM::NPC::Lights }, { Columns::ColumnId_BuysApparati, ESM::NPC::Apparatus }, { Columns::ColumnId_BuysRepairItems, ESM::NPC::RepairItem }, { Columns::ColumnId_BuysMiscItems, ESM::NPC::Misc }, { Columns::ColumnId_BuysPotions, ESM::NPC::Potions }, { Columns::ColumnId_BuysMagicItems, ESM::NPC::MagicItems }, { Columns::ColumnId_SellsSpells, ESM::NPC::Spells }, { Columns::ColumnId_Trainer, ESM::NPC::Training }, { Columns::ColumnId_Spellmaking, ESM::NPC::Spellmaking }, { Columns::ColumnId_EnchantingService, ESM::NPC::Enchanting }, { Columns::ColumnId_RepairService, ESM::NPC::Repair }, { -1, 0 } };
for (int i = 0; sServiceTable[i].mName != -1; ++i) { mColumns.emplace_back(sServiceTable[i].mName, ColumnBase::Display_Boolean); actorsColumns.mServices.insert(std::make_pair(&mColumns.back(), sServiceTable[i].mFlag)); }
mColumns.emplace_back(Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh); const RefIdColumn* autoCalc = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_ApparatusType, ColumnBase::Display_ApparatusType); const RefIdColumn* apparatusType = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_ArmorType, ColumnBase::Display_ArmorType); const RefIdColumn* armorType = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Health, ColumnBase::Display_Integer); const RefIdColumn* health = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_ArmorValue, ColumnBase::Display_Integer); const RefIdColumn* armor = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_BookType, ColumnBase::Display_BookType); const RefIdColumn* bookType = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Skill, ColumnBase::Display_SkillId); const RefIdColumn* skill = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Text, ColumnBase::Display_LongString); const RefIdColumn* text = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_ClothingType, ColumnBase::Display_ClothingType); const RefIdColumn* clothingType = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_WeightCapacity, ColumnBase::Display_Float); const RefIdColumn* weightCapacity = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_OrganicContainer, ColumnBase::Display_Boolean); const RefIdColumn* organic = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Respawn, ColumnBase::Display_Boolean); const RefIdColumn* respawn = &mColumns.back();
// Nested table mColumns.emplace_back( Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); const RefIdColumn* content = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> contMap; contMap.insert(std::make_pair( UniversalId::Type_Container, new NestedInventoryRefIdAdapter<ESM::Container>(UniversalId::Type_Container))); mNestedAdapters.emplace_back(&mColumns.back(), contMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer));
CreatureColumns creatureColumns(actorsColumns);
mColumns.emplace_back(Columns::ColumnId_CreatureType, ColumnBase::Display_CreatureType); creatureColumns.mType = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Scale, ColumnBase::Display_Float); creatureColumns.mScale = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_ParentCreature, ColumnBase::Display_Creature); creatureColumns.mOriginal = &mColumns.back();
static const struct { int mName; unsigned int mFlag; } sCreatureFlagTable[] = { { Columns::ColumnId_Biped, ESM::Creature::Bipedal }, { Columns::ColumnId_HasWeapon, ESM::Creature::Weapon }, { Columns::ColumnId_Swims, ESM::Creature::Swims }, { Columns::ColumnId_Flies, ESM::Creature::Flies }, { Columns::ColumnId_Walks, ESM::Creature::Walks }, { Columns::ColumnId_Essential, ESM::Creature::Essential }, { -1, 0 } };
// for re-use in NPC records const RefIdColumn* essential = nullptr;
for (int i = 0; sCreatureFlagTable[i].mName != -1; ++i) { mColumns.emplace_back(sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean); creatureColumns.mFlags.insert(std::make_pair(&mColumns.back(), sCreatureFlagTable[i].mFlag));
switch (sCreatureFlagTable[i].mFlag) { case ESM::Creature::Essential: essential = &mColumns.back(); break; } }
mColumns.emplace_back(Columns::ColumnId_BloodType, ColumnBase::Display_BloodType); // For re-use in NPC records. const RefIdColumn* bloodType = &mColumns.back(); creatureColumns.mBloodType = bloodType;
creatureColumns.mFlags.insert(std::make_pair(respawn, ESM::Creature::Respawn));
// Nested table mColumns.emplace_back( Columns::ColumnId_CreatureAttributes, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); creatureColumns.mAttributes = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> creaAttrMap; creaAttrMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureAttributesRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), creaAttrMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_Attribute, CSMWorld::ColumnBase::Display_Attribute, false, false)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AttributeValue, CSMWorld::ColumnBase::Display_Integer));
// Nested table mColumns.emplace_back( Columns::ColumnId_CreatureAttack, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); creatureColumns.mAttacks = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> attackMap; attackMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureAttackRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), attackMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_CreatureAttack, CSMWorld::ColumnBase::Display_Integer, false, false)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_MinAttack, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_MaxAttack, CSMWorld::ColumnBase::Display_Integer));
// Nested list mColumns.emplace_back(Columns::ColumnId_CreatureMisc, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); creatureColumns.mMisc = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> creaMiscMap; creaMiscMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureMiscRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), creaMiscMap); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Health, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Mana, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Fatigue, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_SoulPoints, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_CombatState, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_MagicState, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_StealthState, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Gold, CSMWorld::ColumnBase::Display_Integer));
mColumns.emplace_back(Columns::ColumnId_OpenSound, ColumnBase::Display_Sound); const RefIdColumn* openSound = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_CloseSound, ColumnBase::Display_Sound); const RefIdColumn* closeSound = &mColumns.back();
LightColumns lightColumns(inventoryColumns);
mColumns.emplace_back(Columns::ColumnId_Duration, ColumnBase::Display_Integer); lightColumns.mTime = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Radius, ColumnBase::Display_Integer); lightColumns.mRadius = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Colour, ColumnBase::Display_Colour); lightColumns.mColor = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Sound, ColumnBase::Display_Sound); lightColumns.mSound = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_EmitterType, ColumnBase::Display_EmitterType); lightColumns.mEmitterType = &mColumns.back();
static const struct { int mName; unsigned int mFlag; } sLightFlagTable[] = { { Columns::ColumnId_Dynamic, ESM::Light::Dynamic }, { Columns::ColumnId_Portable, ESM::Light::Carry }, { Columns::ColumnId_NegativeLight, ESM::Light::Negative }, { Columns::ColumnId_Fire, ESM::Light::Fire }, { Columns::ColumnId_OffByDefault, ESM::Light::OffDefault }, { -1, 0 } };
for (int i = 0; sLightFlagTable[i].mName != -1; ++i) { mColumns.emplace_back(sLightFlagTable[i].mName, ColumnBase::Display_Boolean); lightColumns.mFlags.insert(std::make_pair(&mColumns.back(), sLightFlagTable[i].mFlag)); }
mColumns.emplace_back(Columns::ColumnId_IsKey, ColumnBase::Display_Boolean); const RefIdColumn* key = &mColumns.back();
NpcColumns npcColumns(actorsColumns);
mColumns.emplace_back(Columns::ColumnId_Race, ColumnBase::Display_Race); npcColumns.mRace = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Class, ColumnBase::Display_Class); npcColumns.mClass = &mColumns.back();
// NAME32 enforced in IdCompletionDelegate::createEditor() mColumns.emplace_back(Columns::ColumnId_Faction, ColumnBase::Display_Faction); npcColumns.mFaction = &mColumns.back();
mColumns.emplace_back(Columns::Columnid_Hair, ColumnBase::Display_BodyPart); npcColumns.mHair = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Head, ColumnBase::Display_BodyPart); npcColumns.mHead = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Gender, ColumnBase::Display_GenderNpc); npcColumns.mGender = &mColumns.back();
npcColumns.mFlags.insert(std::make_pair(essential, ESM::NPC::Essential));
npcColumns.mFlags.insert(std::make_pair(respawn, ESM::NPC::Respawn));
npcColumns.mFlags.insert(std::make_pair(autoCalc, ESM::NPC::Autocalc));
// Re-used from Creature records. npcColumns.mBloodType = bloodType;
// Need a way to add a table of stats and values (rather than adding a long list of // entries in the dialogue subview) E.g. attributes+stats(health, mana, fatigue), skills // These needs to be driven from the autocalculated setting.
// Nested table mColumns.emplace_back(Columns::ColumnId_NpcAttributes, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); npcColumns.mAttributes = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> attrMap; attrMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcAttributesRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), attrMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_Attribute, CSMWorld::ColumnBase::Display_Attribute, false, false)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_UnsignedInteger8));
// Nested table mColumns.emplace_back(Columns::ColumnId_NpcSkills, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); npcColumns.mSkills = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> skillsMap; skillsMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcSkillsRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), skillsMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_Skill, CSMWorld::ColumnBase::Display_SkillId, false, false)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_UnsignedInteger8));
// Nested list mColumns.emplace_back(Columns::ColumnId_NpcMisc, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); npcColumns.mMisc = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> miscMap; miscMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcMiscRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), miscMap); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_SignedInteger16)); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_Health, CSMWorld::ColumnBase::Display_UnsignedInteger16)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Mana, CSMWorld::ColumnBase::Display_UnsignedInteger16)); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_Fatigue, CSMWorld::ColumnBase::Display_UnsignedInteger16)); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_NpcDisposition, CSMWorld::ColumnBase::Display_UnsignedInteger8)); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_NpcReputation, CSMWorld::ColumnBase::Display_UnsignedInteger8)); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_NpcRank, CSMWorld::ColumnBase::Display_UnsignedInteger8)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Gold, CSMWorld::ColumnBase::Display_Integer));
WeaponColumns weaponColumns(enchantableColumns);
mColumns.emplace_back(Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType); weaponColumns.mType = &mColumns.back();
weaponColumns.mHealth = health;
mColumns.emplace_back(Columns::ColumnId_WeaponSpeed, ColumnBase::Display_Float); weaponColumns.mSpeed = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_WeaponReach, ColumnBase::Display_Float); weaponColumns.mReach = &mColumns.back();
for (int i = 0; i < 3; ++i) { const RefIdColumn** column = i == 0 ? weaponColumns.mChop : (i == 1 ? weaponColumns.mSlash : weaponColumns.mThrust);
for (int j = 0; j < 2; ++j) { mColumns.emplace_back(Columns::ColumnId_MinChop + i * 2 + j, ColumnBase::Display_Integer); column[j] = &mColumns.back(); } }
static const struct { int mName; unsigned int mFlag; } sWeaponFlagTable[] = { { Columns::ColumnId_Magical, ESM::Weapon::Magical }, { Columns::ColumnId_Silver, ESM::Weapon::Silver }, { -1, 0 } };
for (int i = 0; sWeaponFlagTable[i].mName != -1; ++i) { mColumns.emplace_back(sWeaponFlagTable[i].mName, ColumnBase::Display_Boolean); weaponColumns.mFlags.insert(std::make_pair(&mColumns.back(), sWeaponFlagTable[i].mFlag)); }
// Nested table mColumns.emplace_back(Columns::ColumnId_PartRefList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); const RefIdColumn* partRef = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> partMap; partMap.insert( std::make_pair(UniversalId::Type_Armor, new BodyPartRefIdAdapter<ESM::Armor>(UniversalId::Type_Armor))); partMap.insert(std::make_pair( UniversalId::Type_Clothing, new BodyPartRefIdAdapter<ESM::Clothing>(UniversalId::Type_Clothing))); mNestedAdapters.emplace_back(&mColumns.back(), partMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_PartRefType)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_BodyPart)); mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_BodyPart));
LevListColumns creatureLevListColumns(baseColumns); LevListColumns itemLevListColumns(baseColumns); std::map<UniversalId::Type, NestedRefIdAdapterBase*> creatureLevListMap, itemLevListMap; creatureLevListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, new NestedLevListRefIdAdapter<ESM::CreatureLevList>(UniversalId::Type_CreatureLevelledList))); itemLevListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList, new NestedLevListRefIdAdapter<ESM::ItemLevList>(UniversalId::Type_ItemLevelledList)));
// Levelled creature nested table mColumns.emplace_back(Columns::ColumnId_LevelledList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); creatureLevListColumns.mLevList = &mColumns.back(); mNestedAdapters.emplace_back(&mColumns.back(), creatureLevListMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_LevelledCreatureId, CSMWorld::ColumnBase::Display_Referenceable)); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer));
// Levelled item nested table mColumns.emplace_back(Columns::ColumnId_LevelledList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); itemLevListColumns.mLevList = &mColumns.back(); mNestedAdapters.emplace_back(&mColumns.back(), itemLevListMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_LevelledItemId, CSMWorld::ColumnBase::Display_Referenceable)); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer));
// Shared levelled list nested list mColumns.emplace_back(Columns::ColumnId_LevelledList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); creatureLevListColumns.mNestedListLevList = &mColumns.back(); itemLevListColumns.mNestedListLevList = &mColumns.back(); std::map<UniversalId::Type, NestedRefIdAdapterBase*> nestedListLevListMap; nestedListLevListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, new NestedListLevListRefIdAdapter<ESM::CreatureLevList>(UniversalId::Type_CreatureLevelledList))); nestedListLevListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList, new NestedListLevListRefIdAdapter<ESM::ItemLevList>(UniversalId::Type_ItemLevelledList))); mNestedAdapters.emplace_back(&mColumns.back(), nestedListLevListMap); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_LevelledItemTypeEach, CSMWorld::ColumnBase::Display_Boolean)); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_LevelledItemType, CSMWorld::ColumnBase::Display_Boolean)); mColumns.back().addColumn( new RefIdColumn(Columns::ColumnId_LevelledItemChanceNone, CSMWorld::ColumnBase::Display_UnsignedInteger8));
mAdapters.insert(std::make_pair( UniversalId::Type_Activator, new NameRefIdAdapter<ESM::Activator>(UniversalId::Type_Activator, nameColumns))); mAdapters.insert(std::make_pair(UniversalId::Type_Potion, new PotionRefIdAdapter(potionColumns, autoCalc))); mAdapters.insert(std::make_pair(UniversalId::Type_Apparatus, new ApparatusRefIdAdapter(inventoryColumns, apparatusType, toolsColumns.mQuality))); mAdapters.insert(std::make_pair( UniversalId::Type_Armor, new ArmorRefIdAdapter(enchantableColumns, armorType, health, armor, partRef))); mAdapters.insert( std::make_pair(UniversalId::Type_Book, new BookRefIdAdapter(enchantableColumns, bookType, skill, text))); mAdapters.insert(std::make_pair( UniversalId::Type_Clothing, new ClothingRefIdAdapter(enchantableColumns, clothingType, partRef))); mAdapters.insert(std::make_pair(UniversalId::Type_Container, new ContainerRefIdAdapter(nameColumns, weightCapacity, organic, respawn, content))); mAdapters.insert(std::make_pair(UniversalId::Type_Creature, new CreatureRefIdAdapter(creatureColumns))); mAdapters.insert(std::make_pair(UniversalId::Type_Door, new DoorRefIdAdapter(nameColumns, openSound, closeSound))); mAdapters.insert(std::make_pair(UniversalId::Type_Ingredient, new IngredientRefIdAdapter(ingredientColumns))); mAdapters.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, new LevelledListRefIdAdapter<ESM::CreatureLevList>( UniversalId::Type_CreatureLevelledList, creatureLevListColumns))); mAdapters.insert(std::make_pair(UniversalId::Type_ItemLevelledList, new LevelledListRefIdAdapter<ESM::ItemLevList>(UniversalId::Type_ItemLevelledList, itemLevListColumns))); mAdapters.insert(std::make_pair(UniversalId::Type_Light, new LightRefIdAdapter(lightColumns))); mAdapters.insert(std::make_pair( UniversalId::Type_Lockpick, new ToolRefIdAdapter<ESM::Lockpick>(UniversalId::Type_Lockpick, toolsColumns))); mAdapters.insert(std::make_pair(UniversalId::Type_Miscellaneous, new MiscRefIdAdapter(inventoryColumns, key))); mAdapters.insert(std::make_pair(UniversalId::Type_Npc, new NpcRefIdAdapter(npcColumns))); mAdapters.insert(std::make_pair( UniversalId::Type_Probe, new ToolRefIdAdapter<ESM::Probe>(UniversalId::Type_Probe, toolsColumns))); mAdapters.insert(std::make_pair( UniversalId::Type_Repair, new ToolRefIdAdapter<ESM::Repair>(UniversalId::Type_Repair, toolsColumns))); mAdapters.insert(std::make_pair( UniversalId::Type_Static, new ModelRefIdAdapter<ESM::Static>(UniversalId::Type_Static, modelColumns))); mAdapters.insert(std::make_pair(UniversalId::Type_Weapon, new WeaponRefIdAdapter(weaponColumns)));}
CSMWorld::RefIdCollection::~RefIdCollection(){ for (std::map<UniversalId::Type, RefIdAdapter*>::iterator iter(mAdapters.begin()); iter != mAdapters.end(); ++iter) delete iter->second;
for (std::vector<std::pair<const ColumnBase*, std::map<UniversalId::Type, NestedRefIdAdapterBase*>>>::iterator iter( mNestedAdapters.begin()); iter != mNestedAdapters.end(); ++iter) { for (std::map<UniversalId::Type, NestedRefIdAdapterBase*>::iterator it((iter->second).begin()); it != (iter->second).end(); ++it) delete it->second; }}
int CSMWorld::RefIdCollection::getSize() const{ return mData.getSize();}
ESM::RefId CSMWorld::RefIdCollection::getId(int index) const{ return ESM::RefId::stringRefId(getData(index, 0).toString().toUtf8().constData());}
int CSMWorld::RefIdCollection::getIndex(const ESM::RefId& id) const{ int index = searchId(id);
if (index == -1) throw std::runtime_error("ID is not found in RefId collection: " + id.toDebugString());
return index;}
int CSMWorld::RefIdCollection::getColumns() const{ return static_cast<int>(mColumns.size());}
const CSMWorld::ColumnBase& CSMWorld::RefIdCollection::getColumn(int column) const{ return mColumns.at(column);}
QVariant CSMWorld::RefIdCollection::getData(int index, int column) const{ RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(index);
const RefIdAdapter& adaptor = findAdapter(localIndex.second);
return adaptor.getData(&mColumns.at(column), mData, localIndex.first);}
QVariant CSMWorld::RefIdCollection::getNestedData(int row, int column, int subRow, int subColumn) const{ RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
return nestedAdapter.getNestedData(&mColumns.at(column), mData, localIndex.first, subRow, subColumn);}
void CSMWorld::RefIdCollection::setData(int index, int column, const QVariant& data){ RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(index);
const RefIdAdapter& adaptor = findAdapter(localIndex.second);
adaptor.setData(&mColumns.at(column), mData, localIndex.first, data);}
void CSMWorld::RefIdCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn){ RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
nestedAdapter.setNestedData(&mColumns.at(column), mData, localIndex.first, data, subRow, subColumn);}
void CSMWorld::RefIdCollection::removeRows(int index, int count){ mData.erase(index, count);}
void CSMWorld::RefIdCollection::removeNestedRows(int row, int column, int subRow){ RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
nestedAdapter.removeNestedRow(&mColumns.at(column), mData, localIndex.first, subRow);}
void CSMWorld::RefIdCollection::appendBlankRecord(const ESM::RefId& id, UniversalId::Type type){ mData.appendRecord(type, id, false);}
int CSMWorld::RefIdCollection::searchId(const ESM::RefId& id) const{ const RefIdData::LocalIndex localIndex = mData.searchId(id);
if (localIndex.first == -1) return -1;
return mData.localToGlobalIndex(localIndex);}
void CSMWorld::RefIdCollection::replace(int index, std::unique_ptr<RecordBase> record){ mData.getRecord(mData.globalToLocalIndex(index)).assign(*record.release());}
void CSMWorld::RefIdCollection::cloneRecord( const ESM::RefId& origin, const ESM::RefId& destination, const CSMWorld::UniversalId::Type type){ std::unique_ptr<RecordBase> newRecord = mData.getRecord(mData.searchId(origin)).modifiedCopy(); auto adapter = mAdapters.find(type); assert(adapter != mAdapters.end()); adapter->second->setId(*newRecord, destination.getRefIdString()); mData.insertRecord(std::move(newRecord), type, destination);}
bool CSMWorld::RefIdCollection::touchRecord(const ESM::RefId& id){ throw std::runtime_error("RefIdCollection::touchRecord is unimplemented");}
void CSMWorld::RefIdCollection::appendRecord(std::unique_ptr<RecordBase> record, UniversalId::Type type){ auto id = findAdapter(type).getId(*record.get());
int index = mData.getAppendIndex(type);
mData.appendRecord(type, id, false);
mData.getRecord(mData.globalToLocalIndex(index)).assign(*record.release());}
const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord(const ESM::RefId& id) const{ return mData.getRecord(mData.searchId(id));}
const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord(int index) const{ return mData.getRecord(mData.globalToLocalIndex(index));}
void CSMWorld::RefIdCollection::load(ESM::ESMReader& reader, bool base, UniversalId::Type type){ mData.load(reader, base, type);}
int CSMWorld::RefIdCollection::getAppendIndex(const ESM::RefId& id, UniversalId::Type type) const{ return mData.getAppendIndex(type);}
std::vector<ESM::RefId> CSMWorld::RefIdCollection::getIds(bool listDeleted) const{ return mData.getIds(listDeleted);}
bool CSMWorld::RefIdCollection::reorderRows(int baseIndex, const std::vector<int>& newOrder){ return false;}
void CSMWorld::RefIdCollection::save(int index, ESM::ESMWriter& writer) const{ mData.save(index, writer);}
const CSMWorld::RefIdData& CSMWorld::RefIdCollection::getDataSet() const{ return mData;}
int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const{ RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
return nestedAdapter.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first);}
int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const{ RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
return nestedAdapter.getNestedColumnsCount(&mColumns.at(column), mData);}
CSMWorld::NestableColumn* CSMWorld::RefIdCollection::getNestableColumn(int column){ return &mColumns.at(column);}
void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position){ RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(col), localIndex.second);
nestedAdapter.addNestedRow(&mColumns.at(col), mData, localIndex.first, position);}
void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable){ RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
nestedAdapter.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable);}
CSMWorld::NestedTableWrapperBase* CSMWorld::RefIdCollection::nestedTable(int row, int column) const{ RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
return nestedAdapter.nestedTable(&mColumns.at(column), mData, localIndex.first);}
const CSMWorld::NestedRefIdAdapterBase& CSMWorld::RefIdCollection::getNestedAdapter( const CSMWorld::ColumnBase& column, UniversalId::Type type) const{ for (std::vector<std::pair<const ColumnBase*, std::map<UniversalId::Type, NestedRefIdAdapterBase*>>>::const_iterator iter(mNestedAdapters.begin()); iter != mNestedAdapters.end(); ++iter) { if ((iter->first) == &column) { std::map<UniversalId::Type, NestedRefIdAdapterBase*>::const_iterator it = (iter->second).find(type);
if (it == (iter->second).end()) throw std::runtime_error("No such type in the nestedadapters");
return *it->second; } } throw std::runtime_error("No such column in the nestedadapters");}
void CSMWorld::RefIdCollection::copyTo(int index, RefIdCollection& target) const{ mData.copyTo(index, target.mData);}