Research:Disposition and Persuasion: Difference between revisions

From OpenMW Wiki
Jump to navigation Jump to search
(Added research navbox.)
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Template:Research Navbox}}
==Disposition==
==Disposition==
{{Formula
{{Formula
|All disposition using functions
|All disposition using functions
|Recalculated every time effective disposition is required. Setting disposition assumes you are specifying the effective disposition, so the base disposition is adjust by the delta between the current and desired effective disposition.
|Recalculated every time effective disposition is required. Setting disposition assumes you are specifying the effective disposition, so the base disposition is adjust by the delta between the current and desired effective disposition.
|{{StatusCol|red|not started yet}}
|{{StatusCol|green|Implemented}}
|{{StatusCol|green|Verified}}}}
|{{StatusCol|green|Verified}}}}
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
Line 26: Line 29:
effective disposition = int(x), normally clamped to [0..100] when used
effective disposition = int(x), normally clamped to [0..100] when used
</syntaxhighlight>
</syntaxhighlight>


==Persuasion==
==Persuasion==
Line 32: Line 34:
|On persuade dialogue action
|On persuade dialogue action
|Persuasion options in the NPC dialogue menu.
|Persuasion options in the NPC dialogue menu.
|{{StatusCol|red|not started yet}}
|{{StatusCol|green|Implemented}}
|{{StatusCol|green|Verified}}}}
|{{StatusCol|green|Verified}}}}
===Note===
===Note===
Successfully performing a Bribe, Admire, Taunt or Intimidate will raise your Speechcraft skill.
Successfully performing a Bribe, Admire, Taunt or Intimidate will raise your Speechcraft skill.
===Shared terms===
===Shared terms===
Per-actor terms:
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
persTerm = personality / fPersonalityMod
persTerm = personality / fPersonalityMod
Line 43: Line 46:
levelTerm = level * fLevelMod
levelTerm = level * fLevelMod
fatigueTerm = fFatigueBase - fFatigueMult*(1 - normalisedFatigue)
fatigueTerm = fFatigueBase - fFatigueMult*(1 - normalisedFatigue)
#where normalisedFatigue is a function of fatigue. empty fatigue bar -> 0.0, full fatigue bar -> 1.0
# where normalisedFatigue is a function of fatigue. empty fatigue bar -> 0.0, full fatigue bar -> 1.0
#note fatigueTerm is normally 1.25 at full fatigue.
# note fatigueTerm is normally 1.25 at full fatigue.
</syntaxhighlight>
</syntaxhighlight>
Using player stats:
Using player stats:
Line 52: Line 55:
playerRating3 = (mercantile + luckTerm + persTerm) * fatigueTerm
playerRating3 = (mercantile + luckTerm + persTerm) * fatigueTerm
</syntaxhighlight>
</syntaxhighlight>
Using NPC stats (note differences):
Using NPC stats (note structural differences; ''all terms are calculated from NPC stats''):
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
npcRating1 = (repTerm + luckTerm + persTerm + speechcraft) * fatigueTerm
npcRating1 = (repTerm + luckTerm + persTerm + speechcraft) * fatigueTerm
npcRating2 = (levelTerm + repTerm + luckTerm + persTerm + npcSpeechcraft) * fatigueTerm
npcRating2 = (levelTerm + repTerm + luckTerm + persTerm + speechcraft) * fatigueTerm
npcRating3 = (mercantile + repTerm + luckTerm + persTerm) * fatigueTerm
npcRating3 = (mercantile + repTerm + luckTerm + persTerm) * fatigueTerm
</syntaxhighlight>
</syntaxhighlight>
Summary:
Opposing roll targets:
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
d = 1 - 0.02 * abs(npcDisposition - 50)
d = 1 - 0.02 * abs(npcDisposition - 50)
Line 94: Line 97:
if success:
if success:
     if abs(c) < iPerMinChange:
     if abs(c) < iPerMinChange:
         x = 0, y = -iPerMinChange
         x = 0, y = -iPerMinChange   # bug, see comments
     else:
     else:
         x = -int(c * fPerTempMult), y = c
         x = -int(c * fPerTempMult), y = c
Line 161: Line 164:


The function is long and highly redundant, much of the same formulas are repeatedly calculated many times for no reason.  
The function is long and highly redundant, much of the same formulas are repeatedly calculated many times for no reason.  
It's just another poorly coded part of Morrowind. There is at least one bug with Intimidate where you can see if the calculated  
It's just another poorly coded part of Morrowind. There is at least one bug with Intimidate, where if the calculated  
change is under iPerMinChange, it fails to set x correctly (it should have the value y does). This is responsible for the disposition meter not moving on some Intimidate Success results.
change is less than iPerMinChange, it fails to set x correctly (it should have the value y does). This is responsible for the disposition meter not moving on some Intimidate Success results.
 
 
 
 
{{Template:Research Navbox}}

Latest revision as of 19:01, 19 November 2015


Disposition

Actions affected All disposition using functions
Description Recalculated every time effective disposition is required. Setting disposition assumes you are specifying the effective disposition, so the base disposition is adjust by the delta between the current and desired effective disposition.
Implementation status Implemented
Analysis status Verified
x = baseDisposition (from npc reference)
if pc and npc are the same race: x += fDispRaceMod
x += fDispPersonalityMult * (pcPersonality - fDispPersonalityBase)

if pc and npc are the same faction and pc is not expelled:
    reaction = faction reaction for same faction
    rank = rank in shared faction, range [0..9]
else if npc has a faction:
    reaction = min(faction reactions for all pc factions) (most hated faction) (0 if no faction)
    rank = 0
else:
    reaction = 0, rank = 0

x += (fDispFactionRankMult * rank + fDispFactionRankBase) * fDispFactionMod * reaction
x -= fDispCrimeMod * pcBounty
if pc has a disease: x += fDispDiseaseMod
if pc has weapon drawn: x += fDispWeaponDrawn

effective disposition = int(x), normally clamped to [0..100] when used

Persuasion

Actions affected On persuade dialogue action
Description Persuasion options in the NPC dialogue menu.
Implementation status Implemented
Analysis status Verified

Note

Successfully performing a Bribe, Admire, Taunt or Intimidate will raise your Speechcraft skill.

Shared terms

Per-actor terms:

persTerm = personality / fPersonalityMod
luckTerm = luck / fLuckMod
repTerm = reputation * fReputationMod
levelTerm = level * fLevelMod
fatigueTerm = fFatigueBase - fFatigueMult*(1 - normalisedFatigue)
# where normalisedFatigue is a function of fatigue. empty fatigue bar -> 0.0, full fatigue bar -> 1.0
# note fatigueTerm is normally 1.25 at full fatigue.

Using player stats:

playerRating1 = (repTerm + luckTerm + persTerm + speechcraft) * fatigueTerm
playerRating2 = playerRating1 + levelTerm
playerRating3 = (mercantile + luckTerm + persTerm) * fatigueTerm

Using NPC stats (note structural differences; all terms are calculated from NPC stats):

npcRating1 = (repTerm + luckTerm + persTerm + speechcraft) * fatigueTerm
npcRating2 = (levelTerm + repTerm + luckTerm + persTerm + speechcraft) * fatigueTerm
npcRating3 = (mercantile + repTerm + luckTerm + persTerm) * fatigueTerm

Opposing roll targets:

d = 1 - 0.02 * abs(npcDisposition - 50)
target1 = d * (playerRating1 - npcRating1 + 50)
target2 = d * (playerRating2 - npcRating2 + 50)
target3 = d * (playerRating3 - npcRating3 + 50) + bribeMod
where bribeMod is fBribe10Mod, fBribe100Mod or fBribe1000Mod


Admire

target1 = max(iPerMinChance, target1)
roll 100, win if roll <= target1
c = int(fPerDieRollMult * (target1 - roll))
x = max(iPerMinChange, c) on success, c on fail

Intimidate

target2 = max(iPerMinChance, target2)
roll 100, win if roll <= target2

if roll != target2:
    r = int(target2 - roll)
else:
    r = 1
        
if roll <= target2:
    s = int(r * fPerDieRollMult * fPerTempMult)
    flee = max(iPerMinChange, s)
    fight = min(-iPerMinChange, -s)

c = -abs(int(r * fPerDieRollMult))
if success:
    if abs(c) < iPerMinChange:
        x = 0, y = -iPerMinChange    # bug, see comments
    else:
        x = -int(c * fPerTempMult), y = c
else fail:
    x = int(c * fPerTempMult), y = c

Taunt

target1 = max(iPerMinChance, target1)
roll 100, win if roll <= target1

c = abs(int(target1 - roll))

if roll <= target1:
    s = c * fPerDieRollMult * fPerTempMult
    flee = min(-iPerMinChange, int(-s))
    fight = max(iPerMinChange, int(s))
 
x = int(-c * fPerDieRollMult)
 
if success and abs(x) < iPerMinChange:
    x = -iPerMinChange

Bribe

target3 = max(iPerMinChance, target3)
roll 100, win if roll <= target3
c = int((target3 - roll) * fPerDieRollMult)
 
x = max(iPerMinChange, c) on success, c on fail


Disposition Change

For all persuasion actions there is a temporary and a permanent disposition change. The temporary one applies to the disposition meter you see in the dialogue window. The permanent one is applied when you say goodbye to the NPC; the NPC's disposition is reset to the disposition they had when you initiated the conversation, then the permanent disposition change is applied. You can see these values in the console by using ToggleDialogStats before persuading.

For all methods:

temporary disposition change = int(x * fPerTempMult)

except for Intimidate:

change = x

This may attempt to change actual disposition below/above 0/100. Disposition changes are clamped so as not to go past the caps, and the actual amount the disposition moved is used in the next function.

permanent disposition change = int(cappedDispositionchange / fPerTempMult)

except for Intimidate

change = -int(cappedDispositionchange/ fPerTempMult) on success
y on fail

There may also be modifications to the NPC's flee and fight ratings. The flee and fight variables hold the amount those ratings are changed. They are also capped at 0 and 100.


Comments

The function is long and highly redundant, much of the same formulas are repeatedly calculated many times for no reason. It's just another poorly coded part of Morrowind. There is at least one bug with Intimidate, where if the calculated change is less than iPerMinChange, it fails to set x correctly (it should have the value y does). This is responsible for the disposition meter not moving on some Intimidate Success results.