WIP: add multiple counters to troopers and cells

This commit is contained in:
2024-07-25 12:25:44 -07:00
parent 37b05156c6
commit f1d67663da
10 changed files with 276 additions and 70 deletions

View File

@@ -84,6 +84,11 @@ async function buildScenario(req) {
// recordSheet.start(svg.querySelector('.start-locations'), gameboard.getUnits());
recordSheet.start(null, scenarioUnits);
const [trooper] = gameboard.getUnits();
Observable.notify('select', trooper);
gameboard.setCounter('prone');
gameboard.setCounter('1st-floor');
}
function updateTurnCounter() {

View File

@@ -34,7 +34,7 @@ function updatePlacement(cell, selected, clone) {
const { q, r, s, t } = clone.parentElement.dataset;
selected.dataset.previous = [q, r, s, t];
cell.appendChild(selected);
placeIn(cell, selected);
Array.from(selected.children).forEach(n => {
if (n.classList.contains('removed')) {
@@ -56,6 +56,10 @@ function createTrace(previous, current, selected) {
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');
@@ -126,7 +130,7 @@ export function place(svg, selected, cell) {
handleTrace(svg, selected, clone, getCellPosition(cell));
} else {
selected.removeAttribute('data-x');
cell.appendChild(selected);
placeIn(cell, selected);
}
}

View File

@@ -34,8 +34,9 @@ function getActiveSightLine(svg) {
return svg.querySelector('line.sight-line.active');
}
function isGrenade(el) {
return el && el.getAttribute('href') === '#counter-grenade';
function isCounter(el) {
const regex = new RegExp('^#counter-')
return el && regex.test(el.getAttribute('href'));
}
function isMechTemplate(el) {
@@ -196,10 +197,10 @@ function endMove() {
}
}
function returnPieces(collection) {
[...svg.querySelector('.pieces').children].forEach(piece => {
collection.get(piece).parent.append(piece);
collection.delete(piece);
function returnPieces(top) {
[...top.container.children].forEach(piece => {
top.collection.get(piece).parent.append(piece);
top.collection.delete(piece);
});
}
@@ -209,19 +210,19 @@ export function start(el) {
const startingLocations = svg.querySelector('.start-locations');
startingLocations && getUnits(startingLocations).forEach(unit => unit.addEventListener('click', selectOffBoard));
const pieces = svg.querySelector('.pieces');
const inFront = new Map();
let inFrontParent;
//addEventListener('pointerout', e => { returnPieces(inFront) });
const top = {
container: svg.querySelector('.grid-top'),
collection: new Map()
};
getCells(svg).forEach(cell => {
cell.addEventListener('click', e => {
const occupant = getCellOccupant(cell);
let toPlace = placing.pop();
if (isGrenade(toPlace) || isMechTemplate(toPlace)) {
if (isCounter(toPlace) || isMechTemplate(toPlace)) {
getHex(cell).after(toPlace);
if (isCounter(toPlace)) arrangeCounters(cell);
removeEventListener("keydown", handleMechTemplateRotation);
} else if (toPlace && !occupant) {
soldier.place(svg, toPlace, cell);
@@ -282,12 +283,12 @@ export function start(el) {
});
cell.addEventListener('pointerover', () => {
if (!pieces.contains(cell)) {
returnPieces(inFront);
inFront.set(cell, { parent: cell.parentElement });
pieces.append(cell);
if (!top.container.contains(cell)) {
returnPieces(top);
top.collection.set(cell, { parent: cell.parentElement });
top.container.append(cell);
}
console.log(top.container.children[0].children);
const selected = getSelected();
if (placing[0]?.getAttributeNS(null, 'class') == 'mech-template') {
@@ -307,22 +308,6 @@ export function start(el) {
});
cell.addEventListener('pointerout', () => {
//if (inFront && inFrontParent) {
// inFrontParent.append(inFront);
// inFront = null;
// inFrontParent = null;
//}
//for (const [el, parent] of inFront) {
// parent.append(el);
// inFront.delete(el);
//}
//[...pieces.children].forEach(piece => {
// inFront.get(piece).parent.append(piece);
// inFront.delete(piece);
//});
//returnPieces(inFront);
getActiveSightLine(svg) && clearSightLine();
const occupant = getCellOccupant(cell);
@@ -334,27 +319,27 @@ export function start(el) {
});
// debug //
const attacker = { dataset: { allegiance: 'attacker', number: 1, squad: 1 }};
// Add a trooper counter
const attacker = { dataset: { allegiance: 'attacker', number: 1, squad: 1 }};
// const defender = { dataset: { allegiance: 'defender', number: 1, squad: 2 }};
const cell = getCell(2, 0, -2, 0);
const cell = getCell(0, 0, 0, 0);
const trooper = soldier.createCounter(attacker, 'blazer');
soldier.place(svg, trooper, cell);
// Add some counters in an unoccupied cell
const countersCell = getCell(-1, 1, 0, 0);
setCounter('grenade');
setCounter('prone');
setCounter('1st-floor');
const e = new PointerEvent('click');
countersCell.dispatchEvent(e);
countersCell.dispatchEvent(e);
countersCell.dispatchEvent(e);
///////////
Observable.subscribe('select', select);
Observable.subscribe('endmove', endMove);
Observable.notify('select', trooper);
//Array(1).fill(null).forEach(() => {
// const counter = document.createElementNS(svgns, 'use');
// counter.setAttributeNS(null, 'href', '#counter-grenade');
// counter.classList.add('counter-grenade');
// trooper.appendChild(counter);
//});
//
//setGrenade();
console.log('gameboard.js loaded');
}
@@ -427,6 +412,30 @@ export function setCounter(name) {
placing.push(counter);
}
function arrangeCounters(cell) {
const counters = cell.querySelectorAll('[class^="counter-"]');
const length = 12;
const gravity = 1;
const lateralForce = gravity;
const rads = Math.atan(lateralForce / gravity);
const bestFitCount = 8;
const deflection = counters.length > bestFitCount ? 2 * Math.PI / counters.length : Math.atan(lateralForce / gravity);
counters.forEach((counter, index, arr) => {
const mult = index - arr.length / 2 + 0.5;
const theta = deflection * mult;
const x = length * Math.sin(theta);
const y = length * Math.cos(theta);
//counter.setAttributeNS(null, 'x', 0);
//counter.setAttributeNS(null, 'y', 10);
//counter.setAttributeNS(null, 'transform', `rotate(${theta * 180 / Math.PI})`);
//counter.setAttributeNS(null, 'style', `y: 10px; transform-origin: 5px 0; transform: translateX(-5px) rotate(${theta * 180 / Math.PI}deg)`);
counter.setAttributeNS(null, 'style', `--x: ${-x}px; --y: ${y}px`);
//counter.setAttributeNS(null, 'style', `x: 0; y: 10px;`);
});
console.log(counters);
}
function handleMechTemplateRotation(event) {
const counter = placing[0];
const upper = placing[0].querySelector('use[href="#mech-template-upper"]');