paritybit.ca

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit f8cd82565346746009543208fc4001709419572c
parent c6107ec1031dddddc0c7f19dd521a6b2a2f4622a
Author: Jake Bauer <jbauer@paritybit.ca>
Date:   Tue, 31 Dec 2019 21:04:39 -0500

Fix remaining known bugs in BL3 calculator code

Diffstat:
Mpublic/js/borderlands-3-dps-calculator.js | 173++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
1 file changed, 106 insertions(+), 67 deletions(-)

diff --git a/public/js/borderlands-3-dps-calculator.js b/public/js/borderlands-3-dps-calculator.js @@ -1,3 +1,4 @@ +"use strict"; /* * borderlands-3-dps-calculator.js * Contains backend code for generation of game parameters @@ -19,22 +20,13 @@ */ /* - * Preconditions: - * dmg (base gun damage) and mag (magazine size) are positive ints > 0 - * acc (gun accuracy) is a float within (0,1] - * rload (reload time in seconds) and frate (shots fired per second) are positive floats - * element (elemental effect type) is a string - * edmg (elemental effect damage) is a nonnegative int >= 0 - * echance (elemental effect chance) is a float within [0,1] - * TVHM (True Vault Hunter Mode) is a boolean + * mults_g: + * A dictionary of elemental damage multipliers based on healthbar type. + * Entries are organized in order of "health, shields, armor", + * with first-row entries corresponding to Normal Mode, + * and second-row entries corresponding to True Vault Hunter Mode. * - * postconditions: - * multipliers is an array of three floats - * multipliers[0] is average DPS against flesh (red health bar) - * multipliers[1] is average DPS against shields (blue health bar) - * multipliers[2] is average DPS against armor (yellow health bar) - * - * multiplier values assigned in switch statement sourced from + * all multiplier values sourced from * https://borderlands.fandom.com/wiki/Elemental_damage#Borderlands_3 * in particular, the following table: * Flesh Shield Armor @@ -46,69 +38,116 @@ Corrosive 80% 65% 70% 50% 150% 175% Cryo 100% 100% 70% 50% 120% 150% Radiation 100% 100% 100% 150% 70% 50% */ -function dps(dmg, acc, rload, frate, mag, element, edmg, echance, TVHM = false) { - //multipliers represent health, shields, and armor, in that order - let dps, - multipliers, - eduration, - adj_dmg, - adj_acc, - adj_frate; +const mults_g = { + None: [ + [1.0, 1.0, 0.8], + [1.0, 1.0, 0.8] + ], + Fire: [ + [1.5, 0.7, 0.7], + [1.75, 0.5, 0.5] + ], + Shock: [ + [0.8, 2.0, 0.8], + [0.65, 2.5, 0.65] + ], + Acid: [ + [0.8, 0.7, 1.5], + [0.65, 0.5, 1.75] + ], + Cryo: [ + [1.0, 0.7, 1.2], + [1.0, 0.5, 1.5] + ], + Rad: [ + [1.0, 1.0, 0.7], + [1.0, 1.5, 0.5] + ] +}; - switch(element) { - case 'fire': - multipliers = TVHM ? [1.75, 0.5, 0.5] : [1.5, 0.7, 0.7]; - eduration = 5.0; - break; - case 'shock': - multipliers = TVHM ? [0.65, 2.5, 0.65] : [0.8, 2.0, 0.8]; - eduration = 2.0; +/** + * gun properties (except "elmnt" and "tvhm") + */ +const properties_g = [ + "dmg","dmg-mult","acc","rload","frate","mag","ammo","e-dmg","e-chance" +]; + +/* + * function dps(): + * Preconditions: + * dmg (base gun damage) and mag (magazine size) are positive ints > 0 + * acc (gun accuracy) is a float within [0,100] + * rload (reload time in seconds) and frate (shots fired per second) are positive floats + * element (elemental effect type) is a string + * edmg (elemental effect damage) is a nonnegative int >= 0 + * echance (elemental effect chance) is a float within [0,1] + * TVHM (True Vault Hunter Mode) is a boolean + * + * Postconditions: + * dps is an array of three floats + * dps[0] is average DPS against flesh (red health bar) + * dps[1] is average DPS against shields (blue health bar) + * dps[2] is average DPS against armor (yellow health bar) +*/ +function calculateDPS(gun, effectDuration) { + let dps = []; + + gun.dmg *= gun["dmg-mult"]; + gun.mag /= gun["ammo"]; + gun.dmg += gun["e-dmg"] * gun["e-chance"] * effectDuration; + gun.acc = ((gun.acc/100) * 0.2) + 0.8; + gun.frate = gun.mag / (((gun.mag - 1) / gun.frate) + gun.rload); + + for (let i = 0; i < 3; i++) { + dps[i] = mults_g[gun.elmnt][gun.tvhm][i]; + dps[i] *= gun.dmg * gun.acc * gun.frate; + } + + return dps; +} + +//elemental duration values: 5 secs for fire/acid, 8 for radiation, 2 for shock +function computeEffectDuration(gun) { + let effectDuration = 0; + switch(gun.elmnt) { + case "Fire": + effectDuration = 5; break; - case 'acid': - multipliers = TVHM ? [0.65, 0.5, 1.75] : [0.8, 0.7, 1.5]; - eduration = 5.0; + case "Acid": + effectDuration = 5; break; - case 'cryo': - multipliers = TVHM ? [1.0, 0.5, 1.5] : [1.0, 0.7, 1.2]; - eduration = 0; + case "Rad": + effectDuration = 8; break; - case 'rad': - multipliers = TVHM ? [1.0, 1.5, 0.5] : [1.0, 1.0, 0.7]; - eduration = 8.0; - edmg *= 1.25; + case "Shock": + effectDuration = 2; break; - default: //kinetic, i.e. non-elemental - multipliers = [1.0, 1.0, 0.8]; - eduration = 0; + default: break; } - adj_dmg = dmg + (edmg * echance * eduration); + return effectDuration; +} - adj_acc = (acc * 0.2) + 0.8; +function gamerMoment() { - adj_frate = ((frate * (mag - 1)) + (1/rload)) / mag; + let gun = {}; + let e; + let dpsResult; + let effectDuration; - dps = adj_dmg * adj_acc * adj_frate; - for (m of multipliers) { - m *= dps; + for (let str of properties_g) { + gun[str] = parseFloat(document.getElementById(str).value); } - return multipliers; -} -function gamerMoment() { - let dmg = document.getElementById("dmg").value, - acc = document.getElementById("acc").value, - frate = document.getElementById("rload").value, - rload = document.getElementById("frate").value, - mag = document.getElementById("mag").value, - elmnt = document.getElementById("elmnt").value, - edmg = document.getElementById("e-dmg").value, - echance = document.getElementById("e-chance").value, - tvhm = document.getElementById("tvhm").value; + e = document.getElementById("elmnt"); + gun["elmnt"] = e.options[e.selectedIndex].value; + gun["tvhm"] = document.getElementById("tvhm").checked ? 1 : 0; - let result = dps(dmg,acc,frate,rload,mag,elmnt,edmg,echance,tvhm); + effectDuration = computeEffectDuration(gun); - document.getElementById("flesh").innerHTML = result[0]; - document.getElementById("shields").innerHTML = result[1]; - document.getElementById("armour").innerHTML = result[2]; - } + dpsResult = calculateDPS(gun, effectDuration); + + document.getElementById("flesh").innerHTML = dpsResult[0].toFixed(2); + document.getElementById("shields").innerHTML = dpsResult[1].toFixed(2); + document.getElementById("armour").innerHTML = dpsResult[2].toFixed(2); +}