From dfc62c99b457bae218f7478db46730028b15766c Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 26 Jun 2016 03:22:58 +0200 Subject: [PATCH 1/4] Show correct class image in level-up dialog (Fixes #3443) --- apps/openmw/mwgui/levelupdialog.cpp | 103 ++++++++++++++++++++++++++- apps/openmw/mwgui/levelupdialog.hpp | 2 + apps/openmw/mwmechanics/npcstats.cpp | 14 ++++ apps/openmw/mwmechanics/npcstats.hpp | 5 +- components/esm/npcstats.cpp | 6 ++ components/esm/npcstats.hpp | 1 + 6 files changed, 129 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index fb9952ba7..6d36a9c42 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -156,7 +156,9 @@ namespace MWGui cls = &*it; } - setClassImage(mClassImage, cls->mId); + setClassImage(mClassImage, getLevelupClassImage(pcStats.getSkillIncreasesForSpecialization(0), + pcStats.getSkillIncreasesForSpecialization(1), + pcStats.getSkillIncreasesForSpecialization(2))); int level = creatureStats.getLevel ()+1; mLevelText->setCaptionWithReplacing("#{sLevelUpMenu1} " + MyGUI::utility::toString(level)); @@ -248,4 +250,103 @@ namespace MWGui } assignCoins(); } + + std::string LevelupDialog::getLevelupClassImage(const int combatIncreases, const int magicIncreases, const int stealthIncreases) + { + std::string ret = "acrobat"; + + int total = combatIncreases + magicIncreases + stealthIncreases; + if (total == 0) + return ret; + + int combatFraction = static_cast(static_cast(combatIncreases) / total * 10.f); + int magicFraction = static_cast(static_cast(magicIncreases) / total * 10.f); + int stealthFraction = static_cast(static_cast(stealthIncreases) / total * 10.f); + + if (combatFraction > 7) + ret = "warrior"; + else if (magicFraction > 7) + ret = "mage"; + else if (stealthFraction > 7) + ret = "thief"; + + switch (combatFraction) + { + case 7: + ret = "warrior"; + break; + case 6: + if (stealthFraction == 1) + ret = "barbarian"; + else if (stealthFraction == 3) + ret = "crusader"; + else + ret = "knight"; + break; + case 5: + if (stealthFraction == 3) + ret = "scout"; + else + ret = "archer"; + break; + case 4: + ret = "rogue"; + break; + default: + break; + } + + switch (magicFraction) + { + case 7: + ret = "mage"; + break; + case 6: + if (combatFraction == 2) + ret = "sorcerer"; + else if (combatIncreases == 3) + ret = "healer"; + else + ret = "battlemage"; + break; + case 5: + ret = "witchhunter"; + break; + case 4: + ret = "spellsword"; + // In vanilla there's also code for "nightblade", however it seems to be unreachable. + break; + default: + break; + } + + switch (stealthFraction) + { + case 7: + ret = "thief"; + break; + case 6: + if (magicFraction == 1) + ret = "agent"; + else if (magicIncreases == 3) + ret = "assassin"; + else + ret = "acrobat"; + break; + case 5: + if (magicIncreases == 3) + ret = "monk"; + else + ret = "pilgrim"; + break; + case 3: + if (magicFraction == 3 && stealthFraction == 3) + ret = "bard"; + break; + default: + break; + } + + return ret; + } } diff --git a/apps/openmw/mwgui/levelupdialog.hpp b/apps/openmw/mwgui/levelupdialog.hpp index e5edbd53c..d49f7536d 100644 --- a/apps/openmw/mwgui/levelupdialog.hpp +++ b/apps/openmw/mwgui/levelupdialog.hpp @@ -39,6 +39,8 @@ namespace MWGui void resetCoins(); void setAttributeValues(); + + std::string getLevelupClassImage(const int combatIncreases, const int magicIncreases, const int stealthIncreases); }; } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 10d603ff1..8bea109d0 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -34,6 +34,7 @@ MWMechanics::NpcStats::NpcStats() , mIsWerewolf(false) { mSkillIncreases.resize (ESM::Attribute::Length, 0); + mSpecIncreases.resize(3, 0); } int MWMechanics::NpcStats::getBaseDisposition() const @@ -255,6 +256,8 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas MWBase::Environment::get().getWorld ()->getStore ().get().find(skillIndex); mSkillIncreases[skill->mData.mAttribute] += increase; + mSpecIncreases[skill->mData.mSpecialization] += gmst.find("iLevelupSpecialization")->getInt(); + // Play sound & skill progress notification /// \todo check if character is the player, if levelling is ever implemented for NPCs MWBase::Environment::get().getSoundManager ()->playSound ("skillraise", 1, 1); @@ -326,6 +329,11 @@ int MWMechanics::NpcStats::getLevelupAttributeMultiplier(int attribute) const return MWBase::Environment::get().getWorld()->getStore().get().find(gmst.str())->getInt(); } +int MWMechanics::NpcStats::getSkillIncreasesForSpecialization(int spec) const +{ + return mSpecIncreases[spec]; +} + void MWMechanics::NpcStats::flagAsUsed (const std::string& id) { mUsedIds.insert (id); @@ -469,6 +477,9 @@ void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const for (int i=0; i::const_iterator iter (state.mUsedIds.begin()); iter!=state.mUsedIds.end(); ++iter) if (store.find (*iter)) diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 8a98b1d1d..9ded47c07 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -34,7 +34,8 @@ namespace MWMechanics std::set mExpelled; std::map mFactionReputation; int mLevelProgress; // 0-10 - std::vector mSkillIncreases; // number of skill increases for each attribute + std::vector mSkillIncreases; // number of skill increases for each attribute (resets after leveling up) + std::vector mSpecIncreases; // number of skill increases for each specialization (accumulates throughout the entire game) std::set mUsedIds; // --------------------------------------------------------------------------- @@ -86,6 +87,8 @@ namespace MWMechanics int getLevelupAttributeMultiplier(int attribute) const; + int getSkillIncreasesForSpecialization(int spec) const; + void levelUp(); void updateHealth(); diff --git a/components/esm/npcstats.cpp b/components/esm/npcstats.cpp index 10c0b6f16..c7804fd44 100644 --- a/components/esm/npcstats.cpp +++ b/components/esm/npcstats.cpp @@ -95,6 +95,8 @@ void ESM::NpcStats::load (ESMReader &esm) esm.getHNT (mSkillIncrease, "INCR"); + esm.getHNOT (mSpecIncreases, "SPEC"); + while (esm.isNextSub ("USED")) mUsedIds.push_back (esm.getHString()); @@ -156,6 +158,8 @@ void ESM::NpcStats::save (ESMWriter &esm) const esm.writeHNT ("INCR", mSkillIncrease); + esm.writeHNT ("SPEC", mSpecIncreases); + for (std::vector::const_iterator iter (mUsedIds.begin()); iter!=mUsedIds.end(); ++iter) esm.writeHNString ("USED", *iter); @@ -178,6 +182,8 @@ void ESM::NpcStats::blank() mLevelProgress = 0; for (int i=0; i<8; ++i) mSkillIncrease[i] = 0; + for (int i=0; i<3; ++i) + mSpecIncreases[i] = 0; mTimeToStartDrowning = 20; mCrimeId = -1; } diff --git a/components/esm/npcstats.hpp b/components/esm/npcstats.hpp index 9b27f587c..467a099ce 100644 --- a/components/esm/npcstats.hpp +++ b/components/esm/npcstats.hpp @@ -37,6 +37,7 @@ namespace ESM int mWerewolfKills; int mLevelProgress; int mSkillIncrease[8]; + int mSpecIncreases[3]; std::vector mUsedIds; // lower case IDs float mTimeToStartDrowning; int mCrimeId; From 0db3af1b894adf1f2188ccae5c6f17950b5e74d1 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 26 Jun 2016 03:28:13 +0200 Subject: [PATCH 2/4] ESSImporter: load specialization increases --- apps/essimporter/convertplayer.cpp | 2 ++ apps/essimporter/importplayer.hpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index 00a2a10f5..55aaad1c5 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -17,6 +17,8 @@ namespace ESSImport faction.mReputation = it->mReputation; out.mObject.mNpcStats.mFactions[Misc::StringUtils::lowerCase(it->mFactionName.toString())] = faction; } + for (int i=0; i<3; ++i) + out.mObject.mNpcStats.mSpecIncreases[i] = pcdt.mPNAM.mSpecIncreases[i]; for (int i=0; i<8; ++i) out.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i]; for (int i=0; i<27; ++i) diff --git a/apps/essimporter/importplayer.hpp b/apps/essimporter/importplayer.hpp index 3e537cc16..3baab1cd8 100644 --- a/apps/essimporter/importplayer.hpp +++ b/apps/essimporter/importplayer.hpp @@ -67,7 +67,9 @@ struct PCDT unsigned int mLevelProgress; float mSkillProgress[27]; // skill progress, non-uniform scaled unsigned char mSkillIncreases[8]; // number of skill increases for each attribute - unsigned char mUnknown3[88]; + unsigned char mUnknown3[84]; + unsigned char mSpecIncreases[3]; // number of skill increases for each specialization + unsigned char mUnknown4; }; #pragma pack(pop) From b99611a7305ae625a391da75de56bdb5ec56157e Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 26 Jun 2016 15:16:32 +0200 Subject: [PATCH 3/4] Initialize mSpecIncreases in ESM::NpcStats::load --- components/esm/npcstats.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/esm/npcstats.cpp b/components/esm/npcstats.cpp index c7804fd44..4c1095b6e 100644 --- a/components/esm/npcstats.cpp +++ b/components/esm/npcstats.cpp @@ -95,6 +95,8 @@ void ESM::NpcStats::load (ESMReader &esm) esm.getHNT (mSkillIncrease, "INCR"); + for (int i=0; i<3; ++i) + mSpecIncreases[i] = 0; esm.getHNOT (mSpecIncreases, "SPEC"); while (esm.isNextSub ("USED")) From 7244809c4a0b95f4a4981fced4a5f58a2c9a57d1 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 26 Jun 2016 15:17:52 +0200 Subject: [PATCH 4/4] Remove redundant part of condition --- apps/openmw/mwgui/levelupdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index 6d36a9c42..e64eb510e 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -340,7 +340,7 @@ namespace MWGui ret = "pilgrim"; break; case 3: - if (magicFraction == 3 && stealthFraction == 3) + if (magicFraction == 3) ret = "bard"; break; default: