fixed weird summary display, animated buttons, full powder special functionality

This commit is contained in:
ferricles 2021-01-13 19:17:01 -08:00
parent d4166b0617
commit 9462223eb6
7 changed files with 133 additions and 80 deletions

View file

@ -56,7 +56,7 @@ class Build{
* @param powders : Powder application. List of lists of integers (powder IDs).
* In order: Helmet, Chestplate, Leggings, Boots, Weapon.
*/
constructor(level,equipment, powders){
constructor(level,equipment, powders, externalStats){
// NOTE: powders is just an array of arrays of powder IDs. Not powder objects.
this.powders = powders;
if(itemMap.get(equipment[0]) && itemMap.get(equipment[0]).type === "helmet") {
@ -135,10 +135,13 @@ class Build{
this.total_skillpoints = result[2];
this.assigned_skillpoints = result[3];
this.activeSetCounts = result[4];
// For strength boosts like warscream, vanish, etc.
this.damageMultiplier = 1.0;
// For other external boosts ;-;
this.externalStats = externalStats;
this.initBuildStats();
}
@ -173,7 +176,7 @@ class Build{
}
// 0 for melee damage.
let results = calculateSpellDamage(stats, [100, 0, 0, 0, 0, 0], stats.get("mdRaw"), stats.get("mdPct"), 0, this.weapon, this.total_skillpoints, this.damageMultiplier);
let results = calculateSpellDamage(stats, [100, 0, 0, 0, 0, 0], stats.get("mdRaw"), stats.get("mdPct") + this.externalStats.get("mdPct"), 0, this.weapon, this.total_skillpoints, this.damageMultiplier, this.externalStats);
let dex = this.total_skillpoints[1];
@ -277,7 +280,13 @@ class Build{
statMap.set("damageBonus", [statMap.get("eDamPct"), statMap.get("tDamPct"), statMap.get("wDamPct"), statMap.get("fDamPct"), statMap.get("aDamPct")]);
statMap.set("defRaw", [statMap.get("eDam"), statMap.get("tDef"), statMap.get("wDef"), statMap.get("fDef"), statMap.get("aDef")]);
statMap.set("defBonus", [statMap.get("eDamPct"), statMap.get("tDefPct"), statMap.get("wDefPct"), statMap.get("fDefPct"), statMap.get("aDefPct")]);
for (const x of skp_elements) {
this.externalStats.set(x + "DamPct", 0);
}
this.externalStats.set("mdPct", 0);
this.externalStats.set("sdPct", 0);
this.externalStats.set("damageBonus", [0, 0, 0, 0, 0]);
this.externalStats.set("defBonus",[0, 0, 0, 0, 0]);
this.statMap = statMap;
}

View file

@ -11,7 +11,7 @@ console.log(url_tag);
* END testing section
*/
const BUILD_VERSION = "6.8.5";
const BUILD_VERSION = "6.9";
function setTitle() {
document.getElementById("header").textContent = "WynnBuilder version "+BUILD_VERSION+" (db version "+DB_VERSION+")";
@ -402,14 +402,13 @@ function calculateBuild(save_skp, skp){
let special = powderSpecialStats[specialNames.indexOf(sName)];
console.log(special);
if (special["weaponSpecialEffects"].has("Damage Boost")) {
if (name === "Courage") { //courage is universal damage boost
player_build.damageMultiplier -= special.weaponSpecialEffects.get("Damage Boost")[i-1]/100;
} else if (name === "Curse") {
player_build.statMap.set("wDamPct", player_build.statMap.get("wDamPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
player_build.statMap.get("damageBonus")[2] -= special.weaponSpecialEffects.get("Damage Boost")[i-1];
if (name === "Courage" || name === "Curse") { //courage is universal damage boost
//player_build.damageMultiplier -= special.weaponSpecialEffects.get("Damage Boost")[i-1]/100;
player_build.externalStats.set("sdPct", player_build.externalStats.get("sdPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
player_build.externalStats.set("mdPct", player_build.externalStats.get("mdPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
} else if (name === "Air Prison") {
player_build.statMap.set("aDamPct", player_build.statMap.get("aDamPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
player_build.statMap.get("damageBonus")[4] -= special.weaponSpecialEffects.get("Damage Boost")[i-1];
player_build.externalStats.set("aDamPct", player_build.externalStats.get("aDamPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
player_build.externalStats.get("damageBonus")[4] -= special.weaponSpecialEffects.get("Damage Boost")[i-1];
}
}
}
@ -458,9 +457,8 @@ function calculateBuild(save_skp, skp){
i.style.visibility = "visible";
}
console.log(equipment);
player_build = new Build(level, equipment, powderings);
console.log(player_build.toString());
player_build = new Build(level, equipment, powderings, new Map());
//console.log(player_build.toString());
displayEquipOrder(document.getElementById("build-order"),player_build.equip_order);
@ -508,6 +506,37 @@ function calculateBuild(save_skp, skp){
/* Updates all build statistics based on (for now) the skillpoint input fields and then calculates build stats.
*/
function updateStats() {
//direct copy of the ext buff un-check code from calculateBuild(). Redo if possible.
for (const boost of ["vanish", "warscream", "yourtotem", "allytotem"]) {
let elem = document.getElementById(boost+"-boost");
elem.classList.remove("toggleOn");
}
let specialNames = ["Quake", "Chain_Lightning", "Curse", "Courage", "Air_Prison"];
for (const sName of specialNames) {
for (let i = 1; i < 6; i++) {
let elem = document.getElementById(sName + "-" + i);
let name = sName.replace("_", " ");
if (elem.classList.contains("toggleOn")) { //toggle the pressed button off
elem.classList.remove("toggleOn");
let special = powderSpecialStats[specialNames.indexOf(sName)];
console.log(special);
if (special["weaponSpecialEffects"].has("Damage Boost")) {
if (name === "Courage" || name === "Curse") { //courage is universal damage boost
//player_build.damageMultiplier -= special.weaponSpecialEffects.get("Damage Boost")[i-1]/100;
player_build.externalStats.set("sdPct", player_build.externalStats.get("sdPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
player_build.externalStats.set("mdPct", player_build.externalStats.get("mdPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
} else if (name === "Air Prison") {
player_build.externalStats.set("aDamPct", player_build.externalStats.get("aDamPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
player_build.externalStats.get("damageBonus")[4] -= special.weaponSpecialEffects.get("Damage Boost")[i-1];
}
}
}
}
}
if(player_build){
updatePowderSpecials("skip");
}
//WILL BREAK WEBSITE IF NO BUILD HAS BEEN INITIALIZED! @HPP
let skillpoints = player_build.total_skillpoints;
let delta_total = 0;
@ -539,7 +568,7 @@ function updateBoosts(buttonId) {
/* Updates all powder special boosts
*/
function updatePowderSpecials(buttonId){
console.log(player_build.statMap);
//console.log(player_build.statMap);
let name = (buttonId).split("-")[0];
let power = (buttonId).split("-")[1]; // [1, 5]
let specialNames = ["Quake", "Chain Lightning", "Curse", "Courage", "Air Prison"];
@ -553,14 +582,13 @@ function updatePowderSpecials(buttonId){
let special = powderSpecialStats[specialNames.indexOf(name.replace("_", " "))];
if (special.weaponSpecialEffects.has("Damage Boost")) {
name = name.replace("_", " ");
if (name === "Courage") { //courage is universal damage boost
player_build.damageMultiplier -= special.weaponSpecialEffects.get("Damage Boost")[power-1]/100;
} else if (name === "Curse") {
player_build.statMap.set("wDamPct", player_build.statMap.get("wDamPct") - special.weaponSpecialEffects.get("Damage Boost")[power-1]);
player_build.statMap.get("damageBonus")[2] -= special.weaponSpecialEffects.get("Damage Boost")[power-1];
if (name === "Courage" || name === "Curse") { //courage and curse are universal damage boost
player_build.externalStats.set("sdPct", player_build.externalStats.get("sdPct") - special.weaponSpecialEffects.get("Damage Boost")[power-1]);
player_build.externalStats.set("mdPct", player_build.externalStats.get("mdPct") - special.weaponSpecialEffects.get("Damage Boost")[power-1]);
//poison?
} else if (name === "Air Prison") {
player_build.statMap.set("aDamPct", player_build.statMap.get("aDamPct") - special.weaponSpecialEffects.get("Damage Boost")[power-1]);
player_build.statMap.get("damageBonus")[4] -= special.weaponSpecialEffects.get("Damage Boost")[power-1];
player_build.externalStats.set("aDamPct", player_build.externalStats.get("aDamPct") - special.weaponSpecialEffects.get("Damage Boost")[power-1]);
player_build.externalStats.get("damageBonus")[4] -= special.weaponSpecialEffects.get("Damage Boost")[power-1];
}
}
} else {
@ -571,14 +599,13 @@ function updatePowderSpecials(buttonId){
let special = powderSpecialStats[specialNames.indexOf(name.replace("_", " "))];
if (special.weaponSpecialEffects.has("Damage Boost")) {
name = name.replace("_", " "); //might be redundant
if (name === "Courage") { //courage is universal damage boost
player_build.damageMultiplier -= special.weaponSpecialEffects.get("Damage Boost")[i-1]/100;
} else if (name === "Curse") {
player_build.statMap.set("wDamPct", player_build.statMap.get("wDamPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
player_build.statMap.get("damageBonus")[2] -= special.weaponSpecialEffects.get("Damage Boost")[i-1];
if (name === "Courage" || name === "Curse") { //courage is universal damage boost
//player_build.damageMultiplier -= special.weaponSpecialEffects.get("Damage Boost")[i-1]/100;
player_build.externalStats.set("sdPct", player_build.externalStats.get("sdPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
player_build.externalStats.set("mdPct", player_build.externalStats.get("mdPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
} else if (name === "Air Prison") {
player_build.statMap.set("aDamPct", player_build.statMap.get("aDamPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
player_build.statMap.get("damageBonus")[4] -= special.weaponSpecialEffects.get("Damage Boost")[i-1];
player_build.externalStats.set("aDamPct", player_build.externalStats.get("aDamPct") - special.weaponSpecialEffects.get("Damage Boost")[i-1]);
player_build.externalStats.get("damageBonus")[4] -= special.weaponSpecialEffects.get("Damage Boost")[i-1];
}
}
}
@ -597,8 +624,7 @@ function updatePowderSpecials(buttonId){
}
}
}
//displayPowderSpecials() runs on build stats. It therefore must run before any duration damage boost is applied.
displayPowderSpecials(document.getElementById("powder-special-stats"), powderSpecials, player_build);
if (name !== "skip") {
let elem = document.getElementById(buttonId);
@ -606,19 +632,18 @@ function updatePowderSpecials(buttonId){
let special = powderSpecialStats[specialNames.indexOf(name.replace("_", " "))];
if (special["weaponSpecialEffects"].has("Damage Boost")) {
let name = special["weaponSpecialName"];
if (name === "Courage") { //courage is universal damage boost
player_build.damageMultiplier += special.weaponSpecialEffects.get("Damage Boost")[power-1]/100;
} else if (name === "Curse") {
player_build.statMap.set("wDamPct", player_build.statMap.get("wDamPct") + special.weaponSpecialEffects.get("Damage Boost")[power-1]);
player_build.statMap.get("damageBonus")[2] += special.weaponSpecialEffects.get("Damage Boost")[power-1];
if (name === "Courage" || name === "Curse") { //courage and curse are is universal damage boost
player_build.externalStats.set("sdPct", player_build.externalStats.get("sdPct") + special.weaponSpecialEffects.get("Damage Boost")[power-1]);
player_build.externalStats.set("mdPct", player_build.externalStats.get("mdPct") + special.weaponSpecialEffects.get("Damage Boost")[power-1]);
} else if (name === "Air Prison") {
player_build.statMap.set("aDamPct", player_build.statMap.get("aDamPct") + special.weaponSpecialEffects.get("Damage Boost")[power-1]);
player_build.statMap.get("damageBonus")[4] += special.weaponSpecialEffects.get("Damage Boost")[power-1];
player_build.externalStats.set("aDamPct", player_build.externalStats.get("aDamPct") + special.weaponSpecialEffects.get("Damage Boost")[power-1]);
player_build.externalStats.get("damageBonus")[4] += special.weaponSpecialEffects.get("Damage Boost")[power-1];
}
}
}
}
displayPowderSpecials(document.getElementById("powder-special-stats"), powderSpecials, player_build);
calculateBuildStats(); //also make damage boosts apply ;-;
}
/* Calculates all build statistics and updates the entire display.
@ -644,38 +669,33 @@ function calculateBuildStats() {
let summarybox = document.getElementById("summary-box");
summarybox.textContent = "";
let skpRow = document.createElement("tr");
let skpSummary = document.createElement("td");
skpSummary.textContent = "Summary: Assigned " + player_build.assigned_skillpoints + " skillpoints. Total: (";
skpSummary.classList.add("itemp");
skpRow.appendChild(skpSummary);
let skpRow = document.createElement("p");
//skpRow.classList.add("left");
let td = document.createElement("p");
//td.classList.add("left");
let skpSummary = document.createElement("b");
skpSummary.textContent = "Assigned " + player_build.assigned_skillpoints + " skillpoints. Total: (";
//skpSummary.classList.add("itemp");
td.appendChild(skpSummary);
for (let i = 0; i < skp_order.length; i++){
let skp = document.createElement("td");
let boost = document.createElement("td");
let separator = document.createElement("td");
skp.classList.add("itemp");
skp.classList.add("nopadding");
let skp = document.createElement("b");
let boost = document.createElement("b");
skp.classList.add(damageClasses[i+1]);
boost.classList.add("itemp");
boost.classList.add("nopadding");
boost.textContent = player_build.total_skillpoints[i];
skpRow.appendChild(skp);
skpRow.appendChild(document.createElement("br"));
skpRow.appendChild(boost);
if(i < 4){
skpRow.appendChild(separator);
if (i < 4) {
boost.classList.add("space");
}
td.appendChild(skp);
td.appendChild(boost);
}
let skpEnd = document.createElement("td");
let skpEnd = document.createElement("b");
skpEnd.textContent = ")";
skpEnd.classList.add("itemp");
skpRow.append(skpEnd);
td.appendChild(skpEnd);
skpRow.append(td);
let remainingRow = document.createElement("tr");
remainingRow.classList.add("itemp");
let remainingSkp = document.createElement("td");
remainingSkp.classList.add("left");
let remainingSkp = document.createElement("p");
remainingSkp.classList.add("center");
let remainingSkpTitle = document.createElement("b");
remainingSkpTitle.textContent = "Remaining skillpoints: ";
let remainingSkpContent = document.createElement("b");
@ -685,10 +705,9 @@ function calculateBuildStats() {
remainingSkp.appendChild(remainingSkpTitle);
remainingSkp.appendChild(remainingSkpContent);
remainingRow.appendChild(remainingSkp);
summarybox.append(skpRow);
summarybox.append(remainingRow);
summarybox.append(remainingSkp);
if(player_build.assigned_skillpoints > levelToSkillPoints(player_build.level)){
let skpWarning = document.createElement("p");
//skpWarning.classList.add("itemp");
@ -784,6 +803,7 @@ function resetFields(){
setValue("agi-skp", "0");
setValue("level-choice", "");
location.hash = "";
calculateBuild();
}
load_init(init);

View file

@ -1,10 +1,27 @@
const damageMultipliers = new Map([ ["allytotem", .15], ["yourtotem", .35], ["vanish", 0.80], ["warscream", 0.10] ]);
// Calculate spell damage given a spell elemental conversion table, and a spell multiplier.
// If spell mult is 0, its melee damage and we don't multiply by attack speed.
function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier, spellMultiplier, weapon, total_skillpoints, damageMultiplier) {
// externalStats should be a map
function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier, spellMultiplier, weapon, total_skillpoints, damageMultiplier, externalStats) {
let buildStats = new Map(stats);
if(externalStats) { //if nothing is passed in, then this hopefully won't trigger
for (const [key,value] of externalStats) {
if (typeof value === "number") {
buildStats.set(key, buildStats.get(key) + value);
} else if (Array.isArray(value)) {
arr = [];
for (let i = 0; i < value.length; i++) {
arr[i] = buildStats.get(key)[i] + value[i];
}
buildStats.set(key, arr);
}
}
}
// Array of neutral + ewtfa damages. Each entry is a pair (min, max).
let damages = [];
for (const damage_string of stats.get("damageRaw")) {
for (const damage_string of buildStats.get("damageRaw")) {
const damage_vals = damage_string.split("-").map(Number);
damages.push(damage_vals);
}
@ -48,7 +65,7 @@ function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier,
melee = true;
}
else {
damageMult *= spellMultiplier * baseDamageMultiplier[attackSpeeds.indexOf(stats.get("atkSpd"))];
damageMult *= spellMultiplier * baseDamageMultiplier[attackSpeeds.indexOf(buildStats.get("atkSpd"))];
}
//console.log(damages);
//console.log(damageMult);
@ -66,7 +83,7 @@ function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier,
let staticBoost = (pctModifier / 100.) + skillPointsToPercentage(str);
let skillBoost = [0];
for (let i in total_skillpoints) {
skillBoost.push(skillPointsToPercentage(total_skillpoints[i]) + stats.get("damageBonus")[i] / 100.);
skillBoost.push(skillPointsToPercentage(total_skillpoints[i]) + buildStats.get("damageBonus")[i] / 100.);
}
for (let i in damages) {
@ -198,6 +215,6 @@ const spell_table = {
]},
{ title: "Courage", cost: 0, parts: [
{ subtitle: "Total Damage", type: "damage", multiplier: [75, 87.5, 100, 112.5, 125], conversion: [0,0,0,0,100,0], summary: true},
]},
]}, //[75, 87.5, 100, 112.5, 125]
]
};

View file

@ -279,7 +279,7 @@ function displayExpandedItem(item, parent_id){
stats.set("atkSpd", item.get("atkSpd"));
stats.set("damageBonus", [0, 0, 0, 0, 0]);
stats.set("damageRaw", [item.get("nDam"), item.get("eDam"), item.get("tDam"), item.get("wDam"), item.get("fDam"), item.get("aDam")]);
let results = calculateSpellDamage(stats, [100, 0, 0, 0, 0, 0], 0, 0, 0, item, [0, 0, 0, 0, 0], 1);
let results = calculateSpellDamage(stats, [100, 0, 0, 0, 0, 0], 0, 0, 0, item, [0, 0, 0, 0, 0], 1, undefined);
let damages = results[2];
let damage_keys = [ "nDam_", "eDam_", "tDam_", "wDam_", "fDam_", "aDam_" ];
for (const i in damage_keys) {
@ -954,6 +954,7 @@ function displayPowderSpecials(parent_elem, powderSpecials, build) {
parent_elem.textContent = "Powder Specials";
let specials = powderSpecials.slice();
let stats = build.statMap;
let expandedStats = new Map();
//each entry of powderSpecials is [ps, power]
for (special of specials) {
//iterate through the special and display its effects.
@ -978,6 +979,9 @@ function displayPowderSpecials(parent_elem, powderSpecials, build) {
if(key === "Damage"){
effect.textContent += elementIcons[powderSpecialStats.indexOf(special[0])];
}
if(special[0]["weaponSpecialName"] === "Air Prison" && key === "Damage Boost") {
effect.textContent += " (only 1st hit)";
}
specialEffects.appendChild(effect);
}
@ -987,12 +991,12 @@ function displayPowderSpecials(parent_elem, powderSpecials, build) {
//if this special is an instant-damage special (Quake, Chain Lightning, Courage Burst), display the damage.
let specialDamage = document.createElement("p");
let spells = spell_table["powder"];
if (powderSpecialStats.indexOf(special[0]) == 0 || powderSpecialStats.indexOf(special[0]) == 1 || powderSpecialStats.indexOf(special[0]) == 3) { //Quake
if (powderSpecialStats.indexOf(special[0]) == 0 || powderSpecialStats.indexOf(special[0]) == 1 || powderSpecialStats.indexOf(special[0]) == 3) { //Quake, Chain Lightning, or Courage
let spell = (powderSpecialStats.indexOf(special[0]) == 3 ? spells[2] : spells[powderSpecialStats.indexOf(special[0])]);
let part = spell["parts"][0];
let _results = calculateSpellDamage(stats, part.conversion,
stats.get("mdRaw"), stats.get("mdPct"),
0, build.weapon, build.total_skillpoints, build.damageMultiplier * part.multiplier[power-1] / 100);//part.multiplier[power] / 100
stats.get("mdRaw"), stats.get("mdPct") + build.externalStats.get("mdPct"),
0, build.weapon, build.total_skillpoints, build.damageMultiplier * ((part.multiplier[power-1] / 100)), build.externalStats);//part.multiplier[power] / 100
let critChance = skillPointsToPercentage(build.total_skillpoints[1]);
let save_damages = [];
@ -1116,10 +1120,10 @@ function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spell
part_divavg.append(subtitle_elemavg);
}
if (part.type === "damage") {
//console.log(build.expandedStats);
let _results = calculateSpellDamage(stats, part.conversion,
stats.get("sdRaw"), stats.get("sdPct"),
part.multiplier / 100, build.weapon, build.total_skillpoints, build.damageMultiplier);
stats.get("sdRaw"), stats.get("sdPct") + build.externalStats.get("sdPct"),
part.multiplier / 100, build.weapon, build.total_skillpoints, build.damageMultiplier, build.externalStats);
let totalDamNormal = _results[0];
let totalDamCrit = _results[1];
let results = _results[2];

View file

@ -172,8 +172,8 @@
</div>
<div class="center" style="grid-column:1/span 3;grid-row:3">
<br><br>
<div class="center" id="summary-box">
Summary:
<div class="nomargin" id="summary-box">
</div>
<br><br>
<div class="externalBuffs" id="buff-box">

View file

@ -5,7 +5,7 @@ function calculate_skillpoints(equipment, weapon) {
let fixed = [];
let consider = [];
let noboost = [];
console.log(equipment);
//console.log(equipment);
for (const item of equipment) {
if (item.get("reqs").every(x => x === 0)) {
fixed.push(item);

View file

@ -110,6 +110,9 @@ a.link{
margin: 2px 2%;
padding: 0;
}
.space {
margin-right: 5px;
}
.damageSubtitle {
text-align: center;