forked from mirror/openmw-tes3mp
Issue #219: implemented rank requirement filter
This commit is contained in:
parent
75f64aa38b
commit
77ba8c5117
6 changed files with 115 additions and 3 deletions
|
@ -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…
Reference in a new issue