commit
9f399846a3
10 changed files with 1149 additions and 88 deletions
|
@ -1322,7 +1322,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container h-75 mx-0 mx-lg-auto dark-2 border border-4 scaled-font align-self-center" style="position: fixed; z-index: 2; overflow: auto; display: none;" id="search-container">
|
<div class="container h-75 mx-0 mx-lg-auto dark-2 border border-4 scaled-font align-self-center" style="position: fixed; z-index: 2000; overflow: auto; display: none;" id="search-container">
|
||||||
<div class="row justify-content-end">
|
<div class="row justify-content-end">
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<button type="button" class="btn-close btn-close-white" aria-label="Close" onclick="document.querySelector('#search-container').style.display = 'none';"></button>
|
<button type="button" class="btn-close btn-close-white" aria-label="Close" onclick="document.querySelector('#search-container').style.display = 'none';"></button>
|
||||||
|
|
85
css/dev.css
Normal file
85
css/dev.css
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/* General Styling - used for all elements on /dev/ */
|
||||||
|
.row > * {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
padding-left: 0 !important; /*Override grid.scss (bs) */
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
border-left: 3px solid white;
|
||||||
|
border-radius: 0.1rem;
|
||||||
|
/* padding-right: 0rem !important;
|
||||||
|
padding-left: 0rem !important; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title:hover{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
margin-bottom: 1.5rem;;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
/*Needed to override <ul> style in sq2bs.css*/
|
||||||
|
list-style-type: circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.indent {
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Math */
|
||||||
|
math, number {
|
||||||
|
font-family: 'CMU Serif', 'Cambria Math', 'Times New Roman', serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
number {
|
||||||
|
color: rgb(17, 234, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-width {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Variable Sizing (specific to dev page) */
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.section-title > * {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
font-size: 6rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) and (max-width: 1400px) {
|
||||||
|
.section-title > * {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
font-size: 4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 1400px) {
|
||||||
|
.section-title > *{
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
font-size: 4.5rem;
|
||||||
|
}
|
||||||
|
}
|
|
@ -437,6 +437,10 @@ input[type=number]::-webkit-outer-spin-button {
|
||||||
|
|
||||||
/* Make links bold when hovered over */
|
/* Make links bold when hovered over */
|
||||||
|
|
||||||
|
.clickable:hover {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
903
dev/index.html
Normal file
903
dev/index.html
Normal file
|
@ -0,0 +1,903 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html scroll-behavior="smooth">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>WynnBuilder Dev</title>
|
||||||
|
<link rel="icon" href="../media/icons/new/atlas64.png">
|
||||||
|
<link rel="manifest" href="manifest.json">
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=.45, user-scalable=no">
|
||||||
|
|
||||||
|
<!-- nunito font, copying wynnbuilder, which is copying wynndata -->
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
||||||
|
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@tarekraafat/autocomplete.js@10.2.6/dist/css/autoComplete.min.css">
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../css/sq2bs.css">
|
||||||
|
<link rel="stylesheet" href="../css/sidebar.css">
|
||||||
|
<link rel="stylesheet" href="../css/wynnstyles.css">
|
||||||
|
<link rel="stylesheet" href="../css/dev.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="body" class="all" style="overflow-y: scroll">
|
||||||
|
<div id="main-sidebar" class="sidebar dark-7 dark-shadow">
|
||||||
|
<a href="../builder/"><img src="../media/icons/new/builder.png" alt="WynnBuilder"
|
||||||
|
title="WynnBuilder"><b>WynnBuilder</b></a>
|
||||||
|
<a href="../crafter/"><img src="../media/icons/new/crafter.png" alt="WynnCrafter"
|
||||||
|
title="WynnCrafter"><b>WynnCrafter</b></a>
|
||||||
|
<a href="../items/"><img src="../media/icons/new/searcher.png" alt="WynnAtlas"
|
||||||
|
title="WynnAtlas"><b>WynnAtlas</b></a>
|
||||||
|
<a href="../custom/"><img src="../media/icons/new/custom.png" alt="WynnCustom"
|
||||||
|
title="WynnCustom"><b>WynnCustom</b></a>
|
||||||
|
<a href="../map/"><img src="../media/icons/new/compass.png" alt="WynnGPS" title="WynnGPS"><b>WynnGPS</b></a>
|
||||||
|
<a href="../wynnfo/"><img src="../media/icons/new/book.png" alt="Wynnfo"
|
||||||
|
title="WynnCrafter"><b>WynnCrafter</b></a>
|
||||||
|
<a href="" onclick="toggleIcons()"><img src="../media/icons/new/reload.png" alt=""
|
||||||
|
title="Swap items on page"><b>Swap Icon Style</b></a>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div class="container text-light px-5 scaled-font">
|
||||||
|
<div class="row justify-content-center page-title">
|
||||||
|
Wynnbuilder Developer Page
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
Welcome to the Wynnbuilder page for developers! Here we provide documentation and specifications for our
|
||||||
|
website. Read through these sections to learn more about how WynnBuilder works!
|
||||||
|
</div>
|
||||||
|
<div class="row section" title="Decoding WynnBuilder links">
|
||||||
|
<p>
|
||||||
|
This section is about the encoding schemes Wynnbuilder uses for its various saveable items (builds,
|
||||||
|
crafted items, and custom items).
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
We use a Base 64 (B64) encode/decode system in most shareable links. It would be quite clunky to put a
|
||||||
|
bunch of numbers (the data we save and read) into one link. To save some space, we compress the
|
||||||
|
base 10 numerical alphabet into a custom B64 alphabet.
|
||||||
|
</p>
|
||||||
|
<div class="row section" title="WB Base 64 (B64)">
|
||||||
|
<p>
|
||||||
|
The Wynnbuilder B64 character table:
|
||||||
|
</p>
|
||||||
|
<pre class="full-width">
|
||||||
|
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-
|
||||||
|
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
|
||||||
|
| | | | | | | | | | | | |
|
||||||
|
0 5 10 15 20 25 30 35 40 45 50 55 60 </pre>
|
||||||
|
<p>
|
||||||
|
The B64 encoding of a number (in the 0 to 63 range) is equal to the character at the index
|
||||||
|
within the above string.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For example, if we have a set of items with id numbers in the range [<number>0</number>,
|
||||||
|
<number>10000</number>], we need at most 3 B64 characters to encode any of these items
|
||||||
|
in the link! The item of id <number>1337</number> corresponds to the B64 hash <code>0Kv</code>:
|
||||||
|
<math>1337 = 0 * 4096 + 20 * 64 + 57</math>, <number>0</number> maps to <code>0</code>,
|
||||||
|
<number>20</number> maps to <code>K</code>, and <number>57</number> maps to <code>v</code>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Decoding is a little different. We can either interpret the B64 string as a <b>signed</b> or <b>unsigned</b> number (signed: using 2s complement binary).
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Things that should be interpreted as <b>signed</b> are:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>Skill Points</li>
|
||||||
|
<li>Any numerical identification value for custom items</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Things that should be interpreted as <b>unsigned</b> are:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>Item ID numbers</li>
|
||||||
|
<li>Tome ID numbers</li>
|
||||||
|
<li>Build Level</li>
|
||||||
|
<li>Ingredient ID numbers</li>
|
||||||
|
<li>Recipe ID numbers</li>
|
||||||
|
<li>Powder numbers</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Now that we understand the B64 system, we can move on to the way builds, crafted items, and custom items are stored in links.
|
||||||
|
</p>
|
||||||
|
<div class="row section" title="Builds">
|
||||||
|
<p>
|
||||||
|
First, what do we need in order to encode an entire build?
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Wynnbuilder mainly runs calculations for damages and defense. Therefore, we need:
|
||||||
|
</p>
|
||||||
|
<ul class="indent">
|
||||||
|
<li>The build's items (equipment, tomes)</li>
|
||||||
|
<li>The skill points distributed by the user (and user level)</li>
|
||||||
|
<li>Item powderings</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Wynnbuilder assigns each item in the Wynncraft item pool to a unique ID number.
|
||||||
|
<!-- For example, the bracelet <b class="atlas">Atlas</b>
|
||||||
|
has an id number of <number>167</number>. We can then store all of a build's item pool items in a link with the items' id numbers. A
|
||||||
|
similar idea is used for skill points and powders. However, we know how many different skills there are already (5), so we can encode
|
||||||
|
the user's assignment of skill points in 5 numbers. With powders, it's a little different. There are 31 "states" of powder: 1 for no
|
||||||
|
powder and then 5 elements with 6 tiers of powder for each element. We will know how many available powder slots we have based on our
|
||||||
|
equipment. We can then put all of these numbers in a specific order (after running B64 encoding) to get our build link. -->
|
||||||
|
</p>
|
||||||
|
<div class = "row section" title = "ID number specifics">
|
||||||
|
<p>
|
||||||
|
For items, you can download the item DB here: <a href = "../clean.json" target = "_blank">clean.json</a>. Each item has an id value that can be put in a map. The NoneItem ID numbers start at 10000 in the canonical order: [helmet, chestplate, leggings, boots, ring 1, ring 2, bracelet, necklace, weapon] (No Weapon has an id of 10008).
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For tomes, you can download the tome DB here: <a href = "../tome_map.json" target = "_blank">tome_map.json</a>. The NoneTome ID numbers start at 61 in the order [no weapon tome, no armor tome, no guild tome] so that we can store tome IDs in 1 B64 character.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For powders: id numbers <number>1</number> through <number>30</number> map to Earth I, Earth II, ..., Earth VI,
|
||||||
|
etc. in the order Earth, Thunder, Water, Fire, Air. 0 is the id number for no powder.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
All build links will end in "#[version number]_[build hash]".
|
||||||
|
</p>
|
||||||
|
<div class="row section" title="Version 6">
|
||||||
|
<p>
|
||||||
|
Version 6 was made to account for the desire to save tomes in a build. As of the last version of this documentation, version 6 is used for encoding whenever there are tomes in the build.
|
||||||
|
</p>
|
||||||
|
<div class = "row section" title = "Example 1: With Tomes">
|
||||||
|
<code class="full-width">
|
||||||
|
https://hppeng-wynn.github.io/builder/#6_06W2SH0D40Qq2SK2SL02d0og0Qi191V-E0i2C1g0000100nZ6ZU6FCDo
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
Build hash format:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>
|
||||||
|
<number>9</number> items from <code>idMap</code> (<number>3</number> B64 characters each):
|
||||||
|
<code>06W</code>,
|
||||||
|
<code>2SH</code>,
|
||||||
|
<code>0D4</code>,
|
||||||
|
<code>0Qq</code>,
|
||||||
|
<code>2SK</code>,
|
||||||
|
<code>2SL</code>,
|
||||||
|
<code>02d</code>,
|
||||||
|
<code>0og</code>,
|
||||||
|
<code>0Qi</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>5</number> skill point totals (<number>2</number> B64 characters each):
|
||||||
|
<code>19</code>,
|
||||||
|
<code>1V</code>,
|
||||||
|
<code>-E</code>,
|
||||||
|
<code>0i</code>,
|
||||||
|
<code>2C</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>1</number> player level (<number>2</number> B64 characters):
|
||||||
|
<code>1g</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
A <b>variable</b> number of powder "blocks" (<number>5</number> B64 characters which give us <number>6</number> powders per block).
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>For each of the 5 powderable equipment fields [helmet, chestplate, leggings, boots, weapon], we will have the following:</li>
|
||||||
|
<li><number>1</number> B64 character that says that we need <number>n</number> blocks for this item.</li>
|
||||||
|
<li><number>n</number> blocks of <number>5</number> B64 characters.</li>
|
||||||
|
<li>
|
||||||
|
Since there are 4 <code>0</code>s (B64 0 = 0 unsigned) in this example, we have no powders on any of the armor piece (no blocks).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Then, we have <code>1</code> (B64 1 = 1 unsigned). There is 1 block of powders to decode for the weapon item. That is <code>00nZ6</code>.
|
||||||
|
</li>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>The unsigned equivalent of <code>00nZ6</code> in binary is 30 <b>binary</b> bits long (omitted). Each section of 5 bits directly corresponds to an powder ID.</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>7</number> tomes (<number>1</number> character each):
|
||||||
|
<code>ZU6FCDo</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>The order of tomes listed is [2x weapon tome, 4x armor tome, 1x guild tome].</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row section" title="Version 5">
|
||||||
|
<p>
|
||||||
|
Version 5 was made to allow for the ability to save custom items. To learn the specifics about custom item encoding, refer to the Custom Items section.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
As of the last version of this documentation, version 5 is only used for encoding when there are custom items (and no tomes) in the build.
|
||||||
|
</p>
|
||||||
|
<div class = "row section" title = "Example 1: With Custom Item">
|
||||||
|
<code class = "full-width">
|
||||||
|
https://hppeng-wynn.github.io/builder/#5_06W00mCI-10000JCustom%20Chestplate0220510G020Fe0M0201a0D40Qq2SK2SL02d0og0Qi191V-E0i2C1g0000100nZ6zz++++-
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
Build Hash format:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>
|
||||||
|
<number>9</number> items from <code>idMap</code> (<number>3</number> B64 characters each):
|
||||||
|
<code>06W</code>,
|
||||||
|
<code>00m</code> (with the custom item <code>CI-10000JCustom%20Chestplate0220510G020Fe0M0201a</code>),
|
||||||
|
<code>0D4</code>,
|
||||||
|
<code>0Qq</code>,
|
||||||
|
<code>2SK</code>,
|
||||||
|
<code>2SL</code>,
|
||||||
|
<code>02d</code>,
|
||||||
|
<code>0og</code>,
|
||||||
|
<code>0Qi</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>Starting in this version, to encode a custom item we substitute in the length of the full hash of a custom item ("CI-[gibberish]") in <number>3</number> B64 characters for the item ID, followed by the full hash.</li>
|
||||||
|
<li>When decoding build links of this version or higher, you must check whether or not the 3 characters after the current item are "CI-". If they are, the current 3 characters are the B64 representation of the unsigned length of the custom item hash (<math>n</math>), in characters. Then the next <math>n</math> characters make up the full custom item hash.</li>
|
||||||
|
<li>No existing item has an item ID of "CI-" in B64, so we can define a special case check for this "id number".</li>
|
||||||
|
<li>Further details on parsing and loading this custom item are in the Custom Item section.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>5</number> skill point totals (<number>2</number> B64 characters each):
|
||||||
|
<code>19</code>,
|
||||||
|
<code>1V</code>,
|
||||||
|
<code>-E</code>,
|
||||||
|
<code>0i</code>,
|
||||||
|
<code>2C</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>1</number> player level (<number>2</number> B64 characters):
|
||||||
|
<code>1g</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
A <b>variable</b> number of powder "blocks" (<number>5</number> B64 characters which give us <number>6</number> powders per block).
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>For each of the 5 powderable equipment fields [helmet, chestplate, leggings, boots, weapon], we will have the following:</li>
|
||||||
|
<li><number>1</number> B64 character that says that we need <number>n</number> blocks for this item.</li>
|
||||||
|
<li><number>n</number> blocks of <number>5</number> B64 characters.</li>
|
||||||
|
<li>
|
||||||
|
Since there are 4 <code>0</code>s (B64 0 = 0 unsigned) in this example, we have no powders on any of the armor piece (no blocks).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Then, we have <code>1</code> (B64 1 = 1 unsigned). There is 1 block of powders to decode for the weapon item. That is <code>00nZ6</code>.
|
||||||
|
</li>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>The unsigned equivalent of <code>00nZ6</code> in binary is 30 <b>binary</b> bits long (omitted). Each section of 5 bits directly corresponds to an powder ID.</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
It is possible that version 5 links will have an extra tome section at the end like above (see: Version 6 section). We ignore this in decoding.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="row section" title="Version 4">
|
||||||
|
<p>
|
||||||
|
Version 4 was made to allow for the ability to save crafted items. To learn the specifics about crafted item encoding, refer to the Crafted Items section.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
As of the last version of this documentation, version 4 is the default version and is used when there are no custom items or tomes in the build.
|
||||||
|
</p>
|
||||||
|
<div class = "row section" title = "Example 1: No Crafted Items">
|
||||||
|
<code class = "full-width">
|
||||||
|
https://hppeng-wynn.github.io/builder/#4_06W2SH0D40Qq2SK2SL02d0og0Qi191V-E0i2C1g0000100nZ6zz++++-
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
Build Hash format:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>
|
||||||
|
<number>9</number> items from <code>idMap</code> (<number>3</number> N64 characters each):
|
||||||
|
<code>06W</code>,
|
||||||
|
<code>2SH</code>,
|
||||||
|
<code>0D4</code>,
|
||||||
|
<code>0Qq</code>,
|
||||||
|
<code>2SK</code>,
|
||||||
|
<code>2SL</code>,
|
||||||
|
<code>02d</code>,
|
||||||
|
<code>0og</code>,
|
||||||
|
<code>0Qi</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>5</number> skill point totals (<number>2</number> B64 characters each):
|
||||||
|
<code>19</code>,
|
||||||
|
<code>1V</code>,
|
||||||
|
<code>-E</code>,
|
||||||
|
<code>0i</code>,
|
||||||
|
<code>2C</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>1</number> player level (<number>2</number> B64 characters):
|
||||||
|
<code>1g</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
A <b>variable</b> number of powder "blocks" (<number>5</number> B64 characters which give us <number>6</number> powders per block).
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>For each of the 5 powderable equipment fields [helmet, chestplate, leggings, boots, weapon], we will have the following:</li>
|
||||||
|
<li><number>1</number> B64 character that says that we need <number>n</number> blocks for this item.</li>
|
||||||
|
<li><number>n</number> blocks of <number>5</number> B64 characters.</li>
|
||||||
|
<li>
|
||||||
|
Since there are 4 <code>0</code>s (B64 0 = 0 unsigned) in this example, we have no powders on any of the armor piece (no blocks).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Then, we have <code>1</code> (B64 1 = 1 unsigned). There is 1 block of powders to decode for the weapon item. That is <code>00nZ6</code>.
|
||||||
|
</li>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>The unsigned equivalent of <code>00nZ6</code> in binary is 30 <b>binary</b> bits long (omitted). Each section of 5 bits directly corresponds to an powder ID.</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class = "row section" title = "Example 2: With Crafted Items">
|
||||||
|
<code class = "full-width">
|
||||||
|
https://hppeng-wynn.github.io/builder/#4_06WCR-1628i8v8v94948f210D40Qq2SK2SL02d0og0Qi1Q1V-E0l2C1g0000100nZ6zz++++-
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
Build Hash format:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>
|
||||||
|
<number>9</number> items from <code>idMap</code> (<number>3</number> B64 characters each):
|
||||||
|
<code>06W</code>,
|
||||||
|
<code>CR-1628i8v8v94948f21</code>,
|
||||||
|
<code>0D4</code>,
|
||||||
|
<code>0Qq</code>,
|
||||||
|
<code>2SK</code>,
|
||||||
|
<code>2SL</code>,
|
||||||
|
<code>02d</code>,
|
||||||
|
<code>0og</code>,
|
||||||
|
<code>0Qi</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>Starting in this version, you can substitute in the full hash of a crafted item ("CR-[gibberish]") for the 3-character hash of an item pool item.</li>
|
||||||
|
<li>The way we can tell that an item is a crafted item is when the 3-character hash of the 'item' is "CR-". No existing item has an item ID of "CR-" in B64, so we can define a special case check for this "id number".</li>
|
||||||
|
<li>Further details on parsing and loading this custom item are in the Crafted Item section.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>5</number> skill point totals (<number>2</number> B64 characters each):
|
||||||
|
<code>19</code>,
|
||||||
|
<code>1V</code>,
|
||||||
|
<code>-E</code>,
|
||||||
|
<code>0i</code>,
|
||||||
|
<code>2C</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>1</number> player level (<number>2</number> B64 characters):
|
||||||
|
<code>1g</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
A <b>variable</b> number of powder "blocks" (<number>5</number> B64 characters which give us <number>6</number> powders per block).
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>For each of the 5 powderable equipment fields [helmet, chestplate, leggings, boots, weapon], we will have the following:</li>
|
||||||
|
<li><number>1</number> B64 character that says that we need <number>n</number> blocks for this item.</li>
|
||||||
|
<li><number>n</number> blocks of <number>5</number> B64 characters.</li>
|
||||||
|
<li>
|
||||||
|
Since there are 4 <code>0</code>s (B64 0 = 0 unsigned) in this example, we have no powders on any of the armor piece (no blocks).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Then, we have <code>1</code> (B64 1 = 1 unsigned). There is 1 block of powders to decode for the weapon item. That is <code>00nZ6</code>.
|
||||||
|
</li>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>The unsigned equivalent of <code>00nZ6</code> in binary is 30 <b>binary</b> bits long (omitted). Each section of 5 bits directly corresponds to an powder ID.</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
It is possible that version 4 links will have an extra tome string like above (see: Version 6 section) after the powders. You can ignore this in decoding.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="row section" title="Version 3">
|
||||||
|
<p>
|
||||||
|
Version 3 encoding added the ability to save build level.
|
||||||
|
</p>
|
||||||
|
<div class = "row section" title = "Example">
|
||||||
|
<code class="full-width">
|
||||||
|
https://hppeng-wynn.github.io/builder/#3_06W2SH0D40Qq2SK2SL02d0og0Qi191V-E0i2C1g0000100nZ6
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
Build hash format:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>
|
||||||
|
<number>9</number> items from <code>idMap</code> (<number>3</number> B64 characters each):
|
||||||
|
<code>06W</code>,
|
||||||
|
<code>2SH</code>,
|
||||||
|
<code>0D4</code>,
|
||||||
|
<code>0Qq</code>,
|
||||||
|
<code>2SK</code>,
|
||||||
|
<code>2SL</code>,
|
||||||
|
<code>02d</code>,
|
||||||
|
<code>0og</code>,
|
||||||
|
<code>0Qi</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>5</number> skill point totals (<number>2</number> B64 characters each):
|
||||||
|
<code>19</code>,
|
||||||
|
<code>1V</code>,
|
||||||
|
<code>-E</code>,
|
||||||
|
<code>0i</code>,
|
||||||
|
<code>2C</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>1</number> player level (<number>2</number> B64 characters):
|
||||||
|
<code>1g</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
A <b>variable</b> number of powder "blocks" (<number>5</number> B64 characters which give us <number>6</number> powders per block).
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>For each of the 5 powderable equipment fields [helmet, chestplate, leggings, boots, weapon], we will have the following:</li>
|
||||||
|
<li><number>1</number> B64 character that says that we need <number>n</number> blocks for this item.</li>
|
||||||
|
<li><number>n</number> blocks of <number>5</number> B64 characters.</li>
|
||||||
|
<li>
|
||||||
|
Since there are 4 <code>0</code>s (B64 0 = 0 unsigned) in this example, we have no powders on any of the armor piece (no blocks).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Then, we have <code>1</code> (B64 1 = 1 unsigned). There is 1 block of powders to decode for the weapon item. That is <code>00nZ6</code>.
|
||||||
|
</li>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>The unsigned equivalent of <code>00nZ6</code> in binary is 30 <b>binary</b> bits long (omitted). Each section of 5 bits directly corresponds to an powder ID.</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row section" title="Version 2">
|
||||||
|
<p>
|
||||||
|
Version 2 encoding added the ability to save skill point info.
|
||||||
|
</p>
|
||||||
|
<div class = "row section" title = "Example">
|
||||||
|
<code class="full-width">
|
||||||
|
https://hppeng-wynn.github.io/builder/#2_06W2SH0D40Qq2SK2SL02d0og0Qi191V-E0i2C0000100nZ6
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
Build hash format:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>
|
||||||
|
<number>9</number> items from <code>idMap</code> (<number>3</number> B64 characters each):
|
||||||
|
<code>06W</code>,
|
||||||
|
<code>2SH</code>,
|
||||||
|
<code>0D4</code>,
|
||||||
|
<code>0Qq</code>,
|
||||||
|
<code>2SK</code>,
|
||||||
|
<code>2SL</code>,
|
||||||
|
<code>02d</code>,
|
||||||
|
<code>0og</code>,
|
||||||
|
<code>0Qi</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<number>5</number> skill point totals (<number>2</number> B64 characters each):
|
||||||
|
<code>19</code>,
|
||||||
|
<code>1V</code>,
|
||||||
|
<code>-E</code>,
|
||||||
|
<code>0i</code>,
|
||||||
|
<code>2C</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
A <b>variable</b> number of powder "blocks" (<number>5</number> B64 characters which give us <number>6</number> powders per block).
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>For each of the 5 powderable equipment fields [helmet, chestplate, leggings, boots, weapon], we will have the following:</li>
|
||||||
|
<li><number>1</number> B64 character that says that we need <number>n</number> blocks for this item.</li>
|
||||||
|
<li><number>n</number> blocks of <number>5</number> B64 characters.</li>
|
||||||
|
<li>
|
||||||
|
Since there are 4 <code>0</code>s (B64 0 = 0 unsigned) in this example, we have no powders on any of the armor piece (no blocks).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Then, we have <code>1</code> (B64 1 = 1 unsigned). There is 1 block of powders to decode for the weapon item. That is <code>00nZ6</code>.
|
||||||
|
</li>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>The unsigned equivalent of <code>00nZ6</code> in binary is 30 <b>binary</b> bits long (omitted). Each section of 5 bits directly corresponds to an powder ID.</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row section" title="Version 1">
|
||||||
|
<p>
|
||||||
|
Version 1 is the very first encoding version by Wynnbuilder. It allows for saving all equipment (armors, accessories, weapon) and powders put on that equipment.
|
||||||
|
</p>
|
||||||
|
<div class = "row section" title = "Example">
|
||||||
|
<code class="full-width">
|
||||||
|
https://hppeng-wynn.github.io/builder/#1_06W2SH0D40Qq2SK2SL02d0og0Qi0000100nZ6
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
Build hash format:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>
|
||||||
|
<number>9</number> items from <code>idMap</code> (<number>3</number> B64 characters each):
|
||||||
|
<code>06W</code>,
|
||||||
|
<code>2SH</code>,
|
||||||
|
<code>0D4</code>,
|
||||||
|
<code>0Qq</code>,
|
||||||
|
<code>2SK</code>,
|
||||||
|
<code>2SL</code>,
|
||||||
|
<code>02d</code>,
|
||||||
|
<code>0og</code>,
|
||||||
|
<code>0Qi</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
A <b>variable</b> number of powder "blocks" (<number>5</number> B64 characters which give us <number>6</number> powders per block).
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>For each of the 5 powderable equipment fields [helmet, chestplate, leggings, boots, weapon], we will have the following:</li>
|
||||||
|
<li><number>1</number> B64 character that says that we need <number>n</number> blocks for this item.</li>
|
||||||
|
<li><number>n</number> blocks of <number>5</number> B64 characters.</li>
|
||||||
|
<li>
|
||||||
|
Since there are 4 <code>0</code>s (B64 0 = 0 unsigned) in this example, we have no powders on any of the armor piece (no blocks).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Then, we have <code>1</code> (B64 1 = 1 unsigned). There is 1 block of powders to decode for the weapon item. That is <code>00nZ6</code>.
|
||||||
|
</li>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>The unsigned equivalent of <code>00nZ6</code> in binary is 30 <b>binary</b> bits long (omitted). Each section of 5 bits directly corresponds to an powder ID.</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="row section" title="Crafted Items">
|
||||||
|
<p>
|
||||||
|
This section is about how to decode crafted items. To view an example of a crafted item in a build, check out <b>Builds > Version 4</b>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Crafted items always start with "CR-" so that they are, as an entire category, distinguishable from item pool items. The ingredients and materials that make up the crafted item are stored in the rest of the "hash".
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
To encode all the info about a crafted item, we need:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>Ingredient Data</li>
|
||||||
|
<li>Recipe Data</li>
|
||||||
|
<li>Crafting Material Tiers</li>
|
||||||
|
<li>Attack Speed (for weapons)</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Wynnbuilder assigns each ingredient and recipe to a unique ID number.
|
||||||
|
</p>
|
||||||
|
<div class = "row section" title = "ID number specifics">
|
||||||
|
<p>
|
||||||
|
For ingredients, you can download the ingredient id map here: <a href = "../ing_map.json" target = "_blank">ing_map.json</a>. The ID number for No Ingredient is 4000.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For recipes, you can download the recipe id map here: <a href = "../recipe_map.json" target = "_blank">recipe_map.json</a> or the recipe DB here: <a href = "recipes_clean.json" target = "_blank">recipes_clean.json</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class = "row section" title = "Version 1">
|
||||||
|
<p>
|
||||||
|
This is the first version of crafted item encoding. Crafted Items are always stored in a constant number of B64 characters.
|
||||||
|
</p>
|
||||||
|
<div class = "row section" title = "Example - Crafted Item">
|
||||||
|
<p>
|
||||||
|
This example shows how to parse a crafted item hash.
|
||||||
|
</p>
|
||||||
|
<code class = "full-width">
|
||||||
|
CR-1628i8v8v94948f21
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
Crafted item hash format:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li><number>3</number> characters to denote item type as crafted: <code>CR-</code> (always)</li>
|
||||||
|
<li><number>1</number> character for encoding version: <code>1</code> </li>
|
||||||
|
<li><number>6</number> ingredient IDs (<number>2</number> B64 characters each):
|
||||||
|
<code>62</code>,
|
||||||
|
<code>8i</code>,
|
||||||
|
<code>8v</code>,
|
||||||
|
<code>8v</code>,
|
||||||
|
<code>94</code>,
|
||||||
|
<code>94</code>
|
||||||
|
</li>
|
||||||
|
<li><number>2</number> B64 characters for recipe ID: <code>8f</code></li>
|
||||||
|
<li><number>1</number> character to encode material tiers: <code>2</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>There are 2 material tiers to decode. The ordering of materials is determined by their order within the corresponding recipe object held in the db.</li>
|
||||||
|
<li>The material tier character (from here on <math>t</math>) is in the range [<number>1</number>, <number>9</number>]. </li>
|
||||||
|
<li>Mat 1's tier is equal to <math>t % 3</math> except when this yields 0, in which case it becomes 3.</li>
|
||||||
|
<li>Mat 2's tier is equal to ceil(<math> (t - 0.5) / 3</math>).</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><number>1</number> character to encode attack speed: <code>1</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>The integer after doing unsigned decoding from the B64 character denotes the index within the following array: [SLOW, NORMAL, FAST]. B64 <code>1</code> maps to the unsigned integer <number>1</number>, meaning that the attack speed of this crafted item would be NORMAL if it were a weapon.</li>
|
||||||
|
<li>Note: although only weapons will have attack speed, we decided to include the character in all crafted item hashes to keep a constant hash length.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You may need to parse a crafted item from a wynnbuilder crafter link.
|
||||||
|
</p>
|
||||||
|
<code class = "full-width">
|
||||||
|
https://hppeng-wynn.github.io/crafter/#1628i8v8v94948f21
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
We can simply take the string after the octothorpe/hash tag (#), tack on "CR-" in front of this string, and arrive at the full hash for the crafted item in question. Decode using the same logic as the previous example.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="row section" title="Custom Items">
|
||||||
|
<p>
|
||||||
|
This section is about how to decode custom items. To view an example of a custom item in a build, check out <b>Builds > Version 5</b>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Custom items always start with "CI-" so that they are, as an entire category, distinguishable from item pool items. The stats and values that make up the custom item are stored in the rest of the "hash".
|
||||||
|
</p>
|
||||||
|
<div class = "row section" title = "Version 1">
|
||||||
|
<p>This is the first version of custom item encoding and decoding.</p>
|
||||||
|
<p>You will need the full array of item identification saving order and all non-rolled identifications (ex: name). View them below.</p>
|
||||||
|
<div class = "row section" title = "Important Arrays">
|
||||||
|
<p> ID saving order: <code>ci_save_order = ["name", "lore", "tier", "set", "slots", "type", "material", "drop", "quest", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "atkSpd", "hp", "fDef", "wDef", "aDef", "tDef", "eDef", "lvl", "classReq", "strReq", "dexReq", "intReq", "defReq", "agiReq","str", "dex", "int", "agi", "def", "id", "skillpoints", "reqs", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_", "majorIds", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd","durability","duration","charges"];</code> </p>
|
||||||
|
<p> Non-rolled string IDs: <code>nonRolled_strings = ["name", "lore", "tier", "set", "type", "material", "drop", "quest", "majorIds", "classReq", "atkSpd", "displayName", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_", "durability", "duration"];</code></p>
|
||||||
|
<p> Rolled IDs: <code>rolledIDs = ["hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd"];</code></p>
|
||||||
|
<p> Non-rolled IDs: <code>nonRolledIDs = ["name", "lore", "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", "str", "dex", "int", "agi", "def", "fixID", "category", "id", "skillpoints", "reqs", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_", "majorIds"];</code></p>
|
||||||
|
<p> Tiers: <code>tiers = ["Normal", "Unique", "Rare", "Legendary", "Fabled", "Mythic", "Set", "Crafted"]</code></p>
|
||||||
|
<p> Types: <code>types = [ "helmet", "chestplate", "leggings", "boots", "ring", "bracelet", "necklace", "wand", "spear", "bow", "dagger", "relik", "potion", "scroll", "food"];</code></p>
|
||||||
|
<p> Attack Speeds: <code>attackSpeeds = ["SUPER_SLOW", "VERY_SLOW", "SLOW", "NORMAL", "FAST", "VERY_FAST", "SUPER_FAST"];</code></p>
|
||||||
|
<p> Class Requirements: <code>classes = ["Warrior", "Assassin", "Mage", "Archer", "Shaman"]</code> </p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class = "row section" title = "Example">
|
||||||
|
<p>
|
||||||
|
Here's an example of a custom item hash.
|
||||||
|
</p>
|
||||||
|
<code class = "full-width">
|
||||||
|
CI-10000HMeta%20Chestplate010Gbest%20in%20slot0240401030510G0302SG0H020Fe0I020Fe0J020Fe0K020Fe0L020Fe0M0201Y0i0200U220z0204iKK150200U22160200U22170200U22180200U22190200U22
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
Given a custom item hash, we will in general continue to parse through many identifications and their values until we reach the end of the custom item hash.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Custom item hash format:
|
||||||
|
</p>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li><number>1</number> B64 character denoting encoding/decoding version number: <code>1</code></li>
|
||||||
|
<li><number>1</number> character denoting whether or not this item has fixed IDs: <code>0</code>. (0 for no fixed IDs, 1 for fixed IDs)</li>
|
||||||
|
<li>A series of encoded identifications, each taking a variable number of characters. For every ID, we have to save:
|
||||||
|
<ul class = "indent">
|
||||||
|
<li><number>2</number> B64 characters that represent the identification ID (its index in the CI save order array). </li>
|
||||||
|
<li><number>2</number> B64 characters that represent the length <math>len</math> of the value of the identification.</li>
|
||||||
|
<li>A variable number characters to encode the value of the identification.
|
||||||
|
<li>For string-valued identifications (in the non-rolled strings array), we do not use any encoding for the value. The next <number>len</number> characters of the custom item hash is the raw value of the identification (before substituting space for "%20").
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>Exception: for the identifications <code>tier</code>, <code>type</code>, <code>atkSpd</code>, and <code>classReq</code>, there is no string used. They are encoded as a numerical value representing an index in a pre-defined array (check the Important Arrays section above). They also do not use the earlier-specified 2 characters to store length; instead, they each use only 1 B64 character to store their index in their corresponding arrays.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>For numerical-valued identifications, encoding depends on the fixed ID value from before.
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>Rolled IDs (with non-fixed IDs):
|
||||||
|
<ul class = "indent">
|
||||||
|
<li><number>1</number> character to denote the sign of the min and max values: 0 for both positive, 1 for negative min and positive max, 2 for positive min and negative max, and 3 for both negative.</li>
|
||||||
|
<li><number>len</number> B64 characters that represent the unsigned <b>minimum</b> value of the identification.</li>
|
||||||
|
<li><number>len</number> B64 characters that represent the unsigned <b>maximum</b> value of the identification.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>Rolled IDs (with fixed IDs) and Non-Rolled IDs:
|
||||||
|
<ul class = "indent">
|
||||||
|
<li><number>1</number> character (binary bit) to denote the sign of the value (0 positive, 1 negative).</li>
|
||||||
|
<li><number>len</number> B64 characters that represent the unsigned value of the identification.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>To finish the example, we'll go through all the actual identifications of the provided custom item.
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>"CI-" constant portion</li>
|
||||||
|
<li>Encoding version number: <code>1</code></li>
|
||||||
|
<li>Fixed IDs: <code>0</code> (non-fixed IDs)</li>
|
||||||
|
<li><code>000HMeta%20Chestplate</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>00</code> ("name")</li>
|
||||||
|
<li>ID value length: <code>0H</code> (<number>17</number>)</li>
|
||||||
|
<li>ID value: <code>Meta%20Chestplate</code> ("Meta Chestplate")</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>010Gbest%20in%20slot</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>01</code> ("lore")</li>
|
||||||
|
<li>ID value length: <code>0G</code> (<number>16</number>)</li>
|
||||||
|
<li>ID value: <code>best%20in%20slot</code> ("best in slot")</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>024</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>02</code> ("tier")</li>
|
||||||
|
<li>ID value length: None (exception) </li>
|
||||||
|
<li>ID value: <code>4</code> (tiers[4] = "Fabled")</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>040103</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>04</code> ("slots")</li>
|
||||||
|
<li>ID value length: <code>01</code> (<number>1</number>)</li>
|
||||||
|
<li>ID sign: <code>0</code> (positive)</li>
|
||||||
|
<li>ID value: <code>3</code> (<number>3</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>051</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>05</code> ("type")</li>
|
||||||
|
<li>ID value length: None (exception)</li>
|
||||||
|
<li>ID value: <code>1</code> (types[1] = "chestplate")</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>0G0302SG</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>0G</code> ("hp")</li>
|
||||||
|
<li>ID value length: <code>03</code> (<number>3</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (positive)</li>
|
||||||
|
<li>ID value: <code>2SG</code> (<number>10000</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>0H020Fe</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>0H</code> ("fDef")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (positive)</li>
|
||||||
|
<li>ID value: <code>Fe</code> (<number>1000</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>0I020Fe</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>0I</code> ("wDef")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (positive)</li>
|
||||||
|
<li>ID value: <code>Fe</code> (<number>1000</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>0J020Fe</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>0J</code> ("aDef")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (positive)</li>
|
||||||
|
<li>ID value: <code>Fe</code> (<number>1000</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>0K020Fe</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>0K</code> ("tDef")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (positive)</li>
|
||||||
|
<li>ID value: <code>Fe</code> (<number>1000</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>0L020Fe</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>0L</code> ("eDef")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (positive)</li>
|
||||||
|
<li>ID value: <code>Fe</code> (<number>1000</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>0M0201Y</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>0M</code> ("lvl")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (positive)</li>
|
||||||
|
<li>ID value: <code>1Y</code> (<number>98</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>0i0200U22</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>0i</code> ("hprPct")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (both positive)</li>
|
||||||
|
<li>ID value minimum: <code>0U</code> (<number>30</number>)</li>
|
||||||
|
<li>ID value maximum: <code>22</code> (<number>130</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>0z0204iKK</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>0z</code> ("hprRaw")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (both positive)</li>
|
||||||
|
<li>ID value minimum: <code>4i</code> (<number>300</number>)</li>
|
||||||
|
<li>ID value maximum: <code>KK</code> (<number>1300</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>0z0204iKK</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>0z</code> ("hprRaw")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (both positive)</li>
|
||||||
|
<li>ID value minimum: <code>4i</code> (<number>300</number>)</li>
|
||||||
|
<li>ID value maximum: <code>KK</code> (<number>1300</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>150200U22</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>15</code> ("fDefPct")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (both positive)</li>
|
||||||
|
<li>ID value minimum: <code>0U</code> (<number>30</number>)</li>
|
||||||
|
<li>ID value maximum: <code>22</code> (<number>130</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>160200U22</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>16</code> ("wDefPct")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (both positive)</li>
|
||||||
|
<li>ID value minimum: <code>0U</code> (<number>30</number>)</li>
|
||||||
|
<li>ID value maximum: <code>22</code> (<number>130</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>170200U22</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>17</code> ("aDefPct")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (both positive)</li>
|
||||||
|
<li>ID value minimum: <code>0U</code> (<number>30</number>)</li>
|
||||||
|
<li>ID value maximum: <code>22</code> (<number>130</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>180200U22</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>18</code> ("tDefPct")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (both positive)</li>
|
||||||
|
<li>ID value minimum: <code>0U</code> (<number>30</number>)</li>
|
||||||
|
<li>ID value maximum: <code>22</code> (<number>130</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><code>190200U22</code>
|
||||||
|
<ul class = "indent">
|
||||||
|
<li>ID name: <code>19</code> ("eDefPct")</li>
|
||||||
|
<li>ID value length: <code>02</code> (<number>2</number>) </li>
|
||||||
|
<li>ID sign: <code>0</code> (both positive)</li>
|
||||||
|
<li>ID value minimum: <code>0U</code> (<number>30</number>)</li>
|
||||||
|
<li>ID value maximum: <code>22</code> (<number>130</number>)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- TODO -->
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You may need to parse a custom item from a Wynnbuilder customizer link.
|
||||||
|
</p>
|
||||||
|
<code class = "full-width">
|
||||||
|
hppeng-wynn.github.io/custom/#10000HMeta%20Chestplate010Gbest%20in%20slot0240401030510G0302SG0H020Fe0I020Fe0J020Fe0K020Fe0L020Fe0M0201Y0i0200U220z0204iKK150200U22160200U22170200U22180200U22190200U22
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
Similar to crafted items, the part of the link after the "#" is the rest of the custom item after the "CI-" constant portion. You may need to convert all "%20" to spaces manually.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Details on reading custom items in build links are provided in the Decoding WB links > Builds section.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Last updated: 30 May 2022
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="row section" title="Test Section">
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="../js/dev.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/sq2icons.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -28,9 +28,9 @@
|
||||||
<a href = "../builder/"><img src="../media/icons/new/builder.png" alt = "WynnBuilder" title = "WynnBuilder"><b>WynnBuilder</b></a>
|
<a href = "../builder/"><img src="../media/icons/new/builder.png" alt = "WynnBuilder" title = "WynnBuilder"><b>WynnBuilder</b></a>
|
||||||
<a href = "../crafter/"><img src = "../media/icons/new/crafter.png" alt = "WynnCrafter" title = "WynnCrafter"><b>WynnCrafter</b></a>
|
<a href = "../crafter/"><img src = "../media/icons/new/crafter.png" alt = "WynnCrafter" title = "WynnCrafter"><b>WynnCrafter</b></a>
|
||||||
<a href = "../items/"><img src = "../media/icons/new/searcher.png" alt = "WynnAtlas" title = "WynnAtlas"><b>WynnAtlas</b></a>
|
<a href = "../items/"><img src = "../media/icons/new/searcher.png" alt = "WynnAtlas" title = "WynnAtlas"><b>WynnAtlas</b></a>
|
||||||
<a href = "/customizer.html"><img src = "../media/icons/new/custom.png" alt = "WynnCustom" title = "WynnCustom"><b>WynnCustom</b></a>
|
<a href = "../custom/"><img src = "../media/icons/new/custom.png" alt = "WynnCustom" title = "WynnCustom"><b>WynnCustom</b></a>
|
||||||
<a href = "/map.html"><img src = "../media/icons/new/compass.png" alt = "WynnGPS" title = "WynnGPS"><b>WynnGPS</b></a>
|
<a href = "../map/"><img src = "../media/icons/new/compass.png" alt = "WynnGPS" title = "WynnGPS"><b>WynnGPS</b></a>
|
||||||
<a href = "/wynnfo/index.html"><img src = "../media/icons/new/book.png" alt = "Wynnfo" title = "WynnCrafter"><b>WynnCrafter</b></a>
|
<a href = "../wynnfo/"><img src = "../media/icons/new/book.png" alt = "Wynnfo" title = "WynnCrafter"><b>WynnCrafter</b></a>
|
||||||
<a onclick = "toggleIcons()"><img src = "../media/icons/new/reload.png" alt = "" title = "Swap items on page"><b>Swap Icon Style</b></a>
|
<a onclick = "toggleIcons()"><img src = "../media/icons/new/reload.png" alt = "" title = "Swap items on page"><b>Swap Icon Style</b></a>
|
||||||
<hr/>
|
<hr/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -220,6 +220,6 @@
|
||||||
docsFns.append(genDocEntry(entry[0], entry[1], null, entry[2]));
|
docsFns.append(genDocEntry(entry[0], entry[1], null, entry[2]));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="/js/icons.js"></script>
|
<script type="text/javascript" src="../js/sq2icons.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
143
js/custom.js
143
js/custom.js
|
@ -1,5 +1,6 @@
|
||||||
const ci_save_order = ["name", "lore", "tier", "set", "slots", "type", "material", "drop", "quest", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "atkSpd", "hp", "fDef", "wDef", "aDef", "tDef", "eDef", "lvl", "classReq", "strReq", "dexReq", "intReq", "defReq", "agiReq","str", "dex", "int", "agi", "def", "id", "skillpoints", "reqs", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_", "majorIds", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd","durability","duration","charges"];
|
const ci_save_order = ["name", "lore", "tier", "set", "slots", "type", "material", "drop", "quest", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "atkSpd", "hp", "fDef", "wDef", "aDef", "tDef", "eDef", "lvl", "classReq", "strReq", "dexReq", "intReq", "defReq", "agiReq", "str", "dex", "int", "agi", "def", "id", "skillpoints", "reqs", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_", "majorIds", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd", "durability", "duration", "charges"];
|
||||||
const nonRolled_strings = ["name","lore", "tier","set","type","material","drop","quest","majorIds","classReq","atkSpd","displayName", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_", "durability", "duration"];
|
const nonRolled_strings = ["name", "lore", "tier", "set", "type", "material", "drop", "quest", "majorIds", "classReq", "atkSpd", "displayName", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_", "durability", "duration"];
|
||||||
|
|
||||||
//omitted restrict - it's always "Custom Item"
|
//omitted restrict - it's always "Custom Item"
|
||||||
//omitted displayName - either it's the same as name (repetitive) or it's "Custom Item"
|
//omitted displayName - either it's the same as name (repetitive) or it's "Custom Item"
|
||||||
//omitted category - can always get this from type
|
//omitted category - can always get this from type
|
||||||
|
@ -34,19 +35,19 @@ function encodeCustom(custom, verbose) {
|
||||||
// 1 - min neg max pos
|
// 1 - min neg max pos
|
||||||
// 2 - min pos max neg (how?)
|
// 2 - min pos max neg (how?)
|
||||||
// 3 - min neg max neg
|
// 3 - min neg max neg
|
||||||
let sign = (Boolean(val_min / Math.abs(val_min) < 0) | 0) + 2*(Boolean(val_max / Math.abs(val_max) < 0) | 0);
|
let sign = (Boolean(val_min / Math.abs(val_min) < 0) | 0) + 2 * (Boolean(val_max / Math.abs(val_max) < 0) | 0);
|
||||||
//console.log(id + ": " + sign);
|
//console.log(id + ": " + sign);
|
||||||
let min_len = Math.max(1,Math.ceil(log(64,Math.abs(val_min)+1)));
|
let min_len = Math.max(1, Math.ceil(log(64, Math.abs(val_min) + 1)));
|
||||||
let max_len = Math.max(1,Math.ceil(log(64,Math.abs(val_max)+1)));
|
let max_len = Math.max(1, Math.ceil(log(64, Math.abs(val_max) + 1)));
|
||||||
let len = Math.max(min_len,max_len);
|
let len = Math.max(min_len, max_len);
|
||||||
val_min = Math.abs(val_min);
|
val_min = Math.abs(val_min);
|
||||||
val_max = Math.abs(val_max);
|
val_max = Math.abs(val_max);
|
||||||
|
|
||||||
if ( val_min != 0 || val_max != 0 ) {
|
if (val_min != 0 || val_max != 0) {
|
||||||
if (custom.get("fixID")) {
|
if (custom.get("fixID")) {
|
||||||
hash += Base64.fromIntN(i,2) + Base64.fromIntN(len,2) + sign + Base64.fromIntN(val_min, len);
|
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(len, 2) + sign + Base64.fromIntN(val_min, len);
|
||||||
} else {
|
} else {
|
||||||
hash += Base64.fromIntN(i,2) + Base64.fromIntN(len,2) + sign + Base64.fromIntN(val_min, len) + Base64.fromIntN(val_max,len);
|
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(len, 2) + sign + Base64.fromIntN(val_min, len) + Base64.fromIntN(val_max, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -61,25 +62,25 @@ function encodeCustom(custom, verbose) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof(val) === "string" && val !== "") {
|
if (typeof (val) === "string" && val !== "") {
|
||||||
if ((damages.includes(id) && val === "0-0") || (!verbose && ["lore","majorIds","quest","materials","drop","set"].includes(id))) { continue; }
|
if ((damages.includes(id) && val === "0-0") || (!verbose && ["lore", "majorIds", "quest", "materials", "drop", "set"].includes(id))) { continue; }
|
||||||
if (id === "type") {
|
if (id === "type") {
|
||||||
hash += Base64.fromIntN(i,2) + Base64.fromIntN(types.indexOf(val.substring(0,1).toUpperCase()+val.slice(1)),1);
|
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(types.indexOf(val.substring(0, 1).toUpperCase() + val.slice(1)), 1);
|
||||||
} else if (id === "tier") {
|
} else if (id === "tier") {
|
||||||
hash += Base64.fromIntN(i,2) + Base64.fromIntN(tiers.indexOf(val),1);
|
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(tiers.indexOf(val), 1);
|
||||||
} else if (id === "atkSpd") {
|
} else if (id === "atkSpd") {
|
||||||
hash += Base64.fromIntN(i,2) + Base64.fromIntN(attackSpeeds.indexOf(val),1);
|
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(attackSpeeds.indexOf(val), 1);
|
||||||
} else if (id === "classReq") {
|
} else if (id === "classReq") {
|
||||||
hash += Base64.fromIntN(i,2) + Base64.fromIntN(classes.indexOf(val),1);
|
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(classes.indexOf(val), 1);
|
||||||
} else {
|
} else {
|
||||||
hash += Base64.fromIntN(i,2) + Base64.fromIntN(val.replaceAll(" ", "%20").length,2) + val.replaceAll(" ", "%20"); //values cannot go above 4096 chars!!!! Is this ok?
|
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(val.replaceAll(" ", "%20").length, 2) + val.replaceAll(" ", "%20"); //values cannot go above 4096 chars!!!! Is this ok?
|
||||||
}
|
}
|
||||||
} else if (typeof(val) === "number" && val != 0) {
|
} else if (typeof (val) === "number" && val != 0) {
|
||||||
let len = Math.max(1,Math.ceil(log(64,Math.abs(val))));
|
let len = Math.max(1, Math.ceil(log(64, Math.abs(val))));
|
||||||
let sign = Boolean(val / Math.abs(val) < 0) | 0;
|
let sign = Boolean(val / Math.abs(val) < 0) | 0;
|
||||||
//console.log(sign);
|
//console.log(sign);
|
||||||
//hash += Base64.fromIntN(i,2) + Base64.fromIntN(val,Math.max(1,Math.ceil(log(64,Math.abs(val))))) + "_";
|
//hash += Base64.fromIntN(i,2) + Base64.fromIntN(val,Math.max(1,Math.ceil(log(64,Math.abs(val))))) + "_";
|
||||||
hash += Base64.fromIntN(i,2) + Base64.fromIntN(len,2) + sign + Base64.fromIntN(Math.abs(val),len);
|
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(len, 2) + sign + Base64.fromIntN(Math.abs(val), len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,15 +94,17 @@ function encodeCustom(custom, verbose) {
|
||||||
function getCustomFromHash(hash) {
|
function getCustomFromHash(hash) {
|
||||||
let name = hash.slice();
|
let name = hash.slice();
|
||||||
let statMap;
|
let statMap;
|
||||||
|
console.log("decoding");
|
||||||
try {
|
try {
|
||||||
if (name.slice(0,3) === "CI-") {
|
if (name.slice(0, 3) === "CI-") {
|
||||||
name = name.substring(3);
|
name = name.substring(3);
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Not a custom item!");
|
throw new Error("Not a custom item!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//probably change vers and fixID to be encoded and decoded to/from B64 in the future
|
||||||
let version = name.charAt(0);
|
let version = name.charAt(0);
|
||||||
let fixID = Boolean(parseInt(name.charAt(1),10));
|
let fixID = Boolean(parseInt(name.charAt(1), 10));
|
||||||
let tag = name.substring(2);
|
let tag = name.substring(2);
|
||||||
statMap = new Map();
|
statMap = new Map();
|
||||||
statMap.set("minRolls", new Map());
|
statMap.set("minRolls", new Map());
|
||||||
|
@ -113,29 +116,29 @@ function getCustomFromHash(hash) {
|
||||||
statMap.set("fixID", true);
|
statMap.set("fixID", true);
|
||||||
}
|
}
|
||||||
while (tag !== "") {
|
while (tag !== "") {
|
||||||
let id = ci_save_order[Base64.toInt(tag.slice(0,2))];
|
let id = ci_save_order[Base64.toInt(tag.slice(0, 2))];
|
||||||
let len = Base64.toInt(tag.slice(2,4));
|
let len = Base64.toInt(tag.slice(2, 4));
|
||||||
if (rolledIDs.includes(id)) {
|
if (rolledIDs.includes(id)) {
|
||||||
let sign = parseInt(tag.slice(4,5),10);
|
let sign = parseInt(tag.slice(4, 5), 10);
|
||||||
let minRoll = Base64.toInt(tag.slice(5,5+len));
|
let minRoll = Base64.toInt(tag.slice(5, 5 + len));
|
||||||
if (!fixID) {
|
if (!fixID) {
|
||||||
let maxRoll = Base64.toInt(tag.slice(5+len,5+2*len));
|
let maxRoll = Base64.toInt(tag.slice(5 + len, 5 + 2 * len));
|
||||||
if (sign > 1) {
|
if (sign > 1) {
|
||||||
maxRoll *= -1;
|
maxRoll *= -1;
|
||||||
}
|
}
|
||||||
if (sign % 2 == 1) {
|
if (sign % 2 == 1) {
|
||||||
minRoll *= -1;
|
minRoll *= -1;
|
||||||
}
|
}
|
||||||
statMap.get("minRolls").set(id,minRoll);
|
statMap.get("minRolls").set(id, minRoll);
|
||||||
statMap.get("maxRolls").set(id,maxRoll);
|
statMap.get("maxRolls").set(id, maxRoll);
|
||||||
tag = tag.slice(5+2*len);
|
tag = tag.slice(5 + 2 * len);
|
||||||
} else {
|
} else {
|
||||||
if (sign != 0) {
|
if (sign != 0) {
|
||||||
minRoll *= -1;
|
minRoll *= -1;
|
||||||
}
|
}
|
||||||
statMap.get("minRolls").set(id,minRoll);
|
statMap.get("minRolls").set(id, minRoll);
|
||||||
statMap.get("maxRolls").set(id,minRoll);
|
statMap.get("maxRolls").set(id, minRoll);
|
||||||
tag = tag.slice(5+len);
|
tag = tag.slice(5 + len);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let val;
|
let val;
|
||||||
|
@ -153,16 +156,16 @@ function getCustomFromHash(hash) {
|
||||||
val = classes[Base64.toInt(tag.charAt(2))];
|
val = classes[Base64.toInt(tag.charAt(2))];
|
||||||
len = -1;
|
len = -1;
|
||||||
} else { //general case
|
} else { //general case
|
||||||
val = tag.slice(4,4+len).replaceAll("%20"," ");
|
val = tag.slice(4, 4 + len).replaceAll("%20", " ");
|
||||||
}
|
}
|
||||||
tag = tag.slice(4+len);
|
tag = tag.slice(4 + len);
|
||||||
} else {
|
} else {
|
||||||
let sign = parseInt(tag.slice(4,5),10);
|
let sign = parseInt(tag.slice(4, 5), 10);
|
||||||
val = Base64.toInt(tag.slice(5,5+len));
|
val = Base64.toInt(tag.slice(5, 5 + len));
|
||||||
if (sign == 1) {
|
if (sign == 1) {
|
||||||
val *= -1;
|
val *= -1;
|
||||||
}
|
}
|
||||||
tag = tag.slice(5+len);
|
tag = tag.slice(5 + len);
|
||||||
}
|
}
|
||||||
if (id === "majorIds") {
|
if (id === "majorIds") {
|
||||||
val = [val];
|
val = [val];
|
||||||
|
@ -171,7 +174,7 @@ function getCustomFromHash(hash) {
|
||||||
statMap.set(id, val);
|
statMap.set(id, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statMap.set("hash","CI-"+name);
|
statMap.set("hash", "CI-" + name);
|
||||||
return new Custom(statMap);
|
return new Custom(statMap);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -185,13 +188,13 @@ function getCustomFromHash(hash) {
|
||||||
* @dep Requires the use of nonRolledIDs and rolledIDs from display_constants.js.
|
* @dep Requires the use of nonRolledIDs and rolledIDs from display_constants.js.
|
||||||
* @dep Requires the use of attackSpeeds from build.js.
|
* @dep Requires the use of attackSpeeds from build.js.
|
||||||
*/
|
*/
|
||||||
class Custom{
|
class Custom {
|
||||||
/**
|
/**
|
||||||
* @description Construct a custom item (CI) from a statMap.
|
* @description Construct a custom item (CI) from a statMap.
|
||||||
* @param {statMap}: A map with keys from rolledIDs or nonRolledIDs or minRolls/maxRolls and values befitting the keys. minRolls and maxRolls are their own maps and have the same keys, but with minimum and maximum values (for rolls).
|
* @param {statMap}: A map with keys from rolledIDs or nonRolledIDs or minRolls/maxRolls and values befitting the keys. minRolls and maxRolls are their own maps and have the same keys, but with minimum and maximum values (for rolls).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
constructor(statMap){
|
constructor(statMap) {
|
||||||
this.statMap = statMap;
|
this.statMap = statMap;
|
||||||
// TODO patch
|
// TODO patch
|
||||||
// this.statMap.set("majorIds", [this.statMap.get("majorIds")]);
|
// this.statMap.set("majorIds", [this.statMap.get("majorIds")]);
|
||||||
|
@ -200,12 +203,12 @@ class Custom{
|
||||||
|
|
||||||
setHash(hash) {
|
setHash(hash) {
|
||||||
let ihash = hash.slice();
|
let ihash = hash.slice();
|
||||||
if (ihash.slice(0,3) !== "CI-") {
|
if (ihash.slice(0, 3) !== "CI-") {
|
||||||
ihash = "CI-" + hash;
|
ihash = "CI-" + hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hash = ihash;
|
this.hash = ihash;
|
||||||
this.statMap.set("hash",ihash);
|
this.statMap.set("hash", ihash);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateName(name) {
|
updateName(name) {
|
||||||
|
@ -218,26 +221,24 @@ class Custom{
|
||||||
* Follows the expandedItem item structure, similar to a crafted item.
|
* Follows the expandedItem item structure, similar to a crafted item.
|
||||||
* TODO: Check if this is even useful
|
* TODO: Check if this is even useful
|
||||||
*/
|
*/
|
||||||
initCustomStats(){
|
initCustomStats() {
|
||||||
//this.setHashVerbose(); //do NOT move sethash from here please
|
//this.setHashVerbose(); //do NOT move sethash from here please
|
||||||
|
|
||||||
this.statMap.set("custom", true);
|
|
||||||
console.log(this.statMap);
|
console.log(this.statMap);
|
||||||
|
|
||||||
for (const id of ci_save_order) {
|
for (const id of ci_save_order) {
|
||||||
if (rolledIDs.includes(id)) {
|
if (rolledIDs.includes(id)) {
|
||||||
if (!(this.statMap.get("minRolls").has(id) && this.statMap.get("minRolls").get(id))) {
|
if (!(this.statMap.get("minRolls").has(id) && this.statMap.get("minRolls").get(id))) {
|
||||||
this.statMap.get("minRolls").set(id,0);
|
this.statMap.get("minRolls").set(id, 0);
|
||||||
this.statMap.get("maxRolls").set(id,0);
|
this.statMap.get("maxRolls").set(id, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (nonRolled_strings.includes(id)) {
|
if (nonRolled_strings.includes(id)) {
|
||||||
if (!(this.statMap.has(id)&&this.statMap.get(id))) {
|
if (!(this.statMap.has(id) && this.statMap.get(id))) {
|
||||||
this.statMap.set(id,"");
|
this.statMap.set(id, "");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!(this.statMap.has(id)&&this.statMap.get(id))) {
|
if (!(this.statMap.has(id) && this.statMap.get(id))) {
|
||||||
this.statMap.set(id,0);
|
this.statMap.set(id, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,14 +246,14 @@ class Custom{
|
||||||
let type = this.statMap.get("type").toLowerCase();
|
let type = this.statMap.get("type").toLowerCase();
|
||||||
console.log(type);
|
console.log(type);
|
||||||
if (weaponTypes.includes(type)) {
|
if (weaponTypes.includes(type)) {
|
||||||
for (const n of ["nDam","eDam","tDam","wDam","fDam","aDam"]) {
|
for (const n of ["nDam", "eDam", "tDam", "wDam", "fDam", "aDam"]) {
|
||||||
if (!(this.statMap.has(n) && this.statMap.get(n))) {
|
if (!(this.statMap.has(n) && this.statMap.get(n))) {
|
||||||
this.statMap.set(n,"0-0");
|
this.statMap.set(n, "0-0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (const n of ["nDam","eDam","tDam","wDam","fDam","aDam"]) {
|
for (const n of ["nDam", "eDam", "tDam", "wDam", "fDam", "aDam"]) {
|
||||||
if (this.statMap.has(n)) {
|
if (this.statMap.has(n)) {
|
||||||
this.statMap.delete(n);
|
this.statMap.delete(n);
|
||||||
}
|
}
|
||||||
|
@ -260,15 +261,15 @@ class Custom{
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.statMap.get("type")) {
|
if (this.statMap.get("type")) {
|
||||||
this.statMap.set("type",this.statMap.get("type").toLowerCase());
|
this.statMap.set("type", this.statMap.get("type").toLowerCase());
|
||||||
if (armorTypes.includes(this.statMap.get("type"))) {
|
if (armorTypes.includes(this.statMap.get("type"))) {
|
||||||
this.statMap.set("category","armor");
|
this.statMap.set("category", "armor");
|
||||||
} else if (accessoryTypes.includes(this.statMap.get("type"))) {
|
} else if (accessoryTypes.includes(this.statMap.get("type"))) {
|
||||||
this.statMap.set("category","accessory");
|
this.statMap.set("category", "accessory");
|
||||||
} else if (weaponTypes.includes(this.statMap.get("type"))) {
|
} else if (weaponTypes.includes(this.statMap.get("type"))) {
|
||||||
this.statMap.set("category","weapon");
|
this.statMap.set("category", "weapon");
|
||||||
} else if (consumableTypes.includes(this.statMap.get("type"))) {
|
} else if (consumableTypes.includes(this.statMap.get("type"))) {
|
||||||
this.statMap.set("category","consumable");
|
this.statMap.set("category", "consumable");
|
||||||
} else if (tomeTypes.includes(this.statMap.get("type"))) {
|
} else if (tomeTypes.includes(this.statMap.get("type"))) {
|
||||||
this.statMap.set("category", "tome");
|
this.statMap.set("category", "tome");
|
||||||
}
|
}
|
||||||
|
@ -278,13 +279,13 @@ class Custom{
|
||||||
this.statMap.set("crafted", true);
|
this.statMap.set("crafted", true);
|
||||||
|
|
||||||
for (const e of skp_elements) {
|
for (const e of skp_elements) {
|
||||||
this.statMap.set(e+"DamLow", this.statMap.get(e+"Dam"));
|
this.statMap.set(e + "DamLow", this.statMap.get(e + "Dam"));
|
||||||
}
|
}
|
||||||
this.statMap.set("nDamLow", this.statMap.get("nDam"));
|
this.statMap.set("nDamLow", this.statMap.get("nDam"));
|
||||||
this.statMap.set("hpLow", this.statMap.get("hp"));
|
this.statMap.set("hpLow", this.statMap.get("hp"));
|
||||||
for (const e of skp_order) {
|
for (const e of skp_order) {
|
||||||
this.statMap.get("minRolls").set(e,this.statMap.get(e));
|
this.statMap.get("minRolls").set(e, this.statMap.get(e));
|
||||||
this.statMap.get("maxRolls").set(e,this.statMap.get(e));
|
this.statMap.get("maxRolls").set(e, this.statMap.get(e));
|
||||||
}
|
}
|
||||||
// for (const e of ["durability", "duration"]) {
|
// for (const e of ["durability", "duration"]) {
|
||||||
// if (this.statMap.get(e) === "") {
|
// if (this.statMap.get(e) === "") {
|
||||||
|
@ -294,15 +295,15 @@ class Custom{
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
this.statMap.set("lvlLow",this.statMap.get("lvl"));
|
this.statMap.set("lvlLow", this.statMap.get("lvl"));
|
||||||
if (this.statMap.get("category") === "weapon") {
|
if (this.statMap.get("category") === "weapon") {
|
||||||
//this is for powder purposes.
|
//this is for powder purposes.
|
||||||
//users will likely not stick to the 0.9,1.1 rule because custom item. We will get around this by breaking everything and rewarding users for sticking to 0.9,1.1.
|
//users will likely not stick to the 0.9,1.1 rule because custom item. We will get around this by breaking everything and rewarding users for sticking to 0.9,1.1.
|
||||||
this.statMap.set("nDamBaseLow", Math.floor((parseFloat(this.statMap.get("nDamLow")) + parseFloat(this.statMap.get("nDam"))) / 2) );
|
this.statMap.set("nDamBaseLow", Math.floor((parseFloat(this.statMap.get("nDamLow")) + parseFloat(this.statMap.get("nDam"))) / 2));
|
||||||
this.statMap.set("nDamBaseHigh", Math.floor((parseFloat(this.statMap.get("nDamLow")) + parseFloat(this.statMap.get("nDam"))) / 2) );
|
this.statMap.set("nDamBaseHigh", Math.floor((parseFloat(this.statMap.get("nDamLow")) + parseFloat(this.statMap.get("nDam"))) / 2));
|
||||||
for (const e in skp_elements) {
|
for (const e in skp_elements) {
|
||||||
this.statMap.set(skp_elements[e]+"DamBaseLow", Math.floor((parseFloat(this.statMap.get(skp_elements[e]+"DamLow")) + parseFloat(this.statMap.get(skp_elements[e]+"Dam"))) / 2));
|
this.statMap.set(skp_elements[e] + "DamBaseLow", Math.floor((parseFloat(this.statMap.get(skp_elements[e] + "DamLow")) + parseFloat(this.statMap.get(skp_elements[e] + "Dam"))) / 2));
|
||||||
this.statMap.set(skp_elements[e]+"DamBaseHigh", Math.floor((parseFloat(this.statMap.get(skp_elements[e]+"DamLow")) + parseFloat(this.statMap.get(skp_elements[e]+"Dam"))) / 2));
|
this.statMap.set(skp_elements[e] + "DamBaseHigh", Math.floor((parseFloat(this.statMap.get(skp_elements[e] + "DamLow")) + parseFloat(this.statMap.get(skp_elements[e] + "Dam"))) / 2));
|
||||||
}
|
}
|
||||||
this.statMap.set("ingredPowders", []);
|
this.statMap.set("ingredPowders", []);
|
||||||
}
|
}
|
||||||
|
@ -310,7 +311,7 @@ class Custom{
|
||||||
|
|
||||||
if (this.statMap.get("category") !== "weapon") {
|
if (this.statMap.get("category") !== "weapon") {
|
||||||
this.statMap.set("atkSpd", "");
|
this.statMap.set("atkSpd", "");
|
||||||
for (const n in ["nDam","eDam","tDam","wDam","fDam","aDam"]) {
|
for (const n in ["nDam", "eDam", "tDam", "wDam", "fDam", "aDam"]) {
|
||||||
//this.statMap.set(n,"");
|
//this.statMap.set(n,"");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -323,11 +324,11 @@ class Custom{
|
||||||
} else {
|
} else {
|
||||||
this.statMap.set("displayName", "Custom Item");
|
this.statMap.set("displayName", "Custom Item");
|
||||||
}
|
}
|
||||||
this.statMap.set("powders",[]);
|
this.statMap.set("powders", []);
|
||||||
|
|
||||||
|
|
||||||
this.statMap.set("reqs",[this.statMap.get("strReq"),this.statMap.get("dexReq"),this.statMap.get("intReq"),this.statMap.get("defReq"),this.statMap.get("agiReq")]);
|
this.statMap.set("reqs", [this.statMap.get("strReq"), this.statMap.get("dexReq"), this.statMap.get("intReq"), this.statMap.get("defReq"), this.statMap.get("agiReq")]);
|
||||||
this.statMap.set("skillpoints", [this.statMap.get("str"),this.statMap.get("dex"),this.statMap.get("int"),this.statMap.get("def"),this.statMap.get("agi")]);
|
this.statMap.set("skillpoints", [this.statMap.get("str"), this.statMap.get("dex"), this.statMap.get("int"), this.statMap.get("def"), this.statMap.get("agi")]);
|
||||||
|
|
||||||
|
|
||||||
this.statMap.set("restrict", "Custom Item")
|
this.statMap.set("restrict", "Custom Item")
|
||||||
|
|
|
@ -232,6 +232,7 @@ function decodeCustom(custom_url_tag) {
|
||||||
let id = ci_save_order[Base64.toInt(tag.slice(0,2))];
|
let id = ci_save_order[Base64.toInt(tag.slice(0,2))];
|
||||||
//console.log(tag.slice(0, 2) + ": " + id);
|
//console.log(tag.slice(0, 2) + ": " + id);
|
||||||
let len = Base64.toInt(tag.slice(2,4));
|
let len = Base64.toInt(tag.slice(2,4));
|
||||||
|
|
||||||
if (rolledIDs.includes(id)) {
|
if (rolledIDs.includes(id)) {
|
||||||
let sign = parseInt(tag.slice(4,5),10);
|
let sign = parseInt(tag.slice(4,5),10);
|
||||||
let minRoll = Base64.toInt(tag.slice(5,5+len));
|
let minRoll = Base64.toInt(tag.slice(5,5+len));
|
||||||
|
|
67
js/dev.js
Normal file
67
js/dev.js
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
function init_dev() {
|
||||||
|
let sections = document.getElementsByClassName("section");
|
||||||
|
|
||||||
|
for (const section of sections) {
|
||||||
|
//so clicking works
|
||||||
|
section.classList.add("down");
|
||||||
|
|
||||||
|
//add title and toggle character
|
||||||
|
let title_row = document.createElement("div");
|
||||||
|
title_row.classList.add("row", "section-title");
|
||||||
|
let title = document.createElement("div");
|
||||||
|
title.classList.add("col");
|
||||||
|
title.textContent = section.title ? section.title : "";
|
||||||
|
title_row.appendChild(title);
|
||||||
|
section.insertBefore(title_row, section.firstChild);
|
||||||
|
|
||||||
|
let toggle_char = document.createElement("div");
|
||||||
|
toggle_char.classList.add("col-auto", "arrow");
|
||||||
|
toggle_char.textContent = "V";
|
||||||
|
title_row.appendChild(toggle_char);
|
||||||
|
title_row.addEventListener("click", (event) =>
|
||||||
|
{
|
||||||
|
toggleSection(section);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
for (const child of section.children) {
|
||||||
|
if (!child.classList.contains("section-title")) {
|
||||||
|
child.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Toggles section content as well as up and down arrow
|
||||||
|
@params:
|
||||||
|
*/
|
||||||
|
function toggleSection(section) {
|
||||||
|
//has down arrow (default state)
|
||||||
|
let down = section.classList.contains("down");
|
||||||
|
let arrow_elem = section.getElementsByClassName("arrow")[0];
|
||||||
|
|
||||||
|
if (down) {
|
||||||
|
section.classList.remove("down");
|
||||||
|
section.classList.add("up");
|
||||||
|
arrow_elem.style.transform = 'rotate(180deg)';
|
||||||
|
|
||||||
|
for (const elem of section.children) {
|
||||||
|
if (!elem.classList.contains("section-title")) {
|
||||||
|
elem.style.display = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
section.classList.remove("up");
|
||||||
|
section.classList.add("down");
|
||||||
|
arrow_elem.style.transform = 'rotate(0deg)';
|
||||||
|
for (const elem of section.children) {
|
||||||
|
if (!elem.classList.contains("section-title")) {
|
||||||
|
elem.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
init_dev();
|
|
@ -123,7 +123,6 @@ function parsePowdering(powder_info) {
|
||||||
for (let i = 0; i < 5; ++i) {
|
for (let i = 0; i < 5; ++i) {
|
||||||
let powders = "";
|
let powders = "";
|
||||||
let n_blocks = Base64.toInt(powder_info.charAt(0));
|
let n_blocks = Base64.toInt(powder_info.charAt(0));
|
||||||
// console.log(n_blocks + " blocks");
|
|
||||||
powder_info = powder_info.slice(1);
|
powder_info = powder_info.slice(1);
|
||||||
for (let j = 0; j < n_blocks; ++j) {
|
for (let j = 0; j < n_blocks; ++j) {
|
||||||
let block = powder_info.slice(0,5);
|
let block = powder_info.slice(0,5);
|
||||||
|
|
|
@ -29,6 +29,7 @@ const changelog = new Map([
|
||||||
//[title ,[genre, filename, author(s), abstract/desc]]
|
//[title ,[genre, filename, author(s), abstract/desc]]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
const sections = ["Changelog", "Mechanics", "History" ]
|
const sections = ["Changelog", "Mechanics", "History" ]
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
@ -127,7 +128,7 @@ function initSections() {
|
||||||
div.id = sec;
|
div.id = sec;
|
||||||
|
|
||||||
let secspan = document.createElement("span");
|
let secspan = document.createElement("span");
|
||||||
secspan.classList.add("row", "up");
|
secspan.classList.add("row", "up", "clickable");
|
||||||
div.appendChild(secspan);
|
div.appendChild(secspan);
|
||||||
let title = document.createElement("div");
|
let title = document.createElement("div");
|
||||||
title.classList.add("col-10", "item-title", "text-start")
|
title.classList.add("col-10", "item-title", "text-start")
|
||||||
|
|
Loading…
Reference in a new issue