bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) const { switch (select.getFunction()) { case SelectWrapper::Function_Global: // internally all globals are float :( return select.selectCompare ( MWBase::Environment::get().getWorld()->getGlobalFloat (select.getName())); case SelectWrapper::Function_Local: { return testFunctionLocal(select); } case SelectWrapper::Function_NotLocal: { return !testFunctionLocal(select); } case SelectWrapper::Function_PcHealthPercent: { MWWorld::Ptr player = MWMechanics::getPlayer(); float ratio = player.getClass().getCreatureStats (player).getHealth().getCurrent() / player.getClass().getCreatureStats (player).getHealth().getModified(); return select.selectCompare (static_cast<int>(ratio*100)); } case SelectWrapper::Function_PcDynamicStat: { MWWorld::Ptr player = MWMechanics::getPlayer(); float value = player.getClass().getCreatureStats (player). getDynamic (select.getArgument()).getCurrent(); return select.selectCompare (value); } case SelectWrapper::Function_HealthPercent: { float ratio = mActor.getClass().getCreatureStats (mActor).getHealth().getCurrent() / mActor.getClass().getCreatureStats (mActor).getHealth().getModified(); return select.selectCompare (static_cast<int>(ratio*100)); } default: throw std::runtime_error ("unknown numeric select function"); } }
int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const { MWWorld::Ptr player = MWMechanics::getPlayer(); switch (select.getFunction()) { case SelectWrapper::Function_Journal: return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName()); case SelectWrapper::Function_Item: { MWWorld::ContainerStore& store = player.getClass().getContainerStore (player); return store.count(select.getName()); } case SelectWrapper::Function_Dead: return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName()); case SelectWrapper::Function_Choice: return mChoice; case SelectWrapper::Function_AiSetting: return mActor.getClass().getCreatureStats (mActor).getAiSetting ( (MWMechanics::CreatureStats::AiSetting)select.getArgument()).getModified(); case SelectWrapper::Function_PcAttribute: return player.getClass().getCreatureStats (player). getAttribute (select.getArgument()).getModified(); case SelectWrapper::Function_PcSkill: return static_cast<int> (player.getClass(). getNpcStats (player).getSkill (select.getArgument()).getModified()); case SelectWrapper::Function_FriendlyHit: { int hits = mActor.getClass().getCreatureStats (mActor).getFriendlyHits(); return hits>4 ? 4 : hits; } case SelectWrapper::Function_PcLevel: return player.getClass().getCreatureStats (player).getLevel(); case SelectWrapper::Function_PcGender: return player.get<ESM::NPC>()->mBase->isMale() ? 0 : 1; case SelectWrapper::Function_PcClothingModifier: { MWWorld::InventoryStore& store = player.getClass().getInventoryStore (player); int value = 0; for (int i=0; i<=15; ++i) // everything except things held in hands and ammunition { MWWorld::ContainerStoreIterator slot = store.getSlot (i); if (slot!=store.end()) value += slot->getClass().getValue (*slot); } return value; } case SelectWrapper::Function_PcCrimeLevel: return player.getClass().getNpcStats (player).getBounty(); case SelectWrapper::Function_RankRequirement: { std::string faction = mActor.getClass().getPrimaryFaction(mActor); if (faction.empty()) return 0; 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; } case SelectWrapper::Function_Level: return mActor.getClass().getCreatureStats (mActor).getLevel(); case SelectWrapper::Function_PCReputation: return player.getClass().getNpcStats (player).getReputation(); case SelectWrapper::Function_Weather: return MWBase::Environment::get().getWorld()->getCurrentWeather(); case SelectWrapper::Function_Reputation: return mActor.getClass().getNpcStats (mActor).getReputation(); case SelectWrapper::Function_FactionRankDiff: { std::string faction = mActor.getClass().getPrimaryFaction(mActor); if (faction.empty()) return 0; int rank = getFactionRank (player, faction); int npcRank = mActor.getClass().getPrimaryFactionRank(mActor); return rank-npcRank; } case SelectWrapper::Function_WerewolfKills: return player.getClass().getNpcStats (player).getWerewolfKills(); case SelectWrapper::Function_RankLow: case SelectWrapper::Function_RankHigh: { bool low = select.getFunction()==SelectWrapper::Function_RankLow; std::string factionId = mActor.getClass().getPrimaryFaction(mActor); if (factionId.empty()) return 0; int value = 0; MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats (player); std::map<std::string, int>::const_iterator playerFactionIt = playerStats.getFactionRanks().begin(); for (; playerFactionIt != playerStats.getFactionRanks().end(); ++playerFactionIt) { int reaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction(factionId, playerFactionIt->first); if (low ? reaction < value : reaction > value) value = reaction; } return value; } case SelectWrapper::Function_CreatureTargetted: { MWWorld::Ptr target; mActor.getClass().getCreatureStats(mActor).getAiSequence().getCombatTarget(target); if (target) { if (target.getClass().isNpc() && target.getClass().getNpcStats(target).isWerewolf()) return 2; if (target.getTypeName() == typeid(ESM::Creature).name()) return 1; } } return 0; default: throw std::runtime_error ("unknown integer select function"); } }
bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) const { switch (select.getFunction()) { case SelectWrapper::Function_Global: // internally all globals are float :( return select.selectCompare ( MWBase::Environment::get().getWorld()->getGlobalFloat (select.getName())); case SelectWrapper::Function_Local: { std::string scriptName = mActor.getClass().getScript (mActor); if (scriptName.empty()) return false; // no script std::string name = Misc::StringUtils::lowerCase (select.getName()); const Compiler::Locals& localDefs = MWBase::Environment::get().getScriptManager()->getLocals (scriptName); char type = localDefs.getType (name); if (type==' ') return false; // script does not have a variable of this name. int index = localDefs.getIndex (name); if (index < 0) return false; // shouldn't happen, we checked that variable has a type above, so must exist const MWScript::Locals& locals = mActor.getRefData().getLocals(); switch (type) { case 's': return select.selectCompare (static_cast<int> (locals.mShorts[index])); case 'l': return select.selectCompare (locals.mLongs[index]); case 'f': return select.selectCompare (locals.mFloats[index]); } throw std::logic_error ("unknown local variable type in dialogue filter"); } case SelectWrapper::Function_PcHealthPercent: { MWWorld::Ptr player = MWMechanics::getPlayer(); float ratio = player.getClass().getCreatureStats (player).getHealth().getCurrent() / player.getClass().getCreatureStats (player).getHealth().getModified(); return select.selectCompare (static_cast<int>(ratio*100)); } case SelectWrapper::Function_PcDynamicStat: { MWWorld::Ptr player = MWMechanics::getPlayer(); float value = player.getClass().getCreatureStats (player). getDynamic (select.getArgument()).getCurrent(); return select.selectCompare (value); } case SelectWrapper::Function_HealthPercent: { float ratio = mActor.getClass().getCreatureStats (mActor).getHealth().getCurrent() / mActor.getClass().getCreatureStats (mActor).getHealth().getModified(); return select.selectCompare (static_cast<int>(ratio*100)); } default: throw std::runtime_error ("unknown numeric select function"); } }
int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); switch (select.getFunction()) { case SelectWrapper::Function_Journal: return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName()); case SelectWrapper::Function_Item: { MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player); int sum = 0; std::string name = select.getName(); for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) if (Misc::StringUtils::lowerCase(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<int> (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; } case SelectWrapper::Function_PcLevel: return MWWorld::Class::get (player).getCreatureStats (player).getLevel(); case SelectWrapper::Function_PcGender: return player.get<ESM::NPC>()->mBase->isMale() ? 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: { 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; } case SelectWrapper::Function_Level: return MWWorld::Class::get (mActor).getCreatureStats (mActor).getLevel(); case SelectWrapper::Function_PCReputation: 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: throw std::runtime_error ("unknown integer select function"); } }
bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) const { 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); if (scriptName.empty()) return false; // no script const ESM::Script *script = MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (scriptName); std::string name = select.getName(); int i = 0; for (; i<static_cast<int> (script->mVarNames.size()); ++i) if (Misc::StringUtils::lowerCase(script->mVarNames[i]) == name) break; if (i>=static_cast<int> (script->mVarNames.size())) return false; // script does not have a variable of this name const MWScript::Locals& locals = mActor.getRefData().getLocals(); if (i<script->mData.mNumShorts) return select.selectCompare (static_cast<int> (locals.mShorts[i])); i -= script->mData.mNumShorts; if (i<script->mData.mNumLongs) return select.selectCompare (locals.mLongs[i]); i -= script->mData.mNumLongs; 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() / 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(); return select.selectCompare (value); } case SelectWrapper::Function_HealthPercent: { 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"); } }