211 lines
8 KiB
Svelte
211 lines
8 KiB
Svelte
<svelte:options runes={true} />
|
|
|
|
<script lang="ts">
|
|
import * as Card from "$lib/components/ui/card";
|
|
import {Button} from "$lib/components/ui/button";
|
|
import {
|
|
applyUnits,
|
|
getFromLocalStorage,
|
|
Localization, weightConversion
|
|
} 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";
|
|
import {CargoMaterial} from "$lib/materials";
|
|
import ThrusterList from "$lib/components/ThrusterList.svelte";
|
|
import {Ship} from "$lib/ship.svelte";
|
|
import {Grid} from "$lib/grid";
|
|
import NewThruster from "$lib/components/NewThruster.svelte";
|
|
import NewInventory from "$lib/components/NewInventory.svelte";
|
|
import {Inventory} from "$lib/containers.svelte";
|
|
import InventoryList from "$lib/components/InventoryList.svelte";
|
|
import type {Thruster} from "$lib/thruster.svelte";
|
|
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"));
|
|
let mounted = $state(false);
|
|
|
|
let ship = $state(new Ship(Grid.Small));
|
|
$effect(() => {
|
|
ship.thrusters;
|
|
if (mounted) {
|
|
localStorage.setItem("ship", JSON.stringify(ship.save()));
|
|
}
|
|
})
|
|
|
|
let inventoryMultiplier: number = $state(3);
|
|
$effect(() => {
|
|
if (mounted) {
|
|
localStorage.setItem("inventoryMultiplier", inventoryMultiplier);
|
|
}
|
|
})
|
|
|
|
let gravity: number = $state(1);
|
|
$effect(() => {
|
|
if (mounted) {
|
|
localStorage.setItem("gravity", gravity);
|
|
}
|
|
})
|
|
|
|
let material: CargoMaterial = $state(CargoMaterial.Ore);
|
|
$effect(() => {
|
|
if (mounted) {
|
|
localStorage.setItem("density", material.save());
|
|
}
|
|
})
|
|
|
|
let atmosphericDensity: number = $state(1);
|
|
$effect(() => {
|
|
if (mounted) {
|
|
localStorage.setItem("atmosphericDensity", atmosphericDensity);
|
|
}
|
|
})
|
|
|
|
function addInventory(newInventory: Inventory) {
|
|
console.log("triggered")
|
|
ship.addInventory(newInventory);
|
|
}
|
|
|
|
function removeInventory(index: number) {
|
|
ship.removeInventory(index);
|
|
}
|
|
|
|
function addThruster(newThruster: Thruster) {
|
|
ship.addThruster(newThruster);
|
|
}
|
|
|
|
function removeThruster(index: number) {
|
|
ship.removeThruster(index);
|
|
}
|
|
|
|
onMount(() => {
|
|
if (navigator) {
|
|
i18n.language = navigator.language;
|
|
}
|
|
|
|
let ret = getFromLocalStorage("version");
|
|
if (ret.result) {
|
|
if (ret.value !== STORAGE_VERSION) {
|
|
localStorage.clear();
|
|
localStorage.setItem("version", STORAGE_VERSION);
|
|
}
|
|
}
|
|
else {
|
|
localStorage.clear();
|
|
localStorage.setItem("version", STORAGE_VERSION);
|
|
}
|
|
|
|
ret = getFromLocalStorage("ship");
|
|
if (ret.result) {
|
|
ship.load(JSON.parse(ret.value));
|
|
}
|
|
|
|
ret = getFromLocalStorage("gravity");
|
|
if (ret.result) {
|
|
gravity = ret.value;
|
|
}
|
|
|
|
ret = getFromLocalStorage("density");
|
|
if (ret.result) {
|
|
let parsed = ret.value;
|
|
Object.values(CargoMaterial).forEach((cargoMaterial) => {
|
|
if (cargoMaterial.name === parsed) {
|
|
material = cargoMaterial
|
|
}
|
|
})
|
|
}
|
|
|
|
ret = getFromLocalStorage("atmosphericDensity");
|
|
if (ret.result) {
|
|
atmosphericDensity = ret.value;
|
|
}
|
|
|
|
ret = getFromLocalStorage("inventoryMultiplier");
|
|
if (ret.result) {
|
|
inventoryMultiplier = ret.value;
|
|
}
|
|
|
|
mounted = true;
|
|
})
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<title>{i18n.localize("title")}</title>
|
|
<meta name="robots" content="noindex nofollow" />
|
|
</svelte:head>
|
|
|
|
{#if mounted}
|
|
<div class="gap-4 flex flex-row flex-wrap h-full">
|
|
<Card.Root class="flex-1 bg-secondary">
|
|
<Card.Header>
|
|
<Card.Title>{i18n.localize("title")}</Card.Title>
|
|
</Card.Header>
|
|
<Card.Content class="flex flex-col gap-3">
|
|
<Separator />
|
|
<Card.Root>
|
|
<Card.Header>
|
|
<Card.Title>{i18n.localize("settings")}</Card.Title>
|
|
</Card.Header>
|
|
<Card.Content class="flex flex-col gap-3">
|
|
<Separator />
|
|
<Label for="grid">{i18n.localize("gridSize")}</Label>
|
|
<div id="grid" class="flex gap-2">
|
|
{#each Object.values(Grid) as size}
|
|
{#if ship.grid === size}
|
|
<Button class="bg-primary">{i18n.localize(size)}</Button>
|
|
{:else}
|
|
<Button variant="secondary" onmousedown={() => ship.grid = size}>{i18n.localize(size)}</Button>
|
|
{/if}
|
|
{/each}
|
|
</div>
|
|
<Label for="gravity">{i18n.localize("gravity")}</Label>
|
|
<Input type="number" step="0.01" id="gravity" bind:value={gravity} min="0"/>
|
|
<Label for="density">{i18n.localize("density")}</Label>
|
|
<div id="density" class="flex gap-2">
|
|
{#each Object.values(CargoMaterial) as value}
|
|
{#if material === value}
|
|
<Button class="bg-primary">{i18n.localize(value.name)}</Button>
|
|
{:else}
|
|
<Button variant="secondary" onmousedown={() => material = value}>{i18n.localize(value.name)}</Button>
|
|
{/if}
|
|
{/each}
|
|
</div>
|
|
<Atmosphere bind:value={atmosphericDensity} />
|
|
<Separator />
|
|
<Label for="weight">{i18n.localize("vehicleWeightInTons")}</Label>
|
|
<Input type="number" step="0.01" id="weight" bind:value={ship.tons} min="0" />
|
|
</Card.Content>
|
|
</Card.Root>
|
|
<Card.Root>
|
|
<Card.Header>
|
|
<Card.Title>{i18n.localize("results")}</Card.Title>
|
|
</Card.Header>
|
|
<Card.Content class="flex flex-col gap-3">
|
|
<Separator />
|
|
<WeightOutputSegment {i18n} maxWeight={ship.getTotalWeightPossible(gravity, atmosphericDensity)} maxVehicleWeight="{ship.getVehicleWeightPossible(gravity, atmosphericDensity, inventoryMultiplier, material)}" />
|
|
<Separator />
|
|
<p>{i18n.localize(ship.getFuelTypes().length > 1 ? "fuels" : "fuel")}:
|
|
{ship.getFuelTypes().map((fuel) => i18n.localize(fuel.name)).join(", ") }
|
|
</p>
|
|
<Separator />
|
|
<AccelerationOutputSegment {i18n} {ship} atmosphere={atmosphericDensity} {inventoryMultiplier} {material} />
|
|
</Card.Content>
|
|
</Card.Root>
|
|
</Card.Content>
|
|
</Card.Root>
|
|
|
|
<Thrusters {i18n} {ship} {atmosphericDensity} onAddThruster={addThruster} onRemoveThruster={removeThruster} />
|
|
<Inventories {i18n} {ship} {inventoryMultiplier} onAddInventory={addInventory} onRemoveInventory={removeInventory} />
|
|
</div>
|
|
{/if}
|
|
|
|
|
|
|