Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Mititiuc <webdevcat@proton.me>2024-08-07 16:12:53 -0700
committerCatalin Mititiuc <webdevcat@proton.me>2024-08-07 16:12:53 -0700
commit16dc347cd7ce364e408b431af3a63c9fddc48a31 (patch)
tree3dbfba7a85c77be32e8fac7c554a5d6cbc4b2b4a
parent39c939ebaf2683b4167ab65eb9cfdc202f90a35e (diff)
Improve armor assign
-rw-r--r--src/modules/record_sheet.js94
1 files changed, 65 insertions, 29 deletions
diff --git a/src/modules/record_sheet.js b/src/modules/record_sheet.js
index 8caf395..b55058d 100644
--- a/src/modules/record_sheet.js
+++ b/src/modules/record_sheet.js
@@ -128,44 +128,80 @@ function deactivationHandler(e) {
}
}
+function closestSibling(el, selector) {
+ let nextMatch, prevMatch;
+ const next = { steps: 0, direction: 'next' };
+ const prev = { steps: 0, direction: 'previous' };
+
+ next.el = prev.el = el;
+
+ while (next.el || prev.el) {
+ next.el = next.el?.nextElementSibling;
+ prev.el = prev.el?.previousElementSibling;
+
+ if (next.el) next.steps += 1
+ if (prev.el) prev.steps += 1
+
+ nextMatch = next.el?.matches(selector);
+ prevMatch = prev.el?.matches(selector);
+
+ if (nextMatch || prevMatch) {
+ const results = [];
+ if (prevMatch) results.push(prev);
+ if (nextMatch) results.push(next);
+ return results;
+ }
+ }
+
+ return [];
+}
+
function configArmor(unit, record) {
+ const track = record.shadowRoot.querySelector('.physical-status-track');
const s = `damage-block:nth-of-type(n + 1):nth-of-type(-n + ${unit.dataset.armor})`;
const armorBlocks = record.shadowRoot.querySelectorAll(s);
armorBlocks.forEach(el => el.classList.add('armor'));
- const ls = 'damage-block:nth-child(1 of .armor):not(:first-child)';
- const rs = 'damage-block:nth-last-child(1 of .armor):not(:last-child)';
- const moveArmorEl = record.shadowRoot.querySelectorAll(`${ls}, ${rs}`);
-
- function moveArmorHandler(e) {
- e.stopPropagation();
-
- this.removeEventListener('click', moveArmorHandler);
- if (!this.previousElementSibling.classList.contains('armor')) {
- this.previousElementSibling.classList.add('armor');
- this.previousElementSibling.addEventListener('click', moveArmorHandler);
- let current = this.nextElementSibling;
- while (current.nextElementSibling && current.nextElementSibling.classList.contains('armor')) {
- current = current.nextElementSibling;
- }
- current.classList.remove('armor');
- current.removeEventListener('click', moveArmorHandler);
- current.previousElementSibling.addEventListener('click', moveArmorHandler);
- } else if (!this.nextElementSibling.classList.contains('armor')) {
- this.nextElementSibling.classList.add('armor');
- this.nextElementSibling.addEventListener('click', moveArmorHandler);
- let current = this.previousElementSibling;
- while (current.previousElementSibling && current.previousElementSibling.classList.contains('armor')) {
- current = current.previousElementSibling;
+ track.addEventListener('pointerover', e => {
+ const unprotected = [...track.querySelectorAll('damage-block:not(.armor):nth-of-type(n + 1):nth-of-type(-n + 10)')];
+
+ if (e.target.getAttributeNS(null, 'slot') === 'block-number' && unprotected.includes(e.target.parentElement)) {
+ e.target.parentElement.classList.add('unprotected');
+ const [{ direction }] = closestSibling(e.target.parentElement, '.armor');
+ const damageBlocks = track.querySelectorAll('damage-block:nth-of-type(n + 1):nth-of-type(-n + 10)');
+ const currentIndex = [...damageBlocks].findIndex(el => el === e.target.parentElement);
+
+ const range = {
+ previous: {
+ from: currentIndex + 2 - +unit.dataset.armor,
+ to: currentIndex + 1
+ },
+ next: {
+ from: currentIndex + 1,
+ to: currentIndex + +unit.dataset.armor
+ }
}
- current.classList.remove('armor');
- current.removeEventListener('click', moveArmorHandler);
- current.nextElementSibling.addEventListener('click', moveArmorHandler);
+
+ const sel = `damage-block:nth-of-type(n + ${range[direction].from}):nth-of-type(-n + ${range[direction].to})`;
+ track.querySelectorAll(sel).forEach(el => el.classList.add('unprotected'));
}
- }
+ });
- moveArmorEl.forEach(el => el.addEventListener('click', moveArmorHandler));
+ track.addEventListener('pointerout', e => {
+ track.querySelectorAll('.unprotected').forEach(el => el.classList.remove('unprotected'));
+ });
+
+ track.addEventListener('click', e => {
+ e.stopPropagation();
+ if (e.target.getAttributeNS(null, 'slot') === 'block-number' && e.target.parentElement.classList.contains('unprotected')) {
+ track.querySelectorAll('damage-block.armor').forEach(el => el.classList.remove('armor'));
+ track.querySelectorAll('damage-block.unprotected').forEach(el => {
+ el.classList.remove('unprotected');
+ el.classList.add('armor');
+ });
+ }
+ });
}
function createRecord(unit) {