Moved mechanics code from MWGui::TradeWindow to MWMechanics::Trading

pull/1/head
Ben Shealy 9 years ago
parent 3645b3357e
commit 5085afa3d7

@ -84,7 +84,7 @@ add_openmw_dir (mwmechanics
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor
aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning
character actors objects aistate coordinateconverter character actors objects aistate coordinateconverter trading
) )
add_openmw_dir (mwstate add_openmw_dir (mwstate

@ -4,8 +4,6 @@
#include <MyGUI_InputManager.h> #include <MyGUI_InputManager.h>
#include <MyGUI_ControllerManager.h> #include <MyGUI_ControllerManager.h>
#include <components/misc/rng.hpp>
#include <components/widgets/numericeditbox.hpp> #include <components/widgets/numericeditbox.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
@ -19,8 +17,8 @@
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/actorutil.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include "itemview.hpp" #include "itemview.hpp"
@ -323,77 +321,23 @@ namespace MWGui
} }
} }
// TODO: move to mwmechanics bool offerAccepted = mTrading.haggle(player, mPtr, mCurrentBalance, mCurrentMerchantOffer);
// Is the player buying? // apply disposition change if merchant is NPC
bool buying = (mCurrentMerchantOffer < 0); if ( mPtr.getClass().isNpc() ) {
int dispositionDelta = offerAccepted
? gmst.find("iBarterSuccessDisposition")->getInt()
: gmst.find("iBarterFailDisposition")->getInt();
if(mCurrentBalance > mCurrentMerchantOffer) MWBase::Environment::get().getDialogueManager()->applyDispositionChange(dispositionDelta);
{
//if npc is a creature: reject (no haggle)
if (mPtr.getTypeName() != typeid(ESM::NPC).name())
{
MWBase::Environment::get().getWindowManager()->
messageBox("#{sNotifyMessage9}");
return;
}
int a = abs(mCurrentMerchantOffer);
int b = abs(mCurrentBalance);
int d = 0;
if (buying)
d = int(100 * (a - b) / a);
else
d = int(100 * (b - a) / a);
int clampedDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr);
const MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
const MWMechanics::CreatureStats &playerStats = player.getClass().getCreatureStats(player);
float a1 = static_cast<float>(player.getClass().getSkill(player, ESM::Skill::Mercantile));
float b1 = 0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified();
float c1 = 0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified();
float d1 = static_cast<float>(mPtr.getClass().getSkill(mPtr, ESM::Skill::Mercantile));
float e1 = 0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified();
float f1 = 0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified();
float dispositionTerm = gmst.find("fDispositionMod")->getFloat() * (clampedDisposition - 50);
float pcTerm = (dispositionTerm - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm();
float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm();
float x = gmst.find("fBargainOfferMulti")->getFloat() * d + gmst.find("fBargainOfferBase")->getFloat();
if (buying)
x += abs(int(pcTerm - npcTerm));
else
x += abs(int(npcTerm - pcTerm));
int roll = Misc::Rng::rollDice(100) + 1;
if(roll > x || (mCurrentMerchantOffer < 0) != (mCurrentBalance < 0)) //trade refused
{
MWBase::Environment::get().getWindowManager()->
messageBox("#{sNotifyMessage9}");
int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt();
if (mPtr.getClass().isNpc())
MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterFailDisposition);
return;
}
//skill use!
float skillGain = 0.f;
int finalPrice = std::abs(mCurrentBalance);
int initialMerchantOffer = std::abs(mCurrentMerchantOffer);
if (!buying && (finalPrice > initialMerchantOffer) && finalPrice > 0)
skillGain = floor(100 * (finalPrice - initialMerchantOffer) / float(finalPrice));
else if (buying && (finalPrice < initialMerchantOffer) && initialMerchantOffer > 0)
skillGain = floor(100 * (initialMerchantOffer - finalPrice) / float(initialMerchantOffer));
player.getClass().skillUsageSucceeded(player, ESM::Skill::Mercantile, 0, skillGain);
} }
int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt(); // display message on haggle failure
if (mPtr.getClass().isNpc()) if ( !offerAccepted ) {
MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterSuccessDisposition); MWBase::Environment::get().getWindowManager()->
messageBox("#{sNotifyMessage9}");
return;
}
// make the item transfer // make the item transfer
mTradeModel->transferItems(); mTradeModel->transferItems();

@ -1,6 +1,8 @@
#ifndef MWGUI_TRADEWINDOW_H #ifndef MWGUI_TRADEWINDOW_H
#define MWGUI_TRADEWINDOW_H #define MWGUI_TRADEWINDOW_H
#include "../mwmechanics/trading.hpp"
#include "referenceinterface.hpp" #include "referenceinterface.hpp"
#include "windowbase.hpp" #include "windowbase.hpp"
@ -40,6 +42,7 @@ namespace MWGui
ItemView* mItemView; ItemView* mItemView;
SortFilterItemModel* mSortModel; SortFilterItemModel* mSortModel;
TradeItemModel* mTradeModel; TradeItemModel* mTradeModel;
MWMechanics::Trading mTrading;
static const float sBalanceChangeInitialPause; // in seconds static const float sBalanceChangeInitialPause; // in seconds
static const float sBalanceChangeInterval; // in seconds static const float sBalanceChangeInterval; // in seconds

@ -0,0 +1,84 @@
#include "trading.hpp"
#include <components/misc/rng.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp"
namespace MWMechanics
{
Trading::Trading() {}
bool Trading::haggle(const MWWorld::Ptr& player, const MWWorld::Ptr& merchant, int playerOffer, int merchantOffer)
{
// accept if merchant offer is better than player offer
if ( playerOffer <= merchantOffer ) {
return true;
}
// reject if npc is a creature
if ( merchant.getTypeName() != typeid(ESM::NPC).name() ) {
return false;
}
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
// Is the player buying?
bool buying = (merchantOffer < 0);
int a = std::abs(merchantOffer);
int b = std::abs(playerOffer);
int d = (buying)
? int(100 * (a - b) / a)
: int(100 * (b - a) / a);
int clampedDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(merchant);
const MWMechanics::CreatureStats &merchantStats = merchant.getClass().getCreatureStats(merchant);
const MWMechanics::CreatureStats &playerStats = player.getClass().getCreatureStats(player);
float a1 = static_cast<float>(player.getClass().getSkill(player, ESM::Skill::Mercantile));
float b1 = 0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified();
float c1 = 0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified();
float d1 = static_cast<float>(merchant.getClass().getSkill(merchant, ESM::Skill::Mercantile));
float e1 = 0.1f * merchantStats.getAttribute(ESM::Attribute::Luck).getModified();
float f1 = 0.2f * merchantStats.getAttribute(ESM::Attribute::Personality).getModified();
float dispositionTerm = gmst.find("fDispositionMod")->getFloat() * (clampedDisposition - 50);
float pcTerm = (dispositionTerm - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm();
float npcTerm = (d1 + e1 + f1) * merchantStats.getFatigueTerm();
float x = gmst.find("fBargainOfferMulti")->getFloat() * d
+ gmst.find("fBargainOfferBase")->getFloat()
+ std::abs(int(pcTerm - npcTerm));
int roll = Misc::Rng::rollDice(100) + 1;
// reject if roll fails
// (or if player tries to buy things and get money)
if ( roll > x || (merchantOffer < 0 && 0 < playerOffer) ) {
return false;
}
// apply skill gain on successful barter
float skillGain = 0.f;
int finalPrice = std::abs(playerOffer);
int initialMerchantOffer = std::abs(merchantOffer);
if ( !buying && (finalPrice > initialMerchantOffer) ) {
skillGain = floor(100.f * (finalPrice - initialMerchantOffer) / finalPrice);
}
else if ( buying && (finalPrice < initialMerchantOffer) ) {
skillGain = floor(100.f * (initialMerchantOffer - finalPrice) / initialMerchantOffer);
}
player.getClass().skillUsageSucceeded(player, ESM::Skill::Mercantile, 0, skillGain);
return true;
}
}

@ -0,0 +1,17 @@
#ifndef OPENMW_MECHANICS_TRADING_H
#define OPENMW_MECHANICS_TRADING_H
#include "../mwworld/ptr.hpp"
namespace MWMechanics
{
class Trading
{
public:
Trading();
bool haggle(const MWWorld::Ptr& player, const MWWorld::Ptr& merchant, int playerOffer, int merchantOffer);
};
}
#endif
Loading…
Cancel
Save