wynnbuilder-forked-for-changes/crafter.js

412 lines
16 KiB
JavaScript
Raw Normal View History

2021-01-19 17:32:27 +00:00
/*
* TESTING SECTION
*/
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);
2021-01-19 17:32:27 +00:00
const ING_BUILD_VERSION = "6.9.20";
2021-01-19 17:32:27 +00:00
/*
* END testing section
*/
/* TODO:
Make material tier do something
Double powders
Integrate to normal builder
*/
let recipeTypes = ["HELMET","CHESTPLATE","LEGGINGS","BOOTS","RELIK","WAND","SPEAR","DAGGER","BOW","RING","NECKLACE","BRACELET","SCROLL","FOOD","POTION"];
let levelTypes = ["1-3","3-5","5-7","7-9","10-13","13-15","15-17","17-19","20-23","23-25","25-27","27-29","30-33","33-35","35-37","37-39","40-43","43-45","45-47","47-49","50-53","53-55","55-57","57-59","60-63","63-65","65-67","67-69","70-73","73-75","75-77","77-79","80-83","83-85","85-87","87-89","90-93","93-95","95-97","97-99","100-103","103-105",]
let ingFields = ["fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "lq", "ref", "str", "dex", "int", "agi", "def", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "jh", "sprint", "sprintReg", "gXp", "gSpd"];
let player_craft;
function setTitle() {
document.getElementById("header").textContent = "WynnCrafter version "+ING_BUILD_VERSION+" (ingredient db version "+ING_DB_VERSION+")";
2021-01-19 17:32:27 +00:00
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);
2021-01-19 17:32:27 +00:00
}
2021-01-19 17:32:27 +00:00
let ingMap = new Map();
let ingList = [];
let recipeMap = new Map();
2021-01-28 00:52:34 +00:00
let recipeList = [];
let ingIDMap = new Map();
let recipeIDMap = new Map();
2021-01-19 17:32:27 +00:00
function init() {
//no ing
let ing = Object();
ing.name = "No Ingredient";
ing.tier = 0;
ing.lvl = 0;
ing.skills = ["ARMOURING", "TAILORING", "WEAPONSMITHING", "WOODWORKING", "JEWELING", "COOKING", "ALCHEMISM", "SCRIBING"];
ing.ids= {};
ing.itemIDs = {"dura": 0, "strReq": 0, "dexReq": 0,"intReq": 0,"defReq": 0,"agiReq": 0,};
ing.consumableIDs = {"dura": 0, "charges": 0};
2021-01-28 00:52:34 +00:00
ing.posMods = {"left": 0, "right": 0, "above": 0, "under": 0, "touching": 0, "notTouching": 0};
ing.id = 4000;
2021-01-28 00:52:34 +00:00
ingMap.set(ing["name"], ing);
ingList.push(ing["name"]);
ingIDMap.set(ing["id"], ing["name"]);
2021-01-28 00:52:34 +00:00
let numerals = new Map([[1, "I"], [2, "II"], [3, "III"], [4, "IV"], [5, "V"], [6, "VI"]]);
for (let i = 0; i < 5; i ++) {
for (const powderIng of powderIngreds) {
let ing = Object();
ing.name = "" + damageClasses[i+1] + " Powder " + numerals.get(powderIngreds.indexOf(powderIng) + 1);
ing.tier = 0;
ing.lvl = 0;
ing.skills = ["ARMOURING", "TAILORING", "WEAPONSMITHING", "WOODWORKING"];
ing.ids = {};
ing.isPowder = true;
ing.pid = 6*i + powderIngreds.indexOf(powderIng);
ing.id = 4001 + ing.pid;
2021-01-28 00:52:34 +00:00
ing.itemIDs = {"dura": powderIng["durability"], "strReq": 0, "dexReq": 0,"intReq": 0,"defReq": 0,"agiReq": 0,};
switch(i) {
case 0:
ing.itemIDs["strReq"] = powderIng["skpReq"];
break;
case 1:
ing.itemIDs["dexReq"] = powderIng["skpReq"];
break;
case 2:
ing.itemIDs["intReq"] = powderIng["skpReq"];
break;
case 3:
ing.itemIDs["defReq"] = powderIng["skpReq"];
break;
case 4:
ing.itemIDs["agiReq"] = powderIng["skpReq"];
break;
}
ing.consumableIDs = {"dura": 0, "charges": 0};
ing.posMods = {"left": 0, "right": 0, "above": 0, "under": 0, "touching": 0, "notTouching": 0};
ingMap.set(ing["name"],ing);
ingList.push(ing["name"]);
ingIDMap.set(ing["id"], ing["name"]);
2021-01-28 00:52:34 +00:00
}
}
2021-01-19 17:32:27 +00:00
for (const ing of ings) {
ingMap.set(ing["name"], ing);
ingList.push(ing["name"]);
ingIDMap.set(ing["id"], ing["name"]);
2021-01-19 17:32:27 +00:00
}
for (const recipe of recipes) {
recipeMap.set(recipe["name"], recipe);
recipeList.push(recipe["name"]);
recipeIDMap.set(recipe["id"],recipe["name"]);
2021-01-19 17:32:27 +00:00
}
console.log("all ingredients");
console.log(ings);
console.log("all recipes");
console.log(recipes);
/*console.log(ingList);
2021-01-28 00:52:34 +00:00
console.log(recipeList);
console.log(ingIDMap);
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)");
}
2021-01-19 17:32:27 +00:00
}
function updateMaterials() {
let recipeName = getValue("recipe-choice") ? getValue("recipe-choice") : "Potion";
let levelRange = getValue("level-choice") ? getValue("level-choice") : "103-105";
let recipe = expandRecipe(recipeMap.get(recipeName + "-" + levelRange));
if (recipe !== undefined) {
try{
document.getElementById("mat-1").textContent = recipe.get("materials")[0].get("item").split(" ").slice(1).join(" ") + " Tier:";
document.getElementById("mat-2").textContent = recipe.get("materials")[1].get("item").split(" ").slice(1).join(" ") + " Tier:";
} catch (error){
2021-01-28 00:52:34 +00:00
//e e e
2021-01-19 17:32:27 +00:00
}
}
else {
document.getElementById("mat-1").textContent = "Material 1 Tier:";
document.getElementById("mat-2").textContent = "Material 2 Tier:";
}
}
function toggleAtkSpd(buttonId) {
let buttons = ["slow-atk-button", "normal-atk-button", "fast-atk-button"];
let elem = document.getElementById(buttonId);
if (elem.classList.contains("toggleOn")) {
elem.classList.remove("toggleOn");
} else {
for (const button of buttons) {
document.getElementById(button).classList.remove("toggleOn");
}
elem.classList.add("toggleOn");
}
}
2021-01-19 17:32:27 +00:00
function calculateCraft() {
//Make things display.
for (let i of document.getElementsByClassName("hide-container-block")) {
i.style.display = "block";
}
for (let i of document.getElementsByClassName("hide-container-grid")) {
i.style.display = "grid";
}
//define the fields that will go into crafting the craft.
let recipe = getValue("recipe-choice") === "" ? "Potion" : getValue("recipe-choice");
let levelrange = getValue("level-choice") === "" ? "103-105" : getValue("level-choice");
recipe = expandRecipe(recipeMap.get(recipe+"-"+levelrange));
let mat_tiers = [];
for (i = 1; i < 3; i++) {
for(j = 1; j < 4; j++) {
let elem = document.getElementById("mat-" + i + "-" + j);
if(elem.classList.contains("toggleOn")) {
mat_tiers.push(j); //Tier is 1, 2, or 3.
break;
}
}
2021-01-19 19:53:41 +00:00
if (mat_tiers.length < i) { //default to t3
2021-01-19 17:32:27 +00:00
mat_tiers.push(3);
document.getElementById("mat-"+i+"-3").classList.add("toggleOn");
}
}
let ingreds = [];
for (i = 1; i < 7; i++) {
getValue("ing-choice-" + i) === "" ? ingreds.push(expandIngredient(ingMap.get("No Ingredient"))) : ingreds.push(expandIngredient(ingMap.get(getValue("ing-choice-" + i))));
}
let atkSpd = "NORMAL"; //default attack speed will be normal.
for (const b of ["slow-atk-button", "normal-atk-button", "fast-atk-button"]) {
button = document.getElementById(b);
if (button.classList.contains("toggleOn")) {
atkSpd = b.split("-")[0].toUpperCase();
}
}
2021-01-19 17:32:27 +00:00
//create the craft
2021-01-28 00:52:34 +00:00
player_craft = new Craft(recipe,mat_tiers,ingreds,atkSpd,"");
2021-01-30 11:06:16 +00:00
let craft_str = encodeCraft(player_craft);
location.hash = craft_str;
player_craft.setHash(craft_str);
2021-01-19 17:32:27 +00:00
console.log(player_craft);
/*console.log(recipe)
console.log(levelrange)
console.log(mat_tiers)
console.log(ingreds)*/
document.getElementById("mat-1").textContent = recipe.get("materials")[0].get("item").split(" ").slice(1).join(" ") + " Tier:";
document.getElementById("mat-2").textContent = recipe.get("materials")[1].get("item").split(" ").slice(1).join(" ") + " Tier:";
//Display Recipe Stats
displayRecipeStats(player_craft, "recipe-stats");
2021-01-20 17:10:27 +00:00
for(let i = 0; i < 6; i++) {
displayExpandedIngredient(player_craft["ingreds"][i],"tooltip-" + i);
}
2021-01-19 17:32:27 +00:00
//Display Craft Stats
displayCraftStats(player_craft, "craft-stats");
//Display Ingredients' Stats
for (let i = 1; i < 7; i++) {
displayExpandedIngredient(player_craft.ingreds[i-1] , "ing-"+i+"-stats");
}
//Display Warnings - only ingred type warnings for now
let warning_elem = document.getElementById("craft-warnings");
warning_elem.textContent = ""; //refresh warnings
warning_elem.classList.add("warning");
let type = player_craft["recipe"].get("skill");
for (const ingred of player_craft["ingreds"]) {
if (!(ingred.get("skills").includes(type))) {
let p = document.createElement("p");
p.textContent = "WARNING: " + ingred.get("name") + " cannot be used for " + type.charAt(0) + type.substring(1).toLowerCase() +"!";
warning_elem.appendChild(p);
}
}
2021-01-28 00:52:34 +00:00
}
2021-01-30 11:06:16 +00:00
function encodeCraft(craft) {
if (craft) {
2021-01-28 00:52:34 +00:00
let atkSpds = ["SLOW","NORMAL","FAST"];
let craft_string = "1" +
2021-01-30 11:06:16 +00:00
Base64.fromIntN(craft.ingreds[0].get("id"), 2) +
Base64.fromIntN(craft.ingreds[1].get("id"), 2) +
Base64.fromIntN(craft.ingreds[2].get("id"), 2) +
Base64.fromIntN(craft.ingreds[3].get("id"), 2) +
Base64.fromIntN(craft.ingreds[4].get("id"), 2) +
Base64.fromIntN(craft.ingreds[5].get("id"), 2) +
Base64.fromIntN(craft.recipe.get("id"),2) +
Base64.fromIntN(craft.mat_tiers[0] + (craft.mat_tiers[1]-1)*3, 1) + //this maps tiers [a,b] to a+3b.
Base64.fromIntN(atkSpds.indexOf(craft["atkSpd"]),1);
2021-01-28 00:52:34 +00:00
return craft_string;
}
return "";
2021-01-19 17:32:27 +00:00
}
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);
2021-01-28 00:52:34 +00:00
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)));
2021-01-28 00:52:34 +00:00
}
recipe = recipeIDMap.get(Base64.toInt(tag.substring(12,14)));
//console.log(Base64.toInt(tag.substring(12,14)));
2021-01-28 00:52:34 +00:00
recipesName = recipe.split("-");
setValue("recipe-choice",recipesName[0]);
setValue("level-choice",recipesName[1]+"-"+recipesName[2]);
tierNum = Base64.toInt(tag.substring(14,15));
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
toggleMaterial("mat-1-"+mat_tiers[0]);
toggleMaterial("mat-2-"+mat_tiers[1]);
atkSpd = Base64.toInt(tag.substring(15));
let atkSpdButtons = ["slow-atk-button", "normal-atk-button", "fast-atk-button"];
toggleAtkSpd(atkSpdButtons[atkSpd]);
calculateCraft();
}
}
}
2021-01-19 17:32:27 +00:00
function populateFields() {
let recipe_list = document.getElementById("recipe-choices");
for (const recipe of recipeTypes) {
let el = document.createElement("option");
el.value = recipe.charAt(0) + recipe.substring(1).toLowerCase();
recipe_list.appendChild(el);
}
let level_list = document.getElementById("level-choices");
for (const range of levelTypes) {
let el = document.createElement("option");
el.value = range;
level_list.appendChild(el);
}
for (i = 1; i < 7; i++) {
let ing_list = document.getElementById("ing-choices-"+i);
for (const ing of ingList) {
let el = document.createElement("option");
el.value = ing;
ing_list.appendChild(el);
}
}
}
/* Toggles ONE button
*/
function toggleButton(buttonId) {
let elem = document.getElementById(buttonId);
if (elem.classList.contains("toggleOn")) {
elem.classList.remove("toggleOn");
} else{
elem.classList.add("toggleOn");
}
}
/* Copy the link
*/
function copyRecipe(){
if (player_craft) {
copyTextToClipboard(ing_url_base+location.hash);
2021-01-19 17:32:27 +00:00
document.getElementById("copy-button").textContent = "Copied!";
}
}
/* Copy the link AND a display of all ingredients
*/
function shareRecipe(){
if (player_craft) {
let copyString = ing_url_base+location.hash + "\n";
let name = player_craft.recipe.get("name").split("-");
2021-01-28 00:52:34 +00:00
copyString += " > " + name[0] + " " + "Lv. " + name[1] + "-" + name[2] + " (" + player_craft.mat_tiers[0] + "\u272B, " + player_craft.mat_tiers[1] + "\u272B)\n";
let names = [
player_craft.ingreds[0].get("name"),
player_craft.ingreds[1].get("name"),
player_craft.ingreds[2].get("name"),
player_craft.ingreds[3].get("name"),
player_craft.ingreds[4].get("name"),
player_craft.ingreds[5].get("name")
];
//fancy justify code that doesn't work properly b/c most font isn't monospaced
let buffer1 = Math.max(names[0].length,names[2].length,names[4].length);
let buffer2 = Math.max(names[1].length,names[3].length,names[5].length);
for (let i in names) {
let name = names[i];
let spaces;
if (i % 2 == 0) { //buffer 1
spaces = buffer1 - name.length;
} else { //buffer 2
spaces = buffer2 - name.length;
}
for (let j = 0; j < spaces; j ++) {
if (j % 2 == 0) {
names[i]+=" ";
} else {
names[i] = " "+names[i];
}
}
}
copyString += " > [" + names[0] + " | " + names[1] + "\n";
copyString += " > " + names[2] + " | " + names[3] + "\n";
copyString += " > " + names[4] + " | " + names[5] + "]";
2021-01-28 00:52:34 +00:00
copyTextToClipboard(copyString);
2021-01-19 17:32:27 +00:00
document.getElementById("share-button").textContent = "Copied!";
}
}
/* Toggles the entire material's buttons
*/
function toggleMaterial(buttonId) {
let elem = document.getElementById(buttonId);
let mat = buttonId.split("-")[1]
if (!elem.classList.contains("toggleOn")) { //we turned on that button, now toggle the others off
toggleButton(buttonId);
for (i = 1; i < 4; i++) {
if ("mat-" + mat + "-" + i !== buttonId) {
document.getElementById("mat-" + mat + "-" + i).classList.remove("toggleOn");
}
}
} else { //we turned off a button: do nothing
toggleButton(buttonId);
}
}
/* Reset all fields
*/
function resetFields() {
for (let i = 1; i < 3; i ++) {
for (let j = 1; j < 4; j++) {
document.getElementById("mat-"+i+"-"+j).classList.remove("toggleOn");
}
}
for (let i = 1; i < 7; i++) {
setValue("ing-choice-"+i, "");
}
setValue("recipe-choice", "");
setValue("level-choice", "");
location.hash = "";
calculateCraft();
}
2021-01-24 03:58:53 +00:00
load_ing_init(init);