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-04-27 18:28:59 -0700 |
---|---|---|
committer | Catalin Mititiuc <webdevcat@proton.me> | 2024-04-27 18:30:03 -0700 |
commit | 0c1f7e2fde7ed6e05271c8aeb8d4babbf4f2188d (patch) | |
tree | b15c46880f7aa4e252df7928dbc5a2a2f5eef366 /src | |
parent | ce98e325656b8419b80d8c248e0469f3a9708322 (diff) |
Add ability to change maps
Diffstat (limited to 'src')
-rw-r--r-- | src/index.js | 169 | ||||
-rw-r--r-- | src/modules/gameboard.js | 16 | ||||
-rw-r--r-- | src/modules/record_sheet.js | 4 |
3 files changed, 107 insertions, 82 deletions
diff --git a/src/index.js b/src/index.js index 40ee397..a8b766a 100644 --- a/src/index.js +++ b/src/index.js @@ -6,13 +6,89 @@ globalThis.svgns = "http://www.w3.org/2000/svg"; const mapPlaceholder = document.querySelector('.map-placeholder'), distanceOutput = document.getElementById('status'), - proneToggle = document.getElementById('toggle-prone-counter'); + proneToggle = document.getElementById('toggle-prone-counter'), + object = document.querySelector('object'); -document.querySelector('object').addEventListener('load', function () { +object.addEventListener('load', function () { mapPlaceholder.remove(); this.style.opacity = 1; + + const svg = this.contentDocument.querySelector('svg'); + panzoom.start(svg); + gameboard.start(svg); +}); + +gameboard.setDistanceCallback((count = '-') => { + distanceOutput.querySelector('#hex-count').textContent = count; + distanceOutput.style.display = count === '-' ? 'none' : 'block'; +}); + +gameboard.setProneFlagCallback(checked => proneToggle.checked = checked); +gameboard.setSelectCallback(data => recordSheet.select(data)); + +document.querySelectorAll('.soldier-record').forEach(el => + el.addEventListener('click', () => { + if (el.classList.contains('selected')) { + el.classList.remove('selected'); + gameboard.unSelect(); + recordSheet.unSelect(); + } else { + gameboard.select(el); + } + }) +); + +document.querySelectorAll('.end-move').forEach(el => el.addEventListener('click', () => { + recordSheet.endMove(); + gameboard.endMove(); +})); + +document.querySelectorAll('.end-turn').forEach(el => + el.addEventListener('click', ({ target: { dataset: { allegiance }}}) => { + const dataSelector = `[data-allegiance="${allegiance}"]`, + records = Array.from(document.querySelectorAll(`.soldier-record${dataSelector}`)), + turnCounter = document.getElementById('turn-count'), + { dataset: { update }} = turnCounter; + + el.setAttribute('disabled', ''); + + document + .querySelector(`button.end-turn:not([data-allegiance="${allegiance}"])`) + .removeAttribute('disabled'); + + if (update === '1') { + turnCounter.children.namedItem('count').textContent++ + turnCounter.dataset.update = '0'; + } else { + turnCounter.dataset.update = '1'; + } + + records + .sort((el1, el2) => el1.dataset.number > el2.dataset.number) + .forEach(el => el.classList.remove('movement-ended')); + + gameboard.endTurn(allegiance); + gameboard.select(records.at(0)); + }) +); + +document.querySelectorAll('.set-firing-arc').forEach(el => + el.addEventListener('click', gameboard.setFiringArc) +); + +document.querySelector('.set-grenade').addEventListener('click', gameboard.setGrenade); + +document.querySelectorAll('#toggle-firing-arc-vis input').forEach(el => + el.addEventListener('input', gameboard.toggleFiringArcVisibility) +); + +document.getElementById('toggle-prone-counter').addEventListener('input', function () { + const selected = recordSheet.getSelected(); + selected && gameboard.toggleProne(); }); +object.data = `${localStorage.getItem('map') || 'map1'}.svg`; + document .querySelector('#content input[type="checkbox"].visible') .addEventListener('input', function () { @@ -27,78 +103,27 @@ document }); }); -window.addEventListener('load', () => { - const svg = document.querySelector('object').contentDocument.querySelector('svg'); - - gameboard.start(svg); - panzoom.start(svg); - - gameboard.setDistanceCallback((count = '-') => { - distanceOutput.querySelector('#hex-count').textContent = count; - distanceOutput.style.display = count === '-' ? 'none' : 'block'; - }); - - gameboard.setProneFlagCallback(checked => proneToggle.checked = checked); - gameboard.setSelectCallback(data => recordSheet.select(data)); - - document.querySelectorAll('.soldier-record').forEach(el => - el.addEventListener('click', () => { - if (el.classList.contains('selected')) { - el.classList.remove('selected'); - gameboard.unSelect(); - recordSheet.unSelect(); - } else { - gameboard.select(el); - } - }) - ); - - document.querySelectorAll('.end-move').forEach(el => el.addEventListener('click', () => { - recordSheet.endMove(); - gameboard.endMove(); - })); - - document.querySelectorAll('.end-turn').forEach(el => - el.addEventListener('click', ({ target: { dataset: { allegiance }}}) => { - const dataSelector = `[data-allegiance="${allegiance}"]`, - records = Array.from(document.querySelectorAll(`.soldier-record${dataSelector}`)), - turnCounter = document.getElementById('turn-count'), - { dataset: { update }} = turnCounter; - - el.setAttribute('disabled', ''); - - document - .querySelector(`button.end-turn:not([data-allegiance="${allegiance}"])`) - .removeAttribute('disabled'); - - if (update === '1') { - turnCounter.children.namedItem('count').textContent++ - turnCounter.dataset.update = '0'; - } else { - turnCounter.dataset.update = '1'; - } - - records - .sort((el1, el2) => el1.dataset.number > el2.dataset.number) - .forEach(el => el.classList.remove('movement-ended')); - - gameboard.endTurn(allegiance); - gameboard.select(records.at(0)); - }) - ); +const showButton = document.getElementById('show-dialog'), + mapDialog = document.getElementById('map-dialog'), + selectEl = mapDialog.querySelector('select'), + confirmBtn = mapDialog.querySelector('#confirm-btn'); - document.querySelectorAll('.set-firing-arc').forEach(el => - el.addEventListener('click', gameboard.setFiringArc) - ); +mapDialog.querySelectorAll('option').forEach(option => + option.value === localStorage.getItem('map') && (option.selected = true) +); - document.querySelector('.set-grenade').addEventListener('click', gameboard.setGrenade); +showButton.addEventListener('click', () => { + mapDialog.showModal(); +}); - document.querySelectorAll('#toggle-firing-arc-vis input').forEach(el => - el.addEventListener('input', gameboard.toggleFiringArcVisibility) - ); +selectEl.addEventListener('change', () => { + confirmBtn.value = selectEl.value; +}); - document.getElementById('toggle-prone-counter').addEventListener('input', function () { - const selected = recordSheet.getSelected(); - selected && gameboard.toggleProne(); - }); +confirmBtn.addEventListener('click', e => { + e.preventDefault(); + localStorage.removeItem('pan-zoom'); + localStorage.setItem('map', selectEl.value); + document.querySelector('object').data = `${selectEl.value}.svg`; + mapDialog.close(); }); diff --git a/src/modules/gameboard.js b/src/modules/gameboard.js index 9f8723e..25db4ad 100644 --- a/src/modules/gameboard.js +++ b/src/modules/gameboard.js @@ -19,14 +19,14 @@ function getCellOccupant(cell) { } function getCells(svg) { - return svg.querySelectorAll('g[data-y] > g[data-x]'); + return svg.querySelectorAll('g.grid > g[data-y] > g[data-x]'); } function getLockedSightLine(svg) { return svg.querySelector('line.sight-line:not(.active)'); } -function getSightLine(svg) { +export function getSightLine(svg) { return svg.querySelector('line.sight-line'); } @@ -63,7 +63,7 @@ function getCellPosition(cell) { } function getCell(x, y) { - return svg.querySelector(`g[data-y="${y}"] > g[data-x="${x}"]`); + return svg.querySelector(`g.grid > g[data-y="${y}"] > g[data-x="${x}"]`); } function getCounterAtGridIndex(x, y) { @@ -85,7 +85,7 @@ function updateSightLine(cell) { { dataset: { x: tX }, parentElement: { dataset: { y: tY }}} = sightLine.getLockTarget(); const selector = sightLine.calcIndexes(+sX, +sY, +tX, +tY) - .map(([x, y]) => `g[data-y="${y}"] g[data-x="${x}"] use[href="#hex"]`) + .map(([x, y]) => `g.grid g[data-y="${y}"] g[data-x="${x}"] use[href="#hex"]`) .join(', '); const hexes = svg.querySelectorAll(selector); @@ -99,7 +99,7 @@ function drawSightLine(sourceCell, targetCell) { { dataset: { x: tX }, parentElement: { dataset: { y: tY }}} = targetCell; const selector = sightLine.calcIndexes(+sX, +sY, +tX, +tY) - .map(([x, y]) => `g[data-y="${y}"] g[data-x="${x}"] use[href="#hex"]`) + .map(([x, y]) => `g.grid g[data-y="${y}"] g[data-x="${x}"] use[href="#hex"]`) .join(', '); const hexes = svg.querySelectorAll(selector); @@ -277,9 +277,9 @@ export function start(el) { }); // debug - const c = soldier.getCounter(svg, { dataset: { allegiance: 'davion', number: '1' }}); - soldier.place(svg, c, getCell(17, 25)); - select(c); + // const c = soldier.getCounter(svg, { dataset: { allegiance: 'davion', number: '1' }}); + // soldier.place(svg, c, getCell(17, 25)); + // select(c); } export function select(selected) { diff --git a/src/modules/record_sheet.js b/src/modules/record_sheet.js index 99af18f..e5e8de6 100644 --- a/src/modules/record_sheet.js +++ b/src/modules/record_sheet.js @@ -14,9 +14,9 @@ export function getSelected() { export function select(data) { const selector = - `#record-sheet .soldier-record[data-number="${data.number}"][data-allegiance="${data.allegiance}"]` + `#record-sheet .soldier-record[data-number="${data.number}"][data-allegiance="${data.allegiance}"]` - unSelect(); + unSelect(); document.querySelector(selector).classList.add('selected'); document.getElementById('toggle-prone-counter').checked = data.prone; } |