many crafted item fixes, crafted item saving implemented, crafted items in builds implemented, build saving with crafted items not implemented.

This commit is contained in:
ferricles 2021-01-30 00:50:25 -08:00
parent b0c23d86a8
commit 07cafe0c0a
9 changed files with 276 additions and 168 deletions

142
build.js
View file

@ -105,7 +105,8 @@ class Build{
constructor(level,equipment, powders, externalStats, inputerrors=[]){
let errors = inputerrors;
//this contains the Craft objects, if there are any crafted items. this.helmet, etc. will contain the statMap of the Craft (which is built to be an expandedItem).
this.craftedItems = [];
// 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") {
@ -113,72 +114,133 @@ class Build{
this.powders[0] = this.powders[0].slice(0,helmet.slots);
this.helmet = expandItem(helmet, this.powders[0]);
}else{
const helmet = itemMap.get("No Helmet");
this.powders[0] = this.powders[0].slice(0,helmet.slots);
this.helmet = expandItem(helmet, this.powders[0]);
errors.push(new ItemNotFound(equipment[0], "helmet", true));
try {
let helmet = getCraftFromHash(equipment[0]);
this.powders[0] = this.powders[0].slice(0,helmet.statMap.slots);
helmet.statMap.set("powders",this.powders[0].slice());
helmet.applyPowders();
this.helmet = helmet.statMap;
this.craftedItems.push(helmet);
} catch (Error) {
//console.log(Error); //fix
const helmet = itemMap.get("No Helmet");
this.powders[0] = this.powders[0].slice(0,helmet.slots);
this.helmet = expandItem(helmet, this.powders[0]);
errors.push(new ItemNotFound(equipment[0], "helmet", true));
}
}
if(itemMap.get(equipment[1]) && itemMap.get(equipment[1]).type === "chestplate") {
const chestplate = itemMap.get(equipment[1]);
this.powders[1] = this.powders[1].slice(0,chestplate.slots);
this.chestplate = expandItem(chestplate, this.powders[1]);
}else{
const chestplate = itemMap.get("No Chestplate");
this.powders[1] = this.powders[1].slice(0,chestplate.slots);
this.chestplate = expandItem(chestplate, this.powders[1]);
errors.push(new ItemNotFound(equipment[1], "chestplate", true));
try {
let chestplate = getCraftFromHash(equipment[1]);
this.powders[1] = this.powders[1].slice(0,chestplate.statMap.slots);
chestplate.statMap.set("powders",this.powders[1].slice());
chestplate.applyPowders();
this.chestplate = chestplate.statMap;
this.craftedItems.push(chestplate);
} catch (Error) {
const chestplate = itemMap.get("No Chestplate");
this.powders[1] = this.powders[1].slice(0,chestplate.slots);
this.chestplate = expandItem(chestplate, this.powders[1]);
errors.push(new ItemNotFound(equipment[1], "chestplate", true));
}
}
if(itemMap.get(equipment[2]) && itemMap.get(equipment[2]).type === "leggings") {
const leggings = itemMap.get(equipment[2]);
this.powders[2] = this.powders[2].slice(0,leggings.slots);
this.leggings = expandItem(leggings, this.powders[2]);
}else{
const leggings = itemMap.get("No Leggings");
this.powders[2] = this.powders[2].slice(0,leggings.slots);
this.leggings = expandItem(leggings, this.powders[2]);
errors.push(new ItemNotFound(equipment[2], "leggings", true));
try {
let leggings = getCraftFromHash(equipment[2]);
this.powders[2] = this.powders[2].slice(0,leggings.statMap.slots);
leggings.statMap.set("powders",this.powders[2].slice());
leggings.applyPowders();
this.leggings = leggings.statMap;
this.craftedItems.push(leggings);
} catch (Error) {
const leggings = itemMap.get("No Leggings");
this.powders[2] = this.powders[2].slice(0,leggings.slots);
this.leggings = expandItem(leggings, this.powders[2]);
errors.push(new ItemNotFound(equipment[2], "leggings", true));
}
}
if(itemMap.get(equipment[3]) && itemMap.get(equipment[3]).type === "boots") {
const boots = itemMap.get(equipment[3]);
this.powders[3] = this.powders[3].slice(0,boots.slots);
this.boots = expandItem(boots, this.powders[3]);
}else{
const boots = itemMap.get("No Boots");
this.powders[3] = this.powders[3].slice(0,boots.slots);
this.boots = expandItem(boots, this.powders[3]);
errors.push(new ItemNotFound(equipment[3], "boots", true));
try {
let boots = getCraftFromHash(equipment[3]);
this.powders[3] = this.powders[3].slice(0,boots.statMap.slots);
boots.statMap.set("powders",this.powders[3].slice());
boots.applyPowders();
this.boots = boots.statMap;
this.craftedItems.push(boots);
} catch (Error) {
const boots = itemMap.get("No Boots");
this.powders[3] = this.powders[3].slice(0,boots.slots);
this.boots = expandItem(boots, this.powders[3]);
errors.push(new ItemNotFound(equipment[3], "boots", true));
}
}
if(itemMap.get(equipment[4]) && itemMap.get(equipment[4]).type === "ring") {
const ring = itemMap.get(equipment[4]);
this.ring1 = expandItem(ring, []);
}else{
const ring = itemMap.get("No Ring 1");
this.ring1 = expandItem(ring, []);
errors.push(new ItemNotFound(equipment[4], "ring1", true, "ring"));
try {
let ring = getCraftFromHash(equipment[4]);
this.ring1 = ring.statMap;
this.craftedItems.push(ring);
} catch (Error) {
const ring = itemMap.get("No Ring 1");
this.ring1 = expandItem(ring, []);
errors.push(new ItemNotFound(equipment[4], "ring1", true, "ring"));
}
}
if(itemMap.get(equipment[5]) && itemMap.get(equipment[5]).type === "ring") {
const ring = itemMap.get(equipment[5]);
this.ring2 = expandItem(ring, []);
}else{
const ring = itemMap.get("No Ring 2");
this.ring2 = expandItem(ring, []);
errors.push(new ItemNotFound(equipment[5], "ring2", true, "ring"));
try {
let ring = getCraftFromHash(equipment[5]);
this.ring2 = ring.statMap;
this.craftedItems.push(ring);
} catch (Error) {
const ring = itemMap.get("No Ring 2");
this.ring2 = expandItem(ring, []);
errors.push(new ItemNotFound(equipment[5], "ring2", true, "ring"));
}
}
if(itemMap.get(equipment[6]) && itemMap.get(equipment[6]).type === "bracelet") {
const bracelet = itemMap.get(equipment[6]);
this.bracelet = expandItem(bracelet, []);
}else{
const bracelet = itemMap.get("No Bracelet");
this.bracelet = expandItem(bracelet, []);
errors.push(new ItemNotFound(equipment[6], "bracelet", true));
try {
let bracelet = getCraftFromHash(equipment[6]);
this.bracelet = bracelet.statMap;
this.craftedItems.push(bracelet);
} catch (Error) {
const bracelet = itemMap.get("No Bracelet");
this.bracelet = expandItem(bracelet, []);
errors.push(new ItemNotFound(equipment[6], "bracelet", true));
}
}
if(itemMap.get(equipment[7]) && itemMap.get(equipment[7]).type === "necklace") {
const necklace = itemMap.get(equipment[7]);
this.necklace = expandItem(necklace, []);
}else{
const necklace = itemMap.get("No Necklace");
this.necklace = expandItem(necklace, []);
errors.push(new ItemNotFound(equipment[7], "necklace", true));
try {
let necklace = getCraftFromHash(equipment[7]);
this.necklace = necklace.statMap;
this.craftedItems.push(necklace);
} catch (Error) {
const necklace = itemMap.get("No Necklace");
this.necklace = expandItem(necklace, []);
errors.push(new ItemNotFound(equipment[7], "necklace", true));
}
}
if(itemMap.get(equipment[8]) && itemMap.get(equipment[8]).category === "weapon") {
const weapon = itemMap.get(equipment[8]);
@ -190,11 +252,20 @@ class Build{
document.getElementsByClassName("powder-specials")[0].style.display = "none";
}
}else{
const weapon = itemMap.get("No Weapon");
this.powders[4] = this.powders[4].slice(0,weapon.slots);
this.weapon = expandItem(weapon, this.powders[4]);
document.getElementsByClassName("powder-specials")[0].style.display = "none";
errors.push(new ItemNotFound(equipment[8], "weapon", true));
try {
let weapon = getCraftFromHash(equipment[8]);
this.weapon = weapon.statMap;
this.craftedItems.push(weapon);
this.powders[4] = this.powders[4].slice(0,this.weapon.slots);
this.weapon.set("powders",this.powders[4].slice());
document.getElementsByClassName("powder-specials")[0].style.display = "grid";
} catch (Error) {
const weapon = itemMap.get("No Weapon");
this.powders[4] = this.powders[4].slice(0,weapon.slots);
this.weapon = expandItem(weapon, this.powders[4]);
document.getElementsByClassName("powder-specials")[0].style.display = "none";
errors.push(new ItemNotFound(equipment[8], "weapon", true));
}
}
if (level < 1) { //Should these be constants?
@ -339,13 +410,12 @@ class Build{
let staticIDs = ["hp", "eDef", "tDef", "wDef", "fDef", "aDef"];
//Create a map of this build's stats
//This is universal for every possible build, so it's possible to move this elsewhere.
let statMap = new Map();
for (const staticID of staticIDs) {
statMap.set(staticID, 0);
}
statMap.set("hp", levelToHPBase(this.level)); //TODO: Add player base health
statMap.set("hp", levelToHPBase(this.level));
for (const item of this.items){
for (let [id, value] of item.get("maxRolls")) {

View file

@ -3,7 +3,7 @@ const url_tag = location.hash.slice(1);
console.log(url_base);
console.log(url_tag);
const BUILD_VERSION = "6.9.11";
const BUILD_VERSION = "6.9.20";
function setTitle() {
let text;
@ -20,10 +20,7 @@ function setTitle() {
setTitle();
let player_build;
// Set up item lists for quick access later.
let armorTypes = [ "helmet", "chestplate", "leggings", "boots" ];
let accessoryTypes = [ "ring", "bracelet", "necklace" ];
let weaponTypes = [ "wand", "spear", "bow", "dagger", "relik" ];
// THIS IS SUPER DANGEROUS, WE SHOULD NOT BE KEEPING THIS IN SO MANY PLACES
let item_fields = [ "name", "displayName", "tier", "set", "slots", "type", "material", "drop", "quest", "restrict", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "atkSpd", "hp", "fDef", "wDef", "aDef", "tDef", "eDef", "lvl", "classReq", "strReq", "dexReq", "intReq", "defReq", "agiReq", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "str", "dex", "int", "agi", "def", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "fixID", "category", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd", "id" ];
let editable_item_fields = [ "sdPct", "sdRaw", "mdPct", "mdRaw", "poison", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "hprRaw", "hprPct", "hpBonus", "atkTier", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4" ];
@ -170,9 +167,9 @@ function init() {
populateItemList(armorType);
// Add change listener to update armor slots.
document.getElementById(armorType+"-choice").addEventListener("change", (event) => {
let item = itemMap.get(event.target.value);
if (item !== undefined) {
document.getElementById(armorType+"-slots").textContent = item.slots + " slots";
let item = itemMap.has(event.target.value) ? itemMap.get(event.target.value) : (getCraftFromHash(event.target.value) != undefined ? getCraftFromHash(event.target.value).statMap : undefined);
if (item !== undefined && event.target.value !== "") {
document.getElementById(armorType+"-slots").textContent = (item["slots"] ? item["slots"] : item.get("slots"))+ " slots";
}
else {
document.getElementById(armorType+"-slots").textContent = "X slots";
@ -205,11 +202,10 @@ function init() {
// Add change listener to update weapon slots.
document.getElementById("weapon-choice").addEventListener("change", (event) => {
let item = itemMap.get(event.target.value);
if (item !== undefined) {
document.getElementById("weapon-slots").textContent = item.slots + " slots";
}
else {
let item = itemMap.has(event.target.value) ? itemMap.get(event.target.value) : (getCraftFromHash(event.target.value) != undefined ? getCraftFromHash(event.target.value).statMap : undefined);
if (item !== undefined && event.target.value !== "") {
document.getElementById("weapon-slots").textContent = (item["slots"] ? item["slots"] : item.get("slots"))+ " slots";
} else {
document.getElementById("weapon-slots").textContent = "X slots";
}
});
@ -241,8 +237,7 @@ function decodeBuild(url_tag) {
for (let i = 0; i < 9; ++i ) {
equipment[i] = getItemNameFromID(Base64.toInt(equipments.slice(i*3,i*3+3)));
}
}
if (version === "1") {
} else if (version === "1") {
let powder_info = info[1].slice(27);
console.log(powder_info);
// TODO: Make this run in linear instead of quadratic time... ew
@ -263,8 +258,7 @@ function decodeBuild(url_tag) {
}
powdering[i] = powders;
}
}
if (version === "2") {
} else if (version === "2") {
save_skp = true;
let skillpoint_info = info[1].slice(27, 37);
for (let i = 0; i < 5; ++i ) {
@ -291,8 +285,7 @@ function decodeBuild(url_tag) {
}
powdering[i] = powders;
}
}
if(version === "3"){
} else if (version === "3"){
level = Base64.toInt(info[1].slice(37,39));
setValue("level-choice",level);
save_skp = true;
@ -319,6 +312,8 @@ function decodeBuild(url_tag) {
}
powdering[i] = powders;
}
} else if (version === "4") { //crafted support
//@hpp
}
for (let i in powderInputs) {
setValue(powderInputs[i], powdering[i]);
@ -334,6 +329,7 @@ function decodeBuild(url_tag) {
*/
function encodeBuild() {
if (player_build) {
//@hpp update for 4_
let build_string = "3_" + Base64.fromIntN(player_build.helmet.get("id"), 3) +
Base64.fromIntN(player_build.chestplate.get("id"), 3) +
Base64.fromIntN(player_build.leggings.get("id"), 3) +
@ -406,7 +402,7 @@ function calculateBuild(save_skp, skp){
let equipment = [ null, null, null, null, null, null, null, null, null ];
for (let i in equipment) {
let equip = getValue(equipmentInputs[i]);
if (equip === "") equip = "No " + equipment_names[i];
if (equip === "") { equip = "No " + equipment_names[i] }
equipment[i] = equip;
}
let powderings = [];
@ -434,14 +430,14 @@ function calculateBuild(save_skp, skp){
else
errors.push(new IncorrectInput(errorederrors[0], "t6 or e3", powderInputs[i]));
}
console.log("POWDERING" + powdering);
console.log("POWDERING: " + powdering);
powderings.push(powdering);
}
console.log(equipment);
console.log(document.getElementById("level-choice").value);
player_build = new Build(document.getElementById("level-choice").value, equipment, powderings, new Map(), errors);
let level = document.getElementById("level-choice").value;
player_build = new Build(level, equipment, powderings, new Map(), errors);
console.log(player_build);
for (let i of document.getElementsByClassName("hide-container-block")) {
i.style.display = "block";
}

115
craft.js
View file

@ -1,31 +1,30 @@
let armorTypes = [ "helmet", "chestplate", "leggings", "boots" ];
let accessoryTypes = [ "ring", "bracelet", "necklace" ];
let weaponTypes = [ "wand", "spear", "bow", "dagger", "relik" ];
let consumableTypes = [ "potion", "scroll", "food"]
//constructs a craft from a hash 'CR-qwoefsabaoe' or 'qwoefsaboe'
function createCraft(hash) {
let name = hash;
function getCraftFromHash(hash) {
let name = hash.slice();
if (name.slice(0,3) === "CR-") {
name = name.substring(3);
}
this.hash = name;
ingreds = [];
/*for (let i = 0; i < 6; i ++ ) {
ingreds.push( ingIDMap.get(Base64.toInt(name.substring(2*i,2*i+2))) );
version = name.substring(0,1);
name = name.substring(1);
if (version === "1") {
let ingreds = [];
for (let i = 0; i < 6; i ++ ) {
ingreds.push( expandIngredient(ingMap.get(ingIDMap.get(Base64.toInt(name.substring(2*i,2*i+2))))) );
}
let recipe = expandRecipe(recipeMap.get(recipeIDMap.get(Base64.toInt(name.substring(12,14)))));
tierNum = Base64.toInt(name.substring(14,15));
let mat_tiers = [];
mat_tiers.push(tierNum % 3 == 0 ? 3 : tierNum % 3);
mat_tiers.push(Math.floor((tierNum-0.5) / 3)+1); //Trying to prevent round-off error, don't yell at me
let atkSpd = Base64.toInt(name.substring(15));
let atkSpds = ["SLOW","NORMAL","FAST"];
let attackSpeed = atkSpds[atkSpd];
return new Craft(recipe,mat_tiers,ingreds,attackSpeed,"1"+name);
}
let recipe = recipeIDMap.get(Base64.toInt(tag.substring(12,14)));
recipesName = recipe.split("-");
setValue("recipe-choice",recipesName[0]);
setValue("level-choice",recipesName[1]+"-"+recipesName[2]);
tierNum = Base64.toInt(tag.substring(14,15));
let mat_tiers = [];
mat_tiers.push(tierNum % 3 == 0 ? 3 : tierNum % 3);
mat_tiers.push(Math.floor((tierNum-0.5) / 3)+1); //Trying to prevent round-off error, don't yell at me
let atkSpd = Base64.toInt(tag.substring(15));
let atkSpds = ["SLOW,NORMAL,FAST"];
let attackSpeed atkSpds[atkSpd];
*/
}
@ -48,7 +47,21 @@ class Craft{
}
applyPowders() {
if (this.statMap.get("category") === "armor") {
//double apply armor powders
for(const id of this.statMap.get("powders")){
let powder = powderStats[id];
let name = powderNames.get(id);
this.statMap.set(name.charAt(0) + "Def", (this.statMap.get(name.charAt(0)+"Def") || 0) + 2 * powder["defPlus"]);
this.statMap.set(skp_elements[(skp_elements.indexOf(name.charAt(0)) + 4 )% 5] + "Def", (this.statMap.get(skp_elements[(skp_elements.indexOf(name.charAt(0)) + 4 )% 5]+"Def") || 0) - 2 * powder["defMinus"]);
}
}else if (this.statMap.get("category") === "weapon") {
//do nothing - weapon powders are handled in displayExpandedItem
}
}
setHash(hash) {
this.hash = hash;
this.statMap.set("displayName", "CR-" + this.hash);
@ -57,7 +70,7 @@ class Craft{
@pre The craft itself should be valid. No checking of validity of pieces is done here.
*/
initCraftStats(){
let consumables = ["POTION", "SCROLL", "FOOD"];
let statMap = new Map();
statMap.set("minRolls", new Map());
statMap.set("maxRolls", new Map());
@ -68,18 +81,22 @@ class Craft{
statMap.set("durability", [this.recipe.get("durability")[0], this.recipe.get("durability")[1]]);
statMap.set("lvl", (this.recipe.get("lvl")[0] + "-" + this.recipe.get("lvl")[1]) );
statMap.set("nDam", 0);
statMap.set("hp",0);
statMap.set("hpLow",0);
for (const e of skp_elements) {
statMap.set(e + "Dam", "0-0");
statMap.set(e + "Def", 0);
}
for (const e of skp_order) {
statMap.set(e + "Req", 0)
statMap.set(e, 0);
}
let allNone = true;
if (armorTypes.includes(statMap.get("type")) || weaponTypes.includes(statMap.get("type"))) {
statMap.set("category","weapon");
if(this.recipe.get("lvl")[0] < 30) {
statMap.set("slots", 1);
} else if (this.recipe.get("lvl") < 70) {
} else if (this.recipe.get("lvl")[0] < 70) {
statMap.set("slots", 2);
} else{
statMap.set("slots", 3);
@ -88,15 +105,16 @@ class Craft{
statMap.set("slots", 0);
}
if (consumableTypes.includes(statMap.get("type"))) {
statMap.set("category","consumable");
if(this.recipe.get("lvl")[0] < 30) {
statMap.set("charges", 1);
} else if (this.recipe.get("lvl") < 70) {
} else if (this.recipe.get("lvl")[0] < 70) {
statMap.set("charges", 2);
} else{
statMap.set("charges", 3);
}
//no ingredient consumables ALWAYS have 3 charges.
let allNone = true;
for(const ingred of this.ingreds) {
if(ingred.get("name") !== "No Ingredient") {
allNone = false;
@ -126,6 +144,9 @@ class Craft{
statMap.set("category","weapon");
statMap.set("atkSpd",this.atkSpd);
}
if (accessoryTypes.includes(statMap.get("type"))) {
statMap.set("category", "accessory");
}
statMap.set("powders",[]);
/* Change certain IDs based on material tier.
@ -152,8 +173,7 @@ class Craft{
let low = this.recipe.get("healthOrDamage")[0];
let high = this.recipe.get("healthOrDamage")[1];
if (statMap.get("category") === "consumable") {
//duration modifier
if(statMap.has("hp")) { //hack
if(allNone) {
statMap.set("hp", Math.floor( low * matmult )+ "-" + Math.floor( high * matmult ));
} else {
statMap.set("duration", [Math.floor( statMap.get("duration")[0] * matmult ), Math.floor( statMap.get("duration")[1] * matmult )]);
@ -229,7 +249,8 @@ class Craft{
}
low = Math.floor(low * matmult);
high = Math.floor(high * matmult);
statMap.set("hp",low+"-"+high);
statMap.set("hp",high);
statMap.set("hpLow",low);
}
/* END SECTION */
@ -293,11 +314,11 @@ class Craft{
let ingred = this.ingreds[n];
let eff_mult = (eff_flat[n] / 100).toFixed(2);
for (const [key, value] of ingred.get("itemIDs")) {
if(key !== "dura") {
if(key !== "dura" && !consumableTypes.includes(statMap.get("type"))) { //consumables NEVER get reqs
if (!ingred.get("isPowder")) {
statMap.set(key, Math.floor(statMap.get(key) + value*eff_mult)); //CHECK IF THIS IS CORRECT
statMap.set(key, Math.round(statMap.get(key) + value*eff_mult));
} else {
statMap.set(key, Math.floor(statMap.get(key) + value));
statMap.set(key, Math.round(statMap.get(key) + value));
}
} else { //durability, NOT affected by effectiveness
statMap.set("durability", statMap.get("durability").map(x => x + value));
@ -320,16 +341,34 @@ class Craft{
}
}
}
for (const e of skp_order) {
statMap.set(e,statMap.get("maxRolls").get(e));
}
for (const d in statMap.get("durability")) {
if(statMap.get("durability")[d] < 1) { statMap.get("durability")[d] = 1;}
if(statMap.get("durability")[d] < 1) { statMap.get("durability")[d] = 1;}
else {
statMap.get("durability")[d] = Math.floor(statMap.get("durability")[d]);
}
}
for (const d in statMap.get("duration")) {
if(statMap.get("duration")[d] < 1) { statMap.get("duration")[d] = 1;}
if(statMap.get("duration")[d] < 10) { statMap.get("duration")[d] = 10;}
}
if(statMap.has("charges") && statMap.get("charges") < 1 ) { statMap.set("charges",1)}
statMap.set("reqs",[0,0,0,0,0]);
statMap.set("skillpoints", [0,0,0,0,0]);
statMap.set("damageBonus",[0,0,0,0,0]);
for (const e in skp_order) {
statMap.set(skp_order[e], statMap.get("maxRolls").has(skp_order[e]) ? statMap.get("maxRolls").get(skp_order[e]) : 0);
statMap.get("skillpoints")[e] = statMap.get("maxRolls").has(skp_order[e]) ? statMap.get("maxRolls").get(skp_order[e]) : 0;
statMap.get("reqs")[e] = statMap.has(skp_order[e]+"Req") && !consumableTypes.includes(statMap.get("type"))? statMap.get(skp_order[e]+"Req") : 0;
statMap.get("damageBonus")[e] = statMap.has(skp_order[e]+"DamPct") ? statMap.get(skp_order[e]+"DamPct") : 0;
}
for (const id of rolledIDs) {
if (statMap.get("minRolls").has(id)) {
continue;
} else {
statMap.get("minRolls").set(id,0);
statMap.get("maxRolls").set(id,0);
}
}
this.statMap = statMap;
}
}

View file

@ -2,14 +2,14 @@
* TESTING SECTION
*/
const url_base = location.href.split("#")[0];
const url_tag = location.hash.slice(1);
console.log(url_base);
console.log(url_tag);
const ing_url_base = location.href.split("#")[0];
const ing_url_tag = location.hash.slice(1);
console.log(ing_url_base);
console.log(ing_url_tag);
const BUILD_VERSION = "6.9.11";
const ING_BUILD_VERSION = "6.9.20";
/*
* END testing section
*/
@ -26,13 +26,13 @@ let ingFields = ["fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "hprPct"
let player_craft;
function setTitle() {
document.getElementById("header").textContent = "WynnCrafter version "+BUILD_VERSION+" (ingredient db version "+ING_DB_VERSION+")";
document.getElementById("header").textContent = "WynnCrafter version "+ING_BUILD_VERSION+" (ingredient db version "+ING_DB_VERSION+")";
document.getElementById("header").classList.add("funnynumber");
let disclaimer = document.createElement("p");
disclaimer.textContent = "THIS CRAFTER IS NEARLY COMPLETE. The effect of material tiers on crafted items is not 100% tested and accurate. If you know how the math behind it works OR if you have a crafted item whose stats contradict this crafter, please contact ferricles on forums, discord, or ingame.";
document.getElementById("header").append(disclaimer);
}
setTitle();
let ingMap = new Map();
let ingList = [];
@ -111,20 +111,25 @@ function init() {
console.log(ings);
console.log("all recipes");
console.log(recipes);
console.log(ingList);
/*console.log(ingList);
console.log(recipeList);
console.log(ingIDMap);
console.log(recipeIDMap);
document.getElementById("recipe-choice").addEventListener("change", (event) => {
updateMaterials();
});
document.getElementById("level-choice").addEventListener("change", (event) => {
updateMaterials();
});
populateFields();
decodeCraft(url_tag);
console.log(recipeIDMap);*/
try {
document.getElementById("recipe-choice").addEventListener("change", (event) => {
updateMaterials();
});
document.getElementById("level-choice").addEventListener("change", (event) => {
updateMaterials();
});
populateFields();
decodeCraft(ing_url_tag);
setTitle();
} catch (Error) {
console.log("If you are seeing this while building, do not worry. Oherwise, panic! (jk contact ferricles)");
}
}
function updateMaterials() {
@ -198,7 +203,7 @@ function calculateCraft() {
player_craft = new Craft(recipe,mat_tiers,ingreds,atkSpd,"");
location.hash = encodeCraft();
player_craft.setHash(encodeCraft().split("_")[1]);
player_craft.setHash(encodeCraft());
console.log(player_craft);
/*console.log(recipe)
console.log(levelrange)
@ -237,7 +242,7 @@ function calculateCraft() {
function encodeCraft() {
if (player_craft) {
let atkSpds = ["SLOW","NORMAL","FAST"];
let craft_string = "1_" +
let craft_string = "1" +
Base64.fromIntN(player_craft.ingreds[0].get("id"), 2) +
Base64.fromIntN(player_craft.ingreds[1].get("id"), 2) +
Base64.fromIntN(player_craft.ingreds[2].get("id"), 2) +
@ -251,19 +256,19 @@ function encodeCraft() {
}
return "";
}
function decodeCraft(url_tag) {
if (url_tag) {
let info = url_tag.split("_");
let version = info[0];
let tag = info[1];
function decodeCraft(ing_url_tag) {
if (ing_url_tag) {
console.log(ing_url_tag);
let version = ing_url_tag.charAt(0);
let tag = ing_url_tag.substring(1);
if (version === "1") {
ingreds = [];
for (let i = 0; i < 6; i ++ ) {
setValue("ing-choice-"+(i+1), ingIDMap.get(Base64.toInt(tag.substring(2*i,2*i+2))));
console.log(Base64.toInt(tag.substring(2*i,2*i+2)));
//console.log(Base64.toInt(tag.substring(2*i,2*i+2)));
}
recipe = recipeIDMap.get(Base64.toInt(tag.substring(12,14)));
console.log(Base64.toInt(tag.substring(12,14)));
//console.log(Base64.toInt(tag.substring(12,14)));
recipesName = recipe.split("-");
setValue("recipe-choice",recipesName[0]);
setValue("level-choice",recipesName[1]+"-"+recipesName[2]);
@ -322,7 +327,7 @@ function toggleButton(buttonId) {
*/
function copyRecipe(){
if (player_craft) {
copyTextToClipboard(url_base+location.hash);
copyTextToClipboard(ing_url_base+location.hash);
document.getElementById("copy-button").textContent = "Copied!";
}
}
@ -331,7 +336,7 @@ function copyRecipe(){
*/
function shareRecipe(){
if (player_craft) {
let copyString = url_base+location.hash + "\n";
let copyString = ing_url_base+location.hash + "\n";
let name = player_craft.recipe.get("name").split("-");
copyString += " > " + name[0] + " " + "Lv. " + name[1] + "-" + name[2] + " (" + player_craft.mat_tiers[0] + "\u272B, " + player_craft.mat_tiers[1] + "\u272B)\n";
let names = [

View file

@ -40,7 +40,14 @@ function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier,
}
//console.log(damages);
let rawBoosts = [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]];
for (const powderID of weapon.get("powders")) {
//Double powder apply for weapons
let powders = weapon.get("powders").slice();
if (weapon.get("tier") === "Crafted") {
powders = powders.flatMap(x => [x,x]);
}
//apply powders to weapon
for (const powderID of powders) {
const powder = powderStats[powderID];
// Bitwise to force conversion to integer (integer division).
const element = (powderID/6) | 0;

View file

@ -60,17 +60,14 @@ function expandItem(item, powders){
expandedItem.set("minRolls",minRolls);
expandedItem.set("maxRolls",maxRolls);
expandedItem.set("powders", powders);
if(expandedItem.get("category") == "armor"){ //item is armor
if(item.category === "armor") {
for(const id of 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") || 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"]);
}
}
//console.log(expandedItem);
return expandedItem;
}
@ -453,7 +450,7 @@ function displayExpandedItem(item, parent_id){
item.set(damage_keys[i], damagesLow[i][0]+"-"+damagesLow[i][1]+"\u279c"+damages[i][0]+"-"+damages[i][1]);
}
}
} else if (item.get("category") === "armor") {
}
let display_commands = [
@ -543,8 +540,6 @@ function displayExpandedItem(item, parent_id){
let p_elem = document.createElement("p");
// PROPER POWDER DISPLAYING
let numerals = new Map([[1, "I"], [2, "II"], [3, "III"], [4, "IV"], [5, "V"], [6, "VI"]]);
/*p_elem.textContent = idPrefixes[id].concat(item.get(id), idSuffixes[id]) +
" [ " + item.get("powders").map(x => powderNames.get(x)) + " ]";*/
let powderPrefix = document.createElement("b");
powderPrefix.classList.add("powderLeft");
@ -553,7 +548,6 @@ function displayExpandedItem(item, parent_id){
p_elem.appendChild(powderPrefix);
let powders = item.get("powders");
//console.log(powders);
for (let i = 0; i < powders.length; i++) {
let powder = document.createElement("b");
powder.textContent = numerals.get((powders[i]%6)+1)+" ";
@ -569,9 +563,11 @@ function displayExpandedItem(item, parent_id){
active_elem.appendChild(p_elem);
} else {
let p_elem;
if( (!skp_order.includes(id)) || (skp_order.includes(id) && item.get("tier") !== "Crafted" && active_elem.nodeName === "DIV") ) { //skp
if ( !(item.get("tier") === "Crafted" && item.get("category") === "armor" && id === "hp") && (!skp_order.includes(id)) || (skp_order.includes(id) && item.get("tier") !== "Crafted" && active_elem.nodeName === "DIV") ) { //skp warp
p_elem = displayFixedID(active_elem, id, item.get(id), elemental_format);
}
} else if (item.get("tier") === "Crafted" && item.get("category") === "armor" && id === "hp") {
p_elem = displayFixedID(active_elem, id, item.get(id+"Low")+"-"+item.get(id), elemental_format);
}
if (id === "displayName") {
p_elem.classList.add("title");
if (item.get("tier") !== " ") {
@ -592,18 +588,7 @@ function displayExpandedItem(item, parent_id){
bckgrd.classList.add("itemp");
active_elem.appendChild(bckgrd);
bckgrd.appendChild(img);
/*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
if ( item.get("tier") !== "Crafted" && active_elem.nodeName === "DIV") {
p_elem.textContent = "";

View file

@ -1005,9 +1005,9 @@
<script type="text/javascript" src="damage_calc.js"></script>
<script type="text/javascript" src="display.js"></script>
<script type="text/javascript" src="load.js"></script>
<!--script type="text/javascript" src="load_ing.js"></script>
<script type="text/javascript" src="load_ing.js"></script>
<script type="text/javascript" src="craft.js"></script>
<script type="text/javascript" src="crafter.js"></script-->
<script type="text/javascript" src="crafter.js"></script>
<script type="text/javascript" src="build.js"></script>
<script type="text/javascript" src="builder.js"></script>
</body>

View file

@ -2,8 +2,8 @@ const ING_DB_VERSION = 4;
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js
let db;
let reload = false;
let idb;
let ireload = false;
let ings;
let recipes;
@ -11,7 +11,7 @@ let recipes;
* Load item set from local DB. Calls init() on success.
*/
async function ing_load_local(init_func) {
let get_tx = db.transaction(['ing_db', 'recipe_db'], 'readonly');
let get_tx = idb.transaction(['ing_db', 'recipe_db'], 'readonly');
let ings_store = get_tx.objectStore('ing_db');
let recipes_store = get_tx.objectStore('recipe_db');
let request3 = ings_store.getAll();
@ -32,7 +32,7 @@ async function ing_load_local(init_func) {
init_func();
}
await get_tx.complete;
db.close();
idb.close();
}
/*
@ -63,12 +63,12 @@ async function load_ings(init_func) {
await clear_tx2.complete;
await clear_tx3.complete;*/
let add_promises = [];
let add_tx2 = db.transaction(['ing_db'], 'readwrite');
let add_tx2 = idb.transaction(['ing_db'], 'readwrite');
let ings_store = add_tx2.objectStore('ing_db');
for (const ing in ings) {
add_promises.push(ings_store.add(ings[ing], ing));
}
let add_tx3 = db.transaction(['recipe_db'], 'readwrite');
let add_tx3 = idb.transaction(['recipe_db'], 'readwrite');
let recipes_store = add_tx3.objectStore('recipe_db');
for (const recipe in recipes) {
add_promises.push(recipes_store.add(recipes[recipe], recipe));
@ -76,7 +76,7 @@ async function load_ings(init_func) {
add_promises.push(add_tx2.complete);
add_promises.push(add_tx3.complete);
Promise.all(add_promises).then((values) => {
db.close();
idb.close();
init_func();
});
}
@ -89,8 +89,8 @@ function load_ing_init(init_func) {
}
request.onsuccess = function() {
db = request.result;
if (!reload) {
idb = request.result;
if (!ireload) {
console.log("Using stored data...")
ing_load_local(init_func);
}
@ -101,24 +101,24 @@ function load_ing_init(init_func) {
}
request.onupgradeneeded = function(e) {
reload = true;
ireload = true;
let db = e.target.result;
let idb = e.target.result;
try {
db.deleteObjectStore('ing_db');
idb.deleteObjectStore('ing_db');
}
catch (error) {
console.log("Could not delete ingredient DB. This is probably fine");
}
try {
db.deleteObjectStore('recipe_db');
idb.deleteObjectStore('recipe_db');
}
catch (error) {
console.log("Could not delete recipe DB. This is probably fine");
}
db.createObjectStore('ing_db');
db.createObjectStore('recipe_db');
idb.createObjectStore('ing_db');
idb.createObjectStore('recipe_db');
console.log("DB setup complete...");
}

View file

@ -2,6 +2,12 @@ let skp_order = ["str","dex","int","def","agi"];
let skill = ["Strength", "Dexterity", "Intelligence", "Defense", "Agility"];
let skp_elements = ["e","t","w","f","a"];
let damageClasses = ["Neutral","Earth","Thunder","Water","Fire","Air"];
// Set up item lists for quick access later.
let armorTypes = [ "helmet", "chestplate", "leggings", "boots" ];
let accessoryTypes = [ "ring", "bracelet", "necklace" ];
let weaponTypes = [ "wand", "spear", "bow", "dagger", "relik" ];
let consumableTypes = [ "potion", "scroll", "food"];
let elementIcons = ["\u2724","\u2726", "\u2749", "\u2739", "\u274b" ];
let skpReqs = skp_order.map(x => x + "Req");