mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-22 04:09:45 +00:00
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 DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const
|
||||||
{
|
{
|
||||||
bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
|
// check DATAstruct
|
||||||
|
|
||||||
// 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
|
|
||||||
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.mSelects.begin());
|
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.mSelects.begin());
|
||||||
iter != info.mSelects.end(); ++iter)
|
iter != info.mSelects.end(); ++iter)
|
||||||
if (!isMatching (actor, *iter))
|
if (!isMatching (actor, *iter))
|
||||||
|
|
|
@ -1,10 +1,117 @@
|
||||||
|
|
||||||
#include "filter.hpp"
|
#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;
|
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;
|
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:
|
public:
|
||||||
|
|
||||||
Filter (const MWWorld::Ptr& actor);
|
Filter (const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
bool operator() (const ESM::DialInfo& dialogue);
|
bool operator() (const ESM::DialInfo& info) const;
|
||||||
///< \return does the dialogue match?
|
///< \return does the dialogue match?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,10 @@ struct DialInfo
|
||||||
{
|
{
|
||||||
int mUnknown1;
|
int mUnknown1;
|
||||||
int mDisposition;
|
int mDisposition;
|
||||||
char mRank; // Rank of NPC
|
signed char mRank; // Rank of NPC
|
||||||
char mGender; // See Gender enum
|
signed char mGender; // See Gender enum
|
||||||
char mPCrank; // Player rank
|
signed char mPCrank; // Player rank
|
||||||
char mUnknown2;
|
signed char mUnknown2;
|
||||||
}; // 12 bytes
|
}; // 12 bytes
|
||||||
DATAstruct mData;
|
DATAstruct mData;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue