2021-02-05 18:09:36 +00:00
let getUrl = window . location ;
const url _base = getUrl . protocol + "//" + getUrl . host + "/" + getUrl . pathname . split ( '/' ) [ 1 ] ;
2021-01-18 20:23:37 +00:00
let skp _order = [ "str" , "dex" , "int" , "def" , "agi" ] ;
let skill = [ "Strength" , "Dexterity" , "Intelligence" , "Defense" , "Agility" ] ;
let skp _elements = [ "e" , "t" , "w" , "f" , "a" ] ;
2021-01-28 00:52:34 +00:00
let damageClasses = [ "Neutral" , "Earth" , "Thunder" , "Water" , "Fire" , "Air" ] ;
2021-01-30 08:50:25 +00:00
// 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" ] ;
2021-03-05 16:28:00 +00:00
const attackSpeeds = [ "SUPER_SLOW" , "VERY_SLOW" , "SLOW" , "NORMAL" , "FAST" , "VERY_FAST" , "SUPER_FAST" ] ;
2021-03-31 06:44:56 +00:00
const baseDamageMultiplier = [ 0.51 , 0.83 , 1.5 , 2.05 , 2.5 , 3.1 , 4.3 ] ;
//0.51, 0.82, 1.50, 2.05, 2.50, 3.11, 4.27
2021-03-14 07:55:08 +00:00
const classes = [ "Warrior" , "Assassin" , "Mage" , "Archer" , "Shaman" ] ;
const tiers = [ "Normal" , "Unique" , "Rare" , "Legendary" , "Fabled" , "Mythic" , "Set" , "Crafted" ] //I'm not sure why you would make a custom crafted but if you do you should be able to use it w/ the correct powder formula
const types = armorTypes . concat ( accessoryTypes ) . concat ( weaponTypes ) . concat ( consumableTypes ) . map ( x => x . substring ( 0 , 1 ) . toUpperCase ( ) + x . substring ( 1 ) ) ;
2021-03-16 05:40:05 +00:00
let itemTypes = armorTypes . concat ( accessoryTypes ) . concat ( weaponTypes ) ;
2021-01-30 08:50:25 +00:00
2021-03-17 04:19:19 +00:00
2021-01-18 20:23:37 +00:00
let elementIcons = [ "\u2724" , "\u2726" , "\u2749" , "\u2739" , "\u274b" ] ;
let skpReqs = skp _order . map ( x => x + "Req" ) ;
2021-03-17 04:19:19 +00:00
2021-02-12 17:00:06 +00:00
function clamp ( num , low , high ) {
return Math . min ( Math . max ( num , low ) , high ) ;
}
2021-01-07 06:41:41 +00:00
// 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 ;
}
2021-02-17 18:08:47 +00:00
function round _near ( value ) {
let eps = 0.00000001 ;
if ( Math . abs ( value - Math . round ( value ) ) < eps ) {
return Math . round ( value ) ;
}
return value ;
}
2021-01-08 02:40:12 +00:00
function setText ( id , text ) {
document . getElementById ( id ) . textContent = text ;
}
2021-01-07 06:41:41 +00:00
function setHTML ( id , html ) {
document . getElementById ( id ) . innerHTML = html ;
}
function setValue ( id , value ) {
2021-01-07 10:23:54 +00:00
let el = document . getElementById ( id ) ;
el . value = value ;
el . dispatchEvent ( new Event ( "change" ) ) ;
2021-01-07 06:41:41 +00:00
}
2021-01-07 08:34:31 +00:00
2021-01-08 20:17:37 +00:00
function getValue ( id ) {
return document . getElementById ( id ) . value ;
}
2021-03-08 22:50:47 +00:00
function log ( b , n ) {
return Math . log ( n ) / Math . log ( b ) ;
}
2021-01-07 08:34:31 +00:00
// Base 64 encoding tools
// https://stackoverflow.com/a/27696695
2021-01-07 10:23:54 +00:00
// Modified for fixed precision
2021-01-07 08:34:31 +00:00
Base64 = ( function ( ) {
var digitsStr =
// 0 8 16 24 32 40 48 56 63
// v v v v v v v v v
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-" ;
var digits = digitsStr . split ( '' ) ;
var digitsMap = { } ;
for ( var i = 0 ; i < digits . length ; i ++ ) {
digitsMap [ digits [ i ] ] = i ;
}
return {
2021-01-07 10:23:54 +00:00
fromIntV : function ( int32 ) {
2021-01-07 08:34:31 +00:00
var result = '' ;
while ( true ) {
result = digits [ int32 & 0x3f ] + result ;
int32 >>>= 6 ;
if ( int32 === 0 )
break ;
}
return result ;
} ,
2021-01-07 10:23:54 +00:00
fromIntN : function ( int32 , n ) {
var result = '' ;
for ( let i = 0 ; i < n ; ++ i ) {
result = digits [ int32 & 0x3f ] + result ;
2021-01-09 09:09:47 +00:00
int32 >>= 6 ;
2021-01-07 10:23:54 +00:00
}
return result ;
} ,
2021-01-07 08:34:31 +00:00
toInt : function ( digitsStr ) {
var result = 0 ;
var digits = digitsStr . split ( '' ) ;
for ( var i = 0 ; i < digits . length ; i ++ ) {
result = ( result << 6 ) + digitsMap [ digits [ i ] ] ;
}
return result ;
2021-01-07 10:23:54 +00:00
} ,
2021-01-09 09:09:47 +00:00
toIntSigned : function ( digitsStr ) {
var result = 0 ;
var digits = digitsStr . split ( '' ) ;
if ( digits [ 0 ] && ( digitsMap [ digits [ 0 ] ] & 0x20 ) ) {
result = - 1 ;
}
for ( var i = 0 ; i < digits . length ; i ++ ) {
result = ( result << 6 ) + digitsMap [ digits [ i ] ] ;
}
return result ;
}
2021-01-07 08:34:31 +00:00
} ;
} ) ( ) ;
// Base64.fromInt(-2147483648); // gives "200000"
// Base64.toInt("200000"); // gives -2147483648
2021-01-10 10:02:23 +00:00
/ *
2021-01-15 00:30:49 +00:00
Turns a raw stat and a % stat into a final stat on the basis that - raw and >= 100 % becomes 0 and + raw and <= - 100 % becomes negative .
2021-01-10 10:02:23 +00:00
Pct would be 0.80 for 80 % , - 1.20 for 120 % , etc
2021-01-11 00:08:14 +00:00
Example Outputs :
raw : - 100
pct : + 0.20 , output = - 80
pct : + 1.20 , output = 0
pct : - 0.20 , output = - 120
pct : - 1.20 , output = - 220
raw : + 100
pct : + 0.20 , output = 120
pct : + 1.20 , output = 220
pct : - 0.20 , output = 80
2021-01-15 00:30:49 +00:00
pct : - 1.20 , output = - 20
2021-01-10 10:02:23 +00:00
* /
function rawToPct ( raw , pct ) {
final = 0 ;
if ( raw < 0 ) {
final = ( Math . min ( 0 , raw - ( raw * pct ) ) ) ;
} else if ( raw > 0 ) {
2021-01-12 07:11:20 +00:00
final = raw + ( raw * pct ) ;
2021-01-10 10:02:23 +00:00
} else { //do nothing - final's already 0
}
return final ;
2021-01-11 11:08:10 +00:00
}
/ *
* Clipboard utilities
* From : https : //stackoverflow.com/a/30810322
* /
function fallbackCopyTextToClipboard ( text ) {
var textArea = document . createElement ( "textarea" ) ;
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if the element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a
// flash, so some of these are just precautions. However in
// Internet Explorer the element is visible whilst the popup
// box asking the user for permission for the web page to
// copy to the clipboard.
//
// Place in the top-left corner of screen regardless of scroll position.
textArea . style . position = 'fixed' ;
textArea . style . top = 0 ;
textArea . style . left = 0 ;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea . style . width = '2em' ;
textArea . style . height = '2em' ;
// We don't need padding, reducing the size if it does flash render.
textArea . style . padding = 0 ;
// Clean up any borders.
textArea . style . border = 'none' ;
textArea . style . outline = 'none' ;
textArea . style . boxShadow = 'none' ;
// Avoid flash of the white box if rendered for any reason.
textArea . style . background = 'transparent' ;
textArea . value = text ;
document . body . appendChild ( textArea ) ;
textArea . focus ( ) ;
textArea . select ( ) ;
try {
var successful = document . execCommand ( 'copy' ) ;
var msg = successful ? 'successful' : 'unsuccessful' ;
console . log ( 'Copying text command was ' + msg ) ;
} catch ( err ) {
console . log ( 'Oops, unable to copy' ) ;
}
document . body . removeChild ( textArea ) ;
}
function copyTextToClipboard ( text ) {
if ( ! navigator . clipboard ) {
fallbackCopyTextToClipboard ( text ) ;
return ;
}
navigator . clipboard . writeText ( text ) . then ( function ( ) {
console . log ( 'Async: Copying to clipboard was successful!' ) ;
} , function ( err ) {
console . error ( 'Async: Could not copy text: ' , err ) ;
} ) ;
}
2021-02-17 18:29:41 +00:00
2021-03-16 05:40:05 +00:00
/ * * G e n e r a t e s a r a n d o m c o l o r u s i n g t h e # ( R ) ( G ) ( B ) f o r m a t . N o t w r i t t e n b y w y n n b u i l d e r d e v s .
*
* /
function randomColor ( ) {
var letters = '0123456789abcdef' ;
var color = '#' ;
for ( var i = 0 ; i < 6 ; i ++ ) {
color += letters [ Math . floor ( Math . random ( ) * 16 ) ] ;
}
return color ;
}
/ * * G e n e r a t e s a r a n d o m c o l o r , b u t l i g h t n i n g m u s t b e r e l a t i v e l y h i g h ( > 0 . 5 ) .
*
* @ returns a random color in RGB 6 - bit form .
* /
function randomColorLight ( ) {
return randomColorHSL ( [ 0 , 1 ] , [ 0 , 1 ] , [ 0.5 , 1 ] ) ;
}
/ * * G e n e r a t e s a r a n d o m c o l o r g i v e n H S L r e s t r i c t i o n s .
*
* @ returns a random color in RGB 6 - bit form .
* /
function randomColorHSL ( h , s , l ) {
var letters = '0123456789abcdef' ;
let h _var = h [ 0 ] + ( h [ 1 ] - h [ 0 ] ) * Math . random ( ) ; //hue
let s _var = s [ 0 ] + ( s [ 1 ] - s [ 0 ] ) * Math . random ( ) ; //saturation
let l _var = l [ 0 ] + ( l [ 1 ] - l [ 0 ] ) * Math . random ( ) ; //lightness
let rgb = hslToRgb ( h _var , s _var , l _var ) ;
let color = "#" ;
for ( const c of rgb ) {
color += letters [ Math . floor ( c / 16 ) ] + letters [ c % 16 ] ;
}
return color ;
}
/ * *
* Converts an HSL color value to RGB . Conversion formula
* adapted from http : //en.wikipedia.org/wiki/HSL_color_space.
* Assumes h , s , and l are contained in the set [ 0 , 1 ] and
* returns r , g , and b in the set [ 0 , 255 ] . Not written by wynnbuilder devs .
*
* @ param { number } h The hue
* @ param { number } s The saturation
* @ param { number } l The lightness
* @ return { Array } The RGB representation
* /
function hslToRgb ( h , s , l ) {
var r , g , b ;
if ( s == 0 ) {
r = g = b = l ; // achromatic
} else {
var hue2rgb = function hue2rgb ( p , q , t ) {
if ( t < 0 ) t += 1 ;
if ( t > 1 ) t -= 1 ;
if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t ;
if ( t < 1 / 2 ) return q ;
if ( t < 2 / 3 ) return p + ( q - p ) * ( 2 / 3 - t ) * 6 ;
return p ;
}
var q = l < 0.5 ? l * ( 1 + s ) : l + s - l * s ;
var p = 2 * l - q ;
r = hue2rgb ( p , q , h + 1 / 3 ) ;
g = hue2rgb ( p , q , h ) ;
b = hue2rgb ( p , q , h - 1 / 3 ) ;
}
return [ Math . round ( r * 255 ) , Math . round ( g * 255 ) , Math . round ( b * 255 ) ] ;
2021-03-31 06:44:56 +00:00
}
/ * * C r e a t e s a t o o l t i p .
*
* @ param { DOM Element } elem - the element to make a tooltip
* @ param { String } element _type - the HTML element type that the tooltiptext should be .
* @ param { String } tooltiptext - the text to display in the tooltip .
* @ param { DOM Element } parent - the parent elem . optional .
* @ param { String [ ] } classList - a list of classes to add to the element .
* /
function createTooltip ( elem , element _type , tooltiptext , parent , classList ) {
elem = document . createElement ( element _type ) ;
elem . classList . add ( "tooltiptext" ) ;
if ( tooltiptext . includes ( "\n" ) ) {
let texts = tooltiptext . split ( "\n" ) ;
for ( const t of texts ) {
let child = document . createElement ( element _type ) ;
child . textContent = t ;
elem . appendChild ( child ) ;
}
} else {
elem . textContent = tooltiptext ;
}
for ( const c of classList ) {
elem . classList . add ( c ) ;
}
if ( parent ) {
parent . classList . add ( "tooltip" ) ;
parent . appendChild ( elem ) ;
}
return elem ;
2021-03-16 05:40:05 +00:00
}