Shaman atree + schema augmentation (#196)
* Beginnings of shaman atree * Fix aura parents * Day's work (ft. frozenearth and endistic) * More incremental work -- finish another two pages i think, or one * One more page to go on shaman atree * Fix missing archetype on overseer and fix regeneration to be not 100% heal per tick * Just missing 4 abils at the bottom hopefully * Fix typos in display * Fix archetype req for chant of the fanatic * Shaman atree complete except fluid healing doesn't work yet * Add comments, fix some misc. formatting related stuffs * Misc. patch Fix rebound interaction Fix translations for newly added target parts Fix tree misc. connection/archetype missing bugs Co-authored-by: hppeng <hppeng>
This commit is contained in:
parent
755def77f3
commit
fb1077de7e
10 changed files with 2671 additions and 533 deletions
531
builder/doc.html
531
builder/doc.html
|
@ -36,20 +36,71 @@
|
||||||
<hr/>
|
<hr/>
|
||||||
<a href = "https://discord.gg/CGavnAnerv" target = "_blank"><img src = "../media/icons/discord.png" alt = "WB Discord" title = "WB Discord"><b>WB Discord</b></a>
|
<a href = "https://discord.gg/CGavnAnerv" target = "_blank"><img src = "../media/icons/discord.png" alt = "WB Discord" title = "WB Discord"><b>WB Discord</b></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="container-fluid me-4" style="max-width: 95%; display: none">
|
<div id="mobile-navbar" class="navbar dark-5 dark-shadow fixed-top d-lg-none pb-0" style="display: none">
|
||||||
|
<div class="container-fluid scaled-font justify-content-center" style="height: 5vh;">
|
||||||
|
<div class="navbar-brand mx-auto scaled-font" style="height: 100%;">
|
||||||
|
<img src="../media/icons/new/builder.png" alt="" style="height: 100%;">
|
||||||
|
<span>WynnBuilder</span>
|
||||||
|
</div>
|
||||||
|
<button class="btn dropdown-toggle dark-2 px-4 text-white scaled-font border-dark border-3" onclick="toggle_tab('mobile-navbar-dropdown');"></button>
|
||||||
|
</div>
|
||||||
|
<div class="container-fluid scaled-font dark-3 px-3 py-3" id="mobile-navbar-dropdown" style="display: none;">
|
||||||
|
<a href="../builder/" class="w-100 mb-3 text-white" style="height: 5vh; text-decoration: none;">
|
||||||
|
<img src="../media/icons/new/builder.png" alt="" style="height: 100%;">
|
||||||
|
<span>WynnBuilder</span>
|
||||||
|
</a>
|
||||||
|
<a href="../crafter/" class="w-100 mb-3 text-white" style="height: 5vh; text-decoration: none;">
|
||||||
|
<img src="../media/icons/new/crafter.png" alt="" style="height: 100%;">
|
||||||
|
<span>WynnCrafter</span>
|
||||||
|
</a>
|
||||||
|
<a href="../items/" class="w-100 mb-3 text-white" style="height: 5vh; text-decoration: none;">
|
||||||
|
<img src="../media/icons/new/searcher.png" alt="" style="height: 100%;">
|
||||||
|
<span>WynnAtlas</span>
|
||||||
|
</a>
|
||||||
|
<a href="../custom/" class="w-100 mb-3 text-white" style="height: 5vh; text-decoration: none;">
|
||||||
|
<img src="../media/icons/new/custom.png" alt="" style="height: 100%;">
|
||||||
|
<span>WynnCustom</span>
|
||||||
|
</a>
|
||||||
|
<a href="../map/" class="w-100 mb-3 text-white" style="height: 5vh; text-decoration: none;">
|
||||||
|
<img src="../media/icons/new/compass.png" alt="" style="height: 100%;">
|
||||||
|
<span>WynnGPS</span>
|
||||||
|
</a>
|
||||||
|
<a href="../wynnfo/" class="w-100 mb-3 text-white" style="height: 5vh; text-decoration: none;">
|
||||||
|
<img src="../media/icons/new/book.png" alt="" style="height: 100%;">
|
||||||
|
<span>WynnFo</span>
|
||||||
|
</a>
|
||||||
|
<a onclick = "toggleIcons()" class="w-100 mb-3 text-white" style="height: 5vh; text-decoration: none;">
|
||||||
|
<img src="../media/icons/new/reload.png" alt="" style="height: 100%;">
|
||||||
|
<span>Swap Icon Style</span>
|
||||||
|
</a>
|
||||||
|
<a href="https://discord.gg/CGavnAnerv" class="w-100 mb-3 text-white" style="height: 5vh; text-decoration: none;">
|
||||||
|
<img src="../media/icons/discord.png" alt="" style="height: 100%;">
|
||||||
|
<span>Discord</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container-fluid overall-box mt-lg-2" style="margin-top: 6vh; display: none">
|
||||||
<!-- REMOVE THIS DIV AT SOME POINT. -->
|
<!-- REMOVE THIS DIV AT SOME POINT. -->
|
||||||
<div class = "row scaled-font mx-auto" id = "discord-banner-dev">
|
<div class = "row scaled-font mx-auto" id = "discord-banner-dev">
|
||||||
<div class = "col text-center item-title">Join the <a class = "link" href = "https://discord.gg/CGavnAnerv" target = "_blank">discord</a> today to suggest new features, submit bug reports, and hangout/talk to devs!</div>
|
<div class = "col text-center item-title">Join the <a class = "link" href = "https://discord.gg/CGavnAnerv" target = "_blank">discord</a> today to suggest new features, submit bug reports, and hangout/talk to devs!</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row h-100 gx-lg-5 gy-3 mx-2 mx-lg-3 py-3">
|
<div class="row h-100 gx-lg-5 gy-3 mx-2 mx-lg-3 py-3 gx-0">
|
||||||
<div class="col-xl-6">
|
<div class="col-xl-6">
|
||||||
<div class="row row-cols-1 mb-3 gy-4">
|
<div class="row my-2 dark-6 rounded text-center g-0 px-3 d-flex d-lg-none">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row row-cols-1 row-cols-xl-2 rounded gy-4 gx-5 justify-content-center">
|
<p class="fake-button scaled-font mb-0 selected-btn" id="equipment-inputs-btn" onclick="show_tab('equipment-inputs', ['equipment-inputs', 'adjust-id'])">Equipments</p>
|
||||||
<div class="col-auto rounded order-xl-0 order-0">
|
</div>
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded" id="helmet-dropdown">
|
<div class="col">
|
||||||
|
<p class="fake-button scaled-font mb-0" id="adjust-id-btn" onclick="show_tab('adjust-id', ['equipment-inputs', 'adjust-id'])">Ability Tree</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 mb-3 gy-4" id="equipment-inputs">
|
||||||
|
<div class="col">
|
||||||
|
<div class="row row-cols-1 row-cols-xl-2 dark-shadow dark-6 justify-content-center equipment-input rounded gy-3 gy-lg-0 mt-auto">
|
||||||
|
<div class="col-auto rounded order-xl-0 order-0 my-0">
|
||||||
|
<div class="row h-100 px-1" id="helmet-dropdown">
|
||||||
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="helmet-img-loc">
|
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="helmet-img-loc">
|
||||||
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -73,10 +124,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto order-xl-0 order-1">
|
<div class="col-auto order-xl-0 order-1 my-0">
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded" id="ring1-dropdown">
|
<div class="row h-100 px-1" id="ring1-dropdown">
|
||||||
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="ring1-img-loc">
|
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="ring1-img-loc">
|
||||||
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -94,16 +145,15 @@
|
||||||
<input class="equipment-input text-light form-control" id="ring1-choice" name="ring1-choice" placeholder="No ring" value="" tabindex="2"/>
|
<input class="equipment-input text-light form-control" id="ring1-choice" name="ring1-choice" placeholder="No ring" value="" tabindex="2"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col d-flex justify-content-end" style="height: 100%;">
|
<div class="col d-flex justify-content-end" style="height: 100%;">
|
||||||
<!-- <input class="equipment-input text-light form-control" type="text" id="ring1-powder" name="ring1-powder" placeholder="no powders" tabindex="2"/> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto order-xl-0 order-0">
|
<div class="col-auto order-xl-0 order-0">
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded" id="chestplate-dropdown">
|
<div class="row h-100 px-1" id="chestplate-dropdown">
|
||||||
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="chestplate-img-loc">
|
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="chestplate-img-loc">
|
||||||
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -128,9 +178,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto order-xl-0 order-1">
|
<div class="col-auto order-xl-0 order-1">
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded" id="ring2-dropdown">
|
<div class="row h-100 px-1" id="ring2-dropdown">
|
||||||
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="ring2-img-loc">
|
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="ring2-img-loc">
|
||||||
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -154,9 +204,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto order-xl-0 order-0">
|
<div class="col-auto order-xl-0 order-0">
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded" id="leggings-dropdown">
|
<div class="row h-100 px-1" id="leggings-dropdown">
|
||||||
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="leggings-img-loc">
|
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="leggings-img-loc">
|
||||||
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -181,9 +231,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto order-xl-0 order-1">
|
<div class="col-auto order-xl-0 order-1">
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded" id="bracelet-dropdown">
|
<div class="row h-100 px-1" id="bracelet-dropdown">
|
||||||
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="bracelet-img-loc">
|
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="bracelet-img-loc">
|
||||||
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -208,9 +258,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto order-xl-0 order-0">
|
<div class="col-auto order-xl-0 order-0">
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded" id="boots-dropdown">
|
<div class="row h-100 px-1" id="boots-dropdown">
|
||||||
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="boots-img-loc">
|
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="boots-img-loc">
|
||||||
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -235,9 +285,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto order-xl-0 order-1">
|
<div class="col-auto order-xl-0 order-1">
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded" id="necklace-dropdown">
|
<div class="row h-100 px-1" id="necklace-dropdown">
|
||||||
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="necklace-img-loc">
|
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="necklace-img-loc">
|
||||||
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -261,9 +311,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto order-xl-0 order-1">
|
<div class="col-auto order-xl-0 order-1">
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded" id='weapon-dropdown'>
|
<div class="row h-auto px-1" id='weapon-dropdown'>
|
||||||
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="weapon-img-loc">
|
<div class="col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon" id="weapon-img-loc">
|
||||||
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -287,29 +337,25 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto order-xl-0 order-1">
|
<div class="col-auto order-xl-0 order-1 level-input">
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded">
|
<div class="row h-100 px-1">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center justify-content-left">
|
||||||
<div class="col-3 text-nowrap fw-bold scaled-font">
|
<div class="col-auto text-nowrap fw-bold scaled-font">
|
||||||
Level:
|
Level:
|
||||||
</div>
|
</div>
|
||||||
<div class="col d-flex justify-content-end">
|
<div class="col d-flex px-1">
|
||||||
<input class="equipment-input text-light form-control form-control-sm" id="level-choice" name="level-choice" value="106" placeholder="Build level" value="" tabindex="2"/>
|
<input class="equipment-input text-light form-control form-control-sm" id="level-choice" name="level-choice" value="106" placeholder="Build level" value="" tabindex="2"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto px-1 text-nowrap scaled-font">
|
<div class="col-auto px-1 scaled-font">
|
||||||
<button class="button fw-bold text-light dark-5 scaled-font rounded" id="reset-button" onclick="resetFields()">Reset</button>
|
<button class="button py-0 fw-bold text-light dark-5 scaled-font rounded" id="reset-button" onclick="resetFields()">Reset</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row align-items-center justify-content-center my-1">
|
<div class="row align-items-left justify-content-left my-1">
|
||||||
<div class="row align-items-center">
|
<button class="col-auto mx-1 px-1 py-0 border-info text-light dark-5 scaled-font rounded fake-button"
|
||||||
<div class="col-auto px-1 text-nowrap scaled-font">
|
id=copy-button onclick="copyBuild()">Copy short</button>
|
||||||
<button class="border-dark text-light dark-5 scaled-font rounded" id=copy-button onclick="copyBuild()">Copy short</button>
|
<button class="col-auto mx-1 px-1 py-0 border-info text-light dark-5 scaled-font rounded fake-button"
|
||||||
</div>
|
id=share-button onclick="shareBuild(player_build)">Copy for sharing</button>
|
||||||
<div class="col-auto px-1 text-nowrap scaled-font">
|
|
||||||
<button class="border-dark text-light dark-5 scaled-font rounded" id=share-button onclick="shareBuild(player_build)">Copy for sharing</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -390,12 +436,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 text-center gx-2">
|
|
||||||
<button class = "button fw-bold text-light dark-5 rounded scaled-font" id = "optimize-strdex" onclick = "optimizeStrDex()">Optimize Str/Dex</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col text-center">
|
<div class="col text-center py-1">
|
||||||
<div id="summary-box"></div>
|
<div id="summary-box"></div>
|
||||||
<div id="err-box"></div>
|
<div id="err-box"></div>
|
||||||
<div id="stack-box"></div>
|
<div id="stack-box"></div>
|
||||||
|
@ -407,188 +450,187 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col mb-1 text-center scaled-font dark-5 rounded dark-shadow">
|
||||||
|
<div class="row row-cols-1 justify-content-center">
|
||||||
|
<div class="col fw-bold dark-4 rounded-top">
|
||||||
|
Active boosts
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="warscream-boost" onclick="update_boosts('warscream-boost')">
|
||||||
|
War Scream
|
||||||
|
</button>
|
||||||
|
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="ragnarokkr-boost" onclick="update_boosts('ragnarokkr-boost')">
|
||||||
|
Ragnarokkr (+30%)
|
||||||
|
</button>
|
||||||
|
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="yourtotem-boost" onclick="update_boosts('yourtotem-boost')">
|
||||||
|
Your Totem (+35%)
|
||||||
|
</button>
|
||||||
|
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="allytotem-boost" onclick="update_boosts('allytotem-boost')">
|
||||||
|
Ally Totem (+15%)
|
||||||
|
</button>
|
||||||
|
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="fortitude-boost" onclick="update_boosts('fortitude-boost')">
|
||||||
|
Fortitude (+60%)
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col" id="boost-toggles">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 justify-content-center" id="boost-sliders">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col mb-1">
|
||||||
|
<div class="row row-cols-1 rounded text-center dark-5 scaled-font">
|
||||||
|
<div class="row p-0 m-0 text-nowrap">
|
||||||
|
<div id = "str-boost-btn" class="col eDam dark-4u fake-button elem-boost" onclick="show_tab('str-boost', ['str-boost', 'dex-boost', 'int-boost', 'def-boost', 'agi-boost'])">
|
||||||
|
Earth
|
||||||
|
</div>
|
||||||
|
<div id = "dex-boost-btn" class="col tDam dark-4u fake-button elem-boost" onclick="show_tab('dex-boost', ['str-boost', 'dex-boost', 'int-boost', 'def-boost', 'agi-boost'])">
|
||||||
|
Thunder
|
||||||
|
</div>
|
||||||
|
<div id = "int-boost-btn" class="col wDam dark-4u fake-button elem-boost" onclick="show_tab('int-boost', ['str-boost', 'dex-boost', 'int-boost', 'def-boost', 'agi-boost'])">
|
||||||
|
Water
|
||||||
|
</div>
|
||||||
|
<div id = "def-boost-btn" class="col fDam dark-4u fake-button elem-boost" onclick="show_tab('def-boost', ['str-boost', 'dex-boost', 'int-boost', 'def-boost', 'agi-boost'])">
|
||||||
|
Fire
|
||||||
|
</div>
|
||||||
|
<div id = "agi-boost-btn" class="col aDam dark-4u fake-button elem-boost" onclick="show_tab('agi-boost', ['str-boost', 'dex-boost', 'int-boost', 'def-boost', 'agi-boost'])">
|
||||||
|
Air
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 p-0 m-0" id="str-boost" style="display: none;">
|
||||||
|
<div class="col eDam dark-5">
|
||||||
|
Quake (Active)
|
||||||
|
</div>
|
||||||
|
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1" >
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-1" onclick = "updatePowderSpecials('Quake-1')">
|
||||||
|
Lv.4 [e4e4]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-2" onclick = "updatePowderSpecials('Quake-2')">
|
||||||
|
Lv.4.5 [e5e4]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-3" onclick = "updatePowderSpecials('Quake-3')">
|
||||||
|
Lv.5 [e5e5]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-4" onclick = "updatePowderSpecials('Quake-4')">
|
||||||
|
Lv.5.5 [e6e5]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-5" onclick = "updatePowderSpecials('Quake-5')">
|
||||||
|
Lv.6 [e6e6]
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col eDam">
|
||||||
|
Rage (Passive)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 p-0 m-0" id="dex-boost" style="display: none;">
|
||||||
|
<div class="col tDam dark-5">
|
||||||
|
Chain Lightning (Active)
|
||||||
|
</div>
|
||||||
|
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-1" onclick = "updatePowderSpecials('Chain_Lightning-1')">
|
||||||
|
Lv.4 [t4t4]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-2" onclick = "updatePowderSpecials('Chain_Lightning-2')">
|
||||||
|
Lv.4.5 [t5t4]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-3" onclick = "updatePowderSpecials('Chain_Lightning-3')">
|
||||||
|
Lv.5 [t5t5]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-4" onclick = "updatePowderSpecials('Chain_Lightning-4')">
|
||||||
|
Lv.5.5 [t6t5]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-5" onclick = "updatePowderSpecials('Chain_Lightning-5')">
|
||||||
|
Lv.6 [t6t6]
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col tDam">
|
||||||
|
Kill Streak (Passive)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 p-0 m-0" id="int-boost">
|
||||||
|
<div class="col wDam dark-5">
|
||||||
|
Curse (Active)
|
||||||
|
</div>
|
||||||
|
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-1" onclick = "updatePowderSpecials('Curse-1')">
|
||||||
|
Lv.4 [w4w4]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-2" onclick = "updatePowderSpecials('Curse-2')">
|
||||||
|
Lv.4.5 [w5w4]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-3" onclick = "updatePowderSpecials('Curse-3')">
|
||||||
|
Lv.5 [w5w5]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-4" onclick = "updatePowderSpecials('Curse-4')">
|
||||||
|
Lv.5.5 [w6w5]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-5" onclick = "updatePowderSpecials('Curse-5')">
|
||||||
|
Lv.6 [w6w6]
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col wDam">
|
||||||
|
Concentration (Passive)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 p-0 m-0" id="def-boost" style="display: none;">
|
||||||
|
<div class="col fDam dark-5">
|
||||||
|
Courage (Active)
|
||||||
|
</div>
|
||||||
|
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-1" onclick = "updatePowderSpecials('Courage-1')">
|
||||||
|
Lv.4 [f4f4]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-2" onclick = "updatePowderSpecials('Courage-2')">
|
||||||
|
Lv.4.5 [f5f4]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-3" onclick = "updatePowderSpecials('Courage-3')">
|
||||||
|
Lv.5 [f5f5]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-4" onclick = "updatePowderSpecials('Courage-4')">
|
||||||
|
Lv.5.5 [f6f5]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-5" onclick = "updatePowderSpecials('Courage-5')">
|
||||||
|
Lv.6 [f6f6]
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col fDam">
|
||||||
|
Endurance (Passive)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 p-0 m-0" id="agi-boost" style="display: none;">
|
||||||
|
<div class="col aDam dark-5">
|
||||||
|
Wind Prison (Active)
|
||||||
|
</div>
|
||||||
|
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-1" onclick = "updatePowderSpecials('Wind_Prison-1')">
|
||||||
|
Lv.4 [a4a4]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-2" onclick = "updatePowderSpecials('Wind_Prison-2')">
|
||||||
|
Lv.4.5 [a5a4]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-3" onclick = "updatePowderSpecials('Wind_Prison-3')">
|
||||||
|
Lv.5 [a5a5]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-4" onclick = "updatePowderSpecials('Wind_Prison-4')">
|
||||||
|
Lv.5.5 [a6a5]
|
||||||
|
</button>
|
||||||
|
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-5" onclick = "updatePowderSpecials('Wind_Prison-5')">
|
||||||
|
Lv.6 [a6a6]
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col aDam">
|
||||||
|
Dodge (Passive)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 d-lg-flex" id="adjust-id" style="display: none;">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row row-cols-1 gy-4">
|
<div class="row row-cols-1 gy-3">
|
||||||
|
|
||||||
<div class="col mb-1 text-center scaled-font dark-5 rounded dark-shadow">
|
|
||||||
<div class="row row-cols-1 justify-content-center">
|
|
||||||
<div class="col fw-bold dark-4 rounded-top">
|
|
||||||
Active boosts
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="vanish-boost" onclick="update_boosts('vanish-boost')">
|
|
||||||
Vanish (+80%)
|
|
||||||
</button>
|
|
||||||
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="warscream-boost" onclick="update_boosts('warscream-boost')">
|
|
||||||
War Scream
|
|
||||||
</button>
|
|
||||||
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="ragnarokkr-boost" onclick="update_boosts('ragnarokkr-boost')">
|
|
||||||
Ragnarokkr (+30%)
|
|
||||||
</button>
|
|
||||||
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="yourtotem-boost" onclick="update_boosts('yourtotem-boost')">
|
|
||||||
Your Totem (+35%)
|
|
||||||
</button>
|
|
||||||
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="allytotem-boost" onclick="update_boosts('allytotem-boost')">
|
|
||||||
Ally Totem (+15%)
|
|
||||||
</button>
|
|
||||||
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="fortitude-boost" onclick="update_boosts('fortitude-boost')">
|
|
||||||
Fortitude (+60%)
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col" id="boost-toggles">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row row-cols-1 justify-content-center" id="boost-sliders">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col mb-1">
|
|
||||||
<div class="row row-cols-1 rounded text-center dark-5 scaled-font">
|
|
||||||
<div class="row p-0 m-0 text-nowrap">
|
|
||||||
<div id = "str-boost-tab" class="col eDam dark-4u fake-button elem-boost" onclick="toggle_boost_tab('str')">
|
|
||||||
Earth
|
|
||||||
</div>
|
|
||||||
<div id = "dex-boost-tab" class="col tDam dark-4u fake-button elem-boost" onclick="toggle_boost_tab('dex')">
|
|
||||||
Thunder
|
|
||||||
</div>
|
|
||||||
<div id = "int-boost-tab" class="col wDam dark-4u fake-button elem-boost" onclick="toggle_boost_tab('int')">
|
|
||||||
Water
|
|
||||||
</div>
|
|
||||||
<div id = "def-boost-tab" class="col fDam dark-4u fake-button elem-boost" onclick="toggle_boost_tab('def')">
|
|
||||||
Fire
|
|
||||||
</div>
|
|
||||||
<div id = "agi-boost-tab" class="col aDam dark-4u fake-button elem-boost" onclick="toggle_boost_tab('agi')">
|
|
||||||
Air
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row row-cols-1 p-0 m-0" id="str-boost" style="display: none;">
|
|
||||||
<div class="col eDam dark-5">
|
|
||||||
Quake (Active)
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1" >
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-1" onclick = "updatePowderSpecials('Quake-1')">
|
|
||||||
Lv.4 [e4e4]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-2" onclick = "updatePowderSpecials('Quake-2')">
|
|
||||||
Lv.4.5 [e5e4]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-3" onclick = "updatePowderSpecials('Quake-3')">
|
|
||||||
Lv.5 [e5e5]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-4" onclick = "updatePowderSpecials('Quake-4')">
|
|
||||||
Lv.5.5 [e6e5]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-5" onclick = "updatePowderSpecials('Quake-5')">
|
|
||||||
Lv.6 [e6e6]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col eDam">
|
|
||||||
Rage (Passive)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row row-cols-1 p-0 m-0" id="dex-boost" style="display: none;">
|
|
||||||
<div class="col tDam dark-5">
|
|
||||||
Chain Lightning (Active)
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-1" onclick = "updatePowderSpecials('Chain_Lightning-1')">
|
|
||||||
Lv.4 [t4t4]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-2" onclick = "updatePowderSpecials('Chain_Lightning-2')">
|
|
||||||
Lv.4.5 [t5t4]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-3" onclick = "updatePowderSpecials('Chain_Lightning-3')">
|
|
||||||
Lv.5 [t5t5]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-4" onclick = "updatePowderSpecials('Chain_Lightning-4')">
|
|
||||||
Lv.5.5 [t6t5]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-5" onclick = "updatePowderSpecials('Chain_Lightning-5')">
|
|
||||||
Lv.6 [t6t6]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col tDam">
|
|
||||||
Kill Streak (Passive)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row row-cols-1 p-0 m-0" id="int-boost">
|
|
||||||
<div class="col wDam dark-5">
|
|
||||||
Curse (Active)
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-1" onclick = "updatePowderSpecials('Curse-1')">
|
|
||||||
Lv.4 [w4w4]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-2" onclick = "updatePowderSpecials('Curse-2')">
|
|
||||||
Lv.4.5 [w5w4]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-3" onclick = "updatePowderSpecials('Curse-3')">
|
|
||||||
Lv.5 [w5w5]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-4" onclick = "updatePowderSpecials('Curse-4')">
|
|
||||||
Lv.5.5 [w6w5]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-5" onclick = "updatePowderSpecials('Curse-5')">
|
|
||||||
Lv.6 [w6w6]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col wDam">
|
|
||||||
Concentration (Passive)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row row-cols-1 p-0 m-0" id="def-boost" style="display: none;">
|
|
||||||
<div class="col fDam dark-5">
|
|
||||||
Courage (Active)
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-1" onclick = "updatePowderSpecials('Courage-1')">
|
|
||||||
Lv.4 [f4f4]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-2" onclick = "updatePowderSpecials('Courage-2')">
|
|
||||||
Lv.4.5 [f5f4]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-3" onclick = "updatePowderSpecials('Courage-3')">
|
|
||||||
Lv.5 [f5f5]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-4" onclick = "updatePowderSpecials('Courage-4')">
|
|
||||||
Lv.5.5 [f6f5]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-5" onclick = "updatePowderSpecials('Courage-5')">
|
|
||||||
Lv.6 [f6f6]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col fDam">
|
|
||||||
Endurance (Passive)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row row-cols-1 p-0 m-0" id="agi-boost" style="display: none;">
|
|
||||||
<div class="col aDam dark-5">
|
|
||||||
Wind Prison (Active)
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-1" onclick = "updatePowderSpecials('Wind_Prison-1')">
|
|
||||||
Lv.4 [a4a4]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-2" onclick = "updatePowderSpecials('Wind_Prison-2')">
|
|
||||||
Lv.4.5 [a5a4]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-3" onclick = "updatePowderSpecials('Wind_Prison-3')">
|
|
||||||
Lv.5 [a5a5]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-4" onclick = "updatePowderSpecials('Wind_Prison-4')">
|
|
||||||
Lv.5.5 [a6a5]
|
|
||||||
</button>
|
|
||||||
<button class = "button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-5" onclick = "updatePowderSpecials('Wind_Prison-5')">
|
|
||||||
Lv.6 [a6a6]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col aDam">
|
|
||||||
Dodge (Passive)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col mb-1">
|
<div class="col mb-1">
|
||||||
<div class="row row-cols-1 row-cols-1 text-center scaled-font dark-5 rounded dark-shadow">
|
<div class="row row-cols-1 row-cols-1 text-center scaled-font dark-5 rounded dark-shadow">
|
||||||
<div class="col fw-bold dark-4 rounded-top">
|
<div class="col fw-bold dark-4 rounded-top">
|
||||||
|
@ -620,7 +662,7 @@
|
||||||
<div class="col-auto rounded">
|
<div class="col-auto rounded">
|
||||||
<div class="row h-100 dark-shadow rounded" id='weaponTome1-dropdown'>
|
<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">
|
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -644,7 +686,7 @@
|
||||||
<div class="col-auto rounded">
|
<div class="col-auto rounded">
|
||||||
<div class="row h-100 dark-shadow rounded" id='weaponTome2-dropdown'>
|
<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">
|
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -668,7 +710,7 @@
|
||||||
<div class="col-auto rounded">
|
<div class="col-auto rounded">
|
||||||
<div class="row h-100 dark-shadow rounded" id='armorTome1-dropdown'>
|
<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">
|
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -692,7 +734,7 @@
|
||||||
<div class="col-auto rounded">
|
<div class="col-auto rounded">
|
||||||
<div class="row h-100 dark-shadow rounded" id='armorTome2-dropdown'>
|
<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">
|
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -716,7 +758,7 @@
|
||||||
<div class="col-auto rounded">
|
<div class="col-auto rounded">
|
||||||
<div class="row h-100 dark-shadow rounded" id='armorTome3-dropdown'>
|
<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">
|
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -740,7 +782,7 @@
|
||||||
<div class="col-auto rounded">
|
<div class="col-auto rounded">
|
||||||
<div class="row h-100 dark-shadow rounded" id='armorTome4-dropdown'>
|
<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">
|
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -764,7 +806,7 @@
|
||||||
<div class="col-auto rounded">
|
<div class="col-auto rounded">
|
||||||
<div class="row h-100 dark-shadow rounded" id='guildTome1-dropdown'>
|
<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">
|
<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>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="row row-cols-1 h-100 align-items-center">
|
<div class="row row-cols-1 h-100 align-items-center">
|
||||||
|
@ -789,7 +831,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class = "col dark-6 rounded-bottom my-3 my-xl-1" id = "atree-dropdown" style = "display:none;">
|
<div class = "col dark-6 rounded-bottom my-3 my-xl-1" id = "atree-dropdown" style = "display:none;">
|
||||||
<div class="row row-cols-1 row-cols-xl-2">
|
<div class="row row-cols-1 row-cols-xl-2">
|
||||||
<div class="col border border-semi-light rounded dark-9 hide-scroll" id="atree-ui" style="height: 90vh; overflow-y: auto; overflow-x: hidden;">
|
<div class="col border border-semi-light rounded dark-9 hide-scroll" id="atree-ui" style="height: 90vh; overflow-y: auto;">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col mx-auto" style="height: 90vh; overflow-y: auto;" id="atree-rhs">
|
<div class="col mx-auto" style="height: 90vh; overflow-y: auto;" id="atree-rhs">
|
||||||
|
@ -1131,24 +1173,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-3 mb-3">
|
<div class="col-xl-3 mb-3 order-2 order-lg-0">
|
||||||
<div class="row row-cols-1 rounded dark-shadow dark-6 scaled-font">
|
<div class="row row-cols-1 rounded dark-shadow dark-6 scaled-font">
|
||||||
<div class="col rounded-top">
|
<div class="col rounded-top">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div id="tab-offensive-btn" class="col-4 text-center fake-button border-bottom border-dark rounded-top dark-4u border border-2 border-dark-7" onclick="show_tab('offensive-stats')">
|
<div id="detailed-stats-btn" class="col text-center fake-button border-bottom border-dark rounded-top dark-4u border border-2 border-dark-7" onclick="show_tab('detailed-stats', ['detailed-stats', 'summary-stats'])">
|
||||||
Offense
|
Detailed
|
||||||
</div>
|
</div>
|
||||||
<div id="tab-defensive-btn" class="col-4 text-center fake-button border-bottom border-dark rounded-top dark-4u border border-2 border-dark-7" onclick="show_tab('defensive-stats')">
|
<div id="summary-stats-btn" class="col text-center fake-button border-bottom border-dark rounded-top dark-4u border border-2 border-dark-7 selected-btn" onclick="show_tab('summary-stats', ['detailed-stats', 'summary-stats'])">
|
||||||
Defense
|
Summary
|
||||||
</div>
|
|
||||||
<div id="tab-overall-btn" class="col-4 text-center fake-button border-bottom border-dark rounded-top dark-4u border border-2 border-dark-7 selected-btn" onclick="show_tab('overall-stats')">
|
|
||||||
Overall
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: none;" id="offensive-stats" class="col text-nowrap"></div>
|
<div style="display: none;" id="detailed-stats" class="col text-nowrap"></div>
|
||||||
<div style="display: none;" id="defensive-stats" class="col text-nowrap"></div>
|
<div id="summary-stats" class="col text-nowrap"></div>
|
||||||
<div id="overall-stats" class="col text-nowrap"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-3 mb-3 px-0">
|
<div class="col-xl-3 mb-3 px-0">
|
||||||
|
@ -1263,8 +1301,7 @@
|
||||||
<script type="text/javascript" src="../js/build_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/computation_graph.js"></script>
|
||||||
<script type="text/javascript">COMPUTE_GRAPH_DEBUG=true;</script>
|
<script type="text/javascript">COMPUTE_GRAPH_DEBUG=true;</script>
|
||||||
<!-- <script type="text/javascript" src="../js/icons.js"></script> -->
|
<script type="text/javascript" src="../js/icons.js"></script>
|
||||||
<script type="text/javascript" src="../js/sq2icons.js"></script>
|
|
||||||
<script type="text/javascript" src="../js/powders.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/skillpoints.js"></script>
|
||||||
<script type="text/javascript" src="../js/damage_calc.js"></script>
|
<script type="text/javascript" src="../js/damage_calc.js"></script>
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -463,11 +463,8 @@
|
||||||
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="ragnarokkr-boost" onclick="update_boosts('ragnarokkr-boost')">
|
<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%)
|
Ragnarokkr (+30%)
|
||||||
</button>
|
</button>
|
||||||
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="yourtotem-boost" onclick="update_boosts('yourtotem-boost')">
|
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="totem-boost" onclick="update_boosts('totem-boost')">
|
||||||
Your Totem (+35%)
|
Vengeful Spirit (+20%)
|
||||||
</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>
|
||||||
<button class="button-boost m-1 border-0 text-white dark-8u dark-shadow-sm" id="fortitude-boost" onclick="update_boosts('fortitude-boost')">
|
<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%)
|
Fortitude (+60%)
|
||||||
|
|
431
js/atree.js
431
js/atree.js
|
@ -50,7 +50,10 @@ add_spell_prop: {
|
||||||
cost: Optional[int] // change to spellcost. If the spell is not spell 1-4, this must be left empty.
|
cost: Optional[int] // change to spellcost. If the spell is not spell 1-4, this must be left empty.
|
||||||
multipliers: Optional[array[float, 6]] // Additive changes to spellmult (for damage spell)
|
multipliers: Optional[array[float, 6]] // Additive changes to spellmult (for damage spell)
|
||||||
power: Optional[float] // Additive change to healing power (for heal spell)
|
power: Optional[float] // Additive change to healing power (for heal spell)
|
||||||
hits: Optional[Map[str, float]] // Additive changes to hits (for total entry)
|
|
||||||
|
hits: Optional[Map[str, Union[str, float]]] // Additive changes to hits (for total entry)
|
||||||
|
// Can either be a raw value number, or a reference
|
||||||
|
// of the format <ability_id>.propname
|
||||||
display: Optional[str] // Optional change to the displayed entry. Replaces old
|
display: Optional[str] // Optional change to the displayed entry. Replaces old
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,8 +194,8 @@ const atree_node = new (class extends ComputeNode {
|
||||||
atree_topo_sort.push(node);
|
atree_topo_sort.push(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("Approximate topological order ability tree:");
|
//console.log("Approximate topological order ability tree:");
|
||||||
console.log(atree_topo_sort);
|
//console.log(atree_topo_sort);
|
||||||
return atree_topo_sort;
|
return atree_topo_sort;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -285,7 +288,10 @@ const atree_merge = new (class extends ComputeNode {
|
||||||
base_abil.subparts.push(abil.id);
|
base_abil.subparts.push(abil.id);
|
||||||
base_abil.effects = base_abil.effects.concat(abil.effects);
|
base_abil.effects = base_abil.effects.concat(abil.effects);
|
||||||
for (let propname in abil.properties) {
|
for (let propname in abil.properties) {
|
||||||
base_abil[propname] = abil[propname];
|
if (propname in base_abil.properties) {
|
||||||
|
base_abil.properties[propname] += abil.properties[propname];
|
||||||
|
}
|
||||||
|
else { base_abil.properties[propname] = abil.properties[propname]; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// do nothing otherwise.
|
// do nothing otherwise.
|
||||||
|
@ -448,6 +454,207 @@ const atree_validate = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
})().link_to(atree_node, 'atree').link_to(atree_state_node, 'atree-state');
|
})().link_to(atree_node, 'atree').link_to(atree_state_node, 'atree-state');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make interactive elements (sliders, buttons)
|
||||||
|
*
|
||||||
|
* Signature: AbilityActiveUINode(atree-merged: MergedATree) => Map<str, slider_info>
|
||||||
|
*
|
||||||
|
* ElemState: {
|
||||||
|
* value: int // value for sliders; 0-1 for toggles
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
const atree_make_interactives = new (class extends ComputeNode {
|
||||||
|
constructor() { super('atree-make-interactives'); }
|
||||||
|
|
||||||
|
compute_func(input_map) {
|
||||||
|
const merged_abils = input_map.get('atree-merged');
|
||||||
|
const atree_order = input_map.get('atree-order');
|
||||||
|
|
||||||
|
const boost_slider_parent = document.getElementById("boost-sliders");
|
||||||
|
const boost_toggle_parent = document.getElementById("boost-toggles");
|
||||||
|
boost_slider_parent.innerHTML = "";
|
||||||
|
boost_toggle_parent.innerHTML = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* slider_info
|
||||||
|
* label_name: str,
|
||||||
|
* max: int,
|
||||||
|
* step: int,
|
||||||
|
* id: str,
|
||||||
|
* abil: atree_node
|
||||||
|
* slider: html element
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
// Map<str, slider_info>
|
||||||
|
const slider_map = new Map();
|
||||||
|
const button_map = new Map();
|
||||||
|
|
||||||
|
// first, pull out all the sliders and toggles.
|
||||||
|
for (const [abil_id, ability] of merged_abils.entries()) {
|
||||||
|
for (const effect of ability.effects) {
|
||||||
|
if (effect['type'] === "stat_scaling" && effect['slider'] === true) {
|
||||||
|
const { slider_name, slider_behavior = 'merge', slider_max, slider_step } = effect;
|
||||||
|
if (slider_map.has(slider_name)) {
|
||||||
|
if (slider_max !== undefined) {
|
||||||
|
const slider_info = slider_map.get(slider_name);
|
||||||
|
slider_info.max += slider_max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (slider_behavior === 'merge') {
|
||||||
|
slider_map.set(slider_name, {
|
||||||
|
label_name: slider_name+' ('+ability.display_name+')',
|
||||||
|
max: slider_max,
|
||||||
|
step: slider_step,
|
||||||
|
id: "ability-slider"+ability.id,
|
||||||
|
//color: effect['slider_color'] TODO: add colors to json
|
||||||
|
abil: ability
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (effect['type'] === "raw_stat" && effect['toggle']) {
|
||||||
|
const { toggle: toggle_name } = effect;
|
||||||
|
button_map.set(toggle_name, {
|
||||||
|
abil: ability
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// next, render the sliders and toggles onto the abilities.
|
||||||
|
for (const [slider_name, slider_info] of slider_map.entries()) {
|
||||||
|
let slider_container = gen_slider_labeled(slider_info);
|
||||||
|
boost_slider_parent.appendChild(slider_container);
|
||||||
|
slider_info.slider = document.getElementById(slider_info.id);
|
||||||
|
slider_info.slider.addEventListener("change", (e) => atree_scaling.mark_dirty().update());
|
||||||
|
}
|
||||||
|
for (const [button_name, button_info] of button_map.entries()) {
|
||||||
|
let button = make_elem('button', ["button-boost", "border-0", "text-white", "dark-8u", "dark-shadow-sm", "m-1"], {
|
||||||
|
id: button_info.abil.id,
|
||||||
|
textContent: button_name
|
||||||
|
});
|
||||||
|
button.addEventListener("click", (e) => {
|
||||||
|
if (button.classList.contains("toggleOn")) {
|
||||||
|
button.classList.remove("toggleOn");
|
||||||
|
} else {
|
||||||
|
button.classList.add("toggleOn");
|
||||||
|
}
|
||||||
|
atree_scaling.mark_dirty().update()
|
||||||
|
});
|
||||||
|
button_info.button = button;
|
||||||
|
boost_toggle_parent.appendChild(button);
|
||||||
|
}
|
||||||
|
return [slider_map, button_map];
|
||||||
|
}
|
||||||
|
})().link_to(atree_node, 'atree-order').link_to(atree_merge, 'atree-merged');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scaling stats from ability tree.
|
||||||
|
* Return StatMap of added stats,
|
||||||
|
*
|
||||||
|
* Signature: AbilityTreeScalingNode(atree-merged: MergedATree, scale-scats: StatMap,
|
||||||
|
* atree-interactive: [Map<str, slider_info>, Map<str, button_info>]) => (ATree, StatMap)
|
||||||
|
*/
|
||||||
|
const atree_scaling = new (class extends ComputeNode {
|
||||||
|
constructor() { super('atree-scaling-collector'); }
|
||||||
|
|
||||||
|
compute_func(input_map) {
|
||||||
|
const atree_merged = input_map.get('atree-merged');
|
||||||
|
const pre_scale_stats = input_map.get('scale-stats');
|
||||||
|
const [slider_map, button_map] = input_map.get('atree-interactive');
|
||||||
|
|
||||||
|
const atree_edit = new Map();
|
||||||
|
for (const [abil_id, abil] of atree_merged.entries()) {
|
||||||
|
atree_edit.set(abil_id, deepcopy(abil));
|
||||||
|
}
|
||||||
|
let ret_effects = new Map();
|
||||||
|
|
||||||
|
// Apply a stat bonus.
|
||||||
|
function apply_bonus(bonus_info, value) {
|
||||||
|
const { type, name, abil = null} = bonus_info;
|
||||||
|
if (type === 'stat') {
|
||||||
|
merge_stat(ret_effects, name, value);
|
||||||
|
} else if (type === 'prop') {
|
||||||
|
const merge_abil = atree_edit.get(abil);
|
||||||
|
merge_abil.properties[name] += value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const [abil_id, abil] of atree_merged.entries()) {
|
||||||
|
if (abil.effects.length == 0) { continue; }
|
||||||
|
|
||||||
|
for (const effect of abil.effects) {
|
||||||
|
switch (effect.type) {
|
||||||
|
case 'raw_stat':
|
||||||
|
if (effect.toggle) {
|
||||||
|
const button = button_map.get(effect.toggle).button;
|
||||||
|
if (!button.classList.contains("toggleOn")) { continue; }
|
||||||
|
for (const bonus of effect.bonuses) {
|
||||||
|
apply_bonus(bonus, bonus.value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const bonus of effect.bonuses) {
|
||||||
|
// Stat was applied earlier...
|
||||||
|
if (bonus.type === 'stat') { continue; }
|
||||||
|
apply_bonus(bonus, bonus.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
case 'stat_scaling':
|
||||||
|
let total = 0;
|
||||||
|
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?
|
||||||
|
for (const [_scaling, input] of zip2(scaling, effect.inputs)) {
|
||||||
|
total += _scaling * pre_scale_stats.get(input.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('output' in effect) { // sometimes nodes will modify slider without having effect.
|
||||||
|
if (round) { total = Math.floor(round_near(total)); }
|
||||||
|
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) {
|
||||||
|
apply_bonus(output, total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
apply_bonus(effect.output, total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [atree_edit, ret_effects];
|
||||||
|
}
|
||||||
|
})().link_to(atree_merge, 'atree-merged').link_to(atree_make_interactives, 'atree-interactive');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These following two nodes are just boilerplate that breaks down the scaling node.
|
||||||
|
*/
|
||||||
|
const atree_scaling_tree = new (class extends ComputeNode {
|
||||||
|
constructor() { super('atree-scaling-tree'); }
|
||||||
|
|
||||||
|
compute_func(input_map) {
|
||||||
|
const [[tree, stats]] = input_map.values();
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
})().link_to(atree_scaling, 'atree-scaling');
|
||||||
|
const atree_scaling_stats = new (class extends ComputeNode {
|
||||||
|
constructor() { super('atree-scaling-stats'); }
|
||||||
|
|
||||||
|
compute_func(input_map) {
|
||||||
|
const [[tree, stats]] = input_map.values();
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
})().link_to(atree_scaling, 'atree-scaling');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render ability tree.
|
* Render ability tree.
|
||||||
* Return map of id -> corresponding html element.
|
* Return map of id -> corresponding html element.
|
||||||
|
@ -506,7 +713,8 @@ const atree_render_active = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
return ret_map;
|
return ret_map;
|
||||||
}
|
}
|
||||||
})().link_to(atree_node, 'atree-order').link_to(atree_merge, 'atree-merged').link_to(atree_validate, 'atree-errors');
|
})().link_to(atree_node, 'atree-order').link_to(atree_scaling_tree, 'atree-merged').link_to(atree_validate, 'atree-errors');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect spells from abilities.
|
* Collect spells from abilities.
|
||||||
|
@ -521,13 +729,29 @@ const atree_collect_spells = new (class extends ComputeNode {
|
||||||
const [hard_error, errors] = input_map.get('atree-errors');
|
const [hard_error, errors] = input_map.get('atree-errors');
|
||||||
if (hard_error) { return []; }
|
if (hard_error) { return []; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse out "parametrized entries".
|
||||||
|
* Straight replace.
|
||||||
|
*
|
||||||
|
* Format: ability_id.propname
|
||||||
|
*/
|
||||||
|
function translate(v) {
|
||||||
|
if (typeof v === 'string') {
|
||||||
|
const [id_str, propname] = v.split('.');
|
||||||
|
const id = parseInt(id_str);
|
||||||
|
const ret = atree_merged.get(id).properties[propname];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
let ret_spells = new Map();
|
let ret_spells = new Map();
|
||||||
for (const [abil_id, abil] of atree_merged.entries()) {
|
for (const [abil_id, abil] of atree_merged.entries()) {
|
||||||
// TODO: Possibly, make a better way for detecting "spell abilities"?
|
// TODO: Possibly, make a better way for detecting "spell abilities"?
|
||||||
for (const effect of abil.effects) {
|
for (const effect of abil.effects) {
|
||||||
if (effect.type === 'replace_spell') {
|
if (effect.type === 'replace_spell') {
|
||||||
// replace_spell just replaces all (defined) aspects.
|
// replace_spell just replaces all (defined) aspects.
|
||||||
const ret_spell = ret_spells.get(effect.base_spell);
|
let ret_spell = ret_spells.get(effect.base_spell);
|
||||||
if (ret_spell) {
|
if (ret_spell) {
|
||||||
// NOTE: do not mutate results of previous steps!
|
// NOTE: do not mutate results of previous steps!
|
||||||
for (const key in effect) {
|
for (const key in effect) {
|
||||||
|
@ -535,7 +759,15 @@ const atree_collect_spells = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret_spells.set(effect.base_spell, deepcopy(effect));
|
ret_spell = deepcopy(effect);
|
||||||
|
ret_spells.set(effect.base_spell, ret_spell);
|
||||||
|
}
|
||||||
|
for (const part of ret_spell.parts) {
|
||||||
|
if ('hits' in part) {
|
||||||
|
for (const idx in part.hits) {
|
||||||
|
part.hits[idx] = translate(part.hits[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -572,7 +804,8 @@ const atree_collect_spells = new (class extends ComputeNode {
|
||||||
part.power += effect.power;
|
part.power += effect.power;
|
||||||
}
|
}
|
||||||
else if ('hits' in effect) {
|
else if ('hits' in effect) {
|
||||||
for (const [idx, v] of Object.entries(effect.hits)) { // looks kinda similar to multipliers case... hmm... can we unify all of these three? (make healpower a list)
|
for (const [idx, _v] of Object.entries(effect.hits)) { // looks kinda similar to multipliers case... hmm... can we unify all of these three? (make healpower a list)
|
||||||
|
let v = translate(_v);
|
||||||
if (idx in part.hits) { part.hits[idx] += v; }
|
if (idx in part.hits) { part.hits[idx] += v; }
|
||||||
else { part.hits[idx] = v; }
|
else { part.hits[idx] = v; }
|
||||||
}
|
}
|
||||||
|
@ -586,6 +819,11 @@ const atree_collect_spells = new (class extends ComputeNode {
|
||||||
if (!found_part && behavior === 'merge') { // add part. if behavior is merge
|
if (!found_part && behavior === 'merge') { // add part. if behavior is merge
|
||||||
let spell_part = deepcopy(effect);
|
let spell_part = deepcopy(effect);
|
||||||
spell_part.name = target_part; // has some extra fields but whatever
|
spell_part.name = target_part; // has some extra fields but whatever
|
||||||
|
if ('hits' in spell_part) {
|
||||||
|
for (const idx in spell_part.hits) {
|
||||||
|
spell_part.hits[idx] = translate(spell_part.hits[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
ret_spell.parts.push(spell_part);
|
ret_spell.parts.push(spell_part);
|
||||||
}
|
}
|
||||||
if ('display' in effect) {
|
if ('display' in effect) {
|
||||||
|
@ -617,185 +855,16 @@ const atree_collect_spells = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
return ret_spells;
|
return ret_spells;
|
||||||
}
|
}
|
||||||
})().link_to(atree_merge, 'atree-merged').link_to(atree_validate, 'atree-errors');
|
})().link_to(atree_scaling_tree, 'atree-merged').link_to(atree_validate, 'atree-errors');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make interactive elements (sliders, buttons)
|
* Collect raw stats from ability tree.
|
||||||
*
|
|
||||||
* Signature: AbilityActiveUINode(atree-merged: MergedATree) => Map<str, slider_info>
|
|
||||||
*
|
|
||||||
* ElemState: {
|
|
||||||
* value: int // value for sliders; 0-1 for toggles
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
const atree_make_interactives = new (class extends ComputeNode {
|
|
||||||
constructor() { super('atree-make-interactives'); }
|
|
||||||
|
|
||||||
compute_func(input_map) {
|
|
||||||
const merged_abils = input_map.get('atree-merged');
|
|
||||||
const atree_order = input_map.get('atree-order');
|
|
||||||
const atree_html = input_map.get('atree-elements');
|
|
||||||
|
|
||||||
document.getElementById("boost-sliders").innerHTML = "";
|
|
||||||
document.getElementById("boost-toggles").innerHTML = "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* slider_info
|
|
||||||
* label_name: str,
|
|
||||||
* max: int,
|
|
||||||
* step: int,
|
|
||||||
* id: str,
|
|
||||||
* abil: atree_node
|
|
||||||
* slider: html element
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
// Map<str, slider_info>
|
|
||||||
const slider_map = new Map();
|
|
||||||
const button_map = new Map();
|
|
||||||
|
|
||||||
// first, pull out all the sliders and toggles.
|
|
||||||
for (const [abil_id, ability] of merged_abils.entries()) {
|
|
||||||
for (const effect of ability.effects) {
|
|
||||||
if (effect['type'] === "stat_scaling" && effect['slider'] === true) {
|
|
||||||
const { slider_name, slider_behavior = 'merge', slider_max, slider_step } = effect;
|
|
||||||
if (slider_map.has(slider_name)) {
|
|
||||||
if (slider_max !== undefined) {
|
|
||||||
const slider_info = slider_map.get(slider_name);
|
|
||||||
slider_info.max += slider_max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (slider_behavior === 'merge') {
|
|
||||||
slider_map.set(slider_name, {
|
|
||||||
label_name: slider_name+' ('+ability.display_name+')',
|
|
||||||
max: slider_max,
|
|
||||||
step: slider_step,
|
|
||||||
id: "ability-slider"+ability.id,
|
|
||||||
//color: effect['slider_color'] TODO: add colors to json
|
|
||||||
abil: ability
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (effect['type'] === "raw_stat" && effect['toggle']) {
|
|
||||||
const { toggle: toggle_name } = effect;
|
|
||||||
button_map.set(toggle_name, {
|
|
||||||
abil: ability
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// next, render the sliders and toggles onto the abilities.
|
|
||||||
for (const [slider_name, slider_info] of slider_map.entries()) {
|
|
||||||
let slider_container = gen_slider_labeled(slider_info);
|
|
||||||
document.getElementById("boost-sliders").appendChild(slider_container);
|
|
||||||
slider_info.slider = document.getElementById(slider_info.id);
|
|
||||||
slider_info.slider.addEventListener("change", (e) => atree_scaling.mark_dirty().update());
|
|
||||||
}
|
|
||||||
for (const [button_name, button_info] of button_map.entries()) {
|
|
||||||
let button = make_elem('button', ["button-boost", "border-0", "text-white", "dark-8u", "dark-shadow-sm", "m-1"], {
|
|
||||||
id: button_info.abil.id,
|
|
||||||
textContent: button_name
|
|
||||||
});
|
|
||||||
button.addEventListener("click", (e) => {
|
|
||||||
if (button.classList.contains("toggleOn")) {
|
|
||||||
button.classList.remove("toggleOn");
|
|
||||||
} else {
|
|
||||||
button.classList.add("toggleOn");
|
|
||||||
}
|
|
||||||
atree_scaling.mark_dirty().update()
|
|
||||||
});
|
|
||||||
button_info.button = button;
|
|
||||||
document.getElementById("boost-toggles").appendChild(button);
|
|
||||||
}
|
|
||||||
return [slider_map, button_map];
|
|
||||||
}
|
|
||||||
})().link_to(atree_node, 'atree-order').link_to(atree_merge, 'atree-merged').link_to(atree_render_active, 'atree-elements');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scaling stats from ability tree.
|
|
||||||
* Return StatMap of added stats,
|
|
||||||
*
|
|
||||||
* Signature: AbilityTreeScalingNode(atree-merged: MergedATree, scale-scats: StatMap,
|
|
||||||
* atree-interactive: [Map<str, slider_info>, Map<str, button_info>]) => StatMap
|
|
||||||
*/
|
|
||||||
const atree_scaling = new (class extends ComputeNode {
|
|
||||||
constructor() { super('atree-scaling-collector'); }
|
|
||||||
|
|
||||||
compute_func(input_map) {
|
|
||||||
const atree_merged = input_map.get('atree-merged');
|
|
||||||
const pre_scale_stats = input_map.get('scale-stats');
|
|
||||||
const [slider_map, button_map] = input_map.get('atree-interactive');
|
|
||||||
|
|
||||||
let ret_effects = new Map();
|
|
||||||
for (const [abil_id, abil] of atree_merged.entries()) {
|
|
||||||
if (abil.effects.length == 0) { continue; }
|
|
||||||
|
|
||||||
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 {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?
|
|
||||||
for (const [_scaling, input] of zip2(scaling, effect.inputs)) {
|
|
||||||
total += _scaling * pre_scale_stats.get(input.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('output' in effect) { // sometimes nodes will modify slider without having effect.
|
|
||||||
if (round) { total = Math.floor(round_near(total)); }
|
|
||||||
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) {
|
|
||||||
if (output.type === 'stat') { // TODO: prop
|
|
||||||
merge_stat(ret_effects, output.name, total);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (effect.output.type === 'stat') {
|
|
||||||
merge_stat(ret_effects, effect.output.name, total);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret_effects;
|
|
||||||
}
|
|
||||||
})().link_to(atree_merge, 'atree-merged').link_to(atree_make_interactives, 'atree-interactive');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collect stats from ability tree.
|
|
||||||
* Return StatMap of added stats.
|
* Return StatMap of added stats.
|
||||||
*
|
*
|
||||||
* Signature: AbilityTreeStatsNode(atree-merged: MergedATree) => StatMap
|
* Signature: AbilityTreeStatsNode(atree-merged: MergedATree) => StatMap
|
||||||
*/
|
*/
|
||||||
const atree_stats = new (class extends ComputeNode {
|
const atree_raw_stats = new (class extends ComputeNode {
|
||||||
constructor() { super('atree-stats-collector'); }
|
constructor() { super('atree-raw-stats-collector'); }
|
||||||
|
|
||||||
compute_func(input_map) {
|
compute_func(input_map) {
|
||||||
const atree_merged = input_map.get('atree-merged');
|
const atree_merged = input_map.get('atree-merged');
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
@ -17,6 +17,8 @@ let armor_powder_node = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
const damageMultipliers = new Map([ ["totem", .2], ["warscream", 0.0], ["ragnarokkr", 0.30], ["fortitude", 0.60] ]);
|
||||||
|
|
||||||
let boosts_node = new (class extends ComputeNode {
|
let boosts_node = new (class extends ComputeNode {
|
||||||
constructor() { super('builder-boost-input'); }
|
constructor() { super('builder-boost-input'); }
|
||||||
|
|
||||||
|
@ -887,6 +889,17 @@ class EditableIDSetterNode extends ComputeNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overriding this to bridge the transparent gap.
|
||||||
|
*/
|
||||||
|
mark_dirty(dirty_state=2) {
|
||||||
|
super.mark_dirty(dirty_state);
|
||||||
|
for (const node of this.notify_nodes) {
|
||||||
|
node.mark_dirty(dirty_state);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
notify() {
|
notify() {
|
||||||
this.mark_dirty();
|
this.mark_dirty();
|
||||||
this.update();
|
this.update();
|
||||||
|
@ -1068,10 +1081,10 @@ function builder_graph_init() {
|
||||||
// These two are defined in `atree.js`
|
// These two are defined in `atree.js`
|
||||||
atree_node.link_to(class_node, 'player-class');
|
atree_node.link_to(class_node, 'player-class');
|
||||||
atree_merge.link_to(class_node, 'player-class');
|
atree_merge.link_to(class_node, 'player-class');
|
||||||
pre_scale_agg_node.link_to(atree_stats, 'atree-raw-stats');
|
pre_scale_agg_node.link_to(atree_raw_stats, 'atree-raw-stats');
|
||||||
atree_scaling.link_to(pre_scale_agg_node, 'scale-stats');
|
atree_scaling.link_to(pre_scale_agg_node, 'scale-stats');
|
||||||
stat_agg_node.link_to(pre_scale_agg_node, 'pre-scaling');
|
stat_agg_node.link_to(pre_scale_agg_node, 'pre-scaling');
|
||||||
stat_agg_node.link_to(atree_scaling, 'atree-scaling');
|
stat_agg_node.link_to(atree_scaling_stats, 'atree-scaling');
|
||||||
|
|
||||||
build_encode_node.link_to(atree_node, 'atree').link_to(atree_state_node, 'atree-state');
|
build_encode_node.link_to(atree_node, 'atree').link_to(atree_state_node, 'atree-state');
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
let all_nodes = new Set();
|
let all_nodes = new Set();
|
||||||
let node_debug_stack = [];
|
let node_debug_stack = [];
|
||||||
let COMPUTE_GRAPH_DEBUG = false;
|
let COMPUTE_GRAPH_DEBUG = true;
|
||||||
class ComputeNode {
|
class ComputeNode {
|
||||||
/**
|
/**
|
||||||
* Make a generic compute node.
|
* Make a generic compute node.
|
||||||
|
@ -15,7 +15,7 @@ class ComputeNode {
|
||||||
this.value = null;
|
this.value = null;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.update_task = null;
|
this.update_task = null;
|
||||||
this.fail_cb = false; // Set to true to force updates even if parent failed.
|
this.fail_cb = false; // Set to true to force updates even if parent failed
|
||||||
this.dirty = 2; // 3 states:
|
this.dirty = 2; // 3 states:
|
||||||
// 2: dirty
|
// 2: dirty
|
||||||
// 1: possibly dirty
|
// 1: possibly dirty
|
||||||
|
@ -39,6 +39,13 @@ class ComputeNode {
|
||||||
if (this.dirty == 2) {
|
if (this.dirty == 2) {
|
||||||
let calc_inputs = new Map();
|
let calc_inputs = new Map();
|
||||||
for (const input of this.inputs) {
|
for (const input of this.inputs) {
|
||||||
|
if (input.dirty) {
|
||||||
|
if (COMPUTE_GRAPH_DEBUG) {
|
||||||
|
console.log(node_debug_stack);
|
||||||
|
console.log(this);
|
||||||
|
}
|
||||||
|
throw "Invalid compute graph state!";
|
||||||
|
}
|
||||||
calc_inputs.set(this.input_translation.get(input.name), input.value);
|
calc_inputs.set(this.input_translation.get(input.name), input.value);
|
||||||
}
|
}
|
||||||
this.value = this.compute_func(calc_inputs);
|
this.value = this.compute_func(calc_inputs);
|
||||||
|
@ -213,7 +220,7 @@ class PrintNode extends ComputeNode {
|
||||||
*
|
*
|
||||||
* Signature: InputNode() => str
|
* Signature: InputNode() => str
|
||||||
*/
|
*/
|
||||||
class InputNode extends ComputeNode {
|
class InputNode extends ValueCheckComputeNode {
|
||||||
constructor(name, input_field) {
|
constructor(name, input_field) {
|
||||||
super(name);
|
super(name);
|
||||||
this.input_field = input_field;
|
this.input_field = input_field;
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
* File implementing core damage calculation logic.
|
* File implementing core damage calculation logic.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const damageMultipliers = new Map([ ["allytotem", .15], ["yourtotem", .35], ["warscream", 0.00], ["ragnarokkr", 0.30], ["fortitude", 0.60] ]);
|
|
||||||
|
|
||||||
function get_base_dps(item) {
|
function get_base_dps(item) {
|
||||||
const attack_speed_mult = baseDamageMultiplier[attackSpeeds.indexOf(item.get("atkSpd"))];
|
const attack_speed_mult = baseDamageMultiplier[attackSpeeds.indexOf(item.get("atkSpd"))];
|
||||||
//SUPER JANK @HPP PLS FIX
|
//SUPER JANK @HPP PLS FIX
|
||||||
|
@ -260,8 +258,9 @@ spell_heal: {
|
||||||
spell_total: {
|
spell_total: {
|
||||||
name: str != "total" Name of the part.
|
name: str != "total" Name of the part.
|
||||||
type: "total" [TODO: DEPRECATED/REMOVE] flag signaling what type of part it is. Can infer from fields
|
type: "total" [TODO: DEPRECATED/REMOVE] flag signaling what type of part it is. Can infer from fields
|
||||||
hits: Map[str, num] Keys are other part names, numbers are the multipliers. Undefined behavior if subparts
|
hits: Map[str, Union[str, num]] Keys are other part names, numbers are the multipliers. Undefined behavior if subparts
|
||||||
are not the same type of spell. Can only pull from spells defined before it.
|
are not the same type of spell. Can only pull from spells defined before it.
|
||||||
|
Alternatively, a property reference of the format <ability_id>.propname
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,25 @@ def translate_id(id_data, atree_data):
|
||||||
for bonus in effect["bonuses"]:
|
for bonus in effect["bonuses"]:
|
||||||
if "abil" in bonus and bonus["abil"] in id_data[_class]:
|
if "abil" in bonus and bonus["abil"] in id_data[_class]:
|
||||||
bonus["abil"] = id_data[_class][bonus["abil"]]
|
bonus["abil"] = id_data[_class][bonus["abil"]]
|
||||||
|
elif effect["type"] == "replace_spell":
|
||||||
|
for part in effect['parts']:
|
||||||
|
if 'hits' in part: # Translate parametrized hits...
|
||||||
|
hits_mapping = part['hits']
|
||||||
|
keys = list(hits_mapping.keys())
|
||||||
|
for k in keys:
|
||||||
|
v = hits_mapping[k]
|
||||||
|
if isinstance(v, str):
|
||||||
|
abil_id, propname = v.split('.')
|
||||||
|
hits_mapping[k] = str(id_data[_class][abil_id])+'.'+propname
|
||||||
|
elif effect["type"] == "add_spell_prop":
|
||||||
|
if 'hits' in effect: # Translate parametrized hits...
|
||||||
|
hits_mapping = effect['hits']
|
||||||
|
keys = list(hits_mapping.keys())
|
||||||
|
for k in keys:
|
||||||
|
v = hits_mapping[k]
|
||||||
|
if isinstance(v, str):
|
||||||
|
abil_id, propname = v.split('.')
|
||||||
|
hits_mapping[k] = str(id_data[_class][abil_id])+'.'+propname
|
||||||
elif effect["type"] == "stat_scaling":
|
elif effect["type"] == "stat_scaling":
|
||||||
if "inputs" in effect: # Might not exist for sliders
|
if "inputs" in effect: # Might not exist for sliders
|
||||||
for _input in effect["inputs"]:
|
for _input in effect["inputs"]:
|
||||||
|
|
Loading…
Reference in a new issue