2021-01-19 17:32:27 +00:00
/ *
* TESTING SECTION
* /
2021-01-30 08:50:25 +00:00
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
2021-01-30 08:50:25 +00:00
const ING _BUILD _VERSION = "6.9.20" ;
2021-01-19 17:32:27 +00:00
/ *
* END testing section
* /
/ * T O D O :
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 ( ) {
2021-01-30 08:50:25 +00:00
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" ) ;
2021-01-24 20:33:00 +00:00
let disclaimer = document . createElement ( "p" ) ;
2021-01-29 02:31:31 +00:00
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." ;
2021-01-24 20:33:00 +00:00
document . getElementById ( "header" ) . append ( disclaimer ) ;
2021-01-19 17:32:27 +00:00
}
2021-01-30 08:50:25 +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-29 02:31:31 +00:00
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 } ;
2021-01-29 02:31:31 +00:00
ing . id = 4000 ;
2021-01-28 00:52:34 +00:00
ingMap . set ( ing [ "name" ] , ing ) ;
ingList . push ( ing [ "name" ] ) ;
2021-01-29 02:31:31 +00:00
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 ) ;
2021-01-29 02:31:31 +00:00
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" ] ) ;
2021-01-29 02:31:31 +00:00
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" ] ) ;
2021-01-29 02:31:31 +00:00
ingIDMap . set ( ing [ "id" ] , ing [ "name" ] ) ;
2021-01-19 17:32:27 +00:00
}
for ( const recipe of recipes ) {
2021-01-29 02:31:31 +00:00
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 ) ;
2021-01-30 08:50:25 +00:00
/ * c o n s o l e . l o g ( i n g L i s t ) ;
2021-01-28 00:52:34 +00:00
console . log ( recipeList ) ;
2021-01-29 02:31:31 +00:00
console . log ( ingIDMap ) ;
2021-01-30 08:50:25 +00:00
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-29 22:11:57 +00:00
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:" ;
}
}
2021-01-21 18:30:22 +00:00
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 ) ) ) ) ;
}
2021-01-21 18:30:22 +00:00
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 ) ;
/ * c o n s o l e . l o g ( r e c i p e )
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:" ;
2021-01-20 05:59:17 +00:00
//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" ) ;
}
2021-01-20 05:59:17 +00:00
//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" ] ;
2021-01-30 08:50:25 +00:00
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
}
2021-01-30 08:50:25 +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 ++ ) {
2021-01-29 02:31:31 +00:00
setValue ( "ing-choice-" + ( i + 1 ) , ingIDMap . get ( Base64 . toInt ( tag . substring ( 2 * i , 2 * i + 2 ) ) ) ) ;
2021-01-30 08:50:25 +00:00
//console.log(Base64.toInt(tag.substring(2*i,2*i+2)));
2021-01-28 00:52:34 +00:00
}
2021-01-29 02:31:31 +00:00
recipe = recipeIDMap . get ( Base64 . toInt ( tag . substring ( 12 , 14 ) ) ) ;
2021-01-30 08:50:25 +00:00
//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 ) ;
}
}
}
/ * T o g g l e s O N E b u t t o n
* /
function toggleButton ( buttonId ) {
let elem = document . getElementById ( buttonId ) ;
if ( elem . classList . contains ( "toggleOn" ) ) {
elem . classList . remove ( "toggleOn" ) ;
} else {
elem . classList . add ( "toggleOn" ) ;
}
}
/ * C o p y t h e l i n k
* /
function copyRecipe ( ) {
if ( player _craft ) {
2021-01-30 08:50:25 +00:00
copyTextToClipboard ( ing _url _base + location . hash ) ;
2021-01-19 17:32:27 +00:00
document . getElementById ( "copy-button" ) . textContent = "Copied!" ;
}
}
/ * C o p y t h e l i n k A N D a d i s p l a y o f a l l i n g r e d i e n t s
* /
function shareRecipe ( ) {
if ( player _craft ) {
2021-01-30 08:50:25 +00:00
let copyString = ing _url _base + location . hash + "\n" ;
2021-01-29 02:31:31 +00:00
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" ;
2021-01-29 02:31:31 +00:00
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!" ;
}
}
/ * T o g g l e s t h e e n t i r e m a t e r i a l ' s b u t t o n s
* /
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 ) ;
}
}
/ * R e s e t a l l f i e l d s
* /
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 ) ;