index : btroops | |
Virtual board game-aid for BattleTroops, an infantry combat simulator wargame published by FASA in 1989. |
aboutsummaryrefslogtreecommitdiff |
diff options
author | Catalin Mititiuc <webdevcat@proton.me> | 2024-06-20 17:12:47 -0700 |
---|---|---|
committer | Catalin Mititiuc <webdevcat@proton.me> | 2024-06-20 17:12:47 -0700 |
commit | 505fc231508000dcc07d5ad52e3795eadb8464cf (patch) | |
tree | 5803b0778c99961e10764e2739613bbed62970f0 | |
parent | 53b18ca2b497a6c5db4c2d06a1d455693c8f0f28 (diff) |
Draw scenario mapsheet hexes with building hexes
-rw-r--r-- | public/radial.html | 128 | ||||
-rw-r--r-- | src/radial.js | 527 |
2 files changed, 385 insertions, 270 deletions
diff --git a/public/radial.html b/public/radial.html index e1dec38..a654979 100644 --- a/public/radial.html +++ b/public/radial.html @@ -23,6 +23,12 @@ /* display: none; */ } + use[href="#hex"] { + stroke: #666; + fill: wheat; + /* fill: url(#asterisk); */ + } + .elevation-basement { fill: lightgray; display: none; @@ -30,18 +36,15 @@ .elevation-1 { /* filter: blur(.5px); */ - /* opacity: 1; */ + /* opacity: 0.5; */ display: none; } - .buildings .elevation-1, - .building .elevation-1 { - /* display: none; */ - fill: lightgreen; - } + .elevation-1 use[href="#hex"] { + /* fill: green; */ + } .elevation-2 { - /* fill: rgb(240, 216, 172); */ opacity: 0.5; /* display: none; */ @@ -55,6 +58,12 @@ display: none; } + .buildings .elevation-1, + .building .elevation-1 { + /* display: none; */ + fill: lightgreen; + } + .building .doors { display: inline; fill: none; @@ -87,44 +96,42 @@ stroke-linecap: square; } - .building.view-elevation-roof .doors, - .building.view-elevation-roof .inner-wall, - .building.view-elevation-roof .outer-wall { + .view-elevation-roof .doors, + .view-elevation-roof .inner-wall, + .view-elevation-roof .outer-wall { display: none; } - .building .elevation-1 { - display: none; + .building .elevation-1 use { + fill: green; } - .building.view-elevation-roof .floor { + .view-elevation-roof .floor { fill: darkgray; } - .building.view-elevation-1 .elevation-1 { - display: inline; + .building .elevation-2 { + display: none; } - .building.view-elevation-2 .elevation-2 { + .view-elevation-1 .elevation-1 { display: inline; } - .building.view-elevation-roof .elevation-roof { + .view-elevation-2 .elevation-2 { display: inline; } - .building.view-elevation-basement .elevation-basement { + .view-elevation-roof .elevation-roof { display: inline; } - .building.view-elevation-basement .doors { - display: none; + .view-elevation-basement .elevation-basement { + display: inline; } - use[href="#hex"] { - stroke: #666; - fill: wheat; - /* fill: url(#asterisk); */ + .view-elevation-basement .doors { + display: none; } .building [class*="elevation"] use { @@ -136,7 +143,6 @@ /* display: none; */ /* opacity: 0.2 */ } - </style> </head> @@ -157,35 +163,59 @@ <use y="-15" x="15" transform="rotate(-60, 15, -15)" href="#ast-line" /> <use y="15" x="-15" transform="rotate(-60, -15, 15)" href="#ast-line" /> </pattern> - </defs> - <g id="building1" style="display: none" class="building view-elevation-1"> - <g transform="translate(-60.62, 105)"> - <path class="floor" d="M -38.969999,-67.499999 H 38.969999 V 67.499999 h -77.939998 z" /> - <path class="outer-wall" - d="m 38.969998,-7.500001 h -12.99 v 12.5 m -21.6499995,32.5 H 38.969998 m -34.6399995,30 v -60 h -8.66 v -45 m -8.6600005,105 v -45 h -25.979997 m 0,-89.999998 H 38.969999 V 67.499999 h -77.939998 z" /> - <path class="inner-wall" - d="m 38.969998,-7.500001 h -12.99 v 12.5 m -21.6499995,32.5 H 38.969998 m -34.6399995,30 v -60 h -8.66 v -45 m -8.6600005,105 v -45 h -25.979997 m 0,-89.999998 H 38.969999 V 67.499999 h -77.939998 z" /> + <g class="building2"> + <g data-grid-footprint="0,0,0:1,0,-1:-1,0,1:1,-1,0:-1,1,0:0,1,-1:0,-1,1:2,0,-2:2,-1,-1:1,1,-2:-2,0,2:-2,1,1:-1,-1,2:2,-2,0:1,-2,1:-2,2,0:-1,2,-1:0,2,-2:0,-2,2:3,-2,-1:1,2,-3:-3,2,1:-1,-2,3:3,-3,0:2,-3,1:1,-3,2:-3,3,0:-2,3,-1:-1,3,-2:0,3,-3:0,-3,3:4,-4,0:3,-4,1:2,-4,2:1,-4,3:-4,4,0:-3,4,-1:-2,4,-2:-1,4,-3:0,4,-4:0,-4,4:3,0,-3:2,1,-3:3,-1,-2:2,2,-4:1,3,-4:-3,0,3:-2,-1,3:-3,1,2:-4,2,2:-4,3,1"> + <path id="building2-floor" class="floor" + d="m 38.786985,67.5 17.32,-30 v -45 l -17.32,-30 v -30 h -77.94 v 30 l -17.32,30 v 45 l 17.32,30 z" /> + <path id="building2-outer-wall" class="outer-wall" + d="m -21.833015,67.5 v -60 m 17.3200004,-75 v 30 M 17.136985,15 4.146985,7.5 m 51.96,30 -12.99,-7.5 m -38.97,-67.5 v 45 h -60.62 m 17.32,-45 h 77.94 m -69.28,105 h 69.28 l 17.32,-30 v -45 l -17.32,-30 v -30 h -77.94 v 30 l -17.32,30 v 45 l 17.32,30 z" /> + <path id="building2-inner-wall" class="inner-wall" + d="m -21.833015,67.5 v -60 m 17.3200004,-75 v 30 M 17.136985,15 4.146985,7.5 m 51.96,30 -12.99,-7.5 m -38.97,-67.5 v 45 h -60.62 m 17.32,-45 h 77.94 m -69.28,105 h 69.28 l 17.32,-30 v -45 l -17.32,-30 v -30 h -77.94 v 30 l -17.32,30 v 45 l 17.32,30 z" /> + <path id="building2-doors" class="doors" + d="m 3.698745,-67.5 h 9.55648 m 7.76351,30 h 9.55648 M -4.9612546,67.5 H 4.595225 m -18.71725,-60 h 9.5564804 m -35.0357204,0 h 9.55648 m 33.74353,-75 h 9.55648 m -35.53648,30 h 9.55648 m 7.7635204,105 H 4.595225 m -18.71725,-60 h 9.5564804 m -35.0357204,0 h 9.55648" /> + </g> </g> - </g> + </defs> - <g id="building2" class="building view-elevation-1"> - <!-- <g transform="translate(-181.86, 105)"> --> - <g> - <path class="floor" - d="m 38.786985,67.5 17.32,-30 v -45 l -17.32,-30 v -30 h -77.94 v 30 l -17.32,30 v 45 l 17.32,30 z" /> - <path class="outer-wall" - d="m -21.833015,67.5 v -60 m 17.3200004,-75 v 30 M 17.136985,15 4.146985,7.5 m 51.96,30 -12.99,-7.5 m -38.97,-67.5 v 45 h -60.62 m 17.32,-45 h 77.94 m -69.28,105 h 69.28 l 17.32,-30 v -45 l -17.32,-30 v -30 h -77.94 v 30 l -17.32,30 v 45 l 17.32,30 z" /> - <path class="inner-wall" - d="m -21.833015,67.5 v -60 m 17.3200004,-75 v 30 M 17.136985,15 4.146985,7.5 m 51.96,30 -12.99,-7.5 m -38.97,-67.5 v 45 h -60.62 m 17.32,-45 h 77.94 m -69.28,105 h 69.28 l 17.32,-30 v -45 l -17.32,-30 v -30 h -77.94 v 30 l -17.32,30 v 45 l 17.32,30 z" /> - <path class="doors" - d="m 3.698745,-67.5 h 9.55648 m 7.76351,30 h 9.55648 M -4.9612546,67.5 H 4.595225 m -18.71725,-60 h 9.5564804 m -35.0357204,0 h 9.55648 m 33.74353,-75 h 9.55648 m -35.53648,30 h 9.55648 m 7.7635204,105 H 4.595225 m -18.71725,-60 h 9.5564804 m -35.0357204,0 h 9.55648" /> + <g class="gameboard view-elevation-1 view-elevation-2"> + <!-- <g class="grid"> --> + <!-- <g id="mapsheet2"> + <g class="grid"></g> + <g class="building building2" data-placement="7,7,-14"></g> + </g> + <g id="mapsheet3"> + <g class="grid"></g> + <g class="building building2" data-placement="0,0,0"></g> + </g> --> + <!-- <g id="mapsheet1" transform="translate(600)"></g> --> + <!-- <g id="mapsheet2" transform="translate(600, -394)"></g> --> + <!-- <g id="mapsheet3" transform="translate(600, 394)"></g> --> + <!-- </g> --> + + <!-- <g id="building1" style="display: none" class="building view-elevation-1"> + <g transform="translate(-60.62, 105)"> + <path class="floor" d="M -38.969999,-67.499999 H 38.969999 V 67.499999 h -77.939998 z" /> + <path class="outer-wall" + d="m 38.969998,-7.500001 h -12.99 v 12.5 m -21.6499995,32.5 H 38.969998 m -34.6399995,30 v -60 h -8.66 v -45 m -8.6600005,105 v -45 h -25.979997 m 0,-89.999998 H 38.969999 V 67.499999 h -77.939998 z" /> + <path class="inner-wall" + d="m 38.969998,-7.500001 h -12.99 v 12.5 m -21.6499995,32.5 H 38.969998 m -34.6399995,30 v -60 h -8.66 v -45 m -8.6600005,105 v -45 h -25.979997 m 0,-89.999998 H 38.969999 V 67.499999 h -77.939998 z" /> + </g> </g> - </g> - <!-- <g id="mapsheet1" transform="translate(600)"></g> - <g id="mapsheet2" transform="translate(600, -394)"></g> - <g id="mapsheet3" transform="translate(600, 394)"></g> --> + <g id="building2" style="display: none;" class="building"> + <g data-grid-footprint="0,0,0:1,0,-1:-1,0,1:1,-1,0:-1,1,0:0,1,-1:0,-1,1:2,0,-2:2,-1,-1:1,1,-2:-2,0,2:-2,1,1:-1,-1,2:2,-2,0:1,-2,1:-2,2,0:-1,2,-1:0,2,-2:0,-2,2:3,-2,-1:1,2,-3:-3,2,1:-1,-2,3:3,-3,0:2,-3,1:1,-3,2:-3,3,0:-2,3,-1:-1,3,-2:0,3,-3:0,-3,3:4,-4,0:3,-4,1:2,-4,2:1,-4,3:-4,4,0:-3,4,-1:-2,4,-2:-1,4,-3:0,4,-4:0,-4,4:3,0,-3:2,1,-3:3,-1,-2:2,2,-4:1,3,-4:-3,0,3:-2,-1,3:-3,1,2:-4,2,2:-4,3,1"> + <path class="floor" + d="m 38.786985,67.5 17.32,-30 v -45 l -17.32,-30 v -30 h -77.94 v 30 l -17.32,30 v 45 l 17.32,30 z" /> + <path class="outer-wall" + d="m -21.833015,67.5 v -60 m 17.3200004,-75 v 30 M 17.136985,15 4.146985,7.5 m 51.96,30 -12.99,-7.5 m -38.97,-67.5 v 45 h -60.62 m 17.32,-45 h 77.94 m -69.28,105 h 69.28 l 17.32,-30 v -45 l -17.32,-30 v -30 h -77.94 v 30 l -17.32,30 v 45 l 17.32,30 z" /> + <path class="inner-wall" + d="m -21.833015,67.5 v -60 m 17.3200004,-75 v 30 M 17.136985,15 4.146985,7.5 m 51.96,30 -12.99,-7.5 m -38.97,-67.5 v 45 h -60.62 m 17.32,-45 h 77.94 m -69.28,105 h 69.28 l 17.32,-30 v -45 l -17.32,-30 v -30 h -77.94 v 30 l -17.32,30 v 45 l 17.32,30 z" /> + <path class="doors" + d="m 3.698745,-67.5 h 9.55648 m 7.76351,30 h 9.55648 M -4.9612546,67.5 H 4.595225 m -18.71725,-60 h 9.5564804 m -35.0357204,0 h 9.55648 m 33.74353,-75 h 9.55648 m -35.53648,30 h 9.55648 m 7.7635204,105 H 4.595225 m -18.71725,-60 h 9.5564804 m -35.0357204,0 h 9.55648" /> + </g> + </g> --> + </g> </svg> <script src="radial.js"></script> </body> diff --git a/src/radial.js b/src/radial.js index 8142f77..42e2e34 100644 --- a/src/radial.js +++ b/src/radial.js @@ -15,7 +15,7 @@ const horzSpacing = hex.inradius; const vertSpacing = hex.circumradius * 3 / 2; -function toKey(q, r, s) { +function toKey({ q, r, s }) { return `${[q, r, s]}`; } @@ -27,40 +27,15 @@ function getNeighbors(coords) { const [q, r, s] = coords.split(',').map(n => +n); return [ - toKey(q + 1, r, s - 1), - toKey(q - 1, r, s + 1), - toKey(q + 1, r - 1, s), - toKey(q - 1, r + 1, s), - toKey(q, r + 1, s - 1), - toKey(q, r - 1, s + 1), + toKey({ q: q + 1, r: r, s: s - 1 }), + toKey({ q: q - 1, r: r, s: s + 1 }), + toKey({ q: q + 1, r: r - 1, s: s }), + toKey({ q: q - 1, r: r + 1, s: s }), + toKey({ q: q, r: r + 1, s: s - 1 }), + toKey({ q: q, r: r - 1, s: s + 1 }), ] } -// function generateRadialCoords(l, { q, r, s }, radius) { -// const origin = toKey(q, r, s); -// const list = new Map(l); -// const neighbors = new Set(); - -// let next = new Set(); - -// list.set(origin); -// next.add(origin); - -// for (let i = 0; i < radius; i++) { -// next.forEach(coords => { -// getNeighbors(coords).forEach(n => { -// list.set(n, null); -// neighbors.add(n); -// }); -// }); - -// next = new Set(neighbors); -// neighbors.clear(); -// } - -// return list; -// } - function generateRadialCoordsRect({ rows, columns, odd = false, equal = true } = {}, { q = 0, r = 0, s = 0 } = {}) { const list = new Map(); @@ -77,7 +52,7 @@ function generateRadialCoordsRect({ rows, columns, odd = false, equal = true } = ds = ds + alternating; } - list.set(toKey(q + dq, r + dr, s + ds), null); + list.set(toKey({ q: q + dq, r: r + dr, s: s + ds }), null); } if (!equal) { @@ -90,7 +65,7 @@ function generateRadialCoordsRect({ rows, columns, odd = false, equal = true } = ds = ds + alternating; } - list.set(toKey(q + dq, r + dr, s + ds), null); + list.set(toKey({ q: q + dq, r: r + dr, s: s + ds }), null); } } } @@ -123,21 +98,26 @@ function addHexText(q, r, s, v) { return [qText, rText, sText, vText]; } -function drawHexes(el, list, renderText = false) { - for ([key, v] of list) { - const [q, r, s] = key.split(',').map(n => +n); +function radialToScreenCoords({ q, r, s }) { + let x; - let x; + if (q === s) + x = 0; + else if (sameSigns(q, s)) + x = Math.abs(q - s); + else + x = Math.abs(q) + Math.abs(s); - if (q === s) - x = 0; - else if (sameSigns(q, s)) - x = Math.abs(q - s); - else - x = Math.abs(q) + Math.abs(s); + x = (q > s ? -1 : 1) * x * horzSpacing; + y = r * vertSpacing; + + return { x, y }; +} - x = (q > s ? -1 : 1) * x * horzSpacing; - y = r * vertSpacing; +function drawHexes(el, list, renderText = false) { + for ([key, v] of list) { + const [q, r, s] = key.split(',').map(n => +n); + const { x, y } = radialToScreenCoords({ q, r, s }); const cell = document.createElementNS(xmlns, 'g'); cell.setAttributeNS(null, 'transform', `translate(${x}, ${y})`); @@ -152,7 +132,7 @@ function drawHexes(el, list, renderText = false) { } } -function translateRadialCoords({ q, r, s }, direction, distance) { +function translateRadialCoords({ q, r, s }, direction, distance = 1) { return { q: q + direction.q * distance, r: r + direction.r * distance, @@ -160,6 +140,103 @@ function translateRadialCoords({ q, r, s }, direction, distance) { }; } + +function generateRadialCoords(l, { q, r, s }, { left, top, right, bottom }, offset) { + const origin = toKey({ q, r, s }); + const list = new Map(l); + + list.set(origin, 0); + let queue = [origin]; + + while (queue.length > 0) { + const v = queue.shift(); + + getNeighbors(v).forEach(w => { + const [wq, wr, ws] = w.split(',').map(n => +n); + const rDist = Math.abs(wr - r); + const alternating = rDist % 2; + const dr = (rDist + alternating) / 2; + + let dLeft = left; + let dRight = right; + + if (['left', 'both'].includes(offset)) dRight -= alternating; + if (['right', 'both'].includes(offset)) dLeft -= alternating; + + if ([ + !list.has(w), + wr < bottom + r && wr > -top + r, + wq > -dRight + q - dr && wq < dLeft + q + dr, + ws > -dLeft + s - dr && ws < dRight + s + dr, + ].every(v => v)) { + list.set(w, dr); + queue.push(w); + } + }); + } + + return list; +} + +function translateCoords(map, translator) { + const translated = new Map(); + + for ([key, val] of map) { + const [q, r, s] = key.split(',').map(n => +n); + translated.set(toKey(translator({ q, r, s })), val); + } + + return translated; +} + +function placeBuilding(buildingSelector, mapsheetSelector) { + const building = svg.querySelector(buildingSelector); + const bld2grid = document.createElementNS(xmlns, 'g'); + const bld2origin = { q: 0, r: 0, s: 0 }; + + const bld2map2 = svg.querySelector(`${mapsheetSelector} ${buildingSelector}`); + const [q, r, s] = bld2map2.dataset.placement.split(',').map(n => +n); + const map2bld2place = { q, r, s }; + + bld2hexes = building.querySelector('[data-grid-footprint]').dataset.gridFootprint.split(':').map(coords => { + const [q, r, s] = coords.split(',').map(n => +n); + const { q: tq, r: tr, s: ts } = translateRadialCoords({ q, r, s }, map2bld2place); + + return [toKey({ q: tq, r: tr, s: ts }), null]; + }); + + const bld2screenCoords = radialToScreenCoords(translateRadialCoords(bld2origin, map2bld2place)); + const bld2structure = document.createElementNS(xmlns, 'g'); + bld2structure.setAttributeNS(null, 'transform', `translate(${bld2screenCoords.x}, ${bld2screenCoords.y})`) + + building.querySelectorAll('[data-grid-footprint] > *').forEach(el => { + const use = document.createElementNS(xmlns, 'use'); + use.setAttributeNS(null, 'href', `#${el.id}`); + el.classList.forEach(className => use.classList.add(className)); + bld2structure.appendChild(use); + }); + + drawHexes(bld2grid, new Map(bld2hexes), true); + + const bld2elvBasement = bld2grid.cloneNode(true); + bld2elvBasement.classList.add('elevation-basement'); + bld2map2.appendChild(bld2elvBasement); + + const bld2elv1 = bld2grid.cloneNode(true); + bld2elv1.classList.add('elevation-1'); + bld2map2.appendChild(bld2elv1); + + const bld2elv2 = bld2grid.cloneNode(true); + bld2elv2.classList.add('elevation-2'); + bld2map2.appendChild(bld2elv2); + + const bld2elvRoof = bld2grid.cloneNode(true); + bld2elvRoof.classList.add('elevation-roof'); + bld2map2.appendChild(bld2elvRoof); + + bld2map2.appendChild(bld2structure); +} + // const building1 = generateRadialCoordsRect({ rows: 5, columns: 3, equal: false }, { q: 7, r: -4, s: -3 }); // const building2 = generateRadialCoordsRect({ rows: 4, columns: 3, odd: true }, { q: 0, r: -4, s: 4 }); // const building3 = generateRadialCoords(new Map(), { q: -1, r: 2, s: -1 }, 1); @@ -214,160 +291,99 @@ function translateRadialCoords({ q, r, s }, direction, distance) { // bldElevation2.classList.add('elevation-2'); // buildingCoords.forEach(building => drawHexes(bldElevation2, building)); -const elevation1 = document.createElementNS(xmlns, 'g'); -elevation1.classList.add('elevation-1'); - // buildings.appendChild(bldElevationBasement); // buildings.appendChild(bldElevation1); // buildings.appendChild(bldElevation2); -const buildingBlah = svg.querySelector('#building2'); +const elevation1 = document.createElementNS(xmlns, 'g'); +elevation1.classList.add('elevation-1'); -const bld2grid = document.createElementNS(xmlns, 'g'); +const elevation2 = document.createElementNS(xmlns, 'g'); +elevation2.classList.add('elevation-2'); -// const bld2hexes = new Map([ -// ...generateRadialCoordsRect({ rows: 9, columns: 4, odd: true, equal: false }, { q: 0, r: 0, s: 0 }), -// ...generateRadialCoordsRect({ rows: 5, columns: 1 }, { q: 10, r: 6, s: -16 }), -// ...generateRadialCoordsRect({ rows: 5, columns: 1, odd: true }, { q: 5, r: 6, s: -11 }), -// ]); +const buildingHexes = {}; -let bld2hexes = generateRadialCoords(new Map(), { q: 0, r: 0, s: 0 }, { left: 3, top: 5, right: 3, bottom: 5 }, 'both'); +buildingHexes.bld2 = generateRadialCoords( + new Map(), + { q: 0, r: 0, s: 0 }, + { left: 3, top: 5, right: 3, bottom: 5 }, + 'both' +); -bld2hexes = generateRadialCoords( - bld2hexes, +buildingHexes.bld2 = generateRadialCoords( + buildingHexes.bld2, translateRadialCoords({ q: 0, r: 0, s: 0 }, { q: 1, r: 0, s: -1 }, 3), { left: 1, top: 2, right: 1, bottom: 4 }, 'right' ); -bld2hexes = generateRadialCoords( - bld2hexes, +buildingHexes.bld2 = generateRadialCoords( + buildingHexes.bld2, translateRadialCoords({ q: 0, r: 0, s: 0 }, { q: 1, r: 0, s: -1 }, -3), { left: 1, top: 2, right: 1, bottom: 4 }, 'left' ); +buildingHexes.bld1 = generateRadialCoords( + new Map(), + { q: 0, r: 0, s: 0 }, + { left: 3, top: 5, right: 3, bottom: 5 }, + 'both' +); -console.log(bld2hexes); - -drawHexes(bld2grid, bld2hexes); - -const bld2elvBasement = bld2grid.cloneNode(true); -bld2elvBasement.classList.add('elevation-basement'); -buildingBlah.appendChild(bld2elvBasement); - -const bld2elv1 = bld2grid.cloneNode(true); -bld2elv1.classList.add('elevation-1'); -buildingBlah.appendChild(bld2elv1); - -const bld2elv2 = bld2grid.cloneNode(true); -bld2elv2.classList.add('elevation-2'); -buildingBlah.appendChild(bld2elv2); - -const bld2elvRoof = bld2grid.cloneNode(true); -bld2elvRoof.classList.add('elevation-roof'); -buildingBlah.appendChild(bld2elvRoof); - - -const bld1 = svg.querySelector('#building1'); - -const bld1grid = document.createElementNS(xmlns, 'g'); -const bld1hexes = generateRadialCoordsRect({ rows: 9, columns: 4, odd: true, equal: false }, { q: 4, r: 3, s: -7 }); -// drawHexes(bld1grid, bld1hexes); - -const bld1elv1 = bld1grid.cloneNode(true); -bld1elv1.classList.add('elevation-1'); -bld1.appendChild(bld1elv1); - -function generateRadialCoords(l, { q, r, s }, { left, top, right, bottom }, offset) { - const origin = toKey(q, r, s); - const list = new Map(l); - - list.set(origin, 0); - let queue = [origin]; +buildingHexes.bld3 = generateRadialCoords( + new Map(), + { q: 0, r: 0, s: 0 }, + { left: 2, top: 3, right: 2, bottom: 4 } +); - while (queue.length > 0) { - const v = queue.shift(); +buildingHexes.bld4 = generateRadialCoords( + new Map(), + { q: 0, r: 0, s: 0 }, + { left: 2, top: 4, right: 3, bottom: 5 }, + 'left' +); - getNeighbors(v).forEach(w => { - const [wq, wr, ws] = w.split(',').map(n => +n); - const rDist = Math.abs(wr - r); - const alternating = rDist % 2; - const dr = (rDist + alternating) / 2; +buildingHexes.bld5 = generateRadialCoords( + new Map(), + { q: 0, r: 0, s: 0 }, + { left: 5, top: 3, right: 4, bottom: 2 } +); - let dLeft = left; - let dRight = right; +buildingHexes.bld6 = generateRadialCoords( + new Map(), + { q: 0, r: 0, s: 0 }, + { left: 1, top: 5, right: 2, bottom: 4 } +); - if (['left', 'both'].includes(offset)) dRight -= alternating; - if (['right', 'both'].includes(offset)) dLeft -= alternating; +buildingHexes.bld7 = generateRadialCoords( + new Map(), + { q: 0, r: 0, s: 0 }, + { left: 7, top: 4, right: 7, bottom: 3 }, + 'left' +); - if ([ - !list.has(w), - wr < bottom + r && wr > -top + r, - wq > -dRight + q - dr && wq < dLeft + q + dr, - ws > -dLeft + s - dr && ws < dRight + s + dr, - ].every(v => v)) { - list.set(w, dr); - queue.push(w); - } - }); - } +buildingHexes.bld7 = generateRadialCoords( + buildingHexes.bld7, + { q: 1, r: -4, s: 3 }, + { left: 5, top: 1, right: 6, bottom: 1 } +); - return list; -} +buildingHexes.bld7 = generateRadialCoords( + buildingHexes.bld7, + { q: 5, r: 3, s: -8 }, + { left: 1, top: 1, right: 2, bottom: 1 } +); -const elevation2 = document.createElementNS(xmlns, 'g'); -elevation2.classList.add('elevation-2'); +buildingHexes.bld7 = generateRadialCoords( + buildingHexes.bld7, + { q: -4, r: 3, s: 1 }, + { left: 3, top: 1, right: 4, bottom: 1 } +); const grid = generateRadialCoordsRect({ rows: 25, columns: 33 }, { q: 22, r: -12, s: -10 }); // const grid = generateRadialCoordsRect({ rows: 52, columns: 33 }, translateRadialCoords({ q: 22, r: -12, s: -10 }, { q: 1, r: -2, s: 1 }, 7)); -const mapsheet2BuildingData = [ - [{ rows: 4, columns: 8, equal: false }, { q: 18, r: -8, s: -10 }], - [{ rows: 8, columns: 2, equal: false }, { q: 9, r: -10, s: 1 }], - - [{ rows: 6, columns: 13, odd: true }, { q: 2, r: -8, s: 6 }], - [{ rows: 1, columns: 10 }, { q: -1, r: -9, s: 10 }], - [{ rows: 1, columns: 2 }, { q: -1, r: -2, s: 3 }], - [{ rows: 1, columns: 6 }, { q: -8, r: -2, s: 10 }], - - [{ rows: 8, columns: 4, odd: true }, { q: -5, r: 3, s: 2 }], - [{ rows: 6, columns: 3, equal: false }, { q: -12, r: 3, s: 9 }], - - [{ rows: 9, columns: 4, odd: true, equal: false }, { q: 11, r: 3, s: -14 }], - [{ rows: 5, columns: 1 }, { q: 10, r: 6, s: -16 }], - [{ rows: 5, columns: 1, odd: true }, { q: 5, r: 6, s: -11 }], - - [{ rows: 9, columns: 4, odd: true, equal: false }, { q: 4, r: 3, s: -7 }] -]//.map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, 7)]) -; - -// const bld2hexes = [ -// generateRadialCoordsRect({ rows: 9, columns: 4, odd: true, equal: false }, { q: 11, r: 3, s: -14 }), -// generateRadialCoordsRect({ rows: 5, columns: 1 }, { q: 10, r: 6, s: -16 }), -// generateRadialCoordsRect({ rows: 5, columns: 1, odd: true }, { q: 5, r: 6, s: -11 }), -// ] -// const bld1hexes = generateRadialCoordsRect({ rows: 9, columns: 4, odd: true, equal: false }, { q: 4, r: 3, s: -7 }); - -const mapsheet3BuildingData = [ - [{ rows: 6, columns: 3, equal: false, odd: true }, { q: 20, r: -10, s: -10 }], - [{ rows: 4, columns: 8, equal: false }, { q: 11, r: 6, s: -17 }], - [{ rows: 8, columns: 2, equal: false, odd: true }, { q: 3, r: 3, s: -6 }], - - [{ rows: 9, columns: 4, odd: true, equal: false }, { q: 13, r: -10, s: -3 }], - [{ rows: 5, columns: 1, odd: true }, { q: 8, r: -9, s: 1 }], - [{ rows: 5, columns: 1 }, { q: 13, r: -9, s: -4 }], - - [{ rows: 9, columns: 4, odd: true, equal: false }, { q: 2, r: -9, s: 7 }], - - [{ rows: 8, columns: 4, odd: true }, { q: -6, r: -9, s: 15 }], - - [{ rows: 6, columns: 13, odd: true }, { q: -4, r: 5, s: -1 }], - [{ rows: 1, columns: 10 }, { q: -7, r: 4, s: 3 }], - [{ rows: 1, columns: 2 }, { q: -7, r: 11, s: -4 }], - [{ rows: 1, columns: 6 }, { q: -14, r: 11, s: 3 }], -]; - const mapsheet1BuildingData = [ [{ rows: 6, columns: 3, equal: false }, { q: -4, r: -8, s: 12 }], [{ rows: 8, columns: 2, equal: false, odd: true }, { q: -10, r: 4, s: 6 }], @@ -383,79 +399,148 @@ const mapsheet1BuildingData = [ ]; const mapsheet1BuildingCoords = mapsheet1BuildingData.map(([size, start]) => generateRadialCoordsRect(size, start)); -const mapsheet2BuildingCoords = mapsheet2BuildingData.map(([size, start]) => generateRadialCoordsRect(size, start)); -const mapsheet3BuildingCoords = mapsheet3BuildingData.map(([size, start]) => generateRadialCoordsRect(size, start)); -const list = generateRadialCoords(new Map(), { q: 0, r: 0, s: 0 }, { left: 17, top: 13, right: 17, bottom: 14 }); +const mapsheet2BuildingCoords = [ + translateCoords(buildingHexes.bld1, ({ q, r, s }) => ({ q: q, r: r + 7, s: s - 7 })), + translateCoords(buildingHexes.bld2, ({ q, r, s }) => ({ q: q + 7, r: r + 7, s: s - 14 })), + translateCoords(buildingHexes.bld3, ({ q, r, s }) => ({ q: q - 14, r: r + 5, s: s + 9 })), + translateCoords(buildingHexes.bld4, ({ q, r, s }) => ({ q: q - 8, r: r + 6, s: s + 2 })), + translateCoords(buildingHexes.bld5, ({ q, r, s }) => ({ q: q + 13, r: r - 6, s: s - 7 })), + translateCoords(buildingHexes.bld6, ({ q, r, s }) => ({ q: q + 7, r: r - 6, s: s - 1 })), + translateCoords(buildingHexes.bld7, ({ q, r, s }) => ({ q: q - 6, r: r - 5, s: s + 11 })), +]; -const mapsheet1 = new Map(list); -const mapsheet2 = new Map(list); -const mapsheet3 = new Map(list); +const mapsheet3BuildingCoords = [ + translateCoords(buildingHexes.bld1, ({ q, r, s }) => ({ q: q - 2, r: r - 5, s: s + 7 })), + translateCoords(buildingHexes.bld2, ({ q, r, s }) => ({ q: -s + 9, r: -r - 6, s: -q - 3 })), + translateCoords(buildingHexes.bld3, ({ q, r, s }) => ({ q: -s + 17, r: -r - 7, s: -q - 10 })), + translateCoords(buildingHexes.bld4, ({ q, r, s }) => ({ q: q - 9, r: r - 6, s: s + 15 })), + translateCoords(buildingHexes.bld5, ({ q, r, s }) => ({ q: q + 6, r: r + 8, s: s - 14 })), + translateCoords(buildingHexes.bld6, ({ q, r, s }) => ({ q: -s + 1, r: -r + 6, s: -q - 7 })), + translateCoords(buildingHexes.bld7, ({ q, r, s }) => ({ q: q - 12, r: r + 8, s: s + 4 })), +] -mapsheet1BuildingCoords.forEach(building => { - for ([coords, v] of building) mapsheet1.delete(coords); -}); +// drawHexes(elevation2, translateCoords(buildingHexes.bld7, ({ q, r, s }) => ({ q: q - 12, r: r + 8, s: s + 4 })), true); +// drawHexes(elevation1, buildingHexes.bld7, true); + +const mapsheetHexCoords = generateRadialCoords(new Map(), { q: 0, r: 0, s: 0 }, { left: 17, top: 13, right: 17, bottom: 14 }); + +const mapsheet1hexCoords = new Map(mapsheetHexCoords); +const mapsheet2hexCoords = new Map(mapsheetHexCoords); +const mapsheet3hexCoords = new Map(mapsheetHexCoords); mapsheet2BuildingCoords.forEach(building => { - for ([coords, v] of building) mapsheet2.delete(coords); + for ([coords, v] of building) mapsheet2hexCoords.delete(coords); }); mapsheet3BuildingCoords.forEach(building => { - for ([coords, v] of building) mapsheet3.delete(coords); + for ([coords, v] of building) mapsheet3hexCoords.delete(coords); }); function coordsScenario2() { const grid = generateRadialCoords(new Map(), { q: 0, r: 0, s: 0 }, { left: 17, top: 39, right: 17, bottom: 40 }); - mapsheet2BuildingData - .map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, 13)]) - .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { - for ([coords, v] of building) grid.delete(coords); - } - ); + // mapsheet2BuildingCoords + // // .map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, 13)]) + // .map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, 13)]) + // .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { + // for ([coords, v] of building) grid.delete(coords); + // } + // ); + + // mapsheet3BuildingCoords + // .map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, -13)]) + // .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { + // for ([coords, v] of building) grid.delete(coords); + // } + // ); + + // mapsheet1BuildingData + // .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { + // for ([coords, v] of building) grid.delete(coords); + // } + // ); + + return new Map([...mapsheet2hexCoords]); +} - mapsheet3BuildingData - .map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, -13)]) - .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { - for ([coords, v] of building) grid.delete(coords); - } - ); +// drawHexes(elevation1, coordsScenario1(), true); - mapsheet1BuildingData - .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { - for ([coords, v] of building) grid.delete(coords); - } - ); +const gameboard = svg.querySelector('.gameboard'); - return grid; -} +function drawScenario1() { + const mapsheet2container = document.createElementNS(xmlns, 'g'); + mapsheet2container.id = 'mapsheet2'; + gameboard.appendChild(mapsheet2container); -function coordsScenario1() { - const grid = generateRadialCoords(new Map(), { q: 0, r: 0, s: 0 }, { left: 17, top: 27, right: 17, bottom: 26 }); + const mapsheet3container = document.createElementNS(xmlns, 'g'); + mapsheet3container.id = 'mapsheet3'; + gameboard.appendChild(mapsheet3container); - mapsheet2BuildingData - .map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, 7)]) - .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { - for ([coords, v] of building) grid.delete(coords); - } - ); + const [map2elevation1, map3elevation1] = [mapsheet2container, mapsheet3container].map(el => { + const hexContainer = document.createElementNS(xmlns, 'g'); + hexContainer.classList.add('elevation-1'); + el.appendChild(hexContainer); + return hexContainer; + }); - mapsheet3BuildingData - .map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, -6)]) - .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { - for ([coords, v] of building) grid.delete(coords); - } - ); + [ + [map2elevation1, mapsheet2hexCoords, ({ q, r, s }) => ({ q: q + 7, r: r - 14, s: s + 7 })], + [map3elevation1, mapsheet3hexCoords, ({ q, r, s }) => ({ q: q - 6, r: r + 12, s: s - 6 })], + ].forEach(([el, coords, translator]) => drawHexes(el, translateCoords(coords, translator), true)); + + mapsheet2BuildingCoords.forEach((buildingCoords, index) => { + const buildingContainer = document.createElementNS(xmlns, 'g'); + buildingContainer.classList.add(`building`); + buildingContainer.classList.add(`building${index}`); + mapsheet2container.appendChild(buildingContainer); + + const translatedCoords = translateCoords(buildingCoords, ({ q, r, s }) => + ({ q: q + 7, r: r - 14, s: s + 7 }) + ); + + ['elevation-1', 'elevation-2', 'elevation-basement'].forEach(elevation => { + const hexContainer = document.createElementNS(xmlns, 'g'); + hexContainer.classList.add(elevation); + buildingContainer.appendChild(hexContainer); - return grid; + drawHexes(hexContainer, translatedCoords, true); + }); + }); + + mapsheet3BuildingCoords.forEach((buildingCoords, index) => { + const buildingContainer = document.createElementNS(xmlns, 'g'); + buildingContainer.classList.add(`building`); + buildingContainer.classList.add(`building${index}`); + mapsheet3container.appendChild(buildingContainer); + + const translatedCoords = translateCoords(buildingCoords, ({ q, r, s }) => + ({ q: q - 6, r: r + 12, s: s - 6 }) + ); + + ['elevation-1', 'elevation-2', 'elevation-basement'].forEach(elevation => { + const hexContainer = document.createElementNS(xmlns, 'g'); + hexContainer.classList.add(elevation); + buildingContainer.appendChild(hexContainer); + + drawHexes(hexContainer, translatedCoords, true); + }); + }); } -drawHexes(elevation1, coordsScenario1(), true); +// const gameboardGrid = svg.querySelector('.grid'); + +drawScenario1(); // drawHexes(document.querySelector('#mapsheet1'), mapsheet1, true); -// drawHexes(document.querySelector('#mapsheet2'), mapsheet2, true); -// drawHexes(document.querySelector('#mapsheet3'), mapsheet3, true); -const defs = svg.querySelector('defs'); +// placeBuilding('.building2', '#mapsheet2'); +// drawHexes(document.querySelector('#mapsheet2 .grid'), mapsheet2, true); + +// placeBuilding('.building2', '#mapsheet3'); +// drawHexes(document.querySelector('#mapsheet3 .grid'), mapsheet3, true); + + // defs.after(elevation2); -defs.after(elevation1); +// gameboardGrid.appendChild(elevation1); +// gameboardGrid.appendChild(elevation2); |