Merge branch 'atree' into experimental
|
@ -36,20 +36,28 @@
|
|||
<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>
|
||||
</div>
|
||||
<div class="container-fluid me-4" style="max-width: 95%;">
|
||||
<div class="container-fluid overall-box">
|
||||
<!-- REMOVE THIS DIV AT SOME POINT. -->
|
||||
<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>
|
||||
<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="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="row row-cols-1 row-cols-xl-2 rounded gy-4 gx-5 justify-content-center">
|
||||
<div class="col-auto rounded order-xl-0 order-0">
|
||||
<div class="row h-100 dark-shadow dark-6 rounded" id="helmet-dropdown">
|
||||
<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>
|
||||
<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">
|
||||
<img id="helmet-img" class="img-fluid rounded" src="../media/items/new/generic-helmet.png">
|
||||
<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 class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -73,10 +81,10 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto order-xl-0 order-1">
|
||||
<div class="row h-100 dark-shadow dark-6 rounded" id="ring1-dropdown">
|
||||
<div class="col-auto order-xl-0 order-1 my-0">
|
||||
<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">
|
||||
<img id="ring1-img" class="img-fluid rounded" src="../media/items/new/generic-ring.png">
|
||||
<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 class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -94,16 +102,15 @@
|
|||
<input class="equipment-input text-light form-control" id="ring1-choice" name="ring1-choice" placeholder="No ring" value="" tabindex="2"/>
|
||||
</div>
|
||||
<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 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">
|
||||
<img id="chestplate-img" class="img-fluid rounded" src="../media/items/new/generic-chestplate.png">
|
||||
<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 class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -128,9 +135,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<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">
|
||||
<img id="ring2-img" class="img-fluid rounded" src="../media/items/new/generic-ring.png">
|
||||
<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 class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -154,9 +161,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<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">
|
||||
<img id="leggings-img" class="img-fluid rounded" src="../media/items/new/generic-leggings.png">
|
||||
<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 class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -181,9 +188,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<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">
|
||||
<img id="bracelet-img" class="img-fluid rounded" src="../media/items/new/generic-bracelet.png">
|
||||
<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 class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -208,9 +215,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<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">
|
||||
<img id="boots-img" class="img-fluid rounded" src="../media/items/new/generic-boots.png">
|
||||
<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 class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -235,9 +242,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<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">
|
||||
<img id="necklace-img" class="img-fluid rounded" src="../media/items/new/generic-necklace.png">
|
||||
<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 class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -261,9 +268,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<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">
|
||||
<img id="weapon-img" class="img-fluid rounded" src="../media/items/new/generic-dagger.png">
|
||||
<div id="weapon-img" class="img-fluid rounded item-display-new-toggleable" style = "background-image: url('../media/items/new.png');"></div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -287,29 +294,25 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto order-xl-0 order-1">
|
||||
<div class="row h-100 dark-shadow dark-6 rounded">
|
||||
<div class="col-auto order-xl-0 order-1 level-input">
|
||||
<div class="row h-100 px-1">
|
||||
<div class="col">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-3 text-nowrap fw-bold scaled-font">
|
||||
<div class="row align-items-center justify-content-left">
|
||||
<div class="col-auto text-nowrap fw-bold scaled-font">
|
||||
Level:
|
||||
</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"/>
|
||||
</div>
|
||||
<div class="col-auto px-1 text-nowrap scaled-font">
|
||||
<button class="button fw-bold text-light dark-5 scaled-font rounded" id="reset-button" onclick="resetFields()">Reset</button>
|
||||
<div class="col-auto px-1 scaled-font">
|
||||
<button class="button py-0 fw-bold text-light dark-5 scaled-font rounded" id="reset-button" onclick="resetFields()">Reset</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-center justify-content-center my-1">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto px-1 text-nowrap scaled-font">
|
||||
<button class="border-dark text-light dark-5 scaled-font rounded" id=copy-button onclick="copyBuild()">Copy short</button>
|
||||
</div>
|
||||
<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 class="row align-items-left justify-content-left my-1">
|
||||
<button class="col-auto mx-1 px-1 py-0 border-info text-light dark-5 scaled-font rounded fake-button"
|
||||
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"
|
||||
id=share-button onclick="shareBuild(player_build)">Copy for sharing</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -390,12 +393,9 @@
|
|||
</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 class="col text-center">
|
||||
<div class="col text-center py-1">
|
||||
<div id="summary-box"></div>
|
||||
<div id="err-box"></div>
|
||||
<div id="stack-box"></div>
|
||||
|
@ -407,188 +407,187 @@
|
|||
</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="row row-cols-1 gy-4">
|
||||
|
||||
<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="row row-cols-1 gy-3">
|
||||
<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="col fw-bold dark-4 rounded-top">
|
||||
|
@ -620,7 +619,7 @@
|
|||
<div class="col-auto rounded">
|
||||
<div class="row h-100 dark-shadow rounded" id='weaponTome1-dropdown'>
|
||||
<div class="col-auto g-0 rounded-end my-auto text-center scaled-item-icon" id="weaponTome1-img-loc">
|
||||
<img id="weaponTome1-img" class="img-fluid rounded" src="../media/items/new/generic-weaponTome.png">
|
||||
<div id="weaponTome1-img" class="img-fluid rounded tome-image"></div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -644,7 +643,7 @@
|
|||
<div class="col-auto rounded">
|
||||
<div class="row h-100 dark-shadow rounded" id='weaponTome2-dropdown'>
|
||||
<div class="col-auto g-0 rounded-end my-auto text-center scaled-item-icon" id="weaponTome2-img-loc">
|
||||
<img id="weaponTome2-img" class="img-fluid rounded" src="../media/items/new/generic-weaponTome.png">
|
||||
<div id="weaponTome2-img" class="img-fluid rounded tome-image"></div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -668,7 +667,7 @@
|
|||
<div class="col-auto rounded">
|
||||
<div class="row h-100 dark-shadow rounded" id='armorTome1-dropdown'>
|
||||
<div class="col-auto g-0 rounded-end my-auto text-center scaled-item-icon" id="armorTome1-img-loc">
|
||||
<img id="armorTome1-img" class="img-fluid rounded" src="../media/items/new/generic-armorTome.png">
|
||||
<div id="armorTome1-img" class="img-fluid rounded tome-image"></div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -692,7 +691,7 @@
|
|||
<div class="col-auto rounded">
|
||||
<div class="row h-100 dark-shadow rounded" id='armorTome2-dropdown'>
|
||||
<div class="col-auto g-0 rounded-end my-auto text-center scaled-item-icon" id="armorTome2-img-loc">
|
||||
<img id="armorTome2-img" class="img-fluid rounded" src="../media/items/new/generic-armorTome.png">
|
||||
<div id="armorTome2-img" class="img-fluid rounded tome-image"></div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -716,7 +715,7 @@
|
|||
<div class="col-auto rounded">
|
||||
<div class="row h-100 dark-shadow rounded" id='armorTome3-dropdown'>
|
||||
<div class="col-auto g-0 rounded-end my-auto text-center scaled-item-icon" id="armorTome3-img-loc">
|
||||
<img id="armorTome3-img" class="img-fluid rounded" src="../media/items/new/generic-armorTome.png">
|
||||
<div id="armorTome3-img" class="img-fluid rounded tome-image"></div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -740,7 +739,7 @@
|
|||
<div class="col-auto rounded">
|
||||
<div class="row h-100 dark-shadow rounded" id='armorTome4-dropdown'>
|
||||
<div class="col-auto g-0 rounded-end my-auto text-center scaled-item-icon" id="armorTome4-img-loc">
|
||||
<img id="armorTome4-img" class="img-fluid rounded" src="../media/items/new/generic-armorTome.png">
|
||||
<div id="armorTome4-img" class="img-fluid rounded tome-image"></div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -764,7 +763,7 @@
|
|||
<div class="col-auto rounded">
|
||||
<div class="row h-100 dark-shadow rounded" id='guildTome1-dropdown'>
|
||||
<div class="col-auto g-0 rounded-end my-auto text-center scaled-item-icon" id="guildTome1-img-loc">
|
||||
<img id="guildTome1-img" class="img-fluid rounded" src="../media/items/new/generic-guildTome.png">
|
||||
<div id="guildTome1-img" class="img-fluid rounded tome-image"></div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row row-cols-1 h-100 align-items-center">
|
||||
|
@ -789,7 +788,7 @@
|
|||
</div>
|
||||
<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="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 class="col mx-auto" style="height: 90vh; overflow-y: auto;" id="atree-rhs">
|
||||
|
@ -1131,24 +1130,20 @@
|
|||
</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="col rounded-top">
|
||||
<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')">
|
||||
Offense
|
||||
<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'])">
|
||||
Detailed
|
||||
</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')">
|
||||
Defense
|
||||
</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 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'])">
|
||||
Summary
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: none;" id="offensive-stats" class="col text-nowrap"></div>
|
||||
<div style="display: none;" id="defensive-stats" class="col text-nowrap"></div>
|
||||
<div id="overall-stats" class="col text-nowrap"></div>
|
||||
<div style="display: none;" id="detailed-stats" class="col text-nowrap"></div>
|
||||
<div id="summary-stats" class="col text-nowrap"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 mb-3 px-0">
|
||||
|
@ -1262,7 +1257,7 @@
|
|||
<script type="text/javascript" src="../js/utils.js"></script>
|
||||
<script type="text/javascript" src="../js/build_utils.js"></script>
|
||||
<script type="text/javascript" src="../js/computation_graph.js"></script>
|
||||
<script type="text/javascript" src="../js/sq2icons.js"></script>
|
||||
<script type="text/javascript" src="../js/icons.js"></script>
|
||||
<script type="text/javascript" src="../js/powders.js"></script>
|
||||
<script type="text/javascript" src="../js/skillpoints.js"></script>
|
||||
<script type="text/javascript" src="../js/damage_calc.js"></script>
|
||||
|
|
130
clean.json
|
@ -40164,32 +40164,6 @@
|
|||
"mr": 5,
|
||||
"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",
|
||||
"tier": "Rare",
|
||||
|
@ -40858,32 +40832,6 @@
|
|||
"tDamPct": 5,
|
||||
"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",
|
||||
"tier": "Normal",
|
||||
|
@ -40978,32 +40926,6 @@
|
|||
"fDefPct": 20,
|
||||
"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",
|
||||
"tier": "Unique",
|
||||
|
@ -42560,32 +42482,6 @@
|
|||
"tDamPct": 6,
|
||||
"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",
|
||||
"tier": "Rare",
|
||||
|
@ -42740,32 +42636,6 @@
|
|||
"lvl": 75,
|
||||
"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",
|
||||
"tier": "Rare",
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
<div class="col" id="recipe-dropdown">
|
||||
<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">
|
||||
<img id = "recipe-img" class = "img-fluid rounded Crafted-shadow" src = "../media/items/new/generic-potion.png">
|
||||
<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 class = "col ps-3">
|
||||
<div class = "row row-cols-2 align-items-center">
|
||||
|
@ -283,7 +283,7 @@
|
|||
<script type="text/javascript" src="../js/query_2.js"></script>
|
||||
<script type="text/javascript" src="../js/utils.js"></script>
|
||||
<script type="text/javascript" src="../js/build_utils.js"></script>
|
||||
<script type="text/javascript" src="../js/sq2icons.js"></script>
|
||||
<script type="text/javascript" src="../js/icons.js"></script>
|
||||
<script type="text/javascript" src="../js/powders.js"></script>
|
||||
<script type="text/javascript" src="../js/skillpoints.js"></script>
|
||||
<script type="text/javascript" src="../js/damage_calc.js"></script>
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
}
|
||||
/* builder containers */
|
||||
|
||||
|
||||
.slider {
|
||||
-webkit-appearance: none;
|
||||
background: #AAAAAA;
|
||||
|
@ -46,7 +45,6 @@ input[type=range]:focus {
|
|||
outline: none; /* Removes the border. */
|
||||
}
|
||||
|
||||
|
||||
/* equipment field specifics */
|
||||
/* inputs and dropdowns */
|
||||
.form-control {
|
||||
|
@ -63,6 +61,7 @@ ul.search-box {
|
|||
position: absolute;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
li.search-item {
|
||||
|
@ -102,10 +101,15 @@ input.equipment-input {
|
|||
font-weight: bold;
|
||||
background-color: hsl(0, 0%, 21%) !important;
|
||||
border-radius: 0.375rem !important;
|
||||
border-color: rgba(33, 37, 41, 1) !important;
|
||||
min-height: calc(1.2 * var(--scaled-fontsize) + 2px);
|
||||
padding: 0rem 0.5rem;
|
||||
font-size: var(--scaled-fontsize);
|
||||
--bs-gutter-y: 1rem;
|
||||
--bs-gutter-x: 3rem
|
||||
}
|
||||
|
||||
input.equipment-input:not(.is-invalid) {
|
||||
border-color: rgba(33, 37, 41, 1) !important;
|
||||
}
|
||||
|
||||
.my-container {
|
||||
|
@ -174,11 +178,11 @@ input.equipment-input {
|
|||
}
|
||||
|
||||
.scaled-item-icon {
|
||||
width: 8rem;
|
||||
width: 6rem;
|
||||
}
|
||||
|
||||
.scaled-item-icon img {
|
||||
width: 6.5rem;
|
||||
width: 6rem;
|
||||
}
|
||||
|
||||
.scaled-bckgrd {
|
||||
|
@ -187,13 +191,28 @@ input.equipment-input {
|
|||
}
|
||||
|
||||
.scaled-bckgrd img {
|
||||
width: 6.5rem;
|
||||
width: 7rem;
|
||||
}
|
||||
|
||||
.overall-box {
|
||||
max-width: 95%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1200px) and (max-width: 1400px) {
|
||||
:root {
|
||||
--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 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
@ -219,11 +238,11 @@ input.equipment-input {
|
|||
}
|
||||
|
||||
.scaled-item-icon {
|
||||
width: 3.2rem;
|
||||
width: 2.6rem;
|
||||
}
|
||||
|
||||
.scaled-item-icon img {
|
||||
width: 2.8rem;
|
||||
width: 2.2rem;
|
||||
}
|
||||
|
||||
.scaled-bckgrd {
|
||||
|
@ -248,6 +267,17 @@ input.equipment-input {
|
|||
:root {
|
||||
--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 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
@ -273,11 +303,11 @@ input.equipment-input {
|
|||
}
|
||||
|
||||
.scaled-item-icon {
|
||||
width: 4rem;
|
||||
width: 3.2rem;
|
||||
}
|
||||
|
||||
.scaled-item-icon img {
|
||||
width: 3.5rem;
|
||||
width: 2.7rem;
|
||||
}
|
||||
|
||||
.scaled-bckgrd {
|
||||
|
@ -289,7 +319,6 @@ input.equipment-input {
|
|||
width: 3.5rem;
|
||||
}
|
||||
|
||||
|
||||
.warning {
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
@ -460,3 +489,16 @@ a:hover {
|
|||
.ferricles{
|
||||
color: #5be553;
|
||||
}
|
||||
|
||||
.item-display-new-toggleable {
|
||||
image-rendering: pixelated;
|
||||
background-size: 1200% 100%;
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
.tome-image {
|
||||
background-image: url('../media/items/common.png');
|
||||
image-rendering: pixelated;
|
||||
background-size: 500% 100%;
|
||||
background-position: 100% 0;
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
|
|
|
@ -959,7 +959,7 @@
|
|||
</div> -->
|
||||
</div>
|
||||
<script type="text/javascript" src="../js/dev.js"></script>
|
||||
<script type="text/javascript" src="../js/sq2icons.js"></script>
|
||||
<script type="text/javascript" src="../js/icons.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -221,6 +221,6 @@
|
|||
docsFns.append(genDocEntry(entry[0], entry[1], null, entry[2]));
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="../js/sq2icons.js"></script>
|
||||
<script type="text/javascript" src="../js/icons.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
178
js/atree.js
|
@ -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:
|
||||
|
||||
|
@ -74,6 +79,7 @@ stat_bonus: {
|
|||
stat_scaling: {
|
||||
"type": "stat_scaling",
|
||||
"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_step": Optional[float],
|
||||
round: Optional[bool] // Control floor behavior. True for stats and false for slider by default
|
||||
|
@ -199,7 +205,6 @@ const atree_node = new (class extends ComputeNode {
|
|||
const atree_render = new (class extends ComputeNode {
|
||||
constructor() {
|
||||
super('builder-atree-render');
|
||||
this.fail_cb = true;
|
||||
this.UI_elem = document.getElementById("atree-ui");
|
||||
this.list_elem = document.getElementById("atree-header");
|
||||
}
|
||||
|
@ -310,7 +315,7 @@ function abil_can_activate(atree_node, atree_state, reachable, archetype_count,
|
|||
}
|
||||
let failed_deps = [];
|
||||
for (const dep_id of ability.dependencies) {
|
||||
if (!atree_state.get(dep_id).active) { failed_deps.push(dep_id) }
|
||||
if (!reachable.has(dep_id)) { failed_deps.push(dep_id) }
|
||||
}
|
||||
if (failed_deps.length > 0) {
|
||||
const dep_strings = failed_deps.map(i => '"' + atree_state.get(i).ability.display_name + '"');
|
||||
|
@ -318,7 +323,7 @@ function abil_can_activate(atree_node, atree_state, reachable, archetype_count,
|
|||
}
|
||||
let blocking_ids = [];
|
||||
for (const blocker_id of ability.blockers) {
|
||||
if (atree_state.get(blocker_id).active) { blocking_ids.push(blocker_id); }
|
||||
if (reachable.has(blocker_id)) { blocking_ids.push(blocker_id); }
|
||||
}
|
||||
if (blocking_ids.length > 0) {
|
||||
const blockers_strings = blocking_ids.map(i => '"' + atree_state.get(i).ability.display_name + '"');
|
||||
|
@ -372,11 +377,11 @@ const atree_validate = new (class extends ComputeNode {
|
|||
const abil = node.ability;
|
||||
if (atree_state.get(abil.id).active) {
|
||||
atree_to_add.push([node, 'not reachable', false]);
|
||||
atree_state.get(abil.id).img.src = '../media/atree/' + abil.display.icon + '_selected.png';
|
||||
drawAtlasImage(atree_state.get(abil.id).img, atreeNodeAtlasImg, [atreeNodeAtlasPositions[abil.display.icon], 2], atreeNodeTileSize);
|
||||
}
|
||||
else {
|
||||
atree_not_present.push(abil.id);
|
||||
atree_state.get(abil.id).img.src = '../media/atree/' + abil.display.icon + '_blocked.png';
|
||||
drawAtlasImage(atree_state.get(abil.id).img, atreeNodeAtlasImg, [atreeNodeAtlasPositions[abil.display.icon], 0], atreeNodeTileSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,7 +430,7 @@ const atree_validate = new (class extends ComputeNode {
|
|||
const node = atree_state.get(node_id);
|
||||
const [success, hard_error, reason] = abil_can_activate(node, atree_state, reachable, archetype_count, ap_left);
|
||||
if (success) {
|
||||
node.img.src = '../media/atree/'+node.ability.display.icon+'.png';
|
||||
drawAtlasImage(node.img, atreeNodeAtlasImg, [atreeNodeAtlasPositions[node.ability.display.icon], 1], atreeNodeTileSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -739,12 +744,29 @@ const atree_scaling = new (class extends ComputeNode {
|
|||
|
||||
for (const effect of abil.effects) {
|
||||
switch (effect.type) {
|
||||
case 'raw_stat':
|
||||
// TODO: toggles...
|
||||
if (effect.toggle) {
|
||||
const button = button_map.get(effect.toggle).button;
|
||||
if (!button.classList.contains("toggleOn")) { continue; }
|
||||
for (const bonus of effect.bonuses) {
|
||||
const { type, name, abil = "", value } = bonus;
|
||||
// TODO: prop
|
||||
if (type === "stat") {
|
||||
merge_stat(ret_effects, name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case 'stat_scaling':
|
||||
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) {
|
||||
const slider_val = slider_map.get(effect.slider_name).slider.value;
|
||||
total = parseInt(slider_val) * scaling[0];
|
||||
round = false;
|
||||
positive = false;
|
||||
}
|
||||
else {
|
||||
// TODO: type: prop?
|
||||
|
@ -755,7 +777,7 @@ const atree_scaling = new (class extends ComputeNode {
|
|||
|
||||
if ('output' in effect) { // sometimes nodes will modify slider without having effect.
|
||||
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 (Array.isArray(effect.output)) {
|
||||
for (const output of effect.output) {
|
||||
|
@ -789,7 +811,6 @@ const atree_stats = new (class extends ComputeNode {
|
|||
|
||||
compute_func(input_map) {
|
||||
const atree_merged = input_map.get('atree-merged');
|
||||
const [slider_map, button_map] = input_map.get('atree-interactive');
|
||||
|
||||
let ret_effects = new Map();
|
||||
for (const [abil_id, abil] of atree_merged.entries()) {
|
||||
|
@ -798,11 +819,8 @@ const atree_stats = new (class extends ComputeNode {
|
|||
for (const effect of abil.effects) {
|
||||
switch (effect.type) {
|
||||
case 'raw_stat':
|
||||
// TODO: toggles...
|
||||
if (effect.toggle) {
|
||||
const button = button_map.get(effect.toggle).button;
|
||||
if (!button.classList.contains("toggleOn")) { continue; }
|
||||
}
|
||||
// toggles are handled in atree_scaling.
|
||||
if (effect.toggle) { continue; }
|
||||
for (const bonus of effect.bonuses) {
|
||||
const { type, name, abil = "", value } = bonus;
|
||||
// TODO: prop
|
||||
|
@ -816,7 +834,7 @@ const atree_stats = new (class extends ComputeNode {
|
|||
}
|
||||
return ret_effects;
|
||||
}
|
||||
})().link_to(atree_merge, 'atree-merged').link_to(atree_make_interactives, 'atree-interactive');
|
||||
})().link_to(atree_merge, 'atree-merged');
|
||||
|
||||
/**
|
||||
* Construct compute nodes to link builder items and edit IDs to the appropriate display outputs.
|
||||
|
@ -966,8 +984,8 @@ function render_AT(UI_elem, list_elem, tree) {
|
|||
let parent_abil = parent.ability;
|
||||
const parent_id = parent_abil.id;
|
||||
|
||||
let connect_elem = document.createElement("div");
|
||||
connect_elem.style = "background-size: cover; width: 200%; height: 200%; position: absolute; top: -50%; left: -50%; image-rendering: pixelated;";
|
||||
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 up
|
||||
for (let i = ability.display.row - 1; i > parent_abil.display.row; i--) {
|
||||
const coord = i + "," + ability.display.col;
|
||||
|
@ -1002,17 +1020,9 @@ function render_AT(UI_elem, list_elem, tree) {
|
|||
}
|
||||
|
||||
// create node
|
||||
let node_elem = document.createElement('div');
|
||||
let icon = ability.display.icon;
|
||||
if (icon === undefined) {
|
||||
icon = "node";
|
||||
}
|
||||
let node_img = document.createElement('img');
|
||||
node_img.src = '../media/atree/'+icon+'.png';
|
||||
node_img.style = "width: 200%; height: 200%; position: absolute; top: -50%; left: -50%; image-rendering: pixelated; z-index: 1;";
|
||||
node_elem.appendChild(node_img);
|
||||
|
||||
node_wrap.img = node_img;
|
||||
let node_elem = document.getElementById("atree-row-" + ability.display.row).children[ability.display.col];
|
||||
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);
|
||||
|
||||
// create hitbox
|
||||
// this is necessary since images exceed the size of their square, but should only be interactible within that square
|
||||
|
@ -1050,8 +1060,6 @@ function render_AT(UI_elem, list_elem, tree) {
|
|||
delete node_wrap.tooltip_elem;
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("atree-row-" + ability.display.row).children[ability.display.col].appendChild(node_elem);
|
||||
};
|
||||
atree_render_connection(atree_connectors_map);
|
||||
|
||||
|
@ -1227,26 +1235,6 @@ function set_connector_type(connector_info) { // left right up down
|
|||
}
|
||||
}
|
||||
|
||||
// draw the connector onto the screen
|
||||
function atree_render_connection(atree_connectors_map) {
|
||||
for (let i of atree_connectors_map.keys()) {
|
||||
let connector_info = atree_connectors_map.get(i);
|
||||
let connector_elem = connector_info.connector;
|
||||
let connector_img = document.createElement('img');
|
||||
set_connector_type(connector_info);
|
||||
connector_img.src = '../media/atree/connect_'+connector_info.type+'.png';
|
||||
connector_img.style = "width: 100%; height: 100%;"
|
||||
connector_elem.replaceChildren(connector_img);
|
||||
connector_info.highlight = [0, 0, 0, 0];
|
||||
let target_elem = document.getElementById("atree-row-" + i.split(",")[0]).children[i.split(",")[1]];
|
||||
if (target_elem.children.length != 0) {
|
||||
// janky special case...
|
||||
connector_elem.style.display = 'none';
|
||||
}
|
||||
target_elem.appendChild(connector_elem);
|
||||
};
|
||||
};
|
||||
|
||||
// toggle the state of a node.
|
||||
function atree_set_state(node_wrapper, new_state) {
|
||||
let icon = node_wrapper.ability.display.icon;
|
||||
|
@ -1255,11 +1243,11 @@ function atree_set_state(node_wrapper, new_state) {
|
|||
}
|
||||
if (new_state) {
|
||||
node_wrapper.active = true;
|
||||
node_wrapper.elem.children[0].src = "../media/atree/" + icon + "_selected.png";
|
||||
drawAtlasImage(node_wrapper.img, atreeNodeAtlasImg, [atreeNodeAtlasPositions[icon], 2], atreeNodeTileSize);
|
||||
}
|
||||
else {
|
||||
node_wrapper.active = false;
|
||||
node_wrapper.elem.children[0].src = "../media/atree/" + icon + ".png";
|
||||
drawAtlasImage(node_wrapper.img, atreeNodeAtlasImg, [atreeNodeAtlasPositions[icon], 1], atreeNodeTileSize);
|
||||
}
|
||||
let atree_connectors_map = node_wrapper.all_connectors_ref;
|
||||
for (const parent of node_wrapper.parents) {
|
||||
|
@ -1274,6 +1262,64 @@ 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
|
||||
const atreeConnectorAtlasPositions = {
|
||||
"1100": {"0000": [0, 0], "1100": [1, 0]},
|
||||
"1010": {"0000": [2, 0], "1010": [3, 0]},
|
||||
"0110": {"0000": [4, 0], "0110": [5, 0]},
|
||||
"1001": {"0000": [6, 0], "1001": [7, 0]},
|
||||
"0101": {"0000": [8, 0], "0101": [9, 0]},
|
||||
"0011": {"0000": [10, 0], "0011": [11, 0]},
|
||||
"1101": {"0000": [0, 1], "1101": [1, 1], "1100": [2, 1], "1001": [3, 1], "0101": [4, 1]},
|
||||
"0111": {"0000": [5, 1], "0111": [6, 1], "0110": [7, 1], "0101": [8, 1], "0011": [9, 1]},
|
||||
"1110": {"0000": [0, 2], "1110": [1, 2], "1100": [2, 2], "1010": [3, 2], "0110": [4, 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]}
|
||||
}
|
||||
const atreeConnectorTileSize = 18;
|
||||
const atreeConnectorAtlasImg = make_elem("img", [], {src: "../media/atree/connectors.png"});
|
||||
|
||||
// just has the x position, y is based on state
|
||||
const atreeNodeAtlasPositions = {
|
||||
"node_0": 0,
|
||||
"node_1": 1,
|
||||
"node_2": 2,
|
||||
"node_3": 3,
|
||||
"node_archer": 4,
|
||||
"node_warrior": 5,
|
||||
"node_mage": 6,
|
||||
"node_assassin": 7,
|
||||
"node_shaman": 8
|
||||
}
|
||||
const atreeNodeTileSize = 32;
|
||||
const atreeNodeAtlasImg = make_elem("img", [], {src: "../media/atree/icons.png"});
|
||||
|
||||
function drawAtlasImage(canvas, img, pos, tileSize) {
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.clearRect(0, 0, tileSize, tileSize);
|
||||
ctx.drawImage(img, tileSize * pos[0], tileSize * pos[1], tileSize, tileSize, 0, 0, tileSize, tileSize);
|
||||
}
|
||||
|
||||
// draw the connector onto the screen
|
||||
function atree_render_connection(atree_connectors_map) {
|
||||
for (let i of atree_connectors_map.keys()) {
|
||||
let connector_info = atree_connectors_map.get(i);
|
||||
let connector_elem = connector_info.connector;
|
||||
set_connector_type(connector_info);
|
||||
connector_info.highlight = [0, 0, 0, 0];
|
||||
drawAtlasImage(connector_elem, atreeConnectorAtlasImg, atreeConnectorAtlasPositions[connector_info.type]["0000"], atreeConnectorTileSize);
|
||||
let target_elem = document.getElementById("atree-row-" + i.split(",")[0]).children[i.split(",")[1]];
|
||||
if (target_elem.children.length != 0) {
|
||||
// janky special case...
|
||||
connector_elem.style.display = 'none';
|
||||
}
|
||||
target_elem.appendChild(connector_elem);
|
||||
};
|
||||
};
|
||||
|
||||
// update the connector (after being drawn the first time by atree_render_connection)
|
||||
function atree_set_edge(atree_connectors_map, parent, child, state) {
|
||||
const connectors = child.connectors.get(parent);
|
||||
const parent_row = parent.ability.display.row;
|
||||
|
@ -1288,8 +1334,6 @@ function atree_set_edge(atree_connectors_map, parent, child, state) {
|
|||
let connector_info = atree_connectors_map.get(connector_label);
|
||||
let connector_elem = connector_info.connector;
|
||||
let highlight_state = connector_info.highlight; // left right up down
|
||||
let connector_img_elem = document.createElement("img");
|
||||
connector_img_elem.style = "width: 100%; height: 100%;";
|
||||
const ctype = connector_info.type;
|
||||
let num_1s = 0;
|
||||
for (let i = 0; i < 4; i++) {
|
||||
|
@ -1317,23 +1361,17 @@ function atree_set_edge(atree_connectors_map, parent, child, state) {
|
|||
for (let i = 0; i < 4; i++) {
|
||||
render += highlight_state[i] === 0 ? "0" : "1";
|
||||
}
|
||||
if (render == "0000") {
|
||||
connector_img_elem.src = "../media/atree/connect_" + ctype + ".png";
|
||||
} else {
|
||||
connector_img_elem.src = "../media/atree/connect_" + ctype + "_" + render + ".png";
|
||||
}
|
||||
connector_elem.replaceChildren(connector_img_elem);
|
||||
drawAtlasImage(connector_elem, atreeConnectorAtlasImg, atreeConnectorAtlasPositions[ctype][render], atreeConnectorTileSize);
|
||||
// connector_elem.style.backgroundPosition = atlasBGPositionCalc(atreeConnectorAtlasPositions[ctype][render], atreeConnectorAtlasSize);
|
||||
continue;
|
||||
}
|
||||
// lol bad overloading, [0] is just the whole state
|
||||
highlight_state[0] += state_delta;
|
||||
if (highlight_state[0] > 0) {
|
||||
connector_img_elem.src = '../media/atree/connect_' + ctype + '_1.png';
|
||||
connector_elem.replaceChildren(connector_img_elem);
|
||||
}
|
||||
else {
|
||||
connector_img_elem.src = '../media/atree/connect_'+ctype+'.png';
|
||||
connector_elem.replaceChildren(connector_img_elem);
|
||||
} else {
|
||||
// lol bad overloading, [0] is just the whole state
|
||||
highlight_state[0] += state_delta;
|
||||
if (highlight_state[0] > 0) {
|
||||
drawAtlasImage(connector_elem, atreeConnectorAtlasImg, atreeConnectorAtlasPositions[ctype][ctype], atreeConnectorTileSize);
|
||||
} else {
|
||||
drawAtlasImage(connector_elem, atreeConnectorAtlasImg, atreeConnectorAtlasPositions[ctype]["0000"], atreeConnectorTileSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ const atrees = {
|
|||
"base_spell": 1,
|
||||
"target_part": "Single Arrow",
|
||||
"multipliers": [
|
||||
-15,
|
||||
-10,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
@ -3715,7 +3715,7 @@ const atrees = {
|
|||
|
||||
{
|
||||
"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_req": 0,
|
||||
"base_abil": "Bak'al's Grasp",
|
||||
|
@ -3739,7 +3739,7 @@ const atrees = {
|
|||
"type": "stat",
|
||||
"name": "damMult.Enraged"
|
||||
},
|
||||
"scaling": [3]
|
||||
"scaling": [2.2]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -3966,7 +3966,7 @@ const atrees = {
|
|||
|
||||
{
|
||||
"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_req": 5,
|
||||
"base_abil": "Bak'al's Grasp",
|
||||
|
@ -4277,7 +4277,7 @@ const atrees = {
|
|||
"parts": [
|
||||
{
|
||||
"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
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"desc": "Incrase your maximum Winded by +5.",
|
||||
"desc": "Increase your maximum Winded by +5.",
|
||||
"base_abil": "Windsweeper",
|
||||
"archetype": "Riftwalker",
|
||||
"archetype_req": 0,
|
||||
|
@ -6705,7 +6691,7 @@ const atrees = {
|
|||
},
|
||||
{
|
||||
"display_name": "More Winded II",
|
||||
"desc": "Incrase your maximum Winded by +5.",
|
||||
"desc": "Increase your maximum Winded by +5.",
|
||||
"base_abil": "Windsweeper",
|
||||
"archetype": "Riftwalker",
|
||||
"archetype_req": 0,
|
||||
|
@ -7665,21 +7651,14 @@ const atrees = {
|
|||
"type": "replace_spell",
|
||||
"name": "Backstab",
|
||||
"base_spell": 3,
|
||||
"display": "Total Damage",
|
||||
"display": "Backstab Damage",
|
||||
"parts": [
|
||||
{
|
||||
"name": "Per Hit",
|
||||
"name": "Backstab Damage",
|
||||
"type": "damage",
|
||||
"multipliers": [
|
||||
200, 50, 0, 0, 0, 0
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Total Damage",
|
||||
"type": "total",
|
||||
"hits": {
|
||||
"Per Hit": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -9139,8 +9118,23 @@ const atrees = {
|
|||
"bonuses": [
|
||||
{
|
||||
"type": "stat",
|
||||
"name": "dmgMult.Satsujin",
|
||||
"value": 300
|
||||
"name": "damMult.Satsujin:3.Backstab Damage",
|
||||
"value": 200
|
||||
},
|
||||
{
|
||||
"type": "stat",
|
||||
"name": "damMult.Satsujin:3.Per Hit",
|
||||
"value": 200
|
||||
},
|
||||
{
|
||||
"type": "stat",
|
||||
"name": "damMult.Satsujin:3.Fatality",
|
||||
"value": 200
|
||||
},
|
||||
{
|
||||
"type": "stat",
|
||||
"name": "damMult.Satsujin:0.Melee",
|
||||
"value": 200
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
21
js/build.js
|
@ -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]]);
|
||||
|
||||
|
@ -10,15 +15,9 @@ class Build{
|
|||
/**
|
||||
* @description Construct a build.
|
||||
* @param {Number} level : Level of the player.
|
||||
* @param {String[]} equipment : List of equipment names that make up the build.
|
||||
* In order: boots, Chestplate, Leggings, Boots, Ring1, Ring2, Brace, Neck, Weapon.
|
||||
* @param {Number[]} powders : Powder application. List of lists of integers (powder IDs).
|
||||
* 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)
|
||||
* @param {String[]} items: List of equipment names that make up the build.
|
||||
* In order: Helmet, Chestplate, Leggings, Boots, Ring1, Ring2, Brace, Neck, Tomes [x7].
|
||||
* @param {Item} weapon: Weapon that this build is using.
|
||||
*/
|
||||
constructor(level, items, weapon){
|
||||
|
||||
|
@ -39,7 +38,6 @@ class Build{
|
|||
this.equipment = items;
|
||||
this.weapon = weapon;
|
||||
this.items = this.equipment.concat([this.weapon]);
|
||||
// return [equip_order, best_skillpoints, final_skillpoints, best_total];
|
||||
|
||||
// calc skillpoints requires statmaps only
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
|
|
@ -232,7 +232,13 @@ function shareBuild(build) {
|
|||
"> "+build.items[5].statMap.get("displayName")+"\n"+
|
||||
"> "+build.items[6].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);
|
||||
document.getElementById("share-button").textContent = "Copied!";
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
* @param skp - the integer skillpoint count to be converted
|
||||
*/
|
||||
|
@ -231,8 +235,15 @@ function expandItem(item) {
|
|||
}
|
||||
|
||||
class Item {
|
||||
constructor(item_obj) {
|
||||
this.statMap = expandItem(item_obj);
|
||||
constructor(item_obj = null) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
const buildList = document.getElementById("build-choice");
|
||||
|
@ -124,7 +127,7 @@ function toggleButton(button_id) {
|
|||
}
|
||||
}
|
||||
|
||||
// toggle tab
|
||||
// Toggles display of a certain element, given the ID.
|
||||
function toggle_tab(tab) {
|
||||
if (document.querySelector("#"+tab).style.display == "none") {
|
||||
document.querySelector("#"+tab).style.display = "";
|
||||
|
@ -133,24 +136,16 @@ function toggle_tab(tab) {
|
|||
}
|
||||
}
|
||||
|
||||
function toggle_boost_tab(tab) {
|
||||
for (const i of skp_order) {
|
||||
document.querySelector("#"+i+"-boost").style.display = "none";
|
||||
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) {
|
||||
// Toggle display of a certain tab, in a group of tabs, given the target tab ID, and a list of associated tabs.
|
||||
// Also sets visual display of an element with ID of target + "-btn" to selected.
|
||||
function show_tab(target, tabs) {
|
||||
//hide all tabs, then show the tab of the div clicked and highlight the correct button
|
||||
for (const i in tabs) {
|
||||
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.getElementById("tab-" + tab.split("-")[0] + "-btn").classList.add("selected-btn");
|
||||
document.querySelector("#" + target).style.display = "";
|
||||
document.getElementById(target + "-btn").classList.add("selected-btn");
|
||||
}
|
||||
|
||||
// autocomplete initialize
|
||||
|
@ -239,8 +234,9 @@ function init_autocomplete() {
|
|||
for (const eq of tome_keys) {
|
||||
// build dropdown
|
||||
let tome_arr = [];
|
||||
for (const tome of tomeLists.get(eq.replace(/[0-9]/g, ''))) {
|
||||
let tome_obj = tomeMap.get(tome);
|
||||
let tome_aliases = new Map();
|
||||
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") {
|
||||
continue;
|
||||
}
|
||||
|
@ -248,8 +244,10 @@ function init_autocomplete() {
|
|||
if (tome_obj["name"].includes('No ' + eq.charAt(0).toUpperCase())) {
|
||||
continue;
|
||||
}
|
||||
let tome_name = tome;
|
||||
let tome_alias = tome_obj['alias'];
|
||||
tome_arr.push(tome_name);
|
||||
tome_arr.push(tome_alias);
|
||||
tome_aliases.set(tome_alias, tome_name);
|
||||
}
|
||||
|
||||
// create dropdown
|
||||
|
@ -284,14 +282,18 @@ function init_autocomplete() {
|
|||
class: "scaled-font search-item",
|
||||
selected: "dark-5",
|
||||
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: {
|
||||
input: {
|
||||
selection: (event) => {
|
||||
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'));
|
||||
},
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/**
|
||||
* File containing compute graph structure of the builder page.
|
||||
*/
|
||||
|
||||
let armor_powder_node = new (class extends ComputeNode {
|
||||
constructor() { super('builder-armor-powder-input'); }
|
||||
|
||||
|
@ -121,7 +125,7 @@ class PowderSpecialDisplayNode extends ComputeNode {
|
|||
/**
|
||||
* Node for getting an item's stats from an item input field.
|
||||
*
|
||||
* Signature: ItemInputNode(powdering: Optional[list[powder]]) => Item | null
|
||||
* Signature: ItemInputNode() => Item | null
|
||||
*/
|
||||
class ItemInputNode extends InputNode {
|
||||
/**
|
||||
|
@ -143,8 +147,6 @@ class ItemInputNode extends InputNode {
|
|||
}
|
||||
|
||||
compute_func(input_map) {
|
||||
const powdering = input_map.get('powdering');
|
||||
|
||||
// built on the assumption of no one will type in CI/CR letter by letter
|
||||
let item_text = this.input_field.value;
|
||||
if (!item_text) {
|
||||
|
@ -158,10 +160,6 @@ class ItemInputNode extends InputNode {
|
|||
else if (tomeMap.has(item_text)) { item = new Item(tomeMap.get(item_text)); }
|
||||
|
||||
if (item) {
|
||||
if (powdering !== undefined) {
|
||||
const max_slots = item.statMap.get('slots');
|
||||
item.statMap.set('powders', powdering.slice(0, max_slots));
|
||||
}
|
||||
let type_match;
|
||||
if (this.category == 'weapon') {
|
||||
type_match = item.statMap.get('category') == 'weapon';
|
||||
|
@ -169,12 +167,6 @@ class ItemInputNode extends InputNode {
|
|||
type_match = item.statMap.get('type') == this.none_item.statMap.get('type');
|
||||
}
|
||||
if (type_match) {
|
||||
if (item.statMap.get('category') == 'armor') {
|
||||
applyArmorPowders(item.statMap);
|
||||
}
|
||||
else if (item.statMap.get('category') == 'weapon') {
|
||||
apply_weapon_powders(item.statMap);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
@ -205,6 +197,31 @@ class ItemInputNode extends InputNode {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Node for updating item input fields from parsed items.
|
||||
*
|
||||
* Signature: ItemInputDisplayNode(item: Item, powdering: List[powder]) => Item
|
||||
*/
|
||||
class ItemPowderingNode extends ComputeNode {
|
||||
constructor(name) { super(name); }
|
||||
|
||||
compute_func(input_map) {
|
||||
const powdering = input_map.get('powdering');
|
||||
const input_item = input_map.get('item');
|
||||
const item = input_item.copy(); // TODO: performance
|
||||
|
||||
const max_slots = item.statMap.get('slots');
|
||||
item.statMap.set('powders', powdering.slice(0, max_slots));
|
||||
if (item.statMap.get('category') == 'armor') {
|
||||
applyArmorPowders(item.statMap);
|
||||
}
|
||||
else if (item.statMap.get('category') == 'weapon') {
|
||||
apply_weapon_powders(item.statMap);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Node for updating item input fields from parsed items.
|
||||
*
|
||||
|
@ -217,7 +234,6 @@ class ItemInputDisplayNode extends ComputeNode {
|
|||
this.input_field = document.getElementById(eq+"-choice");
|
||||
this.health_field = document.getElementById(eq+"-health");
|
||||
this.level_field = document.getElementById(eq+"-lv");
|
||||
this.powder_field = document.getElementById(eq+"-powder"); // possibly None
|
||||
this.image = item_image;
|
||||
this.fail_cb = true;
|
||||
}
|
||||
|
@ -242,18 +258,11 @@ class ItemInputDisplayNode extends ComputeNode {
|
|||
this.input_field.classList.add("is-invalid");
|
||||
return null;
|
||||
}
|
||||
if (this.powder_field && item.statMap.has('powders')) {
|
||||
this.powder_field.placeholder = "powders";
|
||||
}
|
||||
|
||||
if (item.statMap.has('NONE')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.powder_field && item.statMap.has('powders')) {
|
||||
this.powder_field.placeholder = item.statMap.get('slots') + ' slots';
|
||||
}
|
||||
|
||||
const tier = item.statMap.get('tier');
|
||||
this.input_field.classList.add(tier);
|
||||
if (this.health_field) {
|
||||
|
@ -307,7 +316,8 @@ class WeaponInputDisplayNode extends ComputeNode {
|
|||
const [item] = input_map.values(); // Extract values, pattern match it into size one list and bind to first element
|
||||
|
||||
const type = item.statMap.get('type');
|
||||
this.image.setAttribute('src', '../media/items/new/generic-'+type+'.png');
|
||||
this.image.style.backgroundPosition = itemBGPositions[type];
|
||||
|
||||
let dps = get_base_dps(item.statMap);
|
||||
if (isNaN(dps)) {
|
||||
dps = dps[1];
|
||||
|
@ -374,39 +384,39 @@ class URLUpdateNode extends ComputeNode {
|
|||
* Create a "build" object from a set of equipments.
|
||||
* Returns a new Build object, or null if all items are NONE items.
|
||||
*
|
||||
* Signature: BuildAssembleNode(helmet-input: Item,
|
||||
* chestplate-input: Item,
|
||||
* leggings-input: Item,
|
||||
* boots-input: Item,
|
||||
* ring1-input: Item,
|
||||
* ring2-input: Item,
|
||||
* bracelet-input: Item,
|
||||
* necklace-input: Item,
|
||||
* weapon-input: Item,
|
||||
* level-input: int) => Build | null
|
||||
* Signature: BuildAssembleNode(helmet: Item,
|
||||
* chestplate: Item,
|
||||
* leggings: Item,
|
||||
* boots: Item,
|
||||
* ring1: Item,
|
||||
* ring2: Item,
|
||||
* bracelet: Item,
|
||||
* necklace: Item,
|
||||
* weapon: Item,
|
||||
* level: int) => Build | null
|
||||
*/
|
||||
class BuildAssembleNode extends ComputeNode {
|
||||
constructor() { super("builder-make-build"); }
|
||||
|
||||
compute_func(input_map) {
|
||||
let equipments = [
|
||||
input_map.get('helmet-input'),
|
||||
input_map.get('chestplate-input'),
|
||||
input_map.get('leggings-input'),
|
||||
input_map.get('boots-input'),
|
||||
input_map.get('ring1-input'),
|
||||
input_map.get('ring2-input'),
|
||||
input_map.get('bracelet-input'),
|
||||
input_map.get('necklace-input'),
|
||||
input_map.get('weaponTome1-input'),
|
||||
input_map.get('weaponTome2-input'),
|
||||
input_map.get('armorTome1-input'),
|
||||
input_map.get('armorTome2-input'),
|
||||
input_map.get('armorTome3-input'),
|
||||
input_map.get('armorTome4-input'),
|
||||
input_map.get('guildTome1-input')
|
||||
input_map.get('helmet'),
|
||||
input_map.get('chestplate'),
|
||||
input_map.get('leggings'),
|
||||
input_map.get('boots'),
|
||||
input_map.get('ring1'),
|
||||
input_map.get('ring2'),
|
||||
input_map.get('bracelet'),
|
||||
input_map.get('necklace'),
|
||||
input_map.get('weaponTome1'),
|
||||
input_map.get('weaponTome2'),
|
||||
input_map.get('armorTome1'),
|
||||
input_map.get('armorTome2'),
|
||||
input_map.get('armorTome3'),
|
||||
input_map.get('armorTome4'),
|
||||
input_map.get('guildTome1')
|
||||
];
|
||||
let weapon = input_map.get('weapon-input');
|
||||
let weapon = input_map.get('weapon');
|
||||
let level = parseInt(input_map.get('level-input'));
|
||||
if (isNaN(level)) {
|
||||
level = 106;
|
||||
|
@ -429,6 +439,7 @@ class PlayerClassNode extends ValueCheckComputeNode {
|
|||
compute_func(input_map) {
|
||||
if (input_map.size !== 1) { throw "PlayerClassNode accepts exactly one input (build)"; }
|
||||
const [build] = input_map.values(); // Extract values, pattern match it into size one list and bind to first element
|
||||
if (build.weapon.statMap.has('NONE')) { return null; }
|
||||
return wep_to_class.get(build.weapon.statMap.get('type'));
|
||||
}
|
||||
}
|
||||
|
@ -437,15 +448,25 @@ class PlayerClassNode extends ValueCheckComputeNode {
|
|||
* Read an input field and parse into a list of powderings.
|
||||
* Every two characters makes one powder. If parsing fails, NULL is returned.
|
||||
*
|
||||
* Signature: PowderInputNode() => List[powder] | null
|
||||
* Signature: PowderInputNode(item: Item) => List[powder] | null
|
||||
*/
|
||||
class PowderInputNode extends InputNode {
|
||||
|
||||
constructor(name, input_field) { super(name, input_field); }
|
||||
constructor(name, input_field) { super(name, input_field); this.fail_cb = true; }
|
||||
|
||||
compute_func(input_map) {
|
||||
if (input_map.size !== 1) { throw "PowderInputNode accepts exactly one input (item)"; }
|
||||
const [item] = input_map.values(); // Extract values, pattern match it into size one list and bind to first element
|
||||
if (item === null) {
|
||||
this.input_field.placeholder = 'powders';
|
||||
return [];
|
||||
}
|
||||
|
||||
if (item.statMap.has('slots')) {
|
||||
this.input_field.placeholder = item.statMap.get('slots') + ' slots';
|
||||
}
|
||||
|
||||
// TODO: haha improve efficiency to O(n) dumb
|
||||
// also, error handling is missing
|
||||
let input = this.input_field.value.trim();
|
||||
let powdering = [];
|
||||
let errorederrors = [];
|
||||
|
@ -453,12 +474,29 @@ class PowderInputNode extends InputNode {
|
|||
let first = input.slice(0, 2);
|
||||
let powder = powderIDs.get(first);
|
||||
if (powder === undefined) {
|
||||
return null;
|
||||
if (first.length > 0) {
|
||||
errorederrors.push(first);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
powdering.push(powder);
|
||||
}
|
||||
input = input.slice(2);
|
||||
}
|
||||
|
||||
if (this.input_field.getAttribute("placeholder") != null) {
|
||||
if (item.statMap.get('slots') < powdering.length) {
|
||||
errorederrors.push("Too many powders: " + powdering.length);
|
||||
}
|
||||
}
|
||||
|
||||
if (errorederrors.length) {
|
||||
this.input_field.classList.add("is-invalid");
|
||||
} else {
|
||||
this.input_field.classList.remove("is-invalid");
|
||||
}
|
||||
|
||||
return powdering;
|
||||
}
|
||||
}
|
||||
|
@ -671,11 +709,11 @@ class BuildDisplayNode extends ComputeNode {
|
|||
compute_func(input_map) {
|
||||
const build = input_map.get('build');
|
||||
const stats = input_map.get('stats');
|
||||
displayBuildStats('overall-stats', build, build_all_display_commands, stats);
|
||||
displayBuildStats("offensive-stats", build, build_offensive_display_commands, stats);
|
||||
displayBuildStats('summary-stats', build, build_overall_display_commands, stats);
|
||||
displayBuildStats("detailed-stats", build, build_detailed_display_commands, stats);
|
||||
displaySetBonuses("set-info", build);
|
||||
// TODO: move weapon out?
|
||||
displayDefenseStats(document.getElementById("defensive-stats"), stats);
|
||||
// displayDefenseStats(document.getElementById("defensive-stats"), stats);
|
||||
|
||||
displayPoisonDamage(document.getElementById("build-poison-stats"), build);
|
||||
displayEquipOrder(document.getElementById("build-order"), build.equip_order);
|
||||
|
@ -702,7 +740,7 @@ class DisplayBuildWarningsNode extends ComputeNode {
|
|||
input_map.get('def'),
|
||||
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;
|
||||
for (let i in skp_order){ //big bren
|
||||
const assigned = skillpoints[i] - base_totals[i] + min_assigned[i]
|
||||
|
@ -724,20 +762,16 @@ class DisplayBuildWarningsNode extends ComputeNode {
|
|||
|
||||
let summarybox = document.getElementById("summary-box");
|
||||
summarybox.textContent = "";
|
||||
let skpRow = document.createElement("p");
|
||||
|
||||
let remainingSkp = document.createElement("p");
|
||||
remainingSkp.classList.add("scaled-font");
|
||||
let remainingSkpTitle = document.createElement("b");
|
||||
remainingSkpTitle.textContent = "Assigned " + total_assigned + " skillpoints. Remaining skillpoints: ";
|
||||
let remainingSkp = make_elem("p", ['scaled-font', 'my-0']);
|
||||
let remainingSkpTitle = make_elem("b", [], { textContent: "Assigned " + total_assigned + " skillpoints. Remaining skillpoints: " });
|
||||
let remainingSkpContent = document.createElement("b");
|
||||
remainingSkpContent.textContent = "" + (levelToSkillPoints(build.level) - total_assigned);
|
||||
remainingSkpContent.classList.add(levelToSkillPoints(build.level) - total_assigned < 0 ? "negative" : "positive");
|
||||
|
||||
remainingSkp.appendChild(remainingSkpTitle);
|
||||
remainingSkp.appendChild(remainingSkpContent);
|
||||
remainingSkp.append(remainingSkpTitle);
|
||||
remainingSkp.append(remainingSkpContent);
|
||||
|
||||
summarybox.append(skpRow);
|
||||
summarybox.append(remainingSkp);
|
||||
if(total_assigned > levelToSkillPoints(build.level)){
|
||||
let skpWarning = document.createElement("span");
|
||||
|
@ -925,9 +959,11 @@ class SumNumberInputNode extends InputNode {
|
|||
}
|
||||
|
||||
let item_nodes = [];
|
||||
let item_nodes_map = new Map();
|
||||
let powder_nodes = [];
|
||||
let edit_input_nodes = [];
|
||||
let skp_inputs = [];
|
||||
let equip_inputs = [];
|
||||
let build_node;
|
||||
let stat_agg_node;
|
||||
let edit_agg_node;
|
||||
|
@ -936,25 +972,53 @@ let atree_graph_creator;
|
|||
function builder_graph_init() {
|
||||
// Phase 1/3: Set up item input, propagate updates, etc.
|
||||
|
||||
// Level input node.
|
||||
let level_input = new InputNode('level-input', document.getElementById('level-choice'));
|
||||
|
||||
// "Build" now only refers to equipment and level (no powders). Powders are injected before damage calculation / stat display.
|
||||
build_node = new BuildAssembleNode();
|
||||
for (const input of item_nodes) {
|
||||
}
|
||||
build_node.link_to(level_input);
|
||||
|
||||
let build_encode_node = new BuildEncodeNode();
|
||||
build_encode_node.link_to(build_node, 'build');
|
||||
|
||||
// Bind item input fields to input nodes, and some display stuff (for auto colorizing stuff).
|
||||
for (const [eq, display_elem, none_item] of zip3(equipment_fields, build_fields, none_items)) {
|
||||
let input_field = document.getElementById(eq+"-choice");
|
||||
let item_image = document.getElementById(eq+"-img");
|
||||
|
||||
let item_input = new ItemInputNode(eq+'-input', input_field, none_item);
|
||||
equip_inputs.push(item_input);
|
||||
if (powder_inputs.includes(eq+'-powder')) { // TODO: fragile
|
||||
const powder_name = eq+'-powder';
|
||||
let powder_node = new PowderInputNode(powder_name, document.getElementById(powder_name))
|
||||
.link_to(item_input, 'item');
|
||||
powder_nodes.push(powder_node);
|
||||
build_encode_node.link_to(powder_node, powder_name);
|
||||
let item_powdering = new ItemPowderingNode(eq+'-powder-apply')
|
||||
.link_to(powder_node, 'powdering').link_to(item_input, 'item');
|
||||
item_input = item_powdering;
|
||||
}
|
||||
item_nodes.push(item_input);
|
||||
item_nodes_map.set(eq, item_input);
|
||||
new ItemInputDisplayNode(eq+'-input-display', eq, item_image).link_to(item_input);
|
||||
new ItemDisplayNode(eq+'-item-display', display_elem).link_to(item_input);
|
||||
//new PrintNode(eq+'-debug').link_to(item_input);
|
||||
//document.querySelector("#"+eq+"-tooltip").setAttribute("onclick", "collapse_element('#"+ eq +"-tooltip');"); //toggle_plus_minus('" + eq + "-pm');
|
||||
build_node.link_to(item_input, eq);
|
||||
}
|
||||
|
||||
for (const [eq, none_item] of zip2(tome_fields, [none_tomes[0], none_tomes[0], none_tomes[1], none_tomes[1], none_tomes[1], none_tomes[1], none_tomes[2]])) {
|
||||
let input_field = document.getElementById(eq+"-choice");
|
||||
let item_image = document.getElementById(eq+"-img");
|
||||
|
||||
let item_input = new ItemInputNode(eq+'-input', input_field, none_item);
|
||||
equip_inputs.push(item_input);
|
||||
item_nodes.push(item_input);
|
||||
new ItemInputDisplayNode(eq+'-input-display', eq, item_image).link_to(item_input);
|
||||
build_node.link_to(item_input, eq);
|
||||
}
|
||||
|
||||
// weapon image changer node.
|
||||
|
@ -962,38 +1026,12 @@ function builder_graph_init() {
|
|||
let weapon_dps = document.getElementById("weapon-dps");
|
||||
new WeaponInputDisplayNode('weapon-type', weapon_image, weapon_dps).link_to(item_nodes[8]);
|
||||
|
||||
// Level input node.
|
||||
let level_input = new InputNode('level-input', document.getElementById('level-choice'));
|
||||
|
||||
// linking to atree verification
|
||||
atree_validate.link_to(level_input, 'level');
|
||||
|
||||
// "Build" now only refers to equipment and level (no powders). Powders are injected before damage calculation / stat display.
|
||||
build_node = new BuildAssembleNode();
|
||||
for (const input of item_nodes) {
|
||||
build_node.link_to(input);
|
||||
}
|
||||
build_node.link_to(level_input);
|
||||
|
||||
let build_encode_node = new BuildEncodeNode();
|
||||
build_encode_node.link_to(build_node, 'build');
|
||||
|
||||
let url_update_node = new URLUpdateNode();
|
||||
url_update_node.link_to(build_encode_node, 'build-str');
|
||||
|
||||
|
||||
for (const input of powder_inputs) {
|
||||
let powder_node = new PowderInputNode(input, document.getElementById(input));
|
||||
powder_nodes.push(powder_node);
|
||||
build_encode_node.link_to(powder_node, input);
|
||||
}
|
||||
|
||||
item_nodes[0].link_to(powder_nodes[0], 'powdering');
|
||||
item_nodes[1].link_to(powder_nodes[1], 'powdering');
|
||||
item_nodes[2].link_to(powder_nodes[2], 'powdering');
|
||||
item_nodes[3].link_to(powder_nodes[3], 'powdering');
|
||||
item_nodes[8].link_to(powder_nodes[4], 'powdering');
|
||||
|
||||
// Phase 2/3: Set up editable IDs, skill points; use decodeBuild() skill points, calculate damage
|
||||
|
||||
// Create one node that will be the "aggregator node" (listen to all the editable id nodes, as well as the build_node (for non editable stats) and collect them into one statmap)
|
||||
|
@ -1040,7 +1078,7 @@ function builder_graph_init() {
|
|||
// ---------------------------------------------------------------
|
||||
// Trigger the update cascade for build!
|
||||
// ---------------------------------------------------------------
|
||||
for (const input_node of item_nodes.concat(powder_nodes)) {
|
||||
for (const input_node of equip_inputs) {
|
||||
input_node.update();
|
||||
}
|
||||
armor_powder_node.update();
|
||||
|
|
|
@ -135,7 +135,7 @@ class ComputeNode {
|
|||
}
|
||||
|
||||
class ValueCheckComputeNode extends ComputeNode {
|
||||
constructor(name) { super(name); }
|
||||
constructor(name) { super(name); this.valid_val = null; }
|
||||
|
||||
/**
|
||||
* Request update of this compute node. Pushes updates to children,
|
||||
|
@ -154,14 +154,11 @@ class ValueCheckComputeNode extends ComputeNode {
|
|||
calc_inputs.set(this.input_translation.get(input.name), input.value);
|
||||
}
|
||||
let val = this.compute_func(calc_inputs);
|
||||
if (val !== this.value) {
|
||||
super.mark_dirty(2);
|
||||
}
|
||||
else {
|
||||
console.log("soft update");
|
||||
if (val !== null) {
|
||||
if (val !== this.valid_val) { super.mark_dirty(2); } // don't mark dirty if NULL (no update)
|
||||
this.valid_val = val;
|
||||
}
|
||||
this.value = val;
|
||||
|
||||
this.dirty = 0;
|
||||
for (const child of this.children) {
|
||||
child.mark_input_clean(this.name, this.value);
|
||||
|
|
|
@ -397,4 +397,8 @@ class Craft{
|
|||
statMap.set("crafted", true);
|
||||
this.statMap = statMap;
|
||||
}
|
||||
|
||||
copy() {
|
||||
return new Craft(this.recipe, this.mat_tiers, this.ingreds, this.atkSpd, this.hash.slice(3));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -345,9 +345,16 @@ function toggleMaterial(buttonId) {
|
|||
function updateCraftedImage() {
|
||||
let input = document.getElementById("recipe-choice");
|
||||
if (all_types.includes(input.value)) {
|
||||
document.getElementById("recipe-img").src = "../media/items/" + (newIcons ? "new/":"old/") + "generic-" + input.value.toLowerCase() + ".png";
|
||||
let img = document.getElementById("recipe-img");
|
||||
if (["potion", "scroll", "food"].includes(input.value.toLowerCase())) {
|
||||
img.style.backgroundImage = "url('../media/items/common.png')";
|
||||
img.style.backgroundSize = "500% 100%";
|
||||
} else {
|
||||
img.style.backgroundImage = "url('../media/items/" + (newIcons ? "new.png')" : "old.png')");
|
||||
img.style.backgroundSize = "1200% 100%";
|
||||
}
|
||||
img.style.backgroundPosition = itemBGPositions[input.value.toLowerCase()]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Reset all fields
|
||||
|
|
|
@ -336,4 +336,7 @@ class Custom {
|
|||
this.statMap.set("restrict", "Custom Item")
|
||||
}
|
||||
|
||||
copy() {
|
||||
return new Custom(new Map(this.statMap));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
const attack_speed_mult = baseDamageMultiplier[attackSpeeds.indexOf(item.get("atkSpd"))];
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
/**
|
||||
* 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",
|
||||
"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",
|
||||
"potion": "25% 0", "scroll": "50% 0", "food": "75% 0"};
|
||||
|
||||
function apply_elemental_format(p_elem, id, suffix) {
|
||||
suffix = (typeof suffix !== 'undefined') ? suffix : "";
|
||||
|
@ -286,11 +295,18 @@ function displayExpandedItem(item, parent_id){
|
|||
parent_div.appendChild(nolink_row);
|
||||
|
||||
if (item.has("type")) {
|
||||
let img = make_elem("img", [], {
|
||||
src: "../media/items/" + (newIcons ? "new/":"old/") + "generic-" + item.get("type") + ".png",
|
||||
let img = make_elem("div", [], {
|
||||
alt: item.get("type"),
|
||||
style: " z=index: 1; position: relative;"
|
||||
style: "z-index: 1; position: relative; image-rendering: pixelated; width: 50%; height: 50%; background-position: " + itemBGPositions[item.get("type")] + ";"
|
||||
});
|
||||
if (["potion", "scroll", "food"].includes(item.get("type"))) {
|
||||
img.style.backgroundImage = "url('../media/items/common.png')";
|
||||
img.style.backgroundSize = "500% 100%";
|
||||
} else {
|
||||
img.style.backgroundImage = "url('../media/items/" + (newIcons ? "new.png')" : "old.png')");
|
||||
img.style.backgroundSize = "1200% 100%";
|
||||
}
|
||||
|
||||
let container = make_elem("div");
|
||||
|
||||
let bckgrd = make_elem("div", ["col", "px-0", "d-flex", "align-items-center", "justify-content-center", 'scaled-bckgrd'], { // , "no-collapse"
|
||||
|
@ -1499,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);
|
||||
} else if (spell_info.type === "heal") {
|
||||
let heal_amount = spell_info.heal_amount;
|
||||
let healLabel = document.createElement("p");
|
||||
healLabel.textContent = heal_amount;
|
||||
// healLabel.classList.add("damagep");
|
||||
let healLabel = make_elem("p", ["Set"], {textContent: heal_amount.toFixed(2)});
|
||||
part_div.append(healLabel);
|
||||
if (spell_info.name === spell.display) {
|
||||
add_summary(spell_info.name+ ": ", heal_amount, "Set");
|
||||
|
|
|
@ -209,7 +209,25 @@ let posModSuffixes = {
|
|||
/*
|
||||
* 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",
|
||||
"str", "dex", "int", "def", "agi",
|
||||
"!spacer",
|
||||
|
@ -236,23 +254,31 @@ let build_all_display_commands = [
|
|||
"gXp", "gSpd",
|
||||
];
|
||||
|
||||
let build_offensive_display_commands = [
|
||||
"str", "dex", "int", "def", "agi",
|
||||
"mr", "ms",
|
||||
"sdRaw", "sdPct",
|
||||
"mdRaw", "mdPct",
|
||||
"ref", "thorns",
|
||||
"ls",
|
||||
"poison",
|
||||
"expd",
|
||||
"spd",
|
||||
"atkTier",
|
||||
"rainbowRaw",
|
||||
"!elemental",
|
||||
"fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct",
|
||||
"!elemental",
|
||||
"spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4",
|
||||
];
|
||||
// full
|
||||
//"#defense-stats",
|
||||
//"str", "dex", "int", "def", "agi",
|
||||
//"!spacer",
|
||||
//"mr", "ms",
|
||||
//"hprRaw", "hprPct",
|
||||
//"ls",
|
||||
//"sdRaw", "sdPct",
|
||||
//"mdRaw", "mdPct",
|
||||
//"!elemental",
|
||||
//"fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct",
|
||||
//"!elemental",
|
||||
//"spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4",
|
||||
//"atkTier",
|
||||
//"poison",
|
||||
//"ref", "thorns",
|
||||
//"expd",
|
||||
//"spd",
|
||||
//"rainbowRaw",
|
||||
//"sprint", "sprintReg",
|
||||
//"jh",
|
||||
//"xpb", "lb", "lq",
|
||||
//"spRegen",
|
||||
//"eSteal",
|
||||
//"gXp", "gSpd",
|
||||
|
||||
let build_basic_display_commands = [
|
||||
'#defense-stats',
|
||||
|
|
39
js/icons.js
|
@ -1,33 +1,26 @@
|
|||
//which icons to use
|
||||
let window_storage = window.localStorage;
|
||||
icon_state_stored = window_storage.getItem("newicons");
|
||||
newIcons = true;
|
||||
if (icon_state_stored === "false") {toggleIcons()}
|
||||
if (window_storage.getItem("newicons") === "false") {
|
||||
toggleIcons();
|
||||
}
|
||||
|
||||
/** Toggle icons on the ENTIRE page.
|
||||
*
|
||||
*/
|
||||
function toggleIcons() {
|
||||
newIcons = !newIcons;
|
||||
let imgs = document.getElementsByTagName("IMG");
|
||||
let favicon = document.querySelector("link[rel~='icon']");
|
||||
let toggleiconbutton = document.getElementById("toggle-icon-button");
|
||||
window_storage.setItem("newicons", newIcons.toString());
|
||||
let newOrOld = (newIcons ? "new" : "old");
|
||||
|
||||
if (newIcons) { //switch to new
|
||||
favicon.href = favicon.href.replace("media/icons/old","media/icons/new");
|
||||
for (const img of imgs) {
|
||||
if (img.src.includes("media/icons/old")) {img.src = img.src.replace("media/icons/old","media/icons/new");}
|
||||
if (img.src.includes("media/items/old")) {img.src = img.src.replace("media/items/old","media/items/new");}
|
||||
}
|
||||
toggleiconbutton.textContent = "Use Old Icons";
|
||||
window_storage.setItem("newicons","true");
|
||||
} else { //switch to old
|
||||
favicon.href = favicon.href.replace("media/icons/new","media/icons/old");
|
||||
for (const img of imgs) {
|
||||
if (img.src.includes("media/icons/new")) {img.src = img.src.replace("media/icons/new","media/icons/old");}
|
||||
if (img.src.includes("media/items/new")) {img.src = img.src.replace("media/items/new","media/items/old");}
|
||||
}
|
||||
toggleiconbutton.textContent = "Use New Icons";
|
||||
window_storage.setItem("newicons","false");
|
||||
}
|
||||
let imgs = document.getElementsByTagName("img");
|
||||
let divs = document.getElementsByClassName("item-display-new-toggleable");
|
||||
let favicon = document.querySelector("link[rel~='icon']");
|
||||
favicon.href = favicon.href.replace("media/icons/" + (newIcons ? "old" : "new"), "media/icons/" + newOrOld);
|
||||
for (const img of imgs) {
|
||||
// if doesn't contain, replace() does nothing
|
||||
img.src = img.src.replace("media/icons/" + (newIcons ? "old" : "new"), "media/icons/" + newOrOld);
|
||||
}
|
||||
for (let i = 0; i < divs.length; i++) {
|
||||
divs.item(i).style.backgroundImage = "url('../media/items/" + (newIcons ? "new" : "old") + ".png')";
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
let db;
|
||||
|
@ -254,5 +254,4 @@ function init_maps() {
|
|||
redirectMap.set(item.id, item.remapID);
|
||||
}
|
||||
}
|
||||
console.log(itemMap);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
let tdb;
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
//which icons to use
|
||||
let window_storage = window.localStorage;
|
||||
console.log(window_storage);
|
||||
icon_state_stored = window_storage.getItem("newicons");
|
||||
newIcons = true;
|
||||
if (icon_state_stored === "false") {toggleIcons()}
|
||||
|
||||
|
||||
/** Toggle icons on the ENTIRE page.
|
||||
*
|
||||
*/
|
||||
function toggleIcons() {
|
||||
newIcons = !newIcons;
|
||||
let imgs = document.getElementsByTagName("IMG");
|
||||
let favicon = document.querySelector("link[rel~='icon']");
|
||||
|
||||
if (newIcons) { //switch to new
|
||||
favicon.href = favicon.href.replace("media/icons/old","media/icons/new");
|
||||
for (const img of imgs) {
|
||||
if (img.src.includes("media/icons/old")) {img.src = img.src.replace("media/icons/old","media/icons/new");}
|
||||
if (img.src.includes("media/items/old")) {img.src = img.src.replace("media/items/old","media/items/new");}
|
||||
}
|
||||
//toggleiconbutton.textContent = "Use Old Icons";
|
||||
window_storage.setItem("newicons","true");
|
||||
} else { //switch to old
|
||||
favicon.href = favicon.href.replace("media/icons/new","media/icons/old");
|
||||
for (const img of imgs) {
|
||||
if (img.src.includes("media/icons/new")) {img.src = img.src.replace("media/icons/new","media/icons/old");}
|
||||
if (img.src.includes("media/items/new")) {img.src = img.src.replace("media/items/new","media/items/old");}
|
||||
}
|
||||
//toggleiconbutton.textContent = "Use New Icons";
|
||||
window_storage.setItem("newicons","false");
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 182 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 183 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 178 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 202 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 184 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 202 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 184 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 203 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 221 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
BIN
media/atree/connectors.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
media/atree/icons.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 231 B |
Before Width: | Height: | Size: 266 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 254 B |
Before Width: | Height: | Size: 313 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 276 B |
Before Width: | Height: | Size: 328 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 309 B |
Before Width: | Height: | Size: 385 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 297 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 260 B |
Before Width: | Height: | Size: 291 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 297 B |