Wynnbuilder 1.20.3 (no ingred or crafted update yet)

This commit is contained in:
b 2021-07-05 18:46:09 -07:00
parent 08a4bb598c
commit 92f08629c0
11 changed files with 3480 additions and 117982 deletions

File diff suppressed because it is too large Load diff

9073
clean.json

File diff suppressed because it is too large Load diff

110663
clean3.json

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,10 +1,11 @@
const ci_save_order = ["name", "lore", "tier", "set", "slots", "type", "material", "drop", "quest", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "atkSpd", "hp", "fDef", "wDef", "aDef", "tDef", "eDef", "lvl", "classReq", "strReq", "dexReq", "intReq", "defReq", "agiReq","str", "dex", "int", "agi", "def", "id", "skillpoints", "reqs", "majorIds", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd","durability","duration","charges"]; const ci_save_order = ["name", "lore", "tier", "set", "slots", "type", "material", "drop", "quest", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "atkSpd", "hp", "fDef", "wDef", "aDef", "tDef", "eDef", "lvl", "classReq", "strReq", "dexReq", "intReq", "defReq", "agiReq","str", "dex", "int", "agi", "def", "id", "skillpoints", "reqs", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_", "majorIds", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd","durability","duration","charges"];
const nonRolled_strings = ["name","lore", "tier","set","type","material","drop","quest","majorIds","classReq","atkSpd","displayName", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_", "durability", "duration"]; const nonRolled_strings = ["name","lore", "tier","set","type","material","drop","quest","majorIds","classReq","atkSpd","displayName", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_", "durability", "duration"];
//omitted restrict - it's always "Custom Item" //omitted restrict - it's always "Custom Item"
//omitted displayName - either it's the same as name (repetitive) or it's "Custom Item" //omitted displayName - either it's the same as name (repetitive) or it's "Custom Item"
//omitted category - can always get this from type //omitted category - can always get this from type
//omitted fixId - we will denote this early in the string. //omitted fixId - we will denote this early in the string.
//omitted "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_" - will be calculated on display //omitted "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_" - will be calculated on display
// NOTE: DO NOT DELETE ENTRIES FROM ARRAYS FOR BACKWARDS COMPAT REASONS!!!
/** /**
* @param {Map} custom - the statMap of the CI * @param {Map} custom - the statMap of the CI

View file

@ -53,11 +53,11 @@ function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier,
damageBases[element+1] += diff + Math.floor( (powder.min + powder.max) / 2 ); damageBases[element+1] += diff + Math.floor( (powder.min + powder.max) / 2 );
} }
//update all damages //update all damages
//if(!weapon.get("custom")) { if(!weapon.get("custom")) {
for (let i = 0; i < damages.length; i++) { for (let i = 0; i < damages.length; i++) {
damages[i] = [Math.floor(damageBases[i] * 0.9), Math.floor(damageBases[i] * 1.1)]; damages[i] = [Math.floor(damageBases[i] * 0.9), Math.floor(damageBases[i] * 1.1)];
} }
//} }
neutralRemainingRaw = damages[0].slice(); neutralRemainingRaw = damages[0].slice();
neutralBase = damages[0].slice(); neutralBase = damages[0].slice();
@ -117,20 +117,21 @@ function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier,
rawModifier *= spellMultiplier * damageMultiplier; rawModifier *= spellMultiplier * damageMultiplier;
let totalDamNorm = [0, 0]; let totalDamNorm = [0, 0];
let totalDamCrit = [0, 0]; let totalDamCrit = [0, 0];
if(!melee){
totalDamNorm = [rawModifier, rawModifier];
totalDamCrit = [rawModifier, rawModifier];
for (let arr of damageformulas) {
arr = arr.map(x => x + " + " +tooltipinfo.get("rawModifier"));
}
}
let damages_results = []; let damages_results = [];
// 0th skillpoint is strength, 1st is dex. // 0th skillpoint is strength, 1st is dex.
let str = total_skillpoints[0]; let str = total_skillpoints[0];
let strBoost = 1 + skillPointsToPercentage(str); let strBoost = 1 + skillPointsToPercentage(str);
//let staticBoost = (pctModifier / 100.); if(!melee){
let staticBoost = (pctModifier / 100.) + skillPointsToPercentage(str); let baseDam = rawModifier * strBoost;
tooltipinfo.set("staticBoost", `${(pctModifier/ 100.).toFixed(2)} + ${skillPointsToPercentage(str).toFixed(2)}`); let baseDamCrit = rawModifier * (1 + strBoost);
totalDamNorm = [baseDam, baseDam];
totalDamCrit = [baseDamCrit, baseDamCrit];
for (let arr of damageformulas) {
arr = arr.map(x => x + " + " +tooltipinfo.get("rawModifier"));
}
}
let staticBoost = (pctModifier / 100.);
tooltipinfo.set("staticBoost", `${(pctModifier/ 100.).toFixed(2)}`);
tooltipinfo.set("skillBoost",["","","","","",""]); tooltipinfo.set("skillBoost",["","","","","",""]);
let skillBoost = [0]; let skillBoost = [0];
for (let i in total_skillpoints) { for (let i in total_skillpoints) {
@ -143,50 +144,36 @@ function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier,
let damageBoost = 1 + skillBoost[i] + staticBoost; let damageBoost = 1 + skillBoost[i] + staticBoost;
tooltipinfo.set("damageBoost", `(1 + ${(tooltipinfo.get("skillBoost")[i] ? tooltipinfo.get("skillBoost")[i] + " + " : "")} ${tooltipinfo.get("staticBoost")})`) tooltipinfo.set("damageBoost", `(1 + ${(tooltipinfo.get("skillBoost")[i] ? tooltipinfo.get("skillBoost")[i] + " + " : "")} ${tooltipinfo.get("staticBoost")})`)
damages_results.push([ damages_results.push([
//Math.max(damages[i][0] * strBoost * Math.max(damageBoost,0) * damageMult, 0), // Normal min Math.max(damages[i][0] * strBoost * Math.max(damageBoost,0) * damageMult, 0), // Normal min
//Math.max(damages[i][1] * strBoost * Math.max(damageBoost,0) * damageMult, 0), // Normal max Math.max(damages[i][1] * strBoost * Math.max(damageBoost,0) * damageMult, 0), // Normal max
//Math.max(damages[i][0] * strBoost * 2 * Math.max(damageBoost,0) * damageMult, 0), // Crit min Math.max(damages[i][0] * (strBoost + 1) * Math.max(damageBoost,0) * damageMult, 0), // Crit min
//Math.max(damages[i][1] * strBoost * 2 * Math.max(damageBoost,0) * damageMult, 0), // Crit max Math.max(damages[i][1] * (strBoost + 1) * Math.max(damageBoost,0) * damageMult, 0), // Crit max
// Math.max(damages[i][0] * Math.max(damageBoost,0) * damageMult, 0), // Normal min
// Math.max(damages[i][1] * Math.max(damageBoost,0) * damageMult, 0), // Normal max
// Math.max(damages[i][0] * Math.max(1 + damageBoost, 0) * damageMult, 0), // Crit min
// Math.max(damages[i][1] * Math.max(1 + damageBoost, 0) * damageMult, 0), // Crit max
damages[i][0] * Math.max(damageBoost,0) * damageMult, // Normal min
damages[i][1] * Math.max(damageBoost,0) * damageMult, // Normal max
damages[i][0] * Math.max(1 + damageBoost, 0) * damageMult, // Crit min
damages[i][1] * Math.max(1 + damageBoost, 0) * damageMult, // Crit max
]); ]);
damageformulas[i][0] += `(max((${tooltipinfo.get("damageBases")[i][0]} * max(${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))` damageformulas[i][0] += `(max((${tooltipinfo.get("damageBases")[i][0]} * ${strBoost} * max(${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))`
damageformulas[i][1] += `(max((${tooltipinfo.get("damageBases")[i][1]} * max(${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))` damageformulas[i][1] += `(max((${tooltipinfo.get("damageBases")[i][1]} * ${strBoost} * max(${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))`
damageformulas[i][2] += `(max((${tooltipinfo.get("damageBases")[i][0]} * max(1 + ${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))` damageformulas[i][2] += `(max((${tooltipinfo.get("damageBases")[i][0]} * ${strBoost} * 2 * max(${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))`
damageformulas[i][3] += `(max((${tooltipinfo.get("damageBases")[i][1]} * max(1 + ${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))` damageformulas[i][3] += `(max((${tooltipinfo.get("damageBases")[i][1]} * ${strBoost} * 2 * max(${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))`
totalDamNorm[0] += damages_results[i][0]; totalDamNorm[0] += damages_results[i][0];
totalDamNorm[1] += damages_results[i][1]; totalDamNorm[1] += damages_results[i][1];
totalDamCrit[0] += damages_results[i][2]; totalDamCrit[0] += damages_results[i][2];
totalDamCrit[1] += damages_results[i][3]; totalDamCrit[1] += damages_results[i][3];
} }
if (melee) { if (melee) {
//totalDamNorm[0] += Math.max(strBoost*rawModifier, -damages_results[0][0]); totalDamNorm[0] += Math.max(strBoost*rawModifier, -damages_results[0][0]);
//totalDamNorm[1] += Math.max(strBoost*rawModifier, -damages_results[0][1]); totalDamNorm[1] += Math.max(strBoost*rawModifier, -damages_results[0][1]);
//totalDamCrit[0] += Math.max(strBoost*2*rawModifier, -damages_results[0][2]); totalDamCrit[0] += Math.max(strBoost*2*rawModifier, -damages_results[0][2]);
//totalDamCrit[1] += Math.max(strBoost*2*rawModifier, -damages_results[0][3]); totalDamCrit[1] += Math.max(strBoost*2*rawModifier, -damages_results[0][3]);
totalDamNorm[0] += Math.max(rawModifier, -damages_results[0][0]);
totalDamNorm[1] += Math.max(rawModifier, -damages_results[0][1]);
totalDamCrit[0] += Math.max(rawModifier, -damages_results[0][2]);
totalDamCrit[1] += Math.max(rawModifier, -damages_results[0][3]);
} }
//damages_results[0][0] += strBoost*rawModifier; damages_results[0][0] += strBoost*rawModifier;
//damages_results[0][1] += strBoost*rawModifier; damages_results[0][1] += strBoost*rawModifier;
//damages_results[0][2] += strBoost*2*rawModifier; damages_results[0][2] += (strBoost + 1)*rawModifier;
//damages_results[0][3] += strBoost*2*rawModifier; damages_results[0][3] += (strBoost + 1)*rawModifier;
damages_results[0][0] += rawModifier; for (let i = 0; i < 2; i++) {
damages_results[0][1] += rawModifier; damageformulas[0][i] += ` + (${strBoost} * ${tooltipinfo.get("rawModifier")})`
damages_results[0][2] += rawModifier; }
damages_results[0][3] += rawModifier; for (let i = 2; i < 4; i++) {
for (let i in damageformulas[0]) { damageformulas[0][i] += ` + (2 * ${strBoost} * ${tooltipinfo.get("rawModifier")})`
damageformulas[0][i] += ` + ${tooltipinfo.get("rawModifier")}`
} }
if (totalDamNorm[0] < 0) totalDamNorm[0] = 0; if (totalDamNorm[0] < 0) totalDamNorm[0] = 0;
if (totalDamNorm[1] < 0) totalDamNorm[1] = 0; if (totalDamNorm[1] < 0) totalDamNorm[1] = 0;

View file

@ -1,308 +0,0 @@
const damageMultipliers = new Map([ ["allytotem", .15], ["yourtotem", .35], ["vanish", 0.80], ["warscream", 0.10], ["bash", 0.50] ]);
// 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.
// externalStats should be a map
function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier, spellMultiplier, weapon, total_skillpoints, damageMultiplier, externalStats) {
let buildStats = new Map(stats);
let tooltipinfo = new Map();
//6x for damages, normal min normal max crit min crit max
let damageformulas = [["Min: = ","Max: = ","Min: = ","Max: = "],["Min: = ","Max: = ","Min: = ","Max: = "],["Min: = ","Max: = ","Min: = ","Max: = "],["Min: = ","Max: = ","Min: = ","Max: = "],["Min: = ","Max: = ","Min: = ","Max: = "],["Min: = ","Max: = ","Min: = ","Max: = "]];
if(externalStats) { //if nothing is passed in, then this hopefully won't trigger
for (const entry of externalStats) {
const key = entry[0];
const value = entry[1];
if (typeof value === "number") {
buildStats.set(key, buildStats.get(key) + value);
} else if (Array.isArray(value)) {
arr = [];
for (let j = 0; j < value.length; j++) {
arr[j] = buildStats.get(key)[j] + value[j];
}
buildStats.set(key, arr);
}
}
}
let powders = weapon.get("powders").slice();
// Array of neutral + ewtfa damages. Each entry is a pair (min, max).
let damages = [];
const rawDamages = buildStats.get("damageRaw");
for (let i = 0; i < rawDamages.length; i++) {
const damage_vals = rawDamages[i].split("-").map(Number);
damages.push(damage_vals);
}
// Applying spell conversions
let neutralBase = damages[0].slice();
let neutralRemainingRaw = damages[0].slice();
//powder application for custom crafted weapons is inherently fucked because there is no base. Unsure what to do.
//Powder application for Crafted weapons - this implementation is RIGHT YEAAAAAAAAA
//1st round - apply each as ingred, 2nd round - apply as normal
if (weapon.get("tier") === "Crafted") {
let damageBases = buildStats.get("damageBases").slice();
for (const p of powders.concat(weapon.get("ingredPowders"))) {
let powder = powderStats[p]; //use min, max, and convert
let element = Math.floor((p+0.01)/6); //[0,4], the +0.01 attempts to prevent division error
let diff = Math.floor(damageBases[0] * powder.convert/100);
damageBases[0] -= diff;
damageBases[element+1] += diff + Math.floor( (powder.min + powder.max) / 2 );
}
//update all damages
if(!weapon.get("custom")) {
for (let i = 0; i < damages.length; i++) {
damages[i] = [Math.floor(damageBases[i] * 0.9), Math.floor(damageBases[i] * 1.1)];
}
}
neutralRemainingRaw = damages[0].slice();
neutralBase = damages[0].slice();
}
for (let i = 0; i < 5; ++i) {
let conversionRatio = spellConversions[i+1]/100;
let min_diff = Math.min(neutralRemainingRaw[0], conversionRatio * neutralBase[0]);
let max_diff = Math.min(neutralRemainingRaw[1], conversionRatio * neutralBase[1]);
damages[i+1][0] = Math.floor(round_near(damages[i+1][0] + min_diff));
damages[i+1][1] = Math.floor(round_near(damages[i+1][1] + max_diff));
neutralRemainingRaw[0] = Math.floor(round_near(neutralRemainingRaw[0] - min_diff));
neutralRemainingRaw[1] = Math.floor(round_near(neutralRemainingRaw[1] - max_diff));
}
//apply powders to weapon
for (const powderID of powders) {
const powder = powderStats[powderID];
// Bitwise to force conversion to integer (integer division).
const element = (powderID/6) | 0;
let conversionRatio = powder.convert/100;
if (neutralRemainingRaw[1] > 0) {
let min_diff = Math.min(neutralRemainingRaw[0], conversionRatio * neutralBase[0]);
let max_diff = Math.min(neutralRemainingRaw[1], conversionRatio * neutralBase[1]);
damages[element+1][0] = Math.floor(round_near(damages[element+1][0] + min_diff));
damages[element+1][1] = Math.floor(round_near(damages[element+1][1] + max_diff));
neutralRemainingRaw[0] = Math.floor(round_near(neutralRemainingRaw[0] - min_diff));
neutralRemainingRaw[1] = Math.floor(round_near(neutralRemainingRaw[1] - max_diff));
}
damages[element+1][0] += powder.min;
damages[element+1][1] += powder.max;
}
//console.log(tooltipinfo);
damages[0] = neutralRemainingRaw;
tooltipinfo.set("damageBases", damages);
let damageMult = damageMultiplier;
let melee = false;
// If we are doing melee calculations:
tooltipinfo.set("dmgMult", damageMult);
if (spellMultiplier == 0) {
spellMultiplier = 1;
melee = true;
}
else {
tooltipinfo.set("dmgMult", `(${tooltipinfo.get("dmgMult")} * ${spellMultiplier} * ${baseDamageMultiplier[attackSpeeds.indexOf(buildStats.get("atkSpd"))]})`)
damageMult *= spellMultiplier * baseDamageMultiplier[attackSpeeds.indexOf(buildStats.get("atkSpd"))];
}
//console.log(damages);
//console.log(damageMult);
tooltipinfo.set("rawModifier", `(${rawModifier} * ${spellMultiplier} * ${damageMultiplier})`);
rawModifier *= spellMultiplier * damageMultiplier;
let totalDamNorm = [0, 0];
let totalDamCrit = [0, 0];
let damages_results = [];
// 0th skillpoint is strength, 1st is dex.
let str = total_skillpoints[0];
let strBoost = 1 + skillPointsToPercentage(str);
if(!melee){
let baseDam = rawModifier * strBoost;
let baseDamCrit = rawModifier * (1 + strBoost);
totalDamNorm = [baseDam, baseDam];
totalDamCrit = [baseDamCrit, baseDamCrit];
for (let arr of damageformulas) {
arr = arr.map(x => x + " + " +tooltipinfo.get("rawModifier"));
}
}
let staticBoost = (pctModifier / 100.);
tooltipinfo.set("staticBoost", `${(pctModifier/ 100.).toFixed(2)}`);
tooltipinfo.set("skillBoost",["","","","","",""]);
let skillBoost = [0];
for (let i in total_skillpoints) {
skillBoost.push(skillPointsToPercentage(total_skillpoints[i]) + buildStats.get("damageBonus")[i] / 100.);
tooltipinfo.get("skillBoost")[parseInt(i,10)+1] = `(${skillPointsToPercentage(total_skillpoints[i]).toFixed(2)} + ${(buildStats.get("damageBonus")[i]/100.).toFixed(2)})`
}
tooltipinfo.get("skillBoost")[0] = undefined;
for (let i in damages) {
let damageBoost = 1 + skillBoost[i] + staticBoost;
tooltipinfo.set("damageBoost", `(1 + ${(tooltipinfo.get("skillBoost")[i] ? tooltipinfo.get("skillBoost")[i] + " + " : "")} ${tooltipinfo.get("staticBoost")})`)
damages_results.push([
Math.max(damages[i][0] * strBoost * Math.max(damageBoost,0) * damageMult, 0), // Normal min
Math.max(damages[i][1] * strBoost * Math.max(damageBoost,0) * damageMult, 0), // Normal max
Math.max(damages[i][0] * (strBoost + 1) * Math.max(damageBoost,0) * damageMult, 0), // Crit min
Math.max(damages[i][1] * (strBoost + 1) * Math.max(damageBoost,0) * damageMult, 0), // Crit max
]);
damageformulas[i][0] += `(max((${tooltipinfo.get("damageBases")[i][0]} * ${strBoost} * max(${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))`
damageformulas[i][1] += `(max((${tooltipinfo.get("damageBases")[i][1]} * ${strBoost} * max(${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))`
damageformulas[i][2] += `(max((${tooltipinfo.get("damageBases")[i][0]} * ${strBoost} * 2 * max(${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))`
damageformulas[i][3] += `(max((${tooltipinfo.get("damageBases")[i][1]} * ${strBoost} * 2 * max(${tooltipinfo.get("damageBoost")}, 0) * ${tooltipinfo.get("dmgMult")}), 0))`
totalDamNorm[0] += damages_results[i][0];
totalDamNorm[1] += damages_results[i][1];
totalDamCrit[0] += damages_results[i][2];
totalDamCrit[1] += damages_results[i][3];
}
if (melee) {
totalDamNorm[0] += Math.max(strBoost*rawModifier, -damages_results[0][0]);
totalDamNorm[1] += Math.max(strBoost*rawModifier, -damages_results[0][1]);
totalDamCrit[0] += Math.max(strBoost*2*rawModifier, -damages_results[0][2]);
totalDamCrit[1] += Math.max(strBoost*2*rawModifier, -damages_results[0][3]);
}
damages_results[0][0] += strBoost*rawModifier;
damages_results[0][1] += strBoost*rawModifier;
damages_results[0][2] += (strBoost + 1)*rawModifier;
damages_results[0][3] += (strBoost + 1)*rawModifier;
for (let i = 0; i < 2; i++) {
damageformulas[0][i] += ` + (${strBoost} * ${tooltipinfo.get("rawModifier")})`
}
for (let i = 2; i < 4; i++) {
damageformulas[0][i] += ` + (2 * ${strBoost} * ${tooltipinfo.get("rawModifier")})`
}
if (totalDamNorm[0] < 0) totalDamNorm[0] = 0;
if (totalDamNorm[1] < 0) totalDamNorm[1] = 0;
if (totalDamCrit[0] < 0) totalDamCrit[0] = 0;
if (totalDamCrit[1] < 0) totalDamCrit[1] = 0;
tooltipinfo.set("damageformulas", damageformulas);
return [totalDamNorm, totalDamCrit, damages_results, tooltipinfo];
}
const spell_table = {
"wand": [
{ title: "Heal", cost: 6, parts: [
{ subtitle: "First Pulse", type: "heal", strength: 0.12 },
{ subtitle: "Second and Third Pulses", type: "heal", strength: 0.06 },
{ subtitle: "Total Heal", type: "heal", strength: 0.24, summary: true },
{ subtitle: "First Pulse (Ally)", type: "heal", strength: 0.20 },
{ subtitle: "Second and Third Pulses (Ally)", type: "heal", strength: 0.1 },
{ subtitle: "Total Heal (Ally)", type: "heal", strength: 0.4 }
] },
{ title: "Teleport", cost: 4, parts: [
{ subtitle: "Total Damage", type: "damage", multiplier: 100, conversion: [60, 0, 40, 0, 0, 0], summary: true },
] },
{ title: "Meteor", cost: 8, parts: [
{ subtitle: "Blast Damage", type: "damage", multiplier: 500, conversion: [40, 30, 0, 0, 30, 0], summary: true },
{ subtitle: "Burn Damage", type: "damage", multiplier: 125, conversion: [100, 0, 0, 0, 0, 0] },
] },
{ title: "Ice Snake", cost: 4, parts: [
{ subtitle: "Total Damage", type: "damage", multiplier: 70, conversion: [50, 0, 0, 50, 0, 0], summary: true },
] },
],
"spear": [
{ title: "Bash", cost: 6, parts: [
{ subtitle: "First Damage", type: "damage", multiplier: 130, conversion: [60, 40, 0, 0, 0, 0]},
{ subtitle: "Explosion Damage", type: "damage", multiplier: 130, conversion: [100, 0, 0, 0, 0, 0]},
{ subtitle: "Total Damage", type: "total", factors: [1, 1], summary: true },
] },
{ title: "Charge", cost: 4, variants: {
DEFAULT: [
{ subtitle: "Total Damage", type: "damage", multiplier: 150, conversion: [60, 0, 0, 0, 40, 0], summary: true }
],
RALLY: [
{ subtitle: "Self Heal", type: "heal", strength: 0.1, summary: true },
{ subtitle: "Ally Heal", type: "heal", strength: 0.15 }
]
} },
{ title: "Uppercut", cost: 9, parts: [
{ subtitle: "First Damage", type: "damage", multiplier: 300, conversion: [70, 20, 10, 0, 0, 0] },
{ subtitle: "Fireworks Damage", type: "damage", multiplier: 50, conversion: [60, 0, 40, 0, 0, 0] },
{ subtitle: "Crash Damage", type: "damage", multiplier: 50, conversion: [80, 0, 20, 0, 0, 0] },
{ subtitle: "Total Damage", type: "total", factors: [1, 1, 1], summary: true },
] },
{ title: "War Scream", cost: 6, parts: [
{ subtitle: "Area Damage", type: "damage", multiplier: 50, conversion: [0, 0, 0, 0, 75, 25], summary: true },
{ subtitle: "Air Shout (Per Hit)", type: "damage", multiplier: 30, conversion: [0, 0, 0, 0, 75, 25] },
] },
],
"bow": [
{ title: "Arrow Storm", cost: 6, variants: {
DEFAULT: [
{ subtitle: "Total Damage", type: "damage", multiplier: 600, conversion: [60, 0, 25, 0, 15, 0], summary: true },
{ subtitle: "Per Arrow (60)", type: "damage", multiplier: 10, conversion: [60, 0, 25, 0, 15, 0]}
],
HAWKEYE: [
{ subtitle: "Total Damage (Hawkeye)", type: "damage", multiplier: 400, conversion: [60, 0, 25, 0, 15, 0], summary: true },
{ subtitle: "Per Arrow (5)", type: "damage", multiplier: 80, conversion: [60, 0, 25, 0, 15, 0]}
],
} },
{ title: "Escape", cost: 3, parts: [
{ subtitle: "Landing Damage", type: "damage", multiplier: 100, conversion: [50, 0, 0, 0, 0, 50], summary: true },
] },
{ title: "Bomb Arrow", cost: 8, parts: [
{ subtitle: "Total Damage", type: "damage", multiplier: 250, conversion: [60, 25, 0, 0, 15, 0], summary: true },
] },
{ title: "Arrow Shield", cost: 10, parts: [
{ subtitle: "Shield Damage", type: "damage", multiplier: 100, conversion: [70, 0, 0, 0, 0, 30], summary: true },
{ subtitle: "Arrow Rain Damage", type: "damage", multiplier: 200, conversion: [70, 0, 0, 0, 0, 30] },
] },
],
"dagger": [
{ title: "Spin Attack", cost: 6, parts: [
{ subtitle: "Total Damage", type: "damage", multiplier: 150, conversion: [70, 0, 30, 0, 0, 0], summary: true},
] },
{ title: "Vanish", cost: 2, parts: [
{ subtitle: "No Damage", type: "none", summary: true }
] },
{ title: "Multihit", cost: 8, parts: [
{ subtitle: "1st to 10th Hit", type: "damage", multiplier: 27, conversion: [100, 0, 0, 0, 0, 0] },
{ subtitle: "Fatality", type: "damage", multiplier: 120, conversion: [20, 0, 30, 50, 0, 0] },
{ subtitle: "Total Damage", type: "total", factors: [10, 1], summary: true },
] },
{ title: "Smoke Bomb", cost: 8, variants: {
DEFAULT: [
{ subtitle: "Tick Damage (10 max)", type: "damage", multiplier: 60, conversion: [50, 25, 0, 0, 0, 25] },
{ subtitle: "Total Damage", type: "damage", multiplier: 600, conversion: [50, 25, 0, 0, 0, 25], summary: true },
],
CHERRY_BOMBS: [
{ subtitle: "Total Damage (Cherry Bombs)", type: "damage", multiplier: 330, conversion: [50, 25, 0, 0, 0, 25], summary: true },
{ subtitle: "Per Bomb", type: "damage", multiplier: 110, conversion: [50, 25, 0, 0, 0, 25] }
]
} },
],
"relik": [
{ title: "Totem", cost: 4, parts: [
{ subtitle: "Smash Damage", type: "damage", multiplier: 100, conversion: [80, 0, 0, 0, 20, 0]},
{ subtitle: "Damage Tick", type: "damage", multiplier: 20, conversion: [80, 0, 0, 0, 0, 20]},
{ subtitle: "Heal Tick", type: "heal", strength: 0.03, summary: true },
] },
{ title: "Haul", cost: 1, parts: [
{ subtitle: "Total Damage", type: "damage", multiplier: 100, conversion: [80, 0, 20, 0, 0, 0], summary: true },
] },
{ title: "Aura", cost: 8, parts: [
{ subtitle: "One Wave", type: "damage", multiplier: 200, conversion: [70, 0, 0, 30, 0, 0], summary: true },
] },
{ title: "Uproot", cost: 6, parts: [
{ subtitle: "Total Damage", type: "damage", multiplier: 100, conversion: [70, 30, 0, 0, 0, 0], summary: true },
] },
],
"powder": [ //This is how instant-damage powder specials are implemented.
{ title: "Quake", cost: 0, parts:[
{ subtitle: "Total Damage", type: "damage", multiplier: [155, 220, 285, 350, 415], conversion: [0,100,0,0,0,0], summary: true},
] },
{ title: "Chain Lightning", cost: 0, parts: [
{ subtitle: "Total Damage", type: "damage", multiplier: [200, 225, 250, 275, 300], conversion: [0,0,100,0,0,0], summary: true},
]},
{ 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]
]
};

258
load3.js
View file

@ -1,258 +0,0 @@
const DB_VERSION = 67;
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA
let db;
let reload = false;
let load_complete = false;
let load_in_progress = false;
let items;
let sets;
let itemMap;
let idMap;
let redirectMap;
let itemLists = new Map();
/*
* Load item set from local DB. Calls init() on success.
*/
async function load_local(init_func) {
let get_tx = db.transaction(['item3_db', 'set3_db'], 'readonly');
let sets_store = get_tx.objectStore('set3_db');
let get_store = get_tx.objectStore('item3_db');
let request = get_store.getAll();
request.onerror = function(event) {
console.log("Could not read local item db...");
}
request.onsuccess = function(event) {
console.log("Successfully read local item db.");
items = request.result;
//console.log(items);
let request2 = sets_store.openCursor();
sets = {};
request2.onerror = function(event) {
console.log("Could not read local set db...");
}
request2.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
sets[cursor.primaryKey] = cursor.value;
cursor.continue();
}
else {
console.log("Successfully read local set db.");
//console.log(sets);
init_maps();
init_func();
load_complete = true;
}
}
}
await get_tx.complete;
db.close();
}
/*
* Clean bad item data. For now just assigns display name if it isn't already assigned.
*/
function clean_item(item) {
if (item.remapID === undefined) {
if (item.displayName === undefined) {
item.displayName = item.name;
}
item.skillpoints = [item.str, item.dex, item.int, item.def, item.agi];
item.reqs = [item.strReq, item.dexReq, item.intReq, item.defReq, item.agiReq];
item.has_negstat = false;
for (let i = 0; i < 5; ++i) {
if (item.reqs[i] === undefined) { item.reqs[i] = 0; }
if (item.skillpoints[i] === undefined) { item.skillpoints[i] = 0; }
if (item.skillpoints[i] < 0) { item.has_negstat = true; }
}
if (item.slots === undefined) {
item.slots = 0;
}
}
}
/*
* Load item set from remote DB (aka a big json file). Calls init() on success.
*/
async function load(init_func) {
let getUrl = window.location;
let baseUrl = getUrl.protocol + "//" + getUrl.host + "/";// + getUrl.pathname.split('/')[1];
// "Random" string to prevent caching!
let url = baseUrl + "/compress3.json?"+new Date();
let result = await (await fetch(url)).json();
items = result.items;
sets = result.sets;
// let clear_tx = db.transaction(['item_db', 'set_db'], 'readwrite');
// let clear_items = clear_tx.objectStore('item_db');
// let clear_sets = clear_tx.objectStore('item_db');
//
// await clear_items.clear();
// await clear_sets.clear();
// await clear_tx.complete;
let add_tx = db.transaction(['item3_db', 'set3_db'], 'readwrite');
add_tx.onabort = function(e) {
console.log(e);
console.log("Not enough space...");
};
let items_store = add_tx.objectStore('item3_db');
let add_promises = [];
for (const item of items) {
clean_item(item);
let req = items_store.add(item, item.name);
req.onerror = function() {
console.log("ADD ITEM ERROR? " + item.name);
};
add_promises.push(req);
}
let sets_store = add_tx.objectStore('set3_db');
for (const set in sets) {
add_promises.push(sets_store.add(sets[set], set));
}
add_promises.push(add_tx.complete);
Promise.all(add_promises).then((values) => {
init_maps();
init_func();
load_complete = true;
});
// DB not closed? idfk man
}
function load_init(init_func) {
if (load_complete) {
console.log("Item db already loaded, skipping load sequence");
init_func();
return;
}
let request = window.indexedDB.open('item3_db', DB_VERSION);
request.onerror = function() {
console.log("DB failed to open...");
};
request.onsuccess = function() {
(async function() {
db = request.result;
if (!reload) {
console.log("Using stored data...")
load_local(init_func);
}
else {
if (load_in_progress) {
while (!load_complete) {
await sleep(100);
}
console.log("Skipping load...")
init_func();
}
else {
// Not 100% safe... whatever!
load_in_progress = true
console.log("Using new data...")
load(init_func);
}
}
})()
}
request.onupgradeneeded = function(e) {
reload = true;
let db = e.target.result;
try {
db.deleteObjectStore('item3_db');
}
catch (error) {
console.log("Could not delete item DB. This is probably fine");
}
try {
db.deleteObjectStore('set3_db');
}
catch (error) {
console.log("Could not delete set DB. This is probably fine");
}
db.createObjectStore('item3_db');
db.createObjectStore('set3_db');
console.log("DB setup complete...");
}
}
function init_maps() {
//warp
itemMap = new Map();
/* Mapping from item names to set names. */
idMap = new Map();
redirectMap = new Map();
for (const it of itemTypes) {
itemLists.set(it, []);
}
let noneItems = [
["armor", "helmet", "No Helmet"],
["armor", "chestplate", "No Chestplate"],
["armor", "leggings", "No Leggings"],
["armor", "boots", "No Boots"],
["accessory", "ring", "No Ring 1"],
["accessory", "ring", "No Ring 2"],
["accessory", "bracelet", "No Bracelet"],
["accessory", "necklace", "No Necklace"],
["weapon", "dagger", "No Weapon"],
];
for (let i = 0; i < 9; i++) {
let item = Object();
item.slots = 0;
item.category = noneItems[i][0];
item.type = noneItems[i][1];
item.name = noneItems[i][2];
item.displayName = item.name;
item.set = null;
item.quest = null;
item.skillpoints = [0, 0, 0, 0, 0];
item.has_negstat = false;
item.reqs = [0, 0, 0, 0, 0];
item.fixID = true;
item.tier = "Normal";//do not get rid of this @hpp
item.id = 10000 + i;
item.nDam = "0-0";
item.eDam = "0-0";
item.tDam = "0-0";
item.wDam = "0-0";
item.fDam = "0-0";
item.aDam = "0-0";
item.str = 0,
item.dex = 0,
item.int = 0,
item.def = 0,
item.agi = 0,
noneItems[i] = item;
}
items = items.concat(noneItems);
//console.log(items);
for (const item of items) {
if (item.remapID === undefined) {
itemLists.get(item.type).push(item.displayName);
itemMap.set(item.displayName, item);
if (noneItems.includes(item)) {
idMap.set(item.id, "");
}
else {
idMap.set(item.id, item.displayName);
}
}
else {
redirectMap.set(item.id, item.remapID);
}
}
console.log(itemMap);
}

View file

@ -24,11 +24,11 @@ class Powder {
function _p(a,b,c,d,e) { return new Powder(a,b,c,d,e); } //bruh moment function _p(a,b,c,d,e) { return new Powder(a,b,c,d,e); } //bruh moment
let powderStats = [ let powderStats = [
_p(3,6,17,2,1), _p(6,9,21,4,2), _p(8,14,25,8,3), _p(11,16,31,14,5), _p(15,18,38,22,9), _p(18,22,46,30,13), _p(3,6,17,2,1), _p(5,8,21,4,2), _p(6,10,25,8,3), _p(7,10,31,14,5), _p(9,11,38,22,9), _p(11,13,46,30,13),
_p(1,8,9,3,1), _p(1,13,11,5,1), _p(2,18,13,9,2), _p(3,24,17,14,4), _p(3,32,22,20,7), _p(5,40,28,28,10), _p(1,8,9,3,1), _p(1,12,11,5,1), _p(2,15,13,9,2), _p(3,15,17,14,4), _p(4,17,22,20,7), _p(5,20,28,28,10),
_p(3,4,13,3,1), _p(4,7,15,6,1), _p(6,10,17,11,2), _p(8,12,21,18,4), _p(11,14,26,28,7), _p(13,17,32,40,10), _p(3,4,13,3,1), _p(4,6,15,6,1), _p(5,8,17,11,2), _p(6,8,21,18,4), _p(7,10,26,28,7), _p(9,11,32,40,10),
_p(2,5,14,3,1), _p(4,8,16,5,2), _p(6,10,19,9,3), _p(9,13,24,16,5), _p(12,16,30,25,9), _p(15,19,37,36,13), _p(2,5,14,3,1), _p(4,8,16,5,2), _p(5,9,19,9,3), _p(6,9,24,16,5), _p(8,10,30,25,9), _p(10,12,37,36,13),
_p(2,6,11,3,1), _p(4,9,14,6,2), _p(7,10,17,10,3), _p(9,13,22,16,5), _p(13,17,28,24,9), _p(16,18,35,34,13) _p(2,6,11,3,1), _p(3,10,14,6,2), _p(4,11,17,10,3), _p(5,11,22,16,5), _p(7,12,28,24,9), _p(8,14,35,34,13)
]; ];
class PowderIngredient { class PowderIngredient {

View file

@ -1,63 +0,0 @@
let powderIDs = new Map();
let powderNames = new Map();
let _powderID = 0;
for (const x of skp_elements) {
for (let i = 1; i <= 6; ++i) {
// Support both upper and lowercase, I guess.
powderIDs.set(x.toUpperCase()+i, _powderID);
powderIDs.set(x+i, _powderID);
powderNames.set(_powderID, x+i);
_powderID++;
}
}
// Ordering: [dmgMin, dmgMax, convert, defPlus, defMinus (+6 mod 5)]
class Powder {
constructor(min, max, convert, defPlus, defMinus) {
this.min = min;
this.max = max;
this.convert = convert;
this.defPlus = defPlus;
this.defMinus = defMinus;
}
}
function _p(a,b,c,d,e) { return new Powder(a,b,c,d,e); } //bruh moment
let powderStats = [
_p(3,6,17,2,1), _p(5,8,21,4,2), _p(6,10,25,8,3), _p(7,10,31,14,5), _p(9,11,38,22,9), _p(11,13,46,30,13),
_p(1,8,9,3,1), _p(1,12,11,5,1), _p(2,15,13,9,2), _p(3,15,17,14,4), _p(4,17,22,20,7), _p(5,20,28,28,10),
_p(3,4,13,3,1), _p(4,6,15,6,1), _p(5,8,17,11,2), _p(6,8,21,18,4), _p(7,10,26,28,7), _p(9,11,32,40,10),
_p(2,5,14,3,1), _p(4,8,16,5,2), _p(5,9,19,9,3), _p(6,9,24,16,5), _p(8,10,30,25,9), _p(10,12,37,36,13),
_p(2,6,11,3,1), _p(3,10,14,6,2), _p(4,11,17,10,3), _p(5,11,22,16,5), _p(7,12,28,24,9), _p(8,14,35,34,13)
];
class PowderIngredient {
constructor(durability, skpReq) {
this.durability = durability;
this.skpReq = skpReq;
}
}
function _pi(a,b) { return new PowderIngredient(a,b)}
let powderIngreds = [
_pi(-35,0),_pi(-52.5,0),_pi(-70,10),_pi(-91,20),_pi(-112,28),_pi(-133,36)
];
//Ordering: [weapon special name, weapon special effects, armor special name, armor special effects]
class PowderSpecial{
constructor(wSpName, wSpEff, aSpName, aSpEff, cap){
this.weaponSpecialName = wSpName;
this.weaponSpecialEffects = wSpEff;
this.armorSpecialName = aSpName;
this.armorSpecialEffects = aSpEff;
this.cap = cap;
}
}
function _ps(a,b,c,d,e) { return new PowderSpecial(a,b,c,d,e); } //bruh moment
let powderSpecialStats = [
_ps("Quake",new Map([["Radius",[4.4,4.9,5.4,5.9,6.4]], ["Damage",[155,220,285,350,415]] ]),"Rage",new Map([ ["Damage", [0.3,0.4,0.5,0.7,1.0]],["Description", "% " + "\u2764" + " Missing"] ]),400), //e
_ps("Chain Lightning",new Map([ ["Chains", [5,6,7,8,9]], ["Damage", [200,225,250,275,300]] ]),"Kill Streak",new Map([ ["Damage", [3,4.5,6,7.5,9]],["Duration", [5,5,5,5,5]],["Description", "Mob Killed"] ]),200), //t
_ps("Curse",new Map([ ["Duration", [7,7.5,8,8.5,9]],["Damage Boost", [90,120,150,180,210]] ]),"Concentration",new Map([ ["Damage", [1,2,3,4,5]],["Duration",[1,1,1,1,1]],["Description", "Mana Used"] ]),150), //w
_ps("Courage",new Map([ ["Duration", [6,6.5,7,7.5,8]],["Damage", [75,87.5,100,112.5,125]],["Damage Boost", [70,90,110,130,150]] ]),"Endurance",new Map([ ["Damage", [2,3,4,5,6]],["Duration", [8,8,8,8,8]],["Description", "Hit Taken"] ]),200), //f
_ps("Wind Prison",new Map([ ["Duration", [3,3.5,4,4.5,5]],["Damage Boost", [400,450,500,550,600]],["Knockback", [8,12,16,20,24]] ]),"Dodge",new Map([ ["Damage",[2,3,4,5,6]],["Duration",[2,3,4,5,6]],["Description","Near Mobs"] ]),150) //a
];