Skip to content

Calculations

srl edited this page May 6, 2023 · 1 revision

Damage calc

#!/usr/bin/env python
# coding: utf-8

# In[4]:


import random
import numpy as np

statline = np.dtype([
    ('level', 'i4'),
    ('base_atk', 'f4'),
    ('atk_perc', 'f4'),
    ('flat_atk', 'f4'),
    ('base_def', 'f4'),
    ('def_perc', 'f4'),
    ('flat_def', 'f4'),
    ('base_hp', 'f4'),
    ('hp_perc', 'f4'),
    ('flat_hp', 'f4'),
    ('crate_perc', 'f4'),
    ('cdmg_perc', 'f4'),
    ('all_dmg_perc', 'f4'),
    ('basic_dmg_perc', 'f4'),
    ('skill_dmg_perc', 'f4'),
    ('ult_dmg_perc', 'f4'),
    ('dot_dmg_perc', 'f4'),
    ('physical_dmg_perc', 'f4'),
    ('fire_dmg_perc', 'f4'),
    ('ice_dmg_perc', 'f4'),
    ('lightning_dmg_perc', 'f4'),
    ('wind_dmg_perc', 'f4'),
    ('quantum_dmg_perc', 'f4'),
    ('imaginary_dmg_perc', 'f4'),
    ('physical_res_perc', 'f4'),
    ('fire_res_perc', 'f4'),
    ('ice_res_perc', 'f4'),
    ('lightning_res_perc', 'f4'),
    ('wind_res_perc', 'f4'),
    ('quantum_res_perc', 'f4'),
    ('imaginary_res_perc', 'f4'),
    ('physical_pen_perc', 'f4'),
    ('fire_pen_perc', 'f4'),
    ('ice_pen_perc', 'f4'),
    ('lightning_pen_perc', 'f4'),
    ('wind_pen_perc', 'f4'),
    ('quantum_pen_perc', 'f4'),
    ('imaginary_pen_perc', 'f4'),
    ('all_def_shred_perc', 'f4'),
    ('basic_def_shred_perc', 'f4'),
    ('skill_def_shred_perc', 'f4'),
    ('ult_def_shred_perc', 'f4'),
    ('dot_def_shred_perc', 'f4'),
    ('physical_def_shred_perc', 'f4'),
    ('fire_def_shred_perc', 'f4'),
    ('ice_def_shred_perc', 'f4'),
    ('lightning_def_shred_perc', 'f4'),
    ('wind_def_shred_perc', 'f4'),
    ('quantum_def_shred_perc', 'f4'),
    ('imaginary_def_shred_perc', 'f4'),
    ('all_vuln_perc', 'f4'),
    ('basic_vuln_perc', 'f4'),
    ('skill_vuln_perc', 'f4'),
    ('ult_vuln_perc', 'f4'),
    ('dot_vuln_perc', 'f4'),
    ('physical_vuln_perc', 'f4'),
    ('fire_vuln_perc', 'f4'),
    ('ice_vuln_perc', 'f4'),
    ('lightning_vuln_perc', 'f4'),
    ('wind_vuln_perc', 'f4'),
    ('quantum_vuln_perc', 'f4'),
    ('imaginary_vuln_perc', 'f4'),
])


def calc_damage(mv, element, action_type, statline_attacker, statline_target, broken):
    """
    Calculates the total damage dealt during a damaging instance

    :param mv: Tuple consisting out of a damage multiplier and a stat type, on which the multiplier will scale off of (atk, def, hp, flat). The stat 'flat' is always treated as 1.
    :param element: Element of the damaging instance
    :param action_type: Damage type of the damaging instance (basic, skill, ult, dot)
    :param statline_attacker: Statline of the attacker
    :param statline_target: Statline of the target
    :param broken: Whether the target is weakness broken or not
    :return: Total damage dealt with this instance
    """


    elemental_dmg_type = ''
    elemental_res_type = ''
    elemental_pen_type = ''
    elemental_def_shred = ''
    elemental_vuln_type = ''

    match element:
        case 'physical':
            elemental_dmg_type = 'physical_dmg_perc'
            elemental_res_type = 'physical_res_perc'
            elemental_pen_type = 'physical_pen_perc'
            elemental_def_shred = 'physical_def_shred_perc'
            elemental_vuln_type = 'physical_vuln_perc'
        case 'fire':
            elemental_dmg_type = 'fire_dmg_perc'
            elemental_res_type = 'fire_res_perc'
            elemental_pen_type = 'fire_pen_perc'
            elemental_def_shred = 'fire_def_shred_perc'
            elemental_vuln_type = 'fire_vuln_perc'
        case 'ice':
            elemental_dmg_type = 'ice_dmg_perc'
            elemental_res_type = 'ice_res_perc'
            elemental_pen_type = 'ice_pen_perc'
            elemental_def_shred = 'ice_def_shred_perc'
            elemental_vuln_type = 'ice_vuln_perc'
        case 'lightning':
            elemental_dmg_type = 'lightning_dmg_perc'
            elemental_res_type = 'lightning_res_perc'
            elemental_pen_type = 'lightning_pen_perc'
            elemental_def_shred = 'lightning_def_shred_perc'
            elemental_vuln_type = 'lightning_vuln_perc'
        case 'wind':
            elemental_dmg_type = 'wind_dmg_perc'
            elemental_res_type = 'wind_res_perc'
            elemental_pen_type = 'wind_pen_perc'
            elemental_def_shred = 'wind_def_shred_perc'
            elemental_vuln_type = 'wind_vuln_perc'
        case 'quantum':
            elemental_dmg_type = 'quantum_dmg_perc'
            elemental_res_type = 'quantum_res_perc'
            elemental_pen_type = 'quantum_pen_perc'
            elemental_def_shred = 'quantum_def_shred_perc'
            elemental_vuln_type = 'quantum_vuln_perc'
        case 'imaginary':
            elemental_dmg_type = 'imaginary_dmg_perc'
            elemental_res_type = 'imaginary_res_perc'
            elemental_pen_type = 'imaginary_pen_perc'
            elemental_def_shred = 'imaginary_def_shred_perc'
            elemental_vuln_type = 'imaginary_vuln_perc'


    action_dmg_type = ''
    action_def_shred_type = ''
    action_vuln_type = ''

    match action_type:
        case 'basic':
            action_dmg_type = 'basic_dmg_perc'
            action_def_shred_type = 'basic_def_shred_perc'
            action_vuln_type = 'basic_vuln_perc'
        case 'skill':
            action_dmg_type = 'skill_dmg_perc'
            action_def_shred_type = 'skill_def_shred_perc'
            action_vuln_type = 'skill_vuln_perc'
        case 'ult':
            action_dmg_type = 'ult_dmg_perc'
            action_def_shred_type = 'ult_def_shred_perc'
            action_vuln_type = 'ult_vuln_perc'
        case 'dot':
            action_dmg_type = 'dot_dmg_perc'
            action_def_shred_type = 'dot_def_shred_perc'
            action_vuln_type = 'dot_vuln_perc'


    # Group 1: Base Damage

    g1 = 1

    match mv[1]:
        case 'atk':
            g1 = mv[0] * (statline_attacker['base_atk'] * (1 + statline_attacker['atk_perc']) + statline_attacker['flat_atk'])
        case 'def':
            g1 = mv[0] * (statline_attacker['base_def'] * (1 + statline_attacker['def_perc']) + statline_attacker['flat_def'])
        case 'hp':
            g1 = mv[0] * (statline_attacker['base_hp'] * (1 + statline_attacker['hp_perc']) + statline_attacker['flat_hp'])
        case 'flat':
            g1 = mv[0]


    # Group 2: Crit

    g2 = 1

    if random.uniform(0, 1) > statline_attacker['crate_perc']:
        g1 = 1 + statline_attacker['cdmg_perc']


    # Group 3: Bonus Damage Multiplier

    g3 = 1 + statline_attacker['all_dmg_perc'] + statline_attacker[elemental_dmg_type] + statline_attacker[action_dmg_type]


    # Group 4: Defense Multiplier

    target_total_def = (statline_target['base_def'] * (1 + statline_target['def_perc']) + statline_target['flat_def']) \
                       * (1 - statline_attacker['all_def_shred'] * statline_attacker[elemental_def_shred] * statline_attacker[action_def_shred_type])

    g4 = 1 - (target_total_def / (target_total_def + 200 + 10 * statline_attacker['level']))


    # Group 5: Resistance Multiplier

    g5 = 1 - (statline_target[elemental_res_type] - statline_attacker[elemental_pen_type])


    # Group 6: Vulnerability Multiplier

    g6 = 1 + statline_target['all_vuln_perc'] + statline_target[elemental_vuln_type] + statline_target[action_vuln_type]


    # Group 7: Toughness Multiplier

    g7 = 1 if broken else 0.9


    # Total Damage

    return g1 * g2 * g3 * g4 * g5 * g6 * g7


# In[ ]:

Clone this wiki locally