Android Open Source - ShadowCraft_Android Damage Calculator






From Project

Back to project page ShadowCraft_Android.

License

The source code is released under:

GNU General Public License

If you think the Android project ShadowCraft_Android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package calcs;
/*from   w  w  w  .  j a v  a 2  s .co m*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import rogue.Settings;
import classes.Buffs;
import classes.GearBuffs;
import classes.Glyphs;
import classes.Proc;
import classes.ProcsList;
import classes.Race;
import classes.Stats;
import classes.Talents;
import classes.Weapon;
import core.InvalidInputException;
import core.util;

/**
 * This class holds the general interface for a damage calculator - the sorts of
 * parameters and calculated values that will be need by many (or most) classes
 * if they implement a damage calculator using this framework. Not saying that
 * will happen, but I want to leave my options open. Any calculations that are
 * specific to a particular class should go in
 * calcs.<class>.<Class>DamageCalculator instead - for an example, see
 * calcs.rogue.RogueDamageCalculator
 */
public class DamageCalculator {

    // If someone wants to have the constructor take a target level as well and
    // use it to initialize these to a level-dependent value, they're welcome
    // to. At the moment I'm hard-coding them to level 85 values.
    protected static final float TARGET_BASE_ARMOR =       (float) 11977.;
    protected static final float BASE_ONE_HAND_MISS_RATE = (float) .08;
    protected static final float BASE_DW_MISS_RATE =       (float) .27;
    protected static final float BASE_SPELL_MISS_RATE =    (float) .17;
    protected static final float BASE_DODGE_CHANCE =       (float) .065;
    protected static final float BASE_PARRY_CHANCE =       (float) .14;
    protected static final float GLANCE_RATE =             (float) .24;
    protected static final float GLANCE_MULTIPLIER =       (float) .75;

    private Set<String> default_ep_stats = new HashSet<String>();
    private String normalize_ep_stat = null;  // use the setter to initialize in your subclass.
    private int level = 85;
    private Stats stats;
    private Talents talents;
    private Glyphs glyphs;
    private Buffs buffs;
    private Race race;
    private Settings settings;
    private float armor_mitigation_parameter;
    private boolean dodgeable = true;
    private boolean parryable = false;
    private String ep_flag = "";  // EP helpers makes use of this variable.

    /**
     * Constructor. Initializes values and caches values for the information
     * every modeler will need to know about a character. Sets level and
     * eventually propagates it to every object.
     * 
     * @param stats
     *            Stats object; contains gear related stats: numerical stats,
     *            weapons, procs and gear boosts.
     * @param talents
     *            ClassTalent object; contains cached values for talents in the
     *            current game class.
     * @param glyphs
     *            Glyphs object; contains cached values for glyphs in the
     *            current game class.
     * @param buffs
     *            Buffs object; contains raid buffs, food and flasks.
     * @param race
     *            Race object; contains race related stats.
     * @param settings
     *            Settings object; contains fight settings.
     * @param level
     *            Player level.
     */
    public DamageCalculator(Stats stats, Talents talents, Glyphs glyphs, Buffs buffs, Race race, Settings settings, int level) {
        this.stats = stats;
        this.talents = talents;
        this.glyphs = glyphs;
        this.buffs = buffs;
        this.race = race;
        this.settings = settings;
        this.set_level(level);
        if (this.stats.gear_buffs().exists_buff("mixology") && this.buffs.get("agi_flask"))
            this.stats.set("agi", this.stats.get_num_stat("agi") + 80);
        if (this.stats.gear_buffs().exists_buff("master_of_anatomy"))
            this.stats.set("agi", this.stats.get_num_stat("crit") + 80);
    }

    /**
     * This is the general method to change the player level in level dependent
     * classes. Will call _set_constants_for_level().
     * 
     * @param level
     *            Player level.
     */
    public void set_level(int level) {
        this.level = level;
        this._set_constants_for_level();
    }

    public int level() {
        return this.level;
    }

    /**
     * Calculates and caches armor mitigation according to level. Propagates
     * level to every level dependent object.
     */
    protected void _set_constants_for_level() {
        this.buffs.set_level(this.level);
        this.stats.set_level(this.level);
        this.race.set_level(this.level);
        this.armor_mitigation_parameter = ArmorMitigation.parameter(this.level);
    }

    /**
     * Call this in your class specific subclass to list appropriate stats.
     * Allowed values are agi, str, spi, int, white_hit, spell_hit, yellow_hit,
     * haste, crit, mastery, dodge_exp, parry_exp, oh_dodge_exp, mh_dodge_exp,
     * oh_parry_exp, mh_parry_exp
     */
    public void set_default_ep_stats(Set<String> args) {
        this.default_ep_stats = args;
    }

    /**
     * normalize_ep_stat is the stat with value 1 EP, call in your subclass.
     */
    public void set_normalize_ep_stat(String stat) {
        this.normalize_ep_stat = stat;
    }

    /**
     * Most attacks by DPS aren't parryable due to positional negation. But if
     * you ever want to attacking from the front, you can just set that to True.
     */
    public void set_parryable(boolean arg) {
        this.parryable = arg;
    }

    public void set_dodgeable(boolean arg) {
        this.dodgeable = arg;
    }

    // getters
    public Stats stats() {
        return this.stats;
    }

    public Talents talents() {
        return this.talents;
    }

    public Glyphs glyphs() {
        return this.glyphs;
    }

    public Buffs buffs() {
        return this.buffs;
    }

    public Race race() {
        return this.race;
    }

    public Settings settings() {
        return this.settings;
    }

    // //////////////////////
    // EP functions.
    // //////////////////////

    /**
     * The EP methods use this function to bypass capped stats. If we are
     * checking a non capped stat it will add and subtract 1 to the stat and
     * output dps with the changed stat.
     * 
     * @param stat
     * @return Modified dps.
     */
    protected double ep_helper(String stat) {
        Set<String> cap_stats = util.mkSet("dodge_exp", "white_hit",
                "spell_hit", "yellow_hit", "parry_exp", "mh_dodge_exp",
                "oh_dodge_exp", "mh_parry_exp", "oh_parry_exp");
        if (!cap_stats.contains(stat))
            this.stats.set(stat, this.stats.get_num_stat(stat) + 1);
        else
            this.ep_flag = stat;
        double dps = get_dps();
        if (!cap_stats.contains(stat))
            this.stats.set(stat, this.stats.get_num_stat(stat) - 1);
        else
            this.ep_flag = "";

        return dps;
    }

    /**
     * The method to retrieve EP is to modify stats by a small amount and check
     * the dps variance. It deals with numeric stats using ep_helper to modify
     * them by 1. Overloads are provided for different overrides.
     * 
     * @param ep_stats
     *            A set with stats to check; can be defaulted.
     * @param normalize_ep_stat
     *            The stat everything is checked against.
     * @return A hash with EP for numeric stats.
     */
    public Map<String, Double> get_ep(Set<String> ep_stats, String normalize_ep_stat) {
        if (normalize_ep_stat == null)
            normalize_ep_stat = this.normalize_ep_stat;
        if (ep_stats == null)
            ep_stats = this.default_ep_stats;

        double baseline_dps = this.get_dps();
        double normalize_dps = this.ep_helper(normalize_ep_stat);
        double normalize_dps_difference = normalize_dps - baseline_dps;
        Map<String, Double> ep_values = new HashMap<String, Double>();

        for (String stat : ep_stats) {
            double dps = this.ep_helper(stat);
            double ep = Math.abs(dps - baseline_dps) / normalize_dps_difference;
            ep_values.put(stat, ep);
        }

        return ep_values;
    }

    /**
     * get_ep() overload. If you overwrite the default stats, this is the
     * method callers should point to.
     */
    public Map<String, Double> get_ep() {
        return get_ep(null, null);
    }

    /**
     * get_ep() overload. Call this if default stats were not overwritten.
     */
    public Map<String, Double> get_ep(Set<String> ep_stats) {
        return get_ep(ep_stats, null);
    }

    // //////////////////////
    // Weapon EP functions.
    // //////////////////////

    /**
     * Changes the weapon dps by 1 and checks dps difference.
     * 
     * @param normalize_ep_stat
     *            The stat everything is checked against.
     * @return A List with two items: mh dps EP and oh dps EP
     */
    public double get_weapon_dps_ep(String hand, String normalize_ep_stat) {
        if (normalize_ep_stat == null)
            normalize_ep_stat = this.normalize_ep_stat;

        double baseline_dps = this.get_dps();
        double normalize_dps = this.ep_helper(normalize_ep_stat);

        double old_weapon_dps = this.stats.weapon(hand).weapon_dps();
        this.stats.weapon(hand).set_weapon_dps(old_weapon_dps + 1);
        double new_dps = this.get_dps();
        double dps_ep = Math.abs(new_dps - baseline_dps) / (normalize_dps - baseline_dps);
        this.stats.weapon(hand).set_weapon_dps(old_weapon_dps);

        return dps_ep;
    }

    /**
     * get_weapon_dps_ep(...) overload. Callers will point at this if
     * normalize_ep_stat was overridden.
     */
    public Double get_weapon_dps_ep(String hand) {
        return this.get_weapon_dps_ep(hand, null);
    }

    /**
     * Changes the weapon speed and checks dps difference. At some point we
     * should provide a default for these speeds according to class. For the
     * time being callers will need to provide them. Note, however, that speed
     * EP is prone to big variances so most callers won't be using it.
     * 
     * @param speeds A set with different speeds to check.
     * @param normalize_ep_stat The stat everything is checked against.
     * @return A List with two hashes: mh speed EPs and oh speed EPs
     */
    public HashMap<String, Double> get_weapon_speed_ep(String hand, Set<Double> speeds, String normalize_ep_stat) {
        if (normalize_ep_stat == null)
            normalize_ep_stat = this.normalize_ep_stat;

        double baseline_dps = this.get_dps();
        double normalize_dps = this.ep_helper(normalize_ep_stat);
        HashMap<String, Double> speed_ep_values = new HashMap<String, Double>();

        double old_weapon_speed = this.stats.weapon(hand).speed();
        for (double speed : speeds) {
            this.stats.weapon(hand).set_speed((float) speed);
            double new_dps = this.get_dps();
            double ep = (new_dps - baseline_dps) / (normalize_dps - baseline_dps);
            if (Math.abs(ep) < 0.0001)
                ep = 0;
            speed_ep_values.put(hand + "_" + speed, ep);
        }
        this.stats.weapon(hand).set_speed(old_weapon_speed);
        return speed_ep_values;
    }

    /**
     * get_weapon_speed_ep overload. Callers should point to this if the
     * normalize stat was overridden.
     * 
     * @param speeds A set with different speeds to check.
     * @return A List with two hashes: mh speed EPs and oh speed EPs
     */
    public HashMap<String, Double> get_weapon_speed_ep(String hand, Set<Double> speeds) {
        return this.get_weapon_speed_ep(hand, speeds, null);
    }

    public HashMap<String, Double> get_weapon_speed_ep(String hand, double... speeds) {
        Set<Double> set = new HashSet<Double>();
        for (double speed : speeds) {
            set.add(speed);
        }
        return this.get_weapon_speed_ep(hand, set);
    }

    /**
     * Checks the dps difference of every melee enchant available. To do so it
     * will del/set allowed enchants from the weapon.
     * 
     * @param normalize_ep_stat The stat everything is checked against.
     * @param hand The weapon we are checking.
     * @return A hash with enchant EPs.
     */
    public HashMap<String, Double> get_weapon_enchant_ep(String hand, String normalize_ep_stat) {
        if (normalize_ep_stat == null)
            normalize_ep_stat = this.normalize_ep_stat;

        HashMap<String, Double> enchants_ep_values = new HashMap<String, Double>();

        String old_enchant = this.stats.weapon(hand).enchant_name();
        this.stats.weapon(hand);
        for (String enchant : Weapon.allowed_melee_enchants().keySet()) {
            this.stats.weapon(hand).del_enchant();
            double no_enchant_dps = this.get_dps();
            double no_enchant_normalize_dps = this.ep_helper(normalize_ep_stat);
            this.stats.weapon(hand).set_enchant(enchant);
            double new_dps = this.get_dps();
            if (new_dps != no_enchant_dps) {
                double ep = Math.abs(new_dps - no_enchant_dps) / (no_enchant_normalize_dps - no_enchant_dps);
                enchants_ep_values.put(enchant, ep);
            }
            this.stats.weapon(hand).set_enchant(old_enchant);
        }
        return enchants_ep_values;
    }

    /**
     * get_weapon_enchant_ep overload. Callers should point to this if the
     * normalize stat was overridden.
     * 
     * @return A Hash with enchant EPs.
     */
    public HashMap<String, Double> get_weapon_enchant_ep(String hand) {
        return get_weapon_enchant_ep(hand, null);
    }

    // //////////////////////
    // Other EP functions.
    // //////////////////////

    /**
     * Checks the dps difference of every boost/proc passed. To do so it will
     * del/set boosts and procs from the appropriate object. Note that activated
     * abilities like trinkets, potions, or engineering gizmos are handled as
     * gear buffs by the engine.
     * 
     * @param args
     *            A set with procs/boosts to check.
     * @param normalize_ep_stat
     *            The stat everything is checked against.
     * @return A hash containing the EP for each boost or proc
     */
    public Map<String, Double> get_other_ep(Set<String> args, String normalize_ep_stat) {
        if (normalize_ep_stat.equals(""))
            normalize_ep_stat = this.normalize_ep_stat;

        double baseline_dps = this.get_dps();
        double normalize_dps = this.ep_helper(normalize_ep_stat);
        Set<String> proc_set = new HashSet<String>();
        Set<String> boost_set = new HashSet<String>();
        Map<String, Double> ep_values = new HashMap<String, Double>();

        for (String i : args) {
            if (ProcsList.allowed_procs().contains(i))
                proc_set.add(i);
            else if (GearBuffs.allowed_buffs().contains(i))
                boost_set.add(i);
            else
                ep_values.put(i, -1.);  // not allowed
        }

        for (String i : boost_set) {
            this.stats.gear_buffs().switch_buff(i);
            double new_dps = this.get_dps();
            double ep = Math.abs(new_dps - baseline_dps) / (normalize_dps - baseline_dps);
            ep_values.put(i, ep);
            this.stats.gear_buffs().switch_buff(i);
        }

        for (String i : proc_set) {
            try {
                if (this.stats.procs().exists_proc(i))
                    this.stats.procs().del_proc(i);
                else
                    this.stats.procs().append_proc(i);
                double new_dps = this.get_dps();
                double ep = Math.abs(new_dps - baseline_dps) / (normalize_dps - baseline_dps);
                ep_values.put(i, ep);
                if (this.stats.procs().exists_proc(i))
                    this.stats.procs().del_proc(i);
                else
                    this.stats.procs().append_proc(i);
            }
            catch (Proc.InvalidProcException e) {
                ep_values.put(i, -2.);  // not supported proc
                this.stats.procs().del_proc(i);
            }
        }
        return ep_values;
    }

    /**
     * get_other_ep(...) overload. This is what callers should point to if the
     * normalize stat was overridden.
     * 
     * @param args A set with procs/boosts to check.
     * @return A hash containing the EP for each boost or proc
     */
    public Map<String, Double> get_other_ep(Set<String> args) {
        return get_other_ep(args, "");
    }

    /**
     * get_other_ep(...) overload with varargs. Call this only if the normalize
     * stat was overridden.
     * 
     * @param args A set with procs/boosts to check.
     * @return A hash containing the EP for each boost or proc
     */
    public Map<String, Double> get_other_ep(String... args) {
        return get_other_ep(util.mkSet(args), "");
    }

    // //////////////////////
    // Ranking functions.
    // //////////////////////

    /**
     * Checks the dps difference of every glyph passed. If no glyphs are passed
     * it will check every available one to the game class. This returns dps
     * difference, not EP.
     * 
     * @param glyphs
     *            A set with glyphs to check.
     * @return A hash containing the dps difference for each glyph.
     */
    public Map<String, Double> get_glyphs_ranking(Set<String> glyphs) {
        if (glyphs == null)
            glyphs = this.glyphs.allowed_glyphs();

        Map<String, Double> glyph_ranking = new HashMap<String, Double>();
        double baseline_dps = this.get_dps();

        for (String i : glyphs) {
            this.glyphs.switch_glyph(i);
            try {
                double new_dps = get_dps();
                if ((float) new_dps != (float) baseline_dps) {
                    double diff = Math.abs(new_dps - baseline_dps);
                    glyph_ranking.put(i, diff);
                }
            }
            catch (InvalidInputException e) {
                glyph_ranking.put(i, -1.);  // not implemented
            }
            this.glyphs.switch_glyph(i);
        }

        return glyph_ranking;
    }

    /**
     * get_glyphs_ranking(...) overload.
     */
    public Map<String, Double> get_glyphs_ranking() {
        return get_glyphs_ranking(null);
    }

    /**
     * Checks the dps difference of every talent passed. If no talent is passed
     * it will check every available one to the game class. This returns dps
     * difference, not EP.
     * 
     * @param talents
     *            A set with talents to check.
     * @return A hash containing the dps difference for each talent.
     */
    public List<HashMap<String, Double>> get_talents_ranking(Set<String> talents) {
        Map<String, Double> talents_ranking = new HashMap<String, Double>();
        double baseline_dps = this.get_dps();
        Set<String> main_tree_talents = this.talents().get_all_talents_for_active_spec();

        if (talents == null) {
            @SuppressWarnings("unchecked")
            HashSet<String> talent_list = util.addSets(main_tree_talents, this.talents().get_all_talents_up_to_tier(2));
            talents = talent_list;
        }
        for (String talent : talents) {
            int new_talent_value;
            int old_talent_value = this.talents().get(talent);
            if (old_talent_value == 0)
                new_talent_value = 1;
            else
                new_talent_value = old_talent_value - 1;
            this.talents().set_talent(talent, new_talent_value);
            try {
                double new_dps = get_dps();
                if ((float) new_dps != (float) baseline_dps) {
                    double diff = Math.abs(new_dps - baseline_dps);
                    talents_ranking.put(talent, diff);
                }
            }
            catch (InvalidInputException e) {
                talents_ranking.put(talent, -1.);  // not implemented
            }
            this.talents().set_talent(talent, old_talent_value);
        }

        HashMap<String, Double> main_tree_talents_ranking = new HashMap<String, Double>();
        HashMap<String, Double> off_trees_talents_ranking = new HashMap<String, Double>();
        for (Entry<String, Double> talent : talents_ranking.entrySet()) {
            String key = talent.getKey();
            double value = talent.getValue();
            if (main_tree_talents.contains(key))
                main_tree_talents_ranking.put(key, value);
            else
                off_trees_talents_ranking.put(key, value);
        }
        List<HashMap<String, Double>> return_list = new ArrayList<HashMap<String, Double>>();
        return_list.add(main_tree_talents_ranking);
        return_list.add(off_trees_talents_ranking);

        return return_list;
    }

    /**
     * get_talents_ranking(...) overload.
     */
    public List<HashMap<String, Double>> get_talents_ranking() {
        return this.get_talents_ranking(null);
    }

    // //////////////////////
    // Modeler functions.
    // //////////////////////

    /**
     * Overwrite this function with your calculations/simulations/whatever; this
     * is what callers will (initially) be looking at.
     * 
     * @return dps for current spec and stats.
     */
    public double get_dps() {
        return 0;
    }

    /**
     * Overwrite this function with your calculations/simulations/whatever; this
     * is what callers will (initially) be looking at.
     * 
     * @return damage breakdown per ability.
     */
    public Map<String, Double> get_dps_breakdown() {
        return null;
    }

    /**
     * Override this in your subclass to implement talents that modify spell hit
     * chance.
     */
    public double get_spell_hit_from_talents() {
        return 0;
    }

    /**
     * Override this in your subclass to implement talents that modify melee hit
     * chance.
     */
    public double get_melee_hit_from_talents() {
        return 0;
    }

    /**
     * Gets activated boosts from gear and racials.
     * 
     * @return A list containing data for the modeler.
     */
    public List<HashMap<String, Object>> get_all_activated_stat_boosts() {
        List<HashMap<String, Object>> racial_boosts = this.race.get_stat_boosts();
        List<HashMap<String, Object>> gear_boosts = this.stats.gear_buffs().get_all_activated_boosts();
        List<HashMap<String, Object>> boosts = new ArrayList<HashMap<String, Object>>();
        boosts.addAll(racial_boosts);
        boosts.addAll(gear_boosts);
        return boosts;
    }

    /**
     * Computes the armor mitigation modifier.
     * 
     * @param armor
     *            Target armor
     */
    public double armor_mitig_mult(double armor) {
        return ArmorMitigation.multiplier(armor, this.armor_mitigation_parameter);
    }

    /**
     * Pass in raw physical damage and armor value, get armor-mitigated damage
     * value.
     */
    public double armor_mitigate(double damage, double armor) {
        return damage * this.armor_mitig_mult(armor);
    }

    /**
     * General function that we use in subsequent methods. The field variables
     * dodgeable and parryable drive the output of this method. Note that miss
     * chance is capped at 0. We make extensive use of the EP_flag in all of
     * these methods too, to figure add points to capped stats.
     * 
     * @param base_miss_chance
     *            This is provided by the modeler for each call.
     * @param weapon_type
     *            racials have an effect on hit depending on type.
     * @return melee hit chance
     */
    public double melee_hit_chance(float base_miss_chance, String weapon_type) {
        double hit_chance = this.stats.get_melee_hit_from_rating() + this.race.get_racial_hit() + this.get_melee_hit_from_talents();
        double miss_chance = Math.max(base_miss_chance - hit_chance, 0);

        // Expertise represented as the reduced chance to be dodged or parried,
        // not true "Expertise"
        double expertise = this.stats.get_expertise_from_rating() + this.race.get_racial_expertise(weapon_type);

        double dodge_chance = 0;
        if (this.dodgeable) {
            dodge_chance = Math.max(BASE_DODGE_CHANCE - expertise, 0);
            if (this.ep_flag.equals("dodge_exp"))
                dodge_chance += this.stats.get_expertise_from_rating(1);
        }

        double parry_chance = 0;
        if (this.parryable) {
            parry_chance = Math.max(BASE_PARRY_CHANCE - expertise, 0);
            if (util.mkSet("parry_exp", "dodge_exp").contains(this.ep_flag))
                parry_chance += this.stats.get_expertise_from_rating(1);
        }

        return 1 - (miss_chance + dodge_chance + parry_chance);
    }

    /**
     * If no weapon is provided it will take the mh. Uses the field variables
     * dodgeable/parryable along with the ep_flag to add 1 to this capped stat.
     * 
     * @param weapon
     *            Weapon object.
     * @return 1h melee hit chance
     */
    public double one_hand_melee_hit_chance(Weapon weapon) {
        if (weapon == null)
            weapon = this.stats.weapon("mh");
        double hit_chance = this.melee_hit_chance(BASE_ONE_HAND_MISS_RATE, weapon.type());
        if (this.ep_flag.equals("yellow_hit"))
            hit_chance -= this.stats.get_melee_hit_from_rating(1);
        if ((this.ep_flag.equals("mh_dodge_exp") && this.dodgeable) || (this.ep_flag.equals("mh_parry_exp") && this.parryable))
            hit_chance -= this.stats.get_expertise_from_rating(1);
        return hit_chance;
    }

    /**
     * one_hand_melee_hit_chance(...) overload.
     */
    public double one_hand_melee_hit_chance() {
        return one_hand_melee_hit_chance(null);
    }

    /**
     * If no weapon is provided it will take the oh. Uses the field variables
     * dodgeable/parryable along with the ep_flag to add 1 to this capped stat.
     * 
     * @param weapon
     *            Weapon object.
     * @return oh melee hit chance
     */
    public double off_hand_melee_hit_chance(Weapon weapon) {
        if (weapon == null)
            weapon = this.stats.weapon("oh");
        double hit_chance = this.melee_hit_chance(BASE_ONE_HAND_MISS_RATE, weapon.type());
        if (this.ep_flag.equals("yellow_hit"))
            hit_chance -= this.stats.get_melee_hit_from_rating(1);
        if ((this.ep_flag.equals("oh_dodge_exp") && this.dodgeable) || (this.ep_flag.equals("oh_parry_exp") && this.parryable))
            hit_chance -= this.stats.get_expertise_from_rating(1);
        return hit_chance;
    }

    /**
     * off_hand_melee_hit_chance(...) overload.
     */
    public double oh_melee_hit_chance() {
        return off_hand_melee_hit_chance(null);
    }

    /**
     * General function that we use in subsequent methods related to dual
     * wielding. It makes uses of the previous general method melee_hit_chance.
     * 
     * @param weapon_type
     *            racials have an effect on hit depending on type.
     * @return dw hit chance
     */
    public double dw_hit_chance(String weapon_type) {
        double hit_chance = this.melee_hit_chance(
                DamageCalculator.BASE_DW_MISS_RATE, weapon_type);
        if (util.mkSet("yellow_hit", "spell_hit", "white_hit").contains(this.ep_flag))
            hit_chance -= this.stats.get_melee_hit_from_rating(1);
        return hit_chance;
    }

    /**
     * Uses the field variables dodgeable/parryable along with the ep_flag to
     * add 1 to this capped stat.
     * 
     * @return dw mh hit chance
     */
    public double dw_mh_hit_chance() {
        double hit_chance = this.dw_hit_chance(this.stats.weapon("mh").type());
        if ((this.ep_flag.equals("mh_dodge_exp") && this.dodgeable) || (this.ep_flag.equals("mh_parry_exp") && this.parryable))
            hit_chance -= this.stats.get_expertise_from_rating(1);
        return hit_chance;
    }

    /**
     * Uses the field variables dodgeable/parryable along with the ep_flag to
     * add 1 to this capped stat.
     * 
     * @return dw oh hit chance
     */
    public double dw_oh_hit_chance() {
        double hit_chance = this.dw_hit_chance(this.stats.weapon("oh").type());
        if ((this.ep_flag.equals("oh_dodge_exp") && this.dodgeable) || (this.ep_flag.equals("oh_parry_exp") && this.parryable))
            hit_chance -= this.stats.get_expertise_from_rating(1);
        return hit_chance;
    }

    public double spell_hit_chance() {
        float base_miss = BASE_SPELL_MISS_RATE;
        double rating = this.stats.get_spell_hit_from_rating();
        double talents = this.get_spell_hit_from_talents();
        double race = this.race.get_racial_hit();
        double hit_chance = 1 - Math.max(base_miss - rating - talents - race, 0);
        if (util.mkSet("yellow_hit", "spell_hit").contains(this.ep_flag))
            hit_chance -= this.stats.get_spell_hit_from_rating(1);
        return hit_chance;
    }

    public double buff_melee_crit() {
        return this.buffs.buff_all_crit();
    }

    public double buff_spell_crit() {
        return this.buffs.buff_spell_crit() + this.buffs.buff_all_crit();
    }

    /**
     * Passes base armor reduced by armor debuffs or overridden armor
     * 
     * @param armor
     *            Target armor override.
     */
    public double target_armor(float armor) {
        if (armor == 0)
            armor = TARGET_BASE_ARMOR;
        return this.buffs.armor_reduction_mult() * armor;
    }

    /**
     * target_armor(...) overload.
     */
    public double target_armor() {
        return target_armor(0);
    }

    /**
     * This function wraps spell, bleed and physical debuffs from raid along
     * with all-damage buff and armor reduction. It should be called from every
     * damage dealing formula. Armor can be overridden if needed.
     */
    public double raid_settings_mods(String attack_kind, float armor) {
        double modifier = 0;
        if (attack_kind.equals("spell"))
            modifier = this.buffs.spell_dmg_mult();
        else if (attack_kind.equals("bleed"))
            modifier = this.buffs.bleed_dmg_mult();
        else if (attack_kind.equals("physical")) {
            double armor_override = this.target_armor(armor);
            modifier = this.buffs.physical_dmg_mult() * this.armor_mitig_mult(armor_override);
        }
        else
            throw new InvalidInputException(String.format("Attacks must be categorized as physical, spell or bleed"));
        return modifier;
    }

    /**
     * raid_settings_modifiers overload.
     */
    public double raid_settings_mod(String attack_kind) {
        return raid_settings_mods(attack_kind, 0);
    }

}




Java Source Code List

calcs.ArmorMitigation.java
calcs.DamageCalculator.java
classes.Buffs.java
classes.Data.java
classes.GearBuffs.java
classes.Glyphs.java
classes.Proc.java
classes.ProcsList.java
classes.Race.java
classes.Stats.java
classes.Talents.java
classes.Weapon.java
com.shadowcraft.android.APP.java
com.shadowcraft.android.Bnet.java
com.shadowcraft.android.CharHandler.java
com.shadowcraft.android.DataBaseHelper.java
com.shadowcraft.android.Data.java
com.shadowcraft.android.Gear.java
com.shadowcraft.android.IconHandler.java
com.shadowcraft.android.ItemView.java
com.shadowcraft.android.RogueBackend.java
com.shadowcraft.android.ShadowcraftMain.java
com.shadowcraft.android.Stat.java
com.shadowcraft.android.TalentsData.java
com.shadowcraft.android.Talents.java
core.InvalidInputException.java
core.InvalidLevelException.java
core.util.java
rogue.AldrianasRogueDamageCalculator.java
rogue.Cycle.java
rogue.RogueDamageCalculator.java
rogue.RogueGlyphs.java
rogue.RogueModelerData.java
rogue.RogueTalents.java
rogue.Settings.java