Internal spell representation overhaul
Using new (more expressive) schema Somehow made display code cleaner !!!
This commit is contained in:
parent
581891116d
commit
c7fd1c53f8
4 changed files with 218 additions and 115 deletions
|
@ -468,6 +468,7 @@ class PowderInputNode extends InputNode {
|
||||||
* Signature: SpellSelectNode<int>(build: Build) => [Spell, SpellParts]
|
* Signature: SpellSelectNode<int>(build: Build) => [Spell, SpellParts]
|
||||||
*/
|
*/
|
||||||
class SpellSelectNode extends ComputeNode {
|
class SpellSelectNode extends ComputeNode {
|
||||||
|
// TODO: rewrite me entirely...
|
||||||
constructor(spell_num) {
|
constructor(spell_num) {
|
||||||
super("builder-spell"+spell_num+"-select");
|
super("builder-spell"+spell_num+"-select");
|
||||||
this.spell_idx = spell_num;
|
this.spell_idx = spell_num;
|
||||||
|
@ -475,10 +476,18 @@ class SpellSelectNode extends ComputeNode {
|
||||||
|
|
||||||
compute_func(input_map) {
|
compute_func(input_map) {
|
||||||
const build = input_map.get('build');
|
const build = input_map.get('build');
|
||||||
|
let stats = build.statMap;
|
||||||
|
|
||||||
const i = this.spell_idx;
|
const i = this.spell_idx;
|
||||||
let spell = spell_table[build.weapon.statMap.get("type")][i];
|
const spells = default_spells[build.weapon.statMap.get("type")];
|
||||||
let stats = build.statMap;
|
let spell;
|
||||||
|
for (const _spell of spells) {
|
||||||
|
if (_spell.base_spell === i) {
|
||||||
|
spell = _spell;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (spell === undefined) { return null; }
|
||||||
|
|
||||||
let spell_parts;
|
let spell_parts;
|
||||||
if (spell.parts) {
|
if (spell.parts) {
|
||||||
|
@ -551,6 +560,7 @@ class SpellDamageCalcNode extends ComputeNode {
|
||||||
compute_func(input_map) {
|
compute_func(input_map) {
|
||||||
const weapon = input_map.get('build').weapon.statMap;
|
const weapon = input_map.get('build').weapon.statMap;
|
||||||
const spell_info = input_map.get('spell-info');
|
const spell_info = input_map.get('spell-info');
|
||||||
|
const spell = spell_info[0];
|
||||||
const spell_parts = spell_info[1];
|
const spell_parts = spell_info[1];
|
||||||
const stats = input_map.get('stats');
|
const stats = input_map.get('stats');
|
||||||
const damage_mult = stats.get('damageMultiplier');
|
const damage_mult = stats.get('damageMultiplier');
|
||||||
|
@ -562,23 +572,66 @@ class SpellDamageCalcNode extends ComputeNode {
|
||||||
stats.get('agi')
|
stats.get('agi')
|
||||||
];
|
];
|
||||||
let spell_results = []
|
let spell_results = []
|
||||||
|
let spell_result_map = new Map();
|
||||||
|
const use_speed = (('use_atkspd' in spell) ? spell.use_atkspd : true);
|
||||||
|
const use_spell = (('scaling' in spell) ? spell.scaling === 'spell' : true);
|
||||||
|
|
||||||
|
// TODO: move preprocessing to separate node/node chain
|
||||||
for (const part of spell_parts) {
|
for (const part of spell_parts) {
|
||||||
if (part.type === "damage") {
|
let spell_result;
|
||||||
let tmp_conv = [];
|
if ('multipliers' in part) { // damage type spell
|
||||||
for (let i in part.conversion) {
|
let results = calculateSpellDamage(stats, weapon, part.multipliers, use_spell, !use_speed);
|
||||||
tmp_conv.push(part.conversion[i] * part.multiplier/100);
|
spell_result = {
|
||||||
|
type: "damage",
|
||||||
|
normal_min: results[2].map(x => x[0]),
|
||||||
|
normal_max: results[2].map(x => x[1]),
|
||||||
|
normal_total: results[0],
|
||||||
|
crit_min: results[2].map(x => x[2]),
|
||||||
|
crit_max: results[2].map(x => x[3]),
|
||||||
|
crit_total: results[1],
|
||||||
}
|
}
|
||||||
let results = calculateSpellDamage(stats, weapon, tmp_conv, true);
|
} else if ('power' in part) {
|
||||||
spell_results.push(results);
|
|
||||||
} else if (part.type === "heal") {
|
|
||||||
// TODO: wynn2 formula
|
// TODO: wynn2 formula
|
||||||
let heal_amount = (part.strength * getDefenseStats(stats)[0] * Math.max(0.5,Math.min(1.75, 1 + 0.5 * stats.get("wDamPct")/100))).toFixed(2);
|
let _heal_amount = (part.strength * getDefenseStats(stats)[0] * Math.max(0.5,Math.min(1.75, 1 + 0.5 * stats.get("wDamPct")/100))).toFixed(2);
|
||||||
spell_results.push(heal_amount);
|
spell_result = {
|
||||||
} else if (part.type === "total") {
|
type: "heal",
|
||||||
// TODO: remove "total" type
|
heal_amount: _heal_amount
|
||||||
spell_results.push(null);
|
}
|
||||||
|
} else if ('hits' in part) {
|
||||||
|
spell_result = {
|
||||||
|
normal_min: [0, 0, 0, 0, 0, 0],
|
||||||
|
normal_max: [0, 0, 0, 0, 0, 0],
|
||||||
|
normal_total: [0, 0],
|
||||||
|
crit_min: [0, 0, 0, 0, 0, 0],
|
||||||
|
crit_max: [0, 0, 0, 0, 0, 0],
|
||||||
|
crit_total: [0, 0]
|
||||||
|
}
|
||||||
|
const dam_res_keys = ['normal_min', 'normal_max', 'normal_total', 'crit_min', 'crit_max', 'crit_total'];
|
||||||
|
for (const [subpart_name, hits] of Object.entries(part.hits)) {
|
||||||
|
const subpart = spell_result_map.get(subpart_name);
|
||||||
|
if (spell_result.type) {
|
||||||
|
if (subpart.type !== spell_result.type) {
|
||||||
|
throw "SpellCalc total subpart type mismatch";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
spell_result.type = subpart.type;
|
||||||
|
}
|
||||||
|
if (spell_result.type === 'damage') {
|
||||||
|
for (const key of dam_res_keys) {
|
||||||
|
for (let i in spell_result.normal_min) {
|
||||||
|
spell_result[key][i] += subpart[key][i] * hits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
spell_result.heal_amount += subpart.heal_amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
spell_result.name = part.name;
|
||||||
|
spell_results.push(spell_result);
|
||||||
|
spell_result_map.set(part.name, spell_result);
|
||||||
}
|
}
|
||||||
return spell_results;
|
return spell_results;
|
||||||
}
|
}
|
||||||
|
@ -604,12 +657,11 @@ class SpellDisplayNode extends ComputeNode {
|
||||||
const spell_info = input_map.get('spell-info');
|
const spell_info = input_map.get('spell-info');
|
||||||
const damages = input_map.get('spell-damage');
|
const damages = input_map.get('spell-damage');
|
||||||
const spell = spell_info[0];
|
const spell = spell_info[0];
|
||||||
const spell_parts = spell_info[1];
|
|
||||||
|
|
||||||
const i = this.spell_idx;
|
const i = this.spell_idx;
|
||||||
let parent_elem = document.getElementById("spell"+i+"-info");
|
let parent_elem = document.getElementById("spell"+i+"-info");
|
||||||
let overallparent_elem = document.getElementById("spell"+i+"-infoAvg");
|
let overallparent_elem = document.getElementById("spell"+i+"-infoAvg");
|
||||||
displaySpellDamage(parent_elem, overallparent_elem, stats, spell, i+1, spell_parts, damages);
|
displaySpellDamage(parent_elem, overallparent_elem, stats, spell, i+1, damages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1059,7 +1111,8 @@ function builder_graph_init() {
|
||||||
|
|
||||||
// Also do something similar for skill points
|
// Also do something similar for skill points
|
||||||
|
|
||||||
for (let i = 0; i < 4; ++i) {
|
//for (let i = 0; i < 4; ++i) {
|
||||||
|
for (let i = 0; i < 1; ++i) {
|
||||||
let spell_node = new SpellSelectNode(i);
|
let spell_node = new SpellSelectNode(i);
|
||||||
spell_node.link_to(build_node, 'build');
|
spell_node.link_to(build_node, 'build');
|
||||||
// TODO: link and rewrite spell_node to the stat agg node
|
// TODO: link and rewrite spell_node to the stat agg node
|
||||||
|
|
|
@ -89,6 +89,9 @@ class ComputeNode {
|
||||||
throw "no compute func specified";
|
throw "no compute func specified";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add link to a parent compute node, optionally with an alias.
|
||||||
|
*/
|
||||||
link_to(parent_node, link_name) {
|
link_to(parent_node, link_name) {
|
||||||
this.inputs.push(parent_node)
|
this.inputs.push(parent_node)
|
||||||
link_name = (link_name !== undefined) ? link_name : parent_node.name;
|
link_name = (link_name !== undefined) ? link_name : parent_node.name;
|
||||||
|
@ -100,6 +103,26 @@ class ComputeNode {
|
||||||
parent_node.children.push(this);
|
parent_node.children.push(this);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a link to a parent node.
|
||||||
|
* TODO: time complexity of list deletion (not super relevant but it hurts my soul)
|
||||||
|
*/
|
||||||
|
remove_link(parent_node) {
|
||||||
|
const idx = this.inputs.indexOf(parent_node); // Get idx
|
||||||
|
this.inputs.splice(idx, 1); // remove element
|
||||||
|
|
||||||
|
this.input_translations.delete(parent_node.name);
|
||||||
|
const was_dirty = this.inputs_dirty.get(parent_node.name);
|
||||||
|
this.inputs_dirty.delete(parent_node.name);
|
||||||
|
if (was_dirty) {
|
||||||
|
this.inputs_dirty_count -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const idx2 = parent_node.children.indexOf(this);
|
||||||
|
parent_node.children.splice(idx2, 1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -56,11 +56,14 @@ function calculateSpellDamage(stats, weapon, conversions, use_spell_damage, igno
|
||||||
|
|
||||||
// 2.2. Next, apply elemental conversions using damage computed in step 1.1.
|
// 2.2. Next, apply elemental conversions using damage computed in step 1.1.
|
||||||
// Also, track which elements are present. (Add onto those present in the weapon itself.)
|
// Also, track which elements are present. (Add onto those present in the weapon itself.)
|
||||||
|
let total_convert = 0; //TODO get confirmation that this is how raw works.
|
||||||
for (let i = 1; i <= 5; ++i) {
|
for (let i = 1; i <= 5; ++i) {
|
||||||
if (conversions[i] > 0) {
|
if (conversions[i] > 0) {
|
||||||
damages[i][0] += conversions[i]/100 * weapon_min;
|
const conv_frac = conversions[i]/100;
|
||||||
damages[i][1] += conversions[i]/100 * weapon_max;
|
damages[i][0] += conv_frac * weapon_min;
|
||||||
|
damages[i][1] += conf_frac * weapon_max;
|
||||||
present[i] = true;
|
present[i] = true;
|
||||||
|
total_convert += conv_frac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,22 +128,22 @@ function calculateSpellDamage(stats, weapon, conversions, use_spell_damage, igno
|
||||||
raw_boost += stats.get(damage_prefix+'Raw') + stats.get(damage_elements[i]+'DamRaw');
|
raw_boost += stats.get(damage_prefix+'Raw') + stats.get(damage_elements[i]+'DamRaw');
|
||||||
}
|
}
|
||||||
// Next, rainraw and propRaw
|
// Next, rainraw and propRaw
|
||||||
let new_min = damages_obj[0] + raw_boost;
|
let min_boost = raw_boost;
|
||||||
let new_max = damages_obj[1] + raw_boost;
|
let max_boost = raw_boost;
|
||||||
if (total_max > 0) { // TODO: what about total negative all raw?
|
if (total_max > 0) { // TODO: what about total negative all raw?
|
||||||
if (total_elem_min > 0) {
|
if (total_elem_min > 0) {
|
||||||
new_min += (damages_obj[0] / total_min) * prop_raw;
|
min_boost += (damages_obj[0] / total_min) * prop_raw;
|
||||||
}
|
}
|
||||||
new_max += (damages_obj[1] / total_max) * prop_raw;
|
max_boost += (damages_obj[1] / total_max) * prop_raw;
|
||||||
}
|
}
|
||||||
if (i != 0 && total_elem_max > 0) { // rainraw TODO above
|
if (i != 0 && total_elem_max > 0) { // rainraw TODO above
|
||||||
if (total_elem_min > 0) {
|
if (total_elem_min > 0) {
|
||||||
new_min += (damages_obj[0] / total_elem_min) * rainbow_raw;
|
min_boost += (damages_obj[0] / total_elem_min) * rainbow_raw;
|
||||||
}
|
}
|
||||||
new_max += (damages_obj[1] / total_elem_max) * rainbow_raw;
|
max_boost += (damages_obj[1] / total_elem_max) * rainbow_raw;
|
||||||
}
|
}
|
||||||
damages_obj[0] = new_min;
|
damages_obj[0] += min_boost * total_convert;
|
||||||
damages_obj[1] = new_max;
|
damages_obj[1] += max_boost * total_convert;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Strength boosters
|
// 6. Strength boosters
|
||||||
|
@ -182,8 +185,9 @@ spell: {
|
||||||
display_text: str short description of the spell, ex. Bash, Meteor, Arrow Shield
|
display_text: str short description of the spell, ex. Bash, Meteor, Arrow Shield
|
||||||
base_spell: int spell index. 0-4 are reserved (0 is melee, 1-4 is common 4 spells)
|
base_spell: int spell index. 0-4 are reserved (0 is melee, 1-4 is common 4 spells)
|
||||||
spell_type: str [TODO: DEPRECATED/REMOVE] "healing" or "damage"
|
spell_type: str [TODO: DEPRECATED/REMOVE] "healing" or "damage"
|
||||||
scaling: str "melee" or "spell"
|
scaling: Optional[str] [DEFAULT: "spell"] "melee" or "spell"
|
||||||
display: str "total" to sum all parts. Or, the name of a spell part
|
use_atkspd: Optional[bool] [DEFAULT: true] true to factor attack speed, false otherwise.
|
||||||
|
display: Optional[str] [DEFAULT: "total"] "total" to sum all parts. Or, the name of a spell part
|
||||||
parts: List[part] Parts of this spell (different stuff the spell does basically)
|
parts: List[part] Parts of this spell (different stuff the spell does basically)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,37 +216,74 @@ spell_total: {
|
||||||
are not the same type of spell. Can only pull from spells defined before it.
|
are not the same type of spell. Can only pull from spells defined before it.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Before passing to display, use the following structs.
|
||||||
|
NOTE: total is collapsed into damage or healing.
|
||||||
|
|
||||||
|
spell_damage: {
|
||||||
|
type: "damage" Internal use
|
||||||
|
name: str Display name of part. Should be human readable
|
||||||
|
normal_min: array[num, 6] floating point damages (no crit, min), can be less than zero. Order: NETWFA
|
||||||
|
normal_max: array[num, 6] floating point damages (no crit, max)
|
||||||
|
normal_total: array[num, 2] (min, max) noncrit total damage (not negative)
|
||||||
|
crit_min: array[num, 6] floating point damages (crit, min), can be less than zero. Order: NETWFA
|
||||||
|
crit_max: array[num, 6] floating point damages (crit, max)
|
||||||
|
crit_total: array[num, 2] (min, max) crit total damage (not negative)
|
||||||
|
}
|
||||||
|
spell_heal: {
|
||||||
|
type: "heal" Internal use
|
||||||
|
name: str Display name of part. Should be human readable
|
||||||
|
heal_amount: num floating point HP healed (self)
|
||||||
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const default_spells = {
|
const default_spells = {
|
||||||
wand: [{
|
wand: [{
|
||||||
name: "Melee", // TODO: name for melee attacks?
|
name: "Magic Strike", // TODO: name for melee attacks?
|
||||||
display_text: "Mage basic attack",
|
display_text: "Mage basic attack",
|
||||||
base_spell: 0, // Spell 0 is special cased to be handled with melee logic.
|
base_spell: 0,
|
||||||
spell_type: "damage",
|
scaling: "melee", use_atkspd: false,
|
||||||
scaling: "melee",
|
display: "Melee",
|
||||||
display: "total",
|
parts: [{ name: "Melee", multipliers: [100, 0, 0, 0, 0, 0] }]
|
||||||
parts: { name: "Melee", multipliers: [100, 0, 0, 0, 0, 0] }
|
|
||||||
}],
|
}],
|
||||||
spear: [{
|
spear: [{
|
||||||
name: "Melee", // TODO: name for melee attacks?
|
name: "Melee", // TODO: name for melee attacks?
|
||||||
display_text: "Warrior basic attack",
|
display_text: "Warrior basic attack",
|
||||||
base_spell: 0, // Spell 0 is special cased to be handled with melee logic.
|
base_spell: 0,
|
||||||
spell_type: "damage",
|
scaling: "melee", use_atkspd: false,
|
||||||
scaling: "melee",
|
display: "Melee",
|
||||||
display: "total",
|
parts: [{ name: "Melee", multipliers: [100, 0, 0, 0, 0, 0] }]
|
||||||
parts: { name: "Melee", multipliers: [100, 0, 0, 0, 0, 0] }
|
|
||||||
}],
|
}],
|
||||||
bow: [
|
bow: [{
|
||||||
|
name: "Bow Shot", // TODO: name for melee attacks?
|
||||||
],
|
display_text: "Archer basic attack",
|
||||||
dagger: [
|
base_spell: 0,
|
||||||
|
scaling: "melee", use_atkspd: false,
|
||||||
],
|
display: "Melee",
|
||||||
relik: [
|
parts: [{ name: "Melee", multipliers: [100, 0, 0, 0, 0, 0] }]
|
||||||
|
}],
|
||||||
],
|
dagger: [{
|
||||||
}
|
name: "Melee", // TODO: name for melee attacks?
|
||||||
|
display_text: "Assassin basic attack",
|
||||||
|
base_spell: 0,
|
||||||
|
scaling: "melee", use_atkspd: false,
|
||||||
|
display: "Melee",
|
||||||
|
parts: [{ name: "Melee", multipliers: [100, 0, 0, 0, 0, 0] }]
|
||||||
|
}],
|
||||||
|
relik: [{
|
||||||
|
name: "Spread Beam", // TODO: name for melee attacks?
|
||||||
|
display_text: "Shaman basic attack",
|
||||||
|
base_spell: 0,
|
||||||
|
spell_type: "damage",
|
||||||
|
scaling: "melee", use_atkspd: false,
|
||||||
|
display: "Total",
|
||||||
|
parts: [
|
||||||
|
{ name: "Single Beam", multipliers: [33, 0, 0, 0, 0, 0] },
|
||||||
|
{ name: "Total", hits: { "Single Beam": 3 } }
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
const spell_table = {
|
const spell_table = {
|
||||||
"wand": [
|
"wand": [
|
||||||
|
|
116
js/display.js
116
js/display.js
|
@ -1579,7 +1579,7 @@ function getBaseSpellCost(stats, spellIdx, cost) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function displaySpellDamage(parent_elem, overallparent_elem, stats, spell, spellIdx, spell_parts, damages) {
|
function displaySpellDamage(parent_elem, overallparent_elem, stats, spell, spellIdx, spell_results) {
|
||||||
// TODO: remove spellIdx (just used to flag melee and cost)
|
// TODO: remove spellIdx (just used to flag melee and cost)
|
||||||
// TODO: move cost calc out
|
// TODO: move cost calc out
|
||||||
parent_elem.textContent = "";
|
parent_elem.textContent = "";
|
||||||
|
@ -1589,7 +1589,7 @@ function displaySpellDamage(parent_elem, overallparent_elem, stats, spell, spell
|
||||||
overallparent_elem.textContent = "";
|
overallparent_elem.textContent = "";
|
||||||
let title_elemavg = document.createElement("b");
|
let title_elemavg = document.createElement("b");
|
||||||
|
|
||||||
if (spellIdx != 0) {
|
if ('cost' in spell) {
|
||||||
let first = document.createElement("span");
|
let first = document.createElement("span");
|
||||||
first.textContent = spell.title + " (";
|
first.textContent = spell.title + " (";
|
||||||
title_elem.appendChild(first.cloneNode(true)); //cloneNode is needed here.
|
title_elem.appendChild(first.cloneNode(true)); //cloneNode is needed here.
|
||||||
|
@ -1611,44 +1611,36 @@ function displaySpellDamage(parent_elem, overallparent_elem, stats, spell, spell
|
||||||
title_elemavg.appendChild(third_summary);
|
title_elemavg.appendChild(third_summary);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
title_elem.textContent = spell.title;
|
title_elem.textContent = spell.name;
|
||||||
title_elemavg.textContent = spell.title;
|
title_elemavg.textContent = spell.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent_elem.append(title_elem);
|
parent_elem.append(title_elem);
|
||||||
overallparent_elem.append(title_elemavg);
|
overallparent_elem.append(title_elemavg);
|
||||||
|
|
||||||
overallparent_elem.append(displayNextCosts(stats, spell, spellIdx));
|
if ('cost' in spell) {
|
||||||
|
overallparent_elem.append(displayNextCosts(stats, spell, spellIdx));
|
||||||
|
}
|
||||||
|
|
||||||
let critChance = skillPointsToPercentage(stats.get('dex'));
|
let critChance = skillPointsToPercentage(stats.get('dex'));
|
||||||
|
|
||||||
let save_damages = [];
|
|
||||||
|
|
||||||
let part_divavg = document.createElement("p");
|
let part_divavg = document.createElement("p");
|
||||||
overallparent_elem.append(part_divavg);
|
overallparent_elem.append(part_divavg);
|
||||||
|
|
||||||
for (let i = 0; i < spell_parts.length; ++i) {
|
for (let i = 0; i < spell_results.length; ++i) {
|
||||||
const part = spell_parts[i];
|
const damage_info = spell_results[i];
|
||||||
const damage = damages[i];
|
|
||||||
|
|
||||||
let part_div = document.createElement("p");
|
let part_div = document.createElement("p");
|
||||||
parent_elem.append(part_div);
|
parent_elem.append(part_div);
|
||||||
|
|
||||||
let subtitle_elem = document.createElement("p");
|
let subtitle_elem = document.createElement("p");
|
||||||
subtitle_elem.textContent = part.subtitle;
|
subtitle_elem.textContent = damage_info.name
|
||||||
part_div.append(subtitle_elem);
|
part_div.append(subtitle_elem);
|
||||||
|
|
||||||
if (part.type === "damage") {
|
if (damage_info.type === "damage") {
|
||||||
let _results = damage;
|
let totalDamNormal = damage_info.normal_total;
|
||||||
let totalDamNormal = _results[0];
|
let totalDamCrit = damage_info.crit_total;
|
||||||
let totalDamCrit = _results[1];
|
|
||||||
let results = _results[2];
|
|
||||||
|
|
||||||
for (let i = 0; i < 6; ++i) {
|
|
||||||
for (let j in results[i]) {
|
|
||||||
results[i][j] = results[i][j].toFixed(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let nonCritAverage = (totalDamNormal[0]+totalDamNormal[1])/2 || 0;
|
let nonCritAverage = (totalDamNormal[0]+totalDamNormal[1])/2 || 0;
|
||||||
let critAverage = (totalDamCrit[0]+totalDamCrit[1])/2 || 0;
|
let critAverage = (totalDamCrit[0]+totalDamCrit[1])/2 || 0;
|
||||||
let averageDamage = (1-critChance)*nonCritAverage+critChance*critAverage || 0;
|
let averageDamage = (1-critChance)*nonCritAverage+critChance*critAverage || 0;
|
||||||
|
@ -1659,11 +1651,11 @@ function displaySpellDamage(parent_elem, overallparent_elem, stats, spell, spell
|
||||||
part_div.append(averageLabel);
|
part_div.append(averageLabel);
|
||||||
|
|
||||||
|
|
||||||
if (part.summary == true) {
|
if (damage_info.name === spell.display) {
|
||||||
let overallaverageLabel = document.createElement("p");
|
let overallaverageLabel = document.createElement("p");
|
||||||
let first = document.createElement("span");
|
let first = document.createElement("span");
|
||||||
let second = document.createElement("span");
|
let second = document.createElement("span");
|
||||||
first.textContent = part.subtitle + " Average: ";
|
first.textContent = damage_info.name+ " Average: ";
|
||||||
second.textContent = averageDamage.toFixed(2);
|
second.textContent = averageDamage.toFixed(2);
|
||||||
overallaverageLabel.appendChild(first);
|
overallaverageLabel.appendChild(first);
|
||||||
overallaverageLabel.appendChild(second);
|
overallaverageLabel.appendChild(second);
|
||||||
|
@ -1671,71 +1663,65 @@ function displaySpellDamage(parent_elem, overallparent_elem, stats, spell, spell
|
||||||
part_divavg.append(overallaverageLabel);
|
part_divavg.append(overallaverageLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _damage_display(label_text, average, result_idx) {
|
function _damage_display(label_text, average, dmg_min, dmg_max) {
|
||||||
let label = document.createElement("p");
|
let label = document.createElement("p");
|
||||||
label.textContent = label_text+average.toFixed(2);
|
label.textContent = label_text+average.toFixed(2);
|
||||||
part_div.append(label);
|
part_div.append(label);
|
||||||
|
|
||||||
let arrmin = [];
|
|
||||||
let arrmax = [];
|
|
||||||
for (let i = 0; i < 6; i++){
|
for (let i = 0; i < 6; i++){
|
||||||
if (results[i][1] != 0){
|
if (dmg_max[i] != 0){
|
||||||
let p = document.createElement("p");
|
let p = document.createElement("p");
|
||||||
p.classList.add(damageClasses[i]);
|
p.classList.add(damageClasses[i]);
|
||||||
p.textContent = results[i][result_idx] + " \u2013 " + results[i][result_idx + 1];
|
p.textContent = dmg_min[i].toFixed(2)+" \u2013 "+dmg_max[i].toFixed(2);
|
||||||
arrmin.push(results[i][result_idx]);
|
|
||||||
arrmax.push(results[i][result_idx + 1]);
|
|
||||||
part_div.append(p);
|
part_div.append(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_damage_display("Non-Crit Average: ", nonCritAverage, 0);
|
_damage_display("Non-Crit Average: ", nonCritAverage, damage_info.normal_min, damage_info.normal_max);
|
||||||
_damage_display("Crit Average: ", critAverage, 2);
|
_damage_display("Crit Average: ", critAverage, damage_info.crit_min, damage_info.crit_max);
|
||||||
|
} else if (damage_info.type === "heal") {
|
||||||
save_damages.push(averageDamage);
|
let heal_amount = damage_info.heal_amount;
|
||||||
} else if (part.type === "heal") {
|
|
||||||
let heal_amount = damage;
|
|
||||||
let healLabel = document.createElement("p");
|
let healLabel = document.createElement("p");
|
||||||
healLabel.textContent = heal_amount;
|
healLabel.textContent = heal_amount;
|
||||||
// healLabel.classList.add("damagep");
|
// healLabel.classList.add("damagep");
|
||||||
part_div.append(healLabel);
|
part_div.append(healLabel);
|
||||||
if (part.summary == true) {
|
if (damage_info.name === spell.display) {
|
||||||
let overallhealLabel = document.createElement("p");
|
let overallhealLabel = document.createElement("p");
|
||||||
let first = document.createElement("span");
|
let first = document.createElement("span");
|
||||||
let second = document.createElement("span");
|
let second = document.createElement("span");
|
||||||
first.textContent = part.subtitle + ": ";
|
first.textContent = damage_info.name+ ": ";
|
||||||
second.textContent = heal_amount;
|
second.textContent = heal_amount;
|
||||||
overallhealLabel.appendChild(first);
|
overallhealLabel.appendChild(first);
|
||||||
second.classList.add("Set");
|
second.classList.add("Set");
|
||||||
overallhealLabel.appendChild(second);
|
overallhealLabel.appendChild(second);
|
||||||
part_divavg.append(overallhealLabel);
|
part_divavg.append(overallhealLabel);
|
||||||
}
|
}
|
||||||
} else if (part.type === "total") {
|
// } else if (part.type === "total") {
|
||||||
let total_damage = 0;
|
// let total_damage = 0;
|
||||||
for (let i in part.factors) {
|
// for (let i in part.factors) {
|
||||||
total_damage += save_damages[i] * part.factors[i];
|
// total_damage += save_damages[i] * part.factors[i];
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
let dmgarr = part.factors.slice();
|
// let dmgarr = part.factors.slice();
|
||||||
dmgarr = dmgarr.map(x => "(" + x + " * " + save_damages[dmgarr.indexOf(x)].toFixed(2) + ")");
|
// dmgarr = dmgarr.map(x => "(" + x + " * " + save_damages[dmgarr.indexOf(x)].toFixed(2) + ")");
|
||||||
|
//
|
||||||
|
//
|
||||||
let averageLabel = document.createElement("p");
|
// let averageLabel = document.createElement("p");
|
||||||
averageLabel.textContent = "Average: "+total_damage.toFixed(2);
|
// averageLabel.textContent = "Average: "+total_damage.toFixed(2);
|
||||||
averageLabel.classList.add("damageSubtitle");
|
// averageLabel.classList.add("damageSubtitle");
|
||||||
part_div.append(averageLabel);
|
// part_div.append(averageLabel);
|
||||||
|
//
|
||||||
let overallaverageLabel = document.createElement("p");
|
// let overallaverageLabel = document.createElement("p");
|
||||||
let overallaverageLabelFirst = document.createElement("span");
|
// let overallaverageLabelFirst = document.createElement("span");
|
||||||
let overallaverageLabelSecond = document.createElement("span");
|
// let overallaverageLabelSecond = document.createElement("span");
|
||||||
overallaverageLabelFirst.textContent = "Average: ";
|
// overallaverageLabelFirst.textContent = "Average: ";
|
||||||
overallaverageLabelSecond.textContent = total_damage.toFixed(2);
|
// overallaverageLabelSecond.textContent = total_damage.toFixed(2);
|
||||||
overallaverageLabelSecond.classList.add("Damage");
|
// overallaverageLabelSecond.classList.add("Damage");
|
||||||
|
//
|
||||||
|
//
|
||||||
overallaverageLabel.appendChild(overallaverageLabelFirst);
|
// overallaverageLabel.appendChild(overallaverageLabelFirst);
|
||||||
overallaverageLabel.appendChild(overallaverageLabelSecond);
|
// overallaverageLabel.appendChild(overallaverageLabelSecond);
|
||||||
part_divavg.append(overallaverageLabel);
|
// part_divavg.append(overallaverageLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue