Source code for PyPoE.poe.sim.formula
"""
Overview
===============================================================================
+----------+------------------------------------------------------------------+
| Path | PyPoE/poe/sim/formula.py |
+----------+------------------------------------------------------------------+
| Version | 1.0.0a0 |
+----------+------------------------------------------------------------------+
| Revision | $Id: db9df107ffbe3149f2652c1059fae216594b2782 $ |
+----------+------------------------------------------------------------------+
| Author | Omega_K2 |
+----------+------------------------------------------------------------------+
Description
===============================================================================
Formulas for calculating certain things.
Agreement
===============================================================================
See PyPoE/LICENSE
.. todo::
Find out the real function for calculating the stat requirement.
Documentation
===============================================================================
.. autoclass:: GemTypes
.. autofunction:: armour_damage_reduction
.. autofunction:: chance_to_hit
.. autofunction:: chance_to_evade
.. autofunction:: gem_stat_requirement
"""
# =============================================================================
# Imports
# =============================================================================
# Python
from enum import Enum
# self
from PyPoE.shared.mixins import ReprMixin
# =============================================================================
# Globals
# =============================================================================
__all__ = ['GemTypes', 'gem_stat_requirement']
# =============================================================================
# Classes
# =============================================================================
[docs]class GemTypes(Enum):
"""
Attributes
----------
support
Support Skill Gem
active
Active Skill Gem
"""
support = 1
active = 2
# =============================================================================
# Functions
# =============================================================================
[docs]def armour_damage_reduction(armour, damage):
"""
Calculates the damage reduction from armour.
.. note::
The final damage reduction may differ; there are other stats that can
grant damage reduction and damage reduction is capped.
Parameters
----------
armour : int
Armour value of the defender
damage : int
Physical damage of the attacker's hit before mitigation
Returns
-------
int
damage reduction factor
"""
return armour / (armour + 10 * damage)
[docs]def chance_to_hit(accuracy, evasion):
"""
Calculates the chance to hit for the given accuracy and evasion.
Parameters
----------
accuracy : int
Accuracy rating of the attacker
evasion : int
Evasion rating of the defender
Returns
-------
float
chance to hit
"""
return accuracy / (accuracy + (evasion * 0.25) ** 0.8)
[docs]def chance_to_evade(accuracy, evasion):
"""
Calculates the chance to evade for the given accuracy and evasion.
Parameters
----------
accuracy : int
Accuracy rating of the attacker
evasion : int
Evasion rating of the defender
Returns
-------
float
chance to evade
"""
return 1 - chance_to_hit(accuracy, evasion)
[docs]def gem_stat_requirement(level, gtype=GemTypes.support, multi=100):
"""
Calculates and returns the stat requirement for the specified level
requirement.
The calculations vary depending on the gem type (i.e. active or support gem)
and on the multiplier.
Currently only multipliers of 100, 60 and 40 are supported.
.. warning::
These functions are primarily reverse engineered and may break with
updates.
Generally, the gem stat requirements seem to be based on a linear
function (i.e. f(x) = ax+b), however values are rounded.
For the values a & b were calculated with linear regression, then
sightly adjusted to produce the correct results for existing gems, but
it may not be entirely accurate.
In particular it seems strange that the formula changes depending on the
multiplier; I haven't been able to figure out a single formula that
works for all, so for the time being each multiplier comes with their
own formula.
Parameters
----------
level : int
Level requirement for the current gem level
gtype : GemTypes
Type of the gem; i.e. GemTypes.support or GemTypes.active
multi : int
Stat multiplier, i.e. from SkillGems.dat
Returns
-------
int
calculated stat requirement
Raises
------
ValueError
if multi is unsupported
if gtype is invalid
"""
if gtype == GemTypes.active:
b = 8 * multi / 100
if multi == 100:
a = 2.1
# can't find a good a for 8
b = 7.75
elif multi == 60:
a = 1.325
elif multi == 40:
a = 0.924
else:
raise ValueError("Unsupported multi '%s'" % multi)
elif gtype == GemTypes.support:
b = 6 * multi / 100
if multi == 100:
a = 1.495
elif multi == 60:
a = 0.945 # 1.575*0.6
elif multi == 40:
a = 0.6575 # 1.64375 * 0.6
else:
raise ValueError("Unsupported multi '%s'" % multi)
else:
raise ValueError("Invalid gtype '%s'. Valid types are:\n%s" % (gtype, GemTypes))
result = round(level*a+b)
# Gems seem to have no requirements lower then 14
return 0 if result < 14 else result