Merge pull request #106 from OpenMW/master

Add OpenMW changes up to 20 Nov
coverity_scan^2
David Cernat 8 years ago committed by GitHub
commit c6eac31d94

@ -132,6 +132,12 @@ namespace MWGui
mReviewDialog->configureSkills(major, minor);
}
void CharacterCreation::onFrame(float duration)
{
if (mReviewDialog)
mReviewDialog->onFrame(duration);
}
void CharacterCreation::spawnDialog(const char id)
{
try

@ -50,6 +50,8 @@ namespace MWGui
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value);
void configureSkills (const SkillList& major, const SkillList& minor);
void onFrame(float duration);
private:
osg::Group* mParent;
Resource::ResourceSystem* mResourceSystem;

@ -10,6 +10,7 @@
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwmechanics/autocalcspell.hpp"
#include "tooltips.hpp"
@ -29,7 +30,8 @@ namespace MWGui
const int ReviewDialog::sLineHeight = 18;
ReviewDialog::ReviewDialog()
: WindowModal("openmw_chargen_review.layout")
: WindowModal("openmw_chargen_review.layout"),
mUpdateSkillArea(false)
{
// Centre dialog
center();
@ -102,7 +104,16 @@ namespace MWGui
void ReviewDialog::open()
{
WindowModal::open();
updateSkillArea();
mUpdateSkillArea = true;
}
void ReviewDialog::onFrame(float /*duration*/)
{
if (mUpdateSkillArea)
{
updateSkillArea();
mUpdateSkillArea = false;
}
}
void ReviewDialog::setPlayerName(const std::string &name)
@ -121,6 +132,8 @@ namespace MWGui
ToolTips::createRaceToolTip(mRaceWidget, race);
mRaceWidget->setCaption(race->mName);
}
mUpdateSkillArea = true;
}
void ReviewDialog::setClass(const ESM::Class& class_)
@ -141,6 +154,8 @@ namespace MWGui
mBirthSignWidget->setCaption(sign->mName);
ToolTips::createBirthsignToolTip(mBirthSignWidget, mBirthSignId);
}
mUpdateSkillArea = true;
}
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<float>& value)
@ -170,7 +185,11 @@ namespace MWGui
if (attr == mAttributeWidgets.end())
return;
attr->second->setAttributeValue(value);
if (attr->second->getAttributeValue() != value)
{
attr->second->setAttributeValue(value);
mUpdateSkillArea = true;
}
}
void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::SkillValue& value)
@ -191,6 +210,7 @@ namespace MWGui
widget->_setWidgetState(state);
}
mUpdateSkillArea = true;
}
void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor)
@ -211,7 +231,7 @@ namespace MWGui
mMiscSkills.push_back(skill);
}
updateSkillArea();
mUpdateSkillArea = true;
}
void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
@ -245,7 +265,7 @@ namespace MWGui
skillNameWidget->setCaption(text);
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
skillValueWidget = mSkillView->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Top | MyGUI::Align::Right);
skillValueWidget = mSkillView->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Default);
skillValueWidget->setCaption(value);
skillValueWidget->_setWidgetState(state);
skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
@ -273,6 +293,20 @@ namespace MWGui
coord2.top += sLineHeight;
}
void ReviewDialog::addItem(const ESM::Spell* spell, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2)
{
Widgets::MWSpellPtr widget = mSkillView->createWidget<Widgets::MWSpell>("MW_StatName", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
widget->setSpellId(spell->mId);
widget->setUserString("ToolTipType", "Spell");
widget->setUserString("Spell", spell->mId);
widget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
mSkillWidgets.push_back(widget);
coord1.top += sLineHeight;
coord2.top += sLineHeight;
}
void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
// Add a line separator if there are items above
@ -332,6 +366,80 @@ namespace MWGui
if (!mMiscSkills.empty())
addSkills(mMiscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
// starting spells
std::vector<std::string> spells;
const ESM::Race* race = NULL;
if (!mRaceId.empty())
race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(mRaceId);
int skills[ESM::Skill::Length];
for (int i=0; i<ESM::Skill::Length; ++i)
skills[i] = mSkillValues.find(i)->second.getBase();
int attributes[ESM::Attribute::Length];
for (int i=0; i<ESM::Attribute::Length; ++i)
attributes[i] = mAttributeWidgets[i]->getAttributeValue().getBase();
std::vector<std::string> selectedSpells = MWMechanics::autoCalcPlayerSpells(skills, attributes, race);
for (std::vector<std::string>::iterator iter = selectedSpells.begin(); iter != selectedSpells.end(); ++iter)
{
std::string lower = Misc::StringUtils::lowerCase(*iter);
if (std::find(spells.begin(), spells.end(), lower) == spells.end())
spells.push_back(lower);
}
if (race)
{
for (std::vector<std::string>::const_iterator iter = race->mPowers.mList.begin();
iter != race->mPowers.mList.end(); ++iter)
{
std::string lower = Misc::StringUtils::lowerCase(*iter);
if (std::find(spells.begin(), spells.end(), lower) == spells.end())
spells.push_back(lower);
}
}
if (!mBirthSignId.empty())
{
const ESM::BirthSign* sign = MWBase::Environment::get().getWorld()->getStore().get<ESM::BirthSign>().find(mBirthSignId);
for (std::vector<std::string>::const_iterator iter = sign->mPowers.mList.begin();
iter != sign->mPowers.mList.end(); ++iter)
{
std::string lower = Misc::StringUtils::lowerCase(*iter);
if (std::find(spells.begin(), spells.end(), lower) == spells.end())
spells.push_back(lower);
}
}
if (!mSkillWidgets.empty())
addSeparator(coord1, coord2);
addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sTypeAbility", "Abilities"), coord1, coord2);
for (std::vector<std::string>::const_iterator iter = spells.begin(); iter != spells.end(); ++iter)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(*iter);
if (spell->mData.mType == ESM::Spell::ST_Ability)
addItem(spell, coord1, coord2);
}
addSeparator(coord1, coord2);
addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sTypePower", "Powers"), coord1, coord2);
for (std::vector<std::string>::const_iterator iter = spells.begin(); iter != spells.end(); ++iter)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(*iter);
if (spell->mData.mType == ESM::Spell::ST_Power)
addItem(spell, coord1, coord2);
}
addSeparator(coord1, coord2);
addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sTypeSpell", "Spells"), coord1, coord2);
for (std::vector<std::string>::const_iterator iter = spells.begin(); iter != spells.end(); ++iter)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(*iter);
if (spell->mData.mType == ESM::Spell::ST_Spell)
addItem(spell, coord1, coord2);
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mSkillView->setVisibleVScroll(false);
mSkillView->setCanvasSize (mSkillView->getWidth(), std::max(mSkillView->getHeight(), coord1.top));

@ -6,6 +6,11 @@
#include "windowbase.hpp"
#include "widgets.hpp"
namespace ESM
{
class Spell;
}
namespace MWGui
{
class WindowManager;
@ -42,6 +47,8 @@ namespace MWGui
virtual void open();
void onFrame(float duration);
// Events
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_Int;
@ -75,6 +82,7 @@ namespace MWGui
void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
MyGUI::TextBox* addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addItem(const ESM::Spell* spell, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void updateSkillArea();
static const int sLineHeight;
@ -92,6 +100,8 @@ namespace MWGui
std::string mName, mRaceId, mBirthSignId;
ESM::Class mKlass;
std::vector<MyGUI::Widget*> mSkillWidgets; //< Skills and other information
bool mUpdateSkillArea;
};
}
#endif

@ -1009,6 +1009,9 @@ namespace MWGui
mScreenFader->update(frameDuration);
mDebugWindow->onFrame(frameDuration);
if (mCharGen)
mCharGen->onFrame(frameDuration);
}
void WindowManager::changeCell(const MWWorld::CellStore* cell)

@ -141,6 +141,79 @@ namespace MWMechanics
return selectedSpells;
}
std::vector<std::string> autoCalcPlayerSpells(const int* actorSkills, const int* actorAttributes, const ESM::Race* race)
{
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
static const float fPCbaseMagickaMult = esmStore.get<ESM::GameSetting>().find("fPCbaseMagickaMult")->getFloat();
float baseMagicka = fPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence];
bool reachedLimit = false;
const ESM::Spell* weakestSpell = NULL;
int minCost = INT_MAX;
std::vector<std::string> selectedSpells;
const MWWorld::Store<ESM::Spell> &spells =
esmStore.get<ESM::Spell>();
for (MWWorld::Store<ESM::Spell>::iterator iter = spells.begin(); iter != spells.end(); ++iter)
{
const ESM::Spell* spell = &*iter;
if (spell->mData.mType != ESM::Spell::ST_Spell)
continue;
if (!(spell->mData.mFlags & ESM::Spell::F_PCStart))
continue;
if (reachedLimit && spell->mData.mCost <= minCost)
continue;
if (race && std::find(race->mPowers.mList.begin(), race->mPowers.mList.end(), spell->mId) != race->mPowers.mList.end())
continue;
if (baseMagicka < spell->mData.mCost)
continue;
static const float fAutoPCSpellChance = esmStore.get<ESM::GameSetting>().find("fAutoPCSpellChance")->getFloat();
if (calcAutoCastChance(spell, actorSkills, actorAttributes, -1) < fAutoPCSpellChance)
continue;
if (!attrSkillCheck(spell, actorSkills, actorAttributes))
continue;
selectedSpells.push_back(spell->mId);
if (reachedLimit)
{
std::vector<std::string>::iterator it = std::find(selectedSpells.begin(), selectedSpells.end(), weakestSpell->mId);
if (it != selectedSpells.end())
selectedSpells.erase(it);
minCost = INT_MAX;
for (std::vector<std::string>::iterator weakIt = selectedSpells.begin(); weakIt != selectedSpells.end(); ++weakIt)
{
const ESM::Spell* testSpell = esmStore.get<ESM::Spell>().find(*weakIt);
if (testSpell->mData.mCost < minCost)
{
minCost = testSpell->mData.mCost;
weakestSpell = testSpell;
}
}
}
else
{
if (spell->mData.mCost < minCost)
{
weakestSpell = spell;
minCost = weakestSpell->mData.mCost;
}
static const unsigned int iAutoPCSpellMax = esmStore.get<ESM::GameSetting>().find("iAutoPCSpellMax")->getInt();
if (selectedSpells.size() == iAutoPCSpellMax)
reachedLimit = true;
}
}
return selectedSpells;
}
bool attrSkillCheck (const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes)
{
const std::vector<ESM::ENAMstruct>& effects = spell->mEffects.mList;

@ -16,6 +16,8 @@ namespace MWMechanics
std::vector<std::string> autoCalcNpcSpells(const int* actorSkills, const int* actorAttributes, const ESM::Race* race);
std::vector<std::string> autoCalcPlayerSpells(const int* actorSkills, const int* actorAttributes, const ESM::Race* race);
// Helpers
bool attrSkillCheck (const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes);

@ -198,15 +198,6 @@ namespace MWMechanics
}
// F_PCStart spells
static const float fPCbaseMagickaMult = esmStore.get<ESM::GameSetting>().find("fPCbaseMagickaMult")->getFloat();
float baseMagicka = fPCbaseMagickaMult * creatureStats.getAttribute(ESM::Attribute::Intelligence).getBase();
bool reachedLimit = false;
const ESM::Spell* weakestSpell = NULL;
int minCost = INT_MAX;
std::vector<std::string> selectedSpells;
const ESM::Race* race = NULL;
if (mRaceSelected)
race = esmStore.get<ESM::Race>().find(player->mRace);
@ -219,61 +210,7 @@ namespace MWMechanics
for (int i=0; i<ESM::Attribute::Length; ++i)
attributes[i] = npcStats.getAttribute(i).getBase();
const MWWorld::Store<ESM::Spell> &spells =
esmStore.get<ESM::Spell>();
for (MWWorld::Store<ESM::Spell>::iterator iter = spells.begin(); iter != spells.end(); ++iter)
{
const ESM::Spell* spell = &*iter;
if (spell->mData.mType != ESM::Spell::ST_Spell)
continue;
if (!(spell->mData.mFlags & ESM::Spell::F_PCStart))
continue;
if (reachedLimit && spell->mData.mCost <= minCost)
continue;
if (race && std::find(race->mPowers.mList.begin(), race->mPowers.mList.end(), spell->mId) != race->mPowers.mList.end())
continue;
if (baseMagicka < spell->mData.mCost)
continue;
static const float fAutoPCSpellChance = esmStore.get<ESM::GameSetting>().find("fAutoPCSpellChance")->getFloat();
if (calcAutoCastChance(spell, skills, attributes, -1) < fAutoPCSpellChance)
continue;
if (!attrSkillCheck(spell, skills, attributes))
continue;
selectedSpells.push_back(spell->mId);
if (reachedLimit)
{
std::vector<std::string>::iterator it = std::find(selectedSpells.begin(), selectedSpells.end(), weakestSpell->mId);
if (it != selectedSpells.end())
selectedSpells.erase(it);
minCost = INT_MAX;
for (std::vector<std::string>::iterator weakIt = selectedSpells.begin(); weakIt != selectedSpells.end(); ++weakIt)
{
const ESM::Spell* testSpell = esmStore.get<ESM::Spell>().find(*weakIt);
if (testSpell->mData.mCost < minCost)
{
minCost = testSpell->mData.mCost;
weakestSpell = testSpell;
}
}
}
else
{
if (spell->mData.mCost < minCost)
{
weakestSpell = spell;
minCost = weakestSpell->mData.mCost;
}
static const unsigned int iAutoPCSpellMax = esmStore.get<ESM::GameSetting>().find("iAutoPCSpellMax")->getInt();
if (selectedSpells.size() == iAutoPCSpellMax)
reachedLimit = true;
}
}
std::vector<std::string> selectedSpells = autoCalcPlayerSpells(skills, attributes, race);
for (std::vector<std::string>::iterator it = selectedSpells.begin(); it != selectedSpells.end(); ++it)
creatureStats.getSpells().add(*it);

@ -403,6 +403,9 @@ void NpcAnimation::rebuild()
{
updateNpcBase();
if (mAlpha != 1.f)
mResourceSystem->getSceneManager()->recreateShaders(mObjectRoot);
MWBase::Environment::get().getMechanicsManager()->forceStateUpdate(mPtr);
}
@ -503,10 +506,10 @@ void NpcAnimation::updateNpcBase()
if(!isWerewolf)
{
if(Misc::StringUtils::lowerCase(mNpc->mRace).find("argonian") != std::string::npos)
addAnimSource("meshes\\xargonian_swimkna.nif");
if(mNpc->mModel.length() > 0)
addAnimSource(Misc::ResourceHelpers::correctActorModelPath("meshes\\" + mNpc->mModel, mResourceSystem->getVFS()));
if(Misc::StringUtils::lowerCase(mNpc->mRace).find("argonian") != std::string::npos)
addAnimSource("meshes\\xargonian_swimkna.nif");
}
}
else

Loading…
Cancel
Save