mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 18:35:20 +00:00
Reduce skill lookups by index
This commit is contained in:
parent
16c0f0d5cc
commit
1b956521fc
@ -93,7 +93,7 @@ namespace MWGui
|
|||||||
for (int day = 0; day < mDays; ++day)
|
for (int day = 0; day < mDays; ++day)
|
||||||
{
|
{
|
||||||
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||||
const ESM::Skill* skill = skillStore.find(Misc::Rng::rollDice(ESM::Skill::Length, prng));
|
const ESM::Skill* skill = skillStore.searchRandom({}, prng);
|
||||||
skills.insert(skill);
|
skills.insert(skill);
|
||||||
|
|
||||||
MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill->mIndex);
|
MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill->mIndex);
|
||||||
|
@ -21,24 +21,6 @@
|
|||||||
|
|
||||||
#include "tooltips.hpp"
|
#include "tooltips.hpp"
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
// Sorts a container descending by skill value. If skill value is equal, sorts ascending by skill ID.
|
|
||||||
// pair <skill ID, skill value>
|
|
||||||
bool sortSkills(const std::pair<int, int>& left, const std::pair<int, int>& right)
|
|
||||||
{
|
|
||||||
if (left == right)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (left.second > right.second)
|
|
||||||
return true;
|
|
||||||
else if (left.second < right.second)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return left.first < right.first;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -80,34 +62,37 @@ namespace MWGui
|
|||||||
|
|
||||||
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold));
|
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold));
|
||||||
|
|
||||||
|
const auto& store = MWBase::Environment::get().getESMStore();
|
||||||
|
const MWWorld::Store<ESM::GameSetting>& gmst = store->get<ESM::GameSetting>();
|
||||||
|
const MWWorld::Store<ESM::Skill>& skillStore = store->get<ESM::Skill>();
|
||||||
|
|
||||||
// NPC can train you in his best 3 skills
|
// NPC can train you in his best 3 skills
|
||||||
std::vector<std::pair<int, float>> skills;
|
std::vector<std::pair<const ESM::Skill*, float>> skills;
|
||||||
|
|
||||||
MWMechanics::NpcStats const& actorStats(actor.getClass().getNpcStats(actor));
|
MWMechanics::NpcStats const& actorStats(actor.getClass().getNpcStats(actor));
|
||||||
for (int i = 0; i < ESM::Skill::Length; ++i)
|
for (const ESM::Skill& skill : skillStore)
|
||||||
{
|
{
|
||||||
float value = getSkillForTraining(actorStats, i);
|
float value = getSkillForTraining(actorStats, skill.mIndex);
|
||||||
|
|
||||||
skills.emplace_back(i, value);
|
skills.emplace_back(&skill, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(skills.begin(), skills.end(), sortSkills);
|
std::sort(skills.begin(), skills.end(), [](const auto& left, const auto& right) {
|
||||||
|
return std::tie(right.second, left.first->mId) < std::tie(left.second, right.first->mId);
|
||||||
|
});
|
||||||
|
|
||||||
MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator();
|
MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator();
|
||||||
MyGUI::Gui::getInstance().destroyWidgets(widgets);
|
MyGUI::Gui::getInstance().destroyWidgets(widgets);
|
||||||
|
|
||||||
MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player);
|
MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player);
|
||||||
|
|
||||||
const auto& store = MWBase::Environment::get().getESMStore();
|
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = store->get<ESM::GameSetting>();
|
|
||||||
const MWWorld::Store<ESM::Skill>& skillStore = store->get<ESM::Skill>();
|
|
||||||
|
|
||||||
const int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2;
|
const int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2;
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
|
const ESM::Skill* skill = skills[i].first;
|
||||||
int price = static_cast<int>(
|
int price = static_cast<int>(
|
||||||
pcStats.getSkill(skills[i].first).getBase() * gmst.find("iTrainingMod")->mValue.getInteger());
|
pcStats.getSkill(skill->mIndex).getBase() * gmst.find("iTrainingMod")->mValue.getInteger());
|
||||||
price = std::max(1, price);
|
price = std::max(1, price);
|
||||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
|
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
|
||||||
|
|
||||||
@ -120,13 +105,12 @@ namespace MWGui
|
|||||||
button->setUserData(skills[i].first);
|
button->setUserData(skills[i].first);
|
||||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);
|
||||||
|
|
||||||
const ESM::Skill* skill = skillStore.find(skills[i].first);
|
|
||||||
button->setCaptionWithReplacing(
|
button->setCaptionWithReplacing(
|
||||||
MyGUI::TextIterator::toTagsString(skill->mName) + " - " + MyGUI::utility::toString(price));
|
MyGUI::TextIterator::toTagsString(skill->mName) + " - " + MyGUI::utility::toString(price));
|
||||||
|
|
||||||
button->setSize(button->getTextSize().width + 12, button->getSize().height);
|
button->setSize(button->getTextSize().width + 12, button->getSize().height);
|
||||||
|
|
||||||
ToolTips::createSkillToolTip(button, skills[i].first);
|
ToolTips::createSkillToolTip(button, skill->mIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
center();
|
center();
|
||||||
@ -144,29 +128,29 @@ namespace MWGui
|
|||||||
|
|
||||||
void TrainingWindow::onTrainingSelected(MyGUI::Widget* sender)
|
void TrainingWindow::onTrainingSelected(MyGUI::Widget* sender)
|
||||||
{
|
{
|
||||||
int skillId = *sender->getUserData<int>();
|
const ESM::Skill* skill = *sender->getUserData<const ESM::Skill*>();
|
||||||
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player);
|
MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player);
|
||||||
|
|
||||||
const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore();
|
const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore();
|
||||||
|
|
||||||
int price = pcStats.getSkill(skillId).getBase()
|
int price = pcStats.getSkill(skill->mIndex).getBase()
|
||||||
* store.get<ESM::GameSetting>().find("iTrainingMod")->mValue.getInteger();
|
* store.get<ESM::GameSetting>().find("iTrainingMod")->mValue.getInteger();
|
||||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
|
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
|
||||||
|
|
||||||
if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId))
|
if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (getSkillForTraining(mPtr.getClass().getNpcStats(mPtr), skillId) <= pcStats.getSkill(skillId).getBase())
|
if (getSkillForTraining(mPtr.getClass().getNpcStats(mPtr), skill->mIndex)
|
||||||
|
<= pcStats.getSkill(skill->mIndex).getBase())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sServiceTrainingWords}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sServiceTrainingWords}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// You can not train a skill above its governing attribute
|
// You can not train a skill above its governing attribute
|
||||||
const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get<ESM::Skill>().find(skillId);
|
if (pcStats.getSkill(skill->mIndex).getBase() >= pcStats.getAttribute(skill->mData.mAttribute).getBase())
|
||||||
if (pcStats.getSkill(skillId).getBase() >= pcStats.getAttribute(skill->mData.mAttribute).getBase())
|
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage17}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage17}");
|
||||||
return;
|
return;
|
||||||
@ -176,7 +160,7 @@ namespace MWGui
|
|||||||
MWWorld::LiveCellRef<ESM::NPC>* playerRef = player.get<ESM::NPC>();
|
MWWorld::LiveCellRef<ESM::NPC>* playerRef = player.get<ESM::NPC>();
|
||||||
|
|
||||||
const ESM::Class* class_ = store.get<ESM::Class>().find(playerRef->mBase->mClass);
|
const ESM::Class* class_ = store.get<ESM::Class>().find(playerRef->mBase->mClass);
|
||||||
pcStats.increaseSkill(skillId, *class_, true);
|
pcStats.increaseSkill(skill->mIndex, *class_, true);
|
||||||
|
|
||||||
// remove gold
|
// remove gold
|
||||||
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price);
|
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price);
|
||||||
|
@ -155,16 +155,16 @@ namespace MWMechanics
|
|||||||
creatureStats.setAttribute(i, male ? attribute.mMale : attribute.mFemale);
|
creatureStats.setAttribute(i, male ? attribute.mMale : attribute.mFemale);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 27; ++i)
|
for (const ESM::Skill& skill : esmStore.get<ESM::Skill>())
|
||||||
{
|
{
|
||||||
int bonus = 0;
|
int bonus = 0;
|
||||||
|
|
||||||
auto bonusIt = std::find_if(race->mData.mBonus.begin(), race->mData.mBonus.end(),
|
auto bonusIt = std::find_if(race->mData.mBonus.begin(), race->mData.mBonus.end(),
|
||||||
[i](const auto& bonus) { return bonus.mSkill == i; });
|
[&](const auto& bonus) { return bonus.mSkill == skill.mIndex; });
|
||||||
if (bonusIt != race->mData.mBonus.end())
|
if (bonusIt != race->mData.mBonus.end())
|
||||||
bonus = bonusIt->mBonus;
|
bonus = bonusIt->mBonus;
|
||||||
|
|
||||||
npcStats.getSkill(i).setBase(5 + bonus);
|
npcStats.getSkill(skill.mIndex).setBase(5 + bonus);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const ESM::RefId& power : race->mPowers.mList)
|
for (const ESM::RefId& power : race->mPowers.mList)
|
||||||
@ -217,14 +217,7 @@ namespace MWMechanics
|
|||||||
for (const ESM::Skill& skill : esmStore.get<ESM::Skill>())
|
for (const ESM::Skill& skill : esmStore.get<ESM::Skill>())
|
||||||
{
|
{
|
||||||
if (skill.mData.mSpecialization == class_->mData.mSpecialization)
|
if (skill.mData.mSpecialization == class_->mData.mSpecialization)
|
||||||
{
|
npcStats.getSkill(skill.mIndex).setBase(npcStats.getSkill(skill.mIndex).getBase() + 5);
|
||||||
int index = skill.mIndex;
|
|
||||||
|
|
||||||
if (index >= 0 && index < 27)
|
|
||||||
{
|
|
||||||
npcStats.getSkill(index).setBase(npcStats.getSkill(index).getBase() + 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,11 +168,19 @@ namespace MWWorld
|
|||||||
{
|
{
|
||||||
if constexpr (std::is_same_v<Id, ESM::RefId>)
|
if constexpr (std::is_same_v<Id, ESM::RefId>)
|
||||||
{
|
{
|
||||||
std::vector<const T*> results;
|
if (prefix.empty())
|
||||||
std::copy_if(mShared.begin(), mShared.end(), std::back_inserter(results),
|
{
|
||||||
[prefix](const T* item) { return item->mId.startsWith(prefix); });
|
if (!mShared.empty())
|
||||||
if (!results.empty())
|
return mShared[Misc::Rng::rollDice(mShared.size(), prng)];
|
||||||
return results[Misc::Rng::rollDice(results.size(), prng)];
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<const T*> results;
|
||||||
|
std::copy_if(mShared.begin(), mShared.end(), std::back_inserter(results),
|
||||||
|
[prefix](const T* item) { return item->mId.startsWith(prefix); });
|
||||||
|
if (!results.empty())
|
||||||
|
return results[Misc::Rng::rollDice(results.size(), prng)];
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user