176 lines
5.3 KiB
JavaScript
176 lines
5.3 KiB
JavaScript
import counters from './assets/images/counters.svg';
|
|
import { extractWeaponFromRecord, isRecord } from '../record_sheet.js';
|
|
|
|
const selectedClass = 'selected';
|
|
|
|
function dataSelector({ dataset: { allegiance, number }}) {
|
|
return `[data-number="${number}"][data-allegiance="${allegiance}"]`;
|
|
}
|
|
|
|
function traceSelector(counter) {
|
|
return `polyline.move-trace${dataSelector(counter)}`;
|
|
}
|
|
|
|
function getCellPosition(cell) {
|
|
const [x, y] = cell.getAttributeNS(null, 'transform').match(/-?\d+\.?\d*/g);
|
|
|
|
return { x, y };
|
|
}
|
|
|
|
function getClones(svg, counter) {
|
|
return svg.querySelectorAll(`.counter.clone${dataSelector(counter)}`);
|
|
}
|
|
|
|
function addMoveToHistory(selected) {
|
|
const clone = selected.cloneNode(true);
|
|
clone.classList.remove(selectedClass);
|
|
clone.classList.add('clone');
|
|
selected.parentElement.appendChild(clone);
|
|
|
|
return clone;
|
|
}
|
|
|
|
function updatePlacement(cell, selected, clone) {
|
|
const { q, r, s, t } = clone.parentElement.dataset;
|
|
|
|
selected.dataset.previous = [q, r, s, t];
|
|
placeIn(cell, selected);
|
|
|
|
Array.from(selected.children).forEach(n => {
|
|
if (n.classList.contains('removed')) {
|
|
n.remove();
|
|
} else if ('preexisting' in n.dataset) {
|
|
delete n.dataset.preexisting;
|
|
}
|
|
});
|
|
}
|
|
|
|
function createTrace(previous, current, selected) {
|
|
const trace = document.createElementNS(svgns, 'polyline');
|
|
|
|
trace.dataset.number = selected.dataset.number;
|
|
trace.dataset.allegiance = selected.dataset.allegiance;
|
|
trace.classList.add('move-trace');
|
|
trace.setAttributeNS(null, 'points', `${previous.x},${previous.y} ${current.x},${current.y}`);
|
|
|
|
return trace;
|
|
}
|
|
|
|
function placeIn(location, target) {
|
|
location.querySelector('use[href="#hex"]').after(target);
|
|
}
|
|
|
|
export function createCounter(selected, weapon = 'rifle') {
|
|
const g = document.createElementNS(svgns, 'g');
|
|
const weaponCounter = document.createElementNS(svgns, 'use');
|
|
const assignedWeapon = isRecord(selected) ? extractWeaponFromRecord(selected) : weapon;
|
|
const troopNum = document.createElementNS(svgns, 'use');
|
|
const squadNum = document.createElementNS(svgns, 'use');
|
|
|
|
weaponCounter.setAttributeNS(null, 'href', `../../${counters}#${assignedWeapon}`);
|
|
weaponCounter.classList.add('primary-weapon');
|
|
|
|
troopNum.setAttributeNS(null, 'href', `../../${counters}#number-${selected.dataset.number}`);
|
|
troopNum.classList.add('troop-number');
|
|
|
|
squadNum.setAttributeNS(null, 'href', `../../${counters}#number-${selected.dataset.squad}`);
|
|
squadNum.classList.add('squad-number');
|
|
|
|
g.classList.add('counter');
|
|
g.dataset.allegiance = selected.dataset.allegiance;
|
|
g.dataset.number = selected.dataset.number;
|
|
g.dataset.squad = selected.dataset.squad;
|
|
g.appendChild(weaponCounter);
|
|
g.appendChild(troopNum);
|
|
g.appendChild(squadNum);
|
|
|
|
return g;
|
|
}
|
|
|
|
export function handleTrace(svg, selected, clone, current) {
|
|
let trace = getTrace(svg, selected);
|
|
|
|
if (!trace) {
|
|
trace = createTrace(getCellPosition(clone.parentElement), current, selected);
|
|
svg.querySelector('.grid').before(trace);
|
|
} else {
|
|
const points = `${trace.getAttribute('points')} ${current.x},${current.y}`;
|
|
trace.setAttributeNS(null, 'points', points);
|
|
}
|
|
}
|
|
|
|
export function getAllCounters(container) {
|
|
return container.querySelectorAll('g.counter[data-allegiance][data-number]');
|
|
}
|
|
|
|
export function getCounter(svg, selected) {
|
|
return svg.querySelector(`.counter${dataSelector(selected)}:not(.clone)`);
|
|
}
|
|
|
|
export function getTrace(svg, counter) {
|
|
return svg.querySelector(traceSelector(counter));
|
|
}
|
|
|
|
export function place(svg, selected, cell) {
|
|
//console.log(selected.parentElement);
|
|
//const piecesContainer = svg.querySelector('.pieces');
|
|
//const parent = selected.parentElement;
|
|
//if (parent)
|
|
// parent.setAttributeNS(null, 'transform', cell.getAttributeNS(null, 'transform'));
|
|
//else {
|
|
// const container = document.createElementNS(svgns, 'g');
|
|
// container.setAttributeNS(null, 'transform', cell.getAttributeNS(null, 'transform'));
|
|
// container.append(selected);
|
|
// piecesContainer.append(container);
|
|
//}
|
|
|
|
//if (svg.querySelector('.grid').contains(selected)) {
|
|
// const clone = addMoveToHistory(selected);
|
|
// updatePlacement(cell, selected, clone)
|
|
// handleTrace(svg, selected, clone, getCellPosition(cell));
|
|
//} else {
|
|
// selected.removeAttribute('data-x');
|
|
placeIn(cell, selected);
|
|
//}
|
|
}
|
|
|
|
export function removeClones(svg, counter) {
|
|
getClones(svg, counter).forEach(c => c.remove());
|
|
}
|
|
|
|
export function endMove(svg, counter) {
|
|
Array.from(counter.children).forEach(n => {
|
|
if (n.classList.contains('removed')) {
|
|
n.remove();
|
|
} else {
|
|
n.dataset.preexisting = '';
|
|
}
|
|
});
|
|
|
|
svg.querySelector(traceSelector(counter))?.remove();
|
|
delete counter.dataset.previous;
|
|
removeClones(svg, counter);
|
|
}
|
|
|
|
export function hasProne(counter) {
|
|
return !!counter.querySelector('[href="#counter-prone"]:not(.removed)');
|
|
}
|
|
|
|
export function toggleProne(counter) {
|
|
let proneCounter = counter.querySelector('[href="#counter-prone"]');
|
|
|
|
if (!proneCounter) {
|
|
proneCounter = document.createElementNS(svgns, 'use');
|
|
proneCounter.setAttributeNS(null, 'href', '#counter-prone');
|
|
counter.appendChild(proneCounter);
|
|
} else if ('preexisting' in proneCounter.dataset) {
|
|
proneCounter.classList.toggle('removed');
|
|
} else {
|
|
proneCounter.remove();
|
|
}
|
|
}
|
|
|
|
export function getSelectedClass() {
|
|
return selectedClass;
|
|
}
|