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
aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting
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

@ -4,8 +4,6 @@
#include <MyGUI_InputManager.h>
#include <MyGUI_ControllerManager.h>
#include <components/misc/rng.hpp>
#include <components/widgets/numericeditbox.hpp>
#include "../mwbase/environment.hpp"
@ -19,8 +17,8 @@
#include "../mwworld/containerstore.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/actorutil.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "inventorywindow.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?
bool buying = (mCurrentMerchantOffer < 0);
// apply disposition change if merchant is NPC
if ( mPtr.getClass().isNpc() ) {
int dispositionDelta = offerAccepted
? gmst.find("iBarterSuccessDisposition")->getInt()
: gmst.find("iBarterFailDisposition")->getInt();
if(mCurrentBalance > mCurrentMerchantOffer)
{
//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);
MWBase::Environment::get().getDialogueManager()->applyDispositionChange(dispositionDelta);
}
int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt();
if (mPtr.getClass().isNpc())
MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterSuccessDisposition);
// display message on haggle failure
if ( !offerAccepted ) {
MWBase::Environment::get().getWindowManager()->
messageBox("#{sNotifyMessage9}");
return;
}
// make the item transfer
mTradeModel->transferItems();

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