Issue #219: added last missing function filters

actorid
Marc Zinnschlag 12 years ago
parent 5f7d349126
commit 9669eed083

@ -74,7 +74,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
if (iter==stats.getFactionRanks().end()) if (iter==stats.getFactionRanks().end())
return false; return false;
// check rank // check rank
if (iter->second < info.mData.mRank) if (iter->second < info.mData.mRank)
return false; 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)) if (info.mData.mGender==(npc->mBase->mFlags & npc->mBase->Female ? 0 : 1))
return false; return false;
} }
return true; return true;
} }
bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const
{ {
const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
// check player faction // check player faction
if (!info.mPcFaction.empty()) if (!info.mPcFaction.empty())
{ {
@ -123,7 +123,7 @@ bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const
iter != info.mSelects.end(); ++iter) iter != info.mSelects.end(); ++iter)
if (!testSelectStruct (*iter)) if (!testSelectStruct (*iter))
return false; return false;
return true; return true;
} }
@ -131,7 +131,7 @@ bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const
{ {
if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name()) if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name())
return select.isInverted(); return select.isInverted();
switch (select.getType()) switch (select.getType())
{ {
case SelectWrapper::Type_None: return true; 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_Numeric: return testSelectStructNumeric (select);
case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select)); case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select));
} }
return true; return true;
} }
@ -148,11 +148,11 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
switch (select.getFunction()) switch (select.getFunction())
{ {
case SelectWrapper::Function_Global: case SelectWrapper::Function_Global:
// internally all globals are float :( // internally all globals are float :(
return select.selectCompare ( return select.selectCompare (
MWBase::Environment::get().getWorld()->getGlobalVariable (select.getName()).mFloat); MWBase::Environment::get().getWorld()->getGlobalVariable (select.getName()).mFloat);
case SelectWrapper::Function_Local: case SelectWrapper::Function_Local:
{ {
std::string scriptName = MWWorld::Class::get (mActor).getScript (mActor); std::string scriptName = MWWorld::Class::get (mActor).getScript (mActor);
@ -178,7 +178,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
if (i<script->mData.mNumShorts) if (i<script->mData.mNumShorts)
return select.selectCompare (static_cast<int> (locals.mShorts[i])); return select.selectCompare (static_cast<int> (locals.mShorts[i]));
i -= script->mData.mNumShorts; i -= script->mData.mNumShorts;
if (i<script->mData.mNumLongs) if (i<script->mData.mNumLongs)
@ -186,39 +186,39 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
i -= script->mData.mNumShorts; i -= script->mData.mNumShorts;
return select.selectCompare (locals.mFloats.at (i)); return select.selectCompare (locals.mFloats.at (i));
} }
case SelectWrapper::Function_PcHealthPercent: case SelectWrapper::Function_PcHealthPercent:
{ {
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); 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(); MWWorld::Class::get (player).getCreatureStats (player).getHealth().getModified();
return select.selectCompare (ratio); return select.selectCompare (ratio);
} }
case SelectWrapper::Function_PcDynamicStat: case SelectWrapper::Function_PcDynamicStat:
{ {
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
float value = MWWorld::Class::get (player).getCreatureStats (player). float value = MWWorld::Class::get (player).getCreatureStats (player).
getDynamic (select.getArgument()).getCurrent(); getDynamic (select.getArgument()).getCurrent();
return select.selectCompare (value); return select.selectCompare (value);
} }
case SelectWrapper::Function_HealthPercent: 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(); MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getModified();
return select.selectCompare (ratio); return select.selectCompare (ratio);
} }
default: default:
throw std::runtime_error ("unknown numeric select function"); throw std::runtime_error ("unknown numeric select function");
} }
} }
@ -230,11 +230,11 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
switch (select.getFunction()) switch (select.getFunction())
{ {
case SelectWrapper::Function_Journal: case SelectWrapper::Function_Journal:
return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName()); 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); MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player);
int sum = 0; 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) for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
if (toLower(iter->getCellRef().mRefID) == name) if (toLower(iter->getCellRef().mRefID) == name)
sum += iter->getRefData().getCount(); sum += iter->getRefData().getCount();
return sum; return sum;
} }
case SelectWrapper::Function_Dead: case SelectWrapper::Function_Dead:
return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName()); return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName());
case SelectWrapper::Function_Choice: case SelectWrapper::Function_Choice:
return mChoice; return mChoice;
case SelectWrapper::Function_AiSetting: case SelectWrapper::Function_AiSetting:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (select.getArgument()); return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (select.getArgument());
case SelectWrapper::Function_PcAttribute: case SelectWrapper::Function_PcAttribute:
return MWWorld::Class::get (player).getCreatureStats (player). return MWWorld::Class::get (player).getCreatureStats (player).
getAttribute (select.getArgument()).getModified(); getAttribute (select.getArgument()).getModified();
case SelectWrapper::Function_PcSkill: case SelectWrapper::Function_PcSkill:
return static_cast<int> (MWWorld::Class::get (player). return static_cast<int> (MWWorld::Class::get (player).
getNpcStats (player).getSkill (select.getArgument()).getModified()); getNpcStats (player).getSkill (select.getArgument()).getModified());
case SelectWrapper::Function_FriendlyHit: case SelectWrapper::Function_FriendlyHit:
{ {
int hits = MWWorld::Class::get (mActor).getCreatureStats (mActor).getFriendlyHits(); int hits = MWWorld::Class::get (mActor).getCreatureStats (mActor).getFriendlyHits();
return hits>4 ? 4 : hits; return hits>4 ? 4 : hits;
} }
case SelectWrapper::Function_PcLevel: case SelectWrapper::Function_PcLevel:
return MWWorld::Class::get (player).getCreatureStats (player).getLevel(); return MWWorld::Class::get (player).getCreatureStats (player).getLevel();
@ -284,26 +284,26 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
case SelectWrapper::Function_PcGender: case SelectWrapper::Function_PcGender:
return player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female ? 0 : 1; return player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female ? 0 : 1;
case SelectWrapper::Function_PcClothingModifier: case SelectWrapper::Function_PcClothingModifier:
{ {
MWWorld::InventoryStore& store = MWWorld::Class::get (player).getInventoryStore (player); MWWorld::InventoryStore& store = MWWorld::Class::get (player).getInventoryStore (player);
int value = 0; int value = 0;
for (int i=0; i<=15; ++i) // everything except thigns held in hands and amunition for (int i=0; i<=15; ++i) // everything except thigns held in hands and amunition
{ {
MWWorld::ContainerStoreIterator slot = store.getSlot (i); MWWorld::ContainerStoreIterator slot = store.getSlot (i);
if (slot!=store.end()) if (slot!=store.end())
value += MWWorld::Class::get (*slot).getValue (*slot); value += MWWorld::Class::get (*slot).getValue (*slot);
} }
return value; return value;
} }
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: case SelectWrapper::Function_RankRequirement:
@ -313,12 +313,12 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
std::string faction = std::string faction =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first; MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
int rank = getFactionRank (player, faction); int rank = getFactionRank (player, faction);
if (rank>=9) if (rank>=9)
return 0; // max rank return 0; // max rank
int result = 0; int result = 0;
if (hasFactionRankSkillRequirements (player, faction, rank+1)) if (hasFactionRankSkillRequirements (player, faction, rank+1))
@ -328,16 +328,68 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
result += 2; result += 2;
return result; return result;
} }
case SelectWrapper::Function_Level: case SelectWrapper::Function_Level:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getLevel(); return MWWorld::Class::get (mActor).getCreatureStats (mActor).getLevel();
case SelectWrapper::Function_PCReputation: 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<std::string, int> 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<ESM::Faction>().find (factionId);
MWMechanics::NpcStats& playerStats = MWWorld::Class::get (player).getNpcStats (player);
for (std::vector<ESM::Faction::Reaction>::const_iterator iter (faction.mReactions.begin());
iter!=faction.mReactions.end(); ++iter)
if (playerStats.getFactionRanks().find (iter->mFaction)!=playerStats.getFactionRanks().end())
if (low ? iter->mReaction<value : iter->mReaction>value)
value = iter->mReaction;
return value;
}
default: default:
throw std::runtime_error ("unknown integer select function"); throw std::runtime_error ("unknown integer select function");
@ -351,13 +403,13 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
switch (select.getFunction()) switch (select.getFunction())
{ {
case SelectWrapper::Function_False: case SelectWrapper::Function_False:
return false; return false;
case SelectWrapper::Function_Id: case SelectWrapper::Function_Id:
return select.getName()==toLower (MWWorld::Class::get (mActor).getId (mActor)); return select.getName()==toLower (MWWorld::Class::get (mActor).getId (mActor));
case SelectWrapper::Function_Faction: case SelectWrapper::Function_Faction:
return toLower (mActor.get<ESM::NPC>()->mBase->mFaction)==select.getName(); return toLower (mActor.get<ESM::NPC>()->mBase->mFaction)==select.getName();
@ -371,9 +423,9 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
return toLower (mActor.get<ESM::NPC>()->mBase->mRace)==select.getName(); return toLower (mActor.get<ESM::NPC>()->mBase->mRace)==select.getName();
case SelectWrapper::Function_Cell: case SelectWrapper::Function_Cell:
return toLower (mActor.getCell()->mCell->mName)==select.getName(); return toLower (mActor.getCell()->mCell->mName)==select.getName();
case SelectWrapper::Function_SameGender: case SelectWrapper::Function_SameGender:
return (player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female)== return (player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female)==
@ -383,46 +435,70 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
return toLower (mActor.get<ESM::NPC>()->mBase->mRace)!= return toLower (mActor.get<ESM::NPC>()->mBase->mRace)!=
toLower (player.get<ESM::NPC>()->mBase->mRace); toLower (player.get<ESM::NPC>()->mBase->mRace);
case SelectWrapper::Function_SameFaction: case SelectWrapper::Function_SameFaction:
return MWWorld::Class::get (mActor).getNpcStats (mActor).isSameFaction ( return MWWorld::Class::get (mActor).getNpcStats (mActor).isSameFaction (
MWWorld::Class::get (player).getNpcStats (player)); MWWorld::Class::get (player).getNpcStats (player));
case SelectWrapper::Function_PcCommonDisease: case SelectWrapper::Function_PcCommonDisease:
return MWWorld::Class::get (player).getCreatureStats (player).hasCommonDisease(); return MWWorld::Class::get (player).getCreatureStats (player).hasCommonDisease();
case SelectWrapper::Function_PcBlightDisease: case SelectWrapper::Function_PcBlightDisease:
return MWWorld::Class::get (player).getCreatureStats (player).hasBlightDisease(); return MWWorld::Class::get (player).getCreatureStats (player).hasBlightDisease();
case SelectWrapper::Function_PcCorprus: case SelectWrapper::Function_PcCorprus:
return MWWorld::Class::get (player).getCreatureStats (player). return MWWorld::Class::get (player).getCreatureStats (player).
getMagicEffects().get (132).mMagnitude!=0; getMagicEffects().get (132).mMagnitude!=0;
case SelectWrapper::Function_PcExpelled: case SelectWrapper::Function_PcExpelled:
{ {
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty()) if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return false; return false;
std::string faction = std::string faction =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first; MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
std::set<std::string>& expelled = MWWorld::Class::get (player).getNpcStats (player).getExpelled(); std::set<std::string>& expelled = MWWorld::Class::get (player).getNpcStats (player).getExpelled();
return expelled.find (faction)!=expelled.end(); return expelled.find (faction)!=expelled.end();
} }
case SelectWrapper::Function_PcVampire: case SelectWrapper::Function_PcVampire:
return MWWorld::Class::get (player).getNpcStats (player).isVampire(); return MWWorld::Class::get (player).getNpcStats (player).isVampire();
case SelectWrapper::Function_TalkedToPc: case SelectWrapper::Function_TalkedToPc:
return mTalkedToPlayer; 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: default:
throw std::runtime_error ("unknown boolean select function"); 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 int MWDialogue::Filter::getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const
{ {
MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor); MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor);
std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find (factionId); std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find (factionId);
if (iter==stats.getFactionRanks().end()) if (iter==stats.getFactionRanks().end())
return -1; return -1;
return iter->second; return iter->second;
} }

@ -34,7 +34,7 @@ namespace
throw std::runtime_error ("unknown compare type in dialogue info select"); throw std::runtime_error ("unknown compare type in dialogue info select");
} }
template<typename T> template<typename T>
bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1) bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1)
{ {
@ -49,21 +49,22 @@ namespace
} }
else else
throw std::runtime_error ( 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 MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() const
{ {
int index = 0; int index = 0;
std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index; std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index;
switch (index) switch (index)
{ {
// 0, 1 case 0: return Function_RankLow;
case 1: return Function_RankHigh;
case 2: return Function_RankRequirement; case 2: return Function_RankRequirement;
// 3 case 3: return Function_Reputation;
case 4: return Function_HealthPercent; case 4: return Function_HealthPercent;
case 5: return Function_PCReputation; case 5: return Function_PCReputation;
case 6: return Function_PcLevel; case 6: return Function_PcLevel;
@ -82,22 +83,26 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction()
case 44: return Function_SameGender; case 44: return Function_SameGender;
case 45: return Function_SameRace; case 45: return Function_SameRace;
case 46: return Function_SameFaction; 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 50: return Function_Choice;
case 51: case 52: case 53: case 54: case 55: case 56: case 57: return Function_PcAttribute; case 51: case 52: case 53: case 54: case 55: case 56: case 57: return Function_PcAttribute;
case 58: return Function_PcCorprus; case 58: return Function_PcCorprus;
// 59 case 59: return Function_Weather;
case 60: return Function_PcVampire; case 60: return Function_PcVampire;
case 61: return Function_Level; case 61: return Function_Level;
// 62 case 62: return Function_Attacked;
case 63: return Function_TalkedToPc; case 63: return Function_TalkedToPc;
case 64: return Function_PcDynamicStat; case 64: return Function_PcDynamicStat;
// 65 case 65: return Function_CreatureTargetted;
case 66: return Function_FriendlyHit; case 66: return Function_FriendlyHit;
case 67: case 68: case 69: case 70: return Function_AiSetting; 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; return Function_False;
} }
@ -130,11 +135,11 @@ int MWDialogue::SelectWrapper::getArgument() const
{ {
if (mSelect.mSelectRule[1]!='1') if (mSelect.mSelectRule[1]!='1')
return 0; return 0;
int index = 0; int index = 0;
std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index; std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index;
switch (index) switch (index)
{ {
// AI settings // AI settings
@ -142,7 +147,7 @@ int MWDialogue::SelectWrapper::getArgument() const
case 68: return 0; case 68: return 0;
case 69: return 3; case 69: return 3;
case 70: return 2; case 70: return 2;
// attributes // attributes
case 10: return 0; case 10: return 0;
case 51: return 1; case 51: return 1;
@ -152,7 +157,7 @@ int MWDialogue::SelectWrapper::getArgument() const
case 55: return 5; case 55: return 5;
case 56: return 6; case 56: return 6;
case 57: return 7; case 57: return 7;
// skills // skills
case 11: return 0; case 11: return 0;
case 12: return 1; case 12: return 1;
@ -181,13 +186,13 @@ int MWDialogue::SelectWrapper::getArgument() const
case 35: return 24; case 35: return 24;
case 36: return 25; case 36: return 25;
case 37: return 26; case 37: return 26;
// dynamic stats // dynamic stats
case 8: return 1; case 8: return 1;
case 9: return 2; case 9: return 2;
case 64: return 0; case 64: return 0;
} }
return 0; return 0;
} }
@ -204,17 +209,21 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
Function_PcCrimeLevel, Function_PcCrimeLevel,
Function_RankRequirement, Function_RankRequirement,
Function_Level, Function_PCReputation, Function_Level, Function_PCReputation,
Function_Weather,
Function_Reputation, Function_FactionRankDiff,
Function_WerewolfKills,
Function_RankLow, Function_RankHigh,
Function_None // end marker Function_None // end marker
}; };
static const Function numericFunctions[] = static const Function numericFunctions[] =
{ {
Function_Global, Function_Local, Function_Global, Function_Local,
Function_PcDynamicStat, Function_PcHealthPercent, Function_PcDynamicStat, Function_PcHealthPercent,
Function_HealthPercent, Function_HealthPercent,
Function_None // end marker Function_None // end marker
}; };
static const Function booleanFunctions[] = static const Function booleanFunctions[] =
{ {
Function_False, Function_False,
@ -223,15 +232,19 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus,
Function_PcExpelled, Function_PcExpelled,
Function_PcVampire, Function_TalkedToPc, Function_PcVampire, Function_TalkedToPc,
Function_Alarmed, Function_Detected,
Function_Attacked, Function_ShouldAttack,
Function_CreatureTargetted,
Function_PCWerewolf,
Function_None // end marker Function_None // end marker
}; };
Function function = getFunction(); Function function = getFunction();
for (int i=0; integerFunctions[i]!=Function_None; ++i) for (int i=0; integerFunctions[i]!=Function_None; ++i)
if (integerFunctions[i]==function) if (integerFunctions[i]==function)
return Type_Integer; return Type_Integer;
for (int i=0; numericFunctions[i]!=Function_None; ++i) for (int i=0; numericFunctions[i]!=Function_None; ++i)
if (numericFunctions[i]==function) if (numericFunctions[i]==function)
return Type_Numeric; return Type_Numeric;
@ -239,7 +252,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
for (int i=0; booleanFunctions[i]!=Function_None; ++i) for (int i=0; booleanFunctions[i]!=Function_None; ++i)
if (booleanFunctions[i]==function) if (booleanFunctions[i]==function)
return Type_Boolean; return Type_Boolean;
return Type_None; return Type_None;
} }
@ -261,15 +274,18 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const
Function_PcVampire, Function_PcVampire,
Function_PcCrimeLevel, Function_PcCrimeLevel,
Function_RankRequirement, Function_RankRequirement,
Function_Reputation, Function_FactionRankDiff,
Function_PCWerewolf, Function_WerewolfKills,
Function_RankLow, Function_RankHigh,
Function_None // end marker Function_None // end marker
}; };
Function function = getFunction(); Function function = getFunction();
for (int i=0; functions[i]!=Function_None; ++i) for (int i=0; functions[i]!=Function_None; ++i)
if (functions[i]==function) if (functions[i]==function)
return true; return true;
return false; return false;
} }

@ -8,9 +8,9 @@ namespace MWDialogue
class SelectWrapper class SelectWrapper
{ {
const ESM::DialInfo::SelectStruct& mSelect; const ESM::DialInfo::SelectStruct& mSelect;
public: public:
enum Function enum Function
{ {
Function_None, Function_False, Function_None, Function_False,
@ -36,7 +36,13 @@ namespace MWDialogue
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, 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 enum Type
@ -46,32 +52,32 @@ namespace MWDialogue
Type_Numeric, Type_Numeric,
Type_Boolean Type_Boolean
}; };
private: private:
Function decodeFunction() const; Function decodeFunction() const;
public: public:
SelectWrapper (const ESM::DialInfo::SelectStruct& select); SelectWrapper (const ESM::DialInfo::SelectStruct& select);
Function getFunction() const; Function getFunction() const;
int getArgument() const; int getArgument() const;
Type getType() const; Type getType() const;
bool isInverted() const; bool isInverted() const;
bool isNpcOnly() const; bool isNpcOnly() const;
///< \attention Do not call any of the select functions for this select struct! ///< \attention Do not call any of the select functions for this select struct!
bool selectCompare (int value) const; bool selectCompare (int value) const;
bool selectCompare (float value) const; bool selectCompare (float value) const;
bool selectCompare (bool value) const; bool selectCompare (bool value) const;
std::string getName() const; std::string getName() const;
///< Return case-smashed name. ///< Return case-smashed name.
}; };

@ -8,9 +8,10 @@
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
namespace MWMechanics namespace MWMechanics
{ {
CreatureStats::CreatureStats() 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) for (int i=0; i<4; ++i)
mAiSettings[i] = 0; mAiSettings[i] = 0;
@ -30,26 +31,26 @@ namespace MWMechanics
{ {
return mAiSequence; return mAiSequence;
} }
AiSequence& CreatureStats::getAiSequence() AiSequence& CreatureStats::getAiSequence()
{ {
return mAiSequence; return mAiSequence;
} }
float CreatureStats::getFatigueTerm() const float CreatureStats::getFatigueTerm() const
{ {
int max = getFatigue().getModified(); int max = getFatigue().getModified();
int current = getFatigue().getCurrent(); int current = getFatigue().getCurrent();
float normalised = max==0 ? 1 : std::max (0.0f, static_cast<float> (current)/max); float normalised = max==0 ? 1 : std::max (0.0f, static_cast<float> (current)/max);
const MWWorld::Store<ESM::GameSetting> &gmst = const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>(); MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
return gmst.find ("fFatigueBase")->getFloat() return gmst.find ("fFatigueBase")->getFloat()
- gmst.find ("fFatigueMult")->getFloat() * (1-normalised); - gmst.find ("fFatigueMult")->getFloat() * (1-normalised);
} }
const Stat<int> &CreatureStats::getAttribute(int index) const const Stat<int> &CreatureStats::getAttribute(int index) const
{ {
if (index < 0 || index > 7) { if (index < 0 || index > 7) {
@ -92,13 +93,13 @@ namespace MWMechanics
{ {
return mLevel; return mLevel;
} }
int CreatureStats::getAiSetting (int index) const int CreatureStats::getAiSetting (int index) const
{ {
assert (index>=0 && index<4); assert (index>=0 && index<4);
return mAiSettings[index]; return mAiSettings[index];
} }
Stat<int> &CreatureStats::getAttribute(int index) Stat<int> &CreatureStats::getAttribute(int index)
{ {
if (index < 0 || index > 7) { if (index < 0 || index > 7) {
@ -168,7 +169,7 @@ namespace MWMechanics
if (index==0 && mDynamic[index].getCurrent()<1) if (index==0 && mDynamic[index].getCurrent()<1)
mDead = true; mDead = true;
} }
void CreatureStats::setLevel(int level) void CreatureStats::setLevel(int level)
{ {
mLevel = level; mLevel = level;
@ -189,24 +190,24 @@ namespace MWMechanics
assert (index>=0 && index<4); assert (index>=0 && index<4);
mAiSettings[index] = value; mAiSettings[index] = value;
} }
bool CreatureStats::isDead() const bool CreatureStats::isDead() const
{ {
return mDead; return mDead;
} }
void CreatureStats::resurrect() void CreatureStats::resurrect()
{ {
if (mDead) if (mDead)
{ {
if (mDynamic[0].getCurrent()<1) if (mDynamic[0].getCurrent()<1)
mDynamic[0].setCurrent (1); mDynamic[0].setCurrent (1);
if (mDynamic[0].getCurrent()>=1) if (mDynamic[0].getCurrent()>=1)
mDead = false; mDead = false;
} }
} }
bool CreatureStats::hasCommonDisease() const bool CreatureStats::hasCommonDisease() const
{ {
return mSpells.hasCommonDisease(); return mSpells.hasCommonDisease();
@ -216,24 +217,59 @@ namespace MWMechanics
{ {
return mSpells.hasBlightDisease(); return mSpells.hasBlightDisease();
} }
int CreatureStats::getFriendlyHits() const int CreatureStats::getFriendlyHits() const
{ {
return mFriendlyHits; return mFriendlyHits;
} }
void CreatureStats::friendlyHit() void CreatureStats::friendlyHit()
{ {
++mFriendlyHits; ++mFriendlyHits;
} }
bool CreatureStats::hasTalkedToPlayer() const bool CreatureStats::hasTalkedToPlayer() const
{ {
return mTalkedTo; return mTalkedTo;
} }
void CreatureStats::talkedToPlayer() void CreatureStats::talkedToPlayer()
{ {
mTalkedTo = true; 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;
}
} }

@ -30,6 +30,9 @@ namespace MWMechanics
bool mDead; bool mDead;
int mFriendlyHits; int mFriendlyHits;
bool mTalkedTo; bool mTalkedTo;
bool mAlarmed;
bool mAttacked;
bool mHostile;
public: public:
CreatureStats(); CreatureStats();
@ -83,11 +86,11 @@ namespace MWMechanics
void setAiSetting (int index, int value); void setAiSetting (int index, int value);
///< 0: hello, 1 fight, 2 flee, 3 alarm ///< 0: hello, 1 fight, 2 flee, 3 alarm
const AiSequence& getAiSequence() const; const AiSequence& getAiSequence() const;
AiSequence& getAiSequence(); AiSequence& getAiSequence();
float getFatigueTerm() const; float getFatigueTerm() const;
///< Return effective fatigue ///< Return effective fatigue
@ -96,23 +99,37 @@ namespace MWMechanics
float getLevelHealthBonus() const; float getLevelHealthBonus() const;
bool isDead() const; bool isDead() const;
void resurrect(); void resurrect();
bool hasCommonDisease() const; bool hasCommonDisease() const;
bool hasBlightDisease() const; bool hasBlightDisease() const;
int getFriendlyHits() const; int getFriendlyHits() const;
///< Number of friendly hits received. ///< Number of friendly hits received.
void friendlyHit(); void friendlyHit();
///< Increase number of friendly hits by one. ///< Increase number of friendly hits by one.
bool hasTalkedToPlayer() const; bool hasTalkedToPlayer() const;
///< Has this creature talked with the player before? ///< Has this creature talked with the player before?
void talkedToPlayer(); 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;
}; };
} }

@ -22,7 +22,7 @@
MWMechanics::NpcStats::NpcStats() MWMechanics::NpcStats::NpcStats()
: mMovementFlags (0), mDrawState (DrawState_Nothing), mBounty (0) : 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); mSkillIncreases.resize (ESM::Attribute::Length);
for (int i=0; i<ESM::Attribute::Length; ++i) for (int i=0; i<ESM::Attribute::Length; ++i)
@ -99,7 +99,7 @@ bool MWMechanics::NpcStats::isSameFaction (const NpcStats& npcStats) const
++iter) ++iter)
if (npcStats.mFactionRank.find (iter->first)!=npcStats.mFactionRank.end()) if (npcStats.mFactionRank.find (iter->first)!=npcStats.mFactionRank.end())
return true; return true;
return false; return false;
} }
@ -280,10 +280,10 @@ void MWMechanics::NpcStats::setBounty (int bounty)
int MWMechanics::NpcStats::getFactionReputation (const std::string& faction) const int MWMechanics::NpcStats::getFactionReputation (const std::string& faction) const
{ {
std::map<std::string, int>::const_iterator iter = mFactionReputation.find (faction); std::map<std::string, int>::const_iterator iter = mFactionReputation.find (faction);
if (iter==mFactionReputation.end()) if (iter==mFactionReputation.end())
return 0; return 0;
return iter->second; return iter->second;
} }
@ -321,19 +321,33 @@ bool MWMechanics::NpcStats::hasSkillsForRank (const std::string& factionId, int
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId); *MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
std::vector<int> skills; std::vector<int> skills;
for (int i=0; i<6; ++i) for (int i=0; i<6; ++i)
skills.push_back (static_cast<int> (getSkill (faction.mData.mSkillID[i]).getModified())); skills.push_back (static_cast<int> (getSkill (faction.mData.mSkillID[i]).getModified()));
std::sort (skills.begin(), skills.end()); std::sort (skills.begin(), skills.end());
std::vector<int>::const_reverse_iterator iter = skills.rbegin(); std::vector<int>::const_reverse_iterator iter = skills.rbegin();
const ESM::RankData& rankData = faction.mData.mRankData[rank]; const ESM::RankData& rankData = faction.mData.mRankData[rank];
if (*iter<rankData.mSkill1) if (*iter<rankData.mSkill1)
return false; return false;
return *++iter>=rankData.mSkill2; return *++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;
}

@ -51,6 +51,8 @@ namespace MWMechanics
std::map<std::string, int> mFactionReputation; std::map<std::string, int> mFactionReputation;
bool mVampire; bool mVampire;
int mReputation; int mReputation;
bool mWerewolf;
int mWerewolfKills;
int mLevelProgress; // 0-10 int mLevelProgress; // 0-10
@ -83,7 +85,7 @@ namespace MWMechanics
Stat<float>& getSkill (int index); Stat<float>& getSkill (int index);
std::map<std::string, int>& getFactionRanks(); std::map<std::string, int>& getFactionRanks();
std::set<std::string>& getExpelled(); std::set<std::string>& getExpelled();
bool isSameFaction (const NpcStats& npcStats) const; bool isSameFaction (const NpcStats& npcStats) const;
@ -107,24 +109,30 @@ namespace MWMechanics
int getLevelupAttributeMultiplier(int attribute) const; int getLevelupAttributeMultiplier(int attribute) const;
void levelUp(); void levelUp();
void flagAsUsed (const std::string& id); void flagAsUsed (const std::string& id);
bool hasBeenUsed (const std::string& id) const; bool hasBeenUsed (const std::string& id) const;
int getBounty() const; int getBounty() const;
void setBounty (int bounty); void setBounty (int bounty);
int getFactionReputation (const std::string& faction) const; int getFactionReputation (const std::string& faction) const;
void setFactionReputation (const std::string& faction, int value); void setFactionReputation (const std::string& faction, int value);
bool isVampire() const; bool isVampire() const;
void setVampire (bool set); void setVampire (bool set);
bool hasSkillsForRank (const std::string& factionId, int rank) const; bool hasSkillsForRank (const std::string& factionId, int rank) const;
bool isWerewolf() const;
void setWerewolf (bool set);
int getWerewolfKills() const;
}; };
} }

@ -162,6 +162,11 @@ namespace MWWorld
return false; return false;
} }
bool Class::hasDetected (const MWWorld::Ptr& ptr, const MWWorld::Ptr& ptr2) const
{
return false;
}
const Class& Class::get (const std::string& key) const Class& Class::get (const std::string& key)
{ {
std::map<std::string, boost::shared_ptr<Class> >::const_iterator iter = sClasses.find (key); std::map<std::string, boost::shared_ptr<Class> >::const_iterator iter = sClasses.find (key);

@ -191,6 +191,11 @@ namespace MWWorld
/// ///
/// (default implementation: return false) /// (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); static const Class& get (const std::string& key);
///< If there is no class for this \a key, an exception is thrown. ///< If there is no class for this \a key, an exception is thrown.

Loading…
Cancel
Save