Research:Trading and Services

From OpenMW Wiki
Revision as of 17:54, 3 September 2012 by Hrnchamd (talk | contribs) (Migrated Trading and Services from Formulae page.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Trading and services

Common mechanics

Barter function

All bartering and services use a common function to evaluate costs. Uses common formula fatigueTerm for each side of a transaction.

defining a function barterOffer :: (Actor npc, int basePrice, bool buyingSelling) -> int offerPrice

if npc is a creature: return basePrice

clampedDisposition = clamp int(npcDisposition) to [0..100]
a = min(pcMercantile, 100)
b = min(0.1 * pcLuck, 10)
c = min(0.2 * pcPersonality, 10)
d = min(npcMercantile, 100)
e = min(0.1 * npcLuck, 10)
f = min(0.2 * npcPersonality, 10)

pcTerm = (clampedDisposition - 50 + a + b + c) * pcFatigueTerm
npcTerm = (d + e + f) * npcFatigueTerm
buyTerm = 0.01 * (100 - 0.5 * (pcTerm - npcTerm))
sellTerm = 0.01 * (50 - 0.5 * (npcTerm - pcTerm))

if buying: x = buyTerm
if selling: x = min(buyTerm, sellTerm)

if x < 1: offerPrice = int(x * basePrice)
if x >= 1: offerPrice = basePrice + int((x - 1) * basePrice)
offerPrice = max(1, offerPrice)


Bartering

Actions affected On choosing/offering an item to buy/sell
Description When selecting items to trade.
Implementation status
Analysis status Verified
basePrice = price of prototype item of the same kind, enchanted items have prices set at enchant time and saved with the object
stackSize = number of items in selected stack

if item is a weapon or armor: x = basePrice * (remainingDurability / maxDurability)
if item is lockpick, probe or repair hammer: x = basePrice * (remainingUses / maxUses)
if item is a filled soul gem: basePrice = soul points contained * empty soul gem price
otherwise: x = basePrice

if buying: merchant offer is adjusted by -barterOffer(merchant, x * stackSize, buying)
if selling: merchant offer is adjusted by +barterOffer(merchant, x * stackSize, selling)
Actions affected On bartering
Description Includes haggling mechanic.
Implementation status
Analysis status Verified
all prices are negative when player is buying, positive when player is selling

accept if playerOffer <= merchantOffer (same for buy and sell)
if npc is a creature: reject (no haggle)

a = abs(merchantOffer)
b = abs(playerOffer)
if buying: d = int(100 * (a - b) / a)
if selling: d = int(100 * (b - a) / a)

clampedDisposition = clamp int(npcDisposition) to [0..100]
pcTerm = (clampedDisposition - 50 + pcMercantile + 0.1 * pcLuck + 0.2 * pcPersonality) * pcFatigueTerm
npcTerm = (npcMercantile + 0.1 * npcLuck + 0.2 * npcPersonality) * npcFatigueTerm
x = fBargainOfferMulti * d + fBargainOfferBase
if buying: x += abs(int(pcTerm - npcTerm))
if selling: x += abs(int(npcTerm - pcTerm))

roll 100, if roll <= x then trade is accepted
adjust npc temporary disposition by iBarterSuccessDisposition or iBarterFailDisposition


Merchant repair

Actions affected On opening the repair service window
Description
Implementation status
Analysis status Verified
p = max(1, basePrice)
r = max(1, int(maxDurability / p))

x = int((maxDurability - durability) / r)
x = int(fRepairMult * x)
cost = barterOffer(npc, x, buying)


Trainers

Actions affected On purchasing training
Description
Implementation status
Analysis status Verified, but buggy. See notes for solution.
cost of training a skill = barterOffer(npc, pcSkill * iTrainingMod, buying)

Standard Morrowind uses the current skill value, including fortifies and drains, which allows cheap training exploits with drain spells. A new implementation should use the skill's base value.


Spell merchant

Actions affected On purchasing a spell
Description
Implementation status
Analysis status Unverified; spell cost calculations are unspecified
cost of purchasing existing spell = barterOffer(npc, spell cost in magicka * fSpellValueMult, buying)

cost of spellmaking = barterOffer(npc, spell cost in magicka * fSpellMakingValueMult, buying)


Enchanting merchant

Actions affected On purchasing an enchantment
Description
Implementation status
Analysis status Unverified; enchantment points are unspecified
cost of enchanting service = barterOffer(npc, enchantment points * fEnchantmentValueMult, buying)


Travel costs

Physical travel

Actions affected On travelling via silt strider, boat or similar travel service AI
Description
Implementation status
Analysis status Requires independent testing
dist = distance from player to destination
cost = barterOffer(npc, int(dist / fTravelMult), buying)
time = int(dist / fTravelTimeMult)


Guild guide

Actions affected On travelling via Mages' Guild teleport service
Description
Implementation status
Analysis status Verified
cost = barterOffer(npc, fMagesGuildTravel, buying)