diff --git a/src/renderer/src/intl/en-US.ts b/src/renderer/src/intl/en-US.ts
index 29e7338..4de70a0 100644
--- a/src/renderer/src/intl/en-US.ts
+++ b/src/renderer/src/intl/en-US.ts
@@ -144,6 +144,8 @@ export default {
primary: 'Primary',
secondary: 'Secondary',
border: 'Border',
+ planet: 'Planet',
+ planet_complement: "Planet's Complement",
},
color_adjustment: {
LIGHTEN: 'Lighten',
@@ -416,6 +418,7 @@ export default {
systemMapOrbitStroke: 'Orbit Lines',
systemMapOrbitColor: 'Orbit Lines Color',
systemMapPlanetScale: 'Planet Scale',
+ systemMapPlanetRingColor: 'Planet Ring Color',
systemMapLabelPlanetsFont: 'Planet Name Font',
systemMapLabelPlanetsFontSize: 'Planet Name Font Size',
systemMapLabelPlanetsPosition: 'Planet Name Position',
diff --git a/src/renderer/src/lib/SettingControl/ColorSettingControl.svelte b/src/renderer/src/lib/SettingControl/ColorSettingControl.svelte
index c402e1f..7302c7d 100644
--- a/src/renderer/src/lib/SettingControl/ColorSettingControl.svelte
+++ b/src/renderer/src/lib/SettingControl/ColorSettingControl.svelte
@@ -24,7 +24,7 @@
.filter(
// don't show dynamic colors group if no dynamic colors are allowed
(group) =>
- !(group === 'option.color.group.dynamic' && config.allowedDynamicColors?.length === 0),
+ !(group === 'option.color.group.dynamic' && config.allowedDynamicColors.length === 0),
),
),
);
@@ -32,7 +32,6 @@
function filterAllowedOption(option: SelectOption) {
if (option.group !== 'option.color.group.dynamic') return true;
- if (config.allowedDynamicColors == null) return true;
return (config.allowedDynamicColors as string[]).includes(option.id);
}
diff --git a/src/renderer/src/lib/SettingControl/IconSettingControl.svelte b/src/renderer/src/lib/SettingControl/IconSettingControl.svelte
index 269b311..ce645bc 100644
--- a/src/renderer/src/lib/SettingControl/IconSettingControl.svelte
+++ b/src/renderer/src/lib/SettingControl/IconSettingControl.svelte
@@ -127,7 +127,11 @@
{/if}
{/if}
diff --git a/src/renderer/src/lib/map/mapUtils.ts b/src/renderer/src/lib/map/mapUtils.ts
index 8c222a1..02bfe43 100644
--- a/src/renderer/src/lib/map/mapUtils.ts
+++ b/src/renderer/src/lib/map/mapUtils.ts
@@ -1,4 +1,4 @@
-import { lab } from 'd3-color';
+import { hsl, lab } from 'd3-color';
import { interpolateRgb } from 'd3-interpolate';
import type { SVGAttributes } from 'svelte/elements';
@@ -14,12 +14,14 @@ export function resolveColor({
mapSettings,
colors,
countryColors: countryColorsOption,
+ planetColor,
colorStack,
resolveToOpaqueColor,
}: {
mapSettings: MapSettings;
colors: Record;
countryColors?: null | CountryColors | (CountryColors | null | undefined)[];
+ planetColor?: string;
colorStack: ColorSetting[];
resolveToOpaqueColor?: boolean;
}): string {
@@ -49,6 +51,13 @@ export function resolveColor({
colorStack: [mapSettings.borderColor, ...backgroundSettingStack],
resolveToOpaqueColor,
});
+ } else if (colorString === 'planet') {
+ colorString = planetColor ?? 'rgb(0, 0, 0)';
+ } else if (colorString === 'planet_complement') {
+ colorString = planetColor ?? 'rgb(0, 0, 0)';
+ const color = hsl(colorString);
+ color.h = color.h > 180 ? color.h - 180 : color.h + 180;
+ colorString = color.formatRgb();
} else {
if (colorString === 'primary') colorString = countryColors.primaryColor;
if (colorString === 'secondary') colorString = countryColors.secondaryColor;
@@ -201,3 +210,24 @@ export function getBackgroundColor(
colorStack: [mapSettings.backgroundColor],
});
}
+
+export function multiplyOpacity(colorSetting: ColorSetting, value: number): ColorSetting {
+ const opacityAdjustment = colorSetting.colorAdjustments.find(
+ (adjustment) => adjustment.type === 'OPACITY',
+ );
+ if (opacityAdjustment) {
+ return {
+ ...colorSetting,
+ colorAdjustments: colorSetting.colorAdjustments.map((adjustment) =>
+ adjustment === opacityAdjustment
+ ? { type: 'OPACITY', value: opacityAdjustment.value * value }
+ : adjustment,
+ ),
+ };
+ } else {
+ return {
+ ...colorSetting,
+ colorAdjustments: [...colorSetting.colorAdjustments, { type: 'OPACITY', value }],
+ };
+ }
+}
diff --git a/src/renderer/src/lib/map/solarSystemMap/SolarSystemMap.svelte b/src/renderer/src/lib/map/solarSystemMap/SolarSystemMap.svelte
index cf45c61..1254921 100644
--- a/src/renderer/src/lib/map/solarSystemMap/SolarSystemMap.svelte
+++ b/src/renderer/src/lib/map/solarSystemMap/SolarSystemMap.svelte
@@ -15,6 +15,7 @@
getFillColorAttributes,
getStrokeAttributes,
getStrokeColorAttributes,
+ multiplyOpacity,
} from '../mapUtils';
export let system: GalacticObject;
@@ -493,6 +494,27 @@
if (planet.coordinate.x > 0) return angle + 180;
return angle;
}
+
+ const PLANET_RING_PATTERN = (
+ [
+ [0.3, 0],
+ [0.05, 0.05],
+ [0.3, 0.15],
+ [0.1, 0.5],
+ [0.1, 1],
+ [0.02, 0.5],
+ [0.1, 1],
+ [0.1, 0.5],
+ [0.05, 0],
+ [0.2, 0.3],
+ [0.02, 0],
+ [0.05, 0.5],
+ ] as [number, number][]
+ ).map(([width, opacity], index, array) => {
+ const radiusMultiplier =
+ array.slice(0, index).reduce((total, [curWidth]) => total + curWidth, 0) + 1 + width / 2;
+ return { width, opacity, radiusMultiplier };
+ });
{:else}
+ {@const radius = getPlanetRadius(planet, $mapSettings)}
@@ -604,6 +627,23 @@
fill="#000000"
opacity={0.5}
/>
+ {#if planet.has_ring}
+ {#each PLANET_RING_PATTERN as ring}
+
+ {/each}
+ {/if}
{/if}
{/each}
{#each planets.filter((p) => isPlanetLabeled(p, $mapSettings)) as planet (planet.id)}
diff --git a/src/renderer/src/lib/settings/SettingConfig.ts b/src/renderer/src/lib/settings/SettingConfig.ts
index 620f1e0..7621bd1 100644
--- a/src/renderer/src/lib/settings/SettingConfig.ts
+++ b/src/renderer/src/lib/settings/SettingConfig.ts
@@ -58,7 +58,7 @@ export interface SettingConfigColor extends SettingConfigBase;
allowedAdjustments?: ColorSettingAdjustmentType[];
- allowedDynamicColors?: ('primary' | 'secondary' | 'border')[];
+ allowedDynamicColors: ('primary' | 'secondary' | 'border' | 'planet' | 'planet_complement')[];
}
export interface SettingConfigStroke extends SettingConfigBase {
@@ -73,6 +73,7 @@ export interface SettingConfigIcon extends SettingConfigBase;
noAdvanced?: boolean;
+ allowedDynamicColors: SettingConfigColor['allowedDynamicColors'];
}
export type UnknownSettingConfig =
diff --git a/src/renderer/src/lib/settings/mapSettings.ts b/src/renderer/src/lib/settings/mapSettings.ts
index a324363..86cbf00 100644
--- a/src/renderer/src/lib/settings/mapSettings.ts
+++ b/src/renderer/src/lib/settings/mapSettings.ts
@@ -96,6 +96,7 @@ export type ColorMapSettings =
| 'starScapeNebulaAccentColor'
| 'starScapeNebulaColor'
| 'starScapeStarsColor'
+ | 'systemMapPlanetRingColor'
| 'unionBorderColor'
| 'unownedHyperlaneColor'
| 'unownedHyperRelayColor'
@@ -493,6 +494,10 @@ export const defaultMapSettings: MapSettings = {
systemMapLabelFleetsEnabled: true,
systemMapLabelFleetsFontSize: 3,
systemMapLabelFleetsPosition: 'right',
+ systemMapPlanetRingColor: {
+ color: 'planet',
+ colorAdjustments: [{ type: 'OPACITY', value: 0.75 }],
+ },
};
export const mapSettings = localStorageStore('mapSettings', defaultMapSettings);
diff --git a/src/renderer/src/lib/settings/mapSettingsConfig.ts b/src/renderer/src/lib/settings/mapSettingsConfig.ts
index d93b3c0..ff4c614 100644
--- a/src/renderer/src/lib/settings/mapSettingsConfig.ts
+++ b/src/renderer/src/lib/settings/mapSettingsConfig.ts
@@ -4,9 +4,18 @@ import { fontOptions } from './options/fontOptions';
import { glyphOptions } from './options/glyphOptions';
import { speciesOptions } from './options/speciesOptions';
import { unionOptions } from './options/unionOptions';
-import { type MapSettingConfigGroup } from './SettingConfig';
+import { type MapSettingConfigGroup, type SettingConfigColor } from './SettingConfig';
import { isColorDynamic } from './utils';
+const COUNTRY_SCOPED_DYNAMIC_COLORS: SettingConfigColor<
+ unknown,
+ unknown
+>['allowedDynamicColors'][number][] = ['primary', 'secondary', 'border'];
+const PLANET_SCOPED_DYNAMIC_COLORS: SettingConfigColor<
+ unknown,
+ unknown
+>['allowedDynamicColors'][number][] = ['planet', 'planet_complement'];
+
export const mapSettingsConfig: MapSettingConfigGroup[] = [
{
id: 'mapMode',
@@ -54,13 +63,14 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
{
id: 'borderColor',
type: 'color',
- allowedDynamicColors: ['primary', 'secondary'],
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS.filter((c) => c !== 'border'),
hideIf: (settings) => !settings.borderStroke.enabled,
},
{
id: 'borderFillColor',
type: 'color',
hideIf: (settings) => !settings.borderStroke.enabled,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'borderFillFade',
@@ -80,6 +90,7 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
id: 'sectorBorderColor',
type: 'color',
hideIf: (settings) => !settings.sectorBorderStroke.enabled,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'frontierBubbleThreshold',
@@ -107,6 +118,7 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
type: 'color',
hideIf: (settings) =>
!settings.sectorTypeBorderStyles || !settings.sectorBorderStroke.enabled,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'sectorFrontierBorderStroke',
@@ -119,6 +131,7 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
type: 'color',
hideIf: (settings) =>
!settings.sectorTypeBorderStyles || !settings.sectorBorderStroke.enabled,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
],
},
@@ -162,6 +175,7 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
![settings.unionFederations, settings.unionHegemonies, settings.unionSubjects].includes(
'joinedBorders',
),
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'unionFederationsColor',
@@ -208,6 +222,7 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
id: 'occupationColor',
type: 'color',
hideIf: (settings) => !settings.occupation,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
],
},
@@ -356,40 +371,48 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
id: 'countryCapitalIcon',
type: 'icon',
requiresReprocessing: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'sectorCapitalIcon',
type: 'icon',
requiresReprocessing: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'populatedSystemIcon',
type: 'icon',
requiresReprocessing: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'unpopulatedSystemIcon',
type: 'icon',
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'wormholeIcon',
type: 'icon',
requiresReprocessing: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'gatewayIcon',
type: 'icon',
requiresReprocessing: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'lGateIcon',
type: 'icon',
requiresReprocessing: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'shroudTunnelIcon',
type: 'icon',
requiresReprocessing: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
],
},
@@ -406,6 +429,7 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
id: 'hyperlaneColor',
type: 'color',
hideIf: (settings) => !settings.hyperlaneStroke.enabled,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'unownedHyperlaneColor',
@@ -424,6 +448,7 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
id: 'hyperRelayColor',
type: 'color',
hideIf: (settings) => !settings.hyperRelayStroke.enabled,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'unownedHyperRelayColor',
@@ -711,6 +736,11 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
min: 0,
step: 0.1,
},
+ {
+ id: 'systemMapPlanetRingColor',
+ type: 'color',
+ allowedDynamicColors: PLANET_SCOPED_DYNAMIC_COLORS,
+ },
{
id: 'systemMapLabelPlanetsFont',
type: 'select',
@@ -773,21 +803,25 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
id: 'systemMapCivilianFleetIcon',
type: 'icon',
noAdvanced: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'systemMapCivilianStationIcon',
type: 'icon',
noAdvanced: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'systemMapMilitaryFleetIcon',
type: 'icon',
noAdvanced: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'systemMapMilitaryStationIcon',
type: 'icon',
noAdvanced: true,
+ allowedDynamicColors: COUNTRY_SCOPED_DYNAMIC_COLORS,
},
{
id: 'systemMapLabelFleetsEnabled',
diff --git a/src/renderer/src/lib/settings/options/colorOptions.ts b/src/renderer/src/lib/settings/options/colorOptions.ts
index 9c7c812..a1acde1 100644
--- a/src/renderer/src/lib/settings/options/colorOptions.ts
+++ b/src/renderer/src/lib/settings/options/colorOptions.ts
@@ -4,4 +4,10 @@ export const colorOptions: SelectOption[] = [
{ id: 'primary', name: 'option.color.primary', group: 'option.color.group.dynamic' },
{ id: 'secondary', name: 'option.color.secondary', group: 'option.color.group.dynamic' },
{ id: 'border', name: 'option.color.border', group: 'option.color.group.dynamic' },
+ { id: 'planet', name: 'option.color.planet', group: 'option.color.group.dynamic' },
+ {
+ id: 'planet_complement',
+ name: 'option.color.planet_complement',
+ group: 'option.color.group.dynamic',
+ },
];