diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp
index 39d7e6e1a4..bf8d8dee48 100644
--- a/apps/openmw/mwbase/mechanicsmanager.hpp
+++ b/apps/openmw/mwbase/mechanicsmanager.hpp
@@ -74,6 +74,12 @@ namespace MWBase
 
             virtual void restoreDynamicStats() = 0;
             ///< If the player is sleeping, this should be called every hour.
+
+            virtual int barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0;
+            ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC.
+
+            virtual int disposition(const MWWorld::Ptr& ptr) = 0;
+            ///< Calculate the diposition of an NPC toward the player.
     };
 }
 
diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp
index 03b5e56aa4..4bf6c24b7a 100644
--- a/apps/openmw/mwclass/npc.cpp
+++ b/apps/openmw/mwclass/npc.cpp
@@ -94,6 +94,8 @@ namespace MWClass
                 data->mCreatureStats.getFatigue().set (ref->base->mNpdt52.mFatigue);
 
                 data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel);
+
+                data->mNpcStats.setDisposition(ref->base->mNpdt52.mDisposition);
             }
             else
             {
diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp
index c19639aa6a..7195ea7254 100644
--- a/apps/openmw/mwgui/travelwindow.cpp
+++ b/apps/openmw/mwgui/travelwindow.cpp
@@ -66,6 +66,8 @@ namespace MWGui
             price = d/MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelMult")->getFloat();
         }
 
+        price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,price,true);
+
         MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default);
         mCurrentY += sLineHeight;
         /// \todo price adjustment depending on merchantile skill
diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp
index 364e653217..9a3ff610be 100644
--- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp
+++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp
@@ -324,4 +324,56 @@ namespace MWMechanics
         buildPlayer();
         mUpdatePlayer = true;
     }
+
+    float min(float a,float b)
+    {
+        if(a<b) return a;
+        else return b;
+    }
+
+    float max(float a,float b)
+    {
+        if(a>b) return a;
+        else return b;
+    }
+
+    int MechanicsManager::disposition(const MWWorld::Ptr& ptr)
+    {
+        MWMechanics::NpcStats npcSkill = MWWorld::Class::get(ptr).getNpcStats(ptr);
+        return npcSkill.getDisposition();
+    }
+
+    int MechanicsManager::barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying)
+    {
+        MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(ptr).getNpcStats(ptr);
+        MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); 
+
+        MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
+        MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
+        MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr);
+
+        int clampedDisposition = min(disposition(ptr),100);
+        float a = min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100);
+        float b = min(0.1 * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10);
+        float c = min(0.2 * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10);
+        float d = min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100);
+        float e = min(0.1 * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10);
+        float f = min(0.2 * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10);
+ 
+        float pcTerm = (clampedDisposition - 50 + a + b + c) * playerStats.getFatigueTerm();
+        float npcTerm = (d + e + f) * sellerStats.getFatigueTerm();
+        float buyTerm = 0.01 * (100 - 0.5 * (pcTerm - npcTerm));
+        float sellTerm = 0.01 * (50 - 0.5 * (npcTerm - pcTerm));
+
+        float x; 
+        if(buying) x = buyTerm;
+        else x = min(buyTerm, sellTerm);
+        std::cout << "x" << x;
+        int offerPrice;
+        if (x < 1) offerPrice = int(x * basePrice);
+        if (x >= 1) offerPrice = basePrice + int((x - 1) * basePrice);
+        offerPrice = max(1, offerPrice);
+        std::cout <<"barteroffer"<< offerPrice << " " << basePrice << "\n";
+        return offerPrice;
+    }
 }
diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp
index 3a41e8fa60..cdf418a81a 100644
--- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp
+++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp
@@ -76,6 +76,12 @@ namespace MWMechanics
 
             virtual void restoreDynamicStats();
             ///< If the player is sleeping, this should be called every hour.
+
+            virtual int barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying);
+            ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC.
+
+            virtual int disposition(const MWWorld::Ptr& ptr);
+            ///< Calculate the diposition of an NPC toward the player.
     };
 }
 
diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp
index bbd42c1471..f09b7b0bd4 100644
--- a/apps/openmw/mwmechanics/npcstats.cpp
+++ b/apps/openmw/mwmechanics/npcstats.cpp
@@ -19,7 +19,7 @@
 
 MWMechanics::NpcStats::NpcStats()
 : mMovementFlags (0), mDrawState (DrawState_Nothing)
-, mLevelProgress(0)
+, mLevelProgress(0), mDisposition(0)
 {
     mSkillIncreases.resize (ESM::Attribute::Length);
     for (int i=0; i<ESM::Attribute::Length; ++i)
@@ -36,6 +36,16 @@ void MWMechanics::NpcStats::setDrawState (DrawState_ state)
     mDrawState = state;
 }
 
+unsigned int MWMechanics::NpcStats::getDisposition() const
+{
+    return mDisposition;
+}
+
+void MWMechanics::NpcStats::setDisposition(unsigned int disposition)
+{
+    mDisposition = disposition;
+}
+
 bool MWMechanics::NpcStats::getMovementFlag (Flag flag) const
 {
     return mMovementFlags & flag;
diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp
index 48e63d7b6e..1fc173f903 100644
--- a/apps/openmw/mwmechanics/npcstats.hpp
+++ b/apps/openmw/mwmechanics/npcstats.hpp
@@ -43,6 +43,7 @@ namespace MWMechanics
             std::map<std::string, int> mFactionRank;
 
             DrawState_ mDrawState;
+            unsigned int mDisposition;
             unsigned int mMovementFlags;
             Stat<float> mSkill[27];
 
@@ -60,6 +61,10 @@ namespace MWMechanics
 
             void setDrawState (DrawState_ state);
 
+            unsigned int getDisposition() const;
+
+            void setDisposition(unsigned int disposition);
+
             bool getMovementFlag (Flag flag) const;
 
             void setMovementFlag (Flag flag, bool state);