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))
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})
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))
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))
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))
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))
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))
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)
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})
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})