index : btroops | |
Virtual board game-aid for BattleTroops, an infantry combat simulator wargame published by FASA in 1989. |
aboutsummaryrefslogtreecommitdiff |
diff options
-rw-r--r-- | public/assets/css/radial.css | 325 | ||||
-rw-r--r-- | public/radial.html | 329 | ||||
-rw-r--r-- | src/radial.js | 43 |
3 files changed, 358 insertions, 339 deletions
diff --git a/public/assets/css/radial.css b/public/assets/css/radial.css new file mode 100644 index 0000000..b00df20 --- /dev/null +++ b/public/assets/css/radial.css @@ -0,0 +1,325 @@ +polygon { + fill: inherit; + stroke: inherit; + stroke-width: 0.25px; +} + +svg { + border: 1px solid slategray; + fill: none; +} + +text { + font-size: 4px; + text-anchor: middle; + user-select: none; + font-family: sans-serif; + fill: black; + /* display: none; */ +} + +use[href="#hex"] { + stroke: #666; + /* fill: wheat; */ + fill: navajowhite; + /* fill: url(#asterisk); */ +} + +.building .doors { + display: inline; + fill: none; + fill-opacity: 1; + stroke: #ff9900; + stroke-width: 2.5; + stroke-linecap: square; + stroke-dasharray: none; + stroke-opacity: 1; +} + +.building .floor, +.terrain .floor { + opacity: 1; + fill: #ffffff; + fill-opacity: 0.5; + stroke: none; +} + +.building .inner-wall { + fill: none; + stroke: #ffffff; + stroke-width: 1; + stroke-linecap: square; +} + +.building .outer-wall { + fill: none; + stroke: #000000; + stroke-width: 2; + stroke-linecap: square; +} + +.view-elevation-roof .doors, +.view-elevation-roof .inner-wall, +.view-elevation-roof .outer-wall { + display: none; +} + +/* [class^="elevation"] { + display: none; +} + +[class="elevation-0"] { + display: inline; +} */ + +.elevation-basement { + fill: lightgray; + display: none; +} + +.elevation-0 use[href="#hex"] { + /* fill: green; */ +} + +.elevation-1, +.elevation-2 { + display: inline; +} + +.elevation-1 use[href="#hex"] { + fill: lightblue; +} + +.elevation-2 use[href="#hex"] { + fill: lightpink; +} + +.building .elevation-1 { + fill: lightblue; +} + +.elevation-roof { + display: none; +} + +.building .elevation-basement use { + fill: lightgray; +} + +.building .elevation-0 use { + fill: white; +} + +.building .elevation-1 use { + fill: lightblue; +} + +.building .elevation-2 use { + fill: lightgreen; +} + +.building .elevation-3 use { + fill: lightpink; +} + +.view-elevation-roof .floor { + fill: darkgray; +} + +.building .elevation-1 { + display: none; +} + +.building > * { + display: none; +} + +[data-view-elevation="-1"] [class^="elevation"] { + display: none; +} + +[data-view-elevation="-1"] .building > * { + display: none; +} + +[data-view-elevation="-1"] .building > .elevation-basement, +[data-view-elevation="-1"] .building > .elevation-basement ~ .structure { + display: inline; +} + +[data-view-elevation="0"] .building .elevation-0, +[data-view-elevation="0"] .building .elevation-0 ~ .structure { + display: inline; +} + +[data-view-elevation="1"] .building .elevation-1, +[data-view-elevation="1"] .building .elevation-1 ~ .structure { + display: inline; +} + +[data-view-elevation="1"] .building .elevation-1 + .structure [class*='wall'] { + display: none; +} + +[data-view-elevation="1"] .building .elevation-1 + .structure .floor { + fill: gray; +} + +[data-view-elevation="2"] .building .elevation-2, +[data-view-elevation="2"] .building .elevation-2 ~ .structure { + display: inline; +} + +[data-view-elevation="2"] .building .elevation-2 + .structure [class*='wall'] { + display: none; +} + +[data-view-elevation="2"] .building .elevation-2 + .structure .floor { + fill: gray; +} + +[data-view-elevation="3"] .building .elevation-3, +[data-view-elevation="3"] .building .elevation-3 ~ .structure { + display: inline; +} + +[data-view-elevation="3"] .building .elevation-3 + .structure [class*='wall'] { + display: none; +} + +[data-view-elevation="3"] .building .elevation-3 + .structure .floor { + fill: gray; +} + +[data-view-elevation="0"] .elevation-0 { + display: inline; +} + +[data-view-elevation="1"] > .elevation-0, +[data-view-elevation="1"] > .elevation-1 { + display: inline; +} + +[data-view-elevation="1"] .building .elevation-1 { + display: inline; +} + +.view-elevation-0 .elevation-0 { + display: inline; +} + +.view-elevation-1 .elevation-0 { + display: inline; +} + +.view-elevation-1 .elevation-1 { + display: inline; +} + +.view-elevation-1 .building .elevation-0 { + display: none; +} + +.view-elevation-1 .building .elevation-1 { + /* display: none; */ +} + +.view-elevation-roof .elevation-roof { + display: inline; +} + +.view-elevation-basement [class^="elevation"] { + display: none; +} + +.view-elevation-basement .elevation-basement { + display: inline; +} + +.view-elevation-basement .doors { + display: none; +} + +.building [class*="elevation"] use { + /* fill-opacity: 0.33; */ + stroke: black; +} + +.building { + /* display: none; */ + /* opacity: 0.2 */ +} + +#tree .trunk { + fill: brown; +} + +#tree .branches { + fill: rgb(141, 202, 141); + stroke: green; +} + +#bush { + fill: rgb(141, 202, 141); + stroke: green; + stroke-width: 0.5px; + transform: scale(0.9); +} + +.select-elevation { + position: fixed; + right: 0; + top: 50%; + margin-right: 10px; + background-color: #FFFFFF99; + border: 1px solid gray; + padding: 2px; + font-family: sans-serif; + font-size: 10pt; +} + +.select-elevation label { + display: block; + margin: 2px 0; + text-align: center; + border: 1px solid transparent; + user-select: none; +} + +.select-elevation input { + display: none; +} + +input:checked+label { + border: 1px solid salmon; + border-radius: 3px; + background-color: #cdd9e9; +} + +[class^="part"] use { + fill-opacity: 0.75; +} + +.part-1 use { + fill: lightseagreen; +} + +.part-2 use { + fill: lightyellow; +} + +.part-3 use { + fill: lightblue; +} + +.part-4 use { + fill: lightsteelblue; +} + +.part-5 use { + fill: lightsalmon; +} + +.part-6 use { + fill: lightgreen; +} diff --git a/public/radial.html b/public/radial.html index a7f137e..96dd569 100644 --- a/public/radial.html +++ b/public/radial.html @@ -2,332 +2,7 @@ <html> <head> - <style> - polygon { - fill: inherit; - stroke: inherit; - stroke-width: 0.25px; - } - - svg { - border: 1px solid slategray; - fill: none; - } - - text { - font-size: 4px; - text-anchor: middle; - user-select: none; - font-family: sans-serif; - fill: black; - /* display: none; */ - } - - use[href="#hex"] { - stroke: #666; - /* fill: wheat; */ - fill: navajowhite; - /* fill: url(#asterisk); */ - } - - .building .doors { - display: inline; - fill: none; - fill-opacity: 1; - stroke: #ff9900; - stroke-width: 2.5; - stroke-linecap: square; - stroke-dasharray: none; - stroke-opacity: 1; - } - - .building .floor { - opacity: 1; - fill: #ffffff; - fill-opacity: 0.5; - stroke: none; - } - - .building .inner-wall { - fill: none; - stroke: #ffffff; - stroke-width: 1; - stroke-linecap: square; - } - - .building .outer-wall { - fill: none; - stroke: #000000; - stroke-width: 2; - stroke-linecap: square; - } - - .view-elevation-roof .doors, - .view-elevation-roof .inner-wall, - .view-elevation-roof .outer-wall { - display: none; - } - - /* [class^="elevation"] { - display: none; - } - - [class="elevation-0"] { - display: inline; - } */ - - .elevation-basement { - fill: lightgray; - display: none; - } - - .elevation-0 use[href="#hex"] { - /* fill: green; */ - } - - .elevation-1, - .elevation-2 { - display: inline; - } - - .elevation-1 use[href="#hex"] { - fill: lightblue; - } - - .elevation-2 use[href="#hex"] { - fill: lightpink; - } - - .building .elevation-1 { - fill: lightblue; - } - - .elevation-roof { - display: none; - } - - .building .elevation-basement use { - fill: lightgray; - } - - .building .elevation-0 use { - fill: white; - } - - .building .elevation-1 use { - fill: lightblue; - } - - .building .elevation-2 use { - fill: lightgreen; - } - - .building .elevation-3 use { - fill: lightpink; - } - - .view-elevation-roof .floor { - fill: darkgray; - } - - .building .elevation-1 { - display: none; - } - - .building > * { - display: none; - } - - [data-view-elevation="-1"] [class^="elevation"] { - display: none; - } - - [data-view-elevation="-1"] .building > * { - display: none; - } - - [data-view-elevation="-1"] .building > .elevation-basement, - [data-view-elevation="-1"] .building > .elevation-basement ~ .structure { - display: inline; - } - - [data-view-elevation="0"] .building .elevation-0, - [data-view-elevation="0"] .building .elevation-0 ~ .structure { - display: inline; - } - - [data-view-elevation="1"] .building .elevation-1, - [data-view-elevation="1"] .building .elevation-1 ~ .structure { - display: inline; - } - - [data-view-elevation="1"] .building .elevation-1 + .structure [class*='wall'] { - display: none; - } - - [data-view-elevation="1"] .building .elevation-1 + .structure .floor { - fill: gray; - } - - [data-view-elevation="2"] .building .elevation-2, - [data-view-elevation="2"] .building .elevation-2 ~ .structure { - display: inline; - } - - [data-view-elevation="2"] .building .elevation-2 + .structure [class*='wall'] { - display: none; - } - - [data-view-elevation="2"] .building .elevation-2 + .structure .floor { - fill: gray; - } - - [data-view-elevation="3"] .building .elevation-3, - [data-view-elevation="3"] .building .elevation-3 ~ .structure { - display: inline; - } - - [data-view-elevation="3"] .building .elevation-3 + .structure [class*='wall'] { - display: none; - } - - [data-view-elevation="3"] .building .elevation-3 + .structure .floor { - fill: gray; - } - - [data-view-elevation="0"] .elevation-0 { - display: inline; - } - - [data-view-elevation="1"] > .elevation-0, - [data-view-elevation="1"] > .elevation-1 { - display: inline; - } - - [data-view-elevation="1"] .building .elevation-1 { - display: inline; - } - - .view-elevation-0 .elevation-0 { - display: inline; - } - - .view-elevation-1 .elevation-0 { - display: inline; - } - - .view-elevation-1 .elevation-1 { - display: inline; - } - - .view-elevation-1 .building .elevation-0 { - display: none; - } - - .view-elevation-1 .building .elevation-1 { - /* display: none; */ - } - - .view-elevation-roof .elevation-roof { - display: inline; - } - - .view-elevation-basement [class^="elevation"] { - display: none; - } - - .view-elevation-basement .elevation-basement { - display: inline; - } - - .view-elevation-basement .doors { - display: none; - } - - .building [class*="elevation"] use { - /* fill-opacity: 0.33; */ - stroke: black; - } - - .building { - /* display: none; */ - /* opacity: 0.2 */ - } - - #tree .trunk { - fill: brown; - } - - #tree .branches { - fill: rgb(141, 202, 141); - stroke: green; - } - - #bush { - fill: rgb(141, 202, 141); - stroke: green; - stroke-width: 0.5px; - transform: scale(0.9); - } - - .select-elevation { - position: fixed; - right: 0; - top: 50%; - margin-right: 10px; - background-color: #FFFFFF99; - border: 1px solid gray; - padding: 2px; - font-family: sans-serif; - font-size: 10pt; - } - - .select-elevation label { - display: block; - margin: 2px 0; - text-align: center; - border: 1px solid transparent; - user-select: none; - } - - .select-elevation input { - display: none; - } - - input:checked+label { - border: 1px solid salmon; - border-radius: 3px; - background-color: #cdd9e9; - } - - [class^="part"] use { - fill-opacity: 0.75; - } - - .part-1 use { - fill: lightseagreen; - } - - .part-2 use { - fill: lightyellow; - } - - .part-3 use { - fill: lightblue; - } - - .part-4 use { - fill: lightsteelblue; - } - - .part-5 use { - fill: lightsalmon; - } - - .part-6 use { - fill: lightgreen; - } - </style> + <link rel="stylesheet" href="assets/css/radial.css"> </head> <body> @@ -419,7 +94,7 @@ d="m -90.93,-112.5 h 51.96 l 8.66,15 h 95.26 l 8.66,-15 h 43.3 v 15 l -25.98,45 v 60 h 34.64 v 75 h -43.3 v -30 H 12.99 l -25.98,45 h -103.92 v -90 h 25.98 z m 77.94,30 v 15 h 69.28 v -15 m -86.6,37.5 v 7.5 m 0,-60 V -75 M 73.61,-112.5 V -75 M -90.93,-37.5 H 90.93 m 0,45 H -90.93 m 173.2,45 v -15 h 43.3 m -112.58,0 h -43.3 v 60 m 43.3,-45 v -45 m -69.28,30 h -60.62 m 60.62,30 h -60.62 m 60.62,-60 v 90" /> </g> - <g id="terrain"> + <g id="terrain" class="terrain"> <rect id="terrain-floor" class="floor" x="-52.75" y="-68" width="105.5" height="136" id="rect3415" /> <g id="terrain-trees"> <use href="#tree" transform="translate(-27,-45.25)" /> diff --git a/src/radial.js b/src/radial.js index 4812e1f..92e2ae9 100644 --- a/src/radial.js +++ b/src/radial.js @@ -364,9 +364,10 @@ let mapsheet1 = { grid: new Map(buildingHexes.bld6), position: rotate180({ q: -13, r: 7, s: 6 }) }, + ], + features: [ { type: 'terrain', - elevationLevels: range(0, 0), grid: generateRadialCoords( new Map(), { q: 0, r: 0, s: 0 }, @@ -503,16 +504,8 @@ function rotate180(coords) { }; } -function drawMapsheet(gameboard, { id, grid, buildings }, { q: pq, r: pr, s: ps }) { - const container = document.createElementNS(xmlns, 'g'); - container.id = id; - gameboard.appendChild(container); - - const gridContainer = document.createElementNS(xmlns, 'g'); - gridContainer.classList.add('elevation-0'); - container.appendChild(gridContainer); - - const buildingHexes = buildings.reduce((acc, building) => { +function drawBuildings(mapsheet, container, { q: pq, r: pr, s: ps }) { + return mapsheet.buildings.reduce((acc, building) => { const buildingContainer = document.createElementNS(xmlns, 'g'); buildingContainer.classList.add(`building`); buildingContainer.classList.add(building.type); @@ -549,12 +542,38 @@ function drawMapsheet(gameboard, { id, grid, buildings }, { q: pq, r: pr, s: ps return acc; }, new Map()); +} - grid = translateCoords(grid, ({ q, r, s }) => ({ q: q + pq, r: r + pr, s: s + ps })); +function drawMapsheet(gameboard, mapsheet, position) { + const container = document.createElementNS(xmlns, 'g'); + container.id = mapsheet.id; + gameboard.appendChild(container); + + const gridContainer = document.createElementNS(xmlns, 'g'); + gridContainer.classList.add('elevation-0'); + container.appendChild(gridContainer); + + const buildingHexes = drawBuildings(mapsheet, container, position); + + const grid = translateCoords(mapsheet.grid, ({ q, r, s }) => + ({ q: q + position.q, r: r + position.r, s: s + position.s }) + ); for ([coords, v] of buildingHexes) grid.delete(coords); drawHexes(gridContainer, grid, true); + (mapsheet.features || []).forEach(feature => { + const origin = feature.position({ q: 0, r: 0, s: 0 }); + const { x, y } = radialToScreenCoords({ q: origin.q + position.q, r: origin.r + position.r, s: origin.s + position.s }); + const use = document.createElementNS(xmlns, 'use'); + + use.setAttributeNS(null, 'href', `#${feature.type}`); + use.setAttributeNS(null, 'x', x); + use.setAttributeNS(null, 'y', y); + + gridContainer.appendChild(use); + }); + return new Map([...grid, ...buildingHexes]); // return { id, grid, buildings }; } |