diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 8fc16af63..0885517f2 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1,6 +1,8 @@ #ifndef CSM_WOLRD_REFIDADAPTERIMP_H #define CSM_WOLRD_REFIDADAPTERIMP_H +#include + #include #include @@ -424,6 +426,106 @@ namespace CSMWorld InventoryRefIdAdapter::setData (column, data, index, value); } + struct ActorColumns : public NameColumns + { + const RefIdColumn *mHasAi; + const RefIdColumn *mHello; + const RefIdColumn *mFlee; + const RefIdColumn *mFight; + const RefIdColumn *mAlarm; + std::map mServices; + + ActorColumns (const NameColumns& base) : NameColumns (base) {} + }; + + /// \brief Adapter for actor IDs (handles common AI functionality) + template + class ActorRefIdAdapter : public NameRefIdAdapter + { + ActorColumns mActors; + + public: + + ActorRefIdAdapter (UniversalId::Type type, const ActorColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; + + template + ActorRefIdAdapter::ActorRefIdAdapter (UniversalId::Type type, + const ActorColumns& columns) + : NameRefIdAdapter (type, columns), mActors (columns) + {} + + template + QVariant ActorRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mActors.mHasAi) + return record.get().mHasAI!=0; + + if (column==mActors.mHello) + return record.get().mAiData.mHello; + + if (column==mActors.mFlee) + return record.get().mAiData.mFlee; + + if (column==mActors.mFight) + return record.get().mAiData.mFight; + + if (column==mActors.mAlarm) + return record.get().mAiData.mAlarm; + + std::map::const_iterator iter = + mActors.mServices.find (column); + + if (iter!=mActors.mServices.end()) + return (record.get().mAiData.mServices & iter->second)!=0; + + return NameRefIdAdapter::getData (column, data, index); + } + + template + void ActorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mActors.mHasAi) + record.get().mHasAI = value.toInt(); + else if (column==mActors.mHello) + record.get().mAiData.mHello = value.toInt(); + else if (column==mActors.mFlee) + record.get().mAiData.mFlee = value.toInt(); + else if (column==mActors.mFight) + record.get().mAiData.mFight = value.toInt(); + else if (column==mActors.mAlarm) + record.get().mAiData.mAlarm = value.toInt(); + else + { + typename std::map::const_iterator iter = + mActors.mServices.find (column); + if (iter!=mActors.mServices.end()) + { + if (value.toInt()!=0) + record.get().mAiData.mServices |= iter->second; + else + record.get().mAiData.mServices &= ~iter->second; + } + else + NameRefIdAdapter::setData (column, data, index, value); + } + } + class ApparatusRefIdAdapter : public InventoryRefIdAdapter { const RefIdColumn *mType; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 829576725..452f59d19 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -81,6 +81,52 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Uses", ColumnBase::Display_Integer)); toolsColumns.mUses = &mColumns.back(); + ActorColumns actorsColumns (nameColumns); + + mColumns.push_back (RefIdColumn ("AI", ColumnBase::Display_Boolean)); + actorsColumns.mHasAi = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Hello", ColumnBase::Display_Integer)); + actorsColumns.mHello = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Flee", ColumnBase::Display_Integer)); + actorsColumns.mFlee = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Fight", ColumnBase::Display_Integer)); + actorsColumns.mFight = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Alarm", ColumnBase::Display_Integer)); + actorsColumns.mAlarm = &mColumns.back(); + + static const struct + { + const char *mName; + unsigned int mFlag; + } sServiceTable[] = + { + { "Buys Weapons", ESM::NPC::Weapon}, + { "Buys Armor", ESM::NPC::Armor}, + { "Buys Clothing", ESM::NPC::Clothing}, + { "Buys Books", ESM::NPC::Books}, + { "Buys Ingredients", ESM::NPC::Ingredients}, + { "Buys Lockpicks", ESM::NPC::Picks}, + { "Buys Probes", ESM::NPC::Probes}, + { "Buys Lights", ESM::NPC::Lights}, + { "Buys Apparati", ESM::NPC::Apparatus}, + { "Buys Repair Items", ESM::NPC::RepairItem}, + { "Buys Misc Items", ESM::NPC::Misc}, + { "Buys Potions", ESM::NPC::Potions}, + { "Buys Magic Items", ESM::NPC::MagicItems}, + { "Sells Spells", ESM::NPC::Spells}, + { "Trainer", ESM::NPC::Training}, + { "Spellmaking", ESM::NPC::Spellmaking}, + { "Enchanting Service", ESM::NPC::Enchanting}, + { "Repair Serivce", ESM::NPC::Repair}, + { 0, 0 } + }; + + for (int i=0; sServiceTable[i].mName; ++i) + { + mColumns.push_back (RefIdColumn (sServiceTable[i].mName, ColumnBase::Display_Boolean)); + actorsColumns.mServices.insert (std::make_pair (&mColumns.back(), sServiceTable[i].mFlag)); + } + mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); const RefIdColumn *autoCalc = &mColumns.back(); @@ -102,7 +148,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Container, new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new NameRefIdAdapter (UniversalId::Type_Creature, nameColumns))); + new ActorRefIdAdapter (UniversalId::Type_Creature, actorsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, @@ -120,7 +166,7 @@ CSMWorld::RefIdCollection::RefIdCollection() new InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new NameRefIdAdapter (UniversalId::Type_Npc, nameColumns))); + new ActorRefIdAdapter (UniversalId::Type_Npc, actorsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, new ToolRefIdAdapter (UniversalId::Type_Probe, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair,