Esempio n. 1
0
 def test_cycle(self):
     """ Test the spreadsheet port for cycle length """
     my_stat_spread = CharacterStatSpread(
         wd=180, mainstat=5577, det=2272, crit=3802, dh=1100, speed=2139, ten=380, pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     mypps = SchPps()
     self.assertEqual(174.12, mypps.get_cycle(test_char, 0.12))
Esempio n. 2
0
    def test_sample_sch_rotation_correct_casts_237gcd(self):
        """ Ensure the time variable sim allows weaving after instant casts on a cursed gcd """
        my_stat_spread = CharacterStatSpread(wd=180,
                                             mainstat=5577,
                                             det=2272,
                                             crit=3802,
                                             dh=1100,
                                             speed=1674,
                                             ten=380,
                                             pie=340)
        test_char = Character(Jobs.SCH, my_stat_spread)
        mypps = SchPps()
        # in 2 minutes on a 4th gcd chain opener, youd have: 2 AF, 9 ED, 1 CS, 1 SC, 1 Diss, 4 bio, 3 R2, 42 B3
        sim_result = mypps.get_total_potency_variable_time(
            120, test_char, SampleSchRotation(), 0.1)

        # assert this is the expected gcd
        self.assertAlmostEqual(2.37, test_char.get_gcd(), places=2)

        self.assertEqual(len(sim_result.timeline[SchAction.AETHERFLOW]), 2)
        self.assertEqual(len(sim_result.timeline[SchAction.ENERGYDRAIN]), 9)
        self.assertEqual(len(sim_result.timeline[SchAction.CHAINSTRATAGEM]), 1)
        self.assertEqual(len(sim_result.timeline[SchAction.SWIFTCAST]), 2)
        self.assertEqual(len(sim_result.timeline[SchAction.DISSIPATION]), 1)
        self.assertEqual(len(sim_result.timeline[SchAction.BIOLYSIS]), 4)
        self.assertEqual(len(sim_result.timeline[SchAction.RUIN2]), 3)
        self.assertEqual(len(sim_result.timeline[SchAction.BROIL3]), 41)

        # assert expected bio timings
        self.assertListEqual(
            [round(x, 2) for x in sim_result.timeline[SchAction.BIOLYSIS]],
            [0, 29.14, 61.15, 90.69])
Esempio n. 3
0
 def test_total_potency(self):
     """ Test the spreadsheet port for total potency """
     my_stat_spread = CharacterStatSpread(
         wd=180, mainstat=5577, det=2272, crit=3802, dh=1100, speed=2139, ten=380, pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     mypps = SchPps()
     self.assertEqual(24326.1264, mypps.total_potency_spreadsheet_port(test_char, 0.12, 4, 0))
Esempio n. 4
0
 def test_mp(self):
     """ Test the spreadsheet port for mp generation """
     my_stat_spread = CharacterStatSpread(
         wd=180, mainstat=5577, det=2272, crit=3802, dh=1100, speed=2139, ten=380, pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     mypps = SchPps()
     self.assertEqual(508.0952931652587,
                      mypps.get_mp_per_min(test_char, caster_tax=0.1, succ=0, adlo=0, energy_drain=4, rez=0), )
 def test_scholar(self):
     """ E2E scholar damage calc test """
     my_stat_spread = CharacterStatSpread(
         wd=180, mainstat=5577, det=2272, crit=3802, dh=1100, speed=2139, ten=380, pie=340)
     my_character = Character(Jobs.SCH, my_stat_spread)
     the_shitters_i_raid_with = \
         Comp({Jobs.PLD, Jobs.WAR, Jobs.SCH, Jobs.WHM, Jobs.SAM, Jobs.SAM, Jobs.MCH, Jobs.BLM})
     # have to manually provide pps for testing for now
     self.assertEqual(14238.04118, my_character.calc_damage(139.71, the_shitters_i_raid_with))
Esempio n. 6
0
def update_stats():
    """Calculates damage, mp consumption, and gcd based on input.
    Accepts and returns JSON. JSON format is as follows:
    input: {'player': Object
                {'weaponDamage': int
                'mainStat': int
                'det': int
                'crit': int
                'dh': int
                'speed': int
                'ten': int
                'pie': int}
            'job': string
            'comp': Array}
    output: {'dps': float,
             'gcd': float,
             'mp': float}
    """
    data = request.get_json()

    if not data:
        return "abort", abort(400)

    player_data = data['player']

    try:
        my_job = Jobs.create_job(data['job'])[0]
    except KeyError:
        return f"Currently {data['job']} is not supported."

    player = Character(
        my_job,
        CharacterStatSpread(wd=player_data['weaponDamage'],
                            mainstat=player_data['mainStat'],
                            det=player_data['det'],
                            crit=player_data['crit'],
                            dh=player_data['dh'],
                            speed=player_data['speed'],
                            ten=player_data['ten'],
                            pie=player_data['pie']))
    my_sch_pps = SchPps()
    potency = my_sch_pps.get_pps(player)
    try:
        comp_jobs = [Jobs.create_job(comp_job)[0] for comp_job in data['comp']]
    except KeyError:
        return "A job was not supported in that team comp."

    my_comp = Comp(comp_jobs)

    dps = round(player.calc_damage(potency, my_comp), 2)
    gcd = player.get_gcd()
    mp = round(my_sch_pps.get_mp_per_min(player), 2)
    return jsonify({"dps": dps, "gcd": gcd, "mp": mp})
Esempio n. 7
0
 def test_dot_scalar(self):
     """ Test speed is applying dot bonus correctly """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     self.assertAlmostEqual(1.069, test_char.get_dot_scalar(), places=3)
Esempio n. 8
0
 def test_gcd(self):
     """ Test gcd is applying speed correctly """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     self.assertAlmostEqual(2.32, test_char.get_gcd(), places=2)
Esempio n. 9
0
 def test_base_piety(self):
     """ Test applying piety correctly """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     self.assertEqual(200, test_char.calc_piety())
Esempio n. 10
0
 def test_applies_comp_penalty(self):
     """ 3 roles, no raid buffs, should be lower than the number in test_baseline """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     # 3 roles, who even needs raid buffs
     the_shitters_i_raid_with = Comp({Jobs.PLD, Jobs.WHM, Jobs.SAM})
     # have to manually provide pps for testing for now
     self.assertEqual(19855.659200000002,
                      test_char.calc_damage(200, the_shitters_i_raid_with))
Esempio n. 11
0
 def test_applies_crit_dh_raid_bonuses(self):
     """ 5 roles, sch and brd for raid buffs, should be higher than test_baseline """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     # DNC not included to isolate confounding variable (tech step)
     the_shitters_i_raid_with = Comp(
         {Jobs.PLD, Jobs.WAR, Jobs.SCH, Jobs.SAM, Jobs.BRD, Jobs.BLM})
     # have to manually provide pps for testing for now
     self.assertEqual(20685.98776726701,
                      test_char.calc_damage(200, the_shitters_i_raid_with))
Esempio n. 12
0
 def test_baseline(self):
     """ Baseline test: 5 roles, no raid buffs """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     the_shitters_i_raid_with = Comp({
         Jobs.PLD, Jobs.WAR, Jobs.SCH, Jobs.WHM, Jobs.SAM, Jobs.SAM,
         Jobs.MCH, Jobs.BLM
     })
     # have to manually provide pps for testing for now
     self.assertEqual(20381.368540000003,
                      test_char.calc_damage(200, the_shitters_i_raid_with))
Esempio n. 13
0
 def test_multiple_raidbuff(self):
     """ Test multiple raid buffs are applying damage correctly """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     the_shitters_i_raid_with = Comp({
         Jobs.PLD, Jobs.WAR, Jobs.SCH, Jobs.AST, Jobs.NIN, Jobs.SAM,
         Jobs.MCH, Jobs.BLM
     })
     # have to manually provide pps for testing for now
     self.assertEqual(20790.90666410063,
                      test_char.calc_damage(200, the_shitters_i_raid_with))
Esempio n. 14
0
 def test_embolden_has_no_effect(self):
     """ Test embolden isn't mistakenly applying damage """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     the_shitters_i_raid_with = Comp({
         Jobs.PLD, Jobs.WAR, Jobs.SCH, Jobs.WHM, Jobs.SAM, Jobs.SAM,
         Jobs.MCH, Jobs.RDM
     })
     # have to manually provide pps for testing for now
     self.assertEqual(20381.368540000003,
                      test_char.calc_damage(200, the_shitters_i_raid_with))
Esempio n. 15
0
 def test_single_raidbuff(self):
     """ Test raid buff is applying damage correctly """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     test_comp = Comp({
         Jobs.PLD, Jobs.WAR, Jobs.SCH, Jobs.AST, Jobs.SAM, Jobs.SAM,
         Jobs.MCH, Jobs.BLM
     })
     # have to manually provide pps for testing for now
     self.assertAlmostEqual(20534.2288,
                            test_char.calc_damage(200, test_comp),
                            places=3)
Esempio n. 16
0
 def test_variable_time_sim_notes_af_overspending(self):
     """ Ensure the time variable sim allows weaving after instant casts """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     mypps = SchPps()
     # Burn an aetherflow we don't have
     fixed_rotation = [SchAction.ENERGYDRAIN]
     sim_result = mypps.get_total_potency_variable_time(
         1, test_char, FixedSchRotation(fixed_rotation, SchAction.BROIL3),
         0.1)
     # 3 ED, 2 B3, 1 R2
     self.assertIn(SchSimNotice.SCH_SIM_AETHERFLOW_OVERSPENDING,
                   sim_result.notices)
Esempio n. 17
0
 def test_variable_time_sim_allows_weaves(self):
     """ Ensure the time variable sim allows weaving after instant casts """
     my_stat_spread = CharacterStatSpread(wd=180,
                                          mainstat=5577,
                                          det=2272,
                                          crit=3802,
                                          dh=1100,
                                          speed=2139,
                                          ten=380,
                                          pie=340)
     test_char = Character(Jobs.SCH, my_stat_spread)
     mypps = SchPps()
     # If the sim properly supports weaving, this should be 4 full gcds
     fixed_rotation = [
         SchAction.BIOLYSIS, SchAction.AETHERFLOW, SchAction.ENERGYDRAIN,
         SchAction.BROIL3, SchAction.RUIN2, SchAction.ENERGYDRAIN,
         SchAction.SWIFTCAST, SchAction.BROIL3, SchAction.ENERGYDRAIN
     ]
     sim_result = mypps.get_total_potency_variable_time(
         test_char.get_gcd() * 4, test_char,
         FixedSchRotation(fixed_rotation, SchAction.BROIL3), 0.1)
     # 3 ED, 2 B3, 1 R2
     self.assertEqual(1080, sim_result.get_non_dot_potency())
Esempio n. 18
0
def etro_main():
    """Calculates damage, given a gearsetID from Etro. Should check database to see if gearset exist first.
    JSON format:
    'job': String,
    'comp': Array,
    'etro_id': String,
    """

    data = request.get_json()

    # Check comp first before making request
    if not data:
        return "abort", abort(400)
    try:
        comp_jobs = [Jobs.create_job(comp_job)[0] for comp_job in data['comp']]
    except KeyError:
        return "An unsupported job was found in the team composition."

    my_comp = Comp(comp_jobs)

    player_job_data = Jobs.create_job(data['job'])

    # TODO: Check internal database to see if cached before request

    try:
        etro_data = requests.get("/".join(
            ["https://etro.gg/api/gearsets", data["etro_id"]])).json()
    except requests.exceptions.RequestException:
        return "There was an error making the etro request"

    etro_stats = etro_data["totalParams"]
    eq_stats = {stat["name"]: stat["value"] for stat in etro_stats}

    # For Etro sets that are non-tanks
    if "TEN" not in eq_stats:
        eq_stats["TEN"] = 0

    # Making speed job-agnostic
    if "SPS" in eq_stats:
        eq_stats["SPEED"] = eq_stats["SPS"]
    else:
        eq_stats["SPEED"] = eq_stats["SKS"]

    player = Character(
        player_job_data[0],
        CharacterStatSpread(wd=eq_stats["Weapon Damage"],
                            mainstat=eq_stats[player_job_data[1]],
                            det=eq_stats["DET"],
                            crit=eq_stats["CRT"],
                            dh=eq_stats["DH"],
                            speed=eq_stats["SPEED"],
                            ten=eq_stats["TEN"],
                            pie=eq_stats["PIE"]))

    my_sch_pps = SchPps()
    potency = my_sch_pps.get_pps(player)

    dps = round(player.calc_damage(potency, my_comp), 2)
    gcd = player.get_gcd()
    mp = round(my_sch_pps.get_mp_per_min(player), 2)
    return jsonify({"dps": dps, "gcd": gcd, "mp": mp})
Esempio n. 19
0
def update_stats():
    """Calculates damage, mp consumption, and gcd based on input.
    Accepts and returns JSON. JSON format is as follows:
    input: {'player': Object
                {'weaponDamage': int
                'mainStat': int
                'det': int
                'crit': int
                'dh': int
                'speed': int
                'ten': int
                'pie': int}
            'job': string
            'comp': Array
            'rotation': Object
                {'adloquium': int
                 'energyDrain': int
                 'raise': int
                 'succor': int}}
    output: {'dps': float,
             'gcd': float,
             'mp': float}
    """
    data = request.get_json()

    if not data:
        return "abort", abort(400)

    player_data = data['player']

    try:
        my_job = Jobs.create_job(data['job'])[0]
    except KeyError:
        return f"Currently {data['job']} is not supported."

    player = Character(
        my_job,
        CharacterStatSpread(wd=player_data['weaponDamage'],
                            mainstat=player_data['mainStat'],
                            det=player_data['det'],
                            crit=player_data['crit'],
                            dh=player_data['dh'],
                            speed=player_data['speed'],
                            ten=player_data['ten'],
                            pie=player_data['pie']))

    try:
        rotation_data = data['rotation']
        energy_drain_per_min = rotation_data.get('energyDrain', 4)
        adloquium_per_min = rotation_data.get('adloquium', 0)
        raise_per_min = rotation_data.get('raise', 0)
        succor_per_min = rotation_data.get('succor', 0)
    except KeyError:
        # Rotation data was not present in request, use defaults
        energy_drain_per_min, adloquium_per_min, raise_per_min, succor_per_min = 4, 0, 0, 0

    my_sch_pps = SchPps()
    potency = my_sch_pps.get_pps(player,
                                 num_ed_per_min=energy_drain_per_min,
                                 num_filler_casts=adloquium_per_min +
                                 raise_per_min + succor_per_min)
    try:
        comp_jobs = [Jobs.create_job(comp_job)[0] for comp_job in data['comp']]
    except KeyError:
        return "A job was not supported in that team comp."

    dps = round(player.calc_damage(potency, Comp(comp_jobs)), 2)
    gcd = player.get_gcd()
    mp = round(
        my_sch_pps.get_mp_per_min(player,
                                  succ=succor_per_min,
                                  adlo=adloquium_per_min,
                                  energy_drain=energy_drain_per_min,
                                  rez=raise_per_min), 2)
    return jsonify({"dps": dps, "gcd": gcd, "mp": mp})