Merge branch 'dev' into master
107
1_20_ci.json
|
@ -1005,8 +1005,8 @@
|
|||
"int": 50,
|
||||
"def": 0,
|
||||
"agi": 0,
|
||||
"mr": -5,
|
||||
"ms": -5,
|
||||
"mr": -4,
|
||||
"ms": -4,
|
||||
"sdPct": 30,
|
||||
"spPct1": -38,
|
||||
"spPct2": -38,
|
||||
|
@ -4997,7 +4997,7 @@
|
|||
"category": "armor",
|
||||
"lvl": 98,
|
||||
"hp": 3200,
|
||||
"tDef": 200,
|
||||
"tDef": 100,
|
||||
"aDef": -150,
|
||||
"slots": 3,
|
||||
"str": 0,
|
||||
|
@ -5506,13 +5506,15 @@
|
|||
"fDef": 40,
|
||||
"aDef": 40,
|
||||
"slots": 2,
|
||||
"str": 4,
|
||||
"dex": 4,
|
||||
"int": 4,
|
||||
"def": 4,
|
||||
"agi": 4,
|
||||
"sdRaw": 175,
|
||||
"mdRaw": 230,
|
||||
"str": 3,
|
||||
"dex": 3,
|
||||
"int": 3,
|
||||
"def": 3,
|
||||
"agi": 3,
|
||||
"ls": 175,
|
||||
"ms": 2,
|
||||
"lb": 15,
|
||||
"thorns": 20,
|
||||
"id": 10259
|
||||
},
|
||||
{
|
||||
|
@ -5597,11 +5599,6 @@
|
|||
"int": 12,
|
||||
"def": 12,
|
||||
"agi": 12,
|
||||
"eDamPct": 8,
|
||||
"tDamPct": 8,
|
||||
"wDamPct": 8,
|
||||
"fDamPct": 8,
|
||||
"aDamPct": 8,
|
||||
"spPct2": -1,
|
||||
"id": 10262
|
||||
},
|
||||
|
@ -7145,11 +7142,11 @@
|
|||
"category": "weapon",
|
||||
"lvl": 93,
|
||||
"nDam": "0-0",
|
||||
"eDam": "124-140",
|
||||
"tDam": "54-210",
|
||||
"wDam": "94-170",
|
||||
"fDam": "109-115",
|
||||
"aDam": "79-185",
|
||||
"eDam": "120-142",
|
||||
"tDam": "60-202",
|
||||
"wDam": "90-172",
|
||||
"fDam": "105-157",
|
||||
"aDam": "75-187",
|
||||
"slots": 4,
|
||||
"str": 0,
|
||||
"dex": 0,
|
||||
|
@ -9510,7 +9507,7 @@
|
|||
"agi": -550,
|
||||
"ls": 973,
|
||||
"ms": 6,
|
||||
"atkTier": 3,
|
||||
"atkTier": 1,
|
||||
"sdRaw": 342,
|
||||
"mdRaw": 727,
|
||||
"wDamPct": -550,
|
||||
|
@ -10202,73 +10199,5 @@
|
|||
"tDamPct": 30,
|
||||
"aDamPct": -50,
|
||||
"id": 10394
|
||||
},
|
||||
{
|
||||
"tier": "Rare",
|
||||
"type": "helmet",
|
||||
"name": "Dissociation (1.20)",
|
||||
"displayName": "Dissociation (1.20)",
|
||||
"set": null,
|
||||
"quest": null,
|
||||
"classReq": null,
|
||||
"restrict": "1.20 item",
|
||||
"fixID": false,
|
||||
"strReq": 0,
|
||||
"dexReq": 0,
|
||||
"intReq": 0,
|
||||
"defReq": 0,
|
||||
"agiReq": 0,
|
||||
"category": "armor",
|
||||
"lvl": 101,
|
||||
"slots": 0,
|
||||
"str": -35,
|
||||
"dex": 0,
|
||||
"int": -20,
|
||||
"def": -35,
|
||||
"agi": 0,
|
||||
"mr": 2,
|
||||
"hpBonus": 3550,
|
||||
"sdRaw": 300,
|
||||
"mdPct": 60,
|
||||
"tDefPct": 75,
|
||||
"aDefPct": 75,
|
||||
"spRaw3": -1,
|
||||
"id": 10395
|
||||
},
|
||||
{
|
||||
"tier": "Legendary",
|
||||
"type": "leggings",
|
||||
"name": "Anixolytic (1.20)",
|
||||
"displayName": "Anixolytic (1.20)",
|
||||
"set": null,
|
||||
"quest": null,
|
||||
"classReq": null,
|
||||
"restrict": "1.20 item",
|
||||
"fixID": false,
|
||||
"strReq": 35,
|
||||
"dexReq": 40,
|
||||
"intReq": 50,
|
||||
"defReq": 35,
|
||||
"agiReq": 50,
|
||||
"category": "armor",
|
||||
"lvl": 101,
|
||||
"hp": 3880,
|
||||
"eDef": -175,
|
||||
"tDef": 125,
|
||||
"wDef": 150,
|
||||
"fDef": -125,
|
||||
"aDef": 150,
|
||||
"slots": 0,
|
||||
"str": 0,
|
||||
"dex": 15,
|
||||
"int": 10,
|
||||
"def": 0,
|
||||
"agi": 12,
|
||||
"mr": 4,
|
||||
"spRaw1": 1,
|
||||
"spRaw3": 1,
|
||||
"spRaw4": 1,
|
||||
"sprintReg": 13,
|
||||
"id": 10396
|
||||
}
|
||||
]
|
29
build.js
|
@ -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") {
|
||||
|
@ -138,6 +138,10 @@ class Build{
|
|||
|
||||
// For strength boosts like warscream, vanish, etc.
|
||||
this.damageMultiplier = 1.0;
|
||||
this.defenseMultiplier = 1.0;
|
||||
|
||||
// For other external boosts ;-;
|
||||
this.externalStats = externalStats;
|
||||
|
||||
this.initBuildStats();
|
||||
}
|
||||
|
@ -156,7 +160,7 @@ class Build{
|
|||
getSpellCost(spellIdx, cost) {
|
||||
cost = Math.ceil(cost * (1 - skillPointsToPercentage(this.total_skillpoints[2])));
|
||||
cost += this.statMap.get("spRaw"+spellIdx);
|
||||
return Math.max(1, Math.floor(cost * (1 + this.statMap.get("spPct"+spellIdx) / 100)))
|
||||
return Math.max(1, Math.floor(cost * (1 + this.statMap.get("spPct"+spellIdx) / 100)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -173,7 +177,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];
|
||||
|
||||
|
@ -209,19 +213,19 @@ class Build{
|
|||
//EHP
|
||||
let ehp = [totalHp, totalHp];
|
||||
let defMult = classDefenseMultipliers.get(this.weapon.get("type"));
|
||||
ehp[0] /= ((1-def_pct)*(1-agi_pct)*(2-defMult));
|
||||
ehp[1] /= ((1-def_pct)*(2-defMult));
|
||||
ehp[0] /= ((1-def_pct)*(1-agi_pct)*(2-defMult)*(2-this.defenseMultiplier));
|
||||
ehp[1] /= ((1-def_pct)*(2-defMult)*(2-this.defenseMultiplier));
|
||||
defenseStats.push(ehp);
|
||||
//HPR
|
||||
let totalHpr = rawToPct(stats.get("hprRaw"), stats.get("hprPct")/100.);
|
||||
defenseStats.push(totalHpr);
|
||||
//EHPR
|
||||
let ehpr = [totalHpr, totalHpr];
|
||||
ehpr[0] /= ((1-def_pct)*(1-agi_pct)*(2-defMult));
|
||||
ehpr[1] /= ((1-def_pct)*(2-defMult));
|
||||
ehpr[0] /= ((1-def_pct)*(1-agi_pct)*(2-defMult)*(2-this.defenseMultiplier));
|
||||
ehpr[1] /= ((1-def_pct)*(2-defMult)*(2-this.defenseMultiplier));
|
||||
defenseStats.push(ehpr);
|
||||
//skp stats
|
||||
defenseStats.push([def_pct*100, agi_pct*100]);
|
||||
defenseStats.push([ (1 - ((1-def_pct) * (2 - this.defenseMultiplier)))*100, agi_pct*100]);
|
||||
//eledefs - TODO POWDERS
|
||||
let eledefs = [0, 0, 0, 0, 0];
|
||||
for(const i in skp_elements){ //kinda jank but ok
|
||||
|
@ -277,7 +281,16 @@ 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")]);
|
||||
statMap.set("poisonPct", 100);
|
||||
|
||||
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.externalStats.set("poisonPct", 0);
|
||||
this.statMap = statMap;
|
||||
}
|
||||
|
||||
|
|
222
builder.js
|
@ -11,10 +11,11 @@ console.log(url_tag);
|
|||
* END testing section
|
||||
*/
|
||||
|
||||
const BUILD_VERSION = "6.8.6";
|
||||
const BUILD_VERSION = "6.9.2";
|
||||
|
||||
function setTitle() {
|
||||
document.getElementById("header").textContent = "WynnBuilder version "+BUILD_VERSION+" (db version "+DB_VERSION+")";
|
||||
document.getElementById("header").classList.add("funnynumber");
|
||||
}
|
||||
|
||||
setTitle();
|
||||
|
@ -110,8 +111,8 @@ function _ps(a,b,c,d,e) { return new PowderSpecial(a,b,c,d,e); } //bruh moment
|
|||
|
||||
let powderSpecialStats = [
|
||||
_ps("Quake",new Map([["Radius",[5,5.5,6,6.5,7]], ["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", [80,120,160,200,240]] ]),"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", [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("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("Air 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
|
||||
];
|
||||
|
@ -388,10 +389,34 @@ function encodeBuild() {
|
|||
|
||||
function calculateBuild(save_skp, skp){
|
||||
try {
|
||||
for (const boost of ["vanish", "warscream", "yourtotem", "allytotem"]) {
|
||||
let elem = document.getElementById(boost+"-boost");
|
||||
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]);
|
||||
player_build.externalStats.set("poisonPct", player_build.externalStats.get("poisonPct") - 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){
|
||||
updateBoosts("skip");
|
||||
updatePowderSpecials("skip");
|
||||
}
|
||||
//updatePowderSpecials("skip"); //jank pt 1
|
||||
save_skp = (typeof save_skp !== 'undefined') ? save_skp : false;
|
||||
/* TODO: implement level changing
|
||||
Make this entire function prettier
|
||||
|
@ -434,9 +459,8 @@ function calculateBuild(save_skp, skp){
|
|||
i.style.display = "grid";
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
|
@ -484,11 +508,46 @@ function calculateBuild(save_skp, skp){
|
|||
/* Updates all build statistics based on (for now) the skillpoint input fields and then calculates build stats.
|
||||
*/
|
||||
function updateStats() {
|
||||
|
||||
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]);
|
||||
player_build.externalStats.set("poisonPct", player_build.externalStats.get("poisonPct") - 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//WILL BREAK WEBSITE IF NO BUILD HAS BEEN INITIALIZED! @HPP
|
||||
let skillpoints = player_build.total_skillpoints;
|
||||
let delta_total = 0;
|
||||
for (let i in skp_order) {
|
||||
let manual_assigned = getValue(skp_order[i] + "-skp");
|
||||
let value = document.getElementById(skp_order[i] + "-skp").value;
|
||||
let manual_assigned = 0;
|
||||
if (value.includes("+")) {
|
||||
let skp = value.split("+");
|
||||
for (const s of skp) {
|
||||
manual_assigned += parseInt(s,10);
|
||||
}
|
||||
} else {
|
||||
manual_assigned = parseInt(value,10);
|
||||
}
|
||||
let delta = manual_assigned - skillpoints[i];
|
||||
skillpoints[i] = manual_assigned;
|
||||
player_build.base_skillpoints[i] += delta;
|
||||
|
@ -496,36 +555,97 @@ function updateStats() {
|
|||
}
|
||||
player_build.assigned_skillpoints += delta_total;
|
||||
calculateBuildStats();
|
||||
if(player_build){
|
||||
updatePowderSpecials("skip");
|
||||
updateBoosts("skip");
|
||||
}
|
||||
}
|
||||
/* Updates all spell boosts
|
||||
*/
|
||||
function updateBoosts(buttonId) {
|
||||
let elem = document.getElementById(buttonId);
|
||||
let name = buttonId.split("-")[0];
|
||||
if(buttonId !== "skip") {
|
||||
if (elem.classList.contains("toggleOn")) {
|
||||
player_build.damageMultiplier -= damageMultipliers.get(buttonId.split("-")[0]);
|
||||
player_build.damageMultiplier -= damageMultipliers.get(name);
|
||||
if (name === "warscream") {
|
||||
player_build.defenseMultiplier -= .10;
|
||||
}
|
||||
elem.classList.remove("toggleOn");
|
||||
}else{
|
||||
player_build.damageMultiplier += damageMultipliers.get(buttonId.split("-")[0]);
|
||||
player_build.damageMultiplier += damageMultipliers.get(name);
|
||||
if (name === "warscream") {
|
||||
player_build.defenseMultiplier += .10;
|
||||
}
|
||||
elem.classList.add("toggleOn");
|
||||
}
|
||||
updatePowderSpecials("skip"); //jank pt 1
|
||||
} else {
|
||||
for (const [key, value] of damageMultipliers) {
|
||||
let elem = document.getElementById(key + "-boost")
|
||||
if (elem.classList.contains("toggleOn")) {
|
||||
elem.classList.remove("toggleOn");
|
||||
player_build.damageMultiplier -= value;
|
||||
if (key === "warscream") { player_build.defenseMultiplier -= .10 }
|
||||
}
|
||||
}
|
||||
}
|
||||
calculateBuildStats();
|
||||
}
|
||||
|
||||
/* Updates all powder special boosts
|
||||
*/
|
||||
function updatePowderSpecials(buttonId){
|
||||
//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"];
|
||||
let powderSpecials = []; // [ [special, power], [special, power]]
|
||||
|
||||
|
||||
if(name !== "skip"){
|
||||
let elem = document.getElementById(buttonId);
|
||||
if (elem.classList.contains("toggleOn")) {
|
||||
if (elem.classList.contains("toggleOn")) { //toggle the pressed button off
|
||||
elem.classList.remove("toggleOn");
|
||||
}else {
|
||||
for (let i = 1;i < 6; i++) {
|
||||
document.getElementById(name + "-" + i).classList.remove("toggleOn");
|
||||
let special = powderSpecialStats[specialNames.indexOf(name.replace("_", " "))];
|
||||
if (special.weaponSpecialEffects.has("Damage Boost")) {
|
||||
name = name.replace("_", " ");
|
||||
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]);
|
||||
player_build.externalStats.set("poisonPct", player_build.externalStats.get("poisonPct") - special.weaponSpecialEffects.get("Damage Boost")[power-1]);
|
||||
//poison?
|
||||
} else if (name === "Air Prison") {
|
||||
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 {
|
||||
for (let i = 1;i < 6; i++) { //toggle all pressed buttons of the same powder special off
|
||||
//name is same, power is i
|
||||
if(document.getElementById(name.replace(" ", "_") + "-" + i).classList.contains("toggleOn")) {
|
||||
document.getElementById(name.replace(" ", "_") + "-" + i).classList.remove("toggleOn");
|
||||
let special = powderSpecialStats[specialNames.indexOf(name.replace("_", " "))];
|
||||
if (special.weaponSpecialEffects.has("Damage Boost")) {
|
||||
name = name.replace("_", " "); //might be redundant
|
||||
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]);
|
||||
player_build.externalStats.set("poisonPct", player_build.externalStats.get("poisonPct") - 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//toggle the pressed button on
|
||||
elem.classList.add("toggleOn");
|
||||
}
|
||||
}
|
||||
|
||||
for (const sName of specialNames) {
|
||||
for (let i = 1;i < 6; i++) {
|
||||
if (document.getElementById(sName.replace(" ","_") + "-" + i).classList.contains("toggleOn")) {
|
||||
|
@ -536,8 +656,26 @@ function updatePowderSpecials(buttonId){
|
|||
}
|
||||
}
|
||||
|
||||
//console.log(powderSpecials);
|
||||
displayPowderSpecials(document.getElementById("powder-special-stats"), powderSpecials);
|
||||
|
||||
if (name !== "skip") {
|
||||
let elem = document.getElementById(buttonId);
|
||||
if (elem.classList.contains("toggleOn")) {
|
||||
let special = powderSpecialStats[specialNames.indexOf(name.replace("_", " "))];
|
||||
if (special["weaponSpecialEffects"].has("Damage Boost")) {
|
||||
let name = special["weaponSpecialName"];
|
||||
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]);
|
||||
player_build.externalStats.set("poisonPct", player_build.externalStats.get("poisonPct") + special.weaponSpecialEffects.get("Damage Boost")[power-1]);
|
||||
} else if (name === "Air Prison") {
|
||||
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.
|
||||
|
@ -563,38 +701,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);
|
||||
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");
|
||||
|
@ -604,10 +737,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");
|
||||
|
@ -644,8 +776,9 @@ function calculateBuildStats() {
|
|||
displayExpandedItem(player_build.items[i], buildFields[i]);
|
||||
}
|
||||
|
||||
displayBuildStats(player_build, "build-overall-stats");
|
||||
displaySetBonuses(player_build, "set-info");
|
||||
displayBuildStats("build-overall-stats",player_build);
|
||||
displaySetBonuses("set-info",player_build);
|
||||
displayNextCosts("int-info",player_build);
|
||||
|
||||
let meleeStats = player_build.getMeleeStats();
|
||||
displayMeleeDamage(document.getElementById("build-melee-stats"), document.getElementById("build-melee-statsAvg"), meleeStats);
|
||||
|
@ -703,6 +836,7 @@ function resetFields(){
|
|||
setValue("agi-skp", "0");
|
||||
setValue("level-choice", "");
|
||||
location.hash = "";
|
||||
calculateBuild();
|
||||
}
|
||||
|
||||
load_init(init);
|
||||
|
|
193
clean.json
|
@ -276009,6 +276009,199 @@
|
|||
"gXp": 0,
|
||||
"gSpd": 0,
|
||||
"id": 10397
|
||||
},
|
||||
{
|
||||
"tier": "Unique",
|
||||
"type": "boots",
|
||||
"name": "Boots of Blue Stone (1.20)",
|
||||
"displayName": "Boots of Blue Stone (1.20)",
|
||||
"set": null,
|
||||
"quest": null,
|
||||
"classReq": null,
|
||||
"restrict": "1.20 item",
|
||||
"fixID": false,
|
||||
"strReq": 20,
|
||||
"dexReq": 20,
|
||||
"intReq": 20,
|
||||
"defReq": 20,
|
||||
"agiReq": 20,
|
||||
"category": "armor",
|
||||
"lvl": 82,
|
||||
"hp": 2000,
|
||||
"eDef": 30,
|
||||
"tDef": 30,
|
||||
"wDef": 30,
|
||||
"fDef": 30,
|
||||
"aDef": 30,
|
||||
"slots": 2,
|
||||
"str": 5,
|
||||
"dex": 5,
|
||||
"int": 5,
|
||||
"def": 5,
|
||||
"agi": 5,
|
||||
"sdRaw": 140,
|
||||
"mdRaw": 180,
|
||||
"eDamPct": 13,
|
||||
"tDamPct": 13,
|
||||
"wDamPct": 13,
|
||||
"fDamPct": 13,
|
||||
"aDamPct": 13,
|
||||
"sprint": 13,
|
||||
"sprintReg": 13,
|
||||
"id": 10398
|
||||
},
|
||||
{
|
||||
"tier": "Rare",
|
||||
"type": "relik",
|
||||
"name": "Estuarine (1.20)",
|
||||
"displayName": "Estuarine (1.20)",
|
||||
"set": null,
|
||||
"quest": null,
|
||||
"classReq": null,
|
||||
"restrict": "1.20 item",
|
||||
"fixID": false,
|
||||
"strReq": 28,
|
||||
"dexReq": 0,
|
||||
"intReq": 32,
|
||||
"defReq": 0,
|
||||
"agiReq": 0,
|
||||
"atkSpd": "NORMAL",
|
||||
"category": "weapon",
|
||||
"lvl": 71,
|
||||
"nDam": "70-80",
|
||||
"eDam": "100-110",
|
||||
"tDam": "0-0",
|
||||
"wDam": "71-85",
|
||||
"fDam": "0-0",
|
||||
"aDam": "0-0",
|
||||
"slots": 3,
|
||||
"str": 0,
|
||||
"dex": 0,
|
||||
"int": 8,
|
||||
"def": 0,
|
||||
"agi": 0,
|
||||
"mr": 1,
|
||||
"spd": -12,
|
||||
"mdPct": -20,
|
||||
"mdRaw": 130,
|
||||
"wDamPct": 35,
|
||||
"eDefPct": 30,
|
||||
"id": 10399
|
||||
},
|
||||
{
|
||||
"tier": "Rare",
|
||||
"type": "helmet",
|
||||
"name": "The Modulator (1.20)",
|
||||
"displayName": "The Modulator (1.20)",
|
||||
"set": null,
|
||||
"quest": null,
|
||||
"classReq": null,
|
||||
"restrict": "1.20 item",
|
||||
"fixID": true,
|
||||
"strReq": 25,
|
||||
"dexReq": 25,
|
||||
"intReq": 25,
|
||||
"defReq": 25,
|
||||
"agiReq": 25,
|
||||
"category": "armor",
|
||||
"lvl": 88,
|
||||
"hp": 2500,
|
||||
"slots": 5,
|
||||
"str": 8,
|
||||
"dex": 8,
|
||||
"int": 8,
|
||||
"def": 8,
|
||||
"agi": 8,
|
||||
"spd": 15,
|
||||
"eDefPct": 30,
|
||||
"tDefPct": 30,
|
||||
"wDefPct": 30,
|
||||
"fDefPct": 30,
|
||||
"aDefPct": 30,
|
||||
"id": 10400
|
||||
},
|
||||
{
|
||||
"tier": "Rare",
|
||||
"type": "dagger",
|
||||
"name": "Sreggad (1.20)",
|
||||
"displayName": "Sreggad (1.20)",
|
||||
"set": null,
|
||||
"quest": null,
|
||||
"classReq": null,
|
||||
"restrict": "1.20 item",
|
||||
"fixID": false,
|
||||
"strReq": 0,
|
||||
"dexReq": 0,
|
||||
"intReq": 0,
|
||||
"defReq": 0,
|
||||
"agiReq": 0,
|
||||
"atkSpd": "SUPER_SLOW",
|
||||
"category": "weapon",
|
||||
"lvl": 85,
|
||||
"nDam": "0-0",
|
||||
"eDam": "0-0",
|
||||
"tDam": "0-0",
|
||||
"wDam": "0-0",
|
||||
"fDam": "0-0",
|
||||
"aDam": "0-0",
|
||||
"slots": 2,
|
||||
"str": 0,
|
||||
"dex": 0,
|
||||
"int": 0,
|
||||
"def": 20,
|
||||
"agi": 20,
|
||||
"hprRaw": 173,
|
||||
"ls": 354,
|
||||
"thorns": 333,
|
||||
"hpBonus": 2500,
|
||||
"ref": 333,
|
||||
"eDefPct": 50,
|
||||
"tDefPct": 50,
|
||||
"wDefPct": 50,
|
||||
"fDefPct": 50,
|
||||
"aDefPct": 50,
|
||||
"id": 10401
|
||||
},
|
||||
{
|
||||
"tier": "Mythic",
|
||||
"type": "dagger",
|
||||
"name": "Nullification (1.20)",
|
||||
"displayName": "Nullification (1.20)",
|
||||
"set": null,
|
||||
"quest": null,
|
||||
"classReq": null,
|
||||
"restrict": "1.20 item",
|
||||
"fixID": false,
|
||||
"strReq": 30,
|
||||
"dexReq": 30,
|
||||
"intReq": 30,
|
||||
"defReq": 30,
|
||||
"agiReq": 30,
|
||||
"atkSpd": "FAST",
|
||||
"category": "weapon",
|
||||
"lvl": 95,
|
||||
"nDam": "0-0",
|
||||
"eDam": "80-88",
|
||||
"tDam": "20-148",
|
||||
"wDam": "65-103",
|
||||
"fDam": "50-118",
|
||||
"aDam": "35-133",
|
||||
"slots": 3,
|
||||
"str": 0,
|
||||
"dex": 0,
|
||||
"int": 0,
|
||||
"def": 50,
|
||||
"agi": 0,
|
||||
"ls": 495,
|
||||
"ms": 3,
|
||||
"poison": -7000,
|
||||
"ref": 80,
|
||||
"eDefPct": 143,
|
||||
"tDefPct": 143,
|
||||
"wDefPct": 143,
|
||||
"fDefPct": 143,
|
||||
"aDefPct": 143,
|
||||
"id": 10402
|
||||
}
|
||||
],
|
||||
"sets": {
|
||||
|
|
|
@ -1,10 +1,27 @@
|
|||
const damageMultipliers = new Map([ ["allytotem", .15], ["yourtotem", .35], ["vanish", 0.80], ["warscream", 0.10] ]);
|
||||
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.
|
||||
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,16 +83,16 @@ 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) {
|
||||
let damageBoost = Math.max(1 + skillBoost[i] + staticBoost, 0);
|
||||
let damageBoost = 1 + skillBoost[i] + staticBoost;
|
||||
damages_results.push([
|
||||
Math.max(damages[i][0] * damageBoost * damageMult, 0), // Normal min
|
||||
Math.max(damages[i][1] * damageBoost * damageMult, 0), // Normal max
|
||||
Math.max(damages[i][0] * (1 + damageBoost) * damageMult, 0), // Crit min
|
||||
Math.max(damages[i][1] * (1 + damageBoost) * 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
|
||||
]);
|
||||
totalDamNorm[0] += damages_results[i][0];
|
||||
totalDamNorm[1] += damages_results[i][1];
|
||||
|
@ -191,13 +208,13 @@ const spell_table = {
|
|||
],
|
||||
"powder": [ //This is how instant-damage powder specials are implemented. To view time-boosted damage powder specials (curse, 2nd courage, air prison, view @TODO)
|
||||
{ title: "Quake", cost: 0, parts:[
|
||||
{type: "damage", multiplier: [155, 220, 285, 350, 415], conversion: [0,100,0,0,0,0], summary: true},
|
||||
{ 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: [
|
||||
{type: "damage", multiplier: [80, 120, 160, 200, 240], conversion: [0,0,100,0,0,0], summary: true},
|
||||
{ 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: [
|
||||
{type: "damage", multiplier: [75,87.5,100,112.5,125], conversion: [0,0,0,0,100,0], summary: true},
|
||||
]},
|
||||
{ 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]
|
||||
]
|
||||
};
|
||||
|
|
293
display.js
|
@ -55,8 +55,8 @@ function expandItem(item, powders){
|
|||
//console.log(powderStats[id]);
|
||||
let powder = powderStats[id];
|
||||
let name = powderNames.get(id);
|
||||
expandedItem.set(name.charAt(0) + "Def", expandedItem.get(name.charAt(0)+"Def") + powder["defPlus"]);
|
||||
expandedItem.set(skp_elements[(skp_elements.indexOf(name.charAt(0)) + 6 )% 5] + "Def", expandedItem.get(skp_elements[(skp_elements.indexOf(name.charAt(0)) + 6 )% 5]+"Def") - powder["defMinus"]);
|
||||
expandedItem.set(name.charAt(0) + "Def", (expandedItem.get(name.charAt(0)+"Def") || 0) + powder["defPlus"]);
|
||||
expandedItem.set(skp_elements[(skp_elements.indexOf(name.charAt(0)) + 4 )% 5] + "Def", (expandedItem.get(skp_elements[(skp_elements.indexOf(name.charAt(0)) + 4 )% 5]+"Def") || 0) - powder["defMinus"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ function apply_elemental_format(p_elem, id, suffix) {
|
|||
p_elem.appendChild(i_elem2);
|
||||
}
|
||||
|
||||
function displaySetBonuses(build, parent_id) {
|
||||
function displaySetBonuses(parent_id,build) {
|
||||
setHTML(parent_id, "");
|
||||
let parent_div = document.getElementById(parent_id);
|
||||
|
||||
|
@ -134,7 +134,7 @@ function displaySetBonuses(build, parent_id) {
|
|||
}
|
||||
}
|
||||
|
||||
function displayBuildStats(build, parent_id){
|
||||
function displayBuildStats(parent_id,build){
|
||||
// Commands to "script" the creation of nice formatting.
|
||||
// #commands create a new element.
|
||||
// !elemental is some janky hack for elemental damage.
|
||||
|
@ -246,6 +246,9 @@ function displayBuildStats(build, parent_id){
|
|||
if (reversedIDs.filter(e => e !== "atkTier").includes(id)) {
|
||||
style === "positive" ? style = "negative" : style = "positive";
|
||||
}
|
||||
if (id === "poison" && id_val > 0) {
|
||||
id_val = Math.round(id_val*(build.statMap.get("poisonPct") + build.externalStats.get("poisonPct"))/100);
|
||||
}
|
||||
displayFixedID(active_elem, id, id_val, elemental_format, style);
|
||||
if (id === "poison" && id_val > 0) {
|
||||
let style = "positive";
|
||||
|
@ -279,7 +282,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) {
|
||||
|
@ -290,6 +293,7 @@ function displayExpandedItem(item, parent_id){
|
|||
let display_commands = [
|
||||
"#cdiv",
|
||||
"displayName",
|
||||
//"type", //REPLACE THIS WITH SKIN
|
||||
"#ldiv",
|
||||
"atkSpd",
|
||||
"#ldiv",
|
||||
|
@ -404,6 +408,18 @@ function displayExpandedItem(item, parent_id){
|
|||
if (item.get("tier") !== " ") {
|
||||
p_elem.classList.add(item.get("tier"));
|
||||
}
|
||||
/*let validTypes = ["helmet", "chestplate", "leggings", "boots", "relik", "wand", "bow", "spear", "dagger", "ring", "bracelet", "necklace"];
|
||||
if (item.has("type") && validTypes.includes(item.get("type"))) {
|
||||
p = document.createElement("p");
|
||||
img = document.createElement("img");
|
||||
img.src = "./media/items/generic-"+item.get("type")+".png";
|
||||
img.alt = "image no display :(";
|
||||
img.classList.add("center");
|
||||
p.append(img);
|
||||
p.classList.add("itemp");
|
||||
|
||||
p_elem.append(p);
|
||||
}*/
|
||||
} else if (skp_order.includes(id)) { //id = str, dex, int, def, or agi
|
||||
p_elem.textContent = "";
|
||||
p_elem.classList.add("itemtable");
|
||||
|
@ -540,6 +556,80 @@ function displayExpandedItem(item, parent_id){
|
|||
}
|
||||
}
|
||||
|
||||
function displayNextCosts(parent_id, build) {
|
||||
let p_elem = document.getElementById(parent_id);
|
||||
let int = build.total_skillpoints[2];
|
||||
let spells = spell_table[build.weapon.get("type")];
|
||||
|
||||
p_elem.textContent = "";
|
||||
|
||||
let title = document.createElement("p");
|
||||
title.classList.add("title");
|
||||
title.classList.add("Normal");
|
||||
title.textContent = "Next Spell Costs";
|
||||
|
||||
let int_title = document.createElement("p");
|
||||
int_title.classList.add("itemp");
|
||||
int_title.textContent = int + " Intelligence points.";
|
||||
|
||||
p_elem.append(title);
|
||||
p_elem.append(int_title);
|
||||
|
||||
for (const spell of spells) { //warp
|
||||
let spellp = document.createElement("p");
|
||||
let spelltitle = document.createElement("p");
|
||||
spelltitle.classList.add("itemp");
|
||||
spelltitle.textContent = spell.title;
|
||||
spellp.appendChild(spelltitle);
|
||||
let row = document.createElement("p");
|
||||
row.classList.add("itemp");
|
||||
let init_cost = document.createElement("b");
|
||||
init_cost.textContent = build.getSpellCost(spells.indexOf(spell) + 1, spell.cost);
|
||||
init_cost.classList.add("Mana");
|
||||
let arrow = document.createElement("b");
|
||||
arrow.textContent = "\u279C";
|
||||
let next_cost = document.createElement("b");
|
||||
next_cost.textContent = (init_cost.textContent === "1" ? 1 : build.getSpellCost(spells.indexOf(spell) + 1, spell.cost) - 1);
|
||||
next_cost.classList.add("Mana");
|
||||
let int_needed = document.createElement("b");
|
||||
if (init_cost.textContent === "1") {
|
||||
int_needed.textContent = ": n/a (+0)";
|
||||
}else { //do math
|
||||
let target = build.getSpellCost(spells.indexOf(spell) + 1, spell.cost) - 1;
|
||||
let needed = int;
|
||||
let noUpdate = false;
|
||||
//forgive me... I couldn't inverse ceil, floor, and max.
|
||||
while (build.getSpellCost(spells.indexOf(spell) + 1, spell.cost) > target) {
|
||||
if(needed > 150) {
|
||||
noUpdate = true;
|
||||
break;
|
||||
}
|
||||
needed++;
|
||||
build.total_skillpoints[2] = needed;
|
||||
}
|
||||
let missing = needed - int;
|
||||
//in rare circumstances, the next spell cost can jump.
|
||||
if (noUpdate) {
|
||||
next_cost.textContent = (init_cost.textContent === "1" ? 1 : build.getSpellCost(spells.indexOf(spell) + 1, spell.cost)-1);
|
||||
}else {
|
||||
next_cost.textContent = (init_cost.textContent === "1" ? 1 : build.getSpellCost(spells.indexOf(spell) + 1, spell.cost));
|
||||
}
|
||||
|
||||
|
||||
build.total_skillpoints[2] = int;//forgive me pt 2
|
||||
int_needed.textContent = ": " + (needed > 150 ? ">150" : needed) + " int (+" + (needed > 150 ? "n/a" : missing) + ")";
|
||||
}
|
||||
|
||||
row.appendChild(init_cost);
|
||||
row.appendChild(arrow);
|
||||
row.appendChild(next_cost);
|
||||
row.appendChild(int_needed);
|
||||
spellp.appendChild(row);
|
||||
|
||||
p_elem.append(spellp);
|
||||
}
|
||||
}
|
||||
|
||||
function displayFixedID(active, id, value, elemental_format, style) {
|
||||
if (style) {
|
||||
/*if(reversedIDs.filter(e => e !== "atkTier").includes(id)){
|
||||
|
@ -612,8 +702,15 @@ function displayPoisonDamage(overallparent_elem, build) {
|
|||
|
||||
let overallpoisonDamage = document.createElement("p");
|
||||
overallpoisonDamage.classList.add("itemp");
|
||||
let poison_tick = Math.floor(build.statMap.get("poison") * (1+skillPointsToPercentage(build.total_skillpoints[0]))/3);
|
||||
overallpoisonDamage.textContent = "Poison Tick: " + Math.max(poison_tick,0);
|
||||
let overallpoisonDamageFirst = document.createElement("b");
|
||||
let overallpoisonDamageSecond = document.createElement("b");
|
||||
let poison_tick = Math.round(build.statMap.get("poison") * (1+skillPointsToPercentage(build.total_skillpoints[0])) * (build.statMap.get("poisonPct") + build.externalStats.get("poisonPct"))/100 /3);
|
||||
overallpoisonDamageFirst.textContent = "Poison Tick: ";
|
||||
overallpoisonDamageSecond.textContent = Math.max(poison_tick,0);
|
||||
overallpoisonDamageSecond.classList.add("Damage");
|
||||
|
||||
overallpoisonDamage.appendChild(overallpoisonDamageFirst);
|
||||
overallpoisonDamage.appendChild(overallpoisonDamageSecond);
|
||||
overallparent_elem.append(overallpoisonDamage);
|
||||
overallparent_elem.append(document.createElement("br"));
|
||||
}
|
||||
|
@ -665,7 +762,15 @@ function displayMeleeDamage(parent_elem, overallparent_elem, meleeStats){
|
|||
//overall average DPS
|
||||
let overallaverageDamage = document.createElement("p");
|
||||
overallaverageDamage.classList.add("itemp");
|
||||
overallaverageDamage.textContent = "Average DPS: " + stats[10];
|
||||
let overallaverageDamageFirst = document.createElement("b");
|
||||
overallaverageDamageFirst.textContent = "Average DPS: "
|
||||
|
||||
let overallaverageDamageSecond = document.createElement("b");
|
||||
overallaverageDamageSecond.classList.add("Damage");
|
||||
overallaverageDamageSecond.textContent = stats[10];
|
||||
overallaverageDamage.appendChild(overallaverageDamageFirst);
|
||||
overallaverageDamage.appendChild(overallaverageDamageSecond);
|
||||
|
||||
overallparent_elem.append(overallaverageDamage);
|
||||
overallparent_elem.append(document.createElement("br"));
|
||||
|
||||
|
@ -681,7 +786,13 @@ function displayMeleeDamage(parent_elem, overallparent_elem, meleeStats){
|
|||
let overallatkSpd = document.createElement("p");
|
||||
overallatkSpd.classList.add("center");
|
||||
overallatkSpd.classList.add("itemp");
|
||||
overallatkSpd.textContent = "Attack Speed: " + attackSpeeds[stats[11]];
|
||||
let overallatkSpdFirst = document.createElement("b");
|
||||
overallatkSpdFirst.textContent = "Attack Speed: ";
|
||||
let overallatkSpdSecond = document.createElement("b");
|
||||
overallatkSpdSecond.classList.add("Damage");
|
||||
overallatkSpdSecond.textContent = attackSpeeds[stats[11]];
|
||||
overallatkSpd.appendChild(overallatkSpdFirst);
|
||||
overallatkSpd.appendChild(overallatkSpdSecond);
|
||||
overallparent_elem.append(overallatkSpd);
|
||||
overallparent_elem.append(document.createElement("br"));
|
||||
|
||||
|
@ -714,7 +825,14 @@ function displayMeleeDamage(parent_elem, overallparent_elem, meleeStats){
|
|||
//overall average DPS
|
||||
let singleHitDamage = document.createElement("p");
|
||||
singleHitDamage.classList.add("itemp");
|
||||
singleHitDamage.textContent = "Single Hit Average: " + stats[12].toFixed(2);
|
||||
let singleHitDamageFirst = document.createElement("b");
|
||||
singleHitDamageFirst.textContent = "Single Hit Average: ";
|
||||
let singleHitDamageSecond = document.createElement("b");
|
||||
singleHitDamageSecond.classList.add("Damage");
|
||||
singleHitDamageSecond.textContent = stats[12].toFixed(2);
|
||||
|
||||
singleHitDamage.appendChild(singleHitDamageFirst);
|
||||
singleHitDamage.appendChild(singleHitDamageSecond);
|
||||
overallparent_elem.append(singleHitDamage);
|
||||
overallparent_elem.append(document.createElement("br"));
|
||||
|
||||
|
@ -950,12 +1068,14 @@ function displayDefenseStats(parent_elem, build, insertSummary){
|
|||
|
||||
parent_elem.append(statsTable);
|
||||
}
|
||||
function displayPowderSpecials(parent_elem, powderSpecials) {
|
||||
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 it warp
|
||||
//iterate through the special and display its effects.
|
||||
let powder_special = document.createElement("p");
|
||||
powder_special.classList.add("left");
|
||||
let specialSuffixes = new Map([ ["Duration", " sec"], ["Radius", " blocks"], ["Chains", ""], ["Damage", "%"], ["Damage Boost", "%"], ["Knockback", " blocks"] ]);
|
||||
|
@ -969,7 +1089,7 @@ function displayPowderSpecials(parent_elem, powderSpecials) {
|
|||
specialEffects.classList.add("nocolor");
|
||||
let effects = special[0]["weaponSpecialEffects"];
|
||||
let power = special[1];
|
||||
specialTitle.textContent = special[0]["weaponSpecialName"] + " " + power;
|
||||
specialTitle.textContent = special[0]["weaponSpecialName"] + " " + Math.floor((power-1)*0.5 + 4) + (power % 2 == 0 ? ".5" : "");
|
||||
for (const [key,value] of effects) {
|
||||
let effect = document.createElement("p");
|
||||
effect.classList.add("itemp");
|
||||
|
@ -977,35 +1097,99 @@ function displayPowderSpecials(parent_elem, powderSpecials) {
|
|||
if(key === "Damage"){
|
||||
effect.textContent += elementIcons[powderSpecialStats.indexOf(special[0])];
|
||||
}
|
||||
if (powderSpecials.indexOf(special[0]) == 2) {
|
||||
effect.textContent += " / Mana Used";
|
||||
if(special[0]["weaponSpecialName"] === "Air Prison" && key === "Damage Boost") {
|
||||
effect.textContent += " (only 1st hit)";
|
||||
}
|
||||
specialEffects.appendChild(effect);
|
||||
}
|
||||
//specialTitle.textContent = special["weaponSpecialName"];
|
||||
/*
|
||||
if (element !== "") {//powder special is "[e,t,w,f,a]+[0,1,2,3,4]"
|
||||
let powderSpecial = powderSpecialStats[ skp_elements.indexOf(element)];
|
||||
let effects;
|
||||
if (item.get("category") === "weapon") {//weapon
|
||||
|
||||
}else if (item.get("category") === "armor") {//armor
|
||||
effects = powderSpecial["armorSpecialEffects"];
|
||||
specialTitle.textContent += powderSpecial["armorSpecialName"] + ": ";
|
||||
}
|
||||
|
||||
specialTitle.append(specialEffects);
|
||||
powder_special.appendChild(specialTitle);
|
||||
|
||||
|
||||
parent_div.append(powder_special);
|
||||
}
|
||||
*/
|
||||
powder_special.appendChild(specialTitle);
|
||||
powder_special.appendChild(specialEffects);
|
||||
parent_elem.appendChild(powder_special);
|
||||
|
||||
//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, 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") + 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 = [];
|
||||
|
||||
let totalDamNormal = _results[0];
|
||||
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 critAverage = (totalDamCrit[0]+totalDamCrit[1])/2 || 0;
|
||||
let averageDamage = (1-critChance)*nonCritAverage+critChance*critAverage || 0;
|
||||
|
||||
let averageLabel = document.createElement("p");
|
||||
averageLabel.textContent = "Average: "+averageDamage.toFixed(2);
|
||||
averageLabel.classList.add("damageSubtitle");
|
||||
specialDamage.append(averageLabel);
|
||||
|
||||
|
||||
let nonCritLabel = document.createElement("p");
|
||||
nonCritLabel.textContent = "Non-Crit Average: "+nonCritAverage.toFixed(2);
|
||||
nonCritLabel.classList.add("damageSubtitle");
|
||||
specialDamage.append(nonCritLabel);
|
||||
|
||||
for (let i = 0; i < 6; i++){
|
||||
if (results[i][1] > 0){
|
||||
let p = document.createElement("p");
|
||||
p.classList.add("damagep");
|
||||
p.classList.add(damageClasses[i]);
|
||||
p.textContent = results[i][0]+"-"+results[i][1];
|
||||
specialDamage.append(p);
|
||||
}
|
||||
}
|
||||
let normalDamage = document.createElement("p");
|
||||
normalDamage.textContent = "Total: " + totalDamNormal[0].toFixed(2) + "-" + totalDamNormal[1].toFixed(2);
|
||||
normalDamage.classList.add("itemp");
|
||||
specialDamage.append(normalDamage);
|
||||
|
||||
let nonCritChanceLabel = document.createElement("p");
|
||||
nonCritChanceLabel.textContent = "Non-Crit Chance: " + ((1-critChance)*100).toFixed(2) + "%";
|
||||
specialDamage.append(nonCritChanceLabel);
|
||||
|
||||
let critLabel = document.createElement("p");
|
||||
critLabel.textContent = "Crit Average: "+critAverage.toFixed(2);
|
||||
critLabel.classList.add("damageSubtitle");
|
||||
|
||||
specialDamage.append(critLabel);
|
||||
for (let i = 0; i < 6; i++){
|
||||
if (results[i][1] > 0){
|
||||
let p = document.createElement("p");
|
||||
p.classList.add("damagep");
|
||||
p.classList.add(damageClasses[i]);
|
||||
p.textContent = results[i][2]+"-"+results[i][3];
|
||||
specialDamage.append(p);
|
||||
}
|
||||
}
|
||||
let critDamage = document.createElement("p");
|
||||
critDamage.textContent = "Total: " + totalDamCrit[0].toFixed(2) + "-" + totalDamCrit[1].toFixed(2);
|
||||
critDamage.classList.add("itemp");
|
||||
specialDamage.append(critDamage);
|
||||
|
||||
let critChanceLabel = document.createElement("p");
|
||||
critChanceLabel.textContent = "Crit Chance: " + (critChance*100).toFixed(2) + "%";
|
||||
specialDamage.append(critChanceLabel);
|
||||
|
||||
save_damages.push(averageDamage);
|
||||
|
||||
powder_special.append(specialDamage);
|
||||
}
|
||||
|
||||
parent_elem.appendChild(powder_special);
|
||||
}
|
||||
}
|
||||
function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spellIdx) {
|
||||
parent_elem.textContent = "";
|
||||
|
@ -1022,7 +1206,18 @@ function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spell
|
|||
|
||||
if (spellIdx != 0) {
|
||||
title_elem.textContent = spell.title + " (" + build.getSpellCost(spellIdx, spell.cost) + ")";
|
||||
title_elemavg.textContent = spell.title + " (" + build.getSpellCost(spellIdx, spell.cost) + ")";
|
||||
let first = document.createElement("b");
|
||||
first.textContent = spell.title + " (";
|
||||
title_elemavg.appendChild(first);
|
||||
let second = document.createElement("b");
|
||||
second.textContent = build.getSpellCost(spellIdx, spell.cost);
|
||||
second.classList.add("Mana");
|
||||
title_elemavg.appendChild(second);
|
||||
let fourth = document.createElement("b");
|
||||
fourth.textContent = ")";
|
||||
title_elemavg.appendChild(fourth);
|
||||
|
||||
//title_elemavg.textContent = spell.title + " (" + build.getSpellCost(spellIdx, spell.cost) + ")";
|
||||
}
|
||||
else {
|
||||
title_elem.textContent = spell.title;
|
||||
|
@ -1042,6 +1237,7 @@ function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spell
|
|||
parent_elem.append(part_div);
|
||||
|
||||
let part_divavg = document.createElement("p");
|
||||
//part_divavg.classList.add("Normal");
|
||||
overallparent_elem.append(part_divavg);
|
||||
|
||||
let subtitle_elem = document.createElement("p");
|
||||
|
@ -1054,10 +1250,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];
|
||||
|
@ -1077,7 +1273,13 @@ function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spell
|
|||
|
||||
if (part.summary == true) {
|
||||
let overallaverageLabel = document.createElement("p");
|
||||
overallaverageLabel.textContent = "Average: "+averageDamage.toFixed(2);
|
||||
let first = document.createElement("b");
|
||||
let second = document.createElement("b");
|
||||
first.textContent = "Average: ";
|
||||
second.textContent = averageDamage.toFixed(2);
|
||||
overallaverageLabel.appendChild(first);
|
||||
overallaverageLabel.appendChild(second);
|
||||
second.classList.add("Damage");
|
||||
overallaverageLabel.classList.add("damageSubtitle");
|
||||
part_divavg.append(overallaverageLabel);
|
||||
}
|
||||
|
@ -1122,7 +1324,8 @@ function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spell
|
|||
if (part.summary == true) {
|
||||
let overallhealLabel = document.createElement("p");
|
||||
overallhealLabel.textContent = heal_amount;
|
||||
overallhealLabel.classList.add("damagep")
|
||||
overallhealLabel.classList.add("damagep");
|
||||
overallhealLabel.classList.add("Set");
|
||||
part_divavg.append(overallhealLabel);
|
||||
}
|
||||
}
|
||||
|
@ -1137,8 +1340,16 @@ function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spell
|
|||
part_div.append(averageLabel);
|
||||
|
||||
let overallaverageLabel = document.createElement("p");
|
||||
overallaverageLabel.textContent = "Average: "+total_damage.toFixed(2);
|
||||
overallaverageLabel.classList.add("damageSubtitle");
|
||||
let overallaverageLabelFirst = document.createElement("b");
|
||||
let overallaverageLabelSecond = document.createElement("b");
|
||||
overallaverageLabelFirst.textContent = "Average: ";
|
||||
overallaverageLabelSecond.textContent = total_damage.toFixed(2);
|
||||
overallaverageLabelSecond.classList.add("Damage");
|
||||
|
||||
|
||||
overallaverageLabel.appendChild(overallaverageLabelFirst);
|
||||
overallaverageLabel.appendChild(overallaverageLabelSecond);
|
||||
part_divavg.append(overallaverageLabel);
|
||||
}
|
||||
}
|
||||
|
|
34
index.html
|
@ -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">
|
||||
|
@ -185,28 +185,33 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button class = "button" id = "vanish-boost" onclick = "updateBoosts('vanish-boost')">
|
||||
<button class = "button-narrow" id = "vanish-boost" onclick = "updateBoosts('vanish-boost')">
|
||||
Vanish Boost (+80%)
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
<button class = "button" id = "warscream-boost" onclick = "updateBoosts('warscream-boost')">
|
||||
<button class = "button-narrow" id = "warscream-boost" onclick = "updateBoosts('warscream-boost')">
|
||||
War Scream (+10%)
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
<button class = "button" id = "yourtotem-boost" onclick = "updateBoosts('yourtotem-boost')">
|
||||
<button class = "button-narrow" id = "yourtotem-boost" onclick = "updateBoosts('yourtotem-boost')">
|
||||
Your Totem (+35%)
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
<button class = "button" id = "allytotem-boost" onclick = "updateBoosts('allytotem-boost')">
|
||||
<button class = "button-narrow" id = "allytotem-boost" onclick = "updateBoosts('allytotem-boost')">
|
||||
Ally Totem (+15%)
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
<button class = "button-narrow" id = "bash-boost" onclick = "updateBoosts('bash-boost')">
|
||||
Bash (+50%)
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--div class = "powder-specials">
|
||||
<div class = "powder-specials">
|
||||
<div class = "powder-special-stats" style = "grid-column:1;grid-row:1">
|
||||
<div class = "center" id = "powder-special-stats">
|
||||
<p class = "itemp">Powder Specials</p>
|
||||
|
@ -384,7 +389,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -419,7 +424,7 @@
|
|||
<div class="center" style="grid-column:1;grid-row:1">
|
||||
<div>
|
||||
<label for="str-skp" class="skpLabel" id="str-skp-label">Strength:</label><br>
|
||||
<input class="skp-input" type="number" id="str-skp" name="str-skp" value="0" class="skpInput"/>
|
||||
<input class="skp-input" type="string" id="str-skp" name="str-skp" value="0" class="skpInput"/>
|
||||
</div>
|
||||
<div id="str-skp-assign">
|
||||
Manually Assigned: 0
|
||||
|
@ -433,7 +438,7 @@
|
|||
<div class="center" style="grid-column:2;grid-row:1">
|
||||
<div>
|
||||
<label for="dex-skp" class="skpLabel" id="dex-skp-label">Dexterity:</label><br>
|
||||
<input class="skp-input" type="number" id="dex-skp" name="dex-skp" value="0" class="skpInput"/>
|
||||
<input class="skp-input" type="string" id="dex-skp" name="dex-skp" value="0" class="skpInput"/>
|
||||
</div>
|
||||
<div id="dex-skp-assign">
|
||||
Manually Assigned: 0
|
||||
|
@ -447,7 +452,7 @@
|
|||
<div class="center" style="grid-column:3;grid-row:1">
|
||||
<div>
|
||||
<label for="int-skp" class="skpLabel" id="int-skp-label">Intelligence:</label><br>
|
||||
<input class="skp-input" type="number" id="int-skp" name="int-skp" value="0" class="skpInput"/>
|
||||
<input class="skp-input" type="string" id="int-skp" name="int-skp" value="0" class="skpInput"/>
|
||||
</div>
|
||||
<div id="int-skp-assign">
|
||||
Manually Assigned: 0
|
||||
|
@ -461,7 +466,7 @@
|
|||
<div class="center" style="grid-column:4;grid-row:1">
|
||||
<div>
|
||||
<label for="def-skp" class="skpLabel" id="def-skp-label">Defense:</label><br>
|
||||
<input class="skp-input" type="number" id="def-skp" name="def-skp" value="0" class="skpInput"/>
|
||||
<input class="skp-input" type="string" id="def-skp" name="def-skp" value="0" class="skpInput"/>
|
||||
</div>
|
||||
<div id="def-skp-assign">
|
||||
Manually Assigned: 0
|
||||
|
@ -475,7 +480,7 @@
|
|||
<div class="center" style="grid-column:5;grid-row:1">
|
||||
<div>
|
||||
<label for="agi-skp" class="skpLabel" id="agi-skp-label">Agility:</label><br>
|
||||
<input class="skp-input" type="number" id="agi-skp" name="agi-skp" value="0" class="skpInput"/>
|
||||
<input class="skp-input" type="string" id="agi-skp" name="agi-skp" value="0" class="skpInput"/>
|
||||
</div>
|
||||
<div id="agi-skp-assign">
|
||||
Manually Assigned: 0
|
||||
|
@ -549,6 +554,9 @@
|
|||
<div class = "center set-info" id = "set-info-div" style = "grid-column:1;grid-row:1; display: none;">
|
||||
<div class = "center" id = "set-info">Set info</div>
|
||||
</div>
|
||||
<div class = "center int-info" id = "int-info-div" style = "grid-column:4;grid-row:1;visibility:visible;">
|
||||
<div class = "center" id = "int-info">Next Spell Costs</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center" id="header2">
|
||||
<p>Made by <b class = "hppeng">hppeng</b> and <b class = "ferricles">ferricles</b> with Atlas Inc (JavaScript required to function, nothing works without js)</p>
|
||||
|
|
2
load.js
|
@ -1,4 +1,4 @@
|
|||
const DB_VERSION = 18;
|
||||
const DB_VERSION = 19;
|
||||
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js
|
||||
|
||||
let db;
|
||||
|
|
Before Width: | Height: | Size: 463 B |
BIN
media/items/generic-boots.png
Normal file
After Width: | Height: | Size: 418 B |
BIN
media/items/generic-bow.png
Normal file
After Width: | Height: | Size: 109 B |
BIN
media/items/generic-bracelet.png
Normal file
After Width: | Height: | Size: 582 B |
BIN
media/items/generic-chestplate.png
Normal file
After Width: | Height: | Size: 484 B |
BIN
media/items/generic-dagger.png
Normal file
After Width: | Height: | Size: 109 B |
BIN
media/items/generic-helmet.png
Normal file
After Width: | Height: | Size: 395 B |
BIN
media/items/generic-leggings.png
Normal file
After Width: | Height: | Size: 411 B |
BIN
media/items/generic-necklace.png
Normal file
After Width: | Height: | Size: 88 B |
BIN
media/items/generic-relik.png
Normal file
After Width: | Height: | Size: 109 B |
BIN
media/items/generic-ring.png
Normal file
After Width: | Height: | Size: 435 B |
BIN
media/items/generic-spear.png
Normal file
After Width: | Height: | Size: 109 B |
BIN
media/items/generic-wand.png
Normal file
After Width: | Height: | Size: 109 B |
BIN
media/items/palette.png
Normal file
After Width: | Height: | Size: 223 B |
|
@ -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);
|
||||
|
|
39
styles.css
|
@ -78,7 +78,7 @@ a.link{
|
|||
text-align: left;
|
||||
}
|
||||
|
||||
.build-helmet, .build-chestplate, .build-leggings, .build-boots, .build-ring1, .build-ring2, .build-bracelet, .build-necklace, .build-weapon, .build-order, .build-overall, .build-melee-stats, .build-defense-stats, .spell-info, .set-info, .powder-special, .powder-special-stats {
|
||||
.build-helmet, .build-chestplate, .build-leggings, .build-boots, .build-ring1, .build-ring2, .build-bracelet, .build-necklace, .build-weapon, .build-order, .build-overall, .build-melee-stats, .build-defense-stats, .spell-info, .set-info, .powder-special, .powder-special-stats, .int-info {
|
||||
color: #aaa;
|
||||
background: #121516;
|
||||
border: 3px solid #BCBCBC;
|
||||
|
@ -110,6 +110,9 @@ a.link{
|
|||
margin: 2px 2%;
|
||||
padding: 0;
|
||||
}
|
||||
.space {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.damageSubtitle {
|
||||
text-align: center;
|
||||
|
@ -156,6 +159,10 @@ a.link{
|
|||
|
||||
.Neutral { color: #fa0; }
|
||||
.Neutral:before { content: "\2724" ' '; }
|
||||
.Damage { color: rgb(255, 198, 85)}
|
||||
|
||||
.Mana { color: #5ff;}
|
||||
.Mana:after { content: "\2749"}
|
||||
|
||||
.Health {
|
||||
color: #a00;
|
||||
|
@ -193,6 +200,18 @@ a.link{
|
|||
::-webkit-scrollbar-corner{
|
||||
background: #110110;
|
||||
}
|
||||
.button-narrow {
|
||||
background-color: #666;
|
||||
border: 2px solid #444;
|
||||
border-radius: 5px;
|
||||
color: #ddd;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
font-family: 'Nunito',sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 90%;
|
||||
display: inline-block;
|
||||
}
|
||||
button {
|
||||
background-color: #666;
|
||||
border: 2px solid #444;
|
||||
|
@ -205,6 +224,16 @@ button {
|
|||
font-size: 120%;
|
||||
display: inline-block;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #556;
|
||||
}
|
||||
|
||||
|
||||
button:active {
|
||||
background-color: #558;
|
||||
box-shadow: 0 3px #666;
|
||||
transform: translateY(1px);
|
||||
}
|
||||
input {
|
||||
background-color: #666;
|
||||
border: 2px solid #444;
|
||||
|
@ -249,3 +278,11 @@ button.toggleOn{
|
|||
background-color:#0a0;
|
||||
border: 3 px solid rgb(0, 70, 0);
|
||||
}
|
||||
|
||||
.funnynumber {
|
||||
background-image: linear-gradient(to left, #f5f, #a0a, #5ff, #5f5, #ff5, #fa0, #a00); -webkit-background-clip: text;
|
||||
color: transparent;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
transform: translateX(calc(50vw - 50%));
|
||||
}
|
||||
|
|
4
utils.js
|
@ -99,7 +99,7 @@ Base64 = (function () {
|
|||
// Base64.toInt("200000"); // gives -2147483648
|
||||
|
||||
/*
|
||||
Turns a raw stat and a % stat into a final stat on the basis that - raw and >= 100% becomes 0 and + raw and <=-100% becomes 0.
|
||||
Turns a raw stat and a % stat into a final stat on the basis that - raw and >= 100% becomes 0 and + raw and <=-100% becomes negative.
|
||||
Pct would be 0.80 for 80%, -1.20 for 120%, etc
|
||||
Example Outputs:
|
||||
raw: -100
|
||||
|
@ -112,7 +112,7 @@ Base64 = (function () {
|
|||
pct: +0.20, output = 120
|
||||
pct: +1.20, output = 220
|
||||
pct: -0.20, output = 80
|
||||
pct: -1.20, output = 0
|
||||
pct: -1.20, output = -20
|
||||
*/
|
||||
function rawToPct(raw, pct){
|
||||
final = 0;
|
||||
|
|