diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 58fe180e9..6e4c10625 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -118,7 +118,7 @@ namespace MWBase /// Set value for the given ID. virtual void setValue (const std::string& id, const MWMechanics::Stat& value) = 0; virtual void setValue (int parSkill, const MWMechanics::Stat& value) = 0; - virtual void setValue (const std::string& id, const MWMechanics::DynamicStat& value) = 0; + virtual void setValue (const std::string& id, const MWMechanics::DynamicStat& value) = 0; virtual void setValue (const std::string& id, const std::string& value) = 0; virtual void setValue (const std::string& id, int value) = 0; diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 7d63f6922..0005b78ad 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -151,7 +151,7 @@ void CharacterCreation::setValue (const std::string& id, const MWMechanics::Stat } } -void CharacterCreation::setValue (const std::string& id, const MWMechanics::DynamicStat& value) +void CharacterCreation::setValue (const std::string& id, const MWMechanics::DynamicStat& value) { if (mReviewDialog) { @@ -294,17 +294,17 @@ void CharacterCreation::spawnDialog(const char id) } } -void CharacterCreation::setPlayerHealth (const MWMechanics::DynamicStat& value) +void CharacterCreation::setPlayerHealth (const MWMechanics::DynamicStat& value) { mPlayerHealth = value; } -void CharacterCreation::setPlayerMagicka (const MWMechanics::DynamicStat& value) +void CharacterCreation::setPlayerMagicka (const MWMechanics::DynamicStat& value) { mPlayerMagicka = value; } -void CharacterCreation::setPlayerFatigue (const MWMechanics::DynamicStat& value) +void CharacterCreation::setPlayerFatigue (const MWMechanics::DynamicStat& value) { mPlayerFatigue = value; } diff --git a/apps/openmw/mwgui/charactercreation.hpp b/apps/openmw/mwgui/charactercreation.hpp index d65763d0c..28ced2e70 100644 --- a/apps/openmw/mwgui/charactercreation.hpp +++ b/apps/openmw/mwgui/charactercreation.hpp @@ -35,14 +35,14 @@ namespace MWGui //Show a dialog void spawnDialog(const char id); - void setPlayerHealth (const MWMechanics::DynamicStat& value); + void setPlayerHealth (const MWMechanics::DynamicStat& value); - void setPlayerMagicka (const MWMechanics::DynamicStat& value); + void setPlayerMagicka (const MWMechanics::DynamicStat& value); - void setPlayerFatigue (const MWMechanics::DynamicStat& value); + void setPlayerFatigue (const MWMechanics::DynamicStat& value); void setValue (const std::string& id, const MWMechanics::Stat& value); - void setValue (const std::string& id, const MWMechanics::DynamicStat& value); + void setValue (const std::string& id, const MWMechanics::DynamicStat& value); void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat& value); void configureSkills (const SkillList& major, const SkillList& minor); @@ -65,9 +65,9 @@ namespace MWGui std::string mPlayerRaceId; std::string mPlayerBirthSignId; ESM::Class mPlayerClass; - MWMechanics::DynamicStat mPlayerHealth; - MWMechanics::DynamicStat mPlayerMagicka; - MWMechanics::DynamicStat mPlayerFatigue; + MWMechanics::DynamicStat mPlayerHealth; + MWMechanics::DynamicStat mPlayerMagicka; + MWMechanics::DynamicStat mPlayerFatigue; //Class generation vars unsigned mGenerateClassStep; // Keeps track of current step in Generate Class dialog diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index b14833553..72dc0c7fb 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -161,7 +161,7 @@ void HUD::setEffect(const char *img) mEffect1->setImageTexture(img); } -void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat& value) +void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat& value) { static const char *ids[] = { diff --git a/apps/openmw/mwgui/hud.hpp b/apps/openmw/mwgui/hud.hpp index de4228e87..013ad59f0 100644 --- a/apps/openmw/mwgui/hud.hpp +++ b/apps/openmw/mwgui/hud.hpp @@ -14,7 +14,7 @@ namespace MWGui public: HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop); void setEffect(const char *img); - void setValue (const std::string& id, const MWMechanics::DynamicStat& value); + void setValue (const std::string& id, const MWMechanics::DynamicStat& value); void setFPS(float fps); void setTriangleCount(unsigned int count); void setBatchCount(unsigned int count); diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index 9f57a2bdd..610c22bf7 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -4,6 +4,17 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" +#include "../mwworld/class.hpp" + +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/npcstats.hpp" +#include "../mwmechanics/stat.hpp" + +#include +#include namespace MWGui { @@ -26,6 +37,7 @@ namespace MWGui getWidget(b, "Attrib" + boost::lexical_cast(i)); b->setUserData (i-1); b->eventMouseButtonClick += MyGUI::newDelegate(this, &LevelupDialog::onAttributeClicked); + mAttributes.push_back(b); mAttributeValues.push_back(t); @@ -35,29 +47,152 @@ namespace MWGui mAttributeMultipliers.push_back(t); } + int curX = mMainWidget->getWidth()/2 - (16 + 2) * 1.5; + for (int i=0; i<3; ++i) + { + MyGUI::ImageBox* image = mMainWidget->createWidget("ImageBox", MyGUI::IntCoord(curX,250,16,16), MyGUI::Align::Default); + image->setImageTexture ("icons\\tx_goldicon.dds"); + curX += 24+2; + mCoins.push_back(image); + } + center(); + } + + void LevelupDialog::setAttributeValues() + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player); + MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); + + for (int i=0; i<8; ++i) + { + int val = creatureStats.getAttribute (i).getBase (); + if (std::find(mSpentAttributes.begin(), mSpentAttributes.end(), i) != mSpentAttributes.end()) + { + val += pcStats.getLevelupAttributeMultiplier (i); + } + + if (val >= 100) + val = 100; + + mAttributeValues[i]->setCaption(boost::lexical_cast(val)); + } + } + + + void LevelupDialog::resetCoins () + { + int curX = mMainWidget->getWidth()/2 - (16 + 2) * 1.5; + for (int i=0; i<3; ++i) + { + MyGUI::ImageBox* image = mCoins[i]; + image->setCoord(MyGUI::IntCoord(curX,250,16,16)); + curX += 24+2; + } + } + + void LevelupDialog::assignCoins () + { + resetCoins(); + for (unsigned int i=0; igetCaption() == "" ? 0 : 30; + + MyGUI::IntPoint pos = mAttributes[attribute]->getAbsolutePosition() - mMainWidget->getAbsolutePosition() - MyGUI::IntPoint(24+xdiff,-4); + image->setPosition(pos); + } - open(); + setAttributeValues(); } void LevelupDialog::open() { + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player); + MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); + center(); - mClassImage->setImageTexture ("textures\\levelup\\acrobat.dds"); + mSpentAttributes.clear(); + resetCoins(); + + setAttributeValues(); + + // set class image + const ESM::Class& playerClass = MWBase::Environment::get().getWorld ()->getPlayer ().getClass (); + // retrieve the ID to this class + std::string classId; + std::map list = MWBase::Environment::get().getWorld()->getStore ().classes.list; + for (std::map::iterator it = list.begin(); it != list.end(); ++it) + { + if (playerClass.name == it->second.name) + classId = it->first; + } + mClassImage->setImageTexture ("textures\\levelup\\" + classId + ".dds"); /// \todo replace this with INI-imported texts - int level = 2; + int level = creatureStats.getLevel ()+1; mLevelText->setCaptionWithReplacing("#{sLevelUpMenu1} " + boost::lexical_cast(level)); + + for (int i=0; i<8; ++i) + { + MyGUI::TextBox* text = mAttributeMultipliers[i]; + int mult = pcStats.getLevelupAttributeMultiplier (i); + text->setCaption(mult <= 1 ? "" : "x" + boost::lexical_cast(mult)); + } } void LevelupDialog::onOkButtonClicked (MyGUI::Widget* sender) { - MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage36}", std::vector()); + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player); + MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); + + if (mSpentAttributes.size() < 3) + MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage36}", std::vector()); + else + { + // increase attributes + for (int i=0; i<3; ++i) + { + MWMechanics::Stat& attribute = creatureStats.getAttribute(mSpentAttributes[i]); + attribute.setBase (attribute.getBase () + pcStats.getLevelupAttributeMultiplier (mSpentAttributes[i])); + + if (attribute.getBase() >= 100) + attribute.setBase(100); + } + + // "When you gain a level, in addition to increasing three primary attributes, your Health + // will automatically increase by 10% of your Endurance attribute. If you increased Endurance this level, + // the Health increase is calculated from the increased Endurance" + creatureStats.increaseLevelHealthBonus (creatureStats.getAttribute(ESM::Attribute::Endurance).getBase() * 0.1f); + + creatureStats.setLevel (creatureStats.getLevel()+1); + pcStats.levelUp (); + + mWindowManager.removeGuiMode (GM_Rest); + } + } void LevelupDialog::onAttributeClicked (MyGUI::Widget *sender) { - int index = *sender->getUserData(); + int attribute = *sender->getUserData(); + + std::vector::iterator found = std::find(mSpentAttributes.begin(), mSpentAttributes.end(), attribute); + if (found != mSpentAttributes.end()) + mSpentAttributes.erase (found); + else + { + if (mSpentAttributes.size() == 3) + mSpentAttributes[2] = attribute; + else + mSpentAttributes.push_back(attribute); + } + assignCoins(); } } diff --git a/apps/openmw/mwgui/levelupdialog.hpp b/apps/openmw/mwgui/levelupdialog.hpp index 181868e9e..f5b24530d 100644 --- a/apps/openmw/mwgui/levelupdialog.hpp +++ b/apps/openmw/mwgui/levelupdialog.hpp @@ -18,11 +18,20 @@ namespace MWGui MyGUI::ImageBox* mClassImage; MyGUI::TextBox* mLevelText; + std::vector mAttributes; std::vector mAttributeValues; std::vector mAttributeMultipliers; + std::vector mCoins; + + std::vector mSpentAttributes; void onOkButtonClicked (MyGUI::Widget* sender); void onAttributeClicked (MyGUI::Widget* sender); + + void assignCoins(); + void resetCoins(); + + void setAttributeValues(); }; } diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index 76b211b18..411fead08 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -134,21 +134,21 @@ void ReviewDialog::setBirthSign(const std::string& signId) } } -void ReviewDialog::setHealth(const MWMechanics::DynamicStat& value) +void ReviewDialog::setHealth(const MWMechanics::DynamicStat& value) { mHealth->setValue(value.getCurrent(), value.getModified()); std::string valStr = boost::lexical_cast(value.getCurrent()) + "/" + boost::lexical_cast(value.getModified()); mHealth->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr); } -void ReviewDialog::setMagicka(const MWMechanics::DynamicStat& value) +void ReviewDialog::setMagicka(const MWMechanics::DynamicStat& value) { mMagicka->setValue(value.getCurrent(), value.getModified()); std::string valStr = boost::lexical_cast(value.getCurrent()) + "/" + boost::lexical_cast(value.getModified()); mMagicka->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr); } -void ReviewDialog::setFatigue(const MWMechanics::DynamicStat& value) +void ReviewDialog::setFatigue(const MWMechanics::DynamicStat& value) { mFatigue->setValue(value.getCurrent(), value.getModified()); std::string valStr = boost::lexical_cast(value.getCurrent()) + "/" + boost::lexical_cast(value.getModified()); diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index 058e3cff3..2b0740234 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -35,9 +35,9 @@ namespace MWGui void setClass(const ESM::Class& class_); void setBirthSign (const std::string &signId); - void setHealth(const MWMechanics::DynamicStat& value); - void setMagicka(const MWMechanics::DynamicStat& value); - void setFatigue(const MWMechanics::DynamicStat& value); + void setHealth(const MWMechanics::DynamicStat& value); + void setMagicka(const MWMechanics::DynamicStat& value); + void setFatigue(const MWMechanics::DynamicStat& value); void setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat& value); diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index ffbfd7d78..88bc3dc90 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -95,6 +95,7 @@ void StatsWindow::setBar(const std::string& name, const std::string& tname, int getWidget(pt, name); pt->setProgressRange(max); pt->setProgressPosition(val); + std::cout << "set bar " << name << val << " " << max << std::endl; std::stringstream out; out << val << "/" << max; @@ -137,7 +138,7 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat& } } -void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat& value) +void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat& value) { static const char *ids[] = { @@ -150,7 +151,7 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicSta if (ids[i]==id) { std::string id (ids[i]); - setBar (id, id + "T", value.getCurrent(), value.getModified()); + setBar (id, id + "T", static_cast(value.getCurrent()), static_cast(value.getModified())); // health, magicka, fatigue tooltip MyGUI::Widget* w; @@ -236,12 +237,21 @@ void StatsWindow::configureSkills (const std::vector& major, const std::vec void StatsWindow::onFrame () { - if (mMainWidget->getVisible()) + if (!mMainWidget->getVisible()) return; MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWMechanics::NpcStats PCstats = MWWorld::Class::get(player).getNpcStats(player); + // level progress + MyGUI::Widget* levelWidget; + for (int i=0; i<2; ++i) + { + getWidget(levelWidget, i==0 ? "Level_str" : "LevelText"); + levelWidget->setUserString("RangePosition_LevelProgress", boost::lexical_cast(PCstats.getLevelProgress())); + levelWidget->setUserString("Caption_LevelProgressText", boost::lexical_cast(PCstats.getLevelProgress()) + "/10"); + } + setFactions(PCstats.getFactionRanks()); setBirthSign(MWBase::Environment::get().getWorld()->getPlayer().getBirthsign()); diff --git a/apps/openmw/mwgui/stats_window.hpp b/apps/openmw/mwgui/stats_window.hpp index 73c4706dd..75f8c568b 100644 --- a/apps/openmw/mwgui/stats_window.hpp +++ b/apps/openmw/mwgui/stats_window.hpp @@ -32,7 +32,7 @@ namespace MWGui /// Set value for the given ID. void setValue (const std::string& id, const MWMechanics::Stat& value); - void setValue (const std::string& id, const MWMechanics::DynamicStat& value); + void setValue (const std::string& id, const MWMechanics::DynamicStat& value); void setValue (const std::string& id, const std::string& value); void setValue (const std::string& id, int value); void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat& value); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 670f6122e..465f2c239 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -250,6 +250,7 @@ void WindowManager::updateVisible() mAlchemyWindow->setVisible(false); mSpellWindow->setVisible(false); mQuickKeysMenu->setVisible(false); + mLevelupDialog->setVisible(false); mHud->setVisible(true); @@ -301,6 +302,9 @@ void WindowManager::updateVisible() case GM_Alchemy: mAlchemyWindow->setVisible(true); break; + case GM_Rest: + mLevelupDialog->setVisible(true); + break; case GM_Name: case GM_Race: case GM_Class: @@ -398,8 +402,9 @@ void WindowManager::setValue (int parSkill, const MWMechanics::Stat& valu mPlayerSkillValues[parSkill] = value; } -void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat& value) +void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat& value) { + std::cout << " set value " << id << value.getModified () << std::endl; mStatsWindow->setValue (id, value); mHud->setValue (id, value); mCharGen->setValue(id, value); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 09d2f0c7d..131029ed4 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -118,7 +118,7 @@ namespace MWGui ///< Set value for the given ID. virtual void setValue (const std::string& id, const MWMechanics::Stat& value); virtual void setValue (int parSkill, const MWMechanics::Stat& value); - virtual void setValue (const std::string& id, const MWMechanics::DynamicStat& value); + virtual void setValue (const std::string& id, const MWMechanics::DynamicStat& value); virtual void setValue (const std::string& id, const std::string& value); virtual void setValue (const std::string& id, int value); @@ -243,7 +243,7 @@ namespace MWGui std::map > mPlayerAttributes; SkillList mPlayerMajorSkills, mPlayerMinorSkills; std::map > mPlayerSkillValues; - MWMechanics::DynamicStat mPlayerHealth, mPlayerMagicka, mPlayerFatigue; + MWMechanics::DynamicStat mPlayerHealth, mPlayerMagicka, mPlayerFatigue; MyGUI::Gui *mGui; // Gui diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index b198785d2..724dccd8e 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -190,6 +190,9 @@ namespace MWInput case A_ToggleWeapon: toggleWeapon (); break; + case A_Rest: + rest(); + break; case A_ToggleSpell: toggleSpell (); break; @@ -543,6 +546,12 @@ namespace MWInput } } + void InputManager::rest() + { + if (!mWindows.isGuiMode ()) + mWindows.pushGuiMode (MWGui::GM_Rest); + } + void InputManager::screenshot() { mEngine.screenshot(); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 7d03f1d5b..5e6169f68 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -168,6 +168,7 @@ namespace MWInput void toggleWalking(); void toggleAutoMove(); void exitNow(); + void rest(); void quickKey (int index); void showQuickKeysMenu(); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index bd037df9f..b4cc40fec 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -68,7 +68,7 @@ namespace MWMechanics creatureStats.getMagicEffects().get (EffectKey (84)).mMagnitude * 0.1 + 0.5; creatureStats.getHealth().setBase( - static_cast (0.5 * (strength + endurance))); + static_cast (0.5 * (strength + endurance)) + creatureStats.getLevelHealthBonus ()); creatureStats.getMagicka().setBase( static_cast (intelligence + magickaFactor * intelligence)); diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 91a9225fe..fc0523141 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -9,6 +9,21 @@ namespace MWMechanics { + CreatureStats::CreatureStats() + : mLevelHealthBonus(0.f) + { + } + + void CreatureStats::increaseLevelHealthBonus (float value) + { + mLevelHealthBonus += value; + } + + float CreatureStats::getLevelHealthBonus () const + { + return mLevelHealthBonus; + } + const AiSequence& CreatureStats::getAiSequence() const { return mAiSequence; @@ -40,17 +55,17 @@ namespace MWMechanics return mAttributes[index]; } - const DynamicStat &CreatureStats::getHealth() const + const DynamicStat &CreatureStats::getHealth() const { return mDynamic[0]; } - const DynamicStat &CreatureStats::getMagicka() const + const DynamicStat &CreatureStats::getMagicka() const { return mDynamic[1]; } - const DynamicStat &CreatureStats::getFatigue() const + const DynamicStat &CreatureStats::getFatigue() const { return mDynamic[2]; } @@ -103,22 +118,22 @@ namespace MWMechanics return mAttributes[index]; } - DynamicStat &CreatureStats::getHealth() + DynamicStat &CreatureStats::getHealth() { return mDynamic[0]; } - DynamicStat &CreatureStats::getMagicka() + DynamicStat &CreatureStats::getMagicka() { return mDynamic[1]; } - DynamicStat &CreatureStats::getFatigue() + DynamicStat &CreatureStats::getFatigue() { return mDynamic[2]; } - DynamicStat &CreatureStats::getDynamic(int index) + DynamicStat &CreatureStats::getDynamic(int index) { if (index < 0 || index > 2) { throw std::runtime_error("dynamic stat index is out of range"); @@ -154,17 +169,17 @@ namespace MWMechanics mAttributes[index] = value; } - void CreatureStats::setHealth(const DynamicStat &value) + void CreatureStats::setHealth(const DynamicStat &value) { mDynamic[0] = value; } - void CreatureStats::setMagicka(const DynamicStat &value) + void CreatureStats::setMagicka(const DynamicStat &value) { mDynamic[1] = value; } - void CreatureStats::setFatigue(const DynamicStat &value) + void CreatureStats::setFatigue(const DynamicStat &value) { mDynamic[2] = value; } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index a6fb6779a..7a1e46f56 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -19,7 +19,7 @@ namespace MWMechanics class CreatureStats { Stat mAttributes[8]; - DynamicStat mDynamic[3]; // health, magicka, fatigue + DynamicStat mDynamic[3]; // health, magicka, fatigue int mLevel; Spells mSpells; ActiveSpells mActiveSpells; @@ -30,15 +30,18 @@ namespace MWMechanics int mAlarm; AiSequence mAiSequence; + float mLevelHealthBonus; + public: + CreatureStats(); const Stat & getAttribute(int index) const; - const DynamicStat & getHealth() const; + const DynamicStat & getHealth() const; - const DynamicStat & getMagicka() const; + const DynamicStat & getMagicka() const; - const DynamicStat & getFatigue() const; + const DynamicStat & getFatigue() const; const Spells & getSpells() const; @@ -59,13 +62,13 @@ namespace MWMechanics Stat & getAttribute(int index); - DynamicStat & getHealth(); + DynamicStat & getHealth(); - DynamicStat & getMagicka(); + DynamicStat & getMagicka(); - DynamicStat & getFatigue(); + DynamicStat & getFatigue(); - DynamicStat & getDynamic(int index); + DynamicStat & getDynamic(int index); Spells & getSpells(); @@ -76,11 +79,11 @@ namespace MWMechanics void setAttribute(int index, const Stat &value); - void setHealth(const DynamicStat &value); + void setHealth(const DynamicStat &value); - void setMagicka(const DynamicStat &value); + void setMagicka(const DynamicStat &value); - void setFatigue(const DynamicStat &value); + void setFatigue(const DynamicStat &value); void setSpells(const Spells &spells); @@ -104,6 +107,10 @@ namespace MWMechanics float getFatigueTerm() const; ///< Return effective fatigue + + // small hack to allow the fact that Health permanently increases by 10% of endurance on each level up + void increaseLevelHealthBonus(float value); + float getLevelHealthBonus() const; }; } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index d2908e26e..fc99c44a8 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -12,10 +12,16 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/windowmanager.hpp" MWMechanics::NpcStats::NpcStats() : mMovementFlags (0), mDrawState (DrawState_Nothing) -{} +, mLevelProgress(0) +{ + mSkillIncreases.resize (ESM::Attribute::Length); + for (int i=0; i (base)!=level) + { + // skill leveled up base = level+1; + // if this is a major or minor skill of the class, increase level progress + //bool levelProgress = false; + bool levelProgress = true; + for (int i=0; i<2; ++i) + for (int j=0; j<5; ++j) + { + int skill = class_.data.skills[j][i]; + if (skill == skillIndex) + levelProgress = true; + } + + if (!levelProgress) + std::cout <<"This is not a level skilL" << std::endl; + + mLevelProgress += levelProgress; + + // check the attribute this skill belongs to + const ESM::Skill* skill = MWBase::Environment::get().getWorld ()->getStore ().skills.find(skillIndex); + ++mSkillIncreases[skill->data.attribute]; + + if (mLevelProgress >= 10) + { + // levelup is possible now + MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", std::vector()); + } + } + getSkill (skillIndex).setBase (base); } + +int MWMechanics::NpcStats::getLevelProgress () const +{ + return mLevelProgress; +} + +void MWMechanics::NpcStats::levelUp() +{ + mLevelProgress -= 10; + for (int i=0; i #include #include +#include #include "stat.hpp" #include "drawstate.hpp" @@ -45,6 +46,10 @@ namespace MWMechanics unsigned int mMovementFlags; Stat mSkill[27]; + int mLevelProgress; // 0-10 + + std::vector mSkillIncreases; // number of skill increases for each attribute + public: NpcStats(); @@ -73,6 +78,12 @@ namespace MWMechanics void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1); ///< Increase skill by usage. + + int getLevelProgress() const; + + int getLevelupAttributeMultiplier(int attribute) const; + + void levelUp(); }; } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 59b9bca35..8052c6a08 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -183,4 +183,8 @@ op 0x2000172: GetStartingAngle op 0x2000173: GetStartingAngle, explicit reference op 0x2000174: ToggleVanityMode op 0x2000175-0x200018B: Get controls disabled -opcodes 0x200018C-0x3ffffff unused +op 0x200018C: GetLevel +op 0x200018D: GetLevel, explicit reference +op 0x200018E: SetLevel +op 0x200018F: SetLevel, explicit reference +opcodes 0x200018F-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 5113c9dbf..f49d684a5 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -32,6 +32,42 @@ namespace MWScript { namespace Stats { + template + class OpGetLevel : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + Interpreter::Type_Integer value = + MWWorld::Class::get (ptr) + .getCreatureStats (ptr) + .getLevel(); + + runtime.push (value); + } + }; + + template + class OpSetLevel : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + + MWWorld::Class::get (ptr) + .getCreatureStats (ptr) + .setLevel(value); + } + }; + template class OpGetAttribute : public Interpreter::Opcode0 { @@ -592,6 +628,11 @@ namespace MWScript const int opcodeModDisposition = 0x200014d; const int opcodeModDispositionExplicit = 0x200014e; + const int opcodeGetLevel = 0x200018c; + const int opcodeGetLevelExplicit = 0x200018d; + const int opcodeSetLevel = 0x200018e; + const int opcodeSetLevelExplicit = 0x200018f; + void registerExtensions (Compiler::Extensions& extensions) { static const char *attributes[numberOfAttributes] = @@ -674,6 +715,9 @@ namespace MWScript extensions.registerInstruction("moddisposition","l",opcodeModDisposition, opcodeModDispositionExplicit); extensions.registerFunction("getpcrank",'l',"/S",opcodeGetPCRank,opcodeGetPCRankExplicit); + + extensions.registerInstruction("setlevel", "l", opcodeSetLevel, opcodeSetLevelExplicit); + extensions.registerFunction("getlevel", 'l', "", opcodeGetLevel, opcodeGetLevelExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -745,6 +789,12 @@ namespace MWScript interpreter.installSegment5(opcodeModDispositionExplicit,new OpModDisposition); interpreter.installSegment3(opcodeGetPCRank,new OpGetPCRank); interpreter.installSegment3(opcodeGetPCRankExplicit,new OpGetPCRank); + + interpreter.installSegment5 (opcodeGetLevel, new OpGetLevel); + interpreter.installSegment5 (opcodeGetLevelExplicit, new OpGetLevel); + interpreter.installSegment5 (opcodeSetLevel, new OpSetLevel); + interpreter.installSegment5 (opcodeSetLevelExplicit, new OpSetLevel); + } } } diff --git a/files/mygui/openmw_levelup_dialog.layout b/files/mygui/openmw_levelup_dialog.layout index 6525a1e41..86e65e99a 100644 --- a/files/mygui/openmw_levelup_dialog.layout +++ b/files/mygui/openmw_levelup_dialog.layout @@ -4,7 +4,7 @@ - + @@ -31,7 +31,6 @@ - @@ -45,7 +44,6 @@ - @@ -59,7 +57,6 @@ - @@ -73,7 +70,6 @@ - @@ -88,7 +84,6 @@ - @@ -102,7 +97,6 @@ - @@ -116,7 +110,6 @@ - @@ -130,7 +123,6 @@ -