fixed merge issues and minor typos

This commit is contained in:
ferricles 2021-01-07 00:17:53 -08:00
commit 76dee6948f
12 changed files with 495 additions and 3603 deletions

View file

@ -11,5 +11,9 @@ Damage calculation
Skillpoint engine Skillpoint engine
- Make it work... - Make it work...
Item DB searcher Build encoding
- Make it - Allow exporting/importing builds to strings
LATER STUFF:
- Custom items integration
- wynndata parse? And/or google sheets

View file

@ -99,16 +99,25 @@ class Build{
}else{ }else{
this.level = level; this.level = level;
} }
this.skillpoints = levelToSkillPoints(this.level) this.availableSkillpoints = levelToSkillPoints(this.level);
this.equipment = [ helmet, chestplate, leggings, boots, ring1, ring2, bracelet, necklace ];
// return [equip_order, best_skillpoints, final_skillpoints, best_total];
let result = calculate_skillpoints(this.equipment, weapon);
console.log(result);
this.equip_order = result[0];
this.base_skillpoints = result[1];
this.total_skillpoints = result[2];
this.assigned_skillpoints = result[3];
} }
/*Returns build in string format /*Returns build in string format
*/ TODO */
toString(){ toString(){
return this.helmet.name + ", " + this.chestplate.name + ", " + this.leggings.name + ", " + this.boots.name + ", " + this.ring1.name + ", " + this.ring2.name + ", " + this.bracelet.name + ", " + this.necklace.name + ", " + this.weapon.name; return this.helmet.name + ", " + this.chestplate.name + ", " + this.leggings.name + ", " + this.boots.name + ", " + this.ring1.name + ", " + this.ring2.name + ", " + this.bracelet.name + ", " + this.necklace.name + ", " + this.weapon.name;
} }
/* Getters */ TODO /* Getters */
getHealth(){ getHealth(){
health = parseInt(this.helmet.hp,10) + parseInt(this.helmet.hpBonus,10) + parseInt(this.chestplate.hp,10) + parseInt(this.chestplate.hpBonus,10) + parseInt(this.leggings.hp,10) + parseInt(this.leggings.hpBonus,10) + parseInt(this.boots.hp,10) + parseInt(this.boots.hpBonus,10) + parseInt(this.ring1.hp,10) + parseInt(this.ring1.hpBonus,10) + parseInt(this.ring2.hp,10) + parseInt(this.ring2.hpBonus,10) + parseInt(this.bracelet.hp,10) + parseInt(this.bracelet.hpBonus,10) + parseInt(this.necklace.hp,10) + parseInt(this.necklace.hpBonus,10) + parseInt(this.weapon.hp,10) + parseInt(this.weapon.hpBonus,10) + levelToHPBase(this.level); health = parseInt(this.helmet.hp,10) + parseInt(this.helmet.hpBonus,10) + parseInt(this.chestplate.hp,10) + parseInt(this.chestplate.hpBonus,10) + parseInt(this.leggings.hp,10) + parseInt(this.leggings.hpBonus,10) + parseInt(this.boots.hp,10) + parseInt(this.boots.hpBonus,10) + parseInt(this.ring1.hp,10) + parseInt(this.ring1.hpBonus,10) + parseInt(this.ring2.hp,10) + parseInt(this.ring2.hpBonus,10) + parseInt(this.bracelet.hp,10) + parseInt(this.bracelet.hpBonus,10) + parseInt(this.necklace.hp,10) + parseInt(this.necklace.hpBonus,10) + parseInt(this.weapon.hp,10) + parseInt(this.weapon.hpBonus,10) + levelToHPBase(this.level);
if(health<5){ if(health<5){
@ -117,6 +126,8 @@ class Build{
return health; return health;
} }
} }
/* Setters */ TODO
/* Setters */
} }

3545
clean.json

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -13,10 +13,10 @@ translate_mappings = {
#"set": "set", #"set": "set",
"sockets": "slots", "sockets": "slots",
#"type": "type", #"type": "type",
#"armorType": "armorType", #"armorType": "armorType", (deleted)
"armorColor": "color", #"armorColor": "color", (deleted)
"addedLore": "lore", #"addedLore": "lore", (deleted)
#"material": "material", #"material": "material", (deleted)
"dropType": "drop", "dropType": "drop",
#"quest": "quest", #"quest": "quest",
"restrictions": "restrict", "restrictions": "restrict",
@ -55,7 +55,7 @@ translate_mappings = {
"agilityPoints": "agi", "agilityPoints": "agi",
"defensePoints": "def", "defensePoints": "def",
#"thorns": "thorns", #"thorns": "thorns",
#"exploding": "expoding", #"exploding": "exploding",
"speed": "spd", "speed": "spd",
"attackSpeedBonus": "atkTier", "attackSpeedBonus": "atkTier",
#"poison": "poison", #"poison": "poison",
@ -103,7 +103,8 @@ delete_keys = [
"addedLore", "addedLore",
"skin", "skin",
"armorType", "armorType",
"armorColor" "armorColor",
"material"
] ]
for item in items: for item in items:

View file

@ -121,26 +121,54 @@
</button> </button>
</div> </div>
</div> </div>
<div class="center" id="summary-box">
Summary:
</div>
<div class="skillpoints"> <div class="skillpoints">
<div class="center" style="grid-column:1;grid-row:1"> <div class="center" style="grid-column:1;grid-row:1">
<label for="str-skp">Strength:</label><br> <div>
<input type="text" id="str-skp" name="str-skp" /> <label for="str-skp">Strength:</label>
<input type="number" id="str-skp" name="str-skp" value="0"/>
</div>
<div id="str-skp-base">
Original Value: 0
</div>
</div> </div>
<div class="center" style="grid-column:2;grid-row:1"> <div class="center" style="grid-column:2;grid-row:1">
<label for="dex-skp">Dexterity:</label><br> <div>
<input type="text" id="dex-skp" name="dex-skp" /> <label for="dex-skp">Dexterity:</label>
<input type="number" id="dex-skp" name="dex-skp" value="0"/>
</div>
<div id="dex-skp-base">
Original Value: 0
</div>
</div> </div>
<div class="center" style="grid-column:3;grid-row:1"> <div class="center" style="grid-column:3;grid-row:1">
<label for="int-skp">Intelligence:</label><br> <div>
<input type="text" id="int-skp" name="int-skp" /> <label for="int-skp">Intelligence:</label>
<input type="number" id="int-skp" name="int-skp" value="0"/>
</div>
<div id="int-skp-base">
Original Value: 0
</div>
</div> </div>
<div class="center" style="grid-column:4;grid-row:1"> <div class="center" style="grid-column:4;grid-row:1">
<label for="def-skp">Defense:</label><br> <div>
<input type="text" id="def-skp" name="def-skp" /> <label for="def-skp">Defense:</label>
<input type="number" id="def-skp" name="def-skp" value="0"/>
</div>
<div id="def-skp-base">
Original Value: 0
</div>
</div> </div>
<div class="center" style="grid-column:5;grid-row:1"> <div class="center" style="grid-column:5;grid-row:1">
<label for="agi-skp">Agility:</label><br> <div>
<input type="text" id="agi-skp" name="agi-skp" /> <label for="agi-skp">Agility:</label>
<input type="number" id="agi-skp" name="agi-skp" value="0"/>
</div>
<div id="agi-skp-base">
Original Value: 0
</div>
</div> </div>
</div> </div>
<div class = "build"> <div class = "build">
@ -171,11 +199,16 @@
<div class = "center build-weapon" id = "build-weapon" style = "grid-column:1;grid-row:3"> <div class = "center build-weapon" id = "build-weapon" style = "grid-column:1;grid-row:3">
<div class = "center" id = "build-weapon-stats"></div> <div class = "center" id = "build-weapon-stats"></div>
</div> </div>
<div class = "center build-cumulative" id = "build-cumulative" style = "grid-column:2;grid-row:3"> <div class = "center" id = "build-order" style = "grid-column:2;grid-row:3">
<div class = "center" id = "build-cumulative-stats"></div> </div>
<div class = "center" id = "build-cumulative-stats" style = "grid-column:3;grid-row:3">
</div>
<div class = "center" id = "defense-damage-stats" style = "grid-column:4;grid-row:3">
</div> </div>
</div> </div>
<script type="text/javascript" src="utils.js"></script>
<script type="text/javascript" src="skillpoints.js"></script>
<script type="text/javascript" src="build.js"></script> <script type="text/javascript" src="build.js"></script>
<script type="text/javascript" src="load.js"></script> <script type="text/javascript" src="load.js"></script>
<script type="text/javascript" src="test.js"></script> <script type="text/javascript" src="test.js"></script>

View file

@ -1,4 +1,4 @@
const DB_VERSION = 2; const DB_VERSION = 3;
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js // @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js
let db; let db;
@ -31,6 +31,9 @@ function clean_item(item) {
if (item.displayName === undefined) { if (item.displayName === undefined) {
item.displayName = item.name; item.displayName = item.name;
} }
item.skillpoints = [item.str, item.dex, item.int, item.def, item.agi];
item.has_negstat = item.str < 0 || item.dex < 0 || item.int < 0 || item.def < 0 || item.agi < 0;
item.reqs = [item.strReq, item.dexReq, item.intReq, item.defReq, item.agiReq];
} }
/* /*

165
skillpoint_test.py Normal file
View file

@ -0,0 +1,165 @@
import json
import math
import copy
with open("clean.json") as infile:
data = json.load(infile)
def clean_item(item):
if not "displayName" in item:
item["displayName"] = item["name"];
return item
items = data["items"]
item_map = {clean_item(item)["displayName"]: item for item in items}
# build_items_names = [
# "Cumulonimbus",
# "Soulflare",
# "Leictreach Makani",
# "Slayer",
# "Intensity",
# "Moon Pool Circlet",
# "Diamond Static Bracelet",
# "Royal Stormy Amulet"
# ]
# build_weapon_name = "Fatal"
# build_items_names = [
# "Morph-Stardust",
# "Morph-Steel",
# "Morph-Iron",
# "Morph-Gold",
# "Morph-Topaz",
# "Morph-Emerald",
# "Morph-Amethyst",
# "Morph-Ruby"
# ]
# build_weapon_name = "Cascade"
build_items_names = [
"Blue Mask",
"Sparkling Plate",
"Gemini",
"Slayer",
"Draoi Fair",
"Moon Pool Circlet",
"Prowess",
"Diamond Fusion Necklace"
]
build_weapon_name = "Praesidium"
build_items = [item_map[item] for item in build_items_names]
build_weapon = item_map[build_weapon_name]
for item in build_items:
print(item)
print("-------------------------------")
print(build_weapon)
# Consolidate skillpoint and req into arrays for ease of processing.
def setup(item):
item["skillpoints"] = [item["str"], item["dex"], item["int"], item["def"], item["agi"]]
item["has_negstat"] = any(x < 0 for x in item["skillpoints"])
item["reqs"] = [item["strReq"], item["dexReq"], item["intReq"], item["defReq"], item["agiReq"]]
fixed = []
consider = []
noboost = []
for item in build_items:
setup(item)
if all(x == 0 for x in item["reqs"]):
fixed.append(item)
elif all(x == 0 for x in item["skillpoints"]):
noboost.append(item)
else:
consider.append(item)
setup(build_weapon)
fixed = tuple(fixed)
noboost = tuple(noboost)
# Apply the skillpoints an item gives to the build.
def apply_skillpoints(skillpoints, item):
for i in range(5):
skillpoints[i] += item["skillpoints"][i]
def remove_skillpoints(skillpoints, item):
for i in range(5):
skillpoints[i] -= item["skillpoints"][i]
# Figure out (naively) how many skillpoints need to be applied to get the current item to fit.
# Doesn't handle -skp.
def apply_to_fit(skillpoints, item):
applied = [0, 0, 0, 0, 0]
total = 0
for i, req, cur in zip(range(5), item["reqs"], skillpoints):
if (item["reqs"][i] == 0):
continue
if req > cur:
diff = req - cur
applied[i] += diff
total += diff
return applied, total
# Permutations in js reference (also cool algorithm):
# https://stackoverflow.com/a/41068709
static_skillpoints_base = [0, 0, 0, 0, 0]
# Separate out the no req items and add them to the static skillpoint base.
for item in fixed:
apply_skillpoints(static_skillpoints_base, item)
best = None
final_skillpoints = None
best_skillpoints = [0, 0, 0, 0, 0]
best_total = math.inf
# Try every combination and pick the best one.
import itertools
for permutation in itertools.permutations(consider):
permutation += noboost
skillpoints_applied = [0, 0, 0, 0, 0]
skillpoints = copy.copy(static_skillpoints_base)
total_applied = 0
for item in permutation:
needed_skillpoints, total_diff = apply_to_fit(skillpoints, item)
for i in range(5):
skillpoints_applied[i] += needed_skillpoints[i]
skillpoints[i] += needed_skillpoints[i]
apply_skillpoints(skillpoints, item)
total_applied += total_diff
if total_applied >= best_total:
break
if total_applied < best_total:
for item in permutation:
remove_skillpoints(skillpoints, item)
needed_skillpoints, total_diff = apply_to_fit(skillpoints, item)
for i in range(5):
skillpoints_applied[i] += needed_skillpoints[i]
skillpoints[i] += needed_skillpoints[i]
apply_skillpoints(skillpoints, item)
total_applied += total_diff
if total_applied >= best_total:
break
needed_skillpoints, total_diff = apply_to_fit(skillpoints, build_weapon)
for i in range(5):
skillpoints_applied[i] += needed_skillpoints[i]
skillpoints[i] += needed_skillpoints[i]
apply_skillpoints(skillpoints, build_weapon)
total_applied += total_diff
if total_applied < best_total:
best = permutation
final_skillpoints = skillpoints
best_skillpoints = skillpoints_applied
best_total = total_applied
print([i["displayName"] for i in fixed + best])
print(best_skillpoints)
print(final_skillpoints)
print(best_total)
#def attempt(skillpoints, items_in_order):

141
skillpoints.js Normal file
View file

@ -0,0 +1,141 @@
function calculate_skillpoints(equipment, weapon) {
// Calculate equipment equipping order and required skillpoints.
// Return value: [equip_order, best_skillpoints, final_skillpoints, best_total];
let fixed = [];
let consider = [];
let noboost = [];
for (const item of equipment) {
if (item.reqs.every(x => x === 0)) {
fixed.push(item);
}
else if (item.skillpoints.every(x => x === 0)) {
noboost.push(item);
}
else {
consider.push(item);
}
}
function apply_skillpoints(skillpoints, item) {
for (let i = 0; i < 5; i++) {
skillpoints[i] += item.skillpoints[i];
}
}
function remove_skillpoints(skillpoints, item) {
for (let i = 0; i < 5; i++) {
skillpoints[i] -= item.skillpoints[i];
}
}
// Figure out (naively) how many skillpoints need to be applied to get the current item to fit.
// Doesn't handle -skp.
function apply_to_fit(skillpoints, item) {
let applied = [0, 0, 0, 0, 0];
let total = 0;
for (let i = 0; i < 5; i++) {
if (item.reqs[i] == 0) continue;
const req = item.reqs[i];
const cur = skillpoints[i];
if (req > cur) {
const diff = req - cur;
applied[i] += diff;
total += diff;
}
}
return [applied, total];
}
// Separate out the no req items and add them to the static skillpoint base.
let static_skillpoints_base = [0, 0, 0, 0, 0]
for (const item of fixed) {
apply_skillpoints(static_skillpoints_base, item);
}
let best = null;
let final_skillpoints = null;
let best_skillpoints = [0, 0, 0, 0, 0];
let best_total = Infinity;
if (consider.length > 0 || noboost.length > 0) {
// Try every combination and pick the best one.
for (let permutation of perm(consider)) {
permutation = permutation.concat(noboost);
console.log(permutation);
let skillpoints_applied = [0, 0, 0, 0, 0];
// Complete slice is a shallow copy.
let skillpoints = static_skillpoints_base.slice();
let total_applied = 0;
let result;
let needed_skillpoints;
let total_diff;
for (const item of permutation) {
result = apply_to_fit(skillpoints, item);
needed_skillpoints = result[0];
total_diff = result[1];
for (let i = 0; i < 5; ++i) {
skillpoints_applied[i] += needed_skillpoints[i];
skillpoints[i] += needed_skillpoints[i];
}
apply_skillpoints(skillpoints, item);
total_applied += total_diff;
if (total_applied >= best_total) {
break;
}
}
if (total_applied < best_total) {
console.log(total_applied);
console.log(skillpoints_applied);
console.log("Iteration 2");
for (const item of permutation) {
console.log(item);
remove_skillpoints(skillpoints, item);
console.log(skillpoints);
result = apply_to_fit(skillpoints, item);
needed_skillpoints = result[0];
total_diff = result[1];
for (let i = 0; i < 5; ++i) {
skillpoints_applied[i] += needed_skillpoints[i];
skillpoints[i] += needed_skillpoints[i];
}
apply_skillpoints(skillpoints, item);
console.log(skillpoints);
console.log(total_diff);
total_applied += total_diff;
if (total_applied >= best_total) {
break;
}
}
}
result = apply_to_fit(skillpoints, weapon);
needed_skillpoints = result[0];
total_diff = result[1];
for (let i = 0; i < 5; ++i) {
skillpoints_applied[i] += needed_skillpoints[i];
skillpoints[i] += needed_skillpoints[i];
}
apply_skillpoints(skillpoints, weapon);
total_applied += total_diff;
if (total_applied < best_total) {
best = permutation;
final_skillpoints = skillpoints;
best_skillpoints = skillpoints_applied;
best_total = total_applied;
}
}
let equip_order = fixed.concat(best);
return [equip_order, best_skillpoints, final_skillpoints, best_total];
}
else {
return [fixed.concat(noboost), best_skillpoints, static_skillpoints_base, 0];
}
}

110
test.js
View file

@ -1,3 +1,12 @@
/*
* TESTING SECTION
*/
console.log(location.href);
/*
* END testing section
*/
let player_build; let player_build;
// Set up item lists for quick access later. // Set up item lists for quick access later.
@ -32,16 +41,32 @@ function populateItemList(type) {
*/ */
function init() { function init() {
let noneItems = [ let noneItems = [
{displayName:"No Helmet", name: "No Helmet", category: "armor", type: "helmet", aDamPct: 0 ,aDef: 0, aDefPct: 0, agi: 0, agiReq: 0, atkTier: 0, classReq: null, def: 0, defReq: 0, dex: 0, dexReq: 0, drop: "never", eDamPct: 0, eDef: 0, eDefPct: 0, eSteal: 0, exploding: 0, fDamPct: 0, fDef: 0, fDefPct: 0, fixID: true, gSpd: 0, gXp: 0, hp: 0, hpBonus: 0, hprPct: 0, hprRaw: 0, int: 0, intReq: 0, jh: 0, lb: 0, lq: 0, ls: 0, lvl: 0, material: null, mdPct: 0, mdRaw: 0, mr: 0, ms: 0, poison: 0, quest: null, rainbowRaw: 0, ref: 0, sdPct: 0, sdRaw: 0, set: null, slots: 0, spPct1: 0, spPct2: 0, spPct3: 0, spPct4: 0, spRaw1: 0, spRaw2: 0, spRaw3: 0, spRaw4: 0, spRegen: 0, spd: 0, sprintReg: 0, str: 0, strReq: 0, tDamPct: 0, tDef: 0, tDefPct: 0, thorns: 0, tier: null, wDamPct: 0, wDef: 0, wDefPct: 0, xpb: 0}, ["helmet", "No Helmet"],
{displayName:"No Chestplate", name: "No Chestplate", category: "armor", type: "chestplate", aDamPct: 0 ,aDef: 0, aDefPct: 0, agi: 0, agiReq: 0, atkTier: 0, classReq: null, def: 0, defReq: 0, dex: 0, dexReq: 0, drop: "never", eDamPct: 0, eDef: 0, eDefPct: 0, eSteal: 0, exploding: 0, fDamPct: 0, fDef: 0, fDefPct: 0, fixID: true, gSpd: 0, gXp: 0, hp: 0, hpBonus: 0, hprPct: 0, hprRaw: 0, int: 0, intReq: 0, jh: 0, lb: 0, lq: 0, ls: 0, lvl: 0, material: null, mdPct: 0, mdRaw: 0, mr: 0, ms: 0, poison: 0, quest: null, rainbowRaw: 0, ref: 0, sdPct: 0, sdRaw: 0, set: null, slots: 0, spPct1: 0, spPct2: 0, spPct3: 0, spPct4: 0, spRaw1: 0, spRaw2: 0, spRaw3: 0, spRaw4: 0, spRegen: 0, spd: 0, sprintReg: 0, str: 0, strReq: 0, tDamPct: 0, tDef: 0, tDefPct: 0, thorns: 0, tier: null, wDamPct: 0, wDef: 0, wDefPct: 0, xpb: 0}, ["chestplate", "No Chestplate"],
{displayName:"No Leggings", name: "No Leggings", category: "armor", type: "leggings", aDamPct: 0 ,aDef: 0, aDefPct: 0, agi: 0, agiReq: 0, atkTier: 0, classReq: null, def: 0, defReq: 0, dex: 0, dexReq: 0, drop: "never", eDamPct: 0, eDef: 0, eDefPct: 0, eSteal: 0, exploding: 0, fDamPct: 0, fDef: 0, fDefPct: 0, fixID: true, gSpd: 0, gXp: 0, hp: 0, hpBonus: 0, hprPct: 0, hprRaw: 0, int: 0, intReq: 0, jh: 0, lb: 0, lq: 0, ls: 0, lvl: 0, material: null, mdPct: 0, mdRaw: 0, mr: 0, ms: 0, poison: 0, quest: null, rainbowRaw: 0, ref: 0, sdPct: 0, sdRaw: 0, set: null, slots: 0, spPct1: 0, spPct2: 0, spPct3: 0, spPct4: 0, spRaw1: 0, spRaw2: 0, spRaw3: 0, spRaw4: 0, spRegen: 0, spd: 0, sprintReg: 0, str: 0, strReq: 0, tDamPct: 0, tDef: 0, tDefPct: 0, thorns: 0, tier: null, wDamPct: 0, wDef: 0, wDefPct: 0, xpb: 0}, ["leggings", "No Leggings"],
{displayName:"No Boots", name: "No Boots", category: "armor", type: "boots", aDamPct: 0 ,aDef: 0, aDefPct: 0, agi: 0, agiReq: 0, atkTier: 0, classReq: null, def: 0, defReq: 0, dex: 0, dexReq: 0, drop: "never", eDamPct: 0, eDef: 0, eDefPct: 0, eSteal: 0, exploding: 0, fDamPct: 0, fDef: 0, fDefPct: 0, fixID: true, gSpd: 0, gXp: 0, hp: 0, hpBonus: 0, hprPct: 0, hprRaw: 0, int: 0, intReq: 0, jh: 0, lb: 0, lq: 0, ls: 0, lvl: 0, material: null, mdPct: 0, mdRaw: 0, mr: 0, ms: 0, poison: 0, quest: null, rainbowRaw: 0, ref: 0, sdPct: 0, sdRaw: 0, set: null, slots: 0, spPct1: 0, spPct2: 0, spPct3: 0, spPct4: 0, spRaw1: 0, spRaw2: 0, spRaw3: 0, spRaw4: 0, spRegen: 0, spd: 0, sprintReg: 0, str: 0, strReq: 0, tDamPct: 0, tDef: 0, tDefPct: 0, thorns: 0, tier: null, wDamPct: 0, wDef: 0, wDefPct: 0, xpb: 0}, ["boots", "No Boots"],
{displayName:"No Ring 1", name: "No Ring 1", category: "accessory", type: "ring", aDamPct: 0 ,aDef: 0, aDefPct: 0, agi: 0, agiReq: 0, atkTier: 0, classReq: null, def: 0, defReq: 0, dex: 0, dexReq: 0, drop: "never", eDamPct: 0, eDef: 0, eDefPct: 0, eSteal: 0, exploding: 0, fDamPct: 0, fDef: 0, fDefPct: 0, fixID: true, gSpd: 0, gXp: 0, hp: 0, hpBonus: 0, hprPct: 0, hprRaw: 0, int: 0, intReq: 0, jh: 0, lb: 0, lq: 0, ls: 0, lvl: 0, material: null, mdPct: 0, mdRaw: 0, mr: 0, ms: 0, poison: 0, quest: null, rainbowRaw: 0, ref: 0, sdPct: 0, sdRaw: 0, set: null, slots: 0, spPct1: 0, spPct2: 0, spPct3: 0, spPct4: 0, spRaw1: 0, spRaw2: 0, spRaw3: 0, spRaw4: 0, spRegen: 0, spd: 0, sprintReg: 0, str: 0, strReq: 0, tDamPct: 0, tDef: 0, tDefPct: 0, thorns: 0, tier: null, wDamPct: 0, wDef: 0, wDefPct: 0, xpb: 0}, ["ring", "No Ring 1"],
{displayName:"No Ring 2", name: "No Ring 2", category: "accessory", type: "ring", aDamPct: 0 ,aDef: 0, aDefPct: 0, agi: 0, agiReq: 0, atkTier: 0, classReq: null, def: 0, defReq: 0, dex: 0, dexReq: 0, drop: "never", eDamPct: 0, eDef: 0, eDefPct: 0, eSteal: 0, exploding: 0, fDamPct: 0, fDef: 0, fDefPct: 0, fixID: true, gSpd: 0, gXp: 0, hp: 0, hpBonus: 0, hprPct: 0, hprRaw: 0, int: 0, intReq: 0, jh: 0, lb: 0, lq: 0, ls: 0, lvl: 0, material: null, mdPct: 0, mdRaw: 0, mr: 0, ms: 0, poison: 0, quest: null, rainbowRaw: 0, ref: 0, sdPct: 0, sdRaw: 0, set: null, slots: 0, spPct1: 0, spPct2: 0, spPct3: 0, spPct4: 0, spRaw1: 0, spRaw2: 0, spRaw3: 0, spRaw4: 0, spRegen: 0, spd: 0, sprintReg: 0, str: 0, strReq: 0, tDamPct: 0, tDef: 0, tDefPct: 0, thorns: 0, tier: null, wDamPct: 0, wDef: 0, wDefPct: 0, xpb: 0}, ["ring", "No Ring 2"],
{displayName:"No Bracelet", name: "No Bracelet", category: "accessory", type: "bracelet", aDamPct: 0 ,aDef: 0, aDefPct: 0, agi: 0, agiReq: 0, atkTier: 0, classReq: null, def: 0, defReq: 0, dex: 0, dexReq: 0, drop: "never", eDamPct: 0, eDef: 0, eDefPct: 0, eSteal: 0, exploding: 0, fDamPct: 0, fDef: 0, fDefPct: 0, fixID: true, gSpd: 0, gXp: 0, hp: 0, hpBonus: 0, hprPct: 0, hprRaw: 0, int: 0, intReq: 0, jh: 0, lb: 0, lq: 0, ls: 0, lvl: 0, material: null, mdPct: 0, mdRaw: 0, mr: 0, ms: 0, poison: 0, quest: null, rainbowRaw: 0, ref: 0, sdPct: 0, sdRaw: 0, set: null, slots: 0, spPct1: 0, spPct2: 0, spPct3: 0, spPct4: 0, spRaw1: 0, spRaw2: 0, spRaw3: 0, spRaw4: 0, spRegen: 0, spd: 0, sprintReg: 0, str: 0, strReq: 0, tDamPct: 0, tDef: 0, tDefPct: 0, thorns: 0, tier: null, wDamPct: 0, wDef: 0, wDefPct: 0, xpb: 0}, ["bracelet", "No Bracelet"],
{displayName:"No Necklace", name: "No Necklace", category: "accessory", type: "necklace", aDamPct: 0 ,aDef: 0, aDefPct: 0, agi: 0, agiReq: 0, atkTier: 0, classReq: null, def: 0, defReq: 0, dex: 0, dexReq: 0, drop: "never", eDamPct: 0, eDef: 0, eDefPct: 0, eSteal: 0, exploding: 0, fDamPct: 0, fDef: 0, fDefPct: 0, fixID: true, gSpd: 0, gXp: 0, hp: 0, hpBonus: 0, hprPct: 0, hprRaw: 0, int: 0, intReq: 0, jh: 0, lb: 0, lq: 0, ls: 0, lvl: 0, material: null, mdPct: 0, mdRaw: 0, mr: 0, ms: 0, poison: 0, quest: null, rainbowRaw: 0, ref: 0, sdPct: 0, sdRaw: 0, set: null, slots: 0, spPct1: 0, spPct2: 0, spPct3: 0, spPct4: 0, spRaw1: 0, spRaw2: 0, spRaw3: 0, spRaw4: 0, spRegen: 0, spd: 0, sprintReg: 0, str: 0, strReq: 0, tDamPct: 0, tDef: 0, tDefPct: 0, thorns: 0, tier: null, wDamPct: 0, wDef: 0, wDefPct: 0, xpb: 0}, ["necklace", "No Necklace"],
{displayName:"No Weapon", name: "No Weapon", category: "weapon", type: "wand", aDamPct: 0 ,aDef: 0, aDefPct: 0, agi: 0, agiReq: 0, atkTier: 0, classReq: null, def: 0, defReq: 0, dex: 0, dexReq: 0, drop: "never", eDamPct: 0, eDef: 0, eDefPct: 0, eSteal: 0, exploding: 0, fDamPct: 0, fDef: 0, fDefPct: 0, fixID: true, gSpd: 0, gXp: 0, hp: 0, hpBonus: 0, hprPct: 0, hprRaw: 0, int: 0, intReq: 0, jh: 0, lb: 0, lq: 0, ls: 0, lvl: 0, material: null, mdPct: 0, mdRaw: 0, mr: 0, ms: 0, poison: 0, quest: null, rainbowRaw: 0, ref: 0, sdPct: 0, sdRaw: 0, set: null, slots: 0, spPct1: 0, spPct2: 0, spPct3: 0, spPct4: 0, spRaw1: 0, spRaw2: 0, spRaw3: 0, spRaw4: 0, spRegen: 0, spd: 0, sprintReg: 0, str: 0, strReq: 0, tDamPct: 0, tDef: 0, tDefPct: 0, thorns: 0, tier: null, wDamPct: 0, wDef: 0, wDefPct: 0, xpb: 0} ["wand", "No Weapon"],
] ];
for (let i = 0; i < 9; i++) {
let item = Object();
for (const field of item_fields) {
item[field] = 0;
}
item.type = noneItems[i][0];
item.name = noneItems[i][1];
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];
noneItems[i] = item;
}
items = items.concat(noneItems); items = items.concat(noneItems);
console.log(items); console.log(items);
for (const item of items) { for (const item of items) {
@ -164,6 +189,29 @@ function calculateBuild(){
document.getElementById("build-bracelet").innerHTML = expandedItemToString(expandItem(itemMap.get(player_build.bracelet.name))); document.getElementById("build-bracelet").innerHTML = expandedItemToString(expandItem(itemMap.get(player_build.bracelet.name)));
document.getElementById("build-necklace").innerHTML = expandedItemToString(expandItem(itemMap.get(player_build.necklace.name))); document.getElementById("build-necklace").innerHTML = expandedItemToString(expandItem(itemMap.get(player_build.necklace.name)));
document.getElementById("build-weapon").innerHTML = expandedItemToString(expandItem(itemMap.get(player_build.weapon.name))); document.getElementById("build-weapon").innerHTML = expandedItemToString(expandItem(itemMap.get(player_build.weapon.name)));
player_build.equip_order;
player_build.base_skillpoints;
let skillpoints = player_build.total_skillpoints;
setValue("str-skp", skillpoints[0]);
setValue("dex-skp", skillpoints[1]);
setValue("int-skp", skillpoints[2]);
setValue("def-skp", skillpoints[3]);
setValue("agi-skp", skillpoints[4]);
console.log(skillpoints);
player_build.assigned_skillpoints;
setHTML("summary-box", "Summary: Assigned " + player_build.assigned_skillpoints + " skillpoints.");
setHTML("build-helmet", player_build.helmet.name);
setHTML("build-chestplate", player_build.chestplate.name);
setHTML("build-leggings", player_build.helmet.name);
setHTML("build-boots", player_build.helmet.name);
setHTML("build-ring1", player_build.ring1.name);
setHTML("build-ring2", player_build.ring2.name);
setHTML("build-bracelet", player_build.bracelet.name);
setHTML("build-necklace", player_build.necklace.name);
setHTML("build-weapon", player_build.weapon.name);
} }
/* Helper function that gets stats ranges for wearable items. /* Helper function that gets stats ranges for wearable items.
@param item - an item in Object format. @param item - an item in Object format.
@ -219,8 +267,8 @@ function expandItem(item){
function expandedItemToString(item){ function expandedItemToString(item){
console.log(item); console.log(item);
let ids = ["lvl", "classReq","strReq", "dexReq", "intReq", "defReq","agiReq", "nDam", "eDam", "tDam", "wDam", "tDam", "aDam", "atkSpd", "hp", "eDef", "tDef", "wDef", "fDef", "aDef", "str", "dex", "int", "agi", "def", "hpBonus", "hprRaw", "hprPct", "sdRaw", "sdPct", "mdRaw", "mdPct", "mr", "ms", "ref", "ls", "poison", "thorns", "exploding", "spd", "atkTier", "eDamPct", "tDamPct", "wDamPct", "fDamPct", "aDamPct", "eDefPct", "tDefPct", "wDefPct", "fDefPct", "aDefPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "xpb", "lb", "lq", "spRegen", "eSteal", "gXp", "gSpd", "slots", "set", "quest", "restrict"]; let ids = ["lvl", "classReq","strReq", "dexReq", "intReq", "defReq","agiReq", "nDam", "eDam", "tDam", "wDam", "tDam", "aDam", "atkSpd", "hp", "eDef", "tDef", "wDef", "fDef", "aDef", "str", "dex", "int", "agi", "def", "hpBonus", "hprRaw", "hprPct", "sdRaw", "sdPct", "mdRaw", "mdPct", "mr", "ms", "ref", "ls", "poison", "thorns", "exploding", "spd", "atkTier", "eDamPct", "tDamPct", "wDamPct", "fDamPct", "aDamPct", "eDefPct", "tDefPct", "wDefPct", "fDefPct", "aDefPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "xpb", "lb", "lq", "spRegen", "eSteal", "gXp", "gSpd", "slots", "set", "quest", "restrict"];
let idPrefixes = {"lvl":"Combat Level Min: ", "classReq":"Class Req: ","strReq":"Strength Min: ","dexReq":"Dexterity Min: ","intReq":"Intelligence Min: ","defReq":"Defense Min: ","agiReq":"Agility Min: ", "nDam":"Neutral Damage: ", "eDam":"Earth Damage: ", "tDam":"Thunder Damage: ", "wDam":"Water Damage: ", "fDam":"Fire Damage: ", "aDam":"Air Damage: ", "atkSpd":"Attack Speed: ", "hp":"Health: ", "eDef":"Earth Defense: ", "tDef":"Thunder Defense: ", "wDef":"Water Defense: ", "fDef":"Fire Defense: ", "aDef":"Air Defense: ", "str":"Strength: ", "dex":"Dexterity: ", "int":"Intelligence: ", "def":"Defense: ","agi":"Agility: ", "hpBonus":"Health Bonus: ", "hprRaw":"Health Regen Raw: ", "hprPct":"Health Regen %: ", "sdRaw":"Raw Spell Damage: ", "sdPct":"Spell Damage %: ", "mdRaw":"Main Attack Neutral Damage: ", "mdPct":"Main Attack Damage %: ", "mr":"Mana Regen: ", "ms":"Mana Steal: ", "ref":"Reflection: ", "ls":"Life Steal: ", "poison":"Poison: ", "thorns":"Thorns: ", "exploding":"Expoding: ", "spd":"Walk Speed Bonus:", "atkTier":"Attack Speed Bonus: ", "eDamPct":"Earth Damage %: ", "tDamPct":"Thunder Damage %: ", "wDamPct":"Water Damage %: ", "fDamPct":"Fire Damage %: ", "aDamPct":"Air Damage %: ", "eDefPct":"Earth Defense %: ", "tDefPct":"Thunder Defense %: ", "wDefPct":"Water Defense %: ", "fDefPct":"Fire Defense %: ", "aDefPct":"Air Defense %: ", "spPct1":"1st Spell Cost %: ", "spRaw1":"1st Spell Cost Raw: ", "spPct2":"2nd Spell Cost %: ", "spRaw2":"2nd Spell Cost Raw: ", "spPct3":"3rd Spell Cost %: ", "spRaw3":"3rd Spell Cost Raw: ", "spPct4":"4th Spell Cost %: ", "spRaw4":"4th Spell Cost Raw: ", "rainbowRaw":"Rainbow Spell Damage Raw: ", "sprint":"Sprint Bonus: ", "sprintReg":"Sprint Regen Bonus: ", "jh":"Jump Height: ", "xpb":"Combat XP Bonus: ", "lb":"Loot Bonus: ", "lq":"Loot Quality: ", "spRegen":"Soul Point Regen: ", "eSteal":"Stealing: ", "gXp":"Gathering XP Bonus: ", "gSpd":"Gathering Speed Bonus: ", "slots":"Powder Slots: ", "set":"This item belongs to the ", "quest":"This item is the ", "restrict":""}; let idPrefixes = {"lvl":"Combat Level Min: ", "classReq":"Class Req: ","strReq":"Strength Min: ","dexReq":"Dexterity Min: ","intReq":"Intelligence Min: ","defReq":"Defense Min: ","agiReq":"Agility Min: ", "nDam":"Neutral Damage: ", "eDam":"Earth Damage: ", "tDam":"Thunder Damage: ", "wDam":"Water Damage: ", "fDam":"Fire Damage: ", "aDam":"Air Damage: ", "atkSpd":"Attack Speed: ", "hp":"Health: ", "eDef":"Earth Defense: ", "tDef":"Thunder Defense: ", "wDef":"Water Defense: ", "fDef":"Fire Defense: ", "aDef":"Air Defense: ", "str":"Strength: ", "dex":"Dexterity: ", "int":"Intelligence: ", "def":"Defense: ","agi":"Agility: ", "hpBonus":"Health Bonus: ", "hprRaw":"Health Regen Raw: ", "hprPct":"Health Regen %: ", "sdRaw":"Raw Spell Damage: ", "sdPct":"Spell Damage %: ", "mdRaw":"Main Attack Neutral Damage: ", "mdPct":"Main Attack Damage %: ", "mr":"Mana Regen: ", "ms":"Mana Steal: ", "ref":"Reflection: ", "ls":"Life Steal: ", "poison":"Poison: ", "thorns":"Thorns: ", "exploding":"Expoding: ", "spd":"Walk Speed Bonus: ", "atkTier":"Attack Speed Bonus: ", "eDamPct":"Earth Damage %: ", "tDamPct":"Thunder Damage %: ", "wDamPct":"Water Damage %: ", "fDamPct":"Fire Damage %: ", "aDamPct":"Air Damage %: ", "eDefPct":"Earth Defense %: ", "tDefPct":"Thunder Defense %: ", "wDefPct":"Water Defense %: ", "fDefPct":"Fire Defense %: ", "aDefPct":"Air Defense %: ", "spPct1":"1st Spell Cost %: ", "spRaw1":"1st Spell Cost Raw: ", "spPct2":"2nd Spell Cost %: ", "spRaw2":"2nd Spell Cost Raw: ", "spPct3":"3rd Spell Cost %: ", "spRaw3":"3rd Spell Cost Raw: ", "spPct4":"4th Spell Cost %: ", "spRaw4":"4th Spell Cost Raw: ", "rainbowRaw":"Rainbow Spell Damage Raw: ", "sprint":"Sprint Bonus: ", "sprintReg":"Sprint Regen Bonus: ", "jh":"Jump Height: ", "xpb":"Combat XP Bonus: ", "lb":"Loot Bonus: ", "lq":"Loot Quality: ", "spRegen":"Soul Point Regen: ", "eSteal":"Stealing: ", "gXp":"Gathering XP Bonus: ", "gSpd":"Gathering Speed Bonus: ", "slots":"Powder Slots: ", "set":"This item belongs to the ", "quest":"This item is from the quest", "restrict":""};
let idSuffixes = {"lvl":"", "classReq":"","strReq":"","dexReq":"","intReq":"","defReq":"","agiReq":"", "nDam":"", "eDam":"", "tDam":"", "wDam":"", "fDam":"", "aDam":"", "atkSpd":"", "hp":"", "eDef":"", "tDef":"", "wDef":"", "fDef":"", "aDef":"", "str":"", "dex":"", "int":"", "def":"","agi":"", "hpBonus":"", "hprRaw":"", "hprPct":"%", "sdRaw":"", "sdPct":"%", "mdRaw":"", "mdPct":"%", "mr":"/4s", "ms":"/4s", "ref":"%", "ls":"/4s", "poison":"/3s", "thorns":"%", "exploding":"%", "spd":"%", "atkTier":" tier", "eDamPct":"%", "tDamPct":"%", "wDamPct":"%", "fDamPct":"%", "aDamPct":"%", "eDefPct":"%", "tDefPct":"%", "wDefPct":"%", "fDefPct":"%", "aDefPct":"%", "spPct1":"%", "spRaw1":"", "spPct2":"%", "spRaw2":"", "spPct3":"%", "spRaw3":"", "spPct4":"%", "spRaw4":"", "rainbowRaw":"", "sprint":"%", "sprintReg":"%", "jh":"", "xpb":"%", "lb":"%", "lq":"%", "spRegen":"%", "eSteal":"%", "gXp":"%", "gSpd":"%", "slots":"", "set":" set.", "quest":" quest.", "restrict":""}; let idSuffixes = {"lvl":"", "classReq":"","strReq":"","dexReq":"","intReq":"","defReq":"","agiReq":"", "nDam":"", "eDam":"", "tDam":"", "wDam":"", "fDam":"", "aDam":"", "atkSpd":"", "hp":"", "eDef":"", "tDef":"", "wDef":"", "fDef":"", "aDef":"", "str":"", "dex":"", "int":"", "def":"","agi":"", "hpBonus":"", "hprRaw":"", "hprPct":"%", "sdRaw":"", "sdPct":"%", "mdRaw":"", "mdPct":"%", "mr":"/4s", "ms":"/4s", "ref":"%", "ls":"/4s", "poison":"/3s", "thorns":"%", "exploding":"%", "spd":"%", "atkTier":" tier", "eDamPct":"%", "tDamPct":"%", "wDamPct":"%", "fDamPct":"%", "aDamPct":"%", "eDefPct":"%", "tDefPct":"%", "wDefPct":"%", "fDefPct":"%", "aDefPct":"%", "spPct1":"%", "spRaw1":"", "spPct2":"%", "spRaw2":"", "spPct3":"%", "spRaw3":"", "spPct4":"%", "spRaw4":"", "rainbowRaw":"", "sprint":"%", "sprintReg":"%", "jh":"", "xpb":"%", "lb":"%", "lq":"%", "spRegen":"%", "eSteal":"%", "gXp":"%", "gSpd":"%", "slots":"", "set":" set.", "quest":".", "restrict":""};
let itemString = ""; let itemString = "";
itemString = itemString.concat(item.get("name"),"<br><br>"); itemString = itemString.concat(item.get("name"),"<br><br>");
if(item.has("fixID") && item.get("fixID")){//fixed IDs if(item.has("fixID") && item.get("fixID")){//fixed IDs
@ -264,25 +312,25 @@ function idRound(id){
} }
function resetFields(){ function resetFields(){
document.getElementById("helmet-choice").value = ""; setValue("helmet-choice", "");
document.getElementById("helmet-powder").value = ""; setValue("helmet-powder", "");
document.getElementById("chestplate-choice").value = ""; setValue("chestplate-choice", "");
document.getElementById("chestplate-powder").value = ""; setValue("chestplate-powder", "");
document.getElementById("leggings-choice").value = ""; setValue("leggings-choice", "");
document.getElementById("leggings-powder").value = ""; setValue("leggings-powder", "");
document.getElementById("boots-choice").value = ""; setValue("boots-choice", "");
document.getElementById("boots-powder").value = ""; setValue("boots-powder", "");
document.getElementById("ring1-choice").value = ""; setValue("ring1-choice", "");
document.getElementById("ring2-choice").value = ""; setValue("ring2-choice", "");
document.getElementById("bracelet-choice").value = ""; setValue("bracelet-choice", "");
document.getElementById("necklace-choice").value = ""; setValue("necklace-choice", "");
document.getElementById("weapon-choice").value = ""; setValue("weapon-choice", "");
document.getElementById("weapon-powder").value = ""; setValue("weapon-powder", "");
document.getElementById("str-skp").value = ""; setValue("str-skp", "");
document.getElementById("dex-skp").value = ""; setValue("dex-skp", "");
document.getElementById("int-skp").value = ""; setValue("int-skp", "");
document.getElementById("def-skp").value = ""; setValue("def-skp", "");
document.getElementById("agi-skp").value = ""; setValue("agi-skp", "");
} }
load_init(init); load_init(init);

31
utils.js Normal file
View file

@ -0,0 +1,31 @@
// Permutations in js reference (also cool algorithm):
// https://stackoverflow.com/a/41068709
function perm(a){
if (a.length == 0) return [[]];
var r = [[a[0]]],
t = [],
s = [];
if (a.length == 1) return r;
for (var i = 1, la = a.length; i < la; i++){
for (var j = 0, lr = r.length; j < lr; j++){
r[j].push(a[i]);
t.push(r[j]);
for(var k = 1, lrj = r[j].length; k < lrj; k++){
for (var l = 0; l < lrj; l++) s[l] = r[j][(k+l)%lrj];
t[t.length] = s;
s = [];
}
}
r = t;
t = [];
}
return r;
}
function setHTML(id, html) {
document.getElementById(id).innerHTML = html;
}
function setValue(id, value) {
document.getElementById(id).value = value;
}