|
|
|
@ -84,7 +84,7 @@ namespace
|
|
|
|
|
void autoCalculateAttributes(const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats)
|
|
|
|
|
{
|
|
|
|
|
// race bonus
|
|
|
|
|
const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc->mRace);
|
|
|
|
|
const ESM::Race* race = MWBase::Environment::get().getESMStore()->get<ESM::Race>().find(npc->mRace);
|
|
|
|
|
|
|
|
|
|
bool male = (npc->mFlags & ESM::NPC::Female) == 0;
|
|
|
|
|
|
|
|
|
@ -96,8 +96,7 @@ namespace
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// class bonus
|
|
|
|
|
const ESM::Class* class_
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(npc->mClass);
|
|
|
|
|
const ESM::Class* class_ = MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(npc->mClass);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; ++i)
|
|
|
|
|
{
|
|
|
|
@ -115,7 +114,7 @@ namespace
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < ESM::Skill::Length; ++j)
|
|
|
|
|
{
|
|
|
|
|
const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find(j);
|
|
|
|
|
const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get<ESM::Skill>().find(j);
|
|
|
|
|
|
|
|
|
|
if (skill->mData.mAttribute != attribute)
|
|
|
|
|
continue;
|
|
|
|
@ -174,12 +173,11 @@ namespace
|
|
|
|
|
void autoCalculateSkills(
|
|
|
|
|
const ESM::NPC* npc, MWMechanics::NpcStats& npcStats, const MWWorld::Ptr& ptr, bool spellsInitialised)
|
|
|
|
|
{
|
|
|
|
|
const ESM::Class* class_
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(npc->mClass);
|
|
|
|
|
const ESM::Class* class_ = MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(npc->mClass);
|
|
|
|
|
|
|
|
|
|
unsigned int level = npcStats.getLevel();
|
|
|
|
|
|
|
|
|
|
const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc->mRace);
|
|
|
|
|
const ESM::Race* race = MWBase::Environment::get().getESMStore()->get<ESM::Race>().find(npc->mRace);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; ++i)
|
|
|
|
|
{
|
|
|
|
@ -223,8 +221,7 @@ namespace
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// is this skill in the same Specialization as the class?
|
|
|
|
|
const ESM::Skill* skill
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find(skillIndex);
|
|
|
|
|
const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get<ESM::Skill>().find(skillIndex);
|
|
|
|
|
if (skill->mData.mSpecialization == class_->mData.mSpecialization)
|
|
|
|
|
{
|
|
|
|
|
specMultiplier = 0.5f;
|
|
|
|
@ -276,8 +273,8 @@ namespace MWClass
|
|
|
|
|
static const GMST staticGmst = [] {
|
|
|
|
|
GMST gmst;
|
|
|
|
|
|
|
|
|
|
const MWBase::World* world = MWBase::Environment::get().getWorld();
|
|
|
|
|
const MWWorld::Store<ESM::GameSetting>& store = world->getStore().get<ESM::GameSetting>();
|
|
|
|
|
const MWWorld::Store<ESM::GameSetting>& store
|
|
|
|
|
= MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>();
|
|
|
|
|
|
|
|
|
|
gmst.fMinWalkSpeed = store.find("fMinWalkSpeed");
|
|
|
|
|
gmst.fMaxWalkSpeed = store.find("fMaxWalkSpeed");
|
|
|
|
@ -367,22 +364,19 @@ namespace MWClass
|
|
|
|
|
data->mNpcStats.setDeathAnimationFinished(isPersistent(ptr));
|
|
|
|
|
|
|
|
|
|
// race powers
|
|
|
|
|
const ESM::Race* race
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(ref->mBase->mRace);
|
|
|
|
|
const ESM::Race* race = MWBase::Environment::get().getESMStore()->get<ESM::Race>().find(ref->mBase->mRace);
|
|
|
|
|
data->mNpcStats.getSpells().addAllToInstance(race->mPowers.mList);
|
|
|
|
|
|
|
|
|
|
if (!ref->mBase->mFaction.empty())
|
|
|
|
|
{
|
|
|
|
|
static const int iAutoRepFacMod = MWBase::Environment::get()
|
|
|
|
|
.getWorld()
|
|
|
|
|
->getStore()
|
|
|
|
|
.get<ESM::GameSetting>()
|
|
|
|
|
.getESMStore()
|
|
|
|
|
->get<ESM::GameSetting>()
|
|
|
|
|
.find("iAutoRepFacMod")
|
|
|
|
|
->mValue.getInteger();
|
|
|
|
|
static const int iAutoRepLevMod = MWBase::Environment::get()
|
|
|
|
|
.getWorld()
|
|
|
|
|
->getStore()
|
|
|
|
|
.get<ESM::GameSetting>()
|
|
|
|
|
.getESMStore()
|
|
|
|
|
->get<ESM::GameSetting>()
|
|
|
|
|
.find("iAutoRepLevMod")
|
|
|
|
|
->mValue.getInteger();
|
|
|
|
|
int rank = ref->mBase->getFactionRank();
|
|
|
|
@ -435,8 +429,7 @@ namespace MWClass
|
|
|
|
|
const MWWorld::LiveCellRef<ESM::NPC>* ref = ptr.get<ESM::NPC>();
|
|
|
|
|
|
|
|
|
|
std::string model = Settings::Manager::getString("baseanim", "Models");
|
|
|
|
|
const ESM::Race* race
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(ref->mBase->mRace);
|
|
|
|
|
const ESM::Race* race = MWBase::Environment::get().getESMStore()->get<ESM::Race>().find(ref->mBase->mRace);
|
|
|
|
|
if (race->mData.mFlags & ESM::Race::Beast)
|
|
|
|
|
model = Settings::Manager::getString("baseanimkna", "Models");
|
|
|
|
|
|
|
|
|
@ -446,8 +439,7 @@ namespace MWClass
|
|
|
|
|
void Npc::getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const
|
|
|
|
|
{
|
|
|
|
|
const MWWorld::LiveCellRef<ESM::NPC>* npc = ptr.get<ESM::NPC>();
|
|
|
|
|
const ESM::Race* race
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().search(npc->mBase->mRace);
|
|
|
|
|
const ESM::Race* race = MWBase::Environment::get().getESMStore()->get<ESM::Race>().search(npc->mBase->mRace);
|
|
|
|
|
if (race && race->mData.mFlags & ESM::Race::Beast)
|
|
|
|
|
models.emplace_back(Settings::Manager::getString("baseanimkna", "Models"));
|
|
|
|
|
|
|
|
|
@ -464,14 +456,14 @@ namespace MWClass
|
|
|
|
|
if (!npc->mBase->mHead.empty())
|
|
|
|
|
{
|
|
|
|
|
const ESM::BodyPart* head
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>().search(npc->mBase->mHead);
|
|
|
|
|
= MWBase::Environment::get().getESMStore()->get<ESM::BodyPart>().search(npc->mBase->mHead);
|
|
|
|
|
if (head)
|
|
|
|
|
models.push_back(Misc::ResourceHelpers::correctMeshPath(head->mModel, vfs));
|
|
|
|
|
}
|
|
|
|
|
if (!npc->mBase->mHair.empty())
|
|
|
|
|
{
|
|
|
|
|
const ESM::BodyPart* hair
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>().search(npc->mBase->mHair);
|
|
|
|
|
= MWBase::Environment::get().getESMStore()->get<ESM::BodyPart>().search(npc->mBase->mHair);
|
|
|
|
|
if (hair)
|
|
|
|
|
models.push_back(Misc::ResourceHelpers::correctMeshPath(hair->mModel, vfs));
|
|
|
|
|
}
|
|
|
|
@ -510,7 +502,7 @@ namespace MWClass
|
|
|
|
|
= (female && !it->mFemale.empty()) || (!female && it->mMale.empty()) ? it->mFemale : it->mMale;
|
|
|
|
|
|
|
|
|
|
const ESM::BodyPart* part
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>().search(partname);
|
|
|
|
|
= MWBase::Environment::get().getESMStore()->get<ESM::BodyPart>().search(partname);
|
|
|
|
|
if (part && !part->mModel.empty())
|
|
|
|
|
models.push_back(Misc::ResourceHelpers::correctMeshPath(part->mModel, vfs));
|
|
|
|
|
}
|
|
|
|
@ -536,8 +528,8 @@ namespace MWClass
|
|
|
|
|
if (ptr.getRefData().getCustomData()
|
|
|
|
|
&& ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats.isWerewolf())
|
|
|
|
|
{
|
|
|
|
|
const MWBase::World* world = MWBase::Environment::get().getWorld();
|
|
|
|
|
const MWWorld::Store<ESM::GameSetting>& store = world->getStore().get<ESM::GameSetting>();
|
|
|
|
|
const MWWorld::Store<ESM::GameSetting>& store
|
|
|
|
|
= MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>();
|
|
|
|
|
|
|
|
|
|
return store.find("sWerewolfPopup")->mValue.getString();
|
|
|
|
|
}
|
|
|
|
@ -784,7 +776,7 @@ namespace MWClass
|
|
|
|
|
// 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying
|
|
|
|
|
// something, alert the character controller, scripts, etc.
|
|
|
|
|
|
|
|
|
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
|
|
|
|
const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore();
|
|
|
|
|
const GMST& gmst = getGmst();
|
|
|
|
|
|
|
|
|
|
int chance = store.get<ESM::GameSetting>().find("iVoiceHitOdds")->mValue.getInteger();
|
|
|
|
@ -932,7 +924,7 @@ namespace MWClass
|
|
|
|
|
// Werewolfs can't activate NPCs
|
|
|
|
|
if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
|
|
|
|
|
{
|
|
|
|
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
|
|
|
|
const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore();
|
|
|
|
|
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
|
|
|
|
const ESM::Sound* sound = store.get<ESM::Sound>().searchRandom("WolfNPC", prng);
|
|
|
|
|
|
|
|
|
@ -1153,9 +1145,8 @@ namespace MWClass
|
|
|
|
|
{
|
|
|
|
|
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
|
|
|
|
|
static const float fEncumbranceStrMult = MWBase::Environment::get()
|
|
|
|
|
.getWorld()
|
|
|
|
|
->getStore()
|
|
|
|
|
.get<ESM::GameSetting>()
|
|
|
|
|
.getESMStore()
|
|
|
|
|
->get<ESM::GameSetting>()
|
|
|
|
|
.find("fEncumbranceStrMult")
|
|
|
|
|
->mValue.getFloat();
|
|
|
|
|
return stats.getAttribute(ESM::Attribute::Strength).getModified() * fEncumbranceStrMult;
|
|
|
|
@ -1187,16 +1178,15 @@ namespace MWClass
|
|
|
|
|
|
|
|
|
|
MWWorld::LiveCellRef<ESM::NPC>* ref = ptr.get<ESM::NPC>();
|
|
|
|
|
|
|
|
|
|
const ESM::Class* class_
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(ref->mBase->mClass);
|
|
|
|
|
const ESM::Class* class_ = MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(ref->mBase->mClass);
|
|
|
|
|
|
|
|
|
|
stats.useSkill(skill, *class_, usageType, extraFactor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float Npc::getArmorRating(const MWWorld::Ptr& ptr) const
|
|
|
|
|
{
|
|
|
|
|
const MWBase::World* world = MWBase::Environment::get().getWorld();
|
|
|
|
|
const MWWorld::Store<ESM::GameSetting>& store = world->getStore().get<ESM::GameSetting>();
|
|
|
|
|
const MWWorld::Store<ESM::GameSetting>& store
|
|
|
|
|
= MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>();
|
|
|
|
|
|
|
|
|
|
MWMechanics::NpcStats& stats = getNpcStats(ptr);
|
|
|
|
|
const MWWorld::InventoryStore& invStore = getInventoryStore(ptr);
|
|
|
|
@ -1249,8 +1239,7 @@ namespace MWClass
|
|
|
|
|
|
|
|
|
|
const MWWorld::LiveCellRef<ESM::NPC>* ref = ptr.get<ESM::NPC>();
|
|
|
|
|
|
|
|
|
|
const ESM::Race* race
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(ref->mBase->mRace);
|
|
|
|
|
const ESM::Race* race = MWBase::Environment::get().getESMStore()->get<ESM::Race>().find(ref->mBase->mRace);
|
|
|
|
|
|
|
|
|
|
// Race weight should not affect 1st-person meshes, otherwise it will change hand proportions and can break
|
|
|
|
|
// aiming.
|
|
|
|
@ -1283,8 +1272,7 @@ namespace MWClass
|
|
|
|
|
const ESM::NPC* npc = actor.get<ESM::NPC>()->mBase;
|
|
|
|
|
if (npc->mFlags & ESM::NPC::Autocalc)
|
|
|
|
|
{
|
|
|
|
|
const ESM::Class* class_
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(npc->mClass);
|
|
|
|
|
const ESM::Class* class_ = MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(npc->mClass);
|
|
|
|
|
return class_->mData.mServices;
|
|
|
|
|
}
|
|
|
|
|
return npc->mAiData.mServices;
|
|
|
|
@ -1470,7 +1458,7 @@ namespace MWClass
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
const MWWorld::Store<ESM::GameSetting>& gmst
|
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
|
|
|
|
= MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>();
|
|
|
|
|
static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->mValue.getFloat();
|
|
|
|
|
static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->mValue.getFloat();
|
|
|
|
|
|
|
|
|
|