From 9669eed083f6e3346024fa1e122b56279aa5d1e8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 15 Nov 2012 20:00:27 +0100 Subject: [PATCH] Issue #219: added last missing function filters --- apps/openmw/mwdialogue/filter.cpp | 226 +++++++++++++++------- apps/openmw/mwdialogue/selectwrapper.cpp | 70 ++++--- apps/openmw/mwdialogue/selectwrapper.hpp | 36 ++-- apps/openmw/mwmechanics/creaturestats.cpp | 76 ++++++-- apps/openmw/mwmechanics/creaturestats.hpp | 35 +++- apps/openmw/mwmechanics/npcstats.cpp | 34 +++- apps/openmw/mwmechanics/npcstats.hpp | 28 ++- apps/openmw/mwworld/class.cpp | 5 + apps/openmw/mwworld/class.hpp | 5 + 9 files changed, 349 insertions(+), 166 deletions(-) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 21904b4bc..0deef7fd0 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -74,7 +74,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const if (iter==stats.getFactionRanks().end()) return false; - + // check rank if (iter->second < info.mData.mRank) return false; @@ -87,14 +87,14 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const if (info.mData.mGender==(npc->mBase->mFlags & npc->mBase->Female ? 0 : 1)) return false; } - + return true; } bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const { const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - + // check player faction if (!info.mPcFaction.empty()) { @@ -123,7 +123,7 @@ bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const iter != info.mSelects.end(); ++iter) if (!testSelectStruct (*iter)) return false; - + return true; } @@ -131,7 +131,7 @@ bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const { if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name()) return select.isInverted(); - + switch (select.getType()) { case SelectWrapper::Type_None: return true; @@ -139,7 +139,7 @@ bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const case SelectWrapper::Type_Numeric: return testSelectStructNumeric (select); case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select)); } - + return true; } @@ -148,11 +148,11 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c switch (select.getFunction()) { case SelectWrapper::Function_Global: - + // internally all globals are float :( return select.selectCompare ( MWBase::Environment::get().getWorld()->getGlobalVariable (select.getName()).mFloat); - + case SelectWrapper::Function_Local: { std::string scriptName = MWWorld::Class::get (mActor).getScript (mActor); @@ -178,7 +178,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c if (imData.mNumShorts) return select.selectCompare (static_cast (locals.mShorts[i])); - + i -= script->mData.mNumShorts; if (imData.mNumLongs) @@ -186,39 +186,39 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c i -= script->mData.mNumShorts; - return select.selectCompare (locals.mFloats.at (i)); + return select.selectCompare (locals.mFloats.at (i)); } - + case SelectWrapper::Function_PcHealthPercent: { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - - float ratio = MWWorld::Class::get (player).getCreatureStats (player).getHealth().getCurrent() / + + float ratio = MWWorld::Class::get (player).getCreatureStats (player).getHealth().getCurrent() / MWWorld::Class::get (player).getCreatureStats (player).getHealth().getModified(); - + return select.selectCompare (ratio); } - + case SelectWrapper::Function_PcDynamicStat: { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - + float value = MWWorld::Class::get (player).getCreatureStats (player). - getDynamic (select.getArgument()).getCurrent(); - + getDynamic (select.getArgument()).getCurrent(); + return select.selectCompare (value); } - + case SelectWrapper::Function_HealthPercent: { - float ratio = MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getCurrent() / + float ratio = MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getCurrent() / MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getModified(); - + return select.selectCompare (ratio); } default: - + throw std::runtime_error ("unknown numeric select function"); } } @@ -230,11 +230,11 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con switch (select.getFunction()) { case SelectWrapper::Function_Journal: - + return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName()); - - case SelectWrapper::Function_Item: - { + + case SelectWrapper::Function_Item: + { MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player); int sum = 0; @@ -244,39 +244,39 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) if (toLower(iter->getCellRef().mRefID) == name) sum += iter->getRefData().getCount(); - + return sum; } case SelectWrapper::Function_Dead: return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName()); - + case SelectWrapper::Function_Choice: - + return mChoice; - + case SelectWrapper::Function_AiSetting: - + return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (select.getArgument()); - + case SelectWrapper::Function_PcAttribute: - + return MWWorld::Class::get (player).getCreatureStats (player). getAttribute (select.getArgument()).getModified(); case SelectWrapper::Function_PcSkill: - + return static_cast (MWWorld::Class::get (player). getNpcStats (player).getSkill (select.getArgument()).getModified()); - + case SelectWrapper::Function_FriendlyHit: { int hits = MWWorld::Class::get (mActor).getCreatureStats (mActor).getFriendlyHits(); - return hits>4 ? 4 : hits; + return hits>4 ? 4 : hits; } - + case SelectWrapper::Function_PcLevel: return MWWorld::Class::get (player).getCreatureStats (player).getLevel(); @@ -284,26 +284,26 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con case SelectWrapper::Function_PcGender: return player.get()->mBase->mFlags & ESM::NPC::Female ? 0 : 1; - + case SelectWrapper::Function_PcClothingModifier: { MWWorld::InventoryStore& store = MWWorld::Class::get (player).getInventoryStore (player); int value = 0; - + for (int i=0; i<=15; ++i) // everything except thigns held in hands and amunition { MWWorld::ContainerStoreIterator slot = store.getSlot (i); - + if (slot!=store.end()) value += MWWorld::Class::get (*slot).getValue (*slot); } - + return value; } - + case SelectWrapper::Function_PcCrimeLevel: - + return MWWorld::Class::get (player).getNpcStats (player).getBounty(); case SelectWrapper::Function_RankRequirement: @@ -313,12 +313,12 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con 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)) @@ -328,16 +328,68 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con result += 2; return result; - } - + } + case SelectWrapper::Function_Level: - + return MWWorld::Class::get (mActor).getCreatureStats (mActor).getLevel(); - + case SelectWrapper::Function_PCReputation: - - return MWWorld::Class::get (player).getNpcStats (player).getReputation(); - + + return MWWorld::Class::get (player).getNpcStats (player).getReputation(); + + case SelectWrapper::Function_Weather: + + return MWBase::Environment::get().getWorld()->getCurrentWeather(); + + case SelectWrapper::Function_Reputation: + + return MWWorld::Class::get (mActor).getNpcStats (mActor).getReputation(); + + case SelectWrapper::Function_FactionRankDiff: + { + if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty()) + return 0; + + std::pair faction = + *MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin(); + + int rank = getFactionRank (player, faction.first); + + return rank-faction.second; + } + + case SelectWrapper::Function_WerewolfKills: + + return MWWorld::Class::get (player).getNpcStats (player).getWerewolfKills(); + + case SelectWrapper::Function_RankLow: + case SelectWrapper::Function_RankHigh: + { + bool low = select.getFunction()==SelectWrapper::Function_RankLow; + + if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty()) + return 0; + + std::string factionId = + MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first; + + int value = 0; + + const ESM::Faction& faction = + *MWBase::Environment::get().getWorld()->getStore().get().find (factionId); + + MWMechanics::NpcStats& playerStats = MWWorld::Class::get (player).getNpcStats (player); + + for (std::vector::const_iterator iter (faction.mReactions.begin()); + iter!=faction.mReactions.end(); ++iter) + if (playerStats.getFactionRanks().find (iter->mFaction)!=playerStats.getFactionRanks().end()) + if (low ? iter->mReactionmReaction>value) + value = iter->mReaction; + + return value; + } + default: throw std::runtime_error ("unknown integer select function"); @@ -351,13 +403,13 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co switch (select.getFunction()) { case SelectWrapper::Function_False: - + return false; - + case SelectWrapper::Function_Id: - + return select.getName()==toLower (MWWorld::Class::get (mActor).getId (mActor)); - + case SelectWrapper::Function_Faction: return toLower (mActor.get()->mBase->mFaction)==select.getName(); @@ -371,9 +423,9 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co return toLower (mActor.get()->mBase->mRace)==select.getName(); case SelectWrapper::Function_Cell: - + return toLower (mActor.getCell()->mCell->mName)==select.getName(); - + case SelectWrapper::Function_SameGender: return (player.get()->mBase->mFlags & ESM::NPC::Female)== @@ -383,46 +435,70 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co return toLower (mActor.get()->mBase->mRace)!= toLower (player.get()->mBase->mRace); - + case SelectWrapper::Function_SameFaction: return MWWorld::Class::get (mActor).getNpcStats (mActor).isSameFaction ( MWWorld::Class::get (player).getNpcStats (player)); - + case SelectWrapper::Function_PcCommonDisease: return MWWorld::Class::get (player).getCreatureStats (player).hasCommonDisease(); - + case SelectWrapper::Function_PcBlightDisease: return MWWorld::Class::get (player).getCreatureStats (player).hasBlightDisease(); - + case SelectWrapper::Function_PcCorprus: - + return MWWorld::Class::get (player).getCreatureStats (player). getMagicEffects().get (132).mMagnitude!=0; - + case SelectWrapper::Function_PcExpelled: { if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty()) return false; - + std::string faction = MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first; - + std::set& expelled = MWWorld::Class::get (player).getNpcStats (player).getExpelled(); - + return expelled.find (faction)!=expelled.end(); } - + case SelectWrapper::Function_PcVampire: - + return MWWorld::Class::get (player).getNpcStats (player).isVampire(); - + case SelectWrapper::Function_TalkedToPc: - + return mTalkedToPlayer; + case SelectWrapper::Function_Alarmed: + + return MWWorld::Class::get (mActor).getCreatureStats (mActor).isAlarmed(); + + case SelectWrapper::Function_Detected: + + return MWWorld::Class::get (mActor).hasDetected (mActor, player); + + case SelectWrapper::Function_Attacked: + + return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAttacked(); + + case SelectWrapper::Function_ShouldAttack: + + return MWWorld::Class::get (mActor).getCreatureStats (mActor).isHostile(); + + case SelectWrapper::Function_CreatureTargetted: + + return MWWorld::Class::get (mActor).getCreatureStats (mActor).getCreatureTargetted(); + + case SelectWrapper::Function_PCWerewolf: + + return MWWorld::Class::get (player).getNpcStats (player).isWerewolf(); + default: throw std::runtime_error ("unknown boolean select function"); @@ -432,12 +508,12 @@ 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::const_iterator iter = stats.getFactionRanks().find (factionId); - + if (iter==stats.getFactionRanks().end()) return -1; - + return iter->second; } diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index ae5b8c582..bba17bfd1 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -34,7 +34,7 @@ namespace throw std::runtime_error ("unknown compare type in dialogue info select"); } - + template bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1) { @@ -49,21 +49,22 @@ namespace } else throw std::runtime_error ( - "unsupported variable type in dialogue info select"); + "unsupported variable type in dialogue info select"); } } MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() const { int index = 0; - + std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index; switch (index) { - // 0, 1 + case 0: return Function_RankLow; + case 1: return Function_RankHigh; case 2: return Function_RankRequirement; - // 3 + case 3: return Function_Reputation; case 4: return Function_HealthPercent; case 5: return Function_PCReputation; case 6: return Function_PcLevel; @@ -82,22 +83,26 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() case 44: return Function_SameGender; case 45: return Function_SameRace; case 46: return Function_SameFaction; - // 47-49 + case 47: return Function_FactionRankDiff; + case 48: return Function_Detected; + case 49: return Function_Alarmed; case 50: return Function_Choice; case 51: case 52: case 53: case 54: case 55: case 56: case 57: return Function_PcAttribute; case 58: return Function_PcCorprus; - // 59 + case 59: return Function_Weather; case 60: return Function_PcVampire; case 61: return Function_Level; - // 62 + case 62: return Function_Attacked; case 63: return Function_TalkedToPc; case 64: return Function_PcDynamicStat; - // 65 + case 65: return Function_CreatureTargetted; case 66: return Function_FriendlyHit; case 67: case 68: case 69: case 70: return Function_AiSetting; - // 71 + case 71: return Function_ShouldAttack; + case 72: return Function_PCWerewolf; + case 73: return Function_WerewolfKills; } - + return Function_False; } @@ -130,11 +135,11 @@ int MWDialogue::SelectWrapper::getArgument() const { if (mSelect.mSelectRule[1]!='1') return 0; - + int index = 0; - + std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index; - + switch (index) { // AI settings @@ -142,7 +147,7 @@ int MWDialogue::SelectWrapper::getArgument() const case 68: return 0; case 69: return 3; case 70: return 2; - + // attributes case 10: return 0; case 51: return 1; @@ -152,7 +157,7 @@ int MWDialogue::SelectWrapper::getArgument() const case 55: return 5; case 56: return 6; case 57: return 7; - + // skills case 11: return 0; case 12: return 1; @@ -181,13 +186,13 @@ int MWDialogue::SelectWrapper::getArgument() const case 35: return 24; case 36: return 25; case 37: return 26; - + // dynamic stats case 8: return 1; case 9: return 2; case 64: return 0; } - + return 0; } @@ -204,17 +209,21 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const Function_PcCrimeLevel, Function_RankRequirement, Function_Level, Function_PCReputation, + Function_Weather, + Function_Reputation, Function_FactionRankDiff, + Function_WerewolfKills, + Function_RankLow, Function_RankHigh, Function_None // end marker }; - + static const Function numericFunctions[] = { Function_Global, Function_Local, Function_PcDynamicStat, Function_PcHealthPercent, Function_HealthPercent, Function_None // end marker - }; - + }; + static const Function booleanFunctions[] = { Function_False, @@ -223,15 +232,19 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, Function_PcExpelled, Function_PcVampire, Function_TalkedToPc, + Function_Alarmed, Function_Detected, + Function_Attacked, Function_ShouldAttack, + Function_CreatureTargetted, + Function_PCWerewolf, Function_None // end marker - }; - + }; + Function function = getFunction(); for (int i=0; integerFunctions[i]!=Function_None; ++i) if (integerFunctions[i]==function) return Type_Integer; - + for (int i=0; numericFunctions[i]!=Function_None; ++i) if (numericFunctions[i]==function) return Type_Numeric; @@ -239,7 +252,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const for (int i=0; booleanFunctions[i]!=Function_None; ++i) if (booleanFunctions[i]==function) return Type_Boolean; - + return Type_None; } @@ -261,15 +274,18 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const Function_PcVampire, Function_PcCrimeLevel, Function_RankRequirement, + Function_Reputation, Function_FactionRankDiff, + Function_PCWerewolf, Function_WerewolfKills, + Function_RankLow, Function_RankHigh, Function_None // end marker }; Function function = getFunction(); - + for (int i=0; functions[i]!=Function_None; ++i) if (functions[i]==function) return true; - + return false; } diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 15cd5bfff..b77ed7985 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -8,9 +8,9 @@ namespace MWDialogue class SelectWrapper { const ESM::DialInfo::SelectStruct& mSelect; - + public: - + enum Function { Function_None, Function_False, @@ -36,7 +36,13 @@ namespace MWDialogue Function_PcLevel, Function_PcHealthPercent, Function_PcDynamicStat, Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel, Function_RankRequirement, - Function_HealthPercent, Function_Level, Function_PCReputation + Function_HealthPercent, Function_Level, Function_PCReputation, + Function_Weather, + Function_Reputation, Function_Alarmed, Function_FactionRankDiff, Function_Detected, + Function_Attacked, Function_ShouldAttack, + Function_CreatureTargetted, + Function_PCWerewolf, Function_WerewolfKills, + Function_RankLow, Function_RankHigh }; enum Type @@ -46,32 +52,32 @@ namespace MWDialogue Type_Numeric, Type_Boolean }; - + private: - + Function decodeFunction() const; - + public: - + SelectWrapper (const ESM::DialInfo::SelectStruct& select); - + Function getFunction() const; - + int getArgument() const; - + Type getType() const; - + bool isInverted() const; - + bool isNpcOnly() const; ///< \attention Do not call any of the select functions for this select struct! - + bool selectCompare (int value) const; bool selectCompare (float value) const; - + bool selectCompare (bool value) const; - + std::string getName() const; ///< Return case-smashed name. }; diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 9ee7ca7c2..4be5d55b2 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -8,9 +8,10 @@ #include "../mwbase/world.hpp" namespace MWMechanics -{ +{ CreatureStats::CreatureStats() - : mLevel (0), mLevelHealthBonus(0.f), mDead (false), mFriendlyHits (0), mTalkedTo (false) + : mLevel (0), mLevelHealthBonus(0.f), mDead (false), mFriendlyHits (0), mTalkedTo (false), mAlarmed (false), + mAttacked (false), mHostile (false) { for (int i=0; i<4; ++i) mAiSettings[i] = 0; @@ -30,26 +31,26 @@ namespace MWMechanics { return mAiSequence; } - + AiSequence& CreatureStats::getAiSequence() { - return mAiSequence; + return mAiSequence; } - - float CreatureStats::getFatigueTerm() const + + float CreatureStats::getFatigueTerm() const { int max = getFatigue().getModified(); int current = getFatigue().getCurrent(); - + float normalised = max==0 ? 1 : std::max (0.0f, static_cast (current)/max); const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - + return gmst.find ("fFatigueBase")->getFloat() - gmst.find ("fFatigueMult")->getFloat() * (1-normalised); } - + const Stat &CreatureStats::getAttribute(int index) const { if (index < 0 || index > 7) { @@ -92,13 +93,13 @@ namespace MWMechanics { return mLevel; } - + int CreatureStats::getAiSetting (int index) const { assert (index>=0 && index<4); return mAiSettings[index]; } - + Stat &CreatureStats::getAttribute(int index) { if (index < 0 || index > 7) { @@ -168,7 +169,7 @@ namespace MWMechanics if (index==0 && mDynamic[index].getCurrent()<1) mDead = true; } - + void CreatureStats::setLevel(int level) { mLevel = level; @@ -189,24 +190,24 @@ namespace MWMechanics assert (index>=0 && index<4); mAiSettings[index] = value; } - + bool CreatureStats::isDead() const { return mDead; } - + void CreatureStats::resurrect() { if (mDead) { if (mDynamic[0].getCurrent()<1) mDynamic[0].setCurrent (1); - + if (mDynamic[0].getCurrent()>=1) mDead = false; } } - + bool CreatureStats::hasCommonDisease() const { return mSpells.hasCommonDisease(); @@ -216,24 +217,59 @@ namespace MWMechanics { return mSpells.hasBlightDisease(); } - + int CreatureStats::getFriendlyHits() const { return mFriendlyHits; } - + void CreatureStats::friendlyHit() { ++mFriendlyHits; } - + bool CreatureStats::hasTalkedToPlayer() const { return mTalkedTo; } - + void CreatureStats::talkedToPlayer() { mTalkedTo = true; } + + bool CreatureStats::isAlarmed() const + { + return mAlarmed; + } + + void CreatureStats::setAlarmed (bool alarmed) + { + mAlarmed = alarmed; + } + + bool CreatureStats::getAttacked() const + { + return mAttacked; + } + + void CreatureStats::setAttacked (bool attacked) + { + mAttacked = attacked; + } + + bool CreatureStats::isHostile() const + { + return mHostile; + } + + void CreatureStats::setHostile (bool hostile) + { + mHostile = hostile; + } + + bool CreatureStats::getCreatureTargetted() const + { + return false; + } } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 937cb61cc..3375c1af8 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -30,6 +30,9 @@ namespace MWMechanics bool mDead; int mFriendlyHits; bool mTalkedTo; + bool mAlarmed; + bool mAttacked; + bool mHostile; public: CreatureStats(); @@ -83,11 +86,11 @@ namespace MWMechanics void setAiSetting (int index, int value); ///< 0: hello, 1 fight, 2 flee, 3 alarm - + const AiSequence& getAiSequence() const; - + AiSequence& getAiSequence(); - + float getFatigueTerm() const; ///< Return effective fatigue @@ -96,23 +99,37 @@ namespace MWMechanics float getLevelHealthBonus() const; bool isDead() const; - + void resurrect(); - + bool hasCommonDisease() const; bool hasBlightDisease() const; - + int getFriendlyHits() const; ///< Number of friendly hits received. - + void friendlyHit(); ///< Increase number of friendly hits by one. - + bool hasTalkedToPlayer() const; ///< Has this creature talked with the player before? - + void talkedToPlayer(); + + bool isAlarmed() const; + + void setAlarmed (bool alarmed); + + bool getAttacked() const; + + void setAttacked (bool attacked); + + bool isHostile() const; + + void setHostile (bool hostile); + + bool getCreatureTargetted() const; }; } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 26415b631..20a0360e7 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -22,7 +22,7 @@ MWMechanics::NpcStats::NpcStats() : mMovementFlags (0), mDrawState (DrawState_Nothing), mBounty (0) -, mLevelProgress(0), mDisposition(0), mVampire (0), mReputation(0) +, mLevelProgress(0), mDisposition(0), mVampire (0), mReputation(0), mWerewolf (false), mWerewolfKills (0) { mSkillIncreases.resize (ESM::Attribute::Length); for (int i=0; ifirst)!=npcStats.mFactionRank.end()) return true; - + return false; } @@ -280,10 +280,10 @@ void MWMechanics::NpcStats::setBounty (int bounty) int MWMechanics::NpcStats::getFactionReputation (const std::string& faction) const { std::map::const_iterator iter = mFactionReputation.find (faction); - + if (iter==mFactionReputation.end()) return 0; - + return iter->second; } @@ -321,19 +321,33 @@ bool MWMechanics::NpcStats::hasSkillsForRank (const std::string& factionId, int *MWBase::Environment::get().getWorld()->getStore().get().find (factionId); std::vector skills; - + for (int i=0; i<6; ++i) skills.push_back (static_cast (getSkill (faction.mData.mSkillID[i]).getModified())); - + std::sort (skills.begin(), skills.end()); - + std::vector::const_reverse_iterator iter = skills.rbegin(); - + const ESM::RankData& rankData = faction.mData.mRankData[rank]; - + if (*iter=rankData.mSkill2; } +bool MWMechanics::NpcStats::isWerewolf() const +{ + return mWerewolf; +} + +void MWMechanics::NpcStats::setWerewolf (bool set) +{ + mWerewolf = set; +} + +int MWMechanics::NpcStats::getWerewolfKills() const +{ + return mWerewolfKills; +} \ No newline at end of file diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 46af216d9..af32bd294 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -51,6 +51,8 @@ namespace MWMechanics std::map mFactionReputation; bool mVampire; int mReputation; + bool mWerewolf; + int mWerewolfKills; int mLevelProgress; // 0-10 @@ -83,7 +85,7 @@ namespace MWMechanics Stat& getSkill (int index); std::map& getFactionRanks(); - + std::set& getExpelled(); bool isSameFaction (const NpcStats& npcStats) const; @@ -107,24 +109,30 @@ namespace MWMechanics int getLevelupAttributeMultiplier(int attribute) const; void levelUp(); - + void flagAsUsed (const std::string& id); - + bool hasBeenUsed (const std::string& id) const; - + int getBounty() const; - + void setBounty (int bounty); - + int getFactionReputation (const std::string& faction) const; - + void setFactionReputation (const std::string& faction, int value); - + bool isVampire() const; - + void setVampire (bool set); - + bool hasSkillsForRank (const std::string& factionId, int rank) const; + + bool isWerewolf() const; + + void setWerewolf (bool set); + + int getWerewolfKills() const; }; } diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 8c639a874..c76019149 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -162,6 +162,11 @@ namespace MWWorld return false; } + bool Class::hasDetected (const MWWorld::Ptr& ptr, const MWWorld::Ptr& ptr2) const + { + return false; + } + const Class& Class::get (const std::string& key) { std::map >::const_iterator iter = sClasses.find (key); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 4662cbab6..07dcb8fe0 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -191,6 +191,11 @@ namespace MWWorld /// /// (default implementation: return false) + virtual bool hasDetected (const MWWorld::Ptr& ptr, const MWWorld::Ptr& ptr2) const; + ///< Has \æ ptr detected \a ptr2? + /// + /// (default implementation: return false) + static const Class& get (const std::string& key); ///< If there is no class for this \a key, an exception is thrown.