Merge branch 'atree'

This commit is contained in:
hppeng 2022-07-30 23:05:19 -07:00
commit d4e574a69f
23 changed files with 552 additions and 554 deletions

File diff suppressed because one or more lines are too long

View file

@ -36,18 +36,26 @@
<hr/> <hr/>
<a href = "https://discord.gg/CGavnAnerv" target = "_blank"><img src = "../media/icons/discord.png" alt = "WB Discord" title = "WB Discord"><b>WB Discord</b></a> <a href = "https://discord.gg/CGavnAnerv" target = "_blank"><img src = "../media/icons/discord.png" alt = "WB Discord" title = "WB Discord"><b>WB Discord</b></a>
</div> </div>
<div class="container-fluid me-4" style="max-width: 95%;"> <div class="container-fluid overall-box">
<!-- REMOVE THIS DIV AT SOME POINT. --> <!-- REMOVE THIS DIV AT SOME POINT. -->
<div class = "row scaled-font mx-auto" id = "discord-banner-dev"> <div class = "row scaled-font mx-auto" id = "discord-banner-dev">
<div class = "col text-center item-title">Join the <a class = "link" href = "https://discord.gg/CGavnAnerv" target = "_blank">discord</a> today to suggest new features, submit bug reports, and hangout/talk to devs!</div> <div class = "col text-center item-title">Join the <a class = "link" href = "https://discord.gg/CGavnAnerv" target = "_blank">discord</a> today to suggest new features, submit bug reports, and hangout/talk to devs!</div>
</div> </div>
<div class="row h-100 gx-lg-5 gy-3 mx-2 mx-lg-3 py-3"> <div class="row h-100 gx-lg-5 gy-3 mx-2 mx-lg-3 py-3 gx-0">
<div class="col-xl-6"> <div class="col-xl-6">
<div class="row row-cols-1 mb-3 gy-4"> <div class="row my-2 dark-6 rounded text-center g-0 px-3 d-flex d-lg-none">
<div class="col"> <div class="col">
<div class="row row-cols-1 row-cols-xl-2 rounded gy-4 gx-5 justify-content-center"> <p class="fake-button scaled-font mb-0 selected-btn" id="equipment-inputs-btn" onclick="show_tab('equipment-inputs', ['equipment-inputs', 'adjust-id'])">Equipments</p>
<div class="col-auto rounded order-xl-0 order-0"> </div>
<div class="row h-100 dark-shadow dark-6 rounded" id="helmet-dropdown"> <div class="col">
<p class="fake-button scaled-font mb-0" id="adjust-id-btn" onclick="show_tab('adjust-id', ['equipment-inputs', 'adjust-id'])">Ability Tree</p>
</div>
</div>
<div class="row row-cols-1 mb-3 gy-4" id="equipment-inputs">
<div class="col">
<div class="row row-cols-1 row-cols-xl-2 dark-shadow dark-6 justify-content-center equipment-input rounded gy-3 gy-lg-0 mt-auto">
<div class="col-auto rounded order-xl-0 order-0 my-0">
<div class="row h-100 px-1" id="helmet-dropdown">
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="helmet-img-loc"> <div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="helmet-img-loc">
<div id="helmet-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 45.45454545454546% 0;"></div> <div id="helmet-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 45.45454545454546% 0;"></div>
</div> </div>
@ -73,8 +81,8 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-auto order-xl-0 order-1"> <div class="col-auto order-xl-0 order-1 my-0">
<div class="row h-100 dark-shadow dark-6 rounded" id="ring1-dropdown"> <div class="row h-100 px-1" id="ring1-dropdown">
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="ring1-img-loc"> <div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="ring1-img-loc">
<div id="ring1-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 81.81818181818181% 0;"></div> <div id="ring1-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 81.81818181818181% 0;"></div>
</div> </div>
@ -94,14 +102,13 @@
<input class="equipment-input text-light form-control" id="ring1-choice" name="ring1-choice" placeholder="No ring" value="" tabindex="2"/> <input class="equipment-input text-light form-control" id="ring1-choice" name="ring1-choice" placeholder="No ring" value="" tabindex="2"/>
</div> </div>
<div class="col d-flex justify-content-end" style="height: 100%;"> <div class="col d-flex justify-content-end" style="height: 100%;">
<!-- <input class="equipment-input text-light form-control" type="text" id="ring1-powder" name="ring1-powder" placeholder="no powders" tabindex="2"/> -->
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-auto order-xl-0 order-0"> <div class="col-auto order-xl-0 order-0">
<div class="row h-100 dark-shadow dark-6 rounded" id="chestplate-dropdown"> <div class="row h-100 px-1" id="chestplate-dropdown">
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="chestplate-img-loc"> <div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="chestplate-img-loc">
<div id="chestplate-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 54.54545454545454% 0;"></div> <div id="chestplate-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 54.54545454545454% 0;"></div>
</div> </div>
@ -128,7 +135,7 @@
</div> </div>
</div> </div>
<div class="col-auto order-xl-0 order-1"> <div class="col-auto order-xl-0 order-1">
<div class="row h-100 dark-shadow dark-6 rounded" id="ring2-dropdown"> <div class="row h-100 px-1" id="ring2-dropdown">
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="ring2-img-loc"> <div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="ring2-img-loc">
<div id="ring2-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 81.81818181818181% 0;"></div> <div id="ring2-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 81.81818181818181% 0;"></div>
</div> </div>
@ -154,7 +161,7 @@
</div> </div>
</div> </div>
<div class="col-auto order-xl-0 order-0"> <div class="col-auto order-xl-0 order-0">
<div class="row h-100 dark-shadow dark-6 rounded" id="leggings-dropdown"> <div class="row h-100 px-1" id="leggings-dropdown">
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="leggings-img-loc"> <div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="leggings-img-loc">
<div id="leggings-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 63.63636363636363% 0;"></div> <div id="leggings-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 63.63636363636363% 0;"></div>
</div> </div>
@ -181,7 +188,7 @@
</div> </div>
</div> </div>
<div class="col-auto order-xl-0 order-1"> <div class="col-auto order-xl-0 order-1">
<div class="row h-100 dark-shadow dark-6 rounded" id="bracelet-dropdown"> <div class="row h-100 px-1" id="bracelet-dropdown">
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="bracelet-img-loc"> <div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="bracelet-img-loc">
<div id="bracelet-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 90.90909090909092% 0;"></div> <div id="bracelet-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 90.90909090909092% 0;"></div>
</div> </div>
@ -208,7 +215,7 @@
</div> </div>
</div> </div>
<div class="col-auto order-xl-0 order-0"> <div class="col-auto order-xl-0 order-0">
<div class="row h-100 dark-shadow dark-6 rounded" id="boots-dropdown"> <div class="row h-100 px-1" id="boots-dropdown">
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="boots-img-loc"> <div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="boots-img-loc">
<div id="boots-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 72.72727272727272% 0;"></div> <div id="boots-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 72.72727272727272% 0;"></div>
</div> </div>
@ -235,7 +242,7 @@
</div> </div>
</div> </div>
<div class="col-auto order-xl-0 order-1"> <div class="col-auto order-xl-0 order-1">
<div class="row h-100 dark-shadow dark-6 rounded" id="necklace-dropdown"> <div class="row h-100 px-1" id="necklace-dropdown">
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="necklace-img-loc"> <div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="necklace-img-loc">
<div id="necklace-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 100% 0;"></div> <div id="necklace-img" class="img-fluid rounded item-display-new-toggleable" style="background-image: url('../media/items/new.png'); background-position: 100% 0;"></div>
</div> </div>
@ -261,10 +268,10 @@
</div> </div>
</div> </div>
<div class="col-auto order-xl-0 order-1"> <div class="col-auto order-xl-0 order-1">
<div class="row h-100 dark-shadow dark-6 rounded" id='weapon-dropdown'> <div class="row h-auto px-1" id='weapon-dropdown'>
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="weapon-img-loc"> <div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="weapon-img-loc">
<div id="weapon-img" class="img-fluid rounded item-display-new-toggleable"></div> <div id="weapon-img" class="img-fluid rounded item-display-new-toggleable" style = "background-image: url('../media/items/new.png');"></div>
background-image: url('../media/items/new.png'); </div> </div>
<div class="col-3"> <div class="col-3">
<div class="row row-cols-1 h-100 align-items-center"> <div class="row row-cols-1 h-100 align-items-center">
<div class="col text-nowrap scaled-font fw-bold gx-3 Damage base_dps" id="weapon-dps"> <div class="col text-nowrap scaled-font fw-bold gx-3 Damage base_dps" id="weapon-dps">
@ -287,29 +294,25 @@ background-image: url('../media/items/new.png');
</div> </div>
</div> </div>
</div> </div>
<div class="col-auto order-xl-0 order-1"> <div class="col-auto order-xl-0 order-1 level-input">
<div class="row h-100 dark-shadow dark-6 rounded"> <div class="row h-100 px-1">
<div class="col"> <div class="col">
<div class="row align-items-center"> <div class="row align-items-center justify-content-left">
<div class="col-3 text-nowrap fw-bold scaled-font"> <div class="col-auto text-nowrap fw-bold scaled-font">
Level: Level:
</div> </div>
<div class="col d-flex justify-content-end"> <div class="col d-flex px-1">
<input class="equipment-input text-light form-control form-control-sm" id="level-choice" name="level-choice" value="106" placeholder="Build level" value="" tabindex="2"/> <input class="equipment-input text-light form-control form-control-sm" id="level-choice" name="level-choice" value="106" placeholder="Build level" value="" tabindex="2"/>
</div> </div>
<div class="col-auto px-1 text-nowrap scaled-font"> <div class="col-auto px-1 scaled-font">
<button class="button fw-bold text-light dark-5 scaled-font rounded" id="reset-button" onclick="resetFields()">Reset</button> <button class="button py-0 fw-bold text-light dark-5 scaled-font rounded" id="reset-button" onclick="resetFields()">Reset</button>
</div> </div>
</div> </div>
<div class="row align-items-center justify-content-center my-1"> <div class="row align-items-left justify-content-left my-1">
<div class="row align-items-center"> <button class="col-auto mx-1 px-1 py-0 border-info text-light dark-5 scaled-font rounded fake-button"
<div class="col-auto px-1 text-nowrap scaled-font"> id=copy-button onclick="copyBuild()">Copy short</button>
<button class="border-dark text-light dark-5 scaled-font rounded" id=copy-button onclick="copyBuild()">Copy short</button> <button class="col-auto mx-1 px-1 py-0 border-info text-light dark-5 scaled-font rounded fake-button"
</div> id=share-button onclick="shareBuild(player_build)">Copy for sharing</button>
<div class="col-auto px-1 text-nowrap scaled-font">
<button class="border-dark text-light dark-5 scaled-font rounded" id=share-button onclick="shareBuild(player_build)">Copy for sharing</button>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -390,12 +393,9 @@ background-image: url('../media/items/new.png');
</div> </div>
</div> </div>
</div> </div>
<div class="col-12 text-center gx-2">
<button class = "button fw-bold text-light dark-5 rounded scaled-font" id = "optimize-strdex" onclick = "optimizeStrDex()">Optimize Str/Dex</button>
</div>
</div> </div>
</div> </div>
<div class="col text-center"> <div class="col text-center py-1">
<div id="summary-box"></div> <div id="summary-box"></div>
<div id="err-box"></div> <div id="err-box"></div>
<div id="stack-box"></div> <div id="stack-box"></div>
@ -407,188 +407,187 @@ background-image: url('../media/items/new.png');
</div> </div>
</div> </div>
</div> </div>
<div class="col mb-1 text-center scaled-font dark-5 rounded dark-shadow">
<div class="row row-cols-1 justify-content-center">
<div class="col fw-bold dark-4 rounded-top">
Active boosts
</div>
<div class="col">
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="warscream-boost" onclick="update_boosts('warscream-boost')">
War Scream
</button>
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="ragnarokkr-boost" onclick="update_boosts('ragnarokkr-boost')">
Ragnarokkr (+30%)
</button>
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="yourtotem-boost" onclick="update_boosts('yourtotem-boost')">
Your Totem (+35%)
</button>
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="allytotem-boost" onclick="update_boosts('allytotem-boost')">
Ally Totem (+15%)
</button>
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="fortitude-boost" onclick="update_boosts('fortitude-boost')">
Fortitude (+60%)
</button>
</div>
<div class="col" id="boost-toggles">
</div>
</div>
<div class="row row-cols-1 justify-content-center" id="boost-sliders">
</div>
</div>
<div class="col mb-1">
<div class="row row-cols-1 rounded text-center dark-5 scaled-font">
<div class="row p-0 m-0 text-nowrap">
<div id = "str-boost-btn" class="col eDam dark-4u fake-button elem-boost" onclick="show_tab('str-boost', ['str-boost', 'dex-boost', 'int-boost', 'def-boost', 'agi-boost'])">
Earth
</div>
<div id = "dex-boost-btn" class="col tDam dark-4u fake-button elem-boost" onclick="show_tab('dex-boost', ['str-boost', 'dex-boost', 'int-boost', 'def-boost', 'agi-boost'])">
Thunder
</div>
<div id = "int-boost-btn" class="col wDam dark-4u fake-button elem-boost" onclick="show_tab('int-boost', ['str-boost', 'dex-boost', 'int-boost', 'def-boost', 'agi-boost'])">
Water
</div>
<div id = "def-boost-btn" class="col fDam dark-4u fake-button elem-boost" onclick="show_tab('def-boost', ['str-boost', 'dex-boost', 'int-boost', 'def-boost', 'agi-boost'])">
Fire
</div>
<div id = "agi-boost-btn" class="col aDam dark-4u fake-button elem-boost" onclick="show_tab('agi-boost', ['str-boost', 'dex-boost', 'int-boost', 'def-boost', 'agi-boost'])">
Air
</div>
</div>
<div class="row row-cols-1 p-0 m-0" id="str-boost" style="display: none;">
<div class="col eDam dark-5">
Quake (Active)
</div>
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1" >
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-1" onclick = "updatePowderSpecials('Quake-1')">
Lv.4 [e4e4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-2" onclick = "updatePowderSpecials('Quake-2')">
Lv.4.5 [e5e4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-3" onclick = "updatePowderSpecials('Quake-3')">
Lv.5 [e5e5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-4" onclick = "updatePowderSpecials('Quake-4')">
Lv.5.5 [e6e5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-5" onclick = "updatePowderSpecials('Quake-5')">
Lv.6 [e6e6]
</button>
</div>
<div class="col eDam">
Rage (Passive)
</div>
</div>
<div class="row row-cols-1 p-0 m-0" id="dex-boost" style="display: none;">
<div class="col tDam dark-5">
Chain Lightning (Active)
</div>
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-1" onclick = "updatePowderSpecials('Chain_Lightning-1')">
Lv.4 [t4t4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-2" onclick = "updatePowderSpecials('Chain_Lightning-2')">
Lv.4.5 [t5t4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-3" onclick = "updatePowderSpecials('Chain_Lightning-3')">
Lv.5 [t5t5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-4" onclick = "updatePowderSpecials('Chain_Lightning-4')">
Lv.5.5 [t6t5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-5" onclick = "updatePowderSpecials('Chain_Lightning-5')">
Lv.6 [t6t6]
</button>
</div>
<div class="col tDam">
Kill Streak (Passive)
</div>
</div>
<div class="row row-cols-1 p-0 m-0" id="int-boost">
<div class="col wDam dark-5">
Curse (Active)
</div>
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-1" onclick = "updatePowderSpecials('Curse-1')">
Lv.4 [w4w4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-2" onclick = "updatePowderSpecials('Curse-2')">
Lv.4.5 [w5w4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-3" onclick = "updatePowderSpecials('Curse-3')">
Lv.5 [w5w5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-4" onclick = "updatePowderSpecials('Curse-4')">
Lv.5.5 [w6w5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-5" onclick = "updatePowderSpecials('Curse-5')">
Lv.6 [w6w6]
</button>
</div>
<div class="col wDam">
Concentration (Passive)
</div>
</div>
<div class="row row-cols-1 p-0 m-0" id="def-boost" style="display: none;">
<div class="col fDam dark-5">
Courage (Active)
</div>
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-1" onclick = "updatePowderSpecials('Courage-1')">
Lv.4 [f4f4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-2" onclick = "updatePowderSpecials('Courage-2')">
Lv.4.5 [f5f4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-3" onclick = "updatePowderSpecials('Courage-3')">
Lv.5 [f5f5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-4" onclick = "updatePowderSpecials('Courage-4')">
Lv.5.5 [f6f5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-5" onclick = "updatePowderSpecials('Courage-5')">
Lv.6 [f6f6]
</button>
</div>
<div class="col fDam">
Endurance (Passive)
</div>
</div>
<div class="row row-cols-1 p-0 m-0" id="agi-boost" style="display: none;">
<div class="col aDam dark-5">
Wind Prison (Active)
</div>
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-1" onclick = "updatePowderSpecials('Wind_Prison-1')">
Lv.4 [a4a4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-2" onclick = "updatePowderSpecials('Wind_Prison-2')">
Lv.4.5 [a5a4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-3" onclick = "updatePowderSpecials('Wind_Prison-3')">
Lv.5 [a5a5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-4" onclick = "updatePowderSpecials('Wind_Prison-4')">
Lv.5.5 [a6a5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-5" onclick = "updatePowderSpecials('Wind_Prison-5')">
Lv.6 [a6a6]
</button>
</div>
<div class="col aDam">
Dodge (Passive)
</div>
</div>
</div>
</div>
</div>
<div class="row row-cols-1 d-lg-flex" id="adjust-id" style="display: none;">
<div class="col"> <div class="col">
<div class="row row-cols-1 gy-4"> <div class="row row-cols-1 gy-3">
<div class="col mb-1 text-center scaled-font dark-5 rounded dark-shadow">
<div class="row row-cols-1 justify-content-center">
<div class="col fw-bold dark-4 rounded-top">
Active boosts
</div>
<div class="col">
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="vanish-boost" onclick="update_boosts('vanish-boost')">
Vanish (+80%)
</button>
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="warscream-boost" onclick="update_boosts('warscream-boost')">
War Scream
</button>
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="ragnarokkr-boost" onclick="update_boosts('ragnarokkr-boost')">
Ragnarokkr (+30%)
</button>
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="yourtotem-boost" onclick="update_boosts('yourtotem-boost')">
Your Totem (+35%)
</button>
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="allytotem-boost" onclick="update_boosts('allytotem-boost')">
Ally Totem (+15%)
</button>
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="fortitude-boost" onclick="update_boosts('fortitude-boost')">
Fortitude (+60%)
</button>
</div>
<div class="col" id="boost-toggles">
</div>
</div>
<div class="row row-cols-1 justify-content-center" id="boost-sliders">
</div>
</div>
<div class="col mb-1">
<div class="row row-cols-1 rounded text-center dark-5 scaled-font">
<div class="row p-0 m-0 text-nowrap">
<div id = "str-boost-tab" class="col eDam dark-4u fake-button elem-boost" onclick="toggle_boost_tab('str')">
Earth
</div>
<div id = "dex-boost-tab" class="col tDam dark-4u fake-button elem-boost" onclick="toggle_boost_tab('dex')">
Thunder
</div>
<div id = "int-boost-tab" class="col wDam dark-4u fake-button elem-boost" onclick="toggle_boost_tab('int')">
Water
</div>
<div id = "def-boost-tab" class="col fDam dark-4u fake-button elem-boost" onclick="toggle_boost_tab('def')">
Fire
</div>
<div id = "agi-boost-tab" class="col aDam dark-4u fake-button elem-boost" onclick="toggle_boost_tab('agi')">
Air
</div>
</div>
<div class="row row-cols-1 p-0 m-0" id="str-boost" style="display: none;">
<div class="col eDam dark-5">
Quake (Active)
</div>
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1" >
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-1" onclick = "updatePowderSpecials('Quake-1')">
Lv.4 [e4e4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-2" onclick = "updatePowderSpecials('Quake-2')">
Lv.4.5 [e5e4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-3" onclick = "updatePowderSpecials('Quake-3')">
Lv.5 [e5e5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-4" onclick = "updatePowderSpecials('Quake-4')">
Lv.5.5 [e6e5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-5" onclick = "updatePowderSpecials('Quake-5')">
Lv.6 [e6e6]
</button>
</div>
<div class="col eDam">
Rage (Passive)
</div>
</div>
<div class="row row-cols-1 p-0 m-0" id="dex-boost" style="display: none;">
<div class="col tDam dark-5">
Chain Lightning (Active)
</div>
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-1" onclick = "updatePowderSpecials('Chain_Lightning-1')">
Lv.4 [t4t4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-2" onclick = "updatePowderSpecials('Chain_Lightning-2')">
Lv.4.5 [t5t4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-3" onclick = "updatePowderSpecials('Chain_Lightning-3')">
Lv.5 [t5t5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-4" onclick = "updatePowderSpecials('Chain_Lightning-4')">
Lv.5.5 [t6t5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-5" onclick = "updatePowderSpecials('Chain_Lightning-5')">
Lv.6 [t6t6]
</button>
</div>
<div class="col tDam">
Kill Streak (Passive)
</div>
</div>
<div class="row row-cols-1 p-0 m-0" id="int-boost">
<div class="col wDam dark-5">
Curse (Active)
</div>
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-1" onclick = "updatePowderSpecials('Curse-1')">
Lv.4 [w4w4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-2" onclick = "updatePowderSpecials('Curse-2')">
Lv.4.5 [w5w4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-3" onclick = "updatePowderSpecials('Curse-3')">
Lv.5 [w5w5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-4" onclick = "updatePowderSpecials('Curse-4')">
Lv.5.5 [w6w5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-5" onclick = "updatePowderSpecials('Curse-5')">
Lv.6 [w6w6]
</button>
</div>
<div class="col wDam">
Concentration (Passive)
</div>
</div>
<div class="row row-cols-1 p-0 m-0" id="def-boost" style="display: none;">
<div class="col fDam dark-5">
Courage (Active)
</div>
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-1" onclick = "updatePowderSpecials('Courage-1')">
Lv.4 [f4f4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-2" onclick = "updatePowderSpecials('Courage-2')">
Lv.4.5 [f5f4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-3" onclick = "updatePowderSpecials('Courage-3')">
Lv.5 [f5f5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-4" onclick = "updatePowderSpecials('Courage-4')">
Lv.5.5 [f6f5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-5" onclick = "updatePowderSpecials('Courage-5')">
Lv.6 [f6f6]
</button>
</div>
<div class="col fDam">
Endurance (Passive)
</div>
</div>
<div class="row row-cols-1 p-0 m-0" id="agi-boost" style="display: none;">
<div class="col aDam dark-5">
Wind Prison (Active)
</div>
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-1" onclick = "updatePowderSpecials('Wind_Prison-1')">
Lv.4 [a4a4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-2" onclick = "updatePowderSpecials('Wind_Prison-2')">
Lv.4.5 [a5a4]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-3" onclick = "updatePowderSpecials('Wind_Prison-3')">
Lv.5 [a5a5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-4" onclick = "updatePowderSpecials('Wind_Prison-4')">
Lv.5.5 [a6a5]
</button>
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-5" onclick = "updatePowderSpecials('Wind_Prison-5')">
Lv.6 [a6a6]
</button>
</div>
<div class="col aDam">
Dodge (Passive)
</div>
</div>
</div>
</div>
<div class="col mb-1"> <div class="col mb-1">
<div class="row row-cols-1 row-cols-1 text-center scaled-font dark-5 rounded dark-shadow"> <div class="row row-cols-1 row-cols-1 text-center scaled-font dark-5 rounded dark-shadow">
<div class="col fw-bold dark-4 rounded-top"> <div class="col fw-bold dark-4 rounded-top">
@ -789,7 +788,7 @@ background-image: url('../media/items/new.png');
</div> </div>
<div class = "col dark-6 rounded-bottom my-3 my-xl-1" id = "atree-dropdown" style = "display:none;"> <div class = "col dark-6 rounded-bottom my-3 my-xl-1" id = "atree-dropdown" style = "display:none;">
<div class="row row-cols-1 row-cols-xl-2"> <div class="row row-cols-1 row-cols-xl-2">
<div class="col border border-semi-light rounded dark-9 hide-scroll" id="atree-ui" style="height: 90vh; overflow-y: auto; overflow-x: hidden;"> <div class="col border border-semi-light rounded dark-9 hide-scroll" id="atree-ui" style="height: 90vh; overflow-y: auto;">
</div> </div>
<div class="col mx-auto" style="height: 90vh; overflow-y: auto;" id="atree-rhs"> <div class="col mx-auto" style="height: 90vh; overflow-y: auto;" id="atree-rhs">
@ -1131,24 +1130,20 @@ background-image: url('../media/items/new.png');
</div> </div>
</div> </div>
</div> </div>
<div class="col-xl-3 mb-3"> <div class="col-xl-3 mb-3 order-2 order-lg-0">
<div class="row row-cols-1 rounded dark-shadow dark-6 scaled-font"> <div class="row row-cols-1 rounded dark-shadow dark-6 scaled-font">
<div class="col rounded-top"> <div class="col rounded-top">
<div class="row"> <div class="row">
<div id="tab-offensive-btn" class="col-4 text-center fake-button border-bottom border-dark rounded-top dark-4u border border-2 border-dark-7" onclick="show_tab('offensive-stats')"> <div id="detailed-stats-btn" class="col text-center fake-button border-bottom border-dark rounded-top dark-4u border border-2 border-dark-7" onclick="show_tab('detailed-stats', ['detailed-stats', 'summary-stats'])">
Offense Detailed
</div> </div>
<div id="tab-defensive-btn" class="col-4 text-center fake-button border-bottom border-dark rounded-top dark-4u border border-2 border-dark-7" onclick="show_tab('defensive-stats')"> <div id="summary-stats-btn" class="col text-center fake-button border-bottom border-dark rounded-top dark-4u border border-2 border-dark-7 selected-btn" onclick="show_tab('summary-stats', ['detailed-stats', 'summary-stats'])">
Defense Summary
</div>
<div id="tab-overall-btn" class="col-4 text-center fake-button border-bottom border-dark rounded-top dark-4u border border-2 border-dark-7 selected-btn" onclick="show_tab('overall-stats')">
Overall
</div> </div>
</div> </div>
</div> </div>
<div style="display: none;" id="offensive-stats" class="col text-nowrap"></div> <div style="display: none;" id="detailed-stats" class="col text-nowrap"></div>
<div style="display: none;" id="defensive-stats" class="col text-nowrap"></div> <div id="summary-stats" class="col text-nowrap"></div>
<div id="overall-stats" class="col text-nowrap"></div>
</div> </div>
</div> </div>
<div class="col-xl-3 mb-3 px-0"> <div class="col-xl-3 mb-3 px-0">

View file

@ -40164,32 +40164,6 @@
"mr": 5, "mr": 5,
"id": 1848 "id": 1848
}, },
{
"name": "Air Relic Dagger",
"displayName": "Air Relic Daggers",
"tier": "Rare",
"type": "dagger",
"category": "weapon",
"slots": 3,
"drop": "never",
"nDam": "39-66",
"fDam": "0-0",
"wDam": "0-0",
"aDam": "39-66",
"tDam": "0-0",
"eDam": "0-0",
"atkSpd": "VERY_FAST",
"lvl": 65,
"agiReq": 30,
"xpb": 15,
"lb": 15,
"agi": 7,
"spd": 20,
"sdRaw": 85,
"aDamPct": 15,
"aDefPct": 15,
"id": 1846
},
{ {
"name": "Air Relic Relik", "name": "Air Relic Relik",
"tier": "Rare", "tier": "Rare",
@ -40858,32 +40832,6 @@
"tDamPct": 5, "tDamPct": 5,
"id": 1877 "id": 1877
}, },
{
"name": "Earth Relic Dagger",
"displayName": "Earth Relic Daggers",
"tier": "Rare",
"type": "dagger",
"category": "weapon",
"slots": 3,
"drop": "never",
"nDam": "85-110",
"fDam": "0-0",
"wDam": "0-0",
"aDam": "0-0",
"tDam": "0-0",
"eDam": "85-110",
"atkSpd": "NORMAL",
"lvl": 65,
"strReq": 30,
"mdPct": 15,
"xpb": 15,
"lb": 15,
"str": 7,
"expd": 15,
"eDamPct": 20,
"eDefPct": 10,
"id": 1880
},
{ {
"name": "Dull Ancient Helmet", "name": "Dull Ancient Helmet",
"tier": "Normal", "tier": "Normal",
@ -40978,32 +40926,6 @@
"fDefPct": 20, "fDefPct": 20,
"id": 1889 "id": 1889
}, },
{
"name": "Fire Relic Dagger",
"displayName": "Fire Relic Daggers",
"tier": "Rare",
"type": "dagger",
"category": "weapon",
"slots": 3,
"drop": "never",
"nDam": "55-70",
"fDam": "55-70",
"wDam": "0-0",
"aDam": "0-0",
"tDam": "0-0",
"eDam": "0-0",
"atkSpd": "FAST",
"lvl": 65,
"defReq": 30,
"xpb": 15,
"lb": 15,
"def": 7,
"hpBonus": 920,
"hprRaw": 80,
"fDamPct": 10,
"fDefPct": 20,
"id": 1887
},
{ {
"name": "Factory Helmet", "name": "Factory Helmet",
"tier": "Unique", "tier": "Unique",
@ -42560,32 +42482,6 @@
"tDamPct": 6, "tDamPct": 6,
"id": 1971 "id": 1971
}, },
{
"name": "Thunder Relic Dagger",
"displayName": "Thunder Relic Daggers",
"tier": "Rare",
"type": "dagger",
"category": "weapon",
"slots": 3,
"drop": "never",
"nDam": "22-99",
"fDam": "0-0",
"wDam": "0-0",
"aDam": "0-0",
"tDam": "22-99",
"eDam": "0-0",
"atkSpd": "VERY_FAST",
"lvl": 65,
"dexReq": 30,
"ms": 5,
"xpb": 15,
"lb": 15,
"dex": 7,
"mdRaw": 70,
"tDamPct": 20,
"tDefPct": 10,
"id": 1972
},
{ {
"name": "Thunder Relic Relik", "name": "Thunder Relic Relik",
"tier": "Rare", "tier": "Rare",
@ -42740,32 +42636,6 @@
"lvl": 75, "lvl": 75,
"id": 1978 "id": 1978
}, },
{
"name": "Water Relic Dagger",
"displayName": "Water Relic Daggers",
"tier": "Rare",
"type": "dagger",
"category": "weapon",
"slots": 3,
"drop": "never",
"nDam": "55-65",
"fDam": "0-0",
"wDam": "55-65",
"aDam": "0-0",
"tDam": "0-0",
"eDam": "0-0",
"atkSpd": "FAST",
"lvl": 65,
"intReq": 30,
"mr": 5,
"sdPct": 20,
"xpb": 15,
"lb": 15,
"int": 7,
"wDamPct": 10,
"wDefPct": 20,
"id": 1977
},
{ {
"name": "Water Relic Relik", "name": "Water Relic Relik",
"tier": "Rare", "tier": "Rare",

File diff suppressed because one or more lines are too long

View file

@ -39,7 +39,7 @@
<div class="col" id="recipe-dropdown"> <div class="col" id="recipe-dropdown">
<div class="row dark-shadow dark-5 rounded"> <div class="row dark-shadow dark-5 rounded">
<div id = "recipe-img-loc" class = "col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon"> <div id = "recipe-img-loc" class = "col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon">
<div id = "recipe-img" class = "img-fluid rounded Crafted-shadow" style = "background-image: url('../media/items/common.png'); image-rendering: pixelated; background-position: 25% 0; aspect-ratio: 1/1;"></div> <div id = "recipe-img" class = "img-fluid rounded Crafted-shadow" style = "background-image: url('../media/items/common.png'); background-size: 500% 100%; image-rendering: pixelated; background-position: 25% 0; aspect-ratio: 1/1;"></div>
</div> </div>
<div class = "col ps-3"> <div class = "col ps-3">
<div class = "row row-cols-2 align-items-center"> <div class = "row row-cols-2 align-items-center">

View file

@ -7,7 +7,6 @@
} }
/* builder containers */ /* builder containers */
.slider { .slider {
-webkit-appearance: none; -webkit-appearance: none;
background: #AAAAAA; background: #AAAAAA;
@ -46,7 +45,6 @@ input[type=range]:focus {
outline: none; /* Removes the border. */ outline: none; /* Removes the border. */
} }
/* equipment field specifics */ /* equipment field specifics */
/* inputs and dropdowns */ /* inputs and dropdowns */
.form-control { .form-control {
@ -63,6 +61,7 @@ ul.search-box {
position: absolute; position: absolute;
padding: 0; padding: 0;
overflow: auto; overflow: auto;
z-index: 10;
} }
li.search-item { li.search-item {
@ -105,6 +104,8 @@ input.equipment-input {
min-height: calc(1.2 * var(--scaled-fontsize) + 2px); min-height: calc(1.2 * var(--scaled-fontsize) + 2px);
padding: 0rem 0.5rem; padding: 0rem 0.5rem;
font-size: var(--scaled-fontsize); font-size: var(--scaled-fontsize);
--bs-gutter-y: 1rem;
--bs-gutter-x: 3rem
} }
input.equipment-input:not(.is-invalid) { input.equipment-input:not(.is-invalid) {
@ -177,11 +178,11 @@ input.equipment-input:not(.is-invalid) {
} }
.scaled-item-icon { .scaled-item-icon {
width: 8rem; width: 6rem;
} }
.scaled-item-icon img { .scaled-item-icon img {
width: 6.5rem; width: 6rem;
} }
.scaled-bckgrd { .scaled-bckgrd {
@ -190,7 +191,11 @@ input.equipment-input:not(.is-invalid) {
} }
.scaled-bckgrd img { .scaled-bckgrd img {
width: 6.5rem; width: 7rem;
}
.overall-box {
max-width: 95%;
} }
@media screen and (orientation: landscape) and (max-width: 1199px) { @media screen and (orientation: landscape) and (max-width: 1199px) {
@ -251,6 +256,17 @@ input.equipment-input:not(.is-invalid) {
:root { :root {
--scaled-fontsize: 1rem; --scaled-fontsize: 1rem;
} }
.overall-box {
padding-left: var(--sidebar-width);
max-width: 100%;
}
.equipment-input {
--bs-gutter-y: 0.5rem;
--bs-gutter-x: 1.5rem;
}
.level-input {
margin-top: 0
}
.scaled-font { .scaled-font {
font-size: 1rem; font-size: 1rem;
} }
@ -276,11 +292,11 @@ input.equipment-input:not(.is-invalid) {
} }
.scaled-item-icon { .scaled-item-icon {
width: 3.2rem; width: 2.6rem;
} }
.scaled-item-icon img { .scaled-item-icon img {
width: 2.8rem; width: 2.2rem;
} }
.scaled-bckgrd { .scaled-bckgrd {
@ -305,6 +321,17 @@ input.equipment-input:not(.is-invalid) {
:root { :root {
--scaled-fontsize: 1rem; --scaled-fontsize: 1rem;
} }
.overall-box {
padding-left: var(--sidebar-width);
max-width: 100%;
}
.equipment-input {
--bs-gutter-y: 0.5rem;
--bs-gutter-x: 1.5rem
}
.level-input {
margin-top: 0
}
.scaled-font { .scaled-font {
font-size: 1rem; font-size: 1rem;
} }
@ -330,11 +357,11 @@ input.equipment-input:not(.is-invalid) {
} }
.scaled-item-icon { .scaled-item-icon {
width: 4rem; width: 3.2rem;
} }
.scaled-item-icon img { .scaled-item-icon img {
width: 3.5rem; width: 2.7rem;
} }
.scaled-bckgrd { .scaled-bckgrd {
@ -346,7 +373,6 @@ input.equipment-input:not(.is-invalid) {
width: 3.5rem; width: 3.5rem;
} }
.warning { .warning {
font-size: .8rem; font-size: .8rem;
} }

View file

@ -1,3 +1,8 @@
/**
* This file defines computation graph nodes and display code relevant to the ability tree.
* TODO: possibly split it up into compute and render... but its a bit complicated :/
*/
/** /**
ATreeNode spec: ATreeNode spec:
@ -74,6 +79,7 @@ stat_bonus: {
stat_scaling: { stat_scaling: {
"type": "stat_scaling", "type": "stat_scaling",
"slider": bool, "slider": bool,
positive: bool // True to keep stat above 0. False to ignore floor. Default: True for normal, False for scaling
"slider_name": Optional[str], "slider_name": Optional[str],
"slider_step": Optional[float], "slider_step": Optional[float],
round: Optional[bool] // Control floor behavior. True for stats and false for slider by default round: Optional[bool] // Control floor behavior. True for stats and false for slider by default
@ -371,11 +377,11 @@ const atree_validate = new (class extends ComputeNode {
const abil = node.ability; const abil = node.ability;
if (atree_state.get(abil.id).active) { if (atree_state.get(abil.id).active) {
atree_to_add.push([node, 'not reachable', false]); atree_to_add.push([node, 'not reachable', false]);
atree_state.get(abil.id).img.style.backgroundPosition = atlasBGPositionCalc([atreeNodeAtlasPositions[abil.display.icon], 2], atreeNodeAtlasSize); drawAtlasImage(atree_state.get(abil.id).img, atreeNodeAtlasImg, [atreeNodeAtlasPositions[abil.display.icon], 2], atreeNodeTileSize);
} }
else { else {
atree_not_present.push(abil.id); atree_not_present.push(abil.id);
atree_state.get(abil.id).img.style.backgroundPosition = atlasBGPositionCalc([atreeNodeAtlasPositions[abil.display.icon], 0], atreeNodeAtlasSize); drawAtlasImage(atree_state.get(abil.id).img, atreeNodeAtlasImg, [atreeNodeAtlasPositions[abil.display.icon], 0], atreeNodeTileSize);
} }
} }
@ -424,7 +430,7 @@ const atree_validate = new (class extends ComputeNode {
const node = atree_state.get(node_id); const node = atree_state.get(node_id);
const [success, hard_error, reason] = abil_can_activate(node, atree_state, reachable, archetype_count, ap_left); const [success, hard_error, reason] = abil_can_activate(node, atree_state, reachable, archetype_count, ap_left);
if (success) { if (success) {
node.img.style.backgroundPosition = atlasBGPositionCalc([atreeNodeAtlasPositions[node.ability.display.icon], 1], atreeNodeAtlasSize); drawAtlasImage(node.img, atreeNodeAtlasImg, [atreeNodeAtlasPositions[node.ability.display.icon], 1], atreeNodeTileSize);
} }
} }
@ -754,10 +760,13 @@ const atree_scaling = new (class extends ComputeNode {
continue; continue;
case 'stat_scaling': case 'stat_scaling':
let total = 0; let total = 0;
const {round = true, slider = false, scaling = [0]} = effect; const {slider = false, scaling = [0]} = effect;
let { positive = true, round = true } = effect;
if (slider) { if (slider) {
const slider_val = slider_map.get(effect.slider_name).slider.value; const slider_val = slider_map.get(effect.slider_name).slider.value;
total = parseInt(slider_val) * scaling[0]; total = parseInt(slider_val) * scaling[0];
round = false;
positive = false;
} }
else { else {
// TODO: type: prop? // TODO: type: prop?
@ -768,7 +777,7 @@ const atree_scaling = new (class extends ComputeNode {
if ('output' in effect) { // sometimes nodes will modify slider without having effect. if ('output' in effect) { // sometimes nodes will modify slider without having effect.
if (round) { total = Math.floor(round_near(total)); } if (round) { total = Math.floor(round_near(total)); }
if (total < 0) { total = 0; } // Normal stat scaling will not go negative. if (positive && total < 0) { total = 0; } // Normal stat scaling will not go negative.
if ('max' in effect && total > effect.max) { total = effect.max; } if ('max' in effect && total > effect.max) { total = effect.max; }
if (Array.isArray(effect.output)) { if (Array.isArray(effect.output)) {
for (const output of effect.output) { for (const output of effect.output) {
@ -975,8 +984,8 @@ function render_AT(UI_elem, list_elem, tree) {
let parent_abil = parent.ability; let parent_abil = parent.ability;
const parent_id = parent_abil.id; const parent_id = parent_abil.id;
let connect_elem = document.createElement("div"); let connect_elem = make_elem("canvas", [], {style: "width: 112.5%; height: 112.5%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); image-rendering: pixelated;", width: "18", height: "18"});
connect_elem.style = "width: 112.5%; height: 112.5%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); image-rendering: pixelated; background-image: url('../media/atree/connectors.png'); background-size: 1700% 500%;"
// connect up // connect up
for (let i = ability.display.row - 1; i > parent_abil.display.row; i--) { for (let i = ability.display.row - 1; i > parent_abil.display.row; i--) {
const coord = i + "," + ability.display.col; const coord = i + "," + ability.display.col;
@ -1012,7 +1021,7 @@ function render_AT(UI_elem, list_elem, tree) {
// create node // create node
let node_elem = document.getElementById("atree-row-" + ability.display.row).children[ability.display.col]; let node_elem = document.getElementById("atree-row-" + ability.display.row).children[ability.display.col];
node_wrap.img = make_elem("div", [], {style: "width: 200%; height: 200%; position: absolute; top: -50%; left: -50%; image-rendering: pixelated; z-index: 1; background-image: url('../media/atree/icons.png'); background-size: 900% 300%;"}) node_wrap.img = make_elem("canvas", [], {style: "width: 200%; height: 200%; position: absolute; top: -50%; left: -50%; image-rendering: pixelated; z-index: 1;", width: "32", height: "32"})
node_elem.appendChild(node_wrap.img); node_elem.appendChild(node_wrap.img);
// create hitbox // create hitbox
@ -1234,11 +1243,11 @@ function atree_set_state(node_wrapper, new_state) {
} }
if (new_state) { if (new_state) {
node_wrapper.active = true; node_wrapper.active = true;
node_wrapper.img.style.backgroundPosition = atlasBGPositionCalc([atreeNodeAtlasPositions[icon], 2], atreeNodeAtlasSize); drawAtlasImage(node_wrapper.img, atreeNodeAtlasImg, [atreeNodeAtlasPositions[icon], 2], atreeNodeTileSize);
} }
else { else {
node_wrapper.active = false; node_wrapper.active = false;
node_wrapper.img.style.backgroundPosition = atlasBGPositionCalc([atreeNodeAtlasPositions[icon], 1], atreeNodeAtlasSize); drawAtlasImage(node_wrapper.img, atreeNodeAtlasImg, [atreeNodeAtlasPositions[icon], 1], atreeNodeTileSize);
} }
let atree_connectors_map = node_wrapper.all_connectors_ref; let atree_connectors_map = node_wrapper.all_connectors_ref;
for (const parent of node_wrapper.parents) { for (const parent of node_wrapper.parents) {
@ -1253,6 +1262,8 @@ function atree_set_state(node_wrapper, new_state) {
} }
}; };
// atlas vars
// first key is connector type, second key is highlight, then [x, y] pair of 0-index positions in the tile atlas // first key is connector type, second key is highlight, then [x, y] pair of 0-index positions in the tile atlas
const atreeConnectorAtlasPositions = { const atreeConnectorAtlasPositions = {
"1100": {"0000": [0, 0], "1100": [1, 0]}, "1100": {"0000": [0, 0], "1100": [1, 0]},
@ -1267,7 +1278,9 @@ const atreeConnectorAtlasPositions = {
"1011": {"0000": [5, 2], "1011": [6, 2], "1010": [7, 2], "1001": [8, 2], "0011": [9, 2]}, "1011": {"0000": [5, 2], "1011": [6, 2], "1010": [7, 2], "1001": [8, 2], "0011": [9, 2]},
"1111": {"0000": [0, 3], "1111": [1, 3], "1110": [2, 3], "1101": [3, 3], "1100": [4, 3], "1011": [5, 3], "1010": [6, 3], "1001": [7, 3], "0111": [8, 3], "0110": [9, 3], "0101": [10, 3], "0011": [11, 3]} "1111": {"0000": [0, 3], "1111": [1, 3], "1110": [2, 3], "1101": [3, 3], "1100": [4, 3], "1011": [5, 3], "1010": [6, 3], "1001": [7, 3], "0111": [8, 3], "0110": [9, 3], "0101": [10, 3], "0011": [11, 3]}
} }
const atreeConnectorAtlasSize = [17, 5] const atreeConnectorTileSize = 18;
const atreeConnectorAtlasImg = make_elem("img", [], {src: "../media/atree/connectors.png"});
// just has the x position, y is based on state // just has the x position, y is based on state
const atreeNodeAtlasPositions = { const atreeNodeAtlasPositions = {
"node_0": 0, "node_0": 0,
@ -1280,15 +1293,13 @@ const atreeNodeAtlasPositions = {
"node_assassin": 7, "node_assassin": 7,
"node_shaman": 8 "node_shaman": 8
} }
const atreeNodeAtlasSize = [9, 3] const atreeNodeTileSize = 32;
function atlasBGPositionCalc(pos, atlasSize) { const atreeNodeAtlasImg = make_elem("img", [], {src: "../media/atree/icons.png"});
// https://css-tricks.com/focusing-background-image-precise-location-percentages/
// p = (c + 0.5/z - 0.5) * z/(z - 1) + 0.5 function drawAtlasImage(canvas, img, pos, tileSize) {
// z = num tiles in direction let ctx = canvas.getContext("2d");
// c = starting pos of tile in percent of total atlas (equal to index/z) ctx.clearRect(0, 0, tileSize, tileSize);
let x = ((pos[0]/atlasSize[0]) + 0.5/atlasSize[0] - 0.5) * atlasSize[0]/(atlasSize[0] - 1) + 0.5 ctx.drawImage(img, tileSize * pos[0], tileSize * pos[1], tileSize, tileSize, 0, 0, tileSize, tileSize);
let y = ((pos[1]/atlasSize[1]) + 0.5/atlasSize[1] - 0.5) * atlasSize[1]/(atlasSize[1] - 1) + 0.5
return (x * 100) + "% " + (y * 100) + "%" // multiply by 100 to convert decimal to percent
} }
// draw the connector onto the screen // draw the connector onto the screen
@ -1298,7 +1309,7 @@ function atree_render_connection(atree_connectors_map) {
let connector_elem = connector_info.connector; let connector_elem = connector_info.connector;
set_connector_type(connector_info); set_connector_type(connector_info);
connector_info.highlight = [0, 0, 0, 0]; connector_info.highlight = [0, 0, 0, 0];
connector_elem.style.backgroundPosition = atlasBGPositionCalc(atreeConnectorAtlasPositions[connector_info.type]["0000"], atreeConnectorAtlasSize); drawAtlasImage(connector_elem, atreeConnectorAtlasImg, atreeConnectorAtlasPositions[connector_info.type]["0000"], atreeConnectorTileSize);
let target_elem = document.getElementById("atree-row-" + i.split(",")[0]).children[i.split(",")[1]]; let target_elem = document.getElementById("atree-row-" + i.split(",")[0]).children[i.split(",")[1]];
if (target_elem.children.length != 0) { if (target_elem.children.length != 0) {
// janky special case... // janky special case...
@ -1350,15 +1361,16 @@ function atree_set_edge(atree_connectors_map, parent, child, state) {
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
render += highlight_state[i] === 0 ? "0" : "1"; render += highlight_state[i] === 0 ? "0" : "1";
} }
connector_elem.style.backgroundPosition = atlasBGPositionCalc(atreeConnectorAtlasPositions[ctype][render], atreeConnectorAtlasSize); drawAtlasImage(connector_elem, atreeConnectorAtlasImg, atreeConnectorAtlasPositions[ctype][render], atreeConnectorTileSize);
// connector_elem.style.backgroundPosition = atlasBGPositionCalc(atreeConnectorAtlasPositions[ctype][render], atreeConnectorAtlasSize);
continue; continue;
} else { } else {
// lol bad overloading, [0] is just the whole state // lol bad overloading, [0] is just the whole state
highlight_state[0] += state_delta; highlight_state[0] += state_delta;
if (highlight_state[0] > 0) { if (highlight_state[0] > 0) {
connector_elem.style.backgroundPosition = atlasBGPositionCalc(atreeConnectorAtlasPositions[ctype][ctype], atreeConnectorAtlasSize); drawAtlasImage(connector_elem, atreeConnectorAtlasImg, atreeConnectorAtlasPositions[ctype][ctype], atreeConnectorTileSize);
} else { } else {
connector_elem.style.backgroundPosition = atlasBGPositionCalc(atreeConnectorAtlasPositions[ctype]["0000"], atreeConnectorAtlasSize); drawAtlasImage(connector_elem, atreeConnectorAtlasImg, atreeConnectorAtlasPositions[ctype]["0000"], atreeConnectorTileSize);
} }
} }
} }

View file

@ -289,7 +289,7 @@ const atrees = {
"base_spell": 1, "base_spell": 1,
"target_part": "Single Arrow", "target_part": "Single Arrow",
"multipliers": [ "multipliers": [
-15, -10,
0, 0,
0, 0,
0, 0,
@ -3715,7 +3715,7 @@ const atrees = {
{ {
"display_name": "Enraged Blow", "display_name": "Enraged Blow",
"desc": "While Corriupted, every 1% of Health you lose will increase your damage by +3% (Max 300%)", "desc": "While Corriupted, every 1% of Health you lose will increase your damage by +2.2% (Max 220%)",
"archetype": "Fallen", "archetype": "Fallen",
"archetype_req": 0, "archetype_req": 0,
"base_abil": "Bak'al's Grasp", "base_abil": "Bak'al's Grasp",
@ -3739,7 +3739,7 @@ const atrees = {
"type": "stat", "type": "stat",
"name": "damMult.Enraged" "name": "damMult.Enraged"
}, },
"scaling": [3] "scaling": [2.2]
} }
] ]
}, },
@ -3966,7 +3966,7 @@ const atrees = {
{ {
"display_name": "Intoxicating Blood", "display_name": "Intoxicating Blood",
"desc": "After leaving Corrupted, gain 2% of the health lost back for each enemy killed while Corrupted", "desc": "After leaving Corrupted, gain 5% of the health lost back for each enemy killed while Corrupted",
"archetype": "Fallen", "archetype": "Fallen",
"archetype_req": 5, "archetype_req": 5,
"base_abil": "Bak'al's Grasp", "base_abil": "Bak'al's Grasp",
@ -4277,7 +4277,7 @@ const atrees = {
"parts": [ "parts": [
{ {
"name": "Damage Tick", "name": "Damage Tick",
"multipliers": [10, 0, 5, 0, 0, 0] "multipliers": [20, 0, 10, 0, 0, 0]
} }
] ]
} }
@ -5387,20 +5387,6 @@ const atrees = {
0, 0,
0 0
] ]
},
{
"type": "add_spell_prop",
"base_spell": 3,
"target_part": "Lightning Damage",
"behavior": "modify",
"multipliers": [
30,
90,
0,
0,
0,
0
]
} }
] ]
}, },
@ -6395,7 +6381,7 @@ const atrees = {
}, },
{ {
"display_name": "More Winded", "display_name": "More Winded",
"desc": "Incrase your maximum Winded by +5.", "desc": "Increase your maximum Winded by +5.",
"base_abil": "Windsweeper", "base_abil": "Windsweeper",
"archetype": "Riftwalker", "archetype": "Riftwalker",
"archetype_req": 0, "archetype_req": 0,
@ -6705,7 +6691,7 @@ const atrees = {
}, },
{ {
"display_name": "More Winded II", "display_name": "More Winded II",
"desc": "Incrase your maximum Winded by +5.", "desc": "Increase your maximum Winded by +5.",
"base_abil": "Windsweeper", "base_abil": "Windsweeper",
"archetype": "Riftwalker", "archetype": "Riftwalker",
"archetype_req": 0, "archetype_req": 0,

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,9 @@
/**
* This file defines a class representing the player Build.
*
* Keeps track of equipment list, equip order, skillpoint assignment (initial),
* Aggregates item stats into a statMap to be used in damage calculation.
*/
const classDefenseMultipliers = new Map([ ["relik",0.50], ["bow",0.60], ["wand", 0.80], ["dagger", 1.0], ["spear",1.0], ["sword", 1.10]]); const classDefenseMultipliers = new Map([ ["relik",0.50], ["bow",0.60], ["wand", 0.80], ["dagger", 1.0], ["spear",1.0], ["sword", 1.10]]);
@ -10,15 +15,9 @@ class Build{
/** /**
* @description Construct a build. * @description Construct a build.
* @param {Number} level : Level of the player. * @param {Number} level : Level of the player.
* @param {String[]} equipment : List of equipment names that make up the build. * @param {String[]} items: List of equipment names that make up the build.
* In order: boots, Chestplate, Leggings, Boots, Ring1, Ring2, Brace, Neck, Weapon. * In order: Helmet, Chestplate, Leggings, Boots, Ring1, Ring2, Brace, Neck, Tomes [x7].
* @param {Number[]} powders : Powder application. List of lists of integers (powder IDs). * @param {Item} weapon: Weapon that this build is using.
* In order: boots, Chestplate, Leggings, Boots, Weapon.
* @param {Object[]} inputerrors : List of instances of error-like classes.
*
* @param {Object[]} tomes: List of tomes.
* In order: 2x Weapon Mastery Tome, 4x Armor Mastery Tome, 1x Guild Tome.
* 2x Slaying Mastery Tome, 2x Dungeoneering Mastery Tome, 2x Gathering Mastery Tome are in game, but do not have "useful" stats (those that affect damage calculations or building)
*/ */
constructor(level, items, weapon){ constructor(level, items, weapon){
@ -39,7 +38,6 @@ class Build{
this.equipment = items; this.equipment = items;
this.weapon = weapon; this.weapon = weapon;
this.items = this.equipment.concat([this.weapon]); this.items = this.equipment.concat([this.weapon]);
// return [equip_order, best_skillpoints, final_skillpoints, best_total];
// calc skillpoints requires statmaps only // calc skillpoints requires statmaps only
let result = calculate_skillpoints(this.equipment.map((x) => x.statMap), this.weapon.statMap); let result = calculate_skillpoints(this.equipment.map((x) => x.statMap), this.weapon.statMap);
@ -61,7 +59,6 @@ class Build{
return [this.equipment,this.weapon].flat(); return [this.equipment,this.weapon].flat();
} }
/* Get all stats for this build. Stores in this.statMap. /* Get all stats for this build. Stores in this.statMap.
@pre The build itself should be valid. No checking of validity of pieces is done here. @pre The build itself should be valid. No checking of validity of pieces is done here.
*/ */

View file

@ -232,7 +232,13 @@ function shareBuild(build) {
"> "+build.items[5].statMap.get("displayName")+"\n"+ "> "+build.items[5].statMap.get("displayName")+"\n"+
"> "+build.items[6].statMap.get("displayName")+"\n"+ "> "+build.items[6].statMap.get("displayName")+"\n"+
"> "+build.items[7].statMap.get("displayName")+"\n"+ "> "+build.items[7].statMap.get("displayName")+"\n"+
"> "+build.items[15].statMap.get("displayName")+" ["+build_powders[4].map(x => powderNames.get(x)).join("")+"]"; "> "+build.items[15].statMap.get("displayName")+" ["+build_powders[4].map(x => powderNames.get(x)).join("")+"]\n";
for (let tomeslots = 8; tomeslots < 15; tomeslots++) {
if (!build.items[tomeslots].statMap.has('NONE')) {
text += ">"+' (Has Tomes)' ;
break;
}
}
copyTextToClipboard(text); copyTextToClipboard(text);
document.getElementById("share-button").textContent = "Copied!"; document.getElementById("share-button").textContent = "Copied!";
} }

View file

@ -1,3 +1,7 @@
/**
* File containing utility functions that are useful for the builder page.
*/
/*Turns the input amount of skill points into a float precision percentage. /*Turns the input amount of skill points into a float precision percentage.
* @param skp - the integer skillpoint count to be converted * @param skp - the integer skillpoint count to be converted
*/ */
@ -231,8 +235,15 @@ function expandItem(item) {
} }
class Item { class Item {
constructor(item_obj) { constructor(item_obj = null) {
this.statMap = expandItem(item_obj); if (item_obj) { this.statMap = expandItem(item_obj); }
else { this.statMap = new Map(); }
}
copy() {
const ret = new Item();
ret.statMap = new Map(this.statMap);
return ret;
} }
} }

View file

@ -1,3 +1,6 @@
/**
* File containing utility functions relevant to the builder page, as well as the setup code (at the very bottom).
*/
function populateBuildList() { function populateBuildList() {
const buildList = document.getElementById("build-choice"); const buildList = document.getElementById("build-choice");
@ -127,7 +130,7 @@ function toggleButton(button_id) {
} }
} }
// toggle tab // Toggles display of a certain element, given the ID.
function toggle_tab(tab) { function toggle_tab(tab) {
if (document.querySelector("#"+tab).style.display == "none") { if (document.querySelector("#"+tab).style.display == "none") {
document.querySelector("#"+tab).style.display = ""; document.querySelector("#"+tab).style.display = "";
@ -136,24 +139,16 @@ function toggle_tab(tab) {
} }
} }
function toggle_boost_tab(tab) { // Toggle display of a certain tab, in a group of tabs, given the target tab ID, and a list of associated tabs.
for (const i of skp_order) { // Also sets visual display of an element with ID of target + "-btn" to selected.
document.querySelector("#"+i+"-boost").style.display = "none"; function show_tab(target, tabs) {
document.getElementById(i + "-boost-tab").classList.remove("selected-btn");
}
document.querySelector("#"+tab+"-boost").style.display = "";
document.getElementById(tab + "-boost-tab").classList.add("selected-btn");
}
let tabs = ['overall-stats', 'offensive-stats', 'defensive-stats'];
function show_tab(tab) {
//hide all tabs, then show the tab of the div clicked and highlight the correct button //hide all tabs, then show the tab of the div clicked and highlight the correct button
for (const i in tabs) { for (const i in tabs) {
document.querySelector("#" + tabs[i]).style.display = "none"; document.querySelector("#" + tabs[i]).style.display = "none";
document.getElementById("tab-" + tabs[i].split("-")[0] + "-btn").classList.remove("selected-btn"); document.getElementById(tabs[i] + "-btn").classList.remove("selected-btn");
} }
document.querySelector("#" + tab).style.display = ""; document.querySelector("#" + target).style.display = "";
document.getElementById("tab-" + tab.split("-")[0] + "-btn").classList.add("selected-btn"); document.getElementById(target + "-btn").classList.add("selected-btn");
} }
// autocomplete initialize // autocomplete initialize
@ -242,8 +237,9 @@ function init_autocomplete() {
for (const eq of tome_keys) { for (const eq of tome_keys) {
// build dropdown // build dropdown
let tome_arr = []; let tome_arr = [];
for (const tome of tomeLists.get(eq.replace(/[0-9]/g, ''))) { let tome_aliases = new Map();
let tome_obj = tomeMap.get(tome); for (const tome_name of tomeLists.get(eq.replace(/[0-9]/g, ''))) {
let tome_obj = tomeMap.get(tome_name);
if (tome_obj["restrict"] && tome_obj["restrict"] === "DEPRECATED") { if (tome_obj["restrict"] && tome_obj["restrict"] === "DEPRECATED") {
continue; continue;
} }
@ -251,8 +247,10 @@ function init_autocomplete() {
if (tome_obj["name"].includes('No ' + eq.charAt(0).toUpperCase())) { if (tome_obj["name"].includes('No ' + eq.charAt(0).toUpperCase())) {
continue; continue;
} }
let tome_name = tome; let tome_alias = tome_obj['alias'];
tome_arr.push(tome_name); tome_arr.push(tome_name);
tome_arr.push(tome_alias);
tome_aliases.set(tome_alias, tome_name);
} }
// create dropdown // create dropdown
@ -287,14 +285,18 @@ function init_autocomplete() {
class: "scaled-font search-item", class: "scaled-font search-item",
selected: "dark-5", selected: "dark-5",
element: (tome, data) => { element: (tome, data) => {
tome.classList.add(tomeMap.get(data.value).tier); let val = data.value;
if (tome_aliases.has(val)) { val = tome_aliases.get(val); }
tome.classList.add(tomeMap.get(val).tier);
}, },
}, },
events: { events: {
input: { input: {
selection: (event) => { selection: (event) => {
if (event.detail.selection.value) { if (event.detail.selection.value) {
event.target.value = event.detail.selection.value; let val = event.detail.selection.value;
if (tome_aliases.has(val)) { val = tome_aliases.get(val); }
event.target.value = val;
} }
event.target.dispatchEvent(new Event('change')); event.target.dispatchEvent(new Event('change'));
}, },

View file

@ -1,3 +1,7 @@
/**
* File containing compute graph structure of the builder page.
*/
let armor_powder_node = new (class extends ComputeNode { let armor_powder_node = new (class extends ComputeNode {
constructor() { super('builder-armor-powder-input'); } constructor() { super('builder-armor-powder-input'); }
@ -203,8 +207,8 @@ class ItemPowderingNode extends ComputeNode {
compute_func(input_map) { compute_func(input_map) {
const powdering = input_map.get('powdering'); const powdering = input_map.get('powdering');
const item = {}; const input_item = input_map.get('item');
item.statMap = new Map(input_map.get('item').statMap); // TODO: performance const item = input_item.copy(); // TODO: performance
const max_slots = item.statMap.get('slots'); const max_slots = item.statMap.get('slots');
item.statMap.set('powders', powdering.slice(0, max_slots)); item.statMap.set('powders', powdering.slice(0, max_slots));
@ -705,11 +709,11 @@ class BuildDisplayNode extends ComputeNode {
compute_func(input_map) { compute_func(input_map) {
const build = input_map.get('build'); const build = input_map.get('build');
const stats = input_map.get('stats'); const stats = input_map.get('stats');
displayBuildStats('overall-stats', build, build_all_display_commands, stats); displayBuildStats('summary-stats', build, build_overall_display_commands, stats);
displayBuildStats("offensive-stats", build, build_offensive_display_commands, stats); displayBuildStats("detailed-stats", build, build_detailed_display_commands, stats);
displaySetBonuses("set-info", build); displaySetBonuses("set-info", build);
// TODO: move weapon out? // TODO: move weapon out?
displayDefenseStats(document.getElementById("defensive-stats"), stats); // displayDefenseStats(document.getElementById("defensive-stats"), stats);
displayPoisonDamage(document.getElementById("build-poison-stats"), build); displayPoisonDamage(document.getElementById("build-poison-stats"), build);
displayEquipOrder(document.getElementById("build-order"), build.equip_order); displayEquipOrder(document.getElementById("build-order"), build.equip_order);
@ -736,7 +740,7 @@ class DisplayBuildWarningsNode extends ComputeNode {
input_map.get('def'), input_map.get('def'),
input_map.get('agi') input_map.get('agi')
]; ];
let skp_effects = ["% more damage dealt.","% chance to crit.","% spell cost reduction.","% less damage taken.","% chance to dodge."]; let skp_effects = ["% damage","% crit","% cost red.","% resist","% dodge"];
let total_assigned = 0; let total_assigned = 0;
for (let i in skp_order){ //big bren for (let i in skp_order){ //big bren
const assigned = skillpoints[i] - base_totals[i] + min_assigned[i] const assigned = skillpoints[i] - base_totals[i] + min_assigned[i]
@ -758,20 +762,16 @@ class DisplayBuildWarningsNode extends ComputeNode {
let summarybox = document.getElementById("summary-box"); let summarybox = document.getElementById("summary-box");
summarybox.textContent = ""; summarybox.textContent = "";
let skpRow = document.createElement("p");
let remainingSkp = document.createElement("p"); let remainingSkp = make_elem("p", ['scaled-font', 'my-0']);
remainingSkp.classList.add("scaled-font"); let remainingSkpTitle = make_elem("b", [], { textContent: "Assigned " + total_assigned + " skillpoints. Remaining skillpoints: " });
let remainingSkpTitle = document.createElement("b");
remainingSkpTitle.textContent = "Assigned " + total_assigned + " skillpoints. Remaining skillpoints: ";
let remainingSkpContent = document.createElement("b"); let remainingSkpContent = document.createElement("b");
remainingSkpContent.textContent = "" + (levelToSkillPoints(build.level) - total_assigned); remainingSkpContent.textContent = "" + (levelToSkillPoints(build.level) - total_assigned);
remainingSkpContent.classList.add(levelToSkillPoints(build.level) - total_assigned < 0 ? "negative" : "positive"); remainingSkpContent.classList.add(levelToSkillPoints(build.level) - total_assigned < 0 ? "negative" : "positive");
remainingSkp.appendChild(remainingSkpTitle); remainingSkp.append(remainingSkpTitle);
remainingSkp.appendChild(remainingSkpContent); remainingSkp.append(remainingSkpContent);
summarybox.append(skpRow);
summarybox.append(remainingSkp); summarybox.append(remainingSkp);
if(total_assigned > levelToSkillPoints(build.level)){ if(total_assigned > levelToSkillPoints(build.level)){
let skpWarning = document.createElement("span"); let skpWarning = document.createElement("span");
@ -1025,7 +1025,7 @@ function builder_graph_init() {
let weapon_image = document.getElementById("weapon-img"); let weapon_image = document.getElementById("weapon-img");
let weapon_dps = document.getElementById("weapon-dps"); let weapon_dps = document.getElementById("weapon-dps");
new WeaponInputDisplayNode('weapon-type', weapon_image, weapon_dps).link_to(item_nodes[8]); new WeaponInputDisplayNode('weapon-type', weapon_image, weapon_dps).link_to(item_nodes[8]);
// linking to atree verification // linking to atree verification
atree_validate.link_to(level_input, 'level'); atree_validate.link_to(level_input, 'level');

View file

@ -397,4 +397,8 @@ class Craft{
statMap.set("crafted", true); statMap.set("crafted", true);
this.statMap = statMap; this.statMap = statMap;
} }
copy() {
return new Craft(this.recipe, this.mat_tiers, this.ingreds, this.atkSpd, this.hash.slice(3));
}
} }

View file

@ -336,4 +336,7 @@ class Custom {
this.statMap.set("restrict", "Custom Item") this.statMap.set("restrict", "Custom Item")
} }
copy() {
return new Custom(new Map(this.statMap));
}
} }

View file

@ -1,4 +1,8 @@
const damageMultipliers = new Map([ ["allytotem", .15], ["yourtotem", .35], ["vanish", 0.80], ["warscream", 0.00], ["ragnarokkr", 0.30], ["fortitude", 0.60] ]); /**
* File implementing core damage calculation logic.
*/
const damageMultipliers = new Map([ ["allytotem", .15], ["yourtotem", .35], ["warscream", 0.00], ["ragnarokkr", 0.30], ["fortitude", 0.60] ]);
function get_base_dps(item) { function get_base_dps(item) {
const attack_speed_mult = baseDamageMultiplier[attackSpeeds.indexOf(item.get("atkSpd"))]; const attack_speed_mult = baseDamageMultiplier[attackSpeeds.indexOf(item.get("atkSpd"))];

View file

@ -1,3 +1,8 @@
/**
* File containing generic display code, ex. for displaying items and spell damage.
* TODO: split this file into separate parts for each "component".
*/
const itemBGPositions = {"bow": "0 0", "spear": "9.090909090909088% 0", "wand": "18.181818181818183% 0", "dagger": "27.27272727272727% 0", "relik": "36.36363636363637% 0", const itemBGPositions = {"bow": "0 0", "spear": "9.090909090909088% 0", "wand": "18.181818181818183% 0", "dagger": "27.27272727272727% 0", "relik": "36.36363636363637% 0",
"helmet": "45.45454545454546% 0", "chestplate": "54.54545454545454% 0", "leggings": "63.63636363636363% 0", "boots": "72.72727272727272% 0", "helmet": "45.45454545454546% 0", "chestplate": "54.54545454545454% 0", "leggings": "63.63636363636363% 0", "boots": "72.72727272727272% 0",
"ring": "81.81818181818181% 0", "bracelet": "90.90909090909092% 0", "necklace": "100% 0", "ring": "81.81818181818181% 0", "bracelet": "90.90909090909092% 0", "necklace": "100% 0",
@ -1510,9 +1515,7 @@ function displaySpellDamage(parent_elem, _overallparent_elem, stats, spell, spel
_damage_display("Crit Average: ", critAverage, spell_info.crit_min, spell_info.crit_max); _damage_display("Crit Average: ", critAverage, spell_info.crit_min, spell_info.crit_max);
} else if (spell_info.type === "heal") { } else if (spell_info.type === "heal") {
let heal_amount = spell_info.heal_amount; let heal_amount = spell_info.heal_amount;
let healLabel = document.createElement("p"); let healLabel = make_elem("p", ["Set"], {textContent: heal_amount.toFixed(2)});
healLabel.textContent = heal_amount;
// healLabel.classList.add("damagep");
part_div.append(healLabel); part_div.append(healLabel);
if (spell_info.name === spell.display) { if (spell_info.name === spell.display) {
add_summary(spell_info.name+ ": ", heal_amount, "Set"); add_summary(spell_info.name+ ": ", heal_amount, "Set");

View file

@ -209,7 +209,25 @@ let posModSuffixes = {
/* /*
* Display commands * Display commands
*/ */
let build_all_display_commands = [ let build_overall_display_commands = [
"#defense-stats",
"str", "dex", "int", "def", "agi",
"!spacer",
"mr", "ms",
"ls",
"poison",
"ref", "thorns",
"expd",
"spd",
"sprint", "sprintReg",
"jh",
"xpb", "lb", "lq",
"spRegen",
"eSteal",
"gXp", "gSpd",
];
let build_detailed_display_commands = [
"#defense-stats", "#defense-stats",
"str", "dex", "int", "def", "agi", "str", "dex", "int", "def", "agi",
"!spacer", "!spacer",
@ -236,23 +254,31 @@ let build_all_display_commands = [
"gXp", "gSpd", "gXp", "gSpd",
]; ];
let build_offensive_display_commands = [ // full
"str", "dex", "int", "def", "agi", //"#defense-stats",
"mr", "ms", //"str", "dex", "int", "def", "agi",
"sdRaw", "sdPct", //"!spacer",
"mdRaw", "mdPct", //"mr", "ms",
"ref", "thorns", //"hprRaw", "hprPct",
"ls", //"ls",
"poison", //"sdRaw", "sdPct",
"expd", //"mdRaw", "mdPct",
"spd", //"!elemental",
"atkTier", //"fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct",
"rainbowRaw", //"!elemental",
"!elemental", //"spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4",
"fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", //"atkTier",
"!elemental", //"poison",
"spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", //"ref", "thorns",
]; //"expd",
//"spd",
//"rainbowRaw",
//"sprint", "sprintReg",
//"jh",
//"xpb", "lb", "lq",
//"spRegen",
//"eSteal",
//"gXp", "gSpd",
let build_basic_display_commands = [ let build_basic_display_commands = [
'#defense-stats', '#defense-stats',

View file

@ -1,4 +1,4 @@
const DB_VERSION = 101; const DB_VERSION = 102;
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA // @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA
let db; let db;
@ -254,5 +254,4 @@ function init_maps() {
redirectMap.set(item.id, item.remapID); redirectMap.set(item.id, item.remapID);
} }
} }
console.log(itemMap);
} }

View file

@ -1,4 +1,4 @@
const TOME_DB_VERSION = 3; const TOME_DB_VERSION = 4;
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA // @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA
let tdb; let tdb;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -1,6 +1,5 @@
{ {
"tomes": "tomes": [
[
{ {
"name": "Retaliating Tome of Armour Mastery I", "name": "Retaliating Tome of Armour Mastery I",
"tier": "Fabled", "tier": "Fabled",
@ -14,7 +13,8 @@
"ref": 6, "ref": 6,
"hpBonus": 120, "hpBonus": 120,
"fixID": false, "fixID": false,
"id": 0 "id": 0,
"alias": "Thorns I"
}, },
{ {
"name": "Retaliating Tome of Armour Mastery II", "name": "Retaliating Tome of Armour Mastery II",
@ -28,7 +28,8 @@
"thorns": 8, "thorns": 8,
"ref": 8, "ref": 8,
"fixID": false, "fixID": false,
"id": 1 "id": 1,
"alias": "Thorns II"
}, },
{ {
"name": "Destructive Tome of Armour Mastery I", "name": "Destructive Tome of Armour Mastery I",
@ -43,7 +44,8 @@
"mdPct": 5, "mdPct": 5,
"hpBonus": 120, "hpBonus": 120,
"fixID": false, "fixID": false,
"id": 2 "id": 2,
"alias": "Melee I"
}, },
{ {
"name": "Destructive Tome of Armour Mastery II", "name": "Destructive Tome of Armour Mastery II",
@ -57,7 +59,8 @@
"thorns": 6, "thorns": 6,
"reflection": 6, "reflection": 6,
"fixID": false, "fixID": false,
"id": 3 "id": 3,
"alias": "Melee II"
}, },
{ {
"name": "Sorcerer's Tome of Armour Mastery I", "name": "Sorcerer's Tome of Armour Mastery I",
@ -71,7 +74,8 @@
"sdPct": 5, "sdPct": 5,
"hpBonus": 120, "hpBonus": 120,
"fixID": false, "fixID": false,
"id": 4 "id": 4,
"alias": "Spell Damage I"
}, },
{ {
"name": "Sorcerer's Tome of Armour Mastery II", "name": "Sorcerer's Tome of Armour Mastery II",
@ -84,7 +88,8 @@
"defMobs": 5, "defMobs": 5,
"sdPct": 6, "sdPct": 6,
"fixID": false, "fixID": false,
"id": 5 "id": 5,
"alias": "Spell Damage II"
}, },
{ {
"name": "Everlasting Tome of Armour Mastery I", "name": "Everlasting Tome of Armour Mastery I",
@ -98,7 +103,8 @@
"hprRaw": 15, "hprRaw": 15,
"hpBonus": 120, "hpBonus": 120,
"fixID": false, "fixID": false,
"id": 6 "id": 6,
"alias": "Health Regen I"
}, },
{ {
"name": "Everlasting Tome of Armour Mastery II", "name": "Everlasting Tome of Armour Mastery II",
@ -111,7 +117,8 @@
"defMobs": 5, "defMobs": 5,
"hprRaw": 60, "hprRaw": 60,
"fixID": false, "fixID": false,
"id": 7 "id": 7,
"alias": "Health Regen II"
}, },
{ {
"name": "Vampiric Tome of Armour Mastery I", "name": "Vampiric Tome of Armour Mastery I",
@ -125,7 +132,8 @@
"ls": 25, "ls": 25,
"hpBonus": 120, "hpBonus": 120,
"fixID": false, "fixID": false,
"id": 8 "id": 8,
"alias": "Life Steal I"
}, },
{ {
"name": "Vampiric Tome of Armour Mastery II", "name": "Vampiric Tome of Armour Mastery II",
@ -138,7 +146,8 @@
"defMobs": 5, "defMobs": 5,
"ls": 85, "ls": 85,
"fixID": false, "fixID": false,
"id": 9 "id": 9,
"alias": "Life Steal II"
}, },
{ {
"name": "Greedy Tome of Armour Mastery I", "name": "Greedy Tome of Armour Mastery I",
@ -152,7 +161,8 @@
"lb": 5, "lb": 5,
"hpBonus": 120, "hpBonus": 120,
"fixID": false, "fixID": false,
"id": 10 "id": 10,
"alias": "Loot Bonus I"
}, },
{ {
"name": "Greedy Tome of Armour Mastery II", "name": "Greedy Tome of Armour Mastery II",
@ -165,7 +175,8 @@
"defMobs": 5, "defMobs": 5,
"lb": 6, "lb": 6,
"fixID": false, "fixID": false,
"id": 11 "id": 11,
"alias": "Loot Bonus II"
}, },
{ {
"name": "Weightless Tome of Armour Mastery I", "name": "Weightless Tome of Armour Mastery I",
@ -179,7 +190,8 @@
"spd": 5, "spd": 5,
"hpBonus": 120, "hpBonus": 120,
"fixID": false, "fixID": false,
"id": 12 "id": 12,
"alias": "Walk Speed I"
}, },
{ {
"name": "Weightless Tome of Armour Mastery II", "name": "Weightless Tome of Armour Mastery II",
@ -192,7 +204,8 @@
"defMobs": 5, "defMobs": 5,
"spd": 6, "spd": 6,
"fixID": false, "fixID": false,
"id": 13 "id": 13,
"alias": "Walk Speed II"
}, },
{ {
"name": "Blooming Tome of Armour Mastery II", "name": "Blooming Tome of Armour Mastery II",
@ -206,7 +219,8 @@
"eDefPct": 10, "eDefPct": 10,
"hpBonus": 150, "hpBonus": 150,
"fixID": false, "fixID": false,
"id": 14 "id": 14,
"alias": "Earth Defense II"
}, },
{ {
"name": "Pulsing Tome of Armour Mastery II", "name": "Pulsing Tome of Armour Mastery II",
@ -220,7 +234,8 @@
"tDefPct": 10, "tDefPct": 10,
"hpBonus": 150, "hpBonus": 150,
"fixID": false, "fixID": false,
"id": 15 "id": 15,
"alias": "Thunder Defense II"
}, },
{ {
"name": "Oceanic Tome of Armour Mastery II", "name": "Oceanic Tome of Armour Mastery II",
@ -234,7 +249,8 @@
"wDefPct": 10, "wDefPct": 10,
"hpBonus": 150, "hpBonus": 150,
"fixID": false, "fixID": false,
"id": 16 "id": 16,
"alias": "Water Defense II"
}, },
{ {
"name": "Courageous Tome of Armour Mastery II", "name": "Courageous Tome of Armour Mastery II",
@ -248,7 +264,8 @@
"fDefPct": 10, "fDefPct": 10,
"hpBonus": 150, "hpBonus": 150,
"fixID": false, "fixID": false,
"id": 17 "id": 17,
"alias": "Fire Defense II"
}, },
{ {
"name": "Clouded Tome of Armour Mastery II", "name": "Clouded Tome of Armour Mastery II",
@ -262,7 +279,8 @@
"aDefPct": 10, "aDefPct": 10,
"hpBonus": 150, "hpBonus": 150,
"fixID": false, "fixID": false,
"id": 18 "id": 18,
"alias": "Air Defense II"
}, },
{ {
"name": "Radiant Tome of Armour Mastery II", "name": "Radiant Tome of Armour Mastery II",
@ -280,7 +298,8 @@
"aDefPct": 6, "aDefPct": 6,
"hpBonus": 150, "hpBonus": 150,
"fixID": false, "fixID": false,
"id": 19 "id": 19,
"alias": "Rainbow Defense II"
}, },
{ {
"name": "Tome of Weapon Mastery I", "name": "Tome of Weapon Mastery I",
@ -292,7 +311,8 @@
"lvl": 60, "lvl": 60,
"damMobs": 6, "damMobs": 6,
"fixID": false, "fixID": false,
"id": 20 "id": 20,
"alias": "Weapon Mastery I"
}, },
{ {
"name": "Earthbound Tome of Weapon Mastery I", "name": "Earthbound Tome of Weapon Mastery I",
@ -305,7 +325,8 @@
"damMobs": 7, "damMobs": 7,
"str": 3, "str": 3,
"fixID": false, "fixID": false,
"id": 21 "id": 21,
"alias": "Strength I"
}, },
{ {
"name": "Earthbound Tome of Weapon Mastery II", "name": "Earthbound Tome of Weapon Mastery II",
@ -318,7 +339,8 @@
"damMobs": 8, "damMobs": 8,
"str": 3, "str": 3,
"fixID": false, "fixID": false,
"id": 22 "id": 22,
"alias": "Strength II"
}, },
{ {
"name": "Nimble Tome of Weapon Mastery I", "name": "Nimble Tome of Weapon Mastery I",
@ -331,7 +353,8 @@
"damMobs": 7, "damMobs": 7,
"dex": 3, "dex": 3,
"fixID": false, "fixID": false,
"id": 23 "id": 23,
"alias": "Dexterity I"
}, },
{ {
"name": "Nimble Tome of Weapon Mastery II", "name": "Nimble Tome of Weapon Mastery II",
@ -344,7 +367,8 @@
"damMobs": 8, "damMobs": 8,
"dex": 3, "dex": 3,
"fixID": false, "fixID": false,
"id": 24 "id": 24,
"alias": "Dexterity II"
}, },
{ {
"name": "Mystical Tome of Weapon Mastery I", "name": "Mystical Tome of Weapon Mastery I",
@ -357,7 +381,8 @@
"damMobs": 7, "damMobs": 7,
"int": 3, "int": 3,
"fixID": false, "fixID": false,
"id": 25 "id": 25,
"alias": "Intelligence I"
}, },
{ {
"name": "Mystical Tome of Weapon Mastery II", "name": "Mystical Tome of Weapon Mastery II",
@ -370,7 +395,8 @@
"damMobs": 8, "damMobs": 8,
"int": 3, "int": 3,
"fixID": false, "fixID": false,
"id": 26 "id": 26,
"alias": "Intelligence II"
}, },
{ {
"name": "Warding Tome of Weapon Mastery I", "name": "Warding Tome of Weapon Mastery I",
@ -383,7 +409,8 @@
"damMobs": 7, "damMobs": 7,
"def": 3, "def": 3,
"fixID": false, "fixID": false,
"id": 27 "id": 27,
"alias": "Defense I"
}, },
{ {
"name": "Warding Tome of Weapon Mastery II", "name": "Warding Tome of Weapon Mastery II",
@ -396,7 +423,8 @@
"damMobs": 8, "damMobs": 8,
"def": 3, "def": 3,
"fixID": false, "fixID": false,
"id": 28 "id": 28,
"alias": "Defense II"
}, },
{ {
"name": "Athletic Tome of Weapon Mastery I", "name": "Athletic Tome of Weapon Mastery I",
@ -409,7 +437,8 @@
"damMobs": 7, "damMobs": 7,
"agi": 3, "agi": 3,
"fixID": false, "fixID": false,
"id": 29 "id": 29,
"alias": "Agility I"
}, },
{ {
"name": "Athletic Tome of Weapon Mastery II", "name": "Athletic Tome of Weapon Mastery II",
@ -422,7 +451,8 @@
"damMobs": 8, "damMobs": 8,
"agi": 3, "agi": 3,
"fixID": false, "fixID": false,
"id": 30 "id": 30,
"alias": "Agility II"
}, },
{ {
"name": "Cosmic Tome of Weapon Mastery I", "name": "Cosmic Tome of Weapon Mastery I",
@ -439,7 +469,8 @@
"def": 1, "def": 1,
"agi": 1, "agi": 1,
"fixID": false, "fixID": false,
"id": 31 "id": 31,
"alias": "Rainbow Skillpoint I"
}, },
{ {
"name": "Cosmic Tome of Weapon Mastery II", "name": "Cosmic Tome of Weapon Mastery II",
@ -456,7 +487,8 @@
"def": 1, "def": 1,
"agi": 1, "agi": 1,
"fixID": false, "fixID": false,
"id": 32 "id": 32,
"alias": "Rainbow Skillpoint II"
}, },
{ {
"name": "Seismic Tome of Weapon Mastery II", "name": "Seismic Tome of Weapon Mastery II",
@ -469,7 +501,8 @@
"damMobs": 12, "damMobs": 12,
"eDamPct": 7, "eDamPct": 7,
"fixID": false, "fixID": false,
"id": 33 "id": 33,
"alias": "Earth Damage II"
}, },
{ {
"name": "Voltaic Tome of Weapon Mastery II", "name": "Voltaic Tome of Weapon Mastery II",
@ -482,7 +515,8 @@
"damMobs": 12, "damMobs": 12,
"tDamPct": 7, "tDamPct": 7,
"fixID": false, "fixID": false,
"id": 34 "id": 34,
"alias": "Thunder Damage II"
}, },
{ {
"name": "Abyssal Tome of Weapon Mastery II", "name": "Abyssal Tome of Weapon Mastery II",
@ -495,7 +529,8 @@
"damMobs": 12, "damMobs": 12,
"wDamPct": 7, "wDamPct": 7,
"fixID": false, "fixID": false,
"id": 35 "id": 35,
"alias": "Water Damage II"
}, },
{ {
"name": "Infernal Tome of Weapon Mastery II", "name": "Infernal Tome of Weapon Mastery II",
@ -508,7 +543,8 @@
"damMobs": 12, "damMobs": 12,
"fDamPct": 7, "fDamPct": 7,
"fixID": false, "fixID": false,
"id": 36 "id": 36,
"alias": "Fire Damage II"
}, },
{ {
"name": "Cyclonic Tome of Weapon Mastery II", "name": "Cyclonic Tome of Weapon Mastery II",
@ -521,7 +557,8 @@
"damMobs": 12, "damMobs": 12,
"aDamPct": 7, "aDamPct": 7,
"fixID": false, "fixID": false,
"id": 37 "id": 37,
"alias": "Air Damage II"
}, },
{ {
"name": "Astral Tome of Weapon Mastery II", "name": "Astral Tome of Weapon Mastery II",
@ -538,7 +575,8 @@
"fDamPct": 6, "fDamPct": 6,
"aDamPct": 6, "aDamPct": 6,
"fixID": false, "fixID": false,
"id": 38 "id": 38,
"alias": "Rainbow Damage II"
}, },
{ {
"name": "Brute's Tome of Allegiance", "name": "Brute's Tome of Allegiance",
@ -551,7 +589,8 @@
"str": 3, "str": 3,
"eDamPct": 2, "eDamPct": 2,
"fixID": false, "fixID": false,
"id": 39 "id": 39,
"alias": "Strength"
}, },
{ {
"name": "Sadist's Tome of Allegiance", "name": "Sadist's Tome of Allegiance",
@ -564,7 +603,8 @@
"dex": 3, "dex": 3,
"tDamPct": 2, "tDamPct": 2,
"fixID": false, "fixID": false,
"id": 40 "id": 40,
"alias": "Dexterity"
}, },
{ {
"name": "Mastermind's Tome of Allegiance", "name": "Mastermind's Tome of Allegiance",
@ -577,7 +617,8 @@
"int": 3, "int": 3,
"wDamPct": 2, "wDamPct": 2,
"fixID": false, "fixID": false,
"id": 41 "id": 41,
"alias": "Intelligence"
}, },
{ {
"name": "Arsonist's Tome of Allegiance", "name": "Arsonist's Tome of Allegiance",
@ -590,7 +631,8 @@
"def": 3, "def": 3,
"fDamPct": 2, "fDamPct": 2,
"fixID": false, "fixID": false,
"id": 42 "id": 42,
"alias": "Defense"
}, },
{ {
"name": "Ghost's Tome of Allegiance", "name": "Ghost's Tome of Allegiance",
@ -603,7 +645,8 @@
"agi": 3, "agi": 3,
"aDamPct": 2, "aDamPct": 2,
"fixID": false, "fixID": false,
"id": 43 "id": 43,
"alias": "Agility"
}, },
{ {
"name": "Psychopath's Tome of Allegiance", "name": "Psychopath's Tome of Allegiance",
@ -616,7 +659,8 @@
"str": 2, "str": 2,
"dex": 2, "dex": 2,
"fixID": false, "fixID": false,
"id": 44 "id": 44,
"alias": "ET"
}, },
{ {
"name": "Loner's Tome of Allegiance", "name": "Loner's Tome of Allegiance",
@ -629,7 +673,8 @@
"str": 2, "str": 2,
"int": 2, "int": 2,
"fixID": false, "fixID": false,
"id": 45 "id": 45,
"alias": "EW"
}, },
{ {
"name": "Warlock's Tome of Allegiance", "name": "Warlock's Tome of Allegiance",
@ -642,7 +687,8 @@
"dex": 2, "dex": 2,
"int": 2, "int": 2,
"fixID": false, "fixID": false,
"id": 46 "id": 46,
"alias": "TW"
}, },
{ {
"name": "Destroyer's Tome of Allegiance", "name": "Destroyer's Tome of Allegiance",
@ -655,7 +701,8 @@
"str": 2, "str": 2,
"def": 2, "def": 2,
"fixID": false, "fixID": false,
"id": 47 "id": 47,
"alias": "EF"
}, },
{ {
"name": "Devil's Tome of Allegiance", "name": "Devil's Tome of Allegiance",
@ -668,7 +715,8 @@
"dex": 2, "dex": 2,
"def": 2, "def": 2,
"fixID": false, "fixID": false,
"id": 48 "id": 48,
"alias": "TF"
}, },
{ {
"name": "Alchemist's Tome of Allegiance", "name": "Alchemist's Tome of Allegiance",
@ -681,7 +729,8 @@
"int": 2, "int": 2,
"def": 2, "def": 2,
"fixID": false, "fixID": false,
"id": 49 "id": 49,
"alias": "WF"
}, },
{ {
"name": "Barbarian's Tome of Allegiance", "name": "Barbarian's Tome of Allegiance",
@ -694,7 +743,8 @@
"str": 2, "str": 2,
"agi": 2, "agi": 2,
"fixID": false, "fixID": false,
"id": 50 "id": 50,
"alias": "EA"
}, },
{ {
"name": "Freelancer's Tome of Allegiance", "name": "Freelancer's Tome of Allegiance",
@ -707,7 +757,8 @@
"dex": 2, "dex": 2,
"agi": 2, "agi": 2,
"fixID": false, "fixID": false,
"id": 51 "id": 51,
"alias": "TA"
}, },
{ {
"name": "Sycophant's Tome of Allegiance", "name": "Sycophant's Tome of Allegiance",
@ -720,7 +771,8 @@
"int": 2, "int": 2,
"agi": 2, "agi": 2,
"fixID": false, "fixID": false,
"id": 52 "id": 52,
"alias": "WA"
}, },
{ {
"name": "Fanatic's Tome of Allegiance", "name": "Fanatic's Tome of Allegiance",
@ -733,7 +785,8 @@
"def": 2, "def": 2,
"agi": 2, "agi": 2,
"fixID": false, "fixID": false,
"id": 53 "id": 53,
"alias": "FA"
}, },
{ {
"name": "Assimilator's Tome of Allegiance", "name": "Assimilator's Tome of Allegiance",
@ -749,7 +802,8 @@
"def": 1, "def": 1,
"agi": 1, "agi": 1,
"fixID": false, "fixID": false,
"id": 54 "id": 54,
"alias": "Rainbow"
} }
] ]
} }