mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 10:26:41 +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(); | ||||
| 
 | ||||
|         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: | ||||
| 
 | ||||
|             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) | ||||
| : 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
 | ||||
|     }; | ||||
|      | ||||
|  | @ -251,6 +255,7 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const | |||
|         Function_PcExpelled, | ||||
|         Function_PcVampire, | ||||
|         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