ESSImport: fix NPC factions

openmw-35
scrawl 10 years ago
parent 875df46ae9
commit 431f540791

@ -270,7 +270,7 @@ public:
faction.mExpelled = (it->mFlags & 0x2) != 0; faction.mExpelled = (it->mFlags & 0x2) != 0;
faction.mRank = it->mRank; faction.mRank = it->mRank;
faction.mReputation = it->mReputation; faction.mReputation = it->mReputation;
mContext->mPlayer.mObject.mNpcStats.mFactions[it->mFactionName.toString()] = faction; mContext->mPlayer.mObject.mNpcStats.mFactions[Misc::StringUtils::lowerCase(it->mFactionName.toString())] = faction;
} }
for (int i=0; i<8; ++i) for (int i=0; i<8; ++i)
mContext->mPlayer.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i]; mContext->mPlayer.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i];

@ -296,25 +296,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>(); MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
// NPC stats
if (!ref->mBase->mFaction.empty())
{
std::string faction = ref->mBase->mFaction;
if (const ESM::Faction* fact = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().search(faction))
{
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
{
data->mNpcStats.setFactionRank(fact->mId, (int)ref->mBase->mNpdt52.mRank);
}
else
{
data->mNpcStats.setFactionRank(fact->mId, (int)ref->mBase->mNpdt12.mRank);
}
}
else
std::cerr << "Warning: ignoring nonexistent faction '" << faction << "' on NPC '" << ref->mBase->mId << "'" << std::endl;
}
// creature stats // creature stats
int gold=0; int gold=0;
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
@ -371,13 +352,13 @@ namespace MWClass
std::cerr << "Warning: ignoring nonexistent race power '" << *iter << "' on NPC '" << ref->mBase->mId << "'" << std::endl; std::cerr << "Warning: ignoring nonexistent race power '" << *iter << "' on NPC '" << ref->mBase->mId << "'" << std::endl;
} }
if (data->mNpcStats.getFactionRanks().size()) if (!ref->mBase->mFaction.empty())
{ {
static const int iAutoRepFacMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>() static const int iAutoRepFacMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("iAutoRepFacMod")->getInt(); .find("iAutoRepFacMod")->getInt();
static const int iAutoRepLevMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>() static const int iAutoRepLevMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("iAutoRepLevMod")->getInt(); .find("iAutoRepLevMod")->getInt();
int rank = data->mNpcStats.getFactionRanks().begin()->second; int rank = ref->mBase->getFactionRank();
data->mNpcStats.setReputation(iAutoRepFacMod * (rank+1) + iAutoRepLevMod * (data->mNpcStats.getLevel()-1)); data->mNpcStats.setReputation(iAutoRepFacMod * (rank+1) + iAutoRepLevMod * (data->mNpcStats.getLevel()-1));
} }
@ -1371,4 +1352,16 @@ namespace MWClass
{ {
return true; return true;
} }
std::string Npc::getPrimaryFaction (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
return ref->mBase->mFaction;
}
int Npc::getPrimaryFactionRank (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
return ref->mBase->getFactionRank();
}
} }

@ -189,6 +189,9 @@ namespace MWClass
virtual void restock (const MWWorld::Ptr& ptr) const; virtual void restock (const MWWorld::Ptr& ptr) const;
virtual int getBaseFightRating (const MWWorld::Ptr& ptr) const; virtual int getBaseFightRating (const MWWorld::Ptr& ptr) const;
virtual std::string getPrimaryFaction(const MWWorld::Ptr &ptr) const;
virtual int getPrimaryFactionRank(const MWWorld::Ptr &ptr) const;
}; };
} }

@ -67,14 +67,11 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
if (isCreature) if (isCreature)
return false; return false;
MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats (mActor); if (!Misc::StringUtils::ciEqual(mActor.getClass().getPrimaryFaction(mActor), info.mFaction))
std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find ( Misc::StringUtils::lowerCase (info.mFaction));
if (iter==stats.getFactionRanks().end())
return false; return false;
// check rank // check rank
if (iter->second < info.mData.mRank) if (mActor.getClass().getPrimaryFactionRank(mActor) < info.mData.mRank)
return false; return false;
} }
else if (info.mData.mRank != -1) else if (info.mData.mRank != -1)
@ -83,13 +80,8 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
return false; return false;
// Rank requirement, but no faction given. Use the actor's faction, if there is one. // Rank requirement, but no faction given. Use the actor's faction, if there is one.
MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats (mActor);
if (!stats.getFactionRanks().size())
return false;
// check rank // check rank
if (stats.getFactionRanks().begin()->second < info.mData.mRank) if (mActor.getClass().getPrimaryFactionRank(mActor) < info.mData.mRank)
return false; return false;
} }
@ -336,12 +328,10 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
case SelectWrapper::Function_RankRequirement: case SelectWrapper::Function_RankRequirement:
{ {
if (mActor.getClass().getNpcStats (mActor).getFactionRanks().empty()) std::string faction = mActor.getClass().getPrimaryFaction(mActor);
if (faction.empty())
return 0; return 0;
std::string faction =
mActor.getClass().getNpcStats (mActor).getFactionRanks().begin()->first;
int rank = getFactionRank (player, faction); int rank = getFactionRank (player, faction);
if (rank>=9) if (rank>=9)
@ -376,15 +366,14 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
case SelectWrapper::Function_FactionRankDiff: case SelectWrapper::Function_FactionRankDiff:
{ {
if (mActor.getClass().getNpcStats (mActor).getFactionRanks().empty()) std::string faction = mActor.getClass().getPrimaryFaction(mActor);
return 0;
const std::pair<std::string, int> faction =
*mActor.getClass().getNpcStats (mActor).getFactionRanks().begin();
int rank = getFactionRank (player, faction.first); if (faction.empty())
return 0;
return rank-faction.second; int rank = getFactionRank (player, faction);
int npcRank = mActor.getClass().getPrimaryFactionRank(mActor);
return rank-npcRank;
} }
case SelectWrapper::Function_WerewolfKills: case SelectWrapper::Function_WerewolfKills:
@ -396,11 +385,10 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
{ {
bool low = select.getFunction()==SelectWrapper::Function_RankLow; bool low = select.getFunction()==SelectWrapper::Function_RankLow;
if (mActor.getClass().getNpcStats (mActor).getFactionRanks().empty()) std::string factionId = mActor.getClass().getPrimaryFaction(mActor);
return 0;
std::string factionId = if (factionId.empty())
mActor.getClass().getNpcStats (mActor).getFactionRanks().begin()->first; return 0;
int value = 0; int value = 0;
@ -454,7 +442,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
case SelectWrapper::Function_NotFaction: case SelectWrapper::Function_NotFaction:
return !Misc::StringUtils::ciEqual(mActor.get<ESM::NPC>()->mBase->mFaction, select.getName()); return !Misc::StringUtils::ciEqual(mActor.getClass().getPrimaryFaction(mActor), select.getName());
case SelectWrapper::Function_NotClass: case SelectWrapper::Function_NotClass:
@ -494,8 +482,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
case SelectWrapper::Function_SameFaction: case SelectWrapper::Function_SameFaction:
return mActor.getClass().getNpcStats (mActor).isSameFaction ( return player.getClass().getNpcStats (player).isInFaction(mActor.getClass().getPrimaryFaction(mActor));
player.getClass().getNpcStats (player));
case SelectWrapper::Function_PcCommonDisease: case SelectWrapper::Function_PcCommonDisease:
@ -512,11 +499,10 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
case SelectWrapper::Function_PcExpelled: case SelectWrapper::Function_PcExpelled:
{ {
if (mActor.getClass().getNpcStats (mActor).getFactionRanks().empty()) std::string faction = mActor.getClass().getPrimaryFaction(mActor);
return false;
std::string faction = if (faction.empty())
mActor.getClass().getNpcStats (mActor).getFactionRanks().begin()->first; return false;
return player.getClass().getNpcStats(player).getExpelled(faction); return player.getClass().getNpcStats(player).getExpelled(faction);
} }
@ -561,7 +547,7 @@ int MWDialogue::Filter::getFactionRank (const MWWorld::Ptr& actor, const std::st
{ {
MWMechanics::NpcStats& stats = actor.getClass().getNpcStats (actor); MWMechanics::NpcStats& stats = actor.getClass().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 (Misc::StringUtils::lowerCase(factionId));
if (iter==stats.getFactionRanks().end()) if (iter==stats.getFactionRanks().end())
return -1; return -1;

@ -572,8 +572,7 @@ namespace MWMechanics
float reaction = 0; float reaction = 0;
int rank = 0; int rank = 0;
std::string npcFaction = ""; std::string npcFaction = ptr.getClass().getPrimaryFaction(ptr);
if(!npcSkill.getFactionRanks().empty()) npcFaction = npcSkill.getFactionRanks().begin()->first;
Misc::StringUtils::toLower(npcFaction); Misc::StringUtils::toLower(npcFaction);
@ -1156,10 +1155,10 @@ namespace MWMechanics
// If committing a crime against a faction member, expell from the faction // If committing a crime against a faction member, expell from the faction
if (!victim.isEmpty() && victim.getClass().isNpc()) if (!victim.isEmpty() && victim.getClass().isNpc())
{ {
std::string factionID; std::string factionID = victim.getClass().getPrimaryFaction(victim);
if(!victim.getClass().getNpcStats(victim).getFactionRanks().empty())
factionID = victim.getClass().getNpcStats(victim).getFactionRanks().begin()->first; const std::map<std::string, int>& playerRanks = player.getClass().getNpcStats(player).getFactionRanks();
if (player.getClass().getNpcStats(player).isSameFaction(victim.getClass().getNpcStats(victim))) if (playerRanks.find(Misc::StringUtils::lowerCase(factionID)) != playerRanks.end())
{ {
player.getClass().getNpcStats(player).expell(factionID); player.getClass().getNpcStats(player).expell(factionID);
} }

@ -91,12 +91,6 @@ void MWMechanics::NpcStats::lowerRank(const std::string &faction)
} }
} }
void MWMechanics::NpcStats::setFactionRank(const std::string &faction, int rank)
{
const std::string lower = Misc::StringUtils::lowerCase(faction);
mFactionRank[lower] = rank;
}
void MWMechanics::NpcStats::joinFaction(const std::string& faction) void MWMechanics::NpcStats::joinFaction(const std::string& faction)
{ {
const std::string lower = Misc::StringUtils::lowerCase(faction); const std::string lower = Misc::StringUtils::lowerCase(faction);
@ -127,14 +121,9 @@ void MWMechanics::NpcStats::clearExpelled(const std::string& factionID)
mExpelled.erase(Misc::StringUtils::lowerCase(factionID)); mExpelled.erase(Misc::StringUtils::lowerCase(factionID));
} }
bool MWMechanics::NpcStats::isSameFaction (const NpcStats& npcStats) const bool MWMechanics::NpcStats::isInFaction (const std::string& faction) const
{ {
for (std::map<std::string, int>::const_iterator iter (mFactionRank.begin()); iter!=mFactionRank.end(); return (mFactionRank.find(Misc::StringUtils::lowerCase(faction)) != mFactionRank.end());
++iter)
if (npcStats.mFactionRank.find (iter->first)!=npcStats.mFactionRank.end())
return true;
return false;
} }
float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& class_, int usageType, float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& class_, int usageType,

@ -33,9 +33,7 @@ namespace MWMechanics
// ----- used by the player only, maybe should be moved at some point ------- // ----- used by the player only, maybe should be moved at some point -------
int mBounty; int mBounty;
int mWerewolfKills; int mWerewolfKills;
/// NPCs other than the player can only have one faction. But for the sake of consistency /// Used for the player only; NPCs have maximum one faction defined in their NPC record
/// we use the same data structure for the PC and the NPCs.
/// \note the faction key must be in lowercase
std::map<std::string, int> mFactionRank; std::map<std::string, int> mFactionRank;
std::set<std::string> mExpelled; std::set<std::string> mExpelled;
std::map<std::string, int> mFactionReputation; std::map<std::string, int> mFactionReputation;
@ -74,17 +72,13 @@ namespace MWMechanics
void lowerRank(const std::string& faction); void lowerRank(const std::string& faction);
/// Join this faction, setting the initial rank to 0. /// Join this faction, setting the initial rank to 0.
void joinFaction(const std::string& faction); void joinFaction(const std::string& faction);
/// Warning: this function performs no check whether the rank exists,
/// and should be used in initial actor setup only.
void setFactionRank(const std::string& faction, int rank);
const std::set<std::string>& getExpelled() const { return mExpelled; } const std::set<std::string>& getExpelled() const { return mExpelled; }
bool getExpelled(const std::string& factionID) const; bool getExpelled(const std::string& factionID) const;
void expell(const std::string& factionID); void expell(const std::string& factionID);
void clearExpelled(const std::string& factionID); void clearExpelled(const std::string& factionID);
bool isSameFaction (const NpcStats& npcStats) const; bool isInFaction (const std::string& faction) const;
///< Do *this and \a npcStats share a faction?
float getSkillGain (int skillIndex, const ESM::Class& class_, int usageType = -1, float getSkillGain (int skillIndex, const ESM::Class& class_, int usageType = -1,
int level = -1, float extraFactor=1.f) const; int level = -1, float extraFactor=1.f) const;

@ -196,7 +196,7 @@ namespace MWScript
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
runtime.push (ptr.getClass().getNpcStats (ptr).isSameFaction (player.getClass().getNpcStats (player))); player.getClass().getNpcStats (player).isInFaction(ptr.getClass().getPrimaryFaction(ptr));
} }
}; };

@ -313,17 +313,19 @@ namespace MWScript
std::string InterpreterContext::getNPCRank() const std::string InterpreterContext::getNPCRank() const
{ {
if (getReferenceImp().getClass().getNpcStats(getReferenceImp()).getFactionRanks().empty()) const MWWorld::Ptr& ptr = getReferenceImp();
std::string faction = ptr.getClass().getPrimaryFaction(ptr);
if (faction.empty())
throw std::runtime_error("getNPCRank(): NPC is not in a faction"); throw std::runtime_error("getNPCRank(): NPC is not in a faction");
const std::map<std::string, int>& ranks = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks(); int rank = ptr.getClass().getPrimaryFactionRank(ptr);
std::map<std::string, int>::const_iterator it = ranks.begin(); if (rank < 0 || rank > 9)
throw std::runtime_error("getNPCRank(): invalid rank");
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
const MWWorld::ESMStore &store = world->getStore(); const MWWorld::ESMStore &store = world->getStore();
const ESM::Faction *faction = store.get<ESM::Faction>().find(it->first); const ESM::Faction *fact = store.get<ESM::Faction>().find(faction);
return fact->mRanks[rank];
return faction->mRanks[it->second];
} }
std::string InterpreterContext::getPCName() const std::string InterpreterContext::getPCName() const
@ -352,13 +354,12 @@ namespace MWScript
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = world->getPlayerPtr(); MWWorld::Ptr player = world->getPlayerPtr();
if (getReferenceImp().getClass().getNpcStats(getReferenceImp()).getFactionRanks().empty()) std::string factionId = getReferenceImp().getClass().getPrimaryFaction(getReferenceImp());
if (factionId.empty())
throw std::runtime_error("getPCRank(): NPC is not in a faction"); throw std::runtime_error("getPCRank(): NPC is not in a faction");
std::string factionId = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks().begin()->first;
const std::map<std::string, int>& ranks = player.getClass().getNpcStats (player).getFactionRanks(); const std::map<std::string, int>& ranks = player.getClass().getNpcStats (player).getFactionRanks();
std::map<std::string, int>::const_iterator it = ranks.find(factionId); std::map<std::string, int>::const_iterator it = ranks.find(Misc::StringUtils::lowerCase(factionId));
int rank = -1; int rank = -1;
if (it != ranks.end()) if (it != ranks.end())
rank = it->second; rank = it->second;
@ -382,13 +383,12 @@ namespace MWScript
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = world->getPlayerPtr(); MWWorld::Ptr player = world->getPlayerPtr();
if (getReferenceImp().getClass().getNpcStats(getReferenceImp()).getFactionRanks().empty()) std::string factionId = getReferenceImp().getClass().getPrimaryFaction(getReferenceImp());
if (factionId.empty())
throw std::runtime_error("getPCNextRank(): NPC is not in a faction"); throw std::runtime_error("getPCNextRank(): NPC is not in a faction");
std::string factionId = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks().begin()->first;
const std::map<std::string, int>& ranks = player.getClass().getNpcStats (player).getFactionRanks(); const std::map<std::string, int>& ranks = player.getClass().getNpcStats (player).getFactionRanks();
std::map<std::string, int>::const_iterator it = ranks.find(factionId); std::map<std::string, int>::const_iterator it = ranks.find(Misc::StringUtils::lowerCase(factionId));
int rank = -1; int rank = -1;
if (it != ranks.end()) if (it != ranks.end())
rank = it->second; rank = it->second;

@ -32,13 +32,12 @@ namespace
{ {
std::string getDialogueActorFaction(MWWorld::Ptr actor) std::string getDialogueActorFaction(MWWorld::Ptr actor)
{ {
const MWMechanics::NpcStats &stats = actor.getClass().getNpcStats (actor); std::string factionId = actor.getClass().getPrimaryFaction(actor);
if (factionId.empty())
if (stats.getFactionRanks().empty())
throw std::runtime_error ( throw std::runtime_error (
"failed to determine dialogue actors faction (because actor is factionless)"); "failed to determine dialogue actors faction (because actor is factionless)");
return stats.getFactionRanks().begin()->first; return factionId;
} }
} }
@ -665,14 +664,7 @@ namespace MWScript
} }
else else
{ {
if(ptr.getClass().getNpcStats(ptr).getFactionRanks().empty()) factionID = ptr.getClass().getPrimaryFaction(ptr);
{
factionID = "";
}
else
{
factionID = ptr.getClass().getNpcStats(ptr).getFactionRanks().begin()->first;
}
} }
::Misc::StringUtils::toLower(factionID); ::Misc::StringUtils::toLower(factionID);
// Make sure this faction exists // Make sure this faction exists
@ -779,8 +771,7 @@ namespace MWScript
} }
else else
{ {
if (!ptr.getClass().getNpcStats (ptr).getFactionRanks().empty()) factionId = getDialogueActorFaction(ptr);
factionId = ptr.getClass().getNpcStats (ptr).getFactionRanks().begin()->first;
} }
if (factionId.empty()) if (factionId.empty())
@ -815,8 +806,7 @@ namespace MWScript
} }
else else
{ {
if (!ptr.getClass().getNpcStats (ptr).getFactionRanks().empty()) factionId = getDialogueActorFaction(ptr);
factionId = ptr.getClass().getNpcStats (ptr).getFactionRanks().begin()->first;
} }
if (factionId.empty()) if (factionId.empty())
@ -850,8 +840,7 @@ namespace MWScript
} }
else else
{ {
if (!ptr.getClass().getNpcStats (ptr).getFactionRanks().empty()) factionId = getDialogueActorFaction(ptr);
factionId = ptr.getClass().getNpcStats (ptr).getFactionRanks().begin()->first;
} }
if (factionId.empty()) if (factionId.empty())
@ -941,14 +930,7 @@ namespace MWScript
} }
else else
{ {
if(ptr.getClass().getNpcStats(ptr).getFactionRanks().empty()) factionID = ptr.getClass().getPrimaryFaction(ptr);
{
factionID = "";
}
else
{
factionID = ptr.getClass().getNpcStats(ptr).getFactionRanks().begin()->first;
}
} }
::Misc::StringUtils::toLower(factionID); ::Misc::StringUtils::toLower(factionID);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
@ -980,14 +962,7 @@ namespace MWScript
} }
else else
{ {
if(ptr.getClass().getNpcStats(ptr).getFactionRanks().empty()) factionID = ptr.getClass().getPrimaryFaction(ptr);
{
factionID = "";
}
else
{
factionID = ptr.getClass().getNpcStats(ptr).getFactionRanks().begin()->first;
}
} }
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
if(factionID!="") if(factionID!="")
@ -1014,14 +989,7 @@ namespace MWScript
} }
else else
{ {
if(ptr.getClass().getNpcStats(ptr).getFactionRanks().empty()) factionID = ptr.getClass().getPrimaryFaction(ptr);
{
factionID = "";
}
else
{
factionID = ptr.getClass().getNpcStats(ptr).getFactionRanks().begin()->first;
}
} }
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
if(factionID!="") if(factionID!="")
@ -1038,13 +1006,10 @@ namespace MWScript
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
std::string factionID = ""; std::string factionID = ptr.getClass().getPrimaryFaction(ptr);
if(ptr.getClass().getNpcStats(ptr).getFactionRanks().empty()) if(factionID.empty())
return; return;
else
{
factionID = ptr.getClass().getNpcStats(ptr).getFactionRanks().begin()->first;
}
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
// no-op when executed on the player // no-op when executed on the player
@ -1064,13 +1029,10 @@ namespace MWScript
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
std::string factionID = ""; std::string factionID = ptr.getClass().getPrimaryFaction(ptr);
if(ptr.getClass().getNpcStats(ptr).getFactionRanks().empty()) if(factionID.empty())
return; return;
else
{
factionID = ptr.getClass().getNpcStats(ptr).getFactionRanks().begin()->first;
}
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
// no-op when executed on the player // no-op when executed on the player

@ -445,4 +445,13 @@ namespace MWWorld
{ {
throw std::runtime_error("class does not support fight rating"); throw std::runtime_error("class does not support fight rating");
} }
std::string Class::getPrimaryFaction (const MWWorld::Ptr& ptr) const
{
return std::string();
}
int Class::getPrimaryFactionRank (const MWWorld::Ptr& ptr) const
{
return -1;
}
} }

@ -342,6 +342,9 @@ namespace MWWorld
virtual std::string getSound(const MWWorld::Ptr& ptr) const; virtual std::string getSound(const MWWorld::Ptr& ptr) const;
virtual int getBaseFightRating (const MWWorld::Ptr& ptr) const; virtual int getBaseFightRating (const MWWorld::Ptr& ptr) const;
virtual std::string getPrimaryFaction (const MWWorld::Ptr& ptr) const;
virtual int getPrimaryFactionRank (const MWWorld::Ptr& ptr) const;
}; };
} }

@ -144,4 +144,14 @@ void NPC::save(ESMWriter &esm) const
mHair.clear(); mHair.clear();
mHead.clear(); mHead.clear();
} }
int NPC::getFactionRank() const
{
if (mFaction.empty())
return -1;
else if (mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
return mNpdt12.mRank;
else // NPC_DEFAULT
return mNpdt52.mRank;
}
} }

@ -110,6 +110,8 @@ struct NPC
NPDTstruct52 mNpdt52; NPDTstruct52 mNpdt52;
NPDTstruct12 mNpdt12; //for autocalculated characters NPDTstruct12 mNpdt12; //for autocalculated characters
int getFactionRank() const; /// wrapper for mNpdt*, -1 = no rank
int mFlags; int mFlags;
bool mPersistent; bool mPersistent;

@ -34,7 +34,7 @@ namespace ESM
StatState<int> mWerewolfAttributes[8]; StatState<int> mWerewolfAttributes[8];
bool mIsWerewolf; bool mIsWerewolf;
std::map<std::string, Faction> mFactions; std::map<std::string, Faction> mFactions; // lower case IDs
int mDisposition; int mDisposition;
Skill mSkills[27]; Skill mSkills[27];
int mBounty; int mBounty;
@ -43,7 +43,7 @@ namespace ESM
int mProfit; int mProfit;
int mLevelProgress; int mLevelProgress;
int mSkillIncrease[8]; int mSkillIncrease[8];
std::vector<std::string> mUsedIds; std::vector<std::string> mUsedIds; // lower case IDs
float mTimeToStartDrowning; float mTimeToStartDrowning;
int mCrimeId; int mCrimeId;

Loading…
Cancel
Save