diff --git a/src/lib/cards/Inventories.svelte b/src/lib/cards/Inventories.svelte new file mode 100644 index 0000000..4105697 --- /dev/null +++ b/src/lib/cards/Inventories.svelte @@ -0,0 +1,50 @@ + + + + +{#if valid} + + + {i18n.localize("inventorySettings")} + + + + + + + + + + + + + {i18n.localize("inventories")} ({applyUnits(i18n, ship.getTotalVolume(inventoryMultiplier), "l")}) + + + + + + + + +{/if} \ No newline at end of file diff --git a/src/lib/cards/Thrusters.svelte b/src/lib/cards/Thrusters.svelte new file mode 100644 index 0000000..c7707ed --- /dev/null +++ b/src/lib/cards/Thrusters.svelte @@ -0,0 +1,50 @@ + + + + +{#if valid} + + + {i18n.localize("thrusterSettings")} + + + + + + + + + + + {i18n.localize("thrusters")} ({applyUnits(i18n, ship.getTotalThrust(atmosphericDensity), "N")}) + + + + + + + + +{/if} \ No newline at end of file diff --git a/src/lib/components/AccelerationOutputSegment.svelte b/src/lib/components/AccelerationOutputSegment.svelte new file mode 100644 index 0000000..50792c1 --- /dev/null +++ b/src/lib/components/AccelerationOutputSegment.svelte @@ -0,0 +1,35 @@ + + + + +{#if valid} +
+

{i18n.localize("acceleration")} ({i18n.localize("full")}):

+ {#if ship.getAcceleration(atmosphere, inventoryMultiplier, material) <= 0} +

{applyUnits(i18n, ship.getAcceleration(atmosphere, inventoryMultiplier, material), "m/s²")}

+ {:else} +

{applyUnits(i18n, ship.getAcceleration(atmosphere, inventoryMultiplier, material), "m/s²")}

+ {/if} +
+
+

{i18n.localize("acceleration")} ({i18n.localize("empty")}):

+ {#if ship.getMaxAcceleration(atmosphere) < 0} +

{applyUnits(i18n, ship.getMaxAcceleration(atmosphere), "m/s²")}

+ {:else} +

{applyUnits(i18n, ship.getMaxAcceleration(atmosphere), "m/s²")}

+ {/if} +
+{/if} \ No newline at end of file diff --git a/src/lib/components/Atmosphere.svelte b/src/lib/components/Atmosphere.svelte index dcce20b..5b721d6 100644 --- a/src/lib/components/Atmosphere.svelte +++ b/src/lib/components/Atmosphere.svelte @@ -19,7 +19,7 @@
- +
diff --git a/src/lib/components/ThrusterList.svelte b/src/lib/components/ThrusterList.svelte index f41ab29..9211466 100644 --- a/src/lib/components/ThrusterList.svelte +++ b/src/lib/components/ThrusterList.svelte @@ -21,7 +21,7 @@ {#if valid} {#each thrusters as thruster, index}

- - {i18n.localize(thruster.details.size)} {i18n.localize(thruster.details.type.details.name)}: {applyUnits(i18n, thruster.getThrust(grid, atmosphere), "N")} + - {i18n.localize(thruster.details.size)} {i18n.localize(thruster.details.type.details.name)}: {applyUnits(i18n, thruster.getThrust(grid, atmosphere), "N")} ({Math.round(thruster.details.type.details.curve.getEffectiveness(atmosphere).toFixed(2) * 100)}%)

{/each} diff --git a/src/lib/constants.ts b/src/lib/constants.ts index d4e33e1..c6be65d 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -196,6 +196,22 @@ const localization = new Map([ ["deuterium", new Map([ ["en-GB", "Deuterium"], ["de-DE", "Deuterium"], + ])], + ["vehicleWeightInTons", new Map([ + ["en-GB", "Vehicle Weight (in tons)"], + ["de-DE", "Fahrzeug Gewicht (in Tonnen)"], + ])], + ["full", new Map([ + ["en-GB", "full"], + ["de-DE", "voll"], + ])], + ["empty", new Map([ + ["en-GB", "empty"], + ["de-DE", "leer"], + ])], + ["acceleration", new Map([ + ["en-GB", "Acceleration"], + ["de-DE", "Beschleunigung"], ])] ]) @@ -265,6 +281,6 @@ export function weightConversion(i18n: Localization, weight: number): string { return applyUnits(i18n, weight/1000, "t") } else { - return `${weight.toFixed(2)}kg` + return `${(weight * 100).toFixed(2) || (weight * 100) / 100}kg` } } \ No newline at end of file diff --git a/src/lib/ship.svelte.ts b/src/lib/ship.svelte.ts index f9e6456..01464a0 100644 --- a/src/lib/ship.svelte.ts +++ b/src/lib/ship.svelte.ts @@ -2,12 +2,13 @@ import {Thruster, THRUSTER_LIST, THRUSTER_TYPE_LIST} from "$lib/thruster.svelte" import {Grid} from "$lib/grid"; import {INVENTORIES, Inventory} from "$lib/containers.svelte"; import type {Fuel} from "$lib/fuel"; +import type {CargoMaterial} from "$lib/materials"; export class Ship { thrusters: Array = $state([]); inventories: Array = $state([]); grid: Grid = $state(Grid.Small); - weight: number = $state(0); + tons: number = $state(0); constructor(grid: Grid = Grid.Small) { this.grid = grid; @@ -22,7 +23,7 @@ export class Ship { return inventory.details.key; }), grid: this.grid, - weight: this.weight, + weight: this.tons, } } @@ -49,7 +50,7 @@ export class Ship { } if (ship.weight !== undefined) { - this.weight = ship.weight; + this.tons = ship.weight; } } @@ -85,14 +86,6 @@ export class Ship { return thrust; } - getTotalMaxThrust(): number { - let thrust = 0; - this.thrusters.forEach((thruster) => { - thrust += thruster.getMaxThrust(this.grid); - }); - return thrust; - } - getFuelTypes(): Array { let fuels: Array = []; this.thrusters.forEach((thruster) => { @@ -102,4 +95,29 @@ export class Ship { }) return fuels; } + + getTotalWeightPossible(gravity: number, atmosphere: number): number { + return this.getTotalThrust(atmosphere) / (gravity * 9.81) + } + + getVehicleWeightPossible(gravity: number, atmosphere: number, inventoryMultiplier: number, material: CargoMaterial): number { + return this.getTotalWeightPossible(gravity, atmosphere) - this.getTotalVolume(inventoryMultiplier) * material.density; + } + + getVehicleWeight(): number { + return (this.tons * 1000); + } + + getTotalWeight(inventoryMultiplier: number, material: CargoMaterial) { + return this.getVehicleWeight() + this.getTotalVolume(inventoryMultiplier) * material.density; + } + + getAcceleration(atmosphere: number, inventoryMultiplier: number, material: CargoMaterial) { + console.log(material) + return this.getTotalThrust(atmosphere) / this.getTotalWeight(inventoryMultiplier, material) + } + + getMaxAcceleration(atmosphere: number) { + return this.getTotalThrust(atmosphere) / this.getVehicleWeight(); + } } \ No newline at end of file diff --git a/src/lib/thruster.svelte.ts b/src/lib/thruster.svelte.ts index 5f3e781..641b185 100644 --- a/src/lib/thruster.svelte.ts +++ b/src/lib/thruster.svelte.ts @@ -8,11 +8,41 @@ export enum ThrusterSize { Huge = "hugeThruster", } +export type ThrustDensity = { + thrust: number; + density: number; +} + +export class ThrustCurve { + private min: ThrustDensity; + private max: ThrustDensity; + + constructor(min: ThrustDensity, max: ThrustDensity) { + this.min = min; + this.max = max; + } + + getEffectiveness(airDensity: number): number { + if (airDensity >= this.max.density) { + return this.max.thrust; + } + else if (airDensity <= this.min.density) { + return this.min.thrust; + } + else { + return (1 - this.getPointOnCurve(airDensity)) * this.min.thrust + this.getPointOnCurve(airDensity) * this.max.thrust + } + } + + private getPointOnCurve(airDensity: number): number { + return (airDensity-this.min.density)/(this.max.density - this.min.density); + } +} + type ThrusterTypeDetails = { key: string, name: string, - vacuum: number, - atmosphere: number, + curve: ThrustCurve, fuel: Fuel, }; @@ -20,29 +50,25 @@ export const THRUSTER_TYPE_LIST: { [key: string]: ThrusterTypeDetails } = { Atmospheric: { key: "Atmospheric", name: "atmosphericThruster", - vacuum: 0, - atmosphere: 1, + curve: new ThrustCurve({density: 0.3, thrust: 0}, {density: 1, thrust: 1}), fuel: Fuel.Electricity, }, Ion: { key: "Ion", name: "ionThruster", - vacuum: 1, - atmosphere: 0.2, + curve: new ThrustCurve({density: 0, thrust: 1}, {density: 1, thrust: 0.3}), fuel: Fuel.Electricity, }, Hydrogen: { key: "Hydrogen", name: "hydrogenThruster", - vacuum: 1, - atmosphere: 1, + curve: new ThrustCurve({density: 0, thrust: 1}, {density: 1, thrust: 1}), fuel: Fuel.Hydrogen, }, Fusion: { key: "Fusion", name: "fusionThruster", - vacuum: 1, - atmosphere: 0.5, + curve: new ThrustCurve({density: 0, thrust: 1}, {density: 1, thrust: 0.5}), fuel: Fuel.Deuterium, }, } @@ -61,9 +87,8 @@ export class ThrusterType { let equals: Array = []; equals[0] = this.details.key === obj.details.key; equals[1] = this.details.name === obj.details.name; - equals[2] = this.details.vacuum === obj.details.vacuum; - equals[3] = this.details.atmosphere === obj.details.atmosphere; - equals[4] = this.details.fuel === obj.details.fuel; + equals[2] = this.details.curve === obj.details.curve; + equals[3] = this.details.fuel === obj.details.fuel; return !equals.includes(false); } } @@ -229,7 +254,7 @@ export class Thruster { } getThrust(grid: Grid, atmosphereDensity: number): number { - let efficiencyCoefficient: number = (this.details.type.details.vacuum * (1 - atmosphereDensity)) + (this.details.type.details.atmosphere * atmosphereDensity); + let efficiencyCoefficient: number = this.details.type.details.curve.getEffectiveness(atmosphereDensity); let thruster: ThrusterDetails | undefined = THRUSTER_LIST[this.details.key]; if (thruster === undefined) { throw(`Thruster ${this.details.key} undefined, cannot retrieve thrust values`); diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 39fa17a..b535341 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -25,6 +25,9 @@ import {Slider} from "$lib/components/ui/slider"; import Atmosphere from "$lib/components/Atmosphere.svelte"; import WeightOutputSegment from "$lib/components/WeightOutputSegment.svelte"; + import Inventories from "$lib/cards/Inventories.svelte"; + import Thrusters from "$lib/cards/Thrusters.svelte"; + import AccelerationOutputSegment from "$lib/components/AccelerationOutputSegment.svelte"; const STORAGE_VERSION = "2"; let i18n = $state(new Localization("en-GB")); @@ -66,10 +69,6 @@ } }) - let maxWeight: number = $derived(ship.getTotalThrust(atmosphericDensity) / (gravity * 9.81)) - - let maxVehicleWeight: number = $derived(maxWeight - ship.getTotalVolume(inventoryMultiplier) * material.density) - function addInventory(newInventory: Inventory) { console.log("triggered") ship.addInventory(newInventory); @@ -87,12 +86,6 @@ ship.removeThruster(index); } - function handleGravityChange() { - if (gravity <= 0) { - gravity = 0; - } - } - onMount(() => { if (navigator) { i18n.language = navigator.language; @@ -149,107 +142,70 @@ -
- - - {i18n.localize("title")} - - - - - - {i18n.localize("settings")} - - - - -
- {#each Object.values(Grid) as size} - {#if ship.grid === size} - - {:else} - - {/if} - {/each} -
- - {handleGravityChange(change)}}/> - -
- {#each Object.values(CargoMaterial) as value} - {#if material === value} - - {:else} - - {/if} - {/each} -
- -
-
- - - {i18n.localize("results")} - - - - - -

{i18n.localize(ship.getFuelTypes().length > 1 ? "fuels" : "fuel")}: - {ship.getFuelTypes().map((fuel) => i18n.localize(fuel.name)).join(", ") } -

-
-
-
-
- - - {i18n.localize("thrusterSettings")} - - - - - - - - - - - {i18n.localize("thrusters")} ({applyUnits(i18n, ship.getTotalThrust(atmosphericDensity), "N")}) - - - - - - - - +{#if mounted} +
+ + + {i18n.localize("title")} + + + + + + {i18n.localize("settings")} + + + + +
+ {#each Object.values(Grid) as size} + {#if ship.grid === size} + + {:else} + + {/if} + {/each} +
+ + + +
+ {#each Object.values(CargoMaterial) as value} + {#if material === value} + + {:else} + + {/if} + {/each} +
+ + + + +
+
+ + + {i18n.localize("results")} + + + + + +

{i18n.localize(ship.getFuelTypes().length > 1 ? "fuels" : "fuel")}: + {ship.getFuelTypes().map((fuel) => i18n.localize(fuel.name)).join(", ") } +

+ + +
+
+
+
- - - {i18n.localize("inventorySettings")} - - - - - - - - - - - - - {i18n.localize("inventories")} ({applyUnits(i18n, ship.getTotalVolume(inventoryMultiplier), "l")}) - - - - - - - - -
+ + +
+{/if}