diff --git a/package.json b/package.json index 1f19bc4..52652de 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,8 @@ "dependencies": { "bits-ui": "^0.21.8", "clsx": "^2.1.1", + "cmdk-sv": "^0.0.17", + "svelte-radix": "^1.1.0", "tailwind-merge": "^2.3.0", "tailwind-variants": "^0.2.1" } diff --git a/src/lib/constants.ts b/src/lib/constants.ts index e688d52..c5898cf 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -1,10 +1,34 @@ -import {Map} from "svelte/reactivity"; - export enum Grids { Small = "smallGrid", Large = "largeGrid" } +export enum ThrusterFuel { + Electric = "electric", + Hydrogen = "hydrogen", + Deuterium = "deuterium" +} + +export class ThrusterTypeDetails { + atmosphericFactor: number; + vacuumFactor: number; + fuel: ThrusterFuel; + sizes: Map; + + constructor(atmos: number, vacuum: number, fuel: ThrusterFuel, sizes: Map) { + this.atmosphericFactor = atmos; + this.vacuumFactor = vacuum; + this.fuel = fuel; + this.sizes = sizes; + } +} + +export enum ThrusterSize { + Small = "smallThruster", + Large = "largeThruster", + Huge = "hugeThruster", +} + export enum ThrusterType { Ion = "ion", Atmospheric = "atmos", @@ -12,47 +36,54 @@ export enum ThrusterType { Fusion = "fusion" } -export enum ThrusterSize { - Small = "smallThruster", - Large = "largeThruster" +export class ThrusterSizeDetails { + thrust: number; + maxFuelConsumption: number; + + constructor(thrust: number, maxFuelConsumption = 0) { + this.thrust = thrust; + this.maxFuelConsumption = maxFuelConsumption; + } } -export const thrustValues = new Map([ +export const thrusterDetails: Map> = new Map([ [Grids.Large, new Map([ - [ThrusterType.Atmospheric, new Map([ - [ThrusterSize.Large, 4500000], - [ThrusterSize.Small, 350000] - ])], - [ThrusterType.Ion, new Map([ - [ThrusterSize.Large, 4320000], - [ThrusterSize.Small, 345600] - ])], - [ThrusterType.Fusion, new Map([ - [ThrusterSize.Large, 666], - [ThrusterSize.Small, 666] - ])], - [ThrusterType.Hydrogen, new Map([ - [ThrusterSize.Large, 7200000], - [ThrusterSize.Small, 1080000] - ])] + [ThrusterType.Atmospheric, new ThrusterTypeDetails(1, 0, ThrusterFuel.Electric, new Map([ + [ThrusterSize.Large, new ThrusterSizeDetails(4500000)], + [ThrusterSize.Small, new ThrusterSizeDetails(350000)] + ]))], + [ThrusterType.Ion, new ThrusterTypeDetails(0.2, 1, ThrusterFuel.Electric, new Map([ + [ThrusterSize.Large, new ThrusterSizeDetails(4320000)], + [ThrusterSize.Small, new ThrusterSizeDetails(345600)] + ]))], + [ThrusterType.Hydrogen, new ThrusterTypeDetails(1, 1, ThrusterFuel.Hydrogen, new Map([ + [ThrusterSize.Large, new ThrusterSizeDetails(7200000)], + [ThrusterSize.Small, new ThrusterSizeDetails(1080000)] + ]))], + [ThrusterType.Fusion, new ThrusterTypeDetails(0.5, 1, ThrusterFuel.Deuterium, new Map([ + [ThrusterSize.Large, new ThrusterSizeDetails(33780000)], + [ThrusterSize.Small, new ThrusterSizeDetails(9040000)] + ]))] + ])], [Grids.Small, new Map([ - [ThrusterType.Atmospheric, new Map([ - [ThrusterSize.Large, 340000], - [ThrusterSize.Small, 65000] - ])], - [ThrusterType.Ion, new Map([ - [ThrusterSize.Large, 172800], - [ThrusterSize.Small, 14400] - ])], - [ThrusterType.Fusion, new Map([ - [ThrusterSize.Large, 666], - [ThrusterSize.Small, 666] - ])], - [ThrusterType.Hydrogen, new Map([ - [ThrusterSize.Large, 480000], - [ThrusterSize.Small, 98400] - ])] + [ThrusterType.Atmospheric, new ThrusterTypeDetails(1, 0, ThrusterFuel.Electric, new Map([ + [ThrusterSize.Large, new ThrusterSizeDetails(340000)], + [ThrusterSize.Small, new ThrusterSizeDetails(65000)] + ]))], + [ThrusterType.Ion, new ThrusterTypeDetails(0.2, 1, ThrusterFuel.Electric, new Map([ + [ThrusterSize.Large, new ThrusterSizeDetails(172800)], + [ThrusterSize.Small, new ThrusterSizeDetails(14400)] + ]))], + [ThrusterType.Hydrogen, new ThrusterTypeDetails(1, 1, ThrusterFuel.Hydrogen, new Map([ + [ThrusterSize.Large, new ThrusterSizeDetails(480000)], + [ThrusterSize.Small, new ThrusterSizeDetails(98400)] + ]))], + [ThrusterType.Fusion, new ThrusterTypeDetails(0.5, 1, ThrusterFuel.Deuterium, new Map([ + [ThrusterSize.Huge, new ThrusterSizeDetails(9040000)], + [ThrusterSize.Large, new ThrusterSizeDetails(1030000)], + [ThrusterSize.Small, new ThrusterSizeDetails(210000)] + ]))] ])] ]) @@ -159,6 +190,10 @@ export const localization = new Map([ ["en-GB", "Large"], ["de-DE", "Großer"] ])], + ["hugeThruster", new Map([ + ["en-GB", "Huge"], + ["de-DE", "Rießiger"] + ])], ["connector", new Map([ ["en-GB", "Connector"], ["de-DE", "Verbinder"] @@ -251,6 +286,10 @@ export const localization = new Map([ ["en-GB", "Density"], ["de-DE", "Dichte"] ])], + ["atmosDensity", new Map([ + ["en-GB", "Atmospheric Density"], + ["de-DE", "Atmosphärendichte"] + ])], ]) export type Thruster = { diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 03ff8dc..e19fefa 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -10,11 +10,12 @@ localization, metricModifiers, type Thruster, ThrusterSize, ThrusterType, - thrustValues, Density, densityValues + thrusterDetails, Density, densityValues, ThrusterTypeDetails, ThrusterSizeDetails } from "$lib/constants"; import {Input} from "$lib/components/ui/input"; import {Label} from "$lib/components/ui/label"; import {Separator} from "$lib/components/ui/separator"; + import * as DropdownMenu from "$lib/components/ui/dropdown-menu"; import {onMount} from "svelte"; let locale = $state("en-GB"); @@ -61,6 +62,13 @@ } }) + let atmosphericDensity: number = $state(1); + $effect(() => { + if (mounted) { + localStorage.setItem("atmosphericDensity", atmosphericDensity); + } + }) + let newThruster: Thruster = $state({ type: ThrusterType.Atmospheric, size: ThrusterSize.Small, @@ -81,7 +89,7 @@ let totalThrust: number = $derived.by(() => { let thrust = 0; thrusters.forEach((thruster) => { - thrust += getThrusterPower(thruster) + thrust += getThrust(thruster) }) return thrust }); @@ -110,8 +118,19 @@ return inventorySizes.get(gridSize).get(inventory) * inventoryMultiplier } - function getThrusterPower(thruster: Thruster): number { - return thrustValues.get(gridSize).get(thruster.type).get(thruster.size) + function getThrusterDetails(thruster: Thruster): ThrusterSizeDetails { + return thrusterDetails.get(gridSize).get(thruster.type).sizes.get(thruster.size) + } + + function getThrust(thruster: Thruster): number { + let typeDetails = getThrusterTypeDetails(thruster); + let sizeDetails = getThrusterDetails(thruster); + let thrustEfficiency = (typeDetails.vacuumFactor * (1 - atmosphericDensity)) + (typeDetails.atmosphericFactor * atmosphericDensity); + return sizeDetails.thrust * thrustEfficiency; + } + + function getThrusterTypeDetails(thruster: Thruster): ThrusterTypeDetails { + return thrusterDetails.get(gridSize).get(thruster.type) } function addThruster() { @@ -187,6 +206,10 @@ density = localStorage.getItem("density") } + if (localStorage.getItem("atmosphericDensity") !== null) { + atmosphericDensity = localStorage.getItem("atmosphericDensity") + } + if (localStorage.getItem("inventoryMultiplier") !== null) { inventoryMultiplier = localStorage.getItem("inventoryMultiplier") } @@ -217,6 +240,8 @@ + +
@@ -252,24 +277,26 @@ -
- {#each Object.values(ThrusterType) as thruster} - {#if newThruster.type === thruster} - - {:else} - - {/if} - {/each} -
-
- {#each Object.values(ThrusterSize) as size} - {#if newThruster.size === size} - - {:else} - - {/if} - {/each} -
+ + {localized(newThruster.type)} + + + {#each Object.values(ThrusterType) as thrusterType} + {localized(thrusterType)} + {/each} + + + + + {localized(newThruster.size)} + + + {#each getThrusterTypeDetails(newThruster).sizes.keys() as thrusterDetails} + {localized(thrusterDetails)} + {/each} + + +
@@ -282,7 +309,7 @@
{#each thrusters as thruster, index}

- - {localized(thruster.size)} {localized(thruster.type)} {localized("thruster")}: {applyUnits(getThrusterPower(thruster), "N")} + - {localized(thruster.size)} {localized(thruster.type)} {localized("thruster")}: {applyUnits(getThrust(thruster), "N")}

{/each} diff --git a/yarn.lock b/yarn.lock index 103116c..7dd578a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -208,6 +208,18 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@melt-ui/svelte@0.61.2": + version "0.61.2" + resolved "https://registry.yarnpkg.com/@melt-ui/svelte/-/svelte-0.61.2.tgz#2948dd4ef47c4c5b5cf74d028c5143a5f986d239" + integrity sha512-BHkD9G31zQBToA4euDRBgTQRvWxT9scufOVCXgDO6HKTvyxFspbWT2bgiSFqAK4BbAGDn9Ao36Q8F9O71KN4OQ== + dependencies: + "@floating-ui/core" "^1.3.1" + "@floating-ui/dom" "^1.4.5" + "@internationalized/date" "^3.5.0" + dequal "^2.0.3" + focus-trap "^7.5.2" + nanoid "^4.0.2" + "@melt-ui/svelte@0.76.2": version "0.76.2" resolved "https://registry.yarnpkg.com/@melt-ui/svelte/-/svelte-0.76.2.tgz#9d6a578695ac257e34710fdeff3c8a40c8c25f31" @@ -491,6 +503,14 @@ bits-ui@^0.21.8: "@melt-ui/svelte" "0.76.2" nanoid "^5.0.5" +bits-ui@^0.9.0: + version "0.9.9" + resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-0.9.9.tgz#02b20e41ad673670259aadcefe2c75d827fe3626" + integrity sha512-LkdkyTtpXdkjBzPZJVJgpcre4fut6DONoprMfadHFo82HNUhph+02CxDjYEcZcThb5z4YjSxMlCYvQPZm+YtfQ== + dependencies: + "@melt-ui/svelte" "0.61.2" + nanoid "^5.0.3" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -563,6 +583,14 @@ clsx@^2.1.1: resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== +cmdk-sv@^0.0.17: + version "0.0.17" + resolved "https://registry.yarnpkg.com/cmdk-sv/-/cmdk-sv-0.0.17.tgz#1d915040577affc72862161318ef39ab5829f49d" + integrity sha512-28QTrK1tT1TSNoGq9MVnzjeLNNjCgjmsM8c2HJfDpRt9t+GD+9m3wX/WdAPaP9jdoNYU0SSdZVdgsGgpaSQOYQ== + dependencies: + bits-ui "^0.9.0" + nanoid "^5.0.2" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -1035,7 +1063,12 @@ nanoid@^3.3.7: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== -nanoid@^5.0.4, nanoid@^5.0.5: +nanoid@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.2.tgz#140b3c5003959adbebf521c170f282c5e7f9fb9e" + integrity sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw== + +nanoid@^5.0.2, nanoid@^5.0.3, nanoid@^5.0.4, nanoid@^5.0.5: version "5.0.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.7.tgz#6452e8c5a816861fd9d2b898399f7e5fd6944cc6" integrity sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ== @@ -1423,6 +1456,11 @@ svelte-preprocess@^5.1.3: sorcery "^0.11.0" strip-indent "^3.0.0" +svelte-radix@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/svelte-radix/-/svelte-radix-1.1.0.tgz#5fb0c8d37422ea4863649180f6277af2d8b70dd3" + integrity sha512-kyE9wZiJV937INGb+wiBkAjmGtQUUYRPkVL2Q+/gj+9Vog1Ewd2wNvNmpNMUd+c+euxoc5u5YZMuCUgky9EUPw== + svelte@^5.0.0-next: version "5.0.0-next.136" resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.0.0-next.136.tgz#13db3f1e06e92d3951e1b2133590434e765ed1c4"