Skillpoints engine

This commit is contained in:
b 2021-01-07 00:41:41 -06:00
parent 2b95c69176
commit 55ba7f4fc2
9 changed files with 365 additions and 74 deletions

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 */
} }

View file

@ -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",

View file

@ -123,24 +123,49 @@
</div> </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> <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> <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> <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> <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> <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">
@ -162,10 +187,16 @@
</div> </div>
<div class = "center" id = "build-weapon" style = "grid-column:1;grid-row:3"> <div class = "center" id = "build-weapon" style = "grid-column:1;grid-row:3">
</div> </div>
<div class = "center" id = "build-cumulative-stats" style = "grid-column:2;grid-row:3"> <div class = "center" id = "build-order" style = "grid-column:2;grid-row:3">
</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];
} }
/* /*

View file

@ -13,18 +13,40 @@ def clean_item(item):
items = data["items"] items = data["items"]
item_map = {clean_item(item)["displayName"]: item for item in 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 = [ build_items_names = [
"Cumulonimbus", "Blue Mask",
"Soulflare", "Sparkling Plate",
"Leictreach Makani", "Gemini",
"Slayer", "Slayer",
"Intensity", "Draoi Fair",
"Moon Pool Circlet", "Moon Pool Circlet",
"Diamond Static Bracelet", "Prowess",
"Royal Stormy Amulet" "Diamond Fusion Necklace"
] ]
build_weapon_name = "Praesidium"
build_items = [item_map[item] for item in build_items_names] build_items = [item_map[item] for item in build_items_names]
build_weapon_name = "Fatal"
build_weapon = item_map[build_weapon_name] build_weapon = item_map[build_weapon_name]
for item in build_items: for item in build_items:
@ -33,9 +55,6 @@ for item in build_items:
print(build_weapon) print(build_weapon)
def is_reqless(item):
return all(x == 0 for x in item["reqs"])
# Consolidate skillpoint and req into arrays for ease of processing. # Consolidate skillpoint and req into arrays for ease of processing.
def setup(item): def setup(item):
item["skillpoints"] = [item["str"], item["dex"], item["int"], item["def"], item["agi"]] item["skillpoints"] = [item["str"], item["dex"], item["int"], item["def"], item["agi"]]
@ -44,28 +63,40 @@ def setup(item):
fixed = [] fixed = []
consider = [] consider = []
noboost = []
for item in build_items: for item in build_items:
setup(item) setup(item)
if (is_reqless(item)): if all(x == 0 for x in item["reqs"]):
fixed.append(item) fixed.append(item)
elif all(x == 0 for x in item["skillpoints"]):
noboost.append(item)
else: else:
consider.append(item) consider.append(item)
setup(build_weapon) setup(build_weapon)
fixed = tuple(fixed)
noboost = tuple(noboost)
# Apply the skillpoints an item gives to the build. # Apply the skillpoints an item gives to the build.
def apply_skillpoints(skillpoints, item): def apply_skillpoints(skillpoints, item):
for i in range(5): for i in range(5):
skillpoints[i] += item["skillpoints"][i] 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. # Figure out (naively) how many skillpoints need to be applied to get the current item to fit.
# Doesn't handle -skp. # Doesn't handle -skp.
def apply_to_fit(skillpoints, item): def apply_to_fit(skillpoints, item):
applied = [0, 0, 0, 0, 0] applied = [0, 0, 0, 0, 0]
total = 0
for i, req, cur in zip(range(5), item["reqs"], skillpoints): for i, req, cur in zip(range(5), item["reqs"], skillpoints):
if req > cur: if req > cur:
applied[i] += req - cur diff = req - cur
return applied applied[i] += diff
total += diff
return applied, total
# Permutations in js reference (also cool algorithm): # Permutations in js reference (also cool algorithm):
# https://stackoverflow.com/a/41068709 # https://stackoverflow.com/a/41068709
@ -77,6 +108,7 @@ for item in fixed:
apply_skillpoints(static_skillpoints_base, item) apply_skillpoints(static_skillpoints_base, item)
best = None best = None
final_skillpoints = None
best_skillpoints = [0, 0, 0, 0, 0] best_skillpoints = [0, 0, 0, 0, 0]
best_total = math.inf best_total = math.inf
@ -84,24 +116,48 @@ best_total = math.inf
import itertools import itertools
for permutation in itertools.permutations(consider): for permutation in itertools.permutations(consider):
permutation += ( build_weapon, ) permutation += noboost
skillpoints_applied = [0, 0, 0, 0, 0] skillpoints_applied = [0, 0, 0, 0, 0]
skillpoints = copy.copy(static_skillpoints_base) skillpoints = copy.copy(static_skillpoints_base)
total_applied = 0
for item in permutation: for item in permutation:
needed_skillpoints = apply_to_fit(skillpoints, item) needed_skillpoints, total_diff = apply_to_fit(skillpoints, item)
for i in range(5): for i in range(5):
skillpoints_applied[i] += needed_skillpoints[i] skillpoints_applied[i] += needed_skillpoints[i]
skillpoints[i] += needed_skillpoints[i] skillpoints[i] += needed_skillpoints[i]
apply_skillpoints(skillpoints, item) apply_skillpoints(skillpoints, item)
total_applied = sum(skillpoints_applied) 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: if total_applied < best_total:
best = permutation best = permutation
final_skillpoints = skillpoints
best_skillpoints = skillpoints_applied best_skillpoints = skillpoints_applied
best_total = total_applied best_total = total_applied
print([i["displayName"] for i in fixed + list(best)]) print([i["displayName"] for i in fixed + best])
print(best_skillpoints) print(best_skillpoints)
print(final_skillpoints)
print(best_total) print(best_total)
#def attempt(skillpoints, items_in_order): #def attempt(skillpoints, items_in_order):

131
skillpoints.js Normal file
View file

@ -0,0 +1,131 @@
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++) {
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) {
for (const item of permutation) {
remove_skillpoints(skillpoints, item);
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;
}
}
}
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];
}
}

View file

@ -29,5 +29,5 @@
grid-template-columns: repeat(4, 1fr); grid-template-columns: repeat(4, 1fr);
gap: 10px; gap: 10px;
grid-auto-rows: minmax(60px, auto); grid-auto-rows: minmax(60px, auto);
width: 100vw; /* width: 100vw; */
} }

104
test.js
View file

@ -39,16 +39,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 Chesptlate", 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) {
@ -162,37 +178,49 @@ function calculateBuild(){
itemMap.get(weapon), itemMap.get(weapon),
); );
console.log(player_build.toString()); console.log(player_build.toString());
document.getElementById("build-helmet").innerHTML = player_build.helmet.name;
document.getElementById("build-chestplate").innerHTML = player_build.chestplate.name; player_build.equip_order;
document.getElementById("build-leggings").innerHTML = player_build.helmet.name; player_build.base_skillpoints;
document.getElementById("build-boots").innerHTML = player_build.helmet.name; let skillpoints = player_build.total_skillpoints;
document.getElementById("build-ring1").innerHTML = player_build.ring1.name; setValue("str-skp", skillpoints[0]);
document.getElementById("build-ring2").innerHTML = player_build.ring2.name; setValue("dex-skp", skillpoints[1]);
document.getElementById("build-bracelet").innerHTML = player_build.bracelet.name; setValue("int-skp", skillpoints[2]);
document.getElementById("build-necklace").innerHTML = player_build.necklace.name; setValue("def-skp", skillpoints[3]);
document.getElementById("build-weapon").innerHTML = player_build.weapon.name; setValue("agi-skp", skillpoints[4]);
console.log(skillpoints);
player_build.assigned_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);
} }
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;
}