Skip to content

Commit

Permalink
feat(map): add basic display of solar system maps
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelMakesGames committed Sep 2, 2024
1 parent 482acf6 commit 005f3bb
Show file tree
Hide file tree
Showing 9 changed files with 660 additions and 157 deletions.
6 changes: 6 additions & 0 deletions src/renderer/src/intl/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ export default {
select_save: 'Select a save in the top left',
loading: 'This could take a few seconds',
error: 'Something has gone wrong',
click_to_view_system: 'Click to open map',
},
// various generic messages
generic: {
enabled: 'Enabled',
disabled: 'Disabled',
back_button: 'Back',
cancel_button: 'Cancel',
close_button: 'Close',
loading: 'Loading...',
Expand Down Expand Up @@ -257,6 +259,7 @@ export default {
advancedBorder: 'Advanced Border Settings',
starscape: 'Starscape',
legend: 'Legend',
solarSystemMap: 'Solar System Maps',
},
mapMode: 'Map Mode',
mapModePointOfView: 'Point of View',
Expand Down Expand Up @@ -402,6 +405,9 @@ export default {
legendBorderStroke: 'Border',
legendBorderColor: 'Border Color',
legendBackgroundColor: 'Background Color',
systemMapOrbitStroke: 'Orbit Lines',
systemMapOrbitColor: 'Orbit Lines Color',
systemMapPlanetScale: 'Planet Scale',
appLocale: 'StellarMaps Language',
appLocale_tooltip:
'Join the Discord server (link in the top bar) if you want to help translate!',
Expand Down
144 changes: 90 additions & 54 deletions src/renderer/src/lib/ExportModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
getToastStore,
localStorageStore,
} from '@skeletonlabs/skeleton';
import { onDestroy } from 'svelte';
import { t } from '../intl';
import type { GameState } from './GameState';
import type { GalacticObject, GameState } from './GameState';
import convertSvgToPng from './convertSvgToPng';
import type { MapData } from './map/data/processMapData';
import { getBackgroundColor, getFillColorAttributes, resolveColor } from './map/mapUtils';
import SolarSystemMap from './map/solarSystemMap/SolarSystemMap.svelte';
import processStarScape from './map/starScape/renderStarScape';
import { mapSettings } from './settings';
import stellarMapsApi from './stellarMapsApi';
Expand All @@ -19,10 +21,26 @@
const _props = $$props; // this suppresses warning about unknown prop 'parent'
const modalStore = getModalStore();
const toastStore = getToastStore();
const svg: SVGGElement = $modalStore[0]?.meta?.svg;
const galaxyMapSvg: SVGElement = $modalStore[0]?.meta?.svg;
const colors: Record<string, string> = $modalStore[0]?.meta?.colors;
const mapData: MapData = $modalStore[0]?.meta?.mapData;
const gameState: GameState = $modalStore[0]?.meta?.gameState;
const openedSystem: GalacticObject | undefined = $modalStore[0]?.meta?.openedSystem;
const solarSystemMapTarget = document.createElement('div');
const solarSystemMap = openedSystem
? new SolarSystemMap({
target: solarSystemMapTarget,
props: {
id: 'exportSystemMap',
colors: colors,
gameState: gameState,
system: openedSystem,
exportMode: true,
},
})
: null;
onDestroy(() => solarSystemMap?.$destroy());
const defaultExportSettings = {
lockAspectRatio: true,
Expand Down Expand Up @@ -99,39 +117,44 @@
}
async function exportPng() {
const backgroundImageUrl = await processStarScape(
gameState,
$mapSettings,
colors,
const backgroundImageUrl = openedSystem
? undefined
: await processStarScape(
gameState,
$mapSettings,
colors,
{
left: mapLeft,
top: mapTop,
width: mapWidth,
height: mapHeight,
},
{
width: imageWidth,
height: imageHeight,
},
);
const buffer = await convertSvgToPng(
solarSystemMap ? (solarSystemMapTarget.firstChild as SVGElement) : galaxyMapSvg,
{
left: mapLeft,
top: mapTop,
width: mapWidth,
height: mapHeight,
outputWidth: imageWidth,
outputHeight: imageHeight,
backgroundImageUrl,
backgroundColor: getBackgroundColor(colors, $mapSettings),
},
{
width: imageWidth,
height: imageHeight,
},
);
const buffer = await convertSvgToPng(svg, {
left: mapLeft,
top: mapTop,
width: mapWidth,
height: mapHeight,
outputWidth: imageWidth,
outputHeight: imageHeight,
backgroundImageUrl,
backgroundColor: getBackgroundColor(colors, $mapSettings),
}).then((blob) => blob.arrayBuffer());
).then((blob) => blob.arrayBuffer());
const savePath = await stellarMapsApi.dialog.save({
defaultPath: await stellarMapsApi.path.join(
await stellarMapsApi.path.pictureDir(),
'map.png',
),
filters: [{ extensions: ['png'], name: 'Image' }],
});
if (savePath && svg) {
if (savePath && galaxyMapSvg) {
await stellarMapsApi.fs.writeBinaryFile(savePath, new Uint8Array(buffer)).then(() => {
toastStore.trigger({
background: 'variant-filled-success',
Expand All @@ -154,54 +177,59 @@
}
async function exportSvg() {
svg.setAttribute('width', imageWidth.toString());
svg.setAttribute('height', imageHeight.toString());
svg.setAttribute('viewBox', `${mapLeft} ${mapTop} ${mapWidth} ${mapHeight}`);
const svgToExport = openedSystem
? (solarSystemMapTarget.firstChild as SVGElement)
: galaxyMapSvg;
svgToExport.setAttribute('width', imageWidth.toString());
svgToExport.setAttribute('height', imageHeight.toString());
svgToExport.setAttribute('viewBox', `${mapLeft} ${mapTop} ${mapWidth} ${mapHeight}`);
const bgImage = document.createElementNS('http://www.w3.org/2000/svg', 'image');
bgImage.setAttribute('x', mapLeft.toString());
bgImage.setAttribute('y', mapTop.toString());
bgImage.setAttribute('width', mapWidth.toString());
bgImage.setAttribute('height', mapHeight.toString());
bgImage.setAttribute(
'xlink:href',
await processStarScape(
gameState,
$mapSettings,
colors,
{
left: mapLeft,
top: mapTop,
width: mapWidth,
height: mapHeight,
},
{
width: imageWidth,
height: imageHeight,
},
),
);
svg.prepend(bgImage);
if (!openedSystem) {
bgImage.setAttribute('x', mapLeft.toString());
bgImage.setAttribute('y', mapTop.toString());
bgImage.setAttribute('width', mapWidth.toString());
bgImage.setAttribute('height', mapHeight.toString());
bgImage.setAttribute(
'xlink:href',
await processStarScape(
gameState,
$mapSettings,
colors,
{
left: mapLeft,
top: mapTop,
width: mapWidth,
height: mapHeight,
},
{
width: imageWidth,
height: imageHeight,
},
),
);
svgToExport.prepend(bgImage);
}
const bgRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
bgRect.setAttribute('x', mapLeft.toString());
bgRect.setAttribute('y', mapTop.toString());
bgRect.setAttribute('width', mapWidth.toString());
bgRect.setAttribute('height', mapHeight.toString());
bgRect.setAttribute('fill', getBackgroundColor(colors, $mapSettings));
svg.prepend(bgRect);
svgToExport.prepend(bgRect);
const svgString = svg.outerHTML;
svg.removeChild(bgImage);
svg.removeChild(bgRect);
const svgString = svgToExport.outerHTML;
if (!openedSystem) svgToExport.removeChild(bgImage);
svgToExport.removeChild(bgRect);
const savePath = await stellarMapsApi.dialog.save({
defaultPath: await stellarMapsApi.path
.join(await stellarMapsApi.path.pictureDir(), 'map.svg')
.catch(() => ''),
filters: [{ extensions: ['svg'], name: 'Image' }],
});
if (savePath && svg) {
if (savePath && svgToExport) {
await stellarMapsApi.fs.writeFile(savePath, svgString).then(() => {
toastStore.trigger({
background: 'variant-filled-success',
Expand Down Expand Up @@ -377,7 +405,15 @@
role="button"
style:cursor="pointer"
>
{#if mapData}
{#if openedSystem}
<SolarSystemMap
system={openedSystem}
{colors}
{gameState}
id="systemMapPreview"
previewMode
/>
{:else if mapData}
{#each mapData.borders as border}
<path
d={border.borderPath}
Expand Down
15 changes: 15 additions & 0 deletions src/renderer/src/lib/GameState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ const galacticObjectSchema = z
.optional(),
planet: z.number().optional(),
fleet_presence: z.array(z.number()).default([]),
asteroid_belts: z
.array(
z.object({
type: z.string(),
inner_radius: z.number(),
}),
)
.default([]),
$multiKeys: z
.object({
planet: preprocessedArray(z.number()).optional(),
Expand All @@ -89,6 +97,13 @@ const planetSchema = z.object({
species_information: z
.record(z.string(), z.object({ num_pops: z.number(), num_enslaved: z.number().optional() }))
.optional(),
planet_size: z.number(),
planet_class: z.string(),
entity_name: z.string().optional(),
orbit: z.number(),
moon_of: z.number().optional(),
has_ring: z.boolean().optional(),
coordinate: z.object({ x: z.number(), y: z.number() }),
});

/**
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/lib/map/Glow.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script lang="ts">
export let enabled: boolean;
export let filterId = 'glow';
</script>

{#if enabled}
<slot filter="url(#glow)" />
<slot filter="url(#{filterId})" />
{/if}
<slot filter="" />
Loading

0 comments on commit 005f3bb

Please sign in to comment.