index : btroops | |
Virtual board game-aid for BattleTroops, an infantry combat simulator wargame published by FASA in 1989. |
aboutsummaryrefslogtreecommitdiff |
diff options
-rw-r--r-- | index.js | 429 |
1 files changed, 291 insertions, 138 deletions
@@ -349,36 +349,87 @@ function ptGrpToSvgPt(x, y) { return svgP; } -POINTS.forEach((row, index) => row.forEach(([x, y]) => { - var cx = x * INRADIUS * 2 + (isEven(index) ? INRADIUS : 0), - cy = y * 3 / 2 * CIRCUMRADIUS, - point = document.createElementNS(svgns, 'use'); +const Counter = new function() { + let container = cntrGrp, + selectedClass = 'selected', + + dataSelector = function(troopNumber, allegiance) { + return `[data-troop-number="${troopNumber}"][data-troop-allegiance="${allegiance}"]`; + }, + + selector = function(troopNumber, allegiance) { + return `use${dataSelector(troopNumber, allegiance)}`; + }, + + traceSelector = function(troopNumber, allegiance) { + return `polyline.move-trace${dataSelector(troopNumber, allegiance)}`; + }, + + clickClone = function() { + let { troopNumber, troopAllegiance, x, y } = this.dataset, + xAttr = this.getAttribute('x'), + yAttr = this.getAttribute('y'); + + if (Counter.isSelected(troopNumber, troopAllegiance)) { + let trace = container.querySelector(traceSelector(troopNumber, troopAllegiance)), + points = trace.getAttribute('points').split(' '); + + if (`${xAttr},${yAttr}` == points.at(0)) { + let counter = Counter.get(troopNumber, troopAllegiance); + counter.setAttributeNS(null, 'x', xAttr); + counter.setAttributeNS(null, 'y', yAttr); + counter.dataset.x = x; + counter.dataset.y = y; + + container.querySelectorAll(`${selector(troopNumber, troopAllegiance)}.clone`).forEach(el => el.remove()); + trace.remove(); + } else { + points = points.filter(p => p != `${xAttr},${yAttr}`).join(' '); + + trace.setAttributeNS(null, 'points', points); + } - cx = parseFloat(cx.toFixed(1)); - cy = parseFloat(cy.toFixed(1)); + this.remove(); + } + }; - point.setAttributeNS(null, 'href', `#point`); - point.setAttributeNS(null, 'x', cx); - point.setAttributeNS(null, 'y', cy); - point.dataset.x = x; - point.dataset.y = y; + this.get = function(troopNumber, allegiance) { + return container.querySelector(`${selector(troopNumber, allegiance)}:not(.clone)`); + }; - point.addEventListener('click', e => { - let selectedSoldier = document.querySelector('.soldier-record.selected'); - let existingOccupant = - svg.querySelector(`.counter[data-x="${point.dataset.x}"][data-y="${point.dataset.y}"]`); + this.select = function({ dataset: { troopNumber, troopAllegiance }}) { + this.unSelect(); - if (selectedSoldier && !existingOccupant) { + let queriedCounter = container.querySelector(selector(troopNumber, troopAllegiance)); + + if (queriedCounter) { + queriedCounter.classList.add(selectedClass); + } + }; + + this.unSelect = function() { + container + .querySelectorAll(`.${selectedClass}`) + .forEach(el => el.classList.remove(selectedClass)); + }; + + this.isSelected = function(troopNumber, allegiance) { + return container.querySelector(`${selector(troopNumber, allegiance)}.${selectedClass}`) !== null; + }; + + this.place = function({ dataset: { troopNumber, troopAllegiance }}, point) { + let tempSelector = selector(troopNumber, troopAllegiance); + + new function() { let counter, points, - { troopNumber, troopAllegiance } = selectedSoldier.dataset, - selector = troopSelector(troopNumber, troopAllegiance), - counterNodeList = cntrGrp.querySelectorAll(`use${selector}`); + selector = tempSelector, + counterNodeList = container.querySelectorAll(`${selector}`); if (counterNodeList.length > 0) { let counters = Array.from(counterNodeList), original = counters.find(el => !el.classList.contains('clone')), count = counters.filter(el => el.classList.contains('clone')).length, - trace = cntrGrp.querySelector(`polyline.move-trace${selector}`); + trace = container.querySelector(traceSelector(troopNumber, troopAllegiance)); let current = { x: point.dataset.x, @@ -399,6 +450,7 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => { counter.dataset.x = previous.x; counter.dataset.y = previous.y; counter.dataset.cloneOrder = count + 1; + counter.classList.remove(selectedClass); counter.classList.add('clone'); original.setAttributeNS(null, 'x', current.xAttr); @@ -414,161 +466,259 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => { trace.dataset.troopAllegiance = troopAllegiance; trace.classList.add('move-trace'); - cntrGrp.prepend(trace); + container.prepend(trace); } else { points = `${trace.getAttribute('points')} ${current.xAttr},${current.yAttr}`; } trace.setAttributeNS(null, 'points', points); - - counter.addEventListener('click', e => { - let selectedSoldier = document.querySelector('.soldier-record.selected'); - - if (selectedSoldier) { - let { troopNumber, troopAllegiance } = selectedSoldier.dataset, - selector = troopSelector(troopNumber, troopAllegiance); - - if (counter.dataset.troopAllegiance == troopAllegiance && counter.dataset.troopNumber == troopNumber) { - let [xAttr, yAttr] = [counter.getAttribute('x'), counter.getAttribute('y')]; - let points = trace.getAttribute('points').split(' '); - - if (`${xAttr},${yAttr}` == points.at(0)) { - original.setAttributeNS(null, 'x', xAttr); - original.setAttributeNS(null, 'y', yAttr); - original.dataset.x = counter.dataset.x; - original.dataset.y = counter.dataset.y; - - cntrGrp.querySelectorAll(`use${selector}.clone`).forEach(el => el.remove()); - trace.remove(); - } else { - let points = trace.getAttribute('points').split(' ').filter(p => p != `${xAttr},${yAttr}`); - - trace.setAttributeNS(null, 'points', points.join(' ')); - } - - counter.remove(); - } - } - }); - + counter.addEventListener('click', clickClone); } else { counter = document.createElementNS(svgns, 'use'), counter.setAttributeNS(null, 'href', `#t-${troopNumber}`); - counter.classList.add('counter'); - counter.setAttributeNS(null, 'x', cx); - counter.setAttributeNS(null, 'y', cy); + counter.classList.add('counter', 'selected'); + counter.setAttributeNS(null, 'x', point.getAttribute('x')); + counter.setAttributeNS(null, 'y', point.getAttribute('y')); counter.dataset.troopNumber = troopNumber; counter.dataset.troopAllegiance = troopAllegiance; counter.dataset.x = point.dataset.x; counter.dataset.y = point.dataset.y; - counter.addEventListener('dblclick', e => { - let selectedSoldier = document.querySelector('.soldier-record.selected'); - - if (selectedSoldier) { - let trace = cntrGrp.querySelector(`polyline.move-trace${selector}`); - if (!trace) { - let {troopNumber, troopAllegiance} = selectedSoldier.dataset, - selector = troopSelector(troopNumber, troopAllegiance), - targetIsSelectedSoldier = [ - e.target.dataset.troopNumber == troopNumber, - e.target.dataset.troopAllegiance == troopAllegiance - ].every(el => el); - - if (targetIsSelectedSoldier) { - cntrGrp.querySelectorAll(`${selector}`).forEach(el => el.remove()); - document.querySelectorAll(`#firing-arcs ${selector}`).forEach(el => el.remove()); - } - } - } - }); + // counter.addEventListener('dblclick', e => { + // let selectedSoldier = document.querySelector('.soldier-record.selected'); + + // if (selectedSoldier) { + // let trace = container.querySelector(`polyline.move-trace${selector}`); + // if (!trace) { + // let {troopNumber, troopAllegiance} = selectedSoldier.dataset, + // selector = troopSelector(troopNumber, troopAllegiance), + // targetIsSelectedSoldier = [ + // e.target.dataset.troopNumber == troopNumber, + // e.target.dataset.troopAllegiance == troopAllegiance + // ].every(el => el); + + // if (targetIsSelectedSoldier) { + // container.querySelectorAll(`${selector}`).forEach(el => el.remove()); + // document.querySelectorAll(`#firing-arcs ${selector}`).forEach(el => el.remove()); + // } + // } + // } + // }); - counter.addEventListener('click', e => { - let selectedSoldier = document.querySelector('.soldier-record.selected'); + // counter.addEventListener('click', e => { + // let selectedSoldier = document.querySelector('.soldier-record.selected'); - if (selectedSoldier) { - let { troopNumber, troopAllegiance } = selectedSoldier.dataset, - selector = troopSelector(troopNumber, troopAllegiance); + // if (selectedSoldier) { + // let { troopNumber, troopAllegiance } = selectedSoldier.dataset, + // selector = troopSelector(troopNumber, troopAllegiance); - if (counter.dataset.troopAllegiance == troopAllegiance && counter.dataset.troopNumber == troopNumber) { - let trace = cntrGrp.querySelector(`polyline.move-trace${selector}`); + // if (counter.dataset.troopAllegiance == troopAllegiance && counter.dataset.troopNumber == troopNumber) { + // let trace = container.querySelector(`polyline.move-trace${selector}`); - if (trace) { - let points = trace.getAttribute('points').split(' '); - let [xAttr, yAttr] = points.at(-2).split(','); - let clone = cntrGrp.querySelector(`${selector}[x="${xAttr}"][y="${yAttr}"].clone`); + // if (trace) { + // let points = trace.getAttribute('points').split(' '); + // let [xAttr, yAttr] = points.at(-2).split(','); + // let clone = container.querySelector(`${selector}[x="${xAttr}"][y="${yAttr}"].clone`); - points.pop() + // points.pop() - if (points.length >= 2) { - trace.setAttributeNS(null, 'points', points.join(' ')); - } else { - trace.remove(); - } + // if (points.length >= 2) { + // trace.setAttributeNS(null, 'points', points.join(' ')); + // } else { + // trace.remove(); + // } - counter.setAttributeNS(null, 'x', clone.getAttribute('x')); - counter.setAttributeNS(null, 'y', clone.getAttribute('y')); - counter.dataset.x = clone.dataset.x; - counter.dataset.y = clone.dataset.y; + // counter.setAttributeNS(null, 'x', clone.getAttribute('x')); + // counter.setAttributeNS(null, 'y', clone.getAttribute('y')); + // counter.dataset.x = clone.dataset.x; + // counter.dataset.y = clone.dataset.y; - clone.remove(); - } - } - } - }); + // clone.remove(); + // } + // } + // } + // }); } - // info.querySelector('#hex-count').textContent = '-'; - // info.style.display = 'none'; - // ptGrp.querySelectorAll('.active').forEach(el => el.removeAttribute('class')); - // svg.querySelectorAll('.sight-line').forEach(el => el.remove()); + container.appendChild(counter); + } + } +}; + +POINTS.forEach((row, index) => row.forEach(([x, y]) => { + var cx = x * INRADIUS * 2 + (isEven(index) ? INRADIUS : 0), + cy = y * 3 / 2 * CIRCUMRADIUS, + point = document.createElementNS(svgns, 'use'); + + cx = parseFloat(cx.toFixed(1)); + cy = parseFloat(cy.toFixed(1)); + + point.setAttributeNS(null, 'href', `#point`); + point.setAttributeNS(null, 'x', cx); + point.setAttributeNS(null, 'y', cy); + point.dataset.x = x; + point.dataset.y = y; + + point.addEventListener('click', e => { + let selectedSoldier = document.querySelector('.soldier-record.selected'); + let existingOccupant = + svg.querySelector(`.counter[data-x="${point.dataset.x}"][data-y="${point.dataset.y}"]`); + + if (selectedSoldier && !existingOccupant) { + Counter.place(selectedSoldier, point); + + // let counter, points, + // { troopNumber, troopAllegiance } = selectedSoldier.dataset, + // selector = troopSelector(troopNumber, troopAllegiance), + // counterNodeList = cntrGrp.querySelectorAll(`use${selector}`); + + // if (counterNodeList.length > 0) { + // let counters = Array.from(counterNodeList), + // original = counters.find(el => !el.classList.contains('clone')), + // count = counters.filter(el => el.classList.contains('clone')).length, + // trace = cntrGrp.querySelector(`polyline.move-trace${selector}`); + + // let current = { + // x: point.dataset.x, + // y: point.dataset.y, + // xAttr: point.getAttribute('x'), + // yAttr: point.getAttribute('y') + // }, + // previous = { + // x: original.dataset.x, + // y: original.dataset.y, + // xAttr: original.getAttribute('x'), + // yAttr: original.getAttribute('y') + // } + + // counter = original.cloneNode(); + // counter.setAttributeNS(null, 'x', previous.xAttr); + // counter.setAttributeNS(null, 'y', previous.yAttr); + // counter.dataset.x = previous.x; + // counter.dataset.y = previous.y; + // counter.dataset.cloneOrder = count + 1; + // counter.classList.add('clone'); + + // original.setAttributeNS(null, 'x', current.xAttr); + // original.setAttributeNS(null, 'y', current.yAttr); + // original.dataset.x = current.x; + // original.dataset.y = current.y; + + // if (!trace) { + // trace = document.createElementNS(svgns, 'polyline'); + // points = `${previous.xAttr},${previous.yAttr} ${current.xAttr},${current.yAttr}`; + + // trace.dataset.troopNumber = troopNumber; + // trace.dataset.troopAllegiance = troopAllegiance; + // trace.classList.add('move-trace'); + + // cntrGrp.prepend(trace); + // } else { + // points = `${trace.getAttribute('points')} ${current.xAttr},${current.yAttr}`; + // } + + // trace.setAttributeNS(null, 'points', points); - // document.querySelectorAll(`.counter${selector}`).forEach(el => el.remove()); + // counter.addEventListener('click', e => { + // let selectedSoldier = document.querySelector('.soldier-record.selected'); - // counter.addEventListener('mouseenter', e => { - // let selectedSoldier = document.querySelector('.soldier-record.selected'); + // if (selectedSoldier) { + // let { troopNumber, troopAllegiance } = selectedSoldier.dataset, + // selector = troopSelector(troopNumber, troopAllegiance); - // if (selectedSoldier) { - // let {troopNumber, troopAllegiance} = selectedSoldier.dataset, - // selector = troopSelector(troopNumber, troopAllegiance), - // source = document.querySelector(`circle.counter${selector}`), + // if (counter.dataset.troopAllegiance == troopAllegiance && counter.dataset.troopNumber == troopNumber) { + // let [xAttr, yAttr] = [counter.getAttribute('x'), counter.getAttribute('y')]; + // let points = trace.getAttribute('points').split(' '); - // // TODO: use isEqualNode() method instead - // sourceAndTargetAreNotTheSame = [ - // troopNumber != e.target.dataset.troopNumber, - // troopAllegiance != e.target.dataset.troopAllegiance - // ].some(el => el); + // if (`${xAttr},${yAttr}` == points.at(0)) { + // original.setAttributeNS(null, 'x', xAttr); + // original.setAttributeNS(null, 'y', yAttr); + // original.dataset.x = counter.dataset.x; + // original.dataset.y = counter.dataset.y; - // if (source && sourceAndTargetAreNotTheSame) { - // let sightLine = document.createElementNS(svgns, 'line'); + // cntrGrp.querySelectorAll(`use${selector}.clone`).forEach(el => el.remove()); + // trace.remove(); + // } else { + // let points = trace.getAttribute('points').split(' ').filter(p => p != `${xAttr},${yAttr}`); - // sightLine.classList.add('sight-line'); - // sightLine.setAttributeNS(null, 'x1', source.getAttribute('cx')); - // sightLine.setAttributeNS(null, 'y1', source.getAttribute('cy')); - // sightLine.setAttributeNS(null, 'x2', e.target.getAttribute('cx')); - // sightLine.setAttributeNS(null, 'y2', e.target.getAttribute('cy')); + // trace.setAttributeNS(null, 'points', points.join(' ')); + // } - // svg.appendChild(sightLine); + // counter.remove(); + // } // } - // } - // }); + // }); + + // } else { + // counter = document.createElementNS(svgns, 'use'), + + // counter.setAttributeNS(null, 'href', `#t-${troopNumber}`); + // counter.classList.add('counter'); + // counter.setAttributeNS(null, 'x', cx); + // counter.setAttributeNS(null, 'y', cy); + // counter.dataset.troopNumber = troopNumber; + // counter.dataset.troopAllegiance = troopAllegiance; + // counter.dataset.x = point.dataset.x; + // counter.dataset.y = point.dataset.y; + + // counter.addEventListener('dblclick', e => { + // let selectedSoldier = document.querySelector('.soldier-record.selected'); + + // if (selectedSoldier) { + // let trace = cntrGrp.querySelector(`polyline.move-trace${selector}`); + // if (!trace) { + // let {troopNumber, troopAllegiance} = selectedSoldier.dataset, + // selector = troopSelector(troopNumber, troopAllegiance), + // targetIsSelectedSoldier = [ + // e.target.dataset.troopNumber == troopNumber, + // e.target.dataset.troopAllegiance == troopAllegiance + // ].every(el => el); + + // if (targetIsSelectedSoldier) { + // cntrGrp.querySelectorAll(`${selector}`).forEach(el => el.remove()); + // document.querySelectorAll(`#firing-arcs ${selector}`).forEach(el => el.remove()); + // } + // } + // } + // }); - // counter.addEventListener('mouseleave', e => { - // document.querySelectorAll('.sight-line').forEach(el => el.remove()); - // }); + // counter.addEventListener('click', e => { + // let selectedSoldier = document.querySelector('.soldier-record.selected'); - // svg.insertBefore(counter, ptGrp); + // if (selectedSoldier) { + // let { troopNumber, troopAllegiance } = selectedSoldier.dataset, + // selector = troopSelector(troopNumber, troopAllegiance); - // let symbCtr = document.createElementNS(svgns, 'use'); + // if (counter.dataset.troopAllegiance == troopAllegiance && counter.dataset.troopNumber == troopNumber) { + // let trace = cntrGrp.querySelector(`polyline.move-trace${selector}`); - // symbCtr.setAttributeNS(null, 'href', '#troop-counter'); - // symbCtr.setAttributeNS(null, 'x', cx); - // symbCtr.setAttributeNS(null, 'y', cy); + // if (trace) { + // let points = trace.getAttribute('points').split(' '); + // let [xAttr, yAttr] = points.at(-2).split(','); + // let clone = cntrGrp.querySelector(`${selector}[x="${xAttr}"][y="${yAttr}"].clone`); - // cntrGrp.appendChild(symbCtr); + // points.pop() + + // if (points.length >= 2) { + // trace.setAttributeNS(null, 'points', points.join(' ')); + // } else { + // trace.remove(); + // } + + // counter.setAttributeNS(null, 'x', clone.getAttribute('x')); + // counter.setAttributeNS(null, 'y', clone.getAttribute('y')); + // counter.dataset.x = clone.dataset.x; + // counter.dataset.y = clone.dataset.y; + + // clone.remove(); + // } + // } + // } + // }); + // } - cntrGrp.appendChild(counter); + // cntrGrp.appendChild(counter); } }); @@ -579,7 +729,8 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => { // e.target.classList.add('active'); let { troopNumber: tn, troopAllegiance: ta } = selectedSoldier.dataset; - let counter = svg.querySelector(`circle.counter[data-troop-number="${tn}"][data-troop-allegiance="${ta}"]`); + // let counter = svg.querySelector(`circle.counter[data-troop-number="${tn}"][data-troop-allegiance="${ta}"]`); + let counter = Counter.get(tn, ta); let sl = svg.querySelector('.sight-line'); if (counter && (!sl || sl.classList.contains('active'))) { @@ -668,12 +819,14 @@ document.querySelectorAll('.soldier-record').forEach(el => el.addEventListener('click', e => { if (el.classList.contains('selected')) { el.classList.remove('selected'); + Counter.unSelect(); } else { document.querySelectorAll('.soldier-record.selected').forEach(el => el.classList.remove('selected') ); el.classList.add('selected'); + Counter.select(el); } let sl = svg.querySelector('.sight-line'); |