WIP: use scenario template to build scenarios client-side

This commit is contained in:
Catalin Constantin Mititiuc 2025-06-16 22:41:31 -07:00
parent d4974c74de
commit dac61e6121
7 changed files with 300 additions and 2143 deletions

View File

@ -1,69 +1,12 @@
<?xml version="1.0" standalone="no"?>
<svg viewBox="-10 -10 200 300" xmlns="http://www.w3.org/2000/svg">
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="../css/map.css" type="text/css" />
<style>
g[data-edge="north"] { --i: -2; }
g[data-edge="south"] { --i: 78; }
#background {
stroke: #304b75;
fill: #bacae3;
}
pattern use {
stroke: black;
stroke-width: 0.3px;
}
.cw-60-deg {
transform: rotate(60deg);
}
.ccw-60-deg {
transform: rotate(-60deg);
}
</style>
<defs>
<polygon id="hex" points="0,10 8.66,5 8.66,-5 0,-10 -8.66,-5 -8.66,5"/>
<line id="ast-line" x1="-1.2" y1="0" x2="1.2" y2="0"/>
<pattern id="asterisk" viewBox="-8.66 -15 17.32 30" width="17.32" height="30" patternUnits="userSpaceOnUse">
<use y="-15" href="#ast-line"/>
<use y="-15" style="transform-origin: 0 -15px;" class="cw-60-deg" href="#ast-line"/>
<use y="-15" style="transform-origin: 0 -15px;" class="ccw-60-deg" href="#ast-line"/>
<use y="15" href="#ast-line"/>
<use y="15" style="transform-origin: 0 15px;" class="cw-60-deg" href="#ast-line"/>
<use y="15" style="transform-origin: 0 15px;" class="ccw-60-deg" href="#ast-line"/>
<use x="8.66" href="#ast-line"/>
<use x="8.66" style="transform-origin: 8.66px 0;" class="cw-60-deg" href="#ast-line"/>
<use x="8.66" style="transform-origin: 8.66px 0;" class="ccw-60-deg" href="#ast-line"/>
<use x="-8.66" href="#ast-line"/>
<use x="-8.66" style="transform-origin: -8.66px 0;" class="cw-60-deg" href="#ast-line"/>
<use x="-8.66" style="transform-origin: -8.66px 0;" class="ccw-60-deg" href="#ast-line"/>
</pattern>
<image id="counter-prone" href="counter_prone.jpg" width="10"/>
<image id="counter-grenade" href="counter_grenade.jpg" width="10"/>
</defs>
<rect id="background"/>
<?xml version="1.0" standalone="yes"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 200 300">
<g class="gameboard">
<use href="mapsheets.svg#map2"/>
<use href="mapsheets.svg#map1" style="transform: translate(0, 390.25px);"/>
<use href="mapsheets.svg#map3" style="transform: translate(0, 780.5px);"/>
<rect id="dots" fill="url(#asterisk)"/>
<g id="firing-arcs">
<g id="shapes"/>
<g id="lines"/>
</g>
<use class="mapsheet" href="mapsheets.svg#map2"/>
<use class="mapsheet" href="mapsheets.svg#map1" style="transform: translate(0, 390.25px);"/>
<use class="mapsheet" href="mapsheets.svg#map3" style="transform: translate(0, 780.5px);"/>
<g class="start-locations" data-attacker-name="liao" data-defender-name="davion">
<g data-edge="north">
<g data-edge="north" style="--i: -2">
<g data-x="13">
<g class="counter" data-allegiance="attacker" data-number="1">
<use class="primary-weapon" href="counters.svg#blazer"/>
@ -114,7 +57,7 @@
</g>
</g>
</g>
<g data-edge="south">
<g data-edge="south" style="--i: 78">
<g data-x="13">
<g class="counter" data-allegiance="defender" data-number="1">
<use class="primary-weapon" href="#blazer"/>
@ -166,9 +109,7 @@
</g>
</g>
</g>
<g class="grid"/>
</g>
<script data-cols="33" data-rows="77" href="../../map.js"/>
<script data-cols="33" data-rows="77"/>
</svg>

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -1,67 +1,10 @@
<?xml version="1.0" standalone="no"?>
<svg viewBox="-10 -10 200 300" xmlns="http://www.w3.org/2000/svg">
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="../css/map.css" type="text/css" />
<style>
g[data-edge="north"] { --i: -2; }
g[data-edge="south"] { --i: 26; }
#background {
stroke: #304b75;
fill: #bacae3;
}
pattern use {
stroke: black;
stroke-width: 0.3px;
}
.cw-60-deg {
transform: rotate(60deg);
}
.ccw-60-deg {
transform: rotate(-60deg);
}
</style>
<defs>
<polygon id="hex" points="0,10 8.66,5 8.66,-5 0,-10 -8.66,-5 -8.66,5"/>
<line id="ast-line" x1="-1.2" y1="0" x2="1.2" y2="0"/>
<pattern id="asterisk" viewBox="-8.66 -15 17.32 30" width="17.32" height="30" patternUnits="userSpaceOnUse">
<use y="-15" href="#ast-line"/>
<use y="-15" style="transform-origin: 0 -15px;" class="cw-60-deg" href="#ast-line"/>
<use y="-15" style="transform-origin: 0 -15px;" class="ccw-60-deg" href="#ast-line"/>
<use y="15" href="#ast-line"/>
<use y="15" style="transform-origin: 0 15px;" class="cw-60-deg" href="#ast-line"/>
<use y="15" style="transform-origin: 0 15px;" class="ccw-60-deg" href="#ast-line"/>
<use x="8.66" href="#ast-line"/>
<use x="8.66" style="transform-origin: 8.66px 0;" class="cw-60-deg" href="#ast-line"/>
<use x="8.66" style="transform-origin: 8.66px 0;" class="ccw-60-deg" href="#ast-line"/>
<use x="-8.66" href="#ast-line"/>
<use x="-8.66" style="transform-origin: -8.66px 0;" class="cw-60-deg" href="#ast-line"/>
<use x="-8.66" style="transform-origin: -8.66px 0;" class="ccw-60-deg" href="#ast-line"/>
</pattern>
<image id="counter-prone" href="counter_prone.jpg" width="10"/>
<image id="counter-grenade" href="counter_grenade.jpg" width="10"/>
</defs>
<rect id="background"/>
<?xml version="1.0" standalone="yes"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 200 300">
<g class="gameboard">
<use href="mapsheets.svg#map4"/>
<rect id="dots" fill="url(#asterisk)"/>
<g id="firing-arcs">
<g id="shapes"/>
<g id="lines"/>
</g>
<use class="mapsheet" href="mapsheets.svg#map4"/>
<g class="start-locations" data-attacker-name="liao" data-defender-name="davion">
<g data-edge="north">
<g data-edge="north" style="--i: -2">
<g data-x="13">
<g class="counter" data-allegiance="attacker" data-number="1">
<use class="primary-weapon" href="counters.svg#blazer"/>
@ -112,7 +55,7 @@
</g>
</g>
</g>
<g data-edge="south">
<g data-edge="south" style="--i: 26">
<g data-x="13">
<g class="counter" data-allegiance="defender" data-number="1">
<use class="primary-weapon" href="#blazer"/>
@ -164,9 +107,7 @@
</g>
</g>
</g>
<g class="grid"/>
</g>
<script data-cols="33" data-rows="25" href="../../map.js"/>
<script data-cols="33" data-rows="25"/>
</svg>

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -0,0 +1,60 @@
<?xml version="1.0" standalone="no"?>
<svg viewBox="-10 -10 200 300" xmlns="http://www.w3.org/2000/svg">
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="../css/map.css" type="text/css" />
<style>
#background {
stroke: #304b75;
fill: #bacae3;
}
pattern use {
stroke: black;
stroke-width: 0.3px;
}
.cw-60-deg {
transform: rotate(60deg);
}
.ccw-60-deg {
transform: rotate(-60deg);
}
</style>
<defs>
<polygon id="hex" points="0,10 8.66,5 8.66,-5 0,-10 -8.66,-5 -8.66,5"/>
<line id="ast-line" x1="-1.2" y1="0" x2="1.2" y2="0"/>
<pattern id="asterisk" viewBox="-8.66 -15 17.32 30" width="17.32" height="30" patternUnits="userSpaceOnUse">
<use y="-15" href="#ast-line"/>
<use y="-15" style="transform-origin: 0 -15px;" class="cw-60-deg" href="#ast-line"/>
<use y="-15" style="transform-origin: 0 -15px;" class="ccw-60-deg" href="#ast-line"/>
<use y="15" href="#ast-line"/>
<use y="15" style="transform-origin: 0 15px;" class="cw-60-deg" href="#ast-line"/>
<use y="15" style="transform-origin: 0 15px;" class="ccw-60-deg" href="#ast-line"/>
<use x="8.66" href="#ast-line"/>
<use x="8.66" style="transform-origin: 8.66px 0;" class="cw-60-deg" href="#ast-line"/>
<use x="8.66" style="transform-origin: 8.66px 0;" class="ccw-60-deg" href="#ast-line"/>
<use x="-8.66" href="#ast-line"/>
<use x="-8.66" style="transform-origin: -8.66px 0;" class="cw-60-deg" href="#ast-line"/>
<use x="-8.66" style="transform-origin: -8.66px 0;" class="ccw-60-deg" href="#ast-line"/>
</pattern>
<image id="counter-prone" href="counter_prone.jpg" width="10"/>
<image id="counter-grenade" href="counter_grenade.jpg" width="10"/>
</defs>
<rect id="background"/>
<g class="gameboard">
<rect id="dots" fill="url(#asterisk)"/>
<g id="firing-arcs">
<g id="shapes"/>
<g id="lines"/>
</g>
<g class="grid"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -145,7 +145,7 @@
Loading...
</div>
<object type="image/svg+xml"></object>
<object type="image/svg+xml" data="assets/images/scenario_template.svg"></object>
<div id="status">
<span id="hex-counter">Distance: <span id="hex-count">-</span></span>

View File

@ -40,16 +40,134 @@ const mapPlaceholder = document.querySelector('.map-placeholder'),
let mapResourceEl = document.querySelector('object');
async function requestScenario(url) {
return new Promise((res, rej) => {
const request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'document';
request.onload = function() {
if (request.status === 200) {
res(request.response);
} else {
rej(Error('Image didn\'t load successfully; error code:' + request.statusText));
}
};
request.onerror = function() {
rej(Error('There was a network error.'));
};
request.send();
});
}
const scenarioRequest = requestScenario(map);
function loadScenario(data) {
const current = document.querySelector('object');
const next = document.createElement('object');
next.setAttribute('type', 'image/svg+xml');
next.style.opacity = 0;
next.addEventListener('load', load);
mapPlaceholder.style.opacity = 1;
next.data = data;
mapPlaceholder.after(next);
current.remove();
// const current = document.querySelector('object');
// const next = document.createElement('object');
// next.setAttribute('type', 'image/svg+xml');
// next.style.opacity = 0;
// next.addEventListener('load', load);
// mapPlaceholder.style.opacity = 1;
// next.data = data;
// mapPlaceholder.after(next);
// current.remove();
buildScenario(requestScenario(data));
}
async function buildScenario(req) {
console.log('req', req);
const svg = scenarioTemplate.querySelector('svg').cloneNode(true);
document.querySelector('object').contentDocument.querySelector('svg').replaceWith(svg);
const startLocs = svg.querySelector('.start-locations');
const scenario = await req;
console.log(scenario);
const gb = svg.querySelector('.gameboard');
const grid = svg.querySelector('.grid');
const externalResourceEls = Array.from(scenario.querySelectorAll('use[href*=".svg"'));
const refs = externalResourceEls.reduce((acc, el) => {
const href = el.getAttributeNS(null, 'href');
const [filename] = href.match(/.+\.svg/);
const fragmentIdentifier = href.split('.svg').pop();
(acc[filename] ??= new Set()).add(fragmentIdentifier);
el.setAttributeNS(null, 'href', fragmentIdentifier);
return acc;
}, {});
await Promise.all(
Object.keys(refs).map(filename => requestScenario(`assets/images/${filename}`))
).then(result => {
const defs = svg.querySelector('defs');
Object.keys(refs).forEach((filename, index) => {
const external = result[index];
refs[filename].forEach(fragmentIdentifier => {
external
.querySelectorAll(`${fragmentIdentifier} use`)
.forEach(el => refs[filename].add(el.getAttributeNS(null, 'href')));
});
const refsQuery = [...refs[filename]].join(', ');
external.querySelectorAll(refsQuery).forEach(node => defs.append(node));
});
});
scenario.querySelectorAll('use.mapsheet').forEach(el => gb.prepend(el));
grid.before(scenario.querySelector('.start-locations'));
const scenarioGrid = scenario.querySelector('.grid');
console.log('scenarioGrid', scenarioGrid);
if (scenarioGrid) {
grid.replaceWith(svg.ownerDocument.importNode(scenarioGrid, true));
}
async function loadScript() {
return new Promise((resolve, reject) => {
const scriptEl = document.createElementNS("http://www.w3.org/2000/svg", 'script');
// const scriptEl = svg.ownerDocument.importNode(scenario.querySelector('script'));
scriptEl.onload = () => {
console.log('map.js loaded');
resolve();
};
scriptEl.onerror = () => {
reject(Error('Script failed to load.'));
};
const oldScript = scenario.querySelector('script');
if ('cols' in oldScript.dataset && 'rows' in oldScript.dataset) {
scriptEl.dataset.rows = oldScript.dataset.rows;
scriptEl.dataset.cols = oldScript.dataset.cols;
}
scriptEl.setAttributeNS(null, 'href', '../../map.js');
svg.append(scriptEl);
});
}
await loadScript();
// this.style.opacity = 1;
// mapPlaceholder.style.opacity = 0;
panzoom.start(svg);
gameboard.start(svg);
recordSheet.start(startLocs, gameboard.getUnits());
}
function updateTurnCounter() {
@ -91,23 +209,82 @@ function roll(die) {
return numsAsWords[getRandomIntInclusive(0, numsAsWords.length - 1)];
}
function load() {
let scenarioTemplate;
async function load() {
const svg = this.contentDocument.querySelector('svg'),
startLocs = svg.querySelector('.start-locations')
// , scriptEl = this.contentDocument.querySelector('script')
;
scenarioTemplate = this.contentDocument.cloneNode(svg);
buildScenario(scenarioRequest);
// const scenario = await scenarioRequest;
// const gb = svg.querySelector('.gameboard');
// const grid = svg.querySelector('.grid');
// const useEls = svg.querySelectorAll('use[href*=".svg"]');
// const externalResourceEls = Array.from(scenario.querySelectorAll('use[href*=".svg"'));
// console.log(useEls);
// const refs = externalResourceEls.reduce((acc, el) => {
// const href = el.getAttributeNS(null, 'href');
// const [filename] = href.match(/.+\.svg/);
// const fragmentIdentifier = href.split('.svg').pop();
// [...new Set([...useEls].map(el => el.getAttributeNS(null, 'href').match(/^(.*?)\.svg/g).at(0)))].forEach(f => {
// const name = `../assets/images/${f}`;
// import(name);
// console.log(f);
// (acc[filename] ??= new Set()).add(fragmentIdentifier);
// el.setAttributeNS(null, 'href', fragmentIdentifier);
// return acc;
// }, {});
// await Promise.all(
// Object.keys(refs).map(filename => requestScenario(`assets/images/${filename}`))
// ).then(result => {
// const defs = svg.querySelector('defs');
// Object.keys(refs).forEach((filename, index) => {
// const external = result[index];
// refs[filename].forEach(fragmentIdentifier => {
// external
// .querySelectorAll(`${fragmentIdentifier} use`)
// .forEach(el => refs[filename].add(el.getAttributeNS(null, 'href')));
// });
// const refsQuery = [...refs[filename]].join(', ');
// external.querySelectorAll(refsQuery).forEach(node => defs.append(node));
// });
// });
// scenario.querySelectorAll('use.mapsheet').forEach(el => gb.prepend(el));
// grid.before(scenario.querySelector('.start-locations'));
// async function loadScript() {
// return new Promise((resolve, reject) => {
// const scriptEl = document.createElementNS("http://www.w3.org/2000/svg", 'script');
// // const scriptEl = svg.ownerDocument.importNode(scenario.querySelector('script'));
// scriptEl.onload = () => {
// console.log('map.js loaded');
// resolve();
// };
// scriptEl.onerror = () => {
// reject(Error('Script failed to load.'));
// };
// scriptEl.dataset.rows = scenario.querySelector('script').dataset.rows;
// scriptEl.dataset.cols = scenario.querySelector('script').dataset.cols;
// scriptEl.setAttributeNS(null, 'href', '../../map.js');
// svg.append(scriptEl);
// });
// }
// await loadScript();
this.style.opacity = 1;
mapPlaceholder.style.opacity = 0;
// URL.revokeObjectURL(this.data);
// const linkEl = document.createElement('link');
// linkEl.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
// linkEl.setAttribute('rel', 'stylesheet');
@ -116,25 +293,13 @@ function load() {
// linkEl.onload = function (e) {
// console.log('map.css loaded');
// if (scriptEl) {
// scriptEl.onload = function () {
// console.log('map.js loaded');
// };
// scriptEl.setAttribute('href', '../../map.js');
// }
// };
// svg.prepend(linkEl);
this.style.opacity = 1;
mapPlaceholder.style.opacity = 0;
URL.revokeObjectURL(this.data);
panzoom.start(svg);
gameboard.start(svg);
recordSheet.start(startLocs, gameboard.getUnits());
// panzoom.start(svg);
// gameboard.start(svg);
// recordSheet.start(startLocs, gameboard.getUnits());
}
document.querySelectorAll('.end-turn').forEach(el =>
@ -199,7 +364,19 @@ document.querySelector('#upload-save').addEventListener('click', () => {
document.querySelector('input[type="file"]').addEventListener('change', e => {
const [file] = fileInputEl.files;
loadScenario(URL.createObjectURL(file))
let reader = new FileReader();
reader.onload = function () {
const parser = new DOMParser();
const doc = parser.parseFromString(reader.result, "image/svg+xml");
buildScenario(doc);
};
reader.readAsText(file);
// loadScenario(URL.createObjectURL(file));
});
document.querySelector('#roll-dice').addEventListener('click', () => {
@ -221,8 +398,9 @@ mapSelectDialog
.changeMapOnConfirm(loadScenario);
mapResourceEl.addEventListener('load', load);
mapResourceEl.data = map;
mapResourceEl = null;
// mapResourceEl.data = map;
// mapResourceEl = null;
dice.forEach(el => {
el.classList.add(roll(d6));

View File

@ -1,124 +1,6 @@
<?xml version="1.0" standalone="no"?>
<svg viewBox="-150 -150 600 800" xmlns="http://www.w3.org/2000/svg">
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="../css/map.css" type="text/css" />
<style>
g[data-edge="north"] { --i: -2; }
g[data-edge="south"] { --i: 52; }
#background {
stroke: #304b75;
fill: #bacae3;
}
pattern use {
stroke: black;
stroke-width: 0.3px;
}
.cw-60-deg {
transform: rotate(60deg);
}
.ccw-60-deg {
transform: rotate(-60deg);
}
</style>
<defs>
<polygon id="hex" points="0,10 8.66,5 8.66,-5 0,-10 -8.66,-5 -8.66,5"/>
<line id="ast-line" x1="-1.2" y1="0" x2="1.2" y2="0"/>
<pattern id="asterisk" viewBox="-8.66 -15 17.32 30" width="17.32" height="30" patternUnits="userSpaceOnUse">
<use y="-15" href="#ast-line"/>
<use y="-15" style="transform-origin: 0 -15px;" class="cw-60-deg" href="#ast-line"/>
<use y="-15" style="transform-origin: 0 -15px;" class="ccw-60-deg" href="#ast-line"/>
<use y="15" href="#ast-line"/>
<use y="15" style="transform-origin: 0 15px;" class="cw-60-deg" href="#ast-line"/>
<use y="15" style="transform-origin: 0 15px;" class="ccw-60-deg" href="#ast-line"/>
<use x="8.66" href="#ast-line"/>
<use x="8.66" style="transform-origin: 8.66px 0;" class="cw-60-deg" href="#ast-line"/>
<use x="8.66" style="transform-origin: 8.66px 0;" class="ccw-60-deg" href="#ast-line"/>
<use x="-8.66" href="#ast-line"/>
<use x="-8.66" style="transform-origin: -8.66px 0;" class="cw-60-deg" href="#ast-line"/>
<use x="-8.66" style="transform-origin: -8.66px 0;" class="ccw-60-deg" href="#ast-line"/>
</pattern>
<circle id="counter-base" style="r: inherit;" cx="0" cy="0" r="5"/>
<g style="r: inherit;" id="number-1">
<use style="r: inherit;" href="#counter-base"/>
<text style="fill: var(--text-fill); transform: translateY(var(--translateY))">1</text>
</g>
<g style="r: inherit;" id="number-2">
<use style="r: inherit;" href="#counter-base"/>
<text style="fill: var(--text-fill); transform: translateY(var(--translateY))">2</text>
</g>
<g style="r: inherit;" id="number-3">
<use style="r: inherit;" href="#counter-base"/>
<text style="fill: var(--text-fill); transform: translateY(var(--translateY))">3</text>
</g>
<g style="r: inherit;" id="number-4">
<use style="r: inherit;" href="#counter-base"/>
<text style="fill: var(--text-fill); transform: translateY(var(--translateY))">4</text>
</g>
<g style="r: inherit;" id="number-5">
<use style="r: inherit;" href="#counter-base"/>
<text style="fill: var(--text-fill); transform: translateY(var(--translateY))">5</text>
</g>
<g style="r: inherit;" id="number-6">
<use style="r: inherit;" href="#counter-base"/>
<text style="fill: var(--text-fill); transform: translateY(var(--translateY))">6</text>
</g>
<g style="r: inherit;" id="number-7">
<use style="r: inherit;" href="#counter-base"/>
<text style="fill: var(--text-fill); transform: translateY(var(--translateY))">7</text>
</g>
<g id="semi-auto">
<line x1="-2" y1="1" x2="2" y2="1"/>
<line x1="-2" y1="2" x2="2" y2="2"/>
</g>
<g id="auto">
<line x1="-2" y1="0" x2="2" y2="0"/>
<line x1="-2" y1="1" x2="2" y2="1"/>
<line x1="-2" y1="2" x2="2" y2="2"/>
</g>
<g id="rifle" style="r: inherit;" class="weapon-symbol">
<use style="r: inherit;" href="#counter-base"/>
<use href="#semi-auto"/>
<line x1="0" y1="-5" x2="0" y2="5"/>
<polyline style="fill: none;" points="-2,-3.5 0,-5 2,-3.5"/>
</g>
<g id="smg" style="r: inherit;" class="weapon-symbol">
<use style="r: inherit;" href="#counter-base"/>
<use href="#auto"/>
<line x1="0" y1="-5" x2="0" y2="4.5"/>
<line x1="-2" y1="4.5" x2="2" y2="4.5"/>
</g>
<g id="blazer" style="r: inherit;" class="weapon-symbol">
<use style="r: inherit;" href="#counter-base"/>
<use href="#auto"/>
<polyline points="0,-5 0,-3 -3,-2.5 3,-1.5 0,-1 0,2.5 -3,3, 3,4 0,4.5 0,5"/>
<polyline points="-2,-3.5 0,-5 2,-3.5"/>
</g>
<image id="counter-prone" href="counter_prone.jpg" width="10"/>
<image id="counter-grenade" href="counter_grenade.jpg" width="10"/>
</defs>
<rect id="background"/>
<?xml version="1.0" standalone="yes"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 200 300">
<g class="gameboard">
<rect id="dots" fill="url(#asterisk)"/>
<g id="firing-arcs">
<g id="shapes"/>
<g id="lines"/>
</g>
<g class="grid">
<g data-y="0">
<g data-x="0"><use href="#hex"/></g>
@ -129,9 +11,9 @@
<g data-x="0"><use href="#hex"/></g>
<g data-x="1"><use href="#hex"/>
<g class="counter" data-allegiance="attacker" data-number="1">
<use class="primary-weapon" href="#rifle"/>
<use class="troop-number" href="#number-1"/>
<use class="squad-number" href="#number-1"/>
<use class="primary-weapon" href="counters.svg#rifle"/>
<use class="troop-number" href="counters.svg#number-1"/>
<use class="squad-number" href="counters.svg#number-1"/>
</g>
</g>
<g data-x="2"><use href="#hex"/></g>
@ -144,5 +26,5 @@
</g>
</g>
<script href="../../map.js"></script>
<script/>
</svg>

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 991 B