Issue #219: moved checks for various dialogue info fields from DialogueManager to Filter

actorid
Marc Zinnschlag 12 years ago
parent 1502b3f6f8
commit 662054acf4

@ -482,101 +482,7 @@ namespace MWDialogue
bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const
{
bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
// actor id
if (!info.mActor.empty())
if (toLower (info.mActor)!=MWWorld::Class::get (actor).getId (actor))
return false;
//NPC race
if (!info.mRace.empty())
{
if (isCreature)
return false;
MWWorld::LiveCellRef<ESM::NPC> *cellRef = actor.get<ESM::NPC>();
if (!cellRef)
return false;
if (toLower (info.mRace)!=toLower (cellRef->mBase->mRace))
return false;
}
//NPC class
if (!info.mClass.empty())
{
if (isCreature)
return false;
MWWorld::LiveCellRef<ESM::NPC> *cellRef = actor.get<ESM::NPC>();
if (!cellRef)
return false;
if (toLower (info.mClass)!=toLower (cellRef->mBase->mClass))
return false;
}
//NPC faction
if (!info.mNpcFaction.empty())
{
if (isCreature)
return false;
//MWWorld::Class npcClass = MWWorld::Class::get(actor);
MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor);
std::map<std::string,int>::iterator it = stats.getFactionRanks().find(toLower(info.mNpcFaction));
if(it!=stats.getFactionRanks().end())
{
//check rank
if(it->second < (int)info.mData.mRank) return false;
}
else
{
//not in the faction
return false;
}
}
// TODO check player faction
if(!info.mPcFaction.empty())
{
MWMechanics::NpcStats stats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
std::map<std::string,int>::iterator it = stats.getFactionRanks().find(toLower(info.mPcFaction));
if(it!=stats.getFactionRanks().end())
{
//check rank
if(it->second < (int)info.mData.mPCrank) return false;
}
else
{
//not in the faction
return false;
}
}
//check gender
if (!isCreature)
{
MWWorld::LiveCellRef<ESM::NPC>* npc = actor.get<ESM::NPC>();
if(npc->mBase->mFlags & npc->mBase->Female)
{
if(static_cast<int> (info.mData.mGender)==0) return false;
}
else
{
if(static_cast<int> (info.mData.mGender)==1) return false;
}
}
// check cell
if (!info.mCell.empty())
if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mName != info.mCell)
return false;
// TODO check DATAstruct
// check DATAstruct
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.mSelects.begin());
iter != info.mSelects.end(); ++iter)
if (!isMatching (actor, *iter))

@ -1,10 +1,117 @@
#include "filter.hpp"
MWDialogue::Filter::Filter (const MWWorld::Ptr& actor) : mActor (actor) {}
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwmechanics/npcstats.hpp"
namespace
{
std::string toLower (const std::string& name)
{
std::string lowerCase;
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
return lowerCase;
}
}
bool MWDialogue::Filter::operator() (const ESM::DialInfo& dialogue)
bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
{
// actor id
if (!info.mActor.empty())
if (toLower (info.mActor)!=MWWorld::Class::get (mActor).getId (mActor))
return false;
bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name());
// NPC race
if (!info.mRace.empty())
{
if (isCreature)
return false;
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
if (toLower (info.mRace)!=toLower (cellRef->mBase->mRace))
return false;
}
// NPC class
if (!info.mClass.empty())
{
if (isCreature)
return false;
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
if (toLower (info.mClass)!=toLower (cellRef->mBase->mClass))
return false;
}
// NPC faction
if (!info.mNpcFaction.empty())
{
if (isCreature)
return false;
MWMechanics::NpcStats& stats = MWWorld::Class::get (mActor).getNpcStats (mActor);
std::map<std::string, int>::iterator iter = stats.getFactionRanks().find (toLower (info.mNpcFaction));
if (iter==stats.getFactionRanks().end())
return false;
// check rank
if (iter->second < info.mData.mRank)
return false;
}
// Gender
if (!isCreature)
{
MWWorld::LiveCellRef<ESM::NPC>* npc = mActor.get<ESM::NPC>();
if (info.mData.mGender==(npc->mBase->mFlags & npc->mBase->Female ? 0 : 1))
return false;
}
return true;
}
bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const
{
const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
// check player faction
if (!info.mPcFaction.empty())
{
MWMechanics::NpcStats& stats = MWWorld::Class::get (player).getNpcStats (player);
std::map<std::string,int>::iterator iter = stats.getFactionRanks().find (toLower (info.mPcFaction));
if(iter==stats.getFactionRanks().end())
return false;
// check rank
if (iter->second < info.mData.mPCrank)
return false;
}
// check cell
if (!info.mCell.empty())
if (toLower (player.getCell()->mCell->mName) != toLower (info.mCell))
return false;
return true;
}
MWDialogue::Filter::Filter (const MWWorld::Ptr& actor) : mActor (actor) {}
bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const
{
return testActor (info) && testPlayer (info);
}

@ -14,11 +14,17 @@ namespace MWDialogue
{
MWWorld::Ptr mActor;
bool testActor (const ESM::DialInfo& info) const;
///< Is this the right actor for this \a info?
bool testPlayer (const ESM::DialInfo& info) const;
///< Do the player and the cell the player is currently in match \a info?
public:
Filter (const MWWorld::Ptr& actor);
bool operator() (const ESM::DialInfo& dialogue);
bool operator() (const ESM::DialInfo& info) const;
///< \return does the dialogue match?
};
}

@ -32,10 +32,10 @@ struct DialInfo
{
int mUnknown1;
int mDisposition;
char mRank; // Rank of NPC
char mGender; // See Gender enum
char mPCrank; // Player rank
char mUnknown2;
signed char mRank; // Rank of NPC
signed char mGender; // See Gender enum
signed char mPCrank; // Player rank
signed char mUnknown2;
}; // 12 bytes
DATAstruct mData;

Loading…
Cancel
Save