index : btroops | |
Virtual board game-aid for BattleTroops, an infantry combat simulator wargame published by FASA in 1989. |
aboutsummaryrefslogtreecommitdiff |
diff options
-rw-r--r-- | public/index.html | 4 | ||||
-rw-r--r-- | public/map.css | 2 | ||||
-rw-r--r-- | src/index.js | 62 | ||||
-rw-r--r-- | src/modules/game.js | 89 |
4 files changed, 115 insertions, 42 deletions
diff --git a/public/index.html b/public/index.html index a7e84e0..dbb14a9 100644 --- a/public/index.html +++ b/public/index.html @@ -91,9 +91,9 @@ <div id="map-container"> <div id="toggle-firing-arc-vis"> - <div>davion</div> + <div>Davion</div> <input type="checkbox" data-allegiance="davion" /> - <div>liao</div> + <div>Liao</div> <input type="checkbox" data-allegiance="liao" /> </div> diff --git a/public/map.css b/public/map.css index 93232ba..780b912 100644 --- a/public/map.css +++ b/public/map.css @@ -82,7 +82,7 @@ g.troop-counter-template text { stroke: none; } -g.troop-counter [href="#counter-prone"] { +[href="#counter-prone"] { transform: translate(-5px, 6px); } diff --git a/src/index.js b/src/index.js index fd679d2..84001d4 100644 --- a/src/index.js +++ b/src/index.js @@ -55,21 +55,19 @@ const RecordSheet = new function () { if (selected) { selected.classList.remove('selected'); - document.getElementById('toggle-prone-counter').checked = false; } + + document.getElementById('toggle-prone-counter').checked = false; }; this.getSelected = function () { return document.querySelector('.soldier-record.selected'); }; - this.select = function (el) { - let { troopNumber, troopAllegiance } = el.dataset; - // proneStatus = svg.Counter.hasProne(troopNumber, troopAllegiance); - + this.select = function (data) { this.unSelect(); - document.querySelector(`#record-sheet .soldier-record[data-troop-number="${troopNumber}"][data-troop-allegiance="${troopAllegiance}"]`).classList.add('selected'); - // document.getElementById('toggle-prone-counter').checked = proneStatus; + document.querySelector(`#record-sheet .soldier-record[data-troop-number="${data.number}"][data-troop-allegiance="${data.allegiance}"]`).classList.add('selected'); + document.getElementById('toggle-prone-counter').checked = data.prone; }; this.endMove = function() { @@ -92,7 +90,27 @@ window.addEventListener('load', () => { PanZoom.start(svg); - game.info = document.getElementById('status'); + const distanceOutput = document.getElementById('status'); + + game.distanceCallback = count => { + const output = { + count: '-', + display: 'none' + } + + if (count) { + output.count = count; + output.display = 'block'; + } + + distanceOutput.querySelector('#hex-count').textContent = output.count; + distanceOutput.style.display = output.display; + }; + + const proneToggle = document.getElementById('toggle-prone-counter'); + + game.proneFlagCallback = checked => proneToggle.checked = checked; + game.selectCallback = data => RecordSheet.select(data); // Object.values(settingsPanel.querySelectorAll('fieldset')).forEach(fieldset => { // const identityMtx = [1, 0, 0, 1, 0, 0]; @@ -142,18 +160,18 @@ window.addEventListener('load', () => { el.addEventListener('click', e => { if (el.classList.contains('selected')) { el.classList.remove('selected'); + game.unSelect(); RecordSheet.unSelect(); - // Counter.unSelect(); } else { - RecordSheet.select(el); - // Counter.select(el); + game.select(el.dataset.troopAllegiance, el.dataset.troopNumber); } - - // SightLine.clear(); }) ); - document.querySelectorAll('.end-move').forEach(el => el.addEventListener('click', e => game.endMove())); + document.querySelectorAll('.end-move').forEach(el => el.addEventListener('click', e => { + RecordSheet.endMove(); + game.endMove(); + })); document.querySelectorAll('.end-turn').forEach(el => el.addEventListener('click', ({ target: { dataset: { allegiance }}}) => { @@ -175,14 +193,12 @@ window.addEventListener('load', () => { turnCounter.dataset.update = '1'; } - // qA(`#firing-arcs ${dataSelector}`).forEach(el => el.remove()); - records .sort((el1, el2) => el1.dataset.troopNumber > el2.dataset.troopNumber) .forEach(el => el.classList.remove('movement-ended')); - // RecordSheet.select(records.at(0)); - // Counter.select(records.at(0)); + game.endTurn(allegiance); + game.select(records.at(0).dataset.troopAllegiance, records.at(0).dataset.troopNumber); }) ); @@ -210,15 +226,7 @@ window.addEventListener('load', () => { let selected = RecordSheet.getSelected(); if (selected) { - let template = q(`g#${selected.dataset.troopAllegiance}-${selected.dataset.troopNumber}`); - - if (this.checked) { - let counter = document.createElementNS(svgns, 'use'); - counter.setAttributeNS(null, 'href', '#counter-prone'); - template.appendChild(counter); - } else { - template.querySelector('[href="#counter-prone"]').remove(); - } + game.toggleProne(); } }); }); diff --git a/src/modules/game.js b/src/modules/game.js index 0435c28..c94685e 100644 --- a/src/modules/game.js +++ b/src/modules/game.js @@ -345,6 +345,23 @@ export default class Game { } } + select(allegiance, number) { + this.Counter.select({ dataset: { allegiance, number } }); + } + + unSelect() { + this.Counter.unSelect(); + } + + endTurn(allegiance) { + const selector = `#firing-arcs [data-troop-allegiance="${allegiance}"]`; + this.svg.querySelectorAll(selector).forEach(el => el.remove()); + } + + toggleProne() { + this.Counter.toggleProne(); + } + toggleFiringArcVisibility(allegiance) { const vis = this.#firingArcVisibility[allegiance], clipPaths = this.svg.querySelectorAll(`clipPath[data-troop-allegiance="${allegiance}"]`); @@ -483,15 +500,23 @@ export default class Game { container.SightLine.update(this); } + container.proneFlagCallback(!!this.parentElement.querySelector('[href="#counter-prone"]')); + this.parentElement.appendChild(counter); + this.remove(); container.Counter.removeClones(counter); trace.remove(); } else { + const proneCounter = this.parentElement.querySelector('[href="#counter-prone"]'); + + if (proneCounter) { + proneCounter.remove(); + } + points = points.filter(p => p != `${pos.x},${pos.y}`).join(' '); trace.setAttributeNS(null, 'points', points); + this.remove(); } - - this.remove(); } }, @@ -550,6 +575,14 @@ export default class Game { container.SightLine.draw(this.parentElement, clone.parentElement); } + const proneCounter = this.parentElement.querySelector('[href="#counter-prone"]'); + + if (proneCounter) { + proneCounter.remove(); + } + + container.proneFlagCallback(!!clone.parentElement.querySelector('[href="#counter-prone"]')); + clone.parentElement.appendChild(this); clone.remove(); } @@ -588,6 +621,7 @@ export default class Game { counter.classList.add(selectedClass); let existingArcs = container.getExistingArcs(allegiance, number); existingArcs.forEach(el => el.removeAttribute('clip-path')); + container.selectCallback({ prone: this.hasProne(counter), ...counter.dataset }); } }; @@ -639,6 +673,10 @@ export default class Game { original.parentElement.appendChild(counter); point.parentElement.appendChild(original); + if (counter.parentElement.querySelector('[href="#counter-prone"]')) { + container.Counter.toggleProne(); + } + let previous = container.getCellPosition(counter.parentElement), current = container.getCellPosition(original.parentElement); @@ -671,7 +709,15 @@ export default class Game { }; this.removeClones = function ({ dataset: { allegiance, number }}) { - container.getClones(allegiance, number).forEach(el => el.remove()); + container.getClones(allegiance, number).forEach(el => { + const proneCounter = el.parentElement.querySelector('[href="#counter-prone"]'); + + if (proneCounter) { + proneCounter.remove(); + } + + el.remove() + }); }; this.endMove = function (el) { @@ -686,12 +732,33 @@ export default class Game { this.unSelect(); }; - this.hasProne = function (troopNumber, troopAllegiance) { - let selector = `g#${troopAllegiance}-${troopNumber} use[href="#counter-prone"]`; + this.hasProne = function (counter) { + const isOnBoard = counter.parentElement.hasAttribute('data-x'); + + if (isOnBoard) { + return !!counter.parentElement.querySelector('[href="#counter-prone"]'); + } - return !!container.svg.querySelector(selector); + return false; }; + this.toggleProne = function() { + const selected = container.getSelected(), + isOnBoard = selected && selected.parentElement.hasAttribute('data-x'); + + if (selected && isOnBoard) { + const proneCounter = selected.parentElement.querySelector('[href="#counter-prone"]'); + + if (proneCounter) { + proneCounter.remove(); + } else { + const counter = document.createElementNS(svgns, 'use'); + counter.setAttributeNS(null, 'href', '#counter-prone'); + selected.parentElement.appendChild(counter); + } + } + } + this.addEventListeners = function (counter) { counter.addEventListener('pointerover', pointerOver); counter.addEventListener('pointerout', pointerOut); @@ -724,9 +791,8 @@ export default class Game { }; this.clearHexes = function() { - if (ptGrp.info) { - ptGrp.info.querySelector('#hex-count').textContent = '-'; - ptGrp.info.style.display = 'none'; + if (ptGrp.distanceCallback) { + ptGrp.distanceCallback(); } ptGrp.getActiveHexes().forEach(el => el.classList.remove('active')); @@ -800,9 +866,8 @@ export default class Game { this.drawHexes = function (...coords) { this.clearHexes() - if (ptGrp.info) { - ptGrp.info.querySelector('#hex-count').textContent = offset_distance(...coords); - ptGrp.info.style.display = 'block'; + if (ptGrp.distanceCallback) { + ptGrp.distanceCallback(offset_distance(...coords)); } let lineCoords = linedraw(...coords); |