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:
|
case SelectWrapper::Function_PcCrimeLevel:
|
||||||
|
|
||||||
return MWWorld::Class::get (player).getNpcStats (player).getBounty();
|
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:
|
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)
|
MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer)
|
||||||
: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
|
: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -36,6 +36,14 @@ namespace MWDialogue
|
||||||
|
|
||||||
bool getSelectStructBoolean (const SelectWrapper& select) const;
|
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:
|
public:
|
||||||
|
|
||||||
Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);
|
Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);
|
||||||
|
|
|
@ -61,7 +61,9 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction()
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
// 0-5
|
// 0, 1
|
||||||
|
case 2: return Function_RankRequirement;
|
||||||
|
// 3-5
|
||||||
case 6: return Function_PcLevel;
|
case 6: return Function_PcLevel;
|
||||||
case 7: return Function_PcHealthPercent;
|
case 7: return Function_PcHealthPercent;
|
||||||
case 8: case 9: return Function_PcDynamicStat;
|
case 8: case 9: return Function_PcDynamicStat;
|
||||||
|
@ -76,6 +78,7 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction()
|
||||||
// 42
|
// 42
|
||||||
case 42: return Function_PcClothingModifier;
|
case 42: return Function_PcClothingModifier;
|
||||||
case 43: return Function_PcCrimeLevel;
|
case 43: return Function_PcCrimeLevel;
|
||||||
|
// 44-45
|
||||||
case 46: return Function_SameFaction;
|
case 46: return Function_SameFaction;
|
||||||
// 47-49
|
// 47-49
|
||||||
case 50: return Function_Choice;
|
case 50: return Function_Choice;
|
||||||
|
@ -196,6 +199,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
|
||||||
Function_FriendlyHit,
|
Function_FriendlyHit,
|
||||||
Function_PcLevel, Function_PcGender, Function_PcClothingModifier,
|
Function_PcLevel, Function_PcGender, Function_PcClothingModifier,
|
||||||
Function_PcCrimeLevel,
|
Function_PcCrimeLevel,
|
||||||
|
Function_RankRequirement,
|
||||||
Function_None // end marker
|
Function_None // end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -250,7 +254,8 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const
|
||||||
Function_PcSkill,
|
Function_PcSkill,
|
||||||
Function_PcExpelled,
|
Function_PcExpelled,
|
||||||
Function_PcVampire,
|
Function_PcVampire,
|
||||||
Function_PcCrimeLevel,
|
Function_PcCrimeLevel,
|
||||||
|
Function_RankRequirement,
|
||||||
Function_None // end marker
|
Function_None // end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@ namespace MWDialogue
|
||||||
Function_FriendlyHit,
|
Function_FriendlyHit,
|
||||||
Function_TalkedToPc,
|
Function_TalkedToPc,
|
||||||
Function_PcLevel, Function_PcHealthPercent, Function_PcDynamicStat,
|
Function_PcLevel, Function_PcHealthPercent, Function_PcDynamicStat,
|
||||||
Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel
|
Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel,
|
||||||
|
Function_RankRequirement
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
|
|
|
@ -3,12 +3,15 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
#include <components/esm/loadskil.hpp>
|
#include <components/esm/loadskil.hpp>
|
||||||
#include <components/esm/loadclas.hpp>
|
#include <components/esm/loadclas.hpp>
|
||||||
#include <components/esm/loadgmst.hpp>
|
#include <components/esm/loadgmst.hpp>
|
||||||
|
#include <components/esm/loadfact.hpp>
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
|
@ -309,3 +312,28 @@ void MWMechanics::NpcStats::setReputation(int reputation)
|
||||||
mReputation = 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;
|
bool isVampire() const;
|
||||||
|
|
||||||
void setVampire (bool set);
|
void setVampire (bool set);
|
||||||
|
|
||||||
|
bool hasSkillsForRank (const std::string& factionId, int rank) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue