index : btroops | |
Virtual board game-aid for BattleTroops, an infantry combat simulator wargame published by FASA in 1989. |
aboutsummaryrefslogtreecommitdiff |
diff options
author | Catalin Mititiuc <webdevcat@proton.me> | 2024-08-07 16:12:53 -0700 |
---|---|---|
committer | Catalin Mititiuc <webdevcat@proton.me> | 2024-08-07 16:12:53 -0700 |
commit | 16dc347cd7ce364e408b431af3a63c9fddc48a31 (patch) | |
tree | 3dbfba7a85c77be32e8fac7c554a5d6cbc4b2b4a | |
parent | 39c939ebaf2683b4167ab65eb9cfdc202f90a35e (diff) |
Improve armor assign
-rw-r--r-- | src/modules/record_sheet.js | 94 |
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) { |