From 9201baebf97afed41d9c3b82c2b97a48f4230be1 Mon Sep 17 00:00:00 2001
From: Marc Zinnschlag <marc@zpages.de>
Date: Thu, 22 Nov 2012 10:19:11 +0100
Subject: [PATCH 1/7] template fix

---
 apps/openmw/mwworld/store.cpp | 18 ------------------
 apps/openmw/mwworld/store.hpp | 14 +++++++++++---
 2 files changed, 11 insertions(+), 21 deletions(-)
 delete mode 100644 apps/openmw/mwworld/store.cpp

diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp
deleted file mode 100644
index 5a6b6a7630..0000000000
--- a/apps/openmw/mwworld/store.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "store.hpp"
-
-namespace MWWorld
-{
-    template <>
-    void Store<ESM::Dialogue>::load(ESM::ESMReader &esm, const std::string &id) {
-        mStatic.push_back(ESM::Dialogue());
-        mStatic.back().mId = id;
-        mStatic.back().load(esm);
-    }
-
-    template <>
-    void Store<ESM::Script>::load(ESM::ESMReader &esm, const std::string &id) {
-        mStatic.push_back(ESM::Script());
-        mStatic.back().load(esm);
-        StringUtils::toLower(mStatic.back().mId);
-    }
-}
diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp
index a406a39de0..fd93f39f1e 100644
--- a/apps/openmw/mwworld/store.hpp
+++ b/apps/openmw/mwworld/store.hpp
@@ -203,10 +203,18 @@ namespace MWWorld
     };
 
     template <>
-    void Store<ESM::Dialogue>::load(ESM::ESMReader &esm, const std::string &id);
+    inline void Store<ESM::Dialogue>::load(ESM::ESMReader &esm, const std::string &id) {
+        mStatic.push_back(ESM::Dialogue());
+        mStatic.back().mId = id;
+        mStatic.back().load(esm);
+    }
 
     template <>
-    void Store<ESM::Script>::load(ESM::ESMReader &esm, const std::string &id);
+    inline void Store<ESM::Script>::load(ESM::ESMReader &esm, const std::string &id) {
+        mStatic.push_back(ESM::Script());
+        mStatic.back().load(esm);
+        StringUtils::toLower(mStatic.back().mId);
+    }
 
     template <>
     class Store<ESM::LandTexture> : public StoreBase
@@ -347,7 +355,7 @@ namespace MWWorld
 
         typedef std::map<std::string, ESM::Cell>            DynamicInt;
         typedef std::map<std::pair<int, int>, ESM::Cell>    DynamicExt;
-        
+
         DynamicInt mDynamicInt;
         DynamicExt mDynamicExt;
 

From d684b3ae1150ff204f2052b994d9b1426e85b4b6 Mon Sep 17 00:00:00 2001
From: Marc Zinnschlag <marc@zpages.de>
Date: Thu, 22 Nov 2012 10:35:03 +0100
Subject: [PATCH 2/7] fixed getString function in NIF loader

---
 components/nif/nif_file.hpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp
index a4eaa89906..23bccb0fe0 100644
--- a/components/nif/nif_file.hpp
+++ b/components/nif/nif_file.hpp
@@ -193,11 +193,12 @@ public:
 
     std::string getString(size_t length)
     {
-        std::string str;
-        str.resize(length);
+        std::vector<char> str (length+1, 0);
+
         if(inp->read(&str[0], length) != length)
-            return std::string();
-        return str.substr(0, str.find('\0'));
+            throw std::runtime_error ("string length in NIF file does not match");
+
+        return &str[0];
     }
     std::string getString()
     {

From 6643674b13e13b53361cd6a015a04655fff7c90d Mon Sep 17 00:00:00 2001
From: Marc Zinnschlag <marc@zpages.de>
Date: Thu, 22 Nov 2012 17:23:25 +0100
Subject: [PATCH 3/7] ESM tool fix

---
 apps/esmtool/record.cpp | 115 ++++++++++++++++++----------------------
 1 file changed, 53 insertions(+), 62 deletions(-)

diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp
index e26015970e..b5f97e979e 100644
--- a/apps/esmtool/record.cpp
+++ b/apps/esmtool/record.cpp
@@ -15,7 +15,7 @@ void printAIPackage(ESM::AIPackage p)
         std::cout << "    Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl;
         if (p.mWander.mUnk != 1)
             std::cout <<  "    Unknown: " << (int)p.mWander.mUnk << std::endl;
-        
+
         std::cout << "    Idle: ";
         for (int i = 0; i != 8; i++)
             std::cout << (int)p.mWander.mIdle[i] << " ";
@@ -28,7 +28,7 @@ void printAIPackage(ESM::AIPackage p)
         std::cout << "    Travel Unknown: " << (int)p.mTravel.mUnk << std::endl;
     }
     else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort)
-    {       
+    {
         std::cout << "    Follow Coordinates: (" << p.mTarget.mX << ","
                   << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl;
         std::cout << "    Duration: " << p.mTarget.mDuration << std::endl;
@@ -43,7 +43,7 @@ void printAIPackage(ESM::AIPackage p)
     else {
         std::cout << "    BadPackage: " << boost::format("0x%08x") % p.mType << std::endl;
     }
-    
+
     if (p.mCellName != "")
         std::cout << "    Cell Name: " << p.mCellName << std::endl;
 }
@@ -51,13 +51,13 @@ void printAIPackage(ESM::AIPackage p)
 std::string ruleString(ESM::DialInfo::SelectStruct ss)
 {
     std::string rule = ss.mSelectRule;
-    
+
     if (rule.length() < 5)
         return "INVALID";
-    
+
     char type = rule[1];
     char indicator = rule[2];
-    
+
     std::string type_str = "INVALID";
     std::string func_str = str(boost::format("INVALID=%s") % rule.substr(1,3));
     int func;
@@ -71,14 +71,14 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
         func_str = ruleFunction(func);
         break;
     case '2':
-        if (indicator == 's') type_str = "Global short"; 
-        else if (indicator == 'l') type_str = "Global long"; 
-        else if (indicator == 'f') type_str = "Global float"; 
+        if (indicator == 's') type_str = "Global short";
+        else if (indicator == 'l') type_str = "Global long";
+        else if (indicator == 'f') type_str = "Global float";
         break;
     case '3':
-        if (indicator == 's') type_str = "Local short"; 
-        else if (indicator == 'l') type_str = "Local long"; 
-        else if (indicator == 'f') type_str = "Local float"; 
+        if (indicator == 's') type_str = "Local short";
+        else if (indicator == 'l') type_str = "Local long";
+        else if (indicator == 'f') type_str = "Local float";
         break;
     case '4': if (indicator == 'J') type_str = "Journal"; break;
     case '5': if (indicator == 'I') type_str = "Item type"; break;
@@ -90,15 +90,15 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
     case 'B': if (indicator == 'L') type_str = "Not Cell"; break;
     case 'C': if (indicator == 's') type_str = "Not Local"; break;
     }
-    
+
     // Append the variable name to the function string if any.
     if (type != '1') func_str = rule.substr(5);
-    
+
     // In the previous switch, we assumed that the second char was X
     // for all types not qual to one.  If this wasn't true, go back to
     // the error message.
     if (type != '1' && rule[3] != 'X')
-        func_str = str(boost::format("INVALID=%s") % rule.substr(1,3));    
+        func_str = str(boost::format("INVALID=%s") % rule.substr(1,3));
 
     char oper = rule[4];
     std::string oper_str = "??";
@@ -117,8 +117,8 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
         value_str = str(boost::format("%d") % ss.mI);
     else if (ss.mType == ESM::VT_Float)
         value_str = str(boost::format("%f") % ss.mF);
-    
-    std::string result = str(boost::format("%-12s %-32s %2s %s") 
+
+    std::string result = str(boost::format("%-12s %-32s %2s %s")
                              % type_str % func_str % oper_str % value_str);
     return result;
 }
@@ -136,7 +136,7 @@ void printEffectList(ESM::EffectList effects)
                       << " (" << (int)eit->mSkill << ")" << std::endl;
         if (eit->mAttribute != -1)
             std::cout << "    Attribute: " << attributeLabel(eit->mAttribute)
-                      << " (" << (int)eit->mAttribute << ")" << std::endl; 
+                      << " (" << (int)eit->mAttribute << ")" << std::endl;
         std::cout << "    Range: " << rangeTypeLabel(eit->mRange)
                   << " (" << eit->mRange << ")" << std::endl;
         // Area is always zero if range type is "Self"
@@ -412,7 +412,7 @@ void Record<ESM::Armor>::print()
     std::cout << "  Weight: " << mData.mData.mWeight << std::endl;
     std::cout << "  Value: " << mData.mData.mValue << std::endl;
     std::cout << "  Health: " << mData.mData.mHealth << std::endl;
-    std::cout << "  Armor: " << mData.mData.mArmor << std::endl; 
+    std::cout << "  Armor: " << mData.mData.mArmor << std::endl;
     std::cout << "  Enchantment Points: " << mData.mData.mEnchant << std::endl;
     std::vector<ESM::PartReference>::iterator pit;
     for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++)
@@ -483,7 +483,7 @@ void Record<ESM::BirthSign>::print()
     std::cout << "  Description: " << mData.mDescription << std::endl;
     std::vector<std::string>::iterator pit;
     for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); pit++)
-        std::cout << "  Power: " << *pit << std::endl;    
+        std::cout << "  Power: " << *pit << std::endl;
 }
 
 template<>
@@ -495,12 +495,12 @@ void Record<ESM::Cell>::print()
     if (mData.mRegion != "")
         std::cout << "  Region: " << mData.mRegion << std::endl;
     std::cout << "  Flags: " << cellFlags(mData.mData.mFlags) << std::endl;
-    
+
     std::cout << "  Coordinates: " << " (" << mData.getGridX() << ","
               << mData.getGridY() << ")" << std::endl;
-    
-    if (mData.mData.mFlags & ESM::Cell::Interior && 
-        !(mData.mData.mFlags & ESM::Cell::QuasiEx)) 
+
+    if (mData.mData.mFlags & ESM::Cell::Interior &&
+        !(mData.mData.mFlags & ESM::Cell::QuasiEx))
     {
         std::cout << "  Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl;
         std::cout << "  Sunlight Color: " << mData.mAmbi.mSunlight << std::endl;
@@ -508,7 +508,7 @@ void Record<ESM::Cell>::print()
         std::cout << "  Fog Density: " << mData.mAmbi.mFogDensity << std::endl;
         std::cout << "  Water Level: " << mData.mWater << std::endl;
     }
-    else 
+    else
         std::cout << "  Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl;
     std::cout << "  Water Level Int: " << mData.mWaterInt << std::endl;
     std::cout << "  NAM0: " << mData.mNAM0 << std::endl;
@@ -530,7 +530,7 @@ void Record<ESM::Class>::print()
               << " (" << mData.mData.mSpecialization << ")" << std::endl;
     for (int i = 0; i != 5; i++)
         std::cout << "  Major Skill: " << skillLabel(mData.mData.mSkills[i][0])
-                  << " (" << mData.mData.mSkills[i][0] << ")" << std::endl; 
+                  << " (" << mData.mData.mSkills[i][0] << ")" << std::endl;
     for (int i = 0; i != 5; i++)
         std::cout << "  Minor Skill: " << skillLabel(mData.mData.mSkills[i][1])
                   << " (" << mData.mData.mSkills[i][1] << ")" << std::endl;
@@ -573,7 +573,7 @@ void Record<ESM::Container>::print()
     std::cout << "  Weight: " << mData.mWeight << std::endl;
     std::vector<ESM::ContItem>::iterator cit;
     for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++)
-        std::cout << "  Inventory: Count: " << boost::format("%4d") % cit->mCount 
+        std::cout << "  Inventory: Count: " << boost::format("%4d") % cit->mCount
                   << " Item: " << cit->mItem.toString() << std::endl;
 }
 
@@ -608,17 +608,17 @@ void Record<ESM::Creature>::print()
     std::cout << "  Combat: " << mData.mData.mCombat << std::endl;
     std::cout << "  Magic: " << mData.mData.mMagic << std::endl;
     std::cout << "  Stealth: " << mData.mData.mStealth << std::endl;
-    std::cout << "  Attack1: " << mData.mData.mAttack[0] 
+    std::cout << "  Attack1: " << mData.mData.mAttack[0]
               << "-" <<  mData.mData.mAttack[1] << std::endl;
-    std::cout << "  Attack2: " << mData.mData.mAttack[2] 
+    std::cout << "  Attack2: " << mData.mData.mAttack[2]
               << "-" <<  mData.mData.mAttack[3] << std::endl;
-    std::cout << "  Attack3: " << mData.mData.mAttack[4] 
+    std::cout << "  Attack3: " << mData.mData.mAttack[4]
               << "-" <<  mData.mData.mAttack[5] << std::endl;
     std::cout << "  Gold: " << mData.mData.mGold << std::endl;
 
     std::vector<ESM::ContItem>::iterator cit;
     for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++)
-        std::cout << "  Inventory: Count: " << boost::format("%4d") % cit->mCount 
+        std::cout << "  Inventory: Count: " << boost::format("%4d") % cit->mCount
                   << " Item: " << cit->mItem.toString() << std::endl;
 
     std::vector<std::string>::iterator sit;
@@ -694,15 +694,15 @@ void Record<ESM::Faction>::print()
         if (mData.mRanks[i] != "")
         {
             std::cout << "  Rank: " << mData.mRanks[i] << std::endl;
-            std::cout << "    Attribute1 Requirement: " 
+            std::cout << "    Attribute1 Requirement: "
                       << mData.mData.mRankData[i].mAttribute1 << std::endl;
-            std::cout << "    Attribute2 Requirement: " 
+            std::cout << "    Attribute2 Requirement: "
                       << mData.mData.mRankData[i].mAttribute2 << std::endl;
             std::cout << "    One Skill at Level: "
                       << mData.mData.mRankData[i].mSkill1 << std::endl;
-            std::cout << "    Two Skills at Level: " 
+            std::cout << "    Two Skills at Level: "
                       << mData.mData.mRankData[i].mSkill2 << std::endl;
-            std::cout << "    Faction Reaction: " 
+            std::cout << "    Faction Reaction: "
                       << mData.mData.mRankData[i].mFactReaction << std::endl;
         }
     std::vector<ESM::Faction::Reaction>::iterator rit;
@@ -849,7 +849,7 @@ void Record<ESM::CreatureLevList>::print()
     std::cout << "  Number of items: " << mData.mList.size() << std::endl;
     std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
     for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++)
-        std::cout << "  Creature: Level: " << iit->mLevel 
+        std::cout << "  Creature: Level: " << iit->mLevel
                   << " Creature: " << iit->mId << std::endl;
 }
 
@@ -1012,11 +1012,11 @@ void Record<ESM::NPC>::print()
         std::cout << "  Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl;
         std::cout << "  Faction: " << (int)mData.mNpdt52.mFactionID << std::endl;
         std::cout << "  Rank: " << (int)mData.mNpdt12.mRank << std::endl;
-        std::cout << "  Unknown1: " 
+        std::cout << "  Unknown1: "
                   << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl;
-        std::cout << "  Unknown2: " 
+        std::cout << "  Unknown2: "
                   << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl;
-        std::cout << "  Unknown3: " 
+        std::cout << "  Unknown3: "
                   << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl;
         std::cout << "  Gold: " << (int)mData.mNpdt12.mGold << std::endl;
     }
@@ -1038,9 +1038,9 @@ void Record<ESM::NPC>::print()
 
         std::cout << "  Skills:" << std::endl;
         for (int i = 0; i != 27; i++)
-            std::cout << "    " << skillLabel(i) << ": " 
-                      << (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl;   
-        
+            std::cout << "    " << skillLabel(i) << ": "
+                      << (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl;
+
         std::cout << "  Health: " << mData.mNpdt52.mHealth << std::endl;
         std::cout << "  Magicka: " << mData.mNpdt52.mMana << std::endl;
         std::cout << "  Fatigue: " << mData.mNpdt52.mFatigue << std::endl;
@@ -1050,9 +1050,9 @@ void Record<ESM::NPC>::print()
 
     std::vector<ESM::ContItem>::iterator cit;
     for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++)
-        std::cout << "  Inventory: Count: " << boost::format("%4d") % cit->mCount 
+        std::cout << "  Inventory: Count: " << boost::format("%4d") % cit->mCount
                   << " Item: " << cit->mItem.toString() << std::endl;
-    
+
     std::vector<std::string>::iterator sit;
     for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++)
         std::cout << "  Spell: " << *sit << std::endl;
@@ -1060,18 +1060,18 @@ void Record<ESM::NPC>::print()
     std::vector<ESM::NPC::Dest>::iterator dit;
     for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); dit++)
     {
-        std::cout << "  Destination Position: " 
+        std::cout << "  Destination Position: "
                   << boost::format("%12.3f") % dit->mPos.pos[0] << ","
                   << boost::format("%12.3f") % dit->mPos.pos[1] << ","
                   << boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl;
-        std::cout << "  Destination Rotation: " 
+        std::cout << "  Destination Rotation: "
                   << boost::format("%9.6f") % dit->mPos.rot[0] << ","
                   << boost::format("%9.6f") % dit->mPos.rot[1] << ","
-                  << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl;             
+                  << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl;
         if (dit->mCellName != "")
             std::cout << "  Destination Cell: " << dit->mCellName << std::endl;
     }
-    
+
     std::cout << "  Artifical Intelligence: " << mData.mHasAI << std::endl;
     std::cout << "    AI Hello:" << (int)mData.mAiData.mHello << std::endl;
     std::cout << "    AI Fight:" << (int)mData.mAiData.mFight << std::endl;
@@ -1104,7 +1104,7 @@ void Record<ESM::Pathgrid>::print()
     for (pit = mData.mPoints.begin(); pit != mData.mPoints.end(); pit++)
     {
         std::cout << "  Point[" << i << "]:" << std::endl;
-        std::cout << "    Coordinates: (" << pit->mX << "," 
+        std::cout << "    Coordinates: (" << pit->mX << ","
              << pit->mY << "," << pit->mZ << ")" << std::endl;
         std::cout << "    Auto-Generated: " << (int)pit->mAutogenerated << std::endl;
         std::cout << "    Connections: " << (int)pit->mConnectionNum << std::endl;
@@ -1267,7 +1267,7 @@ void Record<ESM::Sound>::print()
     std::cout << "  Sound: " << mData.mSound << std::endl;
     std::cout << "  Volume: " << (int)mData.mData.mVolume << std::endl;
     if (mData.mData.mMinRange != 0 && mData.mData.mMaxRange != 0)
-        std::cout << "  Range: " << (int)mData.mData.mMinRange << " - " 
+        std::cout << "  Range: " << (int)mData.mData.mMinRange << " - "
                   << (int)mData.mData.mMaxRange << std::endl;
 }
 
@@ -1308,7 +1308,7 @@ void Record<ESM::Weapon>::print()
     if (mData.mScript != "")
         std::cout << "  Script: " << mData.mScript << std::endl;
     if (mData.mEnchant != "")
-        std::cout << "  Enchantment: " << mData.mEnchant << std::endl;    
+        std::cout << "  Enchantment: " << mData.mEnchant << std::endl;
     std::cout << "  Type: " << weaponTypeLabel(mData.mData.mType)
               << " (" << mData.mData.mType << ")" << std::endl;
     std::cout << "  Flags: " << weaponFlags(mData.mData.mFlags) << std::endl;
@@ -1319,23 +1319,14 @@ void Record<ESM::Weapon>::print()
     std::cout << "  Reach: " << mData.mData.mReach << std::endl;
     std::cout << "  Enchantment Points: " << mData.mData.mEnchant << std::endl;
     if (mData.mData.mChop[0] != 0 && mData.mData.mChop[1] != 0)
-        std::cout << "  Chop: " << (int)mData.mData.mChop[0] << "-" 
+        std::cout << "  Chop: " << (int)mData.mData.mChop[0] << "-"
                   << (int)mData.mData.mChop[1] << std::endl;
     if (mData.mData.mSlash[0] != 0 && mData.mData.mSlash[1] != 0)
         std::cout << "  Slash: " << (int)mData.mData.mSlash[0] << "-"
                   << (int)mData.mData.mSlash[1] << std::endl;
     if (mData.mData.mThrust[0] != 0 && mData.mData.mThrust[1] != 0)
-        std::cout << "  Thrust: " << (int)mData.mData.mThrust[0] << "-" 
+        std::cout << "  Thrust: " << (int)mData.mData.mThrust[0] << "-"
                   << (int)mData.mData.mThrust[1] << std::endl;
 }
 
-template<>
-void Record<ESM::CellRef>::print()
-{
-    std::cout << "    Refnum: " << mData.mRefnum << std::endl;
-    std::cout << "    ID: '" << mData.mRefID << "'\n";
-    std::cout << "    Owner: '" << mData.mOwner << "'\n";
-    std::cout << "    INTV: " << mData.mIntv << "   NAM9: " << mData.mIntv << std::endl;
-}
-
 } // end namespace

From d7af9fbec6919bf8e1be2b6a91bfa27532d285f1 Mon Sep 17 00:00:00 2001
From: Marc Zinnschlag <marc@zpages.de>
Date: Thu, 22 Nov 2012 17:24:28 +0100
Subject: [PATCH 4/7] various fixes

---
 apps/openmw/mwdialogue/selectwrapper.cpp | 1 +
 apps/openmw/mwworld/failedaction.cpp     | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp
index bba17bfd10..1462ee8ba2 100644
--- a/apps/openmw/mwdialogue/selectwrapper.cpp
+++ b/apps/openmw/mwdialogue/selectwrapper.cpp
@@ -6,6 +6,7 @@
 #include <stdexcept>
 #include <algorithm>
 #include <sstream>
+#include <iterator>
 
 namespace
 {
diff --git a/apps/openmw/mwworld/failedaction.cpp b/apps/openmw/mwworld/failedaction.cpp
index 8c64db69f3..ec763dba01 100644
--- a/apps/openmw/mwworld/failedaction.cpp
+++ b/apps/openmw/mwworld/failedaction.cpp
@@ -9,11 +9,11 @@ namespace MWWorld
 {
     FailedAction::FailedAction (const std::string& msg) : Action (false), message(msg)
     {   }
-    
-    
+
+
     void FailedAction::executeImp (const Ptr& actor)
     {
-        if ( actor.getRefData().getHandle()=="player" and !(message.empty()))
+        if ( actor.getRefData().getHandle()=="player" && !(message.empty()))
 	{
 	  MWBase::Environment::get().getWindowManager() ->messageBox(message, std::vector<std::string>());
 	}

From 1d7e92b6b31dd7a81f8f0830c5bfb8c1a4e0f58f Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Fri, 23 Nov 2012 19:05:40 +0100
Subject: [PATCH 5/7] dialogue fixes

---
 apps/openmw/mwdialogue/dialoguemanagerimp.cpp |  9 +---
 apps/openmw/mwgui/dialogue.cpp                | 48 +++++++++----------
 2 files changed, 24 insertions(+), 33 deletions(-)

diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp
index 31cef7f70e..a97cf98ded 100644
--- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp
+++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp
@@ -110,14 +110,7 @@ namespace MWDialogue
             size_t pos = find_str_ci(text,*it,0);
             if(pos !=std::string::npos)
             {
-                if(pos==0)
-                {
-                    mKnownTopics[*it] = true;
-                }
-                else if(text.substr(pos -1,1) == " ")
-                {
-                    mKnownTopics[*it] = true;
-                }
+                mKnownTopics[*it] = true;
             }
         }
         updateTopics();
diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp
index e4c9945b4a..ff2ecb4c60 100644
--- a/apps/openmw/mwgui/dialogue.cpp
+++ b/apps/openmw/mwgui/dialogue.cpp
@@ -48,6 +48,11 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su
     return lower_string(str).find(lower_string(substr),pos);
 }
 
+bool sortByLength (const std::string& left, const std::string& right)
+{
+    return left.size() > right.size();
+}
+
 }
 
 
@@ -287,7 +292,7 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
     if (mServices & Service_Training)
         mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
 
-    if (anyService)
+    if (anyService || mPtr.getTypeName() == typeid(ESM::NPC).name())
         mTopicsList->addSeparator();
 
     for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
@@ -311,43 +316,36 @@ void addColorInString(std::string& str, const std::string& keyword,std::string c
     size_t pos = 0;
     while((pos = find_str_ci(str,keyword, pos)) != std::string::npos)
     {
-        if(pos==0)
-        {
-            str.insert(pos,color1);
-            pos += color1.length();
-            pos += keyword.length();
-            str.insert(pos,color2);
-            pos+= color2.length();
-        }
-        else
-        {
-            if(str.substr(pos -1,1) == " ")
-            {
-                str.insert(pos,color1);
-                pos += color1.length();
-                pos += keyword.length();
-                str.insert(pos,color2);
-                pos+= color2.length();
-            }
-            else
-            {
-                pos += keyword.length();
-            }
-        }
+        str.insert(pos,color1);
+        pos += color1.length();
+        pos += keyword.length();
+        str.insert(pos,color2);
+        pos+= color2.length();
     }
 }
 
 std::string DialogueWindow::parseText(std::string text)
 {
     bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored)
+
+    std::vector<std::string> topics;
+
     for(unsigned int i = 0;i<mTopicsList->getItemCount();i++)
     {
         std::string keyWord = mTopicsList->getItemNameAt(i);
         if (separatorReached && keyWord != "")
-            addColorInString(text,keyWord,"#686EBA","#B29154");
+            topics.push_back(keyWord);
         else
             separatorReached = true;
     }
+
+    // sort by length to make sure longer topics are replaced first
+    std::sort(topics.begin(), topics.end(), sortByLength);
+
+    for(std::vector<std::string>::const_iterator it = topics.begin(); it != topics.end(); ++it)
+    {
+        addColorInString(text,*it,"#686EBA","#B29154");
+    }
     return text;
 }
 

From f218ef2675d4b9663f4de78a1d76aa580e657718 Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Fri, 23 Nov 2012 19:21:13 +0100
Subject: [PATCH 6/7] fix separator

---
 apps/openmw/mwgui/dialogue.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp
index ff2ecb4c60..827da10852 100644
--- a/apps/openmw/mwgui/dialogue.cpp
+++ b/apps/openmw/mwgui/dialogue.cpp
@@ -333,9 +333,9 @@ std::string DialogueWindow::parseText(std::string text)
     for(unsigned int i = 0;i<mTopicsList->getItemCount();i++)
     {
         std::string keyWord = mTopicsList->getItemNameAt(i);
-        if (separatorReached && keyWord != "")
+        if (separatorReached)
             topics.push_back(keyWord);
-        else
+        else if (keyWord == "")
             separatorReached = true;
     }
 

From eb29b1593b8c8655479e07889c221f4614199486 Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Fri, 23 Nov 2012 19:56:45 +0100
Subject: [PATCH 7/7] ModReputation, SetReputation

---
 apps/openmw/mwgui/stats_window.cpp          |  2 +
 apps/openmw/mwgui/stats_window.hpp          |  4 +-
 apps/openmw/mwscript/dialogueextensions.cpp | 46 +++++++++++++++++++++
 apps/openmw/mwscript/docs/vmformat.txt      |  6 ++-
 4 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp
index 4b47bb0257..38a06940f4 100644
--- a/apps/openmw/mwgui/stats_window.cpp
+++ b/apps/openmw/mwgui/stats_window.cpp
@@ -257,6 +257,8 @@ void StatsWindow::onFrame ()
         MWBase::Environment::get().getWorld()->getPlayer().getBirthSign();
 
     setBirthSign(signId);
+    setReputation (PCstats.getReputation ());
+    setBounty (PCstats.getBounty ());
 
     if (mChanged)
         updateSkillArea();
diff --git a/apps/openmw/mwgui/stats_window.hpp b/apps/openmw/mwgui/stats_window.hpp
index 5186b63285..f43682c96b 100644
--- a/apps/openmw/mwgui/stats_window.hpp
+++ b/apps/openmw/mwgui/stats_window.hpp
@@ -38,8 +38,8 @@ namespace MWGui
             void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
 
             void configureSkills (const SkillList& major, const SkillList& minor);
-            void setReputation (int reputation) { this->mReputation = reputation; }
-            void setBounty (int bounty) { this->mBounty = bounty; }
+            void setReputation (int reputation) { if (reputation != mReputation) mChanged = true; this->mReputation = reputation; }
+            void setBounty (int bounty) { if (bounty != mBounty) mChanged = true; this->mBounty = bounty; }
             void updateSkillArea();
 
         private:
diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp
index 21c21acf00..72ae257241 100644
--- a/apps/openmw/mwscript/dialogueextensions.cpp
+++ b/apps/openmw/mwscript/dialogueextensions.cpp
@@ -11,6 +11,9 @@
 #include "../mwbase/dialoguemanager.hpp"
 #include "../mwbase/journal.hpp"
 
+#include "../mwworld/class.hpp"
+#include "../mwmechanics/npcstats.hpp"
+
 #include "interpretercontext.hpp"
 #include "ref.hpp"
 
@@ -126,6 +129,37 @@ namespace MWScript
                 }
         };
 
+        template<class R>
+        class OpModReputation : 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).getNpcStats (ptr).setReputation (MWWorld::Class::get(ptr).getNpcStats (ptr).getReputation () + value);
+                }
+        };
+
+        template<class R>
+        class OpSetReputation : 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).getNpcStats (ptr).setReputation (value);
+                }
+        };
+
+
         const int opcodeJournal = 0x2000133;
         const int opcodeSetJournalIndex = 0x2000134;
         const int opcodeGetJournalIndex = 0x2000135;
@@ -134,6 +168,10 @@ namespace MWScript
         const int opcodeForceGreeting = 0x200014f;
         const int opcodeForceGreetingExplicit = 0x2000150;
         const int opcodeGoodbye = 0x2000152;
+        const int opcodeSetReputation = 0x20001ad;
+        const int opcodeModReputation = 0x20001ae;
+        const int opcodeSetReputationExplicit = 0x20001af;
+        const int opcodeModReputationExplicit = 0x20001b0;
 
         void registerExtensions (Compiler::Extensions& extensions)
         {
@@ -146,6 +184,10 @@ namespace MWScript
             extensions.registerInstruction("forcegreeting","",opcodeForceGreeting,
                 opcodeForceGreetingExplicit);
             extensions.registerInstruction("goodbye", "", opcodeGoodbye);
+            extensions.registerInstruction("setreputation", "l", opcodeSetReputation,
+                opcodeSetReputationExplicit);
+            extensions.registerInstruction("modreputation", "l", opcodeModReputation,
+                opcodeModReputationExplicit);
         }
 
         void installOpcodes (Interpreter::Interpreter& interpreter)
@@ -158,6 +200,10 @@ namespace MWScript
             interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting<ImplicitRef>);
             interpreter.installSegment5 (opcodeForceGreetingExplicit, new OpForceGreeting<ExplicitRef>);
             interpreter.installSegment5 (opcodeGoodbye, new OpGoodbye);
+            interpreter.installSegment5 (opcodeSetReputation, new OpSetReputation<ImplicitRef>);
+            interpreter.installSegment5 (opcodeModReputation, new OpModReputation<ImplicitRef>);
+            interpreter.installSegment5 (opcodeSetReputationExplicit, new OpSetReputation<ExplicitRef>);
+            interpreter.installSegment5 (opcodeModReputationExplicit, new OpModReputation<ExplicitRef>);
         }
     }
 
diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt
index fdc4f49742..b130aa9547 100644
--- a/apps/openmw/mwscript/docs/vmformat.txt
+++ b/apps/openmw/mwscript/docs/vmformat.txt
@@ -222,5 +222,9 @@ op 0x20001a9: CommonDisease, explicit reference
 op 0x20001aa: BlightDisease
 op 0x20001ab: BlightDisease, explicit reference
 op 0x20001ac: ToggleCollisionBoxes
-opcodes 0x20001ac-0x3ffffff unused
+op 0x20001ad: SetReputation
+op 0x20001ae: ModReputation
+op 0x20001af: SetReputation, explicit
+op 0x20001b0: ModReputation, explicit
+opcodes 0x20001b1-0x3ffffff unused