Merge branch 'atree' of https://github.com/hppeng-wynn/hppeng-wynn.github.io into mobile_ui_tweaks
493
builder/doc.html
|
@ -5,17 +5,6 @@
|
||||||
<meta name="HandheldFriendly" content="true" />
|
<meta name="HandheldFriendly" content="true" />
|
||||||
<meta name="MobileOptimized" content="320" />
|
<meta name="MobileOptimized" content="320" />
|
||||||
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width, user-scalable=no" />
|
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width, user-scalable=no" />
|
||||||
|
|
||||||
<!--OGP suite
|
|
||||||
<meta property="og:title" content="Wynnbuilder" />
|
|
||||||
<meta property="og:type" content="website" />
|
|
||||||
<meta property="og:image" content="https://wynnbuilder.github.io/media/icons/new/builder.png" />
|
|
||||||
<meta property="og:image:width" content="420" />
|
|
||||||
<meta property="og:image:height" content="420" />
|
|
||||||
<meta property="og:image:type" content="image/png" />
|
|
||||||
<meta property="og:description" id = "ogp-build-list" content = "">
|
|
||||||
<meta property="og:url" id = "ogp-url" content="" />
|
|
||||||
-->
|
|
||||||
|
|
||||||
<title>WynnBuilder</title>
|
<title>WynnBuilder</title>
|
||||||
<link rel="icon" href="../media/icons/new/builder.png" type="image/icon type">
|
<link rel="icon" href="../media/icons/new/builder.png" type="image/icon type">
|
||||||
|
@ -35,8 +24,6 @@
|
||||||
<link rel="stylesheet" href="../css/wynnstyles.css">
|
<link rel="stylesheet" href="../css/wynnstyles.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="text-light" id = "body">
|
<body class="text-light" id = "body">
|
||||||
<!-- hover tooltip stuff -->
|
|
||||||
|
|
||||||
<!-- main -->
|
<!-- main -->
|
||||||
<div id="main-sidebar" class="sidebar dark-7 dark-shadow">
|
<div id="main-sidebar" class="sidebar dark-7 dark-shadow">
|
||||||
<a href = ""><img src="../media/icons/new/builder.png" alt = "WynnBuilder" title = "WynnBuilder"><b>WynnBuilder</b></a>
|
<a href = ""><img src="../media/icons/new/builder.png" alt = "WynnBuilder" title = "WynnBuilder"><b>WynnBuilder</b></a>
|
||||||
|
@ -422,6 +409,186 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row row-cols-1 gy-4">
|
<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="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">
|
||||||
|
@ -960,265 +1127,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<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">
|
|
||||||
Active boosts
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
|
||||||
<div class="row row-cols-2 row-cols-xl-0 text-nowrap justify-content-center">
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class="button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id="vanish-boost" onclick="update_boosts('vanish-boost')">
|
|
||||||
Vanish (+80%)
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class="button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id="warscream-boost" onclick="update_boosts('warscream-boost')">
|
|
||||||
War Scream
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class="button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id="ragnarokkr-boost" onclick="update_boosts('ragnarokkr-boost')">
|
|
||||||
Ragnarokkr (+30%)
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class="button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id="yourtotem-boost" onclick="update_boosts('yourtotem-boost')">
|
|
||||||
Your Totem (+35%)
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class="button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id="allytotem-boost" onclick="update_boosts('allytotem-boost')">
|
|
||||||
Ally Totem (+15%)
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class="button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id="fortitude-boost" onclick="update_boosts('fortitude-boost')">
|
|
||||||
Fortitude (+60%)
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col mb-1">
|
|
||||||
<div class="row row-cols-1 rounded text-center dark-5 scaled-font">
|
|
||||||
<div class="col">
|
|
||||||
<div class="row 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>
|
|
||||||
<div class="col" id="str-boost" style="display: none;">
|
|
||||||
<div class="row row-cols-1">
|
|
||||||
<div class="col eDam dark-5">
|
|
||||||
Quake (Active)
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
|
||||||
<div class="row row-cols-2 row-cols-xl-0 text-nowrap justify-content-center">
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-1" onclick = "updatePowderSpecials('Quake-1')">
|
|
||||||
Lv.4 [e4e4]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-2" onclick = "updatePowderSpecials('Quake-2')">
|
|
||||||
Lv.4.5 [e5e4]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-3" onclick = "updatePowderSpecials('Quake-3')">
|
|
||||||
Lv.5 [e5e5]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-4" onclick = "updatePowderSpecials('Quake-4')">
|
|
||||||
Lv.5.5 [e6e5]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Quake-5" onclick = "updatePowderSpecials('Quake-5')">
|
|
||||||
Lv.6 [e6e6]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col eDam">
|
|
||||||
Rage (Passive)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col" id="dex-boost" style="display: none;">
|
|
||||||
<div class="row row-cols-1">
|
|
||||||
<div class="col tDam dark-5">
|
|
||||||
Chain Lightning (Active)
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
|
||||||
<div class="row row-cols-2 row-cols-xl-0 text-nowrap justify-content-center">
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-1" onclick = "updatePowderSpecials('Chain_Lightning-1')">
|
|
||||||
Lv.4 [t4t4]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-2" onclick = "updatePowderSpecials('Chain_Lightning-2')">
|
|
||||||
Lv.4.5 [t5t4]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-3" onclick = "updatePowderSpecials('Chain_Lightning-3')">
|
|
||||||
Lv.5 [t5t5]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-4" onclick = "updatePowderSpecials('Chain_Lightning-4')">
|
|
||||||
Lv.5.5 [t6t5]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Chain_Lightning-5" onclick = "updatePowderSpecials('Chain_Lightning-5')">
|
|
||||||
Lv.6 [t6t6]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col tDam">
|
|
||||||
Kill Streak (Passive)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col" id="int-boost">
|
|
||||||
<div class="row row-cols-1">
|
|
||||||
<div class="col wDam dark-5">
|
|
||||||
Curse (Active)
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
|
||||||
<div class="row row-cols-2 row-cols-xl-0 text-nowrap justify-content-center">
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-1" onclick = "updatePowderSpecials('Curse-1')">
|
|
||||||
Lv.4 [w4w4]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-2" onclick = "updatePowderSpecials('Curse-2')">
|
|
||||||
Lv.4.5 [w5w4]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-3" onclick = "updatePowderSpecials('Curse-3')">
|
|
||||||
Lv.5 [w5w5]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-4" onclick = "updatePowderSpecials('Curse-4')">
|
|
||||||
Lv.5.5 [w6w5]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Curse-5" onclick = "updatePowderSpecials('Curse-5')">
|
|
||||||
Lv.6 [w6w6]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col wDam">
|
|
||||||
Concentration (Passive)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col" id="def-boost" style="display: none;">
|
|
||||||
<div class="row row-cols-1">
|
|
||||||
<div class="col fDam dark-5">
|
|
||||||
Courage (Active)
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
|
||||||
<div class="row row-cols-2 row-cols-xl-0 text-nowrap justify-content-center">
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-1" onclick = "updatePowderSpecials('Courage-1')">
|
|
||||||
Lv.4 [f4f4]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-2" onclick = "updatePowderSpecials('Courage-2')">
|
|
||||||
Lv.4.5 [f5f4]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-3" onclick = "updatePowderSpecials('Courage-3')">
|
|
||||||
Lv.5 [f5f5]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-4" onclick = "updatePowderSpecials('Courage-4')">
|
|
||||||
Lv.5.5 [f6f5]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Courage-5" onclick = "updatePowderSpecials('Courage-5')">
|
|
||||||
Lv.6 [f6f6]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col fDam">
|
|
||||||
Endurance (Passive)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col" id="agi-boost" style="display: none;">
|
|
||||||
<div class="row row-cols-1">
|
|
||||||
<div class="col aDam dark-5">
|
|
||||||
Wind Prison (Active)
|
|
||||||
</div>
|
|
||||||
<div class="col skp-tooltip dark-6 rounded-bottom my-3 my-xl-1">
|
|
||||||
<div class="row row-cols-2 row-cols-xl-0 text-nowrap justify-content-center">
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-1" onclick = "updatePowderSpecials('Wind_Prison-1')">
|
|
||||||
Lv.4 [a4a4]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-2" onclick = "updatePowderSpecials('Wind_Prison-2')">
|
|
||||||
Lv.4.5 [a5a4]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-3" onclick = "updatePowderSpecials('Wind_Prison-3')">
|
|
||||||
Lv.5 [a5a5]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-4" onclick = "updatePowderSpecials('Wind_Prison-4')">
|
|
||||||
Lv.5.5 [a6a5]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto p-1">
|
|
||||||
<button class = "button-boost w-100 border-0 text-white dark-8u dark-shadow-sm" id = "Wind_Prison-5" onclick = "updatePowderSpecials('Wind_Prison-5')">
|
|
||||||
Lv.6 [a6a6]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col aDam">
|
|
||||||
Dodge (Passive)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1244,23 +1152,17 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-3 mb-3 px-0">
|
<div class="col-xl-3 mb-3 px-0">
|
||||||
|
<div id="all-spells-display" class="row row-cols-1 gy-3 mb-4 text-center scaled-font">
|
||||||
|
<div class = "col pe-0">
|
||||||
|
<div class = "col spell-display spell-expand dark-5 rounded dark-shadow pt-2 border border-dark" id="spell0-infoAvg">Input a weapon to see abilities!</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 gy-3 mb-4 text-center scaled-font" id="build-poison-stats" style="display: none">
|
||||||
|
</div>
|
||||||
<div class="row row-cols-1 gy-3 mb-4 text-center scaled-font">
|
<div class="row row-cols-1 gy-3 mb-4 text-center scaled-font">
|
||||||
<div class = "col">
|
<div class = "col pe-0">
|
||||||
<div class = "spell-display spell-expand dark-5 rounded dark-shadow py-2 border border-dark" id="build-melee-statsAvg">melee</div>
|
<div class="col pe-0 spell-display dark-5 rounded dark-shadow py-2 border border-dark" id="powder-special-stats"></div>
|
||||||
<div class = "spell-display dark-5 rounded-bottom py-2 dark-shadow" id = "build-melee-stats" style="display: none;"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class = "col">
|
|
||||||
<div class = "col spell-display dark-5 rounded dark-shadow py-2 border border-dark" id="build-poison-stats">poison</div>
|
|
||||||
</div>
|
|
||||||
<div id="all-spells-display" class="row row-cols-1 gy-3 text-center scaled-font pe-0">
|
|
||||||
<div class = "col pe-0">
|
|
||||||
<div class = "col spell-display spell-expand dark-5 rounded dark-shadow pt-2 border border-dark" id="spell0-infoAvg">Input a weapon to see abilities!</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class = "col">
|
|
||||||
<div class = "spell-display dark-5 rounded dark-shadow py-2 border border-dark" id = "powder-special-stats"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1284,20 +1186,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="weapon-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
<div id="weapon-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
||||||
</div>
|
</div>
|
||||||
<!--div id="weaponTome1-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="weaponTome2-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="armorTome1-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="armorTome2-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="armorTome3-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="armorTome4-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="guildTome1-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div-->
|
|
||||||
<div class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3" id = "build-order">
|
<div class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3" id = "build-order">
|
||||||
</div>
|
</div>
|
||||||
<div class = "rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark p-3" id = "set-info"></div>
|
<div class = "rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark p-3" id = "set-info"></div>
|
||||||
|
@ -1364,10 +1252,8 @@
|
||||||
<div class = "row box-title justify-content-center my-1" id = "summary">
|
<div class = "row box-title justify-content-center my-1" id = "summary">
|
||||||
</div>
|
</div>
|
||||||
<div class = "row" id = "search-results">
|
<div class = "row" id = "search-results">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1376,6 +1262,7 @@
|
||||||
<script type="text/javascript" src="../js/utils.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/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" 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/sq2icons.js"></script>
|
||||||
<script type="text/javascript" src="../js/powders.js"></script>
|
<script type="text/javascript" src="../js/powders.js"></script>
|
||||||
|
|
|
@ -5,17 +5,6 @@
|
||||||
<meta name="HandheldFriendly" content="true" />
|
<meta name="HandheldFriendly" content="true" />
|
||||||
<meta name="MobileOptimized" content="320" />
|
<meta name="MobileOptimized" content="320" />
|
||||||
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width, user-scalable=no" />
|
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width, user-scalable=no" />
|
||||||
|
|
||||||
<!--OGP suite
|
|
||||||
<meta property="og:title" content="Wynnbuilder" />
|
|
||||||
<meta property="og:type" content="website" />
|
|
||||||
<meta property="og:image" content="https://wynnbuilder.github.io/media/icons/new/builder.png" />
|
|
||||||
<meta property="og:image:width" content="420" />
|
|
||||||
<meta property="og:image:height" content="420" />
|
|
||||||
<meta property="og:image:type" content="image/png" />
|
|
||||||
<meta property="og:description" id = "ogp-build-list" content = "">
|
|
||||||
<meta property="og:url" id = "ogp-url" content="" />
|
|
||||||
-->
|
|
||||||
|
|
||||||
<title>WynnBuilder</title>
|
<title>WynnBuilder</title>
|
||||||
<link rel="icon" href="../media/icons/new/builder.png" type="image/icon type">
|
<link rel="icon" href="../media/icons/new/builder.png" type="image/icon type">
|
||||||
|
@ -35,8 +24,6 @@
|
||||||
<link rel="stylesheet" href="../css/wynnstyles.css">
|
<link rel="stylesheet" href="../css/wynnstyles.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="text-light" id = "body">
|
<body class="text-light" id = "body">
|
||||||
<!-- hover tooltip stuff -->
|
|
||||||
|
|
||||||
<!-- main -->
|
<!-- main -->
|
||||||
<div id="main-sidebar" class="sidebar dark-7 dark-shadow">
|
<div id="main-sidebar" class="sidebar dark-7 dark-shadow">
|
||||||
<a href = ""><img src="../media/icons/new/builder.png" alt = "WynnBuilder" title = "WynnBuilder"><b>WynnBuilder</b></a>
|
<a href = ""><img src="../media/icons/new/builder.png" alt = "WynnBuilder" title = "WynnBuilder"><b>WynnBuilder</b></a>
|
||||||
|
@ -49,12 +36,12 @@
|
||||||
<hr/>
|
<hr/>
|
||||||
<a href = "https://discord.gg/CGavnAnerv" target = "_blank"><img src = "../media/icons/discord.png" alt = "WB Discord" title = "WB Discord"><b>WB Discord</b></a>
|
<a href = "https://discord.gg/CGavnAnerv" target = "_blank"><img src = "../media/icons/discord.png" alt = "WB Discord" title = "WB Discord"><b>WB Discord</b></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="container-fluid me-4" style="max-width: 95%;">
|
<div class="container-fluid overall-box">
|
||||||
<!-- REMOVE THIS DIV AT SOME POINT. -->
|
<!-- REMOVE THIS DIV AT SOME POINT. -->
|
||||||
<div class = "row scaled-font mx-auto" id = "discord-banner-dev">
|
<div class = "row scaled-font mx-auto" id = "discord-banner-dev">
|
||||||
<div class = "col text-center item-title">Join the <a class = "link" href = "https://discord.gg/CGavnAnerv" target = "_blank">discord</a> today to suggest new features, submit bug reports, and hangout/talk to devs!</div>
|
<div class = "col text-center item-title">Join the <a class = "link" href = "https://discord.gg/CGavnAnerv" target = "_blank">discord</a> today to suggest new features, submit bug reports, and hangout/talk to devs!</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row h-100 gx-lg-5 gy-3 mx-2 mx-lg-3 py-3">
|
<div class="row h-100 gx-lg-5 gy-3 mx-2 mx-lg-3 py-3 gx-0">
|
||||||
<div class="col-xl-6">
|
<div class="col-xl-6">
|
||||||
<div class="row my-2 g-5 dark-6 rounded-top d-flex d-lg-none">
|
<div class="row my-2 g-5 dark-6 rounded-top d-flex d-lg-none">
|
||||||
<div class="col text-center">
|
<div class="col text-center">
|
||||||
|
@ -66,11 +53,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="row row-cols-1 mb-3 gy-4" id="equipment-inputs">
|
<div class="row row-cols-1 mb-3 gy-4" id="equipment-inputs">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row row-cols-1 row-cols-xl-2 rounded gy-4 gx-5 justify-content-center">
|
<div class="row row-cols-1 row-cols-xl-2 dark-shadow dark-6 justify-content-center equipment-input">
|
||||||
<div class="col-auto rounded order-xl-0 order-0">
|
<div class="col-auto rounded order-xl-0 order-0">
|
||||||
<div class="row h-100 dark-shadow dark-6 rounded" id="helmet-dropdown">
|
<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">
|
||||||
|
@ -95,9 +82,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="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">
|
||||||
|
@ -115,16 +102,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">
|
||||||
|
@ -149,9 +135,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">
|
||||||
|
@ -175,9 +161,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">
|
||||||
|
@ -202,9 +188,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">
|
||||||
|
@ -229,9 +215,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">
|
||||||
|
@ -256,9 +242,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">
|
||||||
|
@ -282,9 +268,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">
|
||||||
|
@ -308,29 +294,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>
|
||||||
|
@ -411,12 +393,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>
|
||||||
|
@ -431,7 +410,186 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="row row-cols-1 d-lg-flex" id="adjust-id" style="display: none;">
|
<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">
|
||||||
|
@ -463,7 +621,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">
|
||||||
|
@ -487,7 +645,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">
|
||||||
|
@ -511,7 +669,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">
|
||||||
|
@ -535,7 +693,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">
|
||||||
|
@ -559,7 +717,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">
|
||||||
|
@ -583,7 +741,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">
|
||||||
|
@ -607,7 +765,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">
|
||||||
|
@ -1241,24 +1399,18 @@
|
||||||
<div id="overall-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 order-1 order-lg-2">
|
<div class="col-xl-3 mb-3 px-0">
|
||||||
|
<div id="all-spells-display" class="row row-cols-1 gy-3 mb-4 text-center scaled-font">
|
||||||
|
<div class = "col pe-0">
|
||||||
|
<div class = "col spell-display spell-expand dark-5 rounded dark-shadow pt-2 border border-dark" id="spell0-infoAvg">Input a weapon to see abilities!</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 gy-3 mb-4 text-center scaled-font" id="build-poison-stats" style="display: none">
|
||||||
|
</div>
|
||||||
<div class="row row-cols-1 gy-3 mb-4 text-center scaled-font">
|
<div class="row row-cols-1 gy-3 mb-4 text-center scaled-font">
|
||||||
<div class = "col">
|
<div class = "col pe-0">
|
||||||
<div class = "spell-display spell-expand dark-5 rounded dark-shadow py-2 border border-dark" id="build-melee-statsAvg">melee</div>
|
<div class="col pe-0 spell-display dark-5 rounded dark-shadow py-2 border border-dark" id="powder-special-stats"></div>
|
||||||
<div class = "spell-display dark-5 rounded-bottom py-2 dark-shadow" id = "build-melee-stats" style="display: none;"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class = "col">
|
|
||||||
<div class = "col spell-display dark-5 rounded dark-shadow py-2 border border-dark" id="build-poison-stats">poison</div>
|
|
||||||
</div>
|
|
||||||
<div id="all-spells-display" class="row row-cols-1 gy-3 text-center scaled-font pe-0">
|
|
||||||
<div class = "col pe-0">
|
|
||||||
<div class = "col spell-display spell-expand dark-5 rounded dark-shadow pt-2 border border-dark" id="spell0-infoAvg">Input a weapon to see abilities!</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class = "col">
|
|
||||||
<div class = "spell-display dark-5 rounded dark-shadow py-2 border border-dark" id = "powder-special-stats"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1282,20 +1434,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="weapon-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
<div id="weapon-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
||||||
</div>
|
</div>
|
||||||
<!--div id="weaponTome1-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="weaponTome2-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="armorTome1-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="armorTome2-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="armorTome3-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="armorTome4-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div>
|
|
||||||
<div id="guildTome1-tooltip" class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3">
|
|
||||||
</div-->
|
|
||||||
<div class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3" id = "build-order">
|
<div class="rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark dark-shadow p-3" id = "build-order">
|
||||||
</div>
|
</div>
|
||||||
<div class = "rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark p-3" id = "set-info"></div>
|
<div class = "rounded row row-cols-1 g-0 scaled-font float-tooltip border border-3 border-dark p-3" id = "set-info"></div>
|
||||||
|
@ -1362,10 +1500,8 @@
|
||||||
<div class = "row box-title justify-content-center my-1" id = "summary">
|
<div class = "row box-title justify-content-center my-1" id = "summary">
|
||||||
</div>
|
</div>
|
||||||
<div class = "row" id = "search-results">
|
<div class = "row" id = "search-results">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1374,8 +1510,7 @@
|
||||||
<script type="text/javascript" src="../js/utils.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/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" 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>
|
||||||
|
|
1368
clean.json
|
@ -39,7 +39,7 @@
|
||||||
<div class="col" id="recipe-dropdown">
|
<div class="col" id="recipe-dropdown">
|
||||||
<div class="row dark-shadow dark-5 rounded">
|
<div class="row dark-shadow dark-5 rounded">
|
||||||
<div id = "recipe-img-loc" class = "col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon">
|
<div id = "recipe-img-loc" class = "col-auto px-lg-1 g-0 dark-7 rounded-end my-auto text-center scaled-item-icon">
|
||||||
<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'); image-rendering: pixelated; background-position: 25% 0; aspect-ratio: 1/1;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class = "col ps-3">
|
<div class = "col ps-3">
|
||||||
<div class = "row row-cols-2 align-items-center">
|
<div class = "row row-cols-2 align-items-center">
|
||||||
|
@ -283,7 +283,7 @@
|
||||||
<script type="text/javascript" src="../js/query_2.js"></script>
|
<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/utils.js"></script>
|
||||||
<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/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/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>
|
||||||
|
|
|
@ -14,6 +14,7 @@ Additional Contributors, in no particular order:
|
||||||
- touhoku (best IM)
|
- touhoku (best IM)
|
||||||
- HeyZeer0 (huge help in getting our damage formulas right)
|
- HeyZeer0 (huge help in getting our damage formulas right)
|
||||||
- blankman (fin444 github) (beautifying atree visuals)
|
- blankman (fin444 github) (beautifying atree visuals)
|
||||||
|
- lemonalade (ability tree pdf for us to copy from :) )
|
||||||
- Lennon (Skill point formula reversing)
|
- Lennon (Skill point formula reversing)
|
||||||
- Phanta (WynnAtlas custom expression parser / item search)
|
- Phanta (WynnAtlas custom expression parser / item search)
|
||||||
- nbcss (and WIM team) (Crafted Item mechanics reverse engineering, testing)
|
- nbcss (and WIM team) (Crafted Item mechanics reverse engineering, testing)
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
}
|
}
|
||||||
/* builder containers */
|
/* builder containers */
|
||||||
|
|
||||||
|
|
||||||
.slider {
|
.slider {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
background: #AAAAAA;
|
background: #AAAAAA;
|
||||||
|
@ -46,7 +45,6 @@ input[type=range]:focus {
|
||||||
outline: none; /* Removes the border. */
|
outline: none; /* Removes the border. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* equipment field specifics */
|
/* equipment field specifics */
|
||||||
/* inputs and dropdowns */
|
/* inputs and dropdowns */
|
||||||
.form-control {
|
.form-control {
|
||||||
|
@ -102,10 +100,15 @@ input.equipment-input {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
background-color: hsl(0, 0%, 21%) !important;
|
background-color: hsl(0, 0%, 21%) !important;
|
||||||
border-radius: 0.375rem !important;
|
border-radius: 0.375rem !important;
|
||||||
border-color: rgba(33, 37, 41, 1) !important;
|
|
||||||
min-height: calc(1.2 * var(--scaled-fontsize) + 2px);
|
min-height: calc(1.2 * var(--scaled-fontsize) + 2px);
|
||||||
padding: 0rem 0.5rem;
|
padding: 0rem 0.5rem;
|
||||||
font-size: var(--scaled-fontsize);
|
font-size: var(--scaled-fontsize);
|
||||||
|
--bs-gutter-y: 1rem;
|
||||||
|
--bs-gutter-x: 3rem
|
||||||
|
}
|
||||||
|
|
||||||
|
input.equipment-input:not(.is-invalid) {
|
||||||
|
border-color: rgba(33, 37, 41, 1) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.my-container {
|
.my-container {
|
||||||
|
@ -132,10 +135,6 @@ input.equipment-input {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spell-expand {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--scaled-fontsize: 2.5rem;
|
--scaled-fontsize: 2.5rem;
|
||||||
}
|
}
|
||||||
|
@ -178,11 +177,11 @@ input.equipment-input {
|
||||||
}
|
}
|
||||||
|
|
||||||
.scaled-item-icon {
|
.scaled-item-icon {
|
||||||
width: 8rem;
|
width: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scaled-item-icon img {
|
.scaled-item-icon img {
|
||||||
width: 6.5rem;
|
width: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scaled-bckgrd {
|
.scaled-bckgrd {
|
||||||
|
@ -191,13 +190,28 @@ input.equipment-input {
|
||||||
}
|
}
|
||||||
|
|
||||||
.scaled-bckgrd img {
|
.scaled-bckgrd img {
|
||||||
width: 6.5rem;
|
width: 7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overall-box {
|
||||||
|
max-width: 95%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1200px) and (max-width: 1400px) {
|
@media screen and (min-width: 1200px) and (max-width: 1400px) {
|
||||||
:root {
|
:root {
|
||||||
--scaled-fontsize: 1rem;
|
--scaled-fontsize: 1rem;
|
||||||
}
|
}
|
||||||
|
.overall-box {
|
||||||
|
padding-left: var(--sidebar-width);
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
.equipment-input {
|
||||||
|
--bs-gutter-y: 0.5rem;
|
||||||
|
--bs-gutter-x: 1.5rem;
|
||||||
|
}
|
||||||
|
.level-input {
|
||||||
|
margin-top: 0
|
||||||
|
}
|
||||||
.scaled-font {
|
.scaled-font {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
@ -223,11 +237,11 @@ input.equipment-input {
|
||||||
}
|
}
|
||||||
|
|
||||||
.scaled-item-icon {
|
.scaled-item-icon {
|
||||||
width: 3.2rem;
|
width: 2.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scaled-item-icon img {
|
.scaled-item-icon img {
|
||||||
width: 2.8rem;
|
width: 2.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scaled-bckgrd {
|
.scaled-bckgrd {
|
||||||
|
@ -252,6 +266,17 @@ input.equipment-input {
|
||||||
:root {
|
:root {
|
||||||
--scaled-fontsize: 1rem;
|
--scaled-fontsize: 1rem;
|
||||||
}
|
}
|
||||||
|
.overall-box {
|
||||||
|
padding-left: var(--sidebar-width);
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
.equipment-input {
|
||||||
|
--bs-gutter-y: 0.5rem;
|
||||||
|
--bs-gutter-x: 1.5rem
|
||||||
|
}
|
||||||
|
.level-input {
|
||||||
|
margin-top: 0
|
||||||
|
}
|
||||||
.scaled-font {
|
.scaled-font {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
@ -277,11 +302,11 @@ input.equipment-input {
|
||||||
}
|
}
|
||||||
|
|
||||||
.scaled-item-icon {
|
.scaled-item-icon {
|
||||||
width: 4rem;
|
width: 3.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scaled-item-icon img {
|
.scaled-item-icon img {
|
||||||
width: 3.5rem;
|
width: 2.7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scaled-bckgrd {
|
.scaled-bckgrd {
|
||||||
|
@ -293,7 +318,6 @@ input.equipment-input {
|
||||||
width: 3.5rem;
|
width: 3.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.warning {
|
.warning {
|
||||||
font-size: .8rem;
|
font-size: .8rem;
|
||||||
}
|
}
|
||||||
|
@ -464,3 +488,16 @@ a:hover {
|
||||||
.ferricles{
|
.ferricles{
|
||||||
color: #5be553;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -181,4 +181,23 @@ Wynn-Related CSS
|
||||||
|
|
||||||
.restrict {
|
.restrict {
|
||||||
color: #ff8180;
|
color: #ff8180;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Every text color in Minecraft */
|
||||||
|
|
||||||
|
.mc-black { color: #000000 !important; }
|
||||||
|
.mc-dark-blue { color: #0000AA !important; }
|
||||||
|
.mc-dark-green { color: #00AA00 !important; }
|
||||||
|
.mc-dark-aqua { color: #00AAAA !important; }
|
||||||
|
.mc-dark-red { color: #AA0000 !important; }
|
||||||
|
.mc-dark-purple { color: #AA00AA !important; }
|
||||||
|
.mc-gold { color: #FFAA00 !important; }
|
||||||
|
.mc-gray { color: #AAAAAA !important; }
|
||||||
|
.mc-dark-gray { color: #555555 !important; }
|
||||||
|
.mc-blue { color: #5555FF !important; }
|
||||||
|
.mc-green { color: #55FF55 !important; }
|
||||||
|
.mc-aqua { color: #55FFFF !important; }
|
||||||
|
.mc-red { color: #FF5555 !important; }
|
||||||
|
.mc-light-purple { color: #FF55FF !important; }
|
||||||
|
.mc-yellow { color: #FFFF55 !important; }
|
||||||
|
.mc-white { color: #FFFFFF !important; }
|
|
@ -959,7 +959,7 @@
|
||||||
</div> -->
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="../js/dev.js"></script>
|
<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>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
<script type="text/javascript" src="/js/icons.js"></script>
|
<script type="text/javascript" src="/js/icons.js"></script>
|
||||||
<script type="text/javascript" src="/js/damage_calc.js"></script>
|
<script type="text/javascript" src="/js/damage_calc.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/powders.js"></script> -->
|
|
||||||
<script type="text/javascript" src="/js/load.js"></script>
|
<script type="text/javascript" src="/js/load.js"></script>
|
||||||
<script type="text/javascript" src="/js/load_ing.js"></script>
|
<script type="text/javascript" src="/js/load_ing.js"></script>
|
||||||
<script type="text/javascript" src="/js/display_constants.js"></script>
|
<script type="text/javascript" src="/js/display_constants.js"></script>
|
||||||
|
|
|
@ -221,6 +221,6 @@
|
||||||
docsFns.append(genDocEntry(entry[0], entry[1], null, entry[2]));
|
docsFns.append(genDocEntry(entry[0], entry[1], null, entry[2]));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="../js/sq2icons.js"></script>
|
<script type="text/javascript" src="../js/icons.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
512
js/atree.js
|
@ -41,8 +41,8 @@ add_spell_prop: {
|
||||||
// If target part does not exist, a new part is created.
|
// If target part does not exist, a new part is created.
|
||||||
behavior: Optional[str] // One of: "merge", "modify". default: merge
|
behavior: Optional[str] // One of: "merge", "modify". default: merge
|
||||||
// merge: add if exist, make new part if not exist
|
// merge: add if exist, make new part if not exist
|
||||||
// modify: change existing part. do nothing if not exist
|
// modify: increment existing part. do nothing if not exist
|
||||||
cost: Optional[int] // change to spellcost
|
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, float]] // Additive changes to hits (for total entry)
|
||||||
|
@ -62,7 +62,7 @@ raw_stat: {
|
||||||
// string value means bind to (or create) named button
|
// string value means bind to (or create) named button
|
||||||
behavior: Optional[str] // One of: "merge", "modify". default: merge
|
behavior: Optional[str] // One of: "merge", "modify". default: merge
|
||||||
// merge: add if exist, make new part if not exist
|
// merge: add if exist, make new part if not exist
|
||||||
// modify: change existing part. do nothing if not exist
|
// modify: increment existing part. do nothing if not exist
|
||||||
bonuses: List[stat_bonus]
|
bonuses: List[stat_bonus]
|
||||||
}
|
}
|
||||||
stat_bonus: {
|
stat_bonus: {
|
||||||
|
@ -79,12 +79,16 @@ stat_scaling: {
|
||||||
round: Optional[bool] // Control floor behavior. True for stats and false for slider by default
|
round: Optional[bool] // Control floor behavior. True for stats and false for slider by default
|
||||||
slider_behavior: Optional[str] // One of: "merge", "modify". default: merge
|
slider_behavior: Optional[str] // One of: "merge", "modify". default: merge
|
||||||
// merge: add if exist, make new part if not exist
|
// merge: add if exist, make new part if not exist
|
||||||
// modify: change existing part. do nothing if not exist
|
// modify: change existing part, by incrementing properties. do nothing if not exist
|
||||||
slider_max: Optional[float] // affected by slider_behavior
|
slider_max: Optional[float] // affected by slider_behavior
|
||||||
"inputs": Optional[list[scaling_target]],
|
inputs: Optional[list[scaling_target]] // List of things to scale. Omit this if using slider
|
||||||
"output": scaling_target | List[scaling_target],
|
|
||||||
"scaling": list[float],
|
output: Optional[scaling_target | List[scaling_target]] // One of the following:
|
||||||
"max": float
|
// 1. Single output scaling target
|
||||||
|
// 2. List of scaling targets (all scaled the same)
|
||||||
|
// 3. Omitted. no output (useful for modifying slider only without input or output)
|
||||||
|
scaling: Optional[list[float]] // One float for each input. Sums into output.
|
||||||
|
max: float
|
||||||
}
|
}
|
||||||
scaling_target: {
|
scaling_target: {
|
||||||
"type": "stat" | "prop",
|
"type": "stat" | "prop",
|
||||||
|
@ -170,40 +174,23 @@ const atree_node = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
node.parents = parents;
|
node.parents = parents;
|
||||||
}
|
}
|
||||||
console.log(atree_map);
|
|
||||||
|
|
||||||
|
let sccs = make_SCC_graph(atree_head, atree_map.values());
|
||||||
let atree_topo_sort = [];
|
let atree_topo_sort = [];
|
||||||
topological_sort_tree(atree_head, atree_topo_sort, new Map());
|
for (const scc of sccs) {
|
||||||
atree_topo_sort.reverse();
|
for (const node of scc.nodes) {
|
||||||
|
delete node.visited;
|
||||||
|
delete node.assigned;
|
||||||
|
delete node.scc;
|
||||||
|
atree_topo_sort.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("Approximate topological order ability tree:");
|
||||||
|
console.log(atree_topo_sort);
|
||||||
return atree_topo_sort;
|
return atree_topo_sort;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a reverse topological sort of the tree in the result list.
|
|
||||||
* NOTE: our structure isn't a tree... it isn't even acyclic... but do it anyway i guess...
|
|
||||||
*
|
|
||||||
* https://en.wikipedia.org/wiki/Topological_sorting
|
|
||||||
* @param tree: Root of tree to sort
|
|
||||||
* @param res: Result list (reverse topological order)
|
|
||||||
* @param mark_state: Bookkeeping. Call with empty Map()
|
|
||||||
*/
|
|
||||||
function topological_sort_tree(tree, res, mark_state) {
|
|
||||||
const state = mark_state.get(tree);
|
|
||||||
if (state === undefined) {
|
|
||||||
// unmarked.
|
|
||||||
mark_state.set(tree, false); // temporary mark
|
|
||||||
for (const child of tree.children) {
|
|
||||||
topological_sort_tree(child, res, mark_state);
|
|
||||||
}
|
|
||||||
mark_state.set(tree, true); // permanent mark
|
|
||||||
res.push(tree);
|
|
||||||
}
|
|
||||||
// these cases are not needed. Case 1 does nothing, case 2 should never happen.
|
|
||||||
// else if (state === true) { return; } // permanent mark.
|
|
||||||
// else if (state === false) { throw "not a DAG"; } // temporary mark.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display ability tree from topologically sorted list.
|
* Display ability tree from topologically sorted list.
|
||||||
*
|
*
|
||||||
|
@ -212,7 +199,6 @@ function topological_sort_tree(tree, res, mark_state) {
|
||||||
const atree_render = new (class extends ComputeNode {
|
const atree_render = new (class extends ComputeNode {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('builder-atree-render');
|
super('builder-atree-render');
|
||||||
this.fail_cb = true;
|
|
||||||
this.UI_elem = document.getElementById("atree-ui");
|
this.UI_elem = document.getElementById("atree-ui");
|
||||||
this.list_elem = document.getElementById("atree-header");
|
this.list_elem = document.getElementById("atree-header");
|
||||||
}
|
}
|
||||||
|
@ -323,7 +309,7 @@ function abil_can_activate(atree_node, atree_state, reachable, archetype_count,
|
||||||
}
|
}
|
||||||
let failed_deps = [];
|
let failed_deps = [];
|
||||||
for (const dep_id of ability.dependencies) {
|
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) {
|
if (failed_deps.length > 0) {
|
||||||
const dep_strings = failed_deps.map(i => '"' + atree_state.get(i).ability.display_name + '"');
|
const dep_strings = failed_deps.map(i => '"' + atree_state.get(i).ability.display_name + '"');
|
||||||
|
@ -331,7 +317,7 @@ function abil_can_activate(atree_node, atree_state, reachable, archetype_count,
|
||||||
}
|
}
|
||||||
let blocking_ids = [];
|
let blocking_ids = [];
|
||||||
for (const blocker_id of ability.blockers) {
|
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) {
|
if (blocking_ids.length > 0) {
|
||||||
const blockers_strings = blocking_ids.map(i => '"' + atree_state.get(i).ability.display_name + '"');
|
const blockers_strings = blocking_ids.map(i => '"' + atree_state.get(i).ability.display_name + '"');
|
||||||
|
@ -385,11 +371,11 @@ const atree_validate = new (class extends ComputeNode {
|
||||||
const abil = node.ability;
|
const abil = node.ability;
|
||||||
if (atree_state.get(abil.id).active) {
|
if (atree_state.get(abil.id).active) {
|
||||||
atree_to_add.push([node, 'not reachable', false]);
|
atree_to_add.push([node, 'not reachable', false]);
|
||||||
atree_state.get(abil.id).img.src = '../media/atree/' + abil.display.icon + '_selected.png';
|
atree_state.get(abil.id).img.style.backgroundPosition = atlasBGPositionCalc([atreeNodeAtlasPositions[abil.display.icon], 2], atreeNodeAtlasSize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
atree_not_present.push(abil.id);
|
atree_not_present.push(abil.id);
|
||||||
atree_state.get(abil.id).img.src = '../media/atree/' + abil.display.icon + '_blocked.png';
|
atree_state.get(abil.id).img.style.backgroundPosition = atlasBGPositionCalc([atreeNodeAtlasPositions[abil.display.icon], 0], atreeNodeAtlasSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,6 +402,7 @@ const atree_validate = new (class extends ComputeNode {
|
||||||
reachable.add(ability.id);
|
reachable.add(ability.id);
|
||||||
}
|
}
|
||||||
if (atree_to_add.length == _add.length) {
|
if (atree_to_add.length == _add.length) {
|
||||||
|
atree_to_add = _add;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
atree_to_add = _add;
|
atree_to_add = _add;
|
||||||
|
@ -437,7 +424,7 @@ const atree_validate = new (class extends ComputeNode {
|
||||||
const node = atree_state.get(node_id);
|
const node = atree_state.get(node_id);
|
||||||
const [success, hard_error, reason] = abil_can_activate(node, atree_state, reachable, archetype_count, ap_left);
|
const [success, hard_error, reason] = abil_can_activate(node, atree_state, reachable, archetype_count, ap_left);
|
||||||
if (success) {
|
if (success) {
|
||||||
node.img.src = '../media/atree/'+node.ability.display.icon+'.png';
|
node.img.style.backgroundPosition = atlasBGPositionCalc([atreeNodeAtlasPositions[node.ability.display.icon], 1], atreeNodeAtlasSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,6 +643,9 @@ const atree_make_interactives = new (class extends ComputeNode {
|
||||||
const atree_order = input_map.get('atree-order');
|
const atree_order = input_map.get('atree-order');
|
||||||
const atree_html = input_map.get('atree-elements');
|
const atree_html = input_map.get('atree-elements');
|
||||||
|
|
||||||
|
document.getElementById("boost-sliders").innerHTML = "";
|
||||||
|
document.getElementById("boost-toggles").innerHTML = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* slider_info
|
* slider_info
|
||||||
* label_name: str,
|
* label_name: str,
|
||||||
|
@ -670,7 +660,7 @@ const atree_make_interactives = new (class extends ComputeNode {
|
||||||
const slider_map = new Map();
|
const slider_map = new Map();
|
||||||
const button_map = new Map();
|
const button_map = new Map();
|
||||||
|
|
||||||
// first, pull out all the sliders.
|
// first, pull out all the sliders and toggles.
|
||||||
for (const [abil_id, ability] of merged_abils.entries()) {
|
for (const [abil_id, ability] of merged_abils.entries()) {
|
||||||
for (const effect of ability.effects) {
|
for (const effect of ability.effects) {
|
||||||
if (effect['type'] === "stat_scaling" && effect['slider'] === true) {
|
if (effect['type'] === "stat_scaling" && effect['slider'] === true) {
|
||||||
|
@ -683,7 +673,7 @@ const atree_make_interactives = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
else if (slider_behavior === 'merge') {
|
else if (slider_behavior === 'merge') {
|
||||||
slider_map.set(slider_name, {
|
slider_map.set(slider_name, {
|
||||||
label_name: slider_name,
|
label_name: slider_name+' ('+ability.display_name+')',
|
||||||
max: slider_max,
|
max: slider_max,
|
||||||
step: slider_step,
|
step: slider_step,
|
||||||
id: "ability-slider"+ability.id,
|
id: "ability-slider"+ability.id,
|
||||||
|
@ -700,15 +690,15 @@ const atree_make_interactives = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// next, render the sliders onto the abilities.
|
// next, render the sliders and toggles onto the abilities.
|
||||||
for (const [slider_name, slider_info] of slider_map.entries()) {
|
for (const [slider_name, slider_info] of slider_map.entries()) {
|
||||||
let slider_container = gen_slider_labeled(slider_info);
|
let slider_container = gen_slider_labeled(slider_info);
|
||||||
atree_html.get(slider_info.abil.id).appendChild(slider_container);
|
document.getElementById("boost-sliders").appendChild(slider_container);
|
||||||
slider_info.slider = document.getElementById(slider_info.id);
|
slider_info.slider = document.getElementById(slider_info.id);
|
||||||
slider_info.slider.addEventListener("change", (e) => atree_stats.mark_dirty().update());
|
slider_info.slider.addEventListener("change", (e) => atree_scaling.mark_dirty().update());
|
||||||
}
|
}
|
||||||
for (const [button_name, button_info] of button_map.entries()) {
|
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"], {
|
let button = make_elem('button', ["button-boost", "border-0", "text-white", "dark-8u", "dark-shadow-sm", "m-1"], {
|
||||||
id: button_info.abil.id,
|
id: button_info.abil.id,
|
||||||
textContent: button_name
|
textContent: button_name
|
||||||
});
|
});
|
||||||
|
@ -718,28 +708,28 @@ const atree_make_interactives = new (class extends ComputeNode {
|
||||||
} else {
|
} else {
|
||||||
button.classList.add("toggleOn");
|
button.classList.add("toggleOn");
|
||||||
}
|
}
|
||||||
atree_stats.mark_dirty().update()
|
atree_scaling.mark_dirty().update()
|
||||||
});
|
});
|
||||||
button_info.button = button;
|
button_info.button = button;
|
||||||
atree_html.get(button_info.abil.id).appendChild(button);
|
document.getElementById("boost-toggles").appendChild(button);
|
||||||
}
|
}
|
||||||
return [slider_map, button_map];
|
return [slider_map, button_map];
|
||||||
}
|
}
|
||||||
})().link_to(atree_node, 'atree-order').link_to(atree_merge, 'atree-merged').link_to(atree_render_active, 'atree-elements');
|
})().link_to(atree_node, 'atree-order').link_to(atree_merge, 'atree-merged').link_to(atree_render_active, 'atree-elements');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect stats from ability tree.
|
* Scaling stats from ability tree.
|
||||||
* Return StatMap of added stats (incl. cost modifications as raw cost)
|
* Return StatMap of added stats,
|
||||||
*
|
*
|
||||||
* Signature: AbilityTreeStatsNode(atree-merged: MergedATree, build: Build, atree-interactive: Map<str, slider_info>) => StatMap
|
* Signature: AbilityTreeScalingNode(atree-merged: MergedATree, scale-scats: StatMap,
|
||||||
|
* atree-interactive: [Map<str, slider_info>, Map<str, button_info>]) => StatMap
|
||||||
*/
|
*/
|
||||||
const atree_stats = new (class extends ComputeNode {
|
const atree_scaling = new (class extends ComputeNode {
|
||||||
constructor() { super('atree-stats-collector'); }
|
constructor() { super('atree-scaling-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');
|
||||||
const item_stats = input_map.get('build').statMap;
|
const pre_scale_stats = input_map.get('scale-stats');
|
||||||
const [slider_map, button_map] = input_map.get('atree-interactive');
|
const [slider_map, button_map] = input_map.get('atree-interactive');
|
||||||
|
|
||||||
let ret_effects = new Map();
|
let ret_effects = new Map();
|
||||||
|
@ -748,42 +738,41 @@ const atree_stats = new (class extends ComputeNode {
|
||||||
|
|
||||||
for (const effect of abil.effects) {
|
for (const effect of abil.effects) {
|
||||||
switch (effect.type) {
|
switch (effect.type) {
|
||||||
case 'stat_scaling':
|
case 'raw_stat':
|
||||||
if (effect.slider) {
|
// TODO: toggles...
|
||||||
if ('output' in effect) { // sometimes nodes will modify slider without having effect.
|
if (effect.toggle) {
|
||||||
const slider_val = slider_map.get(effect.slider_name).slider.value;
|
const button = button_map.get(effect.toggle).button;
|
||||||
const {round = true} = effect;
|
if (!button.classList.contains("toggleOn")) { continue; }
|
||||||
let total = parseInt(slider_val) * effect.scaling[0];
|
for (const bonus of effect.bonuses) {
|
||||||
if (round) { total = Math.floor(round_near(total)); }
|
const { type, name, abil = "", value } = bonus;
|
||||||
if ('max' in effect && total > effect.max) { total = effect.max; }
|
// TODO: prop
|
||||||
if (Array.isArray(effect.output)) {
|
if (type === "stat") {
|
||||||
for (const output of effect.output) {
|
merge_stat(ret_effects, name, value);
|
||||||
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;
|
||||||
|
case 'stat_scaling':
|
||||||
|
let total = 0;
|
||||||
|
const {round = true, slider = false, scaling = [0]} = effect;
|
||||||
|
if (slider) {
|
||||||
|
const slider_val = slider_map.get(effect.slider_name).slider.value;
|
||||||
|
total = parseInt(slider_val) * scaling[0];
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: type: prop?
|
// TODO: type: prop?
|
||||||
let total = 0;
|
for (const [_scaling, input] of zip2(scaling, effect.inputs)) {
|
||||||
const {round = true} = effect;
|
total += _scaling * pre_scale_stats.get(input.name);
|
||||||
for (const [scaling, input] of zip2(effect.scaling, effect.inputs)) {
|
|
||||||
total += scaling * item_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 (round) { total = Math.floor(round_near(total)); }
|
||||||
if (total < 0) { total = 0; } // Normal stat scaling will not go negative.
|
if (total < 0) { total = 0; } // Normal stat scaling will not go negative.
|
||||||
if ('max' in effect && total > effect.max) { total = effect.max; }
|
if ('max' in effect && total > effect.max) { total = effect.max; }
|
||||||
// TODO: output (list...)
|
|
||||||
if (Array.isArray(effect.output)) {
|
if (Array.isArray(effect.output)) {
|
||||||
for (const output of effect.output) {
|
for (const output of effect.output) {
|
||||||
if (output.type === 'stat') {
|
if (output.type === 'stat') { // TODO: prop
|
||||||
merge_stat(ret_effects, output.name, total);
|
merge_stat(ret_effects, output.name, total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -795,12 +784,34 @@ const atree_stats = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
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.
|
||||||
|
*
|
||||||
|
* Signature: AbilityTreeStatsNode(atree-merged: MergedATree) => StatMap
|
||||||
|
*/
|
||||||
|
const atree_stats = new (class extends ComputeNode {
|
||||||
|
constructor() { super('atree-stats-collector'); }
|
||||||
|
|
||||||
|
compute_func(input_map) {
|
||||||
|
const atree_merged = input_map.get('atree-merged');
|
||||||
|
|
||||||
|
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':
|
case 'raw_stat':
|
||||||
// TODO: toggles...
|
// toggles are handled in atree_scaling.
|
||||||
if (effect.toggle) {
|
if (effect.toggle) { continue; }
|
||||||
const button = button_map.get(effect.toggle).button;
|
|
||||||
if (!button.classList.contains("toggleOn")) { continue; }
|
|
||||||
}
|
|
||||||
for (const bonus of effect.bonuses) {
|
for (const bonus of effect.bonuses) {
|
||||||
const { type, name, abil = "", value } = bonus;
|
const { type, name, abil = "", value } = bonus;
|
||||||
// TODO: prop
|
// TODO: prop
|
||||||
|
@ -809,27 +820,12 @@ const atree_stats = new (class extends ComputeNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case 'add_spell_prop':
|
|
||||||
continue;
|
|
||||||
// TODO unjankify....
|
|
||||||
// costs are converted to raw cost ID
|
|
||||||
// const { base_spell, cost = 0} = effect;
|
|
||||||
// if (cost) {
|
|
||||||
// const key = "spRaw"+base_spell;
|
|
||||||
// if (ret_effects.has(key)) { ret_effects.set(key, ret_effects.get(key) + cost); }
|
|
||||||
// else { ret_effects.set(key, cost); }
|
|
||||||
// }
|
|
||||||
// continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret_effects.has('baseResist')) {
|
|
||||||
merge_stat(ret_effects, "defMult", 1 - (ret_effects.get('baseResist') / 100));
|
|
||||||
}
|
|
||||||
return ret_effects;
|
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.
|
* Construct compute nodes to link builder items and edit IDs to the appropriate display outputs.
|
||||||
|
@ -852,16 +848,15 @@ class AbilityTreeEnsureNodesNode extends ComputeNode {
|
||||||
this.build_node = build_node;
|
this.build_node = build_node;
|
||||||
this.stat_agg_node = stat_agg_node;
|
this.stat_agg_node = stat_agg_node;
|
||||||
// Slight amount of wasted compute to keep internal state non-changing.
|
// Slight amount of wasted compute to keep internal state non-changing.
|
||||||
this.passthrough = new PassThroughNode('atree-make-nodes_internal').link_to(this.build_node, 'build').link_to(this.stat_agg_node, 'stats');
|
this.passthrough = new PassThroughNode('spell-calc-buffer').link_to(this.build_node, 'build').link_to(this.stat_agg_node, 'stats');
|
||||||
this.spelldmg_nodes = []; // debugging use
|
this.spelldmg_nodes = []; // debugging use
|
||||||
this.spell_display_elem = document.getElementById("all-spells-display");
|
this.spell_display_elem = document.getElementById("all-spells-display");
|
||||||
}
|
}
|
||||||
|
|
||||||
compute_func(input_map) {
|
compute_func(input_map) {
|
||||||
console.log('atree make nodes');
|
|
||||||
this.passthrough.remove_link(this.build_node);
|
this.passthrough.remove_link(this.build_node);
|
||||||
this.passthrough.remove_link(this.stat_agg_node);
|
this.passthrough.remove_link(this.stat_agg_node);
|
||||||
this.passthrough = new PassThroughNode('atree-make-nodes_internal').link_to(this.build_node, 'build').link_to(this.stat_agg_node, 'stats');
|
this.passthrough = new PassThroughNode('spell-calc-buffer').link_to(this.build_node, 'build').link_to(this.stat_agg_node, 'stats');
|
||||||
this.spell_display_elem.textContent = "";
|
this.spell_display_elem.textContent = "";
|
||||||
const build_node = this.passthrough.get_node('build'); // aaaaaaaaa performance... savings... help....
|
const build_node = this.passthrough.get_node('build'); // aaaaaaaaa performance... savings... help....
|
||||||
const stat_agg_node = this.passthrough.get_node('stats');
|
const stat_agg_node = this.passthrough.get_node('stats');
|
||||||
|
@ -881,10 +876,10 @@ class AbilityTreeEnsureNodesNode extends ComputeNode {
|
||||||
let display_elem = document.createElement('div');
|
let display_elem = document.createElement('div');
|
||||||
display_elem.classList.add("col", "pe-0");
|
display_elem.classList.add("col", "pe-0");
|
||||||
// TODO: just pass these elements into the display node instead of juggling the raw IDs...
|
// TODO: just pass these elements into the display node instead of juggling the raw IDs...
|
||||||
let spell_summary = document.createElement('div'); spell_summary.setAttribute('id', "spell"+spell.base_spell+"-infoAvg");
|
let spell_summary = make_elem('div', ["col", "spell-display", "fake-button", "dark-5", "rounded", "dark-shadow", "pt-2", "border", "border-dark"],
|
||||||
spell_summary.classList.add("col", "spell-display", "spell-expand", "dark-5", "rounded", "dark-shadow", "pt-2", "border", "border-dark");
|
{ id: "spell"+spell.base_spell+"-infoAvg" });
|
||||||
let spell_detail = document.createElement('div'); spell_detail.setAttribute('id', "spell"+spell.base_spell+"-info");
|
let spell_detail = make_elem('div', ["col", "spell-display", "dark-5", "rounded", "dark-shadow", "py-2"],
|
||||||
spell_detail.classList.add("col", "spell-display", "dark-5", "rounded", "dark-shadow", "py-2");
|
{ id: "spell"+spell.base_spell+"-info" });
|
||||||
spell_detail.style.display = "none";
|
spell_detail.style.display = "none";
|
||||||
|
|
||||||
display_elem.appendChild(spell_summary); display_elem.appendChild(spell_detail);
|
display_elem.appendChild(spell_summary); display_elem.appendChild(spell_detail);
|
||||||
|
@ -981,7 +976,7 @@ function render_AT(UI_elem, list_elem, tree) {
|
||||||
const parent_id = parent_abil.id;
|
const parent_id = parent_abil.id;
|
||||||
|
|
||||||
let connect_elem = document.createElement("div");
|
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;";
|
connect_elem.style = "width: 112.5%; height: 112.5%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); image-rendering: pixelated; background-image: url('../media/atree/connectors.png'); background-size: 1700% 500%;"
|
||||||
// connect up
|
// connect up
|
||||||
for (let i = ability.display.row - 1; i > parent_abil.display.row; i--) {
|
for (let i = ability.display.row - 1; i > parent_abil.display.row; i--) {
|
||||||
const coord = i + "," + ability.display.col;
|
const coord = i + "," + ability.display.col;
|
||||||
|
@ -1016,17 +1011,9 @@ function render_AT(UI_elem, list_elem, tree) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create node
|
// create node
|
||||||
let node_elem = document.createElement('div');
|
let node_elem = document.getElementById("atree-row-" + ability.display.row).children[ability.display.col];
|
||||||
let icon = ability.display.icon;
|
node_wrap.img = make_elem("div", [], {style: "width: 200%; height: 200%; position: absolute; top: -50%; left: -50%; image-rendering: pixelated; z-index: 1; background-image: url('../media/atree/icons.png'); background-size: 900% 300%;"})
|
||||||
if (icon === undefined) {
|
node_elem.appendChild(node_wrap.img);
|
||||||
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;
|
|
||||||
|
|
||||||
// create hitbox
|
// create hitbox
|
||||||
// this is necessary since images exceed the size of their square, but should only be interactible within that square
|
// this is necessary since images exceed the size of their square, but should only be interactible within that square
|
||||||
|
@ -1044,8 +1031,6 @@ function render_AT(UI_elem, list_elem, tree) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// add tooltip
|
// add tooltip
|
||||||
// tooltips are being changed to generate on mouseover for fin444's future style updates
|
|
||||||
// this is being implemented before those updates since it helps with a hotfix
|
|
||||||
hitbox.addEventListener('mouseover', function(e) {
|
hitbox.addEventListener('mouseover', function(e) {
|
||||||
if (e.target !== this) {
|
if (e.target !== this) {
|
||||||
return;
|
return;
|
||||||
|
@ -1054,7 +1039,7 @@ function render_AT(UI_elem, list_elem, tree) {
|
||||||
node_wrap.tooltip_elem.remove();
|
node_wrap.tooltip_elem.remove();
|
||||||
delete node_wrap.tooltip_elem;
|
delete node_wrap.tooltip_elem;
|
||||||
}
|
}
|
||||||
node_wrap.tooltip_elem = generateTooltip(UI_elem, node_elem, ability);
|
node_wrap.tooltip_elem = generateTooltip(UI_elem, node_elem, ability, atree_map);
|
||||||
});
|
});
|
||||||
|
|
||||||
hitbox.addEventListener('mouseout', function(e) {
|
hitbox.addEventListener('mouseout', function(e) {
|
||||||
|
@ -1066,50 +1051,160 @@ function render_AT(UI_elem, list_elem, tree) {
|
||||||
delete node_wrap.tooltip_elem;
|
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);
|
atree_render_connection(atree_connectors_map);
|
||||||
|
|
||||||
return atree_map;
|
return atree_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
function generateTooltip(UI_elem, node_elem, ability) {
|
function generateTooltip(UI_elem, node_elem, ability, atree_map) {
|
||||||
let tooltip = document.createElement('div');
|
let container = make_elem("div", ["rounded-bottom", "dark-4", "border", "mx-2", "my-4", "dark-shadow", "text-start"], {"style": "position: absolute; z-index: 100;"});
|
||||||
tooltip.classList.add("rounded-bottom", "dark-4", "border", "p-0", "mx-2", "my-4", "dark-shadow");
|
container.style.top = (node_elem.getBoundingClientRect().top + window.pageYOffset + 50) + "px";
|
||||||
|
container.style.left = UI_elem.getBoundingClientRect().left + "px";
|
||||||
|
container.style.width = UI_elem.getBoundingClientRect().width * 0.95 + "px";
|
||||||
|
|
||||||
// tooltip text formatting
|
// title
|
||||||
|
let title = make_elem("b", ["scaled-font", "mx-1"], {});
|
||||||
|
title.innerHTML = ability.display_name;
|
||||||
|
switch(ability.display.icon) {
|
||||||
|
case "node_0":
|
||||||
|
// already white
|
||||||
|
break;
|
||||||
|
case "node_1":
|
||||||
|
title.classList.add("mc-gold");
|
||||||
|
break;
|
||||||
|
case "node_2":
|
||||||
|
title.classList.add("mc-light-purple");
|
||||||
|
break;
|
||||||
|
case "node_3":
|
||||||
|
title.classList.add("mc-red");
|
||||||
|
break;
|
||||||
|
case "node_warrior":
|
||||||
|
case "node_archer":
|
||||||
|
case "node_mage":
|
||||||
|
case "node_assassin":
|
||||||
|
case "node_shaman":
|
||||||
|
title.classList.add("mc-green");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
container.appendChild(title);
|
||||||
|
|
||||||
let tooltip_title = document.createElement('b');
|
container.innerHTML += "<br/><br/>";
|
||||||
tooltip_title.classList.add("scaled-font");
|
|
||||||
tooltip_title.innerHTML = ability.display_name;
|
|
||||||
tooltip.appendChild(tooltip_title);
|
|
||||||
|
|
||||||
if ('archetype' in ability && ability.archetype !== "") {
|
// description
|
||||||
let tooltip_archetype = document.createElement('p');
|
let description = make_elem("p", ["scaled-font-sm", "my-0", "mx-1", "text-wrap", "mc-gray"], {});
|
||||||
tooltip_archetype.classList.add("scaled-font");
|
let numberRegex = /[+-]?\d+(\.\d+)?[%+s]?/g; // +/- (optional), 1 or more digits, period followed by 1 or more digits (optional), %/+/s (optional)
|
||||||
tooltip_archetype.innerHTML = "(Archetype: " + ability.archetype+")";
|
description.innerHTML = ability.desc.replaceAll(numberRegex, (m) => { return "<span class = 'mc-white'>" + m + "</span>" });
|
||||||
tooltip.appendChild(tooltip_archetype);
|
container.appendChild(description);
|
||||||
|
|
||||||
|
container.appendChild(document.createElement("br"));
|
||||||
|
|
||||||
|
// archetype
|
||||||
|
if ("archetype" in ability && ability.archetype !== "") {
|
||||||
|
let archetype = make_elem("p", ["scaled-font-sm", "my-0", "mx-1"], {});
|
||||||
|
archetype.innerHTML = ability.archetype + " Archetype";
|
||||||
|
switch(ability.archetype) {
|
||||||
|
case "Riftwalker":
|
||||||
|
case "Paladin":
|
||||||
|
archetype.classList.add("mc-aqua");
|
||||||
|
break;
|
||||||
|
case "Fallen":
|
||||||
|
archetype.classList.add("mc-red");
|
||||||
|
break;
|
||||||
|
case "Boltslinger":
|
||||||
|
case "Battle Monk":
|
||||||
|
archetype.classList.add("mc-yellow");
|
||||||
|
break;
|
||||||
|
case "Trapper":
|
||||||
|
archetype.classList.add("mc-dark-green");
|
||||||
|
break;
|
||||||
|
case "Trickster":
|
||||||
|
case "Sharpshooter":
|
||||||
|
archetype.classList.add("mc-light-purple");
|
||||||
|
break;
|
||||||
|
case "Arcanist":
|
||||||
|
archetype.classList.add("mc-dark-purple");
|
||||||
|
break;
|
||||||
|
case "Acrobat":
|
||||||
|
case "Light Bender":
|
||||||
|
// already white
|
||||||
|
break;
|
||||||
|
case "Shadestepper":
|
||||||
|
archetype.classList.add("mc-dark-red");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
container.appendChild(archetype);
|
||||||
|
container.appendChild(document.createElement("br"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let tooltip_desc = document.createElement('p');
|
// calculate if requirements are satisfied
|
||||||
tooltip_desc.classList.add("scaled-font-sm", "my-0", "mx-1", "text-wrap");
|
let apUsed = 0;
|
||||||
tooltip_desc.textContent = ability.desc;
|
let maxAP = parseInt(document.getElementById("active_AP_cap").innerHTML);
|
||||||
tooltip.appendChild(tooltip_desc);
|
let archChosen = 0;
|
||||||
|
let satisfiedDependencies = [];
|
||||||
|
let blockedBy = [];
|
||||||
|
for (let [id, node_wrap] of atree_map.entries()) {
|
||||||
|
if (!node_wrap.active || id == ability.id) {
|
||||||
|
continue; // we don't want to count abilities that are not selected, and an ability should not count towards itself
|
||||||
|
}
|
||||||
|
apUsed += node_wrap.ability.cost;
|
||||||
|
if (node_wrap.ability.archetype == ability.archetype) {
|
||||||
|
archChosen++;
|
||||||
|
}
|
||||||
|
if (ability.dependencies.includes(id)) {
|
||||||
|
satisfiedDependencies.push(id);
|
||||||
|
}
|
||||||
|
if (ability.blockers.includes(id)) {
|
||||||
|
blockedBy.push(node_wrap.ability.display_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let tooltip_cost = document.createElement('p');
|
let reqYes = "<span class = 'mc-green'>✔</span>" // green check mark
|
||||||
tooltip_cost.classList.add("scaled-font-sm", "my-0", "mx-1", "text-start");
|
let reqNo = "<span class = 'mc-red'>✖</span>" // red x
|
||||||
tooltip_cost.textContent = "Cost: " + ability.cost + " AP";
|
|
||||||
tooltip.appendChild(tooltip_cost);
|
|
||||||
|
|
||||||
tooltip.style.position = "absolute";
|
// cost
|
||||||
tooltip.style.zIndex = "100";
|
let cost = make_elem("p", ["scaled-font-sm", "my-0", "mx-1"], {});
|
||||||
tooltip.style.top = (node_elem.getBoundingClientRect().top + window.pageYOffset + 50) + "px";
|
if (apUsed + ability.cost > maxAP) {
|
||||||
tooltip.style.left = UI_elem.getBoundingClientRect().left + "px";
|
cost.innerHTML = reqNo;
|
||||||
tooltip.style.width = UI_elem.getBoundingClientRect().width * 0.95 + "px";
|
} else {
|
||||||
|
cost.innerHTML = reqYes;
|
||||||
|
}
|
||||||
|
cost.innerHTML += " <span class = 'mc-gray'>Ability Points:</span> " + (maxAP - apUsed) + "<span class = 'mc-gray'>/" + ability.cost;
|
||||||
|
container.appendChild(cost);
|
||||||
|
|
||||||
UI_elem.appendChild(tooltip);
|
// archetype req
|
||||||
return tooltip;
|
if (ability.archetype_req > 0 && ability.archetype != null) {
|
||||||
|
let archReq = make_elem("p", ["scaled-font-sm", "my-0", "mx-1"], {});
|
||||||
|
if (archChosen >= ability.archetype_req) {
|
||||||
|
archReq.innerHTML = reqYes;
|
||||||
|
} else {
|
||||||
|
archReq.innerHTML = reqNo;
|
||||||
|
}
|
||||||
|
archReq.innerHTML += " <span class = 'mc-gray'>Min " + ability.archetype + " Archetype:</span> " + archChosen + "<span class = 'mc-gray'>/" + ability.archetype_req;
|
||||||
|
container.appendChild(archReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
// dependencies
|
||||||
|
for (let i = 0; i < ability.dependencies.length; i++) {
|
||||||
|
let dependency = make_elem("p", ["scaled-font-sm", "my-0", "mx-1"], {});
|
||||||
|
if (satisfiedDependencies.includes(ability.dependencies[i])) {
|
||||||
|
dependency.innerHTML = reqYes;
|
||||||
|
} else {
|
||||||
|
dependency.innerHTML = reqNo;
|
||||||
|
}
|
||||||
|
dependency.innerHTML += " <span class = 'mc-gray'>Required Ability:</span> " + atree_map.get(ability.dependencies[i]).ability.display_name;
|
||||||
|
container.appendChild(dependency);
|
||||||
|
}
|
||||||
|
|
||||||
|
// blockers
|
||||||
|
for (let i = 0; i < blockedBy.length; i++) {
|
||||||
|
let blocker = make_elem("p", ["scaled-font-sm", "my-0", "mx-1"], {});
|
||||||
|
blocker.innerHTML = reqNo + " <span class = 'mc-gray'>Blocked By:</span> " + blockedBy[i];
|
||||||
|
container.appendChild(blocker);
|
||||||
|
}
|
||||||
|
|
||||||
|
UI_elem.appendChild(container);
|
||||||
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve connector conflict, when they occupy the same cell.
|
// resolve connector conflict, when they occupy the same cell.
|
||||||
|
@ -1131,26 +1226,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.
|
// toggle the state of a node.
|
||||||
function atree_set_state(node_wrapper, new_state) {
|
function atree_set_state(node_wrapper, new_state) {
|
||||||
let icon = node_wrapper.ability.display.icon;
|
let icon = node_wrapper.ability.display.icon;
|
||||||
|
@ -1159,11 +1234,11 @@ function atree_set_state(node_wrapper, new_state) {
|
||||||
}
|
}
|
||||||
if (new_state) {
|
if (new_state) {
|
||||||
node_wrapper.active = true;
|
node_wrapper.active = true;
|
||||||
node_wrapper.elem.children[0].src = "../media/atree/" + icon + "_selected.png";
|
node_wrapper.img.style.backgroundPosition = atlasBGPositionCalc([atreeNodeAtlasPositions[icon], 2], atreeNodeAtlasSize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node_wrapper.active = false;
|
node_wrapper.active = false;
|
||||||
node_wrapper.elem.children[0].src = "../media/atree/" + icon + ".png";
|
node_wrapper.img.style.backgroundPosition = atlasBGPositionCalc([atreeNodeAtlasPositions[icon], 1], atreeNodeAtlasSize);
|
||||||
}
|
}
|
||||||
let atree_connectors_map = node_wrapper.all_connectors_ref;
|
let atree_connectors_map = node_wrapper.all_connectors_ref;
|
||||||
for (const parent of node_wrapper.parents) {
|
for (const parent of node_wrapper.parents) {
|
||||||
|
@ -1178,6 +1253,62 @@ function atree_set_state(node_wrapper, new_state) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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 atreeConnectorAtlasSize = [17, 5]
|
||||||
|
// 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 atreeNodeAtlasSize = [9, 3]
|
||||||
|
function atlasBGPositionCalc(pos, atlasSize) {
|
||||||
|
// https://css-tricks.com/focusing-background-image-precise-location-percentages/
|
||||||
|
// p = (c + 0.5/z - 0.5) * z/(z - 1) + 0.5
|
||||||
|
// z = num tiles in direction
|
||||||
|
// c = starting pos of tile in percent of total atlas (equal to index/z)
|
||||||
|
let x = ((pos[0]/atlasSize[0]) + 0.5/atlasSize[0] - 0.5) * atlasSize[0]/(atlasSize[0] - 1) + 0.5
|
||||||
|
let y = ((pos[1]/atlasSize[1]) + 0.5/atlasSize[1] - 0.5) * atlasSize[1]/(atlasSize[1] - 1) + 0.5
|
||||||
|
return (x * 100) + "% " + (y * 100) + "%" // multiply by 100 to convert decimal to percent
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the connector onto the screen
|
||||||
|
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];
|
||||||
|
connector_elem.style.backgroundPosition = atlasBGPositionCalc(atreeConnectorAtlasPositions[connector_info.type]["0000"], atreeConnectorAtlasSize);
|
||||||
|
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) {
|
function atree_set_edge(atree_connectors_map, parent, child, state) {
|
||||||
const connectors = child.connectors.get(parent);
|
const connectors = child.connectors.get(parent);
|
||||||
const parent_row = parent.ability.display.row;
|
const parent_row = parent.ability.display.row;
|
||||||
|
@ -1192,8 +1323,6 @@ function atree_set_edge(atree_connectors_map, parent, child, state) {
|
||||||
let connector_info = atree_connectors_map.get(connector_label);
|
let connector_info = atree_connectors_map.get(connector_label);
|
||||||
let connector_elem = connector_info.connector;
|
let connector_elem = connector_info.connector;
|
||||||
let highlight_state = connector_info.highlight; // left right up down
|
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;
|
const ctype = connector_info.type;
|
||||||
let num_1s = 0;
|
let num_1s = 0;
|
||||||
for (let i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
|
@ -1221,23 +1350,16 @@ function atree_set_edge(atree_connectors_map, parent, child, state) {
|
||||||
for (let i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
render += highlight_state[i] === 0 ? "0" : "1";
|
render += highlight_state[i] === 0 ? "0" : "1";
|
||||||
}
|
}
|
||||||
if (render == "0000") {
|
connector_elem.style.backgroundPosition = atlasBGPositionCalc(atreeConnectorAtlasPositions[ctype][render], atreeConnectorAtlasSize);
|
||||||
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);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
// lol bad overloading, [0] is just the whole state
|
// lol bad overloading, [0] is just the whole state
|
||||||
highlight_state[0] += state_delta;
|
highlight_state[0] += state_delta;
|
||||||
if (highlight_state[0] > 0) {
|
if (highlight_state[0] > 0) {
|
||||||
connector_img_elem.src = '../media/atree/connect_' + ctype + '_1.png';
|
connector_elem.style.backgroundPosition = atlasBGPositionCalc(atreeConnectorAtlasPositions[ctype][ctype], atreeConnectorAtlasSize);
|
||||||
connector_elem.replaceChildren(connector_img_elem);
|
} else {
|
||||||
}
|
connector_elem.style.backgroundPosition = atlasBGPositionCalc(atreeConnectorAtlasPositions[ctype]["0000"], atreeConnectorAtlasSize);
|
||||||
else {
|
}
|
||||||
connector_img_elem.src = '../media/atree/connect_'+ctype+'.png';
|
|
||||||
connector_elem.replaceChildren(connector_img_elem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ class PowderSpecialDisplayNode extends ComputeNode {
|
||||||
/**
|
/**
|
||||||
* Node for getting an item's stats from an item input field.
|
* 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 {
|
class ItemInputNode extends InputNode {
|
||||||
/**
|
/**
|
||||||
|
@ -143,8 +143,6 @@ class ItemInputNode extends InputNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
compute_func(input_map) {
|
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
|
// built on the assumption of no one will type in CI/CR letter by letter
|
||||||
let item_text = this.input_field.value;
|
let item_text = this.input_field.value;
|
||||||
if (!item_text) {
|
if (!item_text) {
|
||||||
|
@ -158,10 +156,6 @@ class ItemInputNode extends InputNode {
|
||||||
else if (tomeMap.has(item_text)) { item = new Item(tomeMap.get(item_text)); }
|
else if (tomeMap.has(item_text)) { item = new Item(tomeMap.get(item_text)); }
|
||||||
|
|
||||||
if (item) {
|
if (item) {
|
||||||
if (powdering !== undefined) {
|
|
||||||
const max_slots = item.statMap.get('slots');
|
|
||||||
item.statMap.set('powders', powdering.slice(0, max_slots));
|
|
||||||
}
|
|
||||||
let type_match;
|
let type_match;
|
||||||
if (this.category == 'weapon') {
|
if (this.category == 'weapon') {
|
||||||
type_match = item.statMap.get('category') == 'weapon';
|
type_match = item.statMap.get('category') == 'weapon';
|
||||||
|
@ -169,12 +163,6 @@ class ItemInputNode extends InputNode {
|
||||||
type_match = item.statMap.get('type') == this.none_item.statMap.get('type');
|
type_match = item.statMap.get('type') == this.none_item.statMap.get('type');
|
||||||
}
|
}
|
||||||
if (type_match) {
|
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;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,6 +193,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 item = {};
|
||||||
|
item.statMap = new Map(input_map.get('item').statMap); // 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.
|
* Node for updating item input fields from parsed items.
|
||||||
*
|
*
|
||||||
|
@ -217,7 +230,6 @@ class ItemInputDisplayNode extends ComputeNode {
|
||||||
this.input_field = document.getElementById(eq+"-choice");
|
this.input_field = document.getElementById(eq+"-choice");
|
||||||
this.health_field = document.getElementById(eq+"-health");
|
this.health_field = document.getElementById(eq+"-health");
|
||||||
this.level_field = document.getElementById(eq+"-lv");
|
this.level_field = document.getElementById(eq+"-lv");
|
||||||
this.powder_field = document.getElementById(eq+"-powder"); // possibly None
|
|
||||||
this.image = item_image;
|
this.image = item_image;
|
||||||
this.fail_cb = true;
|
this.fail_cb = true;
|
||||||
}
|
}
|
||||||
|
@ -242,18 +254,11 @@ class ItemInputDisplayNode extends ComputeNode {
|
||||||
this.input_field.classList.add("is-invalid");
|
this.input_field.classList.add("is-invalid");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (this.powder_field && item.statMap.has('powders')) {
|
|
||||||
this.powder_field.placeholder = "powders";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.statMap.has('NONE')) {
|
if (item.statMap.has('NONE')) {
|
||||||
return null;
|
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');
|
const tier = item.statMap.get('tier');
|
||||||
this.input_field.classList.add(tier);
|
this.input_field.classList.add(tier);
|
||||||
if (this.health_field) {
|
if (this.health_field) {
|
||||||
|
@ -307,7 +312,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 [item] = input_map.values(); // Extract values, pattern match it into size one list and bind to first element
|
||||||
|
|
||||||
const type = item.statMap.get('type');
|
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);
|
let dps = get_base_dps(item.statMap);
|
||||||
if (isNaN(dps)) {
|
if (isNaN(dps)) {
|
||||||
dps = dps[1];
|
dps = dps[1];
|
||||||
|
@ -374,39 +380,39 @@ class URLUpdateNode extends ComputeNode {
|
||||||
* Create a "build" object from a set of equipments.
|
* Create a "build" object from a set of equipments.
|
||||||
* Returns a new Build object, or null if all items are NONE items.
|
* Returns a new Build object, or null if all items are NONE items.
|
||||||
*
|
*
|
||||||
* Signature: BuildAssembleNode(helmet-input: Item,
|
* Signature: BuildAssembleNode(helmet: Item,
|
||||||
* chestplate-input: Item,
|
* chestplate: Item,
|
||||||
* leggings-input: Item,
|
* leggings: Item,
|
||||||
* boots-input: Item,
|
* boots: Item,
|
||||||
* ring1-input: Item,
|
* ring1: Item,
|
||||||
* ring2-input: Item,
|
* ring2: Item,
|
||||||
* bracelet-input: Item,
|
* bracelet: Item,
|
||||||
* necklace-input: Item,
|
* necklace: Item,
|
||||||
* weapon-input: Item,
|
* weapon: Item,
|
||||||
* level-input: int) => Build | null
|
* level: int) => Build | null
|
||||||
*/
|
*/
|
||||||
class BuildAssembleNode extends ComputeNode {
|
class BuildAssembleNode extends ComputeNode {
|
||||||
constructor() { super("builder-make-build"); }
|
constructor() { super("builder-make-build"); }
|
||||||
|
|
||||||
compute_func(input_map) {
|
compute_func(input_map) {
|
||||||
let equipments = [
|
let equipments = [
|
||||||
input_map.get('helmet-input'),
|
input_map.get('helmet'),
|
||||||
input_map.get('chestplate-input'),
|
input_map.get('chestplate'),
|
||||||
input_map.get('leggings-input'),
|
input_map.get('leggings'),
|
||||||
input_map.get('boots-input'),
|
input_map.get('boots'),
|
||||||
input_map.get('ring1-input'),
|
input_map.get('ring1'),
|
||||||
input_map.get('ring2-input'),
|
input_map.get('ring2'),
|
||||||
input_map.get('bracelet-input'),
|
input_map.get('bracelet'),
|
||||||
input_map.get('necklace-input'),
|
input_map.get('necklace'),
|
||||||
input_map.get('weaponTome1-input'),
|
input_map.get('weaponTome1'),
|
||||||
input_map.get('weaponTome2-input'),
|
input_map.get('weaponTome2'),
|
||||||
input_map.get('armorTome1-input'),
|
input_map.get('armorTome1'),
|
||||||
input_map.get('armorTome2-input'),
|
input_map.get('armorTome2'),
|
||||||
input_map.get('armorTome3-input'),
|
input_map.get('armorTome3'),
|
||||||
input_map.get('armorTome4-input'),
|
input_map.get('armorTome4'),
|
||||||
input_map.get('guildTome1-input')
|
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'));
|
let level = parseInt(input_map.get('level-input'));
|
||||||
if (isNaN(level)) {
|
if (isNaN(level)) {
|
||||||
level = 106;
|
level = 106;
|
||||||
|
@ -429,6 +435,7 @@ class PlayerClassNode extends ValueCheckComputeNode {
|
||||||
compute_func(input_map) {
|
compute_func(input_map) {
|
||||||
if (input_map.size !== 1) { throw "PlayerClassNode accepts exactly one input (build)"; }
|
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
|
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'));
|
return wep_to_class.get(build.weapon.statMap.get('type'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,15 +444,25 @@ class PlayerClassNode extends ValueCheckComputeNode {
|
||||||
* Read an input field and parse into a list of powderings.
|
* Read an input field and parse into a list of powderings.
|
||||||
* Every two characters makes one powder. If parsing fails, NULL is returned.
|
* 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 {
|
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) {
|
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
|
// TODO: haha improve efficiency to O(n) dumb
|
||||||
// also, error handling is missing
|
|
||||||
let input = this.input_field.value.trim();
|
let input = this.input_field.value.trim();
|
||||||
let powdering = [];
|
let powdering = [];
|
||||||
let errorederrors = [];
|
let errorederrors = [];
|
||||||
|
@ -453,12 +470,29 @@ class PowderInputNode extends InputNode {
|
||||||
let first = input.slice(0, 2);
|
let first = input.slice(0, 2);
|
||||||
let powder = powderIDs.get(first);
|
let powder = powderIDs.get(first);
|
||||||
if (powder === undefined) {
|
if (powder === undefined) {
|
||||||
return null;
|
if (first.length > 0) {
|
||||||
|
errorederrors.push(first);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
powdering.push(powder);
|
powdering.push(powder);
|
||||||
}
|
}
|
||||||
input = input.slice(2);
|
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;
|
return powdering;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -620,7 +654,7 @@ class SpellDamageCalcNode extends ComputeNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
spell_result.heal_amount += subpart.heal_amount;
|
spell_result.heal_amount += subpart.heal_amount * hits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spell_result.name = part.name;
|
spell_result.name = part.name;
|
||||||
|
@ -656,59 +690,10 @@ class SpellDisplayNode extends ComputeNode {
|
||||||
const i = this.spell_idx;
|
const i = this.spell_idx;
|
||||||
let parent_elem = document.getElementById("spell"+i+"-info");
|
let parent_elem = document.getElementById("spell"+i+"-info");
|
||||||
let overallparent_elem = document.getElementById("spell"+i+"-infoAvg");
|
let overallparent_elem = document.getElementById("spell"+i+"-infoAvg");
|
||||||
displaySpellDamage(parent_elem, overallparent_elem, stats, spell, i+1, damages);
|
displaySpellDamage(parent_elem, overallparent_elem, stats, spell, i, damages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get melee stats for build.
|
|
||||||
Returns an array in the order:
|
|
||||||
*/
|
|
||||||
function getMeleeStats(stats, weapon) {
|
|
||||||
stats = new Map(stats); // Shallow copy
|
|
||||||
const weapon_stats = weapon.statMap;
|
|
||||||
const skillpoints = [
|
|
||||||
stats.get('str'),
|
|
||||||
stats.get('dex'),
|
|
||||||
stats.get('int'),
|
|
||||||
stats.get('def'),
|
|
||||||
stats.get('agi')
|
|
||||||
];
|
|
||||||
if (weapon_stats.get("tier") === "Crafted") {
|
|
||||||
stats.set("damageBases", [weapon_stats.get("nDamBaseHigh"),weapon_stats.get("eDamBaseHigh"),weapon_stats.get("tDamBaseHigh"),weapon_stats.get("wDamBaseHigh"),weapon_stats.get("fDamBaseHigh"),weapon_stats.get("aDamBaseHigh")]);
|
|
||||||
}
|
|
||||||
let adjAtkSpd = attackSpeeds.indexOf(stats.get("atkSpd")) + stats.get("atkTier");
|
|
||||||
if(adjAtkSpd > 6){
|
|
||||||
adjAtkSpd = 6;
|
|
||||||
}else if(adjAtkSpd < 0){
|
|
||||||
adjAtkSpd = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (weapon_stats.get("type") === "relik") {
|
|
||||||
merge_stat(stats, 'damMult.ShamanMelee', 0.99); // CURSE YOU WYNNCRAFT
|
|
||||||
//One day we will create WynnWynn and no longer have shaman 99% melee injustice.
|
|
||||||
//In all seriousness 99% is because wynn uses 0.33 to estimate dividing the damage by 3 to split damage between 3 beams.
|
|
||||||
}
|
|
||||||
let results = calculateSpellDamage(stats, weapon_stats, [100, 0, 0, 0, 0, 0], false, true);
|
|
||||||
|
|
||||||
let dex = skillpoints[1];
|
|
||||||
|
|
||||||
let totalDamNorm = results[0];
|
|
||||||
let totalDamCrit = results[1];
|
|
||||||
totalDamNorm.push(1-skillPointsToPercentage(dex));
|
|
||||||
totalDamCrit.push(skillPointsToPercentage(dex));
|
|
||||||
let damages_results = results[2];
|
|
||||||
|
|
||||||
let singleHitTotal = ((totalDamNorm[0]+totalDamNorm[1])*(totalDamNorm[2])
|
|
||||||
+(totalDamCrit[0]+totalDamCrit[1])*(totalDamCrit[2]))/2;
|
|
||||||
|
|
||||||
//Now do math
|
|
||||||
let normDPS = (totalDamNorm[0]+totalDamNorm[1])/2 * baseDamageMultiplier[adjAtkSpd];
|
|
||||||
let critDPS = (totalDamCrit[0]+totalDamCrit[1])/2 * baseDamageMultiplier[adjAtkSpd];
|
|
||||||
let avgDPS = (normDPS * (1 - skillPointsToPercentage(dex))) + (critDPS * (skillPointsToPercentage(dex)));
|
|
||||||
//[[n n n n] [e e e e] [t t t t] [w w w w] [f f f f] [a a a a] [lowtotal hightotal normalChance] [critlowtotal crithightotal critChance] normalDPS critCPS averageDPS adjAttackSpeed, singleHit]
|
|
||||||
return damages_results.concat([totalDamNorm,totalDamCrit,normDPS,critDPS,avgDPS,adjAtkSpd, singleHitTotal]).concat(results[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display build stats.
|
* Display build stats.
|
||||||
*
|
*
|
||||||
|
@ -723,10 +708,7 @@ class BuildDisplayNode extends ComputeNode {
|
||||||
displayBuildStats('overall-stats', build, build_all_display_commands, stats);
|
displayBuildStats('overall-stats', build, build_all_display_commands, stats);
|
||||||
displayBuildStats("offensive-stats", build, build_offensive_display_commands, stats);
|
displayBuildStats("offensive-stats", build, build_offensive_display_commands, stats);
|
||||||
displaySetBonuses("set-info", build);
|
displaySetBonuses("set-info", build);
|
||||||
let meleeStats = getMeleeStats(stats, build.weapon);
|
|
||||||
// TODO: move weapon out?
|
// TODO: move weapon out?
|
||||||
displayMeleeDamage(document.getElementById("build-melee-stats"), document.getElementById("build-melee-statsAvg"), meleeStats);
|
|
||||||
|
|
||||||
displayDefenseStats(document.getElementById("defensive-stats"), stats);
|
displayDefenseStats(document.getElementById("defensive-stats"), stats);
|
||||||
|
|
||||||
displayPoisonDamage(document.getElementById("build-poison-stats"), build);
|
displayPoisonDamage(document.getElementById("build-poison-stats"), build);
|
||||||
|
@ -754,7 +736,7 @@ class DisplayBuildWarningsNode extends ComputeNode {
|
||||||
input_map.get('def'),
|
input_map.get('def'),
|
||||||
input_map.get('agi')
|
input_map.get('agi')
|
||||||
];
|
];
|
||||||
let skp_effects = ["% more damage dealt.","% chance to crit.","% spell cost reduction.","% less damage taken.","% chance to dodge."];
|
let skp_effects = ["% damage","% crit","% cost red.","% resist","% dodge"];
|
||||||
let total_assigned = 0;
|
let total_assigned = 0;
|
||||||
for (let i in skp_order){ //big bren
|
for (let i in skp_order){ //big bren
|
||||||
const assigned = skillpoints[i] - base_totals[i] + min_assigned[i]
|
const assigned = skillpoints[i] - base_totals[i] + min_assigned[i]
|
||||||
|
@ -776,20 +758,16 @@ class DisplayBuildWarningsNode extends ComputeNode {
|
||||||
|
|
||||||
let summarybox = document.getElementById("summary-box");
|
let summarybox = document.getElementById("summary-box");
|
||||||
summarybox.textContent = "";
|
summarybox.textContent = "";
|
||||||
let skpRow = document.createElement("p");
|
|
||||||
|
|
||||||
let remainingSkp = document.createElement("p");
|
let remainingSkp = make_elem("p", ['scaled-font', 'my-0']);
|
||||||
remainingSkp.classList.add("scaled-font");
|
let remainingSkpTitle = make_elem("b", [], { textContent: "Assigned " + total_assigned + " skillpoints. Remaining skillpoints: " });
|
||||||
let remainingSkpTitle = document.createElement("b");
|
|
||||||
remainingSkpTitle.textContent = "Assigned " + total_assigned + " skillpoints. Remaining skillpoints: ";
|
|
||||||
let remainingSkpContent = document.createElement("b");
|
let remainingSkpContent = document.createElement("b");
|
||||||
remainingSkpContent.textContent = "" + (levelToSkillPoints(build.level) - total_assigned);
|
remainingSkpContent.textContent = "" + (levelToSkillPoints(build.level) - total_assigned);
|
||||||
remainingSkpContent.classList.add(levelToSkillPoints(build.level) - total_assigned < 0 ? "negative" : "positive");
|
remainingSkpContent.classList.add(levelToSkillPoints(build.level) - total_assigned < 0 ? "negative" : "positive");
|
||||||
|
|
||||||
remainingSkp.appendChild(remainingSkpTitle);
|
remainingSkp.append(remainingSkpTitle);
|
||||||
remainingSkp.appendChild(remainingSkpContent);
|
remainingSkp.append(remainingSkpContent);
|
||||||
|
|
||||||
summarybox.append(skpRow);
|
|
||||||
summarybox.append(remainingSkp);
|
summarybox.append(remainingSkp);
|
||||||
if(total_assigned > levelToSkillPoints(build.level)){
|
if(total_assigned > levelToSkillPoints(build.level)){
|
||||||
let skpWarning = document.createElement("span");
|
let skpWarning = document.createElement("span");
|
||||||
|
@ -846,7 +824,7 @@ class DisplayBuildWarningsNode extends ComputeNode {
|
||||||
* Signature: AggregateStatsNode(*args) => StatMap
|
* Signature: AggregateStatsNode(*args) => StatMap
|
||||||
*/
|
*/
|
||||||
class AggregateStatsNode extends ComputeNode {
|
class AggregateStatsNode extends ComputeNode {
|
||||||
constructor() { super("builder-aggregate-stats"); }
|
constructor(name) { super(name); }
|
||||||
|
|
||||||
compute_func(input_map) {
|
compute_func(input_map) {
|
||||||
const output_stats = new Map();
|
const output_stats = new Map();
|
||||||
|
@ -977,9 +955,11 @@ class SumNumberInputNode extends InputNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
let item_nodes = [];
|
let item_nodes = [];
|
||||||
|
let item_nodes_map = new Map();
|
||||||
let powder_nodes = [];
|
let powder_nodes = [];
|
||||||
let edit_input_nodes = [];
|
let edit_input_nodes = [];
|
||||||
let skp_inputs = [];
|
let skp_inputs = [];
|
||||||
|
let equip_inputs = [];
|
||||||
let build_node;
|
let build_node;
|
||||||
let stat_agg_node;
|
let stat_agg_node;
|
||||||
let edit_agg_node;
|
let edit_agg_node;
|
||||||
|
@ -988,68 +968,71 @@ let atree_graph_creator;
|
||||||
function builder_graph_init() {
|
function builder_graph_init() {
|
||||||
// Phase 1/3: Set up item input, propagate updates, etc.
|
// Phase 1/3: Set up item input, propagate updates, etc.
|
||||||
|
|
||||||
// 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);
|
|
||||||
item_nodes.push(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');
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
item_nodes.push(item_input);
|
|
||||||
new ItemInputDisplayNode(eq+'-input-display', eq, item_image).link_to(item_input);
|
|
||||||
}
|
|
||||||
|
|
||||||
// weapon image changer node.
|
|
||||||
let weapon_image = document.getElementById("weapon-img");
|
|
||||||
let weapon_dps = document.getElementById("weapon-dps");
|
|
||||||
new WeaponInputDisplayNode('weapon-type', weapon_image, weapon_dps).link_to(item_nodes[8]);
|
|
||||||
|
|
||||||
// Level input node.
|
// Level input node.
|
||||||
let level_input = new InputNode('level-input', document.getElementById('level-choice'));
|
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" now only refers to equipment and level (no powders). Powders are injected before damage calculation / stat display.
|
||||||
build_node = new BuildAssembleNode();
|
build_node = new BuildAssembleNode();
|
||||||
for (const input of item_nodes) {
|
for (const input of item_nodes) {
|
||||||
build_node.link_to(input);
|
|
||||||
}
|
}
|
||||||
build_node.link_to(level_input);
|
build_node.link_to(level_input);
|
||||||
|
|
||||||
let build_encode_node = new BuildEncodeNode();
|
let build_encode_node = new BuildEncodeNode();
|
||||||
build_encode_node.link_to(build_node, 'build');
|
build_encode_node.link_to(build_node, 'build');
|
||||||
|
|
||||||
let url_update_node = new URLUpdateNode();
|
// Bind item input fields to input nodes, and some display stuff (for auto colorizing stuff).
|
||||||
url_update_node.link_to(build_encode_node, 'build-str');
|
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);
|
||||||
for (const input of powder_inputs) {
|
equip_inputs.push(item_input);
|
||||||
let powder_node = new PowderInputNode(input, document.getElementById(input));
|
if (powder_inputs.includes(eq+'-powder')) { // TODO: fragile
|
||||||
powder_nodes.push(powder_node);
|
const powder_name = eq+'-powder';
|
||||||
build_encode_node.link_to(powder_node, input);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
item_nodes[0].link_to(powder_nodes[0], 'powdering');
|
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]])) {
|
||||||
item_nodes[1].link_to(powder_nodes[1], 'powdering');
|
let input_field = document.getElementById(eq+"-choice");
|
||||||
item_nodes[2].link_to(powder_nodes[2], 'powdering');
|
let item_image = document.getElementById(eq+"-img");
|
||||||
item_nodes[3].link_to(powder_nodes[3], 'powdering');
|
|
||||||
item_nodes[8].link_to(powder_nodes[4], 'powdering');
|
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.
|
||||||
|
let weapon_image = document.getElementById("weapon-img");
|
||||||
|
let weapon_dps = document.getElementById("weapon-dps");
|
||||||
|
new WeaponInputDisplayNode('weapon-type', weapon_image, weapon_dps).link_to(item_nodes[8]);
|
||||||
|
|
||||||
|
// linking to atree verification
|
||||||
|
atree_validate.link_to(level_input, 'level');
|
||||||
|
|
||||||
|
let url_update_node = new URLUpdateNode();
|
||||||
|
url_update_node.link_to(build_encode_node, 'build-str');
|
||||||
|
|
||||||
// Phase 2/3: Set up editable IDs, skill points; use decodeBuild() skill points, calculate damage
|
// 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)
|
// 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)
|
||||||
stat_agg_node = new AggregateStatsNode();
|
pre_scale_agg_node = new AggregateStatsNode('pre-scale-stats');
|
||||||
|
stat_agg_node = new AggregateStatsNode('final-stats');
|
||||||
edit_agg_node = new AggregateEditableIDNode();
|
edit_agg_node = new AggregateEditableIDNode();
|
||||||
edit_agg_node.link_to(build_node, 'build');
|
edit_agg_node.link_to(build_node, 'build');
|
||||||
for (const field of editable_item_fields) {
|
for (const field of editable_item_fields) {
|
||||||
|
@ -1073,7 +1056,7 @@ function builder_graph_init() {
|
||||||
edit_input_nodes.push(node);
|
edit_input_nodes.push(node);
|
||||||
skp_inputs.push(node);
|
skp_inputs.push(node);
|
||||||
}
|
}
|
||||||
stat_agg_node.link_to(edit_agg_node);
|
pre_scale_agg_node.link_to(edit_agg_node);
|
||||||
|
|
||||||
// Phase 3/3: Set up atree stuff.
|
// Phase 3/3: Set up atree stuff.
|
||||||
|
|
||||||
|
@ -1081,15 +1064,17 @@ 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');
|
||||||
atree_stats.link_to(build_node, 'build');
|
pre_scale_agg_node.link_to(atree_stats, 'atree-raw-stats');
|
||||||
stat_agg_node.link_to(atree_stats, 'atree-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(atree_scaling, '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');
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// Trigger the update cascade for build!
|
// 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();
|
input_node.update();
|
||||||
}
|
}
|
||||||
armor_powder_node.update();
|
armor_powder_node.update();
|
||||||
|
@ -1114,7 +1099,7 @@ function builder_graph_init() {
|
||||||
let powder_special_calc = new PowderSpecialCalcNode().link_to(powder_special_input, 'powder-specials');
|
let powder_special_calc = new PowderSpecialCalcNode().link_to(powder_special_input, 'powder-specials');
|
||||||
new PowderSpecialDisplayNode().link_to(powder_special_input, 'powder-specials')
|
new PowderSpecialDisplayNode().link_to(powder_special_input, 'powder-specials')
|
||||||
.link_to(stat_agg_node, 'stats').link_to(build_node, 'build');
|
.link_to(stat_agg_node, 'stats').link_to(build_node, 'build');
|
||||||
stat_agg_node.link_to(powder_special_calc, 'powder-boost');
|
pre_scale_agg_node.link_to(powder_special_calc, 'powder-boost');
|
||||||
stat_agg_node.link_to(armor_powder_node, 'armor-powder');
|
stat_agg_node.link_to(armor_powder_node, 'armor-powder');
|
||||||
powder_special_input.update();
|
powder_special_input.update();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
let all_nodes = [];
|
let all_nodes = new Set();
|
||||||
let node_debug_stack = [];
|
let node_debug_stack = [];
|
||||||
|
let COMPUTE_GRAPH_DEBUG = false;
|
||||||
class ComputeNode {
|
class ComputeNode {
|
||||||
/**
|
/**
|
||||||
* Make a generic compute node.
|
* Make a generic compute node.
|
||||||
|
@ -21,7 +22,7 @@ class ComputeNode {
|
||||||
// 0: clean
|
// 0: clean
|
||||||
this.inputs_dirty = new Map();
|
this.inputs_dirty = new Map();
|
||||||
this.inputs_dirty_count = 0;
|
this.inputs_dirty_count = 0;
|
||||||
all_nodes.push(this);
|
if (COMPUTE_GRAPH_DEBUG) { all_nodes.add(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,7 +35,7 @@ class ComputeNode {
|
||||||
if (this.dirty === 0) {
|
if (this.dirty === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node_debug_stack.push(this.name);
|
if (COMPUTE_GRAPH_DEBUG) { node_debug_stack.push(this.name); }
|
||||||
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) {
|
||||||
|
@ -46,7 +47,7 @@ class ComputeNode {
|
||||||
for (const child of this.children) {
|
for (const child of this.children) {
|
||||||
child.mark_input_clean(this.name, this.value);
|
child.mark_input_clean(this.name, this.value);
|
||||||
}
|
}
|
||||||
node_debug_stack.pop();
|
if (COMPUTE_GRAPH_DEBUG) { node_debug_stack.pop(); }
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +135,7 @@ class ComputeNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ValueCheckComputeNode extends 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,
|
* Request update of this compute node. Pushes updates to children,
|
||||||
|
@ -153,14 +154,11 @@ class ValueCheckComputeNode extends ComputeNode {
|
||||||
calc_inputs.set(this.input_translation.get(input.name), input.value);
|
calc_inputs.set(this.input_translation.get(input.name), input.value);
|
||||||
}
|
}
|
||||||
let val = this.compute_func(calc_inputs);
|
let val = this.compute_func(calc_inputs);
|
||||||
if (val !== this.value) {
|
if (val !== null) {
|
||||||
super.mark_dirty(2);
|
if (val !== this.valid_val) { super.mark_dirty(2); } // don't mark dirty if NULL (no update)
|
||||||
}
|
this.valid_val = val;
|
||||||
else {
|
|
||||||
console.log("soft update");
|
|
||||||
}
|
}
|
||||||
this.value = val;
|
this.value = val;
|
||||||
|
|
||||||
this.dirty = 0;
|
this.dirty = 0;
|
||||||
for (const child of this.children) {
|
for (const child of this.children) {
|
||||||
child.mark_input_clean(this.name, this.value);
|
child.mark_input_clean(this.name, this.value);
|
||||||
|
@ -190,7 +188,7 @@ function calcSchedule(node, timeout) {
|
||||||
}
|
}
|
||||||
node.mark_dirty();
|
node.mark_dirty();
|
||||||
node.update_task = setTimeout(function() {
|
node.update_task = setTimeout(function() {
|
||||||
node_debug_stack = [];
|
if (COMPUTE_GRAPH_DEBUG) { node_debug_stack = []; }
|
||||||
node.update();
|
node.update();
|
||||||
node.update_task = null;
|
node.update_task = null;
|
||||||
}, timeout);
|
}, timeout);
|
||||||
|
|
|
@ -345,9 +345,16 @@ function toggleMaterial(buttonId) {
|
||||||
function updateCraftedImage() {
|
function updateCraftedImage() {
|
||||||
let input = document.getElementById("recipe-choice");
|
let input = document.getElementById("recipe-choice");
|
||||||
if (all_types.includes(input.value)) {
|
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
|
/* Reset all fields
|
||||||
|
|
|
@ -65,7 +65,7 @@ function encodeCustom(custom, verbose) {
|
||||||
if (typeof (val) === "string" && val !== "") {
|
if (typeof (val) === "string" && val !== "") {
|
||||||
if ((damages.includes(id) && val === "0-0") || (!verbose && ["lore", "majorIds", "quest", "materials", "drop", "set"].includes(id))) { continue; }
|
if ((damages.includes(id) && val === "0-0") || (!verbose && ["lore", "majorIds", "quest", "materials", "drop", "set"].includes(id))) { continue; }
|
||||||
if (id === "type") {
|
if (id === "type") {
|
||||||
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(types.indexOf(val.substring(0, 1).toUpperCase() + val.slice(1)), 1);
|
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(all_types.indexOf(val.substring(0, 1).toUpperCase() + val.slice(1)), 1);
|
||||||
} else if (id === "tier") {
|
} else if (id === "tier") {
|
||||||
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(tiers.indexOf(val), 1);
|
hash += Base64.fromIntN(i, 2) + Base64.fromIntN(tiers.indexOf(val), 1);
|
||||||
} else if (id === "atkSpd") {
|
} else if (id === "atkSpd") {
|
||||||
|
@ -147,7 +147,7 @@ function getCustomFromHash(hash) {
|
||||||
val = tiers[Base64.toInt(tag.charAt(2))];
|
val = tiers[Base64.toInt(tag.charAt(2))];
|
||||||
len = -1;
|
len = -1;
|
||||||
} else if (id === "type") {
|
} else if (id === "type") {
|
||||||
val = types[Base64.toInt(tag.charAt(2))];
|
val = all_types[Base64.toInt(tag.charAt(2))];
|
||||||
len = -1;
|
len = -1;
|
||||||
} else if (id === "atkSpd") {
|
} else if (id === "atkSpd") {
|
||||||
val = attackSpeeds[Base64.toInt(tag.charAt(2))];
|
val = attackSpeeds[Base64.toInt(tag.charAt(2))];
|
||||||
|
@ -179,7 +179,8 @@ function getCustomFromHash(hash) {
|
||||||
return new Custom(statMap);
|
return new Custom(statMap);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
//console.log(statMap);
|
console.log(error);
|
||||||
|
console.log(statMap);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,22 @@ d3.select("#graph_body")
|
||||||
.classed("svg-content-responsive", true);
|
.classed("svg-content-responsive", true);
|
||||||
let graph = d3.select("svg");
|
let graph = d3.select("svg");
|
||||||
let svg = graph.append('g');
|
let svg = graph.append('g');
|
||||||
|
|
||||||
|
// triangle arrow head definition
|
||||||
|
graph.append('defs').append('marker')
|
||||||
|
.attr('id', 'arrowhead')
|
||||||
|
.attr('viewBox', '-0 -5 10 10')
|
||||||
|
.attr('refX', 23)
|
||||||
|
.attr('refY', 0)
|
||||||
|
.attr('orient', 'auto')
|
||||||
|
.attr('markerWidth', 13)
|
||||||
|
.attr('markerHeight', 13)
|
||||||
|
.attr('xoverflow', 'visible')
|
||||||
|
.append('svg:path')
|
||||||
|
.attr('d', 'M 0,-5 L 10 ,0 L 0,5')
|
||||||
|
.attr('fill', '#aaa')
|
||||||
|
.style('stroke','none');
|
||||||
|
|
||||||
let margin = {top: 20, right: 20, bottom: 35, left: 40};
|
let margin = {top: 20, right: 20, bottom: 35, left: 40};
|
||||||
|
|
||||||
function bbox() {
|
function bbox() {
|
||||||
|
@ -87,6 +103,7 @@ function create_svg(data, redraw_func) {
|
||||||
.enter()
|
.enter()
|
||||||
.append("line")
|
.append("line")
|
||||||
.style("stroke", "#aaa")
|
.style("stroke", "#aaa")
|
||||||
|
.attr('marker-end','url(#arrowhead)');
|
||||||
|
|
||||||
// Initialize the nodes
|
// Initialize the nodes
|
||||||
let node = svg
|
let node = svg
|
||||||
|
@ -197,7 +214,7 @@ d3.select(window)
|
||||||
});
|
});
|
||||||
redraw();
|
redraw();
|
||||||
|
|
||||||
const data = convert_data(all_nodes);
|
const data = convert_data(Array.from(all_nodes));
|
||||||
create_svg(data, redraw);
|
create_svg(data, redraw);
|
||||||
|
|
||||||
console.log("render");
|
console.log("render");
|
||||||
|
|
298
js/display.js
|
@ -1,3 +1,7 @@
|
||||||
|
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) {
|
function apply_elemental_format(p_elem, id, suffix) {
|
||||||
suffix = (typeof suffix !== 'undefined') ? suffix : "";
|
suffix = (typeof suffix !== 'undefined') ? suffix : "";
|
||||||
|
@ -286,11 +290,18 @@ function displayExpandedItem(item, parent_id){
|
||||||
parent_div.appendChild(nolink_row);
|
parent_div.appendChild(nolink_row);
|
||||||
|
|
||||||
if (item.has("type")) {
|
if (item.has("type")) {
|
||||||
let img = make_elem("img", [], {
|
let img = make_elem("div", [], {
|
||||||
src: "../media/items/" + (newIcons ? "new/":"old/") + "generic-" + item.get("type") + ".png",
|
|
||||||
alt: item.get("type"),
|
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 container = make_elem("div");
|
||||||
|
|
||||||
let bckgrd = make_elem("div", ["col", "px-0", "d-flex", "align-items-center", "justify-content-center", 'scaled-bckgrd'], { // , "no-collapse"
|
let bckgrd = make_elem("div", ["col", "px-0", "d-flex", "align-items-center", "justify-content-center", 'scaled-bckgrd'], { // , "no-collapse"
|
||||||
|
@ -866,7 +877,7 @@ function displayNextCosts(_stats, spell, spellIdx) {
|
||||||
let int_needed = document.createElement("b");
|
let int_needed = document.createElement("b");
|
||||||
if (init_cost.textContent === "1") {
|
if (init_cost.textContent === "1") {
|
||||||
int_needed.textContent = ": n/a (+0)";
|
int_needed.textContent = ": n/a (+0)";
|
||||||
}else { //do math
|
} else { //do math
|
||||||
let target = getSpellCost(stats, spellIdx, spell.cost) - 1;
|
let target = getSpellCost(stats, spellIdx, spell.cost) - 1;
|
||||||
let needed = intel;
|
let needed = intel;
|
||||||
let noUpdate = false;
|
let noUpdate = false;
|
||||||
|
@ -989,23 +1000,30 @@ function displayFixedID(active, id, value, elemental_format, style) {
|
||||||
|
|
||||||
function displayPoisonDamage(overallparent_elem, build) {
|
function displayPoisonDamage(overallparent_elem, build) {
|
||||||
overallparent_elem.textContent = "";
|
overallparent_elem.textContent = "";
|
||||||
|
if (build.statMap.get('poison') <= 0) {
|
||||||
|
overallparent_elem.style = "display: none";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
overallparent_elem.style = "";
|
||||||
|
|
||||||
|
let container = make_elem('div', ['col', 'pe-0']);
|
||||||
|
let spell_summary = make_elem('div', ["col", "spell-display", "dark-5", "rounded", "dark-shadow", "py-2", "border", "border-dark"]);
|
||||||
|
|
||||||
//Title
|
//Title
|
||||||
let title_elemavg = document.createElement("b");
|
let title_elemavg = make_elem("b");
|
||||||
title_elemavg.textContent = "Poison Stats";
|
title_elemavg.append(make_elem('span', [], { textContent: "Poison Stats" }));
|
||||||
overallparent_elem.append(title_elemavg);
|
spell_summary.append(title_elemavg);
|
||||||
|
|
||||||
let overallpoisonDamage = document.createElement("p");
|
|
||||||
let overallpoisonDamageFirst = document.createElement("span");
|
|
||||||
let overallpoisonDamageSecond = document.createElement("span");
|
|
||||||
let poison_tick = Math.ceil(build.statMap.get("poison") * (1+skillPointsToPercentage(build.total_skillpoints[0])) * (build.statMap.get("poisonPct"))/100 /3);
|
let poison_tick = Math.ceil(build.statMap.get("poison") * (1+skillPointsToPercentage(build.total_skillpoints[0])) * (build.statMap.get("poisonPct"))/100 /3);
|
||||||
overallpoisonDamageFirst.textContent = "Poison Tick: ";
|
|
||||||
overallpoisonDamageSecond.textContent = Math.max(poison_tick,0);
|
|
||||||
overallpoisonDamageSecond.classList.add("Damage");
|
|
||||||
|
|
||||||
overallpoisonDamage.appendChild(overallpoisonDamageFirst);
|
let overallpoisonDamage = make_elem("p");
|
||||||
overallpoisonDamage.appendChild(overallpoisonDamageSecond);
|
overallpoisonDamage.append(
|
||||||
overallparent_elem.append(overallpoisonDamage);
|
make_elem("span", [], { textContent: "Poison Tick: " }),
|
||||||
|
make_elem("span", ["Damage"], { textContent: Math.max(poison_tick,0) })
|
||||||
|
);
|
||||||
|
spell_summary.append(overallpoisonDamage);
|
||||||
|
container.append(spell_summary);
|
||||||
|
overallparent_elem.append(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayEquipOrder(parent_elem, buildOrder){
|
function displayEquipOrder(parent_elem, buildOrder){
|
||||||
|
@ -1022,152 +1040,6 @@ function displayEquipOrder(parent_elem, buildOrder){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayMeleeDamage(parent_elem, overallparent_elem, meleeStats) {
|
|
||||||
let attackSpeeds = ["Super Slow", "Very Slow", "Slow", "Normal", "Fast", "Very Fast", "Super Fast"];
|
|
||||||
//let damagePrefixes = ["Neutral Damage: ","Earth Damage: ","Thunder Damage: ","Water Damage: ","Fire Damage: ","Air Damage: "];
|
|
||||||
parent_elem.textContent = "";
|
|
||||||
overallparent_elem.textContent = "";
|
|
||||||
const stats = meleeStats.slice();
|
|
||||||
|
|
||||||
for (let i = 0; i < 6; ++i) {
|
|
||||||
for (let j in stats[i]) {
|
|
||||||
stats[i][j] = stats[i][j].toFixed(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 6; i < 8; ++i) {
|
|
||||||
for (let j = 0; j < 2; j++) {
|
|
||||||
stats[i][j] = stats[i][j].toFixed(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 8; i < 11; ++i) {
|
|
||||||
stats[i] = stats[i].toFixed(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//title
|
|
||||||
let title_elem = document.createElement("p");
|
|
||||||
title_elem.classList.add("title");
|
|
||||||
title_elem.textContent = "Melee Stats";
|
|
||||||
parent_elem.append(title_elem);
|
|
||||||
parent_elem.append(document.createElement("br"));
|
|
||||||
|
|
||||||
//overall title
|
|
||||||
let title_elemavg = document.createElement("b");
|
|
||||||
title_elemavg.textContent = "Melee Stats";
|
|
||||||
overallparent_elem.append(title_elemavg);
|
|
||||||
|
|
||||||
//average DPS
|
|
||||||
let averageDamage = document.createElement("p");
|
|
||||||
averageDamage.classList.add("left");
|
|
||||||
averageDamage.textContent = "Average DPS: " + stats[10];
|
|
||||||
parent_elem.append(averageDamage);
|
|
||||||
|
|
||||||
//overall average DPS
|
|
||||||
let overallaverageDamage = document.createElement("p");
|
|
||||||
let overallaverageDamageFirst = document.createElement("span");
|
|
||||||
overallaverageDamageFirst.textContent = "Average DPS: "
|
|
||||||
|
|
||||||
let overallaverageDamageSecond = document.createElement("span");
|
|
||||||
overallaverageDamageSecond.classList.add("Damage");
|
|
||||||
overallaverageDamageSecond.textContent = stats[10];
|
|
||||||
overallaverageDamage.appendChild(overallaverageDamageFirst);
|
|
||||||
overallaverageDamage.appendChild(overallaverageDamageSecond);
|
|
||||||
|
|
||||||
overallparent_elem.append(overallaverageDamage);
|
|
||||||
//overallparent_elem.append(document.createElement("br"));
|
|
||||||
|
|
||||||
//attack speed
|
|
||||||
let atkSpd = document.createElement("p");
|
|
||||||
atkSpd.classList.add("left");
|
|
||||||
atkSpd.textContent = "Attack Speed: " + attackSpeeds[stats[11]];
|
|
||||||
parent_elem.append(atkSpd);
|
|
||||||
parent_elem.append(document.createElement("br"));
|
|
||||||
|
|
||||||
//overall attack speed
|
|
||||||
let overallatkSpd = document.createElement("p");
|
|
||||||
let overallatkSpdFirst = document.createElement("span");
|
|
||||||
overallatkSpdFirst.textContent = "Attack Speed: ";
|
|
||||||
let overallatkSpdSecond = document.createElement("span");
|
|
||||||
overallatkSpdSecond.classList.add("Damage");
|
|
||||||
overallatkSpdSecond.textContent = attackSpeeds[stats[11]];
|
|
||||||
overallatkSpd.appendChild(overallatkSpdFirst);
|
|
||||||
overallatkSpd.appendChild(overallatkSpdSecond);
|
|
||||||
overallparent_elem.append(overallatkSpd);
|
|
||||||
|
|
||||||
//Non-Crit: n->elem, total dmg, DPS
|
|
||||||
let nonCritStats = document.createElement("p");
|
|
||||||
nonCritStats.classList.add("left");
|
|
||||||
nonCritStats.textContent = "Non-Crit Stats: ";
|
|
||||||
nonCritStats.append(document.createElement("br"));
|
|
||||||
for (let i = 0; i < 6; i++) {
|
|
||||||
if (stats[i][1] != 0) {
|
|
||||||
let dmg = document.createElement("p");
|
|
||||||
dmg.textContent = stats[i][0] + " \u2013 " + stats[i][1];
|
|
||||||
dmg.classList.add(damageClasses[i]);
|
|
||||||
dmg.classList.add("itemp");
|
|
||||||
nonCritStats.append(dmg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let normalDamage = document.createElement("p");
|
|
||||||
normalDamage.textContent = "Total: " + stats[6][0] + " \u2013 " + stats[6][1];
|
|
||||||
nonCritStats.append(normalDamage);
|
|
||||||
|
|
||||||
let normalDPS = document.createElement("p");
|
|
||||||
normalDPS.textContent = "Normal DPS: " + stats[8];
|
|
||||||
nonCritStats.append(normalDPS);
|
|
||||||
|
|
||||||
//overall average DPS
|
|
||||||
let singleHitDamage = document.createElement("p");
|
|
||||||
let singleHitDamageFirst = document.createElement("span");
|
|
||||||
singleHitDamageFirst.textContent = "Single Hit Average: ";
|
|
||||||
let singleHitDamageSecond = document.createElement("span");
|
|
||||||
singleHitDamageSecond.classList.add("Damage");
|
|
||||||
singleHitDamageSecond.textContent = stats[12].toFixed(2);
|
|
||||||
singleHitDamage.appendChild(singleHitDamageFirst);
|
|
||||||
singleHitDamage.appendChild(singleHitDamageSecond);
|
|
||||||
overallparent_elem.append(singleHitDamage);
|
|
||||||
|
|
||||||
let normalChance = document.createElement("p");
|
|
||||||
normalChance.textContent = "Non-Crit Chance: " + (stats[6][2]*100).toFixed(2) + "%";
|
|
||||||
normalChance.append(document.createElement("br"));
|
|
||||||
normalChance.append(document.createElement("br"));
|
|
||||||
nonCritStats.append(normalChance);
|
|
||||||
|
|
||||||
parent_elem.append(nonCritStats);
|
|
||||||
parent_elem.append(document.createElement("br"));
|
|
||||||
|
|
||||||
//Crit: n->elem, total dmg, DPS
|
|
||||||
let critStats = document.createElement("p");
|
|
||||||
critStats.classList.add("left");
|
|
||||||
critStats.textContent = "Crit Stats: ";
|
|
||||||
critStats.append(document.createElement("br"));
|
|
||||||
for (let i = 0; i < 6; i++){
|
|
||||||
if(stats[i][3] != 0) {
|
|
||||||
dmg = document.createElement("p");
|
|
||||||
dmg.textContent = stats[i][2] + " \u2013 " + stats[i][3];
|
|
||||||
dmg.classList.add(damageClasses[i]);
|
|
||||||
dmg.classList.add("itemp");
|
|
||||||
critStats.append(dmg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let critDamage = document.createElement("p");
|
|
||||||
critDamage.textContent = "Total: " + stats[7][0] + " \u2013 " + stats[7][1];
|
|
||||||
critStats.append(critDamage);
|
|
||||||
|
|
||||||
let critDPS = document.createElement("p");
|
|
||||||
critDPS.textContent = "Crit DPS: " + stats[9];
|
|
||||||
critStats.append(critDPS);
|
|
||||||
|
|
||||||
let critChance = document.createElement("p");
|
|
||||||
critChance.textContent = "Crit Chance: " + (stats[7][2]*100).toFixed(2) + "%";
|
|
||||||
critChance.append(document.createElement("br"));
|
|
||||||
critChance.append(document.createElement("br"));
|
|
||||||
critStats.append(critChance);
|
|
||||||
|
|
||||||
parent_elem.append(critStats);
|
|
||||||
addClickableArrow(overallparent_elem, parent_elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayDefenseStats(parent_elem, statMap, insertSummary){
|
function displayDefenseStats(parent_elem, statMap, insertSummary){
|
||||||
let defenseStats = getDefenseStats(statMap);
|
let defenseStats = getDefenseStats(statMap);
|
||||||
insertSummary = (typeof insertSummary !== 'undefined') ? insertSummary : false;
|
insertSummary = (typeof insertSummary !== 'undefined') ? insertSummary : false;
|
||||||
|
@ -1374,6 +1246,13 @@ function displayDefenseStats(parent_elem, statMap, insertSummary){
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayPowderSpecials(parent_elem, powderSpecials, stats, weapon, overall=false) {
|
function displayPowderSpecials(parent_elem, powderSpecials, stats, weapon, overall=false) {
|
||||||
|
parent_elem.textContent = "";
|
||||||
|
if (powderSpecials.length === 0) {
|
||||||
|
parent_elem.style = "display: none";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parent_elem.style = "";
|
||||||
|
|
||||||
const skillpoints = [
|
const skillpoints = [
|
||||||
stats.get('str'),
|
stats.get('str'),
|
||||||
stats.get('dex'),
|
stats.get('dex'),
|
||||||
|
@ -1381,16 +1260,13 @@ function displayPowderSpecials(parent_elem, powderSpecials, stats, weapon, overa
|
||||||
stats.get('def'),
|
stats.get('def'),
|
||||||
stats.get('agi')
|
stats.get('agi')
|
||||||
];
|
];
|
||||||
parent_elem.textContent = ""
|
parent_elem.append(make_elem("b", [], { textContent: "Powder Specials" }));
|
||||||
let title = document.createElement("b");
|
|
||||||
title.textContent = "Powder Specials";
|
|
||||||
parent_elem.appendChild(title);
|
|
||||||
let specials = powderSpecials.slice();
|
let specials = powderSpecials.slice();
|
||||||
let expandedStats = new Map();
|
let expandedStats = new Map();
|
||||||
//each entry of powderSpecials is [ps, power]
|
//each entry of powderSpecials is [ps, power]
|
||||||
for (special of specials) {
|
for (special of specials) {
|
||||||
//iterate through the special and display its effects.
|
//iterate through the special and display its effects.
|
||||||
let powder_special = document.createElement("p");
|
let powder_special = make_elem("p", ["pt-3"]);
|
||||||
let specialSuffixes = new Map([ ["Duration", " sec"], ["Radius", " blocks"], ["Chains", ""], ["Damage", "%"], ["Damage Boost", "%"], ["Knockback", " blocks"] ]);
|
let specialSuffixes = new Map([ ["Duration", " sec"], ["Radius", " blocks"], ["Chains", ""], ["Damage", "%"], ["Damage Boost", "%"], ["Knockback", " blocks"] ]);
|
||||||
let specialTitle = document.createElement("p");
|
let specialTitle = document.createElement("p");
|
||||||
let specialEffects = document.createElement("p");
|
let specialEffects = document.createElement("p");
|
||||||
|
@ -1521,43 +1397,35 @@ function getSpellCost(stats, spell) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBaseSpellCost(stats, spell) {
|
function getBaseSpellCost(stats, spell) {
|
||||||
// old intelligence:
|
let cost = spell.cost * (1 - skillPointsToPercentage(stats.get('int')) * skillpoint_final_mult[2]);
|
||||||
let cost = Math.ceil(spell.cost * (1 - skillPointsToPercentage(stats.get('int')) * skillpoint_final_mult[2]));
|
|
||||||
cost += stats.get("spRaw"+spell.base_spell);
|
cost += stats.get("spRaw"+spell.base_spell);
|
||||||
return Math.floor(cost * (1 + stats.get("spPct"+spell.base_spell) / 100));
|
return cost * (1 + stats.get("spPct"+spell.base_spell) / 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function displaySpellDamage(parent_elem, overallparent_elem, stats, spell, spellIdx, spell_results) {
|
function displaySpellDamage(parent_elem, _overallparent_elem, stats, spell, spellIdx, spell_results) {
|
||||||
// TODO: remove spellIdx (just used to flag melee and cost)
|
// TODO: remove spellIdx (just used to flag melee and cost)
|
||||||
// TODO: move cost calc out
|
// TODO: move cost calc out
|
||||||
parent_elem.textContent = "";
|
parent_elem.textContent = "";
|
||||||
|
|
||||||
let title_elem = document.createElement("p");
|
let title_elem = make_elem("p");
|
||||||
|
|
||||||
overallparent_elem.textContent = "";
|
_overallparent_elem.textContent = "";
|
||||||
|
const overallparent_elem = make_elem("div", ['col'])
|
||||||
let title_elemavg = document.createElement("b");
|
let title_elemavg = document.createElement("b");
|
||||||
|
|
||||||
if ('cost' in spell) {
|
if ('cost' in spell) {
|
||||||
let first = document.createElement("span");
|
let first = make_elem("span", [], { textContent: spell.name + " (" });
|
||||||
first.textContent = spell.name + " (";
|
|
||||||
title_elem.appendChild(first.cloneNode(true)); //cloneNode is needed here.
|
title_elem.appendChild(first.cloneNode(true)); //cloneNode is needed here.
|
||||||
title_elemavg.appendChild(first);
|
title_elemavg.appendChild(first);
|
||||||
|
|
||||||
let second = document.createElement("span");
|
let second = make_elem("span", ["Mana"], { textContent: getSpellCost(stats, spell).toFixed(2) });
|
||||||
second.textContent = getSpellCost(stats, spell);
|
|
||||||
second.classList.add("Mana");
|
|
||||||
|
|
||||||
title_elem.appendChild(second.cloneNode(true));
|
title_elem.appendChild(second.cloneNode(true));
|
||||||
title_elemavg.appendChild(second);
|
title_elemavg.appendChild(second);
|
||||||
|
|
||||||
|
|
||||||
let third = document.createElement("span");
|
let third = make_elem("span", [], { textContent: ")" });// " + getBaseSpellCost(stats, spellIdx, spell.cost) + " ]";
|
||||||
third.textContent = ")";// [Base: " + getBaseSpellCost(stats, spellIdx, spell.cost) + " ]";
|
title_elem.appendChild(third.cloneNode(true));
|
||||||
title_elem.appendChild(third);
|
title_elemavg.appendChild(third);
|
||||||
let third_summary = document.createElement("span");
|
|
||||||
third_summary.textContent = ")";
|
|
||||||
title_elemavg.appendChild(third_summary);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
title_elem.textContent = spell.name;
|
title_elem.textContent = spell.name;
|
||||||
|
@ -1568,36 +1436,31 @@ function displaySpellDamage(parent_elem, overallparent_elem, stats, spell, spell
|
||||||
overallparent_elem.append(title_elemavg);
|
overallparent_elem.append(title_elemavg);
|
||||||
|
|
||||||
// if ('cost' in spell) {
|
// if ('cost' in spell) {
|
||||||
// :( ...... ?
|
// overallparent_elem.append(displayNextCosts(stats, spell, spellIdx));
|
||||||
// overallparent_elem.append(displayNextCosts(stats, spell, spellIdx));
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
let critChance = skillPointsToPercentage(stats.get('dex'));
|
let critChance = skillPointsToPercentage(stats.get('dex'));
|
||||||
|
|
||||||
let part_divavg = document.createElement("p");
|
let part_divavg = make_elem("p");
|
||||||
overallparent_elem.append(part_divavg);
|
overallparent_elem.append(part_divavg);
|
||||||
|
|
||||||
function _summary(text, val, fmt) {
|
function add_summary(text, val, fmt) {
|
||||||
let overallaverageLabel = document.createElement("p");
|
if (typeof(val) === 'number') { val = val.toFixed(2); }
|
||||||
let first = document.createElement("span");
|
let summary_elem = make_elem("p");
|
||||||
let second = document.createElement("span");
|
summary_elem.append(
|
||||||
first.textContent = text;
|
make_elem("span", [], { textContent: text }),
|
||||||
second.textContent = val.toFixed(2);
|
make_elem("span", [fmt], { textContent: val })
|
||||||
overallaverageLabel.appendChild(first);
|
);
|
||||||
overallaverageLabel.appendChild(second);
|
part_divavg.append(summary_elem);
|
||||||
second.classList.add(fmt);
|
|
||||||
part_divavg.append(overallaverageLabel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < spell_results.length; ++i) {
|
for (let i = 0; i < spell_results.length; ++i) {
|
||||||
const spell_info = spell_results[i];
|
const spell_info = spell_results[i];
|
||||||
|
|
||||||
let part_div = document.createElement("p");
|
let part_div = make_elem("p", ["pt-3"]);
|
||||||
parent_elem.append(part_div);
|
parent_elem.append(part_div);
|
||||||
|
|
||||||
let subtitle_elem = document.createElement("p");
|
part_div.append(make_elem("p", [], { textContent: spell_info.name }));
|
||||||
subtitle_elem.textContent = spell_info.name
|
|
||||||
part_div.append(subtitle_elem);
|
|
||||||
|
|
||||||
if (spell_info.type === "damage") {
|
if (spell_info.type === "damage") {
|
||||||
let totalDamNormal = spell_info.normal_total;
|
let totalDamNormal = spell_info.normal_total;
|
||||||
|
@ -1607,14 +1470,26 @@ function displaySpellDamage(parent_elem, overallparent_elem, stats, spell, spell
|
||||||
let critAverage = (totalDamCrit[0]+totalDamCrit[1])/2 || 0;
|
let critAverage = (totalDamCrit[0]+totalDamCrit[1])/2 || 0;
|
||||||
let averageDamage = (1-critChance)*nonCritAverage+critChance*critAverage || 0;
|
let averageDamage = (1-critChance)*nonCritAverage+critChance*critAverage || 0;
|
||||||
|
|
||||||
let averageLabel = document.createElement("p");
|
let averageLabel = make_elem("p", [], { textContent: "Average: "+averageDamage.toFixed(2) });
|
||||||
averageLabel.textContent = "Average: "+averageDamage.toFixed(2);
|
|
||||||
// averageLabel.classList.add("damageSubtitle");
|
// averageLabel.classList.add("damageSubtitle");
|
||||||
part_div.append(averageLabel);
|
part_div.append(averageLabel);
|
||||||
|
|
||||||
|
|
||||||
if (spell_info.name === spell.display) {
|
if (spell_info.name === spell.display) {
|
||||||
_summary(spell_info.name+ ": ", averageDamage, "Damage");
|
if (spellIdx === 0) {
|
||||||
|
let display_attack_speeds = ["Super Slow", "Very Slow", "Slow", "Normal", "Fast", "Very Fast", "Super Fast"];
|
||||||
|
let adjAtkSpd = attackSpeeds.indexOf(stats.get("atkSpd")) + stats.get("atkTier");
|
||||||
|
if(adjAtkSpd > 6) {
|
||||||
|
adjAtkSpd = 6;
|
||||||
|
} else if(adjAtkSpd < 0) {
|
||||||
|
adjAtkSpd = 0;
|
||||||
|
}
|
||||||
|
add_summary("Average DPS: ", averageDamage * baseDamageMultiplier[adjAtkSpd], "Damage");
|
||||||
|
add_summary("Attack Speed: ", display_attack_speeds[adjAtkSpd], "Damage");
|
||||||
|
add_summary("Per Attack: ", averageDamage, "Damage");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
add_summary(spell_info.name+ ": ", averageDamage, "Damage");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _damage_display(label_text, average, dmg_min, dmg_max) {
|
function _damage_display(label_text, average, dmg_min, dmg_max) {
|
||||||
|
@ -1640,12 +1515,13 @@ function displaySpellDamage(parent_elem, overallparent_elem, stats, spell, spell
|
||||||
// healLabel.classList.add("damagep");
|
// healLabel.classList.add("damagep");
|
||||||
part_div.append(healLabel);
|
part_div.append(healLabel);
|
||||||
if (spell_info.name === spell.display) {
|
if (spell_info.name === spell.display) {
|
||||||
_summary(spell_info.name+ ": ", heal_amount, "Set");
|
add_summary(spell_info.name+ ": ", heal_amount, "Set");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addClickableArrow(overallparent_elem, parent_elem);
|
addClickableArrow(overallparent_elem, parent_elem);
|
||||||
|
_overallparent_elem.append(overallparent_elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Displays the ID costs of an item
|
/** Displays the ID costs of an item
|
||||||
|
@ -2061,12 +1937,10 @@ function stringCDF(id,val,base,amp) {
|
||||||
|
|
||||||
function addClickableArrow(elem, target) {
|
function addClickableArrow(elem, target) {
|
||||||
//up and down arrow - done ugly
|
//up and down arrow - done ugly
|
||||||
let arrow = document.createElement("img");
|
let arrow = make_elem("img", [], { id: "arrow_" + elem.id, src: "../media/icons/" + (newIcons ? "new" : "old") + "/toggle_down.png" });
|
||||||
arrow.id = "arrow_" + elem.id;
|
|
||||||
arrow.style.maxWidth = document.body.clientWidth > 900 ? "3rem" : "10rem";
|
arrow.style.maxWidth = document.body.clientWidth > 900 ? "3rem" : "10rem";
|
||||||
arrow.src = "../media/icons/" + (newIcons ? "new" : "old") + "/toggle_down.png";
|
|
||||||
elem.appendChild(arrow);
|
elem.appendChild(arrow);
|
||||||
arrow.addEventListener("click", () => toggle_spell_tab(arrow, target));
|
elem.addEventListener("click", () => toggle_spell_tab(arrow, target));
|
||||||
}
|
}
|
||||||
|
|
||||||
// toggle arrow thinger
|
// toggle arrow thinger
|
||||||
|
|
39
js/icons.js
|
@ -1,33 +1,26 @@
|
||||||
//which icons to use
|
|
||||||
let window_storage = window.localStorage;
|
let window_storage = window.localStorage;
|
||||||
icon_state_stored = window_storage.getItem("newicons");
|
|
||||||
newIcons = true;
|
newIcons = true;
|
||||||
if (icon_state_stored === "false") {toggleIcons()}
|
if (window_storage.getItem("newicons") === "false") {
|
||||||
|
toggleIcons();
|
||||||
|
}
|
||||||
|
|
||||||
/** Toggle icons on the ENTIRE page.
|
/** Toggle icons on the ENTIRE page.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function toggleIcons() {
|
function toggleIcons() {
|
||||||
newIcons = !newIcons;
|
newIcons = !newIcons;
|
||||||
let imgs = document.getElementsByTagName("IMG");
|
window_storage.setItem("newicons", newIcons.toString());
|
||||||
let favicon = document.querySelector("link[rel~='icon']");
|
let newOrOld = (newIcons ? "new" : "old");
|
||||||
let toggleiconbutton = document.getElementById("toggle-icon-button");
|
|
||||||
|
|
||||||
if (newIcons) { //switch to new
|
let imgs = document.getElementsByTagName("img");
|
||||||
favicon.href = favicon.href.replace("media/icons/old","media/icons/new");
|
let divs = document.getElementsByClassName("item-display-new-toggleable");
|
||||||
for (const img of imgs) {
|
let favicon = document.querySelector("link[rel~='icon']");
|
||||||
if (img.src.includes("media/icons/old")) {img.src = img.src.replace("media/icons/old","media/icons/new");}
|
favicon.href = favicon.href.replace("media/icons/" + (newIcons ? "old" : "new"), "media/icons/" + newOrOld);
|
||||||
if (img.src.includes("media/items/old")) {img.src = img.src.replace("media/items/old","media/items/new");}
|
for (const img of imgs) {
|
||||||
}
|
// if doesn't contain, replace() does nothing
|
||||||
toggleiconbutton.textContent = "Use Old Icons";
|
img.src = img.src.replace("media/icons/" + (newIcons ? "old" : "new"), "media/icons/" + newOrOld);
|
||||||
window_storage.setItem("newicons","true");
|
}
|
||||||
} else { //switch to old
|
for (let i = 0; i < divs.length; i++) {
|
||||||
favicon.href = favicon.href.replace("media/icons/new","media/icons/old");
|
divs.item(i).style.backgroundImage = "url('../media/items/" + (newIcons ? "new" : "old") + ".png')";
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -20,8 +20,8 @@ function init_itempage() {
|
||||||
//displayExpandedItem(expandItem(itemMap.get(item_url_tag).statMap, []), "item-view");
|
//displayExpandedItem(expandItem(itemMap.get(item_url_tag).statMap, []), "item-view");
|
||||||
try{
|
try{
|
||||||
item = expandItem(itemMap.get(item_url_tag.replaceAll("%20"," ")), []);
|
item = expandItem(itemMap.get(item_url_tag.replaceAll("%20"," ")), []);
|
||||||
|
item.set('powders', []);
|
||||||
if (item.get('category') === 'weapon') {
|
if (item.get('category') === 'weapon') {
|
||||||
item.set('powders', []);
|
|
||||||
apply_weapon_powders(item);
|
apply_weapon_powders(item);
|
||||||
}
|
}
|
||||||
displayExpandedItem(item, "item-view");
|
displayExpandedItem(item, "item-view");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const DB_VERSION = 97;
|
const DB_VERSION = 101;
|
||||||
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA
|
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA
|
||||||
|
|
||||||
let db;
|
let db;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const ING_DB_VERSION = 13;
|
const ING_DB_VERSION = 14;
|
||||||
|
|
||||||
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js
|
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js
|
||||||
|
|
||||||
|
|
|
@ -223,21 +223,15 @@ function construct_scc_graph(items_to_consider) {
|
||||||
let terminal_node = {
|
let terminal_node = {
|
||||||
item: null,
|
item: null,
|
||||||
children: [],
|
children: [],
|
||||||
parents: nodes,
|
parents: nodes
|
||||||
visited: false,
|
|
||||||
assigned: false,
|
|
||||||
scc: null
|
|
||||||
};
|
};
|
||||||
let root_node = {
|
let root_node = {
|
||||||
item: null,
|
item: null,
|
||||||
children: nodes,
|
children: nodes,
|
||||||
parents: [],
|
parents: [],
|
||||||
visited: false,
|
|
||||||
assigned: false,
|
|
||||||
scc: null
|
|
||||||
};
|
};
|
||||||
for (const item of items_to_consider) {
|
for (const item of items_to_consider) {
|
||||||
nodes.push({item: item, children: [terminal_node], parents: [root_node], visited: false, assigned: false, scc: null});
|
nodes.push({item: item, children: [terminal_node], parents: [root_node]});
|
||||||
}
|
}
|
||||||
// Dependency graph construction.
|
// Dependency graph construction.
|
||||||
for (const node_a of nodes) {
|
for (const node_a of nodes) {
|
||||||
|
@ -253,50 +247,6 @@ function construct_scc_graph(items_to_consider) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const res = []
|
const sccs = make_SCC_graph(root_node, nodes);
|
||||||
/*
|
|
||||||
* SCC graph construction.
|
|
||||||
* https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
|
|
||||||
*/
|
|
||||||
function visit(u, res) {
|
|
||||||
if (u.visited) { return; }
|
|
||||||
u.visited = true;
|
|
||||||
for (const child of u.children) {
|
|
||||||
if (!child.visited) { visit(child, res); }
|
|
||||||
}
|
|
||||||
res.push(u);
|
|
||||||
}
|
|
||||||
visit(root_node, res);
|
|
||||||
res.reverse();
|
|
||||||
const sccs = [];
|
|
||||||
function assign(node, cur_scc) {
|
|
||||||
if (node.assigned) { return; }
|
|
||||||
cur_scc.nodes.push(node);
|
|
||||||
node.scc = cur_scc;
|
|
||||||
node.assigned = true;
|
|
||||||
for (const parent of node.parents) {
|
|
||||||
assign(parent, cur_scc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const node of res) {
|
|
||||||
if (node.assigned) { continue; }
|
|
||||||
const cur_scc = {
|
|
||||||
nodes: [],
|
|
||||||
children: new Set(),
|
|
||||||
parents: new Set()
|
|
||||||
};
|
|
||||||
assign(node, cur_scc);
|
|
||||||
sccs.push(cur_scc);
|
|
||||||
}
|
|
||||||
for (const scc of sccs) {
|
|
||||||
for (const node of scc.nodes) {
|
|
||||||
for (const child of node.children) {
|
|
||||||
scc.children.add(child.scc);
|
|
||||||
}
|
|
||||||
for (const parent of node.parents) {
|
|
||||||
scc.parents.add(parent.scc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [root_node, terminal_node, sccs];
|
return [root_node, terminal_node, sccs];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
67
js/utils.js
|
@ -788,12 +788,11 @@ function deepcopy(obj, refs=undefined) {
|
||||||
*/
|
*/
|
||||||
function gen_slider_labeled({label_name, label_classlist = [], min = 0, max = 100, step = 1, default_val = min, id = undefined, color = "#FFFFFF", classlist = []}) {
|
function gen_slider_labeled({label_name, label_classlist = [], min = 0, max = 100, step = 1, default_val = min, id = undefined, color = "#FFFFFF", classlist = []}) {
|
||||||
let slider_container = document.createElement("div");
|
let slider_container = document.createElement("div");
|
||||||
|
slider_container.classList.add("col");
|
||||||
|
|
||||||
let buf_col = document.createElement("div");
|
let buf_col = document.createElement("div");
|
||||||
buf_col.classList.add("col");
|
|
||||||
|
|
||||||
let label = document.createElement("div");
|
let label = document.createElement("div");
|
||||||
label.classList.add("col");
|
|
||||||
label.classList.add(...label_classlist);
|
label.classList.add(...label_classlist);
|
||||||
label.textContent = label_name + ": " + default_val;
|
label.textContent = label_name + ": " + default_val;
|
||||||
|
|
||||||
|
@ -889,3 +888,67 @@ function make_elem(type, classlist = [], args = {}) {
|
||||||
}
|
}
|
||||||
return ret_elem;
|
return ret_elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nodes must have:
|
||||||
|
* node: {
|
||||||
|
* parents: List[node]
|
||||||
|
* children: List[node]
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* This function will define: "visited, assigned, scc" properties
|
||||||
|
* Assuming a connected graph. (only one root)
|
||||||
|
*/
|
||||||
|
function make_SCC_graph(root_node, nodes) {
|
||||||
|
for (const node of nodes) {
|
||||||
|
node.visited = false;
|
||||||
|
node.assigned = false;
|
||||||
|
node.scc = null;
|
||||||
|
}
|
||||||
|
const res = []
|
||||||
|
/*
|
||||||
|
* SCC graph construction.
|
||||||
|
* https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
|
||||||
|
*/
|
||||||
|
function visit(u, res) {
|
||||||
|
if (u.visited) { return; }
|
||||||
|
u.visited = true;
|
||||||
|
for (const child of u.children) {
|
||||||
|
if (!child.visited) { visit(child, res); }
|
||||||
|
}
|
||||||
|
res.push(u);
|
||||||
|
}
|
||||||
|
visit(root_node, res);
|
||||||
|
res.reverse();
|
||||||
|
const sccs = [];
|
||||||
|
function assign(node, cur_scc) {
|
||||||
|
if (node.assigned) { return; }
|
||||||
|
cur_scc.nodes.push(node);
|
||||||
|
node.scc = cur_scc;
|
||||||
|
node.assigned = true;
|
||||||
|
for (const parent of node.parents) {
|
||||||
|
assign(parent, cur_scc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const node of res) {
|
||||||
|
if (node.assigned) { continue; }
|
||||||
|
const cur_scc = {
|
||||||
|
nodes: [],
|
||||||
|
children: new Set(),
|
||||||
|
parents: new Set()
|
||||||
|
};
|
||||||
|
assign(node, cur_scc);
|
||||||
|
sccs.push(cur_scc);
|
||||||
|
}
|
||||||
|
for (const scc of sccs) {
|
||||||
|
for (const node of scc.nodes) {
|
||||||
|
for (const child of node.children) {
|
||||||
|
scc.children.add(child.scc);
|
||||||
|
}
|
||||||
|
for (const parent of node.parents) {
|
||||||
|
scc.parents.add(parent.scc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sccs;
|
||||||
|
}
|
||||||
|
|
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.9 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 |