Skip to content

Commit 918cb83

Browse files
feat(map,data): add system labels
1 parent 46830c2 commit 918cb83

8 files changed

Lines changed: 103 additions & 13 deletions

File tree

src/renderer/src/intl/en-US.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,21 @@ export default {
223223
striped: 'Striped',
224224
cloudy: 'Cloudy',
225225
},
226+
system_names: {
227+
none: 'None',
228+
country_capitals: 'Country Capitals',
229+
sector_capitals: 'Country and Sector Capitals',
230+
colonized: 'Colonized Systems',
231+
all: 'All Systems',
232+
},
226233
},
227234
// labels and tooltips for various settings
228235
setting: {
229236
group: {
230237
borders: 'Borders',
231238
unions: 'Union Mode',
232239
countryLabels: 'Country Labels',
240+
systemLabels: 'System Labels',
233241
systemIcons: 'System Icons',
234242
hyperlanes: 'Hyperlanes',
235243
bypassLinks: 'Bypass Links',
@@ -262,6 +270,9 @@ export default {
262270
countryEmblemsMinSize: 'Emblem Min Size',
263271
countryEmblemsMaxSize: 'Emblem Max Size',
264272
labelsAvoidHoles: 'Avoid Holes in Border',
273+
systemNames: 'System Names',
274+
systemNamesFont: 'Font',
275+
systemNamesFontSize: 'Font Size',
265276
countryCapitalIcon: 'Country Capital',
266277
sectorCapitalIcon: 'Sector Capital',
267278
populatedSystemIcon: 'Populated System',

src/renderer/src/lib/map/SystemIcons.svelte

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,31 @@
100100
});
101101
return { center, left, right, top, bottom, system };
102102
}
103+
104+
function getIconsBottom(systemIcons: ReturnType<typeof getSystemIcons>): number {
105+
return Math.max(
106+
systemIcons.center
107+
? systemIcons.center.y + systemIcons.center.size / 2
108+
: systemIcons.system.y,
109+
...systemIcons.left.map((i) => i.y + i.size / 2),
110+
...systemIcons.right.map((i) => i.y + i.size / 2),
111+
...systemIcons.top.map((i) => i.y + i.size / 2),
112+
...systemIcons.bottom.map((i) => i.y + i.size / 2),
113+
);
114+
}
115+
116+
function shouldShowLabel(system: MapData['systems'][number]) {
117+
if ($mapSettings.systemNames === 'none') return false;
118+
if ($mapSettings.systemNames === 'all') return true;
119+
if ($mapSettings.systemNames === 'countryCapitals' && system.isCountryCapital) return true;
120+
if (
121+
$mapSettings.systemNames === 'sectorCapitals' &&
122+
(system.isCountryCapital || system.isSectorCapital)
123+
)
124+
return true;
125+
if ($mapSettings.systemNames === 'colonized' && system.isColonized) return true;
126+
return false;
127+
}
103128
</script>
104129

105130
{#each data.systems
@@ -120,4 +145,18 @@
120145
})}
121146
/>
122147
{/each}
148+
{#if shouldShowLabel(systemIcons.system)}
149+
<text
150+
x={systemIcons.system.x}
151+
y={getIconsBottom(systemIcons) + $mapSettings.systemNamesFontSize / 4}
152+
text-anchor="middle"
153+
dominant-baseline="hanging"
154+
font-size={$mapSettings.systemNamesFontSize}
155+
fill="white"
156+
font-family={$mapSettings.systemNamesFont}
157+
style:text-shadow="0px 0px 3px black"
158+
>
159+
{systemIcons.system.name}
160+
</text>
161+
{/if}
123162
{/each}

src/renderer/src/lib/map/data/processLabels.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import polylabel from 'polylabel';
33
import type { GameState } from '../../GameState';
44
import type { MapSettings } from '../../settings';
55
import type processBorders from './processBorders';
6-
import type processNames from './processNames';
76
import type processSystemOwnership from './processSystemOwnership';
87
import type processTerraIncognita from './processTerraIncognita';
98
import {
@@ -37,7 +36,7 @@ export default function processLabels(
3736
countryToGeojson: Record<number, PolygonalFeature>,
3837
unionLeaderToUnionMembers: Record<number, Set<number>>,
3938
borders: ReturnType<typeof processBorders>,
40-
countryNames: Awaited<ReturnType<typeof processNames>>,
39+
countryNames: Record<number, string>,
4140
knownCountries: ReturnType<typeof processTerraIncognita>['knownCountries'],
4241
ownedSystemPoints: ReturnType<typeof processSystemOwnership>['ownedSystemPoints'],
4342
) {

src/renderer/src/lib/map/data/processMapData.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export default async function processMapData(
4040
cached(processEmblems),
4141
Object.values(gameState.country),
4242
);
43-
const countryNamesPromise = timeItAsync('names', cached(processNames), gameState, language);
43+
const namesPromise = timeItAsync('names', cached(processNames), gameState, language);
4444

4545
const getSystemCoordinates = timeIt(
4646
'system coordinates',
@@ -145,7 +145,7 @@ export default async function processMapData(
145145
galaxyBorderCirclesGeoJSON,
146146
getSystemCoordinates,
147147
);
148-
const countryNames = await countryNamesPromise;
148+
const { countryNames, systemNames } = await namesPromise;
149149
const labels = timeIt(
150150
'labels',
151151
cached(processLabels),
@@ -167,6 +167,7 @@ export default async function processMapData(
167167
knownCountries,
168168
knownSystems,
169169
getSystemCoordinates,
170+
systemNames,
170171
);
171172
const bypassLinks = timeIt(
172173
'bypassLinks',
Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import { get } from 'svelte/store';
2-
import type { Country, GameState } from '../../GameState';
2+
import type { GameState, LocalizedText } from '../../GameState';
33
import { stellarisDataPromiseStore } from '../../loadStellarisData';
44
import { localizeTextSync } from './locUtils';
55

66
// _language is just here to control caching
77
export default async function processNames(gameState: GameState, _language: string) {
8-
const countryNames = await localizeCountryNames(gameState.country);
9-
return countryNames;
8+
const countryNames = await localizeEntityNames(gameState.country);
9+
const systemNames = await localizeEntityNames(gameState.galactic_object);
10+
return { countryNames, systemNames };
1011
}
1112

12-
function localizeCountryNames(countries: Record<number, Country>) {
13+
function localizeEntityNames(entities: Record<number, { id: number; name: LocalizedText }>) {
1314
return get(stellarisDataPromiseStore).then(({ loc }) => {
14-
return Object.fromEntries<string | undefined>(
15-
Object.values(countries).map((c) => [c.id, localizeTextSync(c.name, loc)] as const),
16-
);
15+
return Object.fromEntries<string>(
16+
Object.values(entities).map(
17+
(entity) => [entity.id, localizeTextSync(entity.name, loc)] as const,
18+
),
19+
) as Record<number, string>;
1720
});
1821
}

src/renderer/src/lib/map/data/processSystems.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default function processSystems(
1818
knownCountries: Set<number>,
1919
knownSystems: Set<number>,
2020
getSystemCoordinates: (id: number, options?: { invertX?: boolean }) => [number, number],
21+
systemNames: Record<number, string>,
2122
) {
2223
const systems = Object.values(gameState.galactic_object).map((system) => {
2324
const countryId = systemIdToCountry[system.id];
@@ -61,6 +62,7 @@ export default function processSystems(
6162
hasShroudTunnel,
6263
x,
6364
y,
65+
name: systemNames[system.id] ?? 'Unknown',
6466
};
6567
});
6668
return systems;

src/renderer/src/lib/settings/mapSettings.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ export type NumberMapSettings =
1010
| 'unionLeaderSymbolSize'
1111
| 'terraIncognitaBrightness'
1212
| 'borderFillFade'
13-
| 'claimVoidBorderThreshold';
13+
| 'claimVoidBorderThreshold'
14+
| 'systemNamesFontSize';
1415

1516
export type NumberOptionalMapSettings =
1617
| 'countryEmblemsMaxSize'
@@ -30,7 +31,9 @@ export type StringMapSettings =
3031
| 'unionSubjects'
3132
| 'unionLeaderSymbol'
3233
| 'terraIncognitaPerspectiveCountry'
33-
| 'terraIncognitaStyle';
34+
| 'terraIncognitaStyle'
35+
| 'systemNames'
36+
| 'systemNamesFont';
3437

3538
export type BooleanMapSettings =
3639
| 'hyperlaneSensitiveBorders'
@@ -152,6 +155,9 @@ export const defaultMapSettings: MapSettings = {
152155
countryEmblemsMinSize: null,
153156
countryEmblemsMaxSize: 75,
154157
labelsAvoidHoles: 'owned',
158+
systemNames: 'none',
159+
systemNamesFont: 'Orbitron',
160+
systemNamesFontSize: 3,
155161
sectorBorderStroke: {
156162
enabled: true,
157163
width: 1,

src/renderer/src/lib/settings/mapSettingsConfig.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,35 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
214214
},
215215
],
216216
},
217+
{
218+
id: 'systemLabels',
219+
name: 'setting.group.systemLabels',
220+
settings: [
221+
{
222+
id: 'systemNames',
223+
type: 'select',
224+
options: [
225+
{ id: 'none', name: 'option.system_names.none' },
226+
{ id: 'countryCapitals', name: 'option.system_names.country_capitals' },
227+
{ id: 'sectorCapitals', name: 'option.system_names.sector_capitals' },
228+
{ id: 'colonized', name: 'option.system_names.colonized' },
229+
{ id: 'all', name: 'option.system_names.all' },
230+
],
231+
},
232+
{
233+
id: 'systemNamesFont',
234+
type: 'select',
235+
options: [{ id: 'Orbitron', literalName: 'Orbitron' }],
236+
dynamicOptions: fontOptions,
237+
},
238+
{
239+
id: 'systemNamesFontSize',
240+
type: 'number',
241+
min: 0,
242+
step: 0.5,
243+
},
244+
],
245+
},
217246
{
218247
id: 'systemIcons',
219248
name: 'setting.group.systemIcons',

0 commit comments

Comments
 (0)