forked from mirror/openmw-tes3mp
implement barterOffer. It's used for travel only.
I've started to implement disposition, but it's very basic for now.
This commit is contained in:
parent
234716daa6
commit
f72f898bd9
7 changed files with 84 additions and 1 deletions
|
@ -74,6 +74,12 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void restoreDynamicStats() = 0;
|
virtual void restoreDynamicStats() = 0;
|
||||||
///< If the player is sleeping, this should be called every hour.
|
///< 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.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,8 @@ namespace MWClass
|
||||||
data->mCreatureStats.getFatigue().set (ref->base->mNpdt52.mFatigue);
|
data->mCreatureStats.getFatigue().set (ref->base->mNpdt52.mFatigue);
|
||||||
|
|
||||||
data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel);
|
data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel);
|
||||||
|
|
||||||
|
data->mNpcStats.setDisposition(ref->base->mNpdt52.mDisposition);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,6 +66,8 @@ namespace MWGui
|
||||||
price = d/MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelMult")->getFloat();
|
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);
|
MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default);
|
||||||
mCurrentY += sLineHeight;
|
mCurrentY += sLineHeight;
|
||||||
/// \todo price adjustment depending on merchantile skill
|
/// \todo price adjustment depending on merchantile skill
|
||||||
|
|
|
@ -324,4 +324,56 @@ namespace MWMechanics
|
||||||
buildPlayer();
|
buildPlayer();
|
||||||
mUpdatePlayer = true;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,12 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual void restoreDynamicStats();
|
virtual void restoreDynamicStats();
|
||||||
///< If the player is sleeping, this should be called every hour.
|
///< 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.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
MWMechanics::NpcStats::NpcStats()
|
MWMechanics::NpcStats::NpcStats()
|
||||||
: mMovementFlags (0), mDrawState (DrawState_Nothing)
|
: mMovementFlags (0), mDrawState (DrawState_Nothing)
|
||||||
, mLevelProgress(0)
|
, mLevelProgress(0), mDisposition(0)
|
||||||
{
|
{
|
||||||
mSkillIncreases.resize (ESM::Attribute::Length);
|
mSkillIncreases.resize (ESM::Attribute::Length);
|
||||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
@ -36,6 +36,16 @@ void MWMechanics::NpcStats::setDrawState (DrawState_ state)
|
||||||
mDrawState = 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
|
bool MWMechanics::NpcStats::getMovementFlag (Flag flag) const
|
||||||
{
|
{
|
||||||
return mMovementFlags & flag;
|
return mMovementFlags & flag;
|
||||||
|
|
|
@ -43,6 +43,7 @@ namespace MWMechanics
|
||||||
std::map<std::string, int> mFactionRank;
|
std::map<std::string, int> mFactionRank;
|
||||||
|
|
||||||
DrawState_ mDrawState;
|
DrawState_ mDrawState;
|
||||||
|
unsigned int mDisposition;
|
||||||
unsigned int mMovementFlags;
|
unsigned int mMovementFlags;
|
||||||
Stat<float> mSkill[27];
|
Stat<float> mSkill[27];
|
||||||
|
|
||||||
|
@ -60,6 +61,10 @@ namespace MWMechanics
|
||||||
|
|
||||||
void setDrawState (DrawState_ state);
|
void setDrawState (DrawState_ state);
|
||||||
|
|
||||||
|
unsigned int getDisposition() const;
|
||||||
|
|
||||||
|
void setDisposition(unsigned int disposition);
|
||||||
|
|
||||||
bool getMovementFlag (Flag flag) const;
|
bool getMovementFlag (Flag flag) const;
|
||||||
|
|
||||||
void setMovementFlag (Flag flag, bool state);
|
void setMovementFlag (Flag flag, bool state);
|
||||||
|
|
Loading…
Reference in a new issue