forked from teamnwah/openmw-tes3coop
Issue #219: moved checks for various dialogue info fields from DialogueManager to Filter
This commit is contained in:
parent
1502b3f6f8
commit
662054acf4
4 changed files with 121 additions and 102 deletions
|
@ -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"
|
||||
|
||||
bool MWDialogue::Filter::operator() (const ESM::DialInfo& dialogue)
|
||||
#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::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…
Reference in a new issue