mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-30 02:56:44 +00:00 
			
		
		
		
	Issue #219: implemented rank requirement filter
This commit is contained in:
		
							parent
							
								
									75f64aa38b
								
							
						
					
					
						commit
						77ba8c5117
					
				
					 6 changed files with 115 additions and 3 deletions
				
			
		|  | @ -301,6 +301,30 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con | ||||||
|          |          | ||||||
|             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: | ||||||
| 
 | 
 | ||||||
|             throw std::runtime_error ("unknown integer select function"); |             throw std::runtime_error ("unknown integer select function"); | ||||||
|  | @ -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
 | ||||||
|     }; |     }; | ||||||
|      |      | ||||||
|  | @ -251,6 +255,7 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const | ||||||
|         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