Issue #219: implemented rank requirement filter

actorid
Marc Zinnschlag 12 years ago
parent 75f64aa38b
commit 77ba8c5117

@ -300,6 +300,30 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
case SelectWrapper::Function_PcCrimeLevel:
return MWWorld::Class::get (player).getNpcStats (player).getBounty();
case SelectWrapper::Function_RankRequirement:
{
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return 0;
std::string faction =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
int rank = getFactionRank (player, faction);
if (rank>=9)
return 0; // max rank
int result = 0;
if (hasFactionRankSkillRequirements (player, faction, rank+1))
result += 1;
if (hasFactionRankReputationRequirements (player, faction, rank+1))
result += 2;
return result;
}
default:
@ -382,6 +406,50 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
}
}
int MWDialogue::Filter::getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const
{
MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor);
std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find (factionId);
if (iter==stats.getFactionRanks().end())
return -1;
return iter->second;
}
bool MWDialogue::Filter::hasFactionRankSkillRequirements (const MWWorld::Ptr& actor,
const std::string& factionId, int rank) const
{
if (rank<0 || rank>=10)
throw std::runtime_error ("rank index out of range");
if (!MWWorld::Class::get (actor).getNpcStats (actor).hasSkillsForRank (factionId, rank))
return false;
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
MWMechanics::CreatureStats& stats = MWWorld::Class::get (actor).getCreatureStats (actor);
return stats.getAttribute (faction.mData.mAttribute1).getBase()>=faction.mData.mRankData[rank].mAttribute1 &&
stats.getAttribute (faction.mData.mAttribute2).getBase()>=faction.mData.mRankData[rank].mAttribute2;
}
bool MWDialogue::Filter::hasFactionRankReputationRequirements (const MWWorld::Ptr& actor,
const std::string& factionId, int rank) const
{
if (rank<0 || rank>=10)
throw std::runtime_error ("rank index out of range");
MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor);
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
return stats.getFactionReputation (factionId)>=faction.mData.mRankData[rank].mFactReaction;
}
MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer)
: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
{}

@ -36,6 +36,14 @@ namespace MWDialogue
bool getSelectStructBoolean (const SelectWrapper& select) const;
int getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const;
bool hasFactionRankSkillRequirements (const MWWorld::Ptr& actor, const std::string& factionId,
int rank) const;
bool hasFactionRankReputationRequirements (const MWWorld::Ptr& actor, const std::string& factionId,
int rank) const;
public:
Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);

@ -61,7 +61,9 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction()
switch (index)
{
// 0-5
// 0, 1
case 2: return Function_RankRequirement;
// 3-5
case 6: return Function_PcLevel;
case 7: return Function_PcHealthPercent;
case 8: case 9: return Function_PcDynamicStat;
@ -76,6 +78,7 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction()
// 42
case 42: return Function_PcClothingModifier;
case 43: return Function_PcCrimeLevel;
// 44-45
case 46: return Function_SameFaction;
// 47-49
case 50: return Function_Choice;
@ -196,6 +199,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
Function_FriendlyHit,
Function_PcLevel, Function_PcGender, Function_PcClothingModifier,
Function_PcCrimeLevel,
Function_RankRequirement,
Function_None // end marker
};
@ -250,7 +254,8 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const
Function_PcSkill,
Function_PcExpelled,
Function_PcVampire,
Function_PcCrimeLevel,
Function_PcCrimeLevel,
Function_RankRequirement,
Function_None // end marker
};

@ -34,7 +34,8 @@ namespace MWDialogue
Function_FriendlyHit,
Function_TalkedToPc,
Function_PcLevel, Function_PcHealthPercent, Function_PcDynamicStat,
Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel
Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel,
Function_RankRequirement
};
enum Type

@ -3,12 +3,15 @@
#include <cmath>
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <boost/format.hpp>
#include <components/esm/loadskil.hpp>
#include <components/esm/loadclas.hpp>
#include <components/esm/loadgmst.hpp>
#include <components/esm/loadfact.hpp>
#include "../mwworld/esmstore.hpp"
@ -309,3 +312,28 @@ void MWMechanics::NpcStats::setReputation(int reputation)
mReputation = reputation;
}
bool MWMechanics::NpcStats::hasSkillsForRank (const std::string& factionId, int rank) const
{
if (rank<0 || rank>=10)
throw std::runtime_error ("rank index out of range");
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
std::vector<int> skills;
for (int i=0; i<6; ++i)
skills.push_back (static_cast<int> (getSkill (faction.mData.mSkillID[i]).getModified()));
std::sort (skills.begin(), skills.end());
std::vector<int>::const_reverse_iterator iter = skills.rbegin();
const ESM::RankData& rankData = faction.mData.mRankData[rank];
if (*iter<rankData.mSkill1)
return false;
return *++iter>=rankData.mSkill2;
}

@ -123,6 +123,8 @@ namespace MWMechanics
bool isVampire() const;
void setVampire (bool set);
bool hasSkillsForRank (const std::string& factionId, int rank) const;
};
}

Loading…
Cancel
Save