Merge branch 'running-sveltekit' into version-2
This commit is contained in:
commit
67c6abbe96
34
.storybook/main.js
Normal file
34
.storybook/main.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
const path = require("path");
|
||||||
|
const preprocess = require("svelte-preprocess");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
staticDirs: ["../static", "../pictures"],
|
||||||
|
stories: [
|
||||||
|
"../src/**/*.stories.mdx",
|
||||||
|
"../src/**/*.stories.svelte",
|
||||||
|
"../src/**/stories.svelte",
|
||||||
|
],
|
||||||
|
addons: [
|
||||||
|
"@storybook/addon-links",
|
||||||
|
"@storybook/addon-essentials",
|
||||||
|
"@storybook/addon-svelte-csf",
|
||||||
|
],
|
||||||
|
framework: "@storybook/svelte",
|
||||||
|
svelteOptions: {
|
||||||
|
preprocess: preprocess(),
|
||||||
|
},
|
||||||
|
webpackFinal: async (config) => {
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
resolve: {
|
||||||
|
...config.resolve,
|
||||||
|
alias: {
|
||||||
|
...config.resolve?.alias,
|
||||||
|
$app: path.resolve("./fake/app"),
|
||||||
|
"\\$lib": path.resolve(__dirname, "../src/lib/"),
|
||||||
|
$lib: path.resolve(__dirname, "../src/lib/"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
3
.storybook/package.json
Normal file
3
.storybook/package.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"type": "commonjs"
|
||||||
|
}
|
11
.storybook/preview.js
Normal file
11
.storybook/preview.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import "$lib/style/index.js";
|
||||||
|
|
||||||
|
export const parameters = {
|
||||||
|
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||||
|
controls: {
|
||||||
|
matchers: {
|
||||||
|
color: /(background|color)$/i,
|
||||||
|
date: /Date$/,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
@ -1,5 +1,6 @@
|
|||||||
|
<svelte:component this={component} />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import "$lib/style/index.js";
|
||||||
export let component;
|
export let component;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:component this={component} />
|
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||||
import { clientPlugin, defineConfig } from '@vitebook/client/node';
|
import { clientPlugin, defineConfig } from "@vitebook/client/node";
|
||||||
import { defaultThemePlugin } from '@vitebook/theme-default/node';
|
import { defaultThemePlugin } from "@vitebook/theme-default/node";
|
||||||
import preprocess from 'svelte-preprocess';
|
import preprocess from "svelte-preprocess";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
include: ['src/**/*.story.svelte'],
|
include: ["src/**/*.story.svelte"],
|
||||||
alias: {
|
alias: {
|
||||||
$app: '/node_modules/@sveltejs/kit/assets/app',
|
$app: "/node_modules/@sveltejs/kit/assets/app",
|
||||||
$lib: '/src/lib',
|
$lib: "/src/lib",
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
clientPlugin({ appFile: 'App.svelte' }),
|
clientPlugin({ appFile: "App.svelte" }),
|
||||||
defaultThemePlugin(),
|
defaultThemePlugin(),
|
||||||
svelte({
|
svelte({
|
||||||
compilerOptions: {
|
compilerOptions: {
|
||||||
hydratable: true
|
hydratable: true,
|
||||||
},
|
},
|
||||||
extensions: ['.svelte'],
|
extensions: [".svelte"],
|
||||||
// Consult https://github.com/sveltejs/svelte-preprocess for more information
|
// Consult https://github.com/sveltejs/svelte-preprocess for more information
|
||||||
// about preprocessors.
|
// about preprocessors.
|
||||||
preprocess: preprocess(),
|
preprocess: preprocess(),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
site: {
|
site: {
|
||||||
title: '',
|
title: "",
|
||||||
description: '',
|
description: "",
|
||||||
/** @type {(import('@vitebook/theme-default/node').DefaultThemeConfig} */
|
/** @type {(import('@vitebook/theme-default/node').DefaultThemeConfig} */
|
||||||
theme: {},
|
theme: {},
|
||||||
},
|
},
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
import Theme from '@vitebook/theme-default';
|
import Theme from "@vitebook/theme-default";
|
||||||
|
|
||||||
export default Theme;
|
export default Theme;
|
||||||
|
10
package.json
10
package.json
@ -7,6 +7,7 @@
|
|||||||
"preview": "svelte-kit preview",
|
"preview": "svelte-kit preview",
|
||||||
"lint": "prettier --check . && eslint --ignore-path .gitignore .",
|
"lint": "prettier --check . && eslint --ignore-path .gitignore .",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
|
"storybook": "storybook-server",
|
||||||
"vitebook:dev": "vitebook dev",
|
"vitebook:dev": "vitebook dev",
|
||||||
"vitebook:build": "vitebook build",
|
"vitebook:build": "vitebook build",
|
||||||
"vitebook:preview": "vitebook preview"
|
"vitebook:preview": "vitebook preview"
|
||||||
@ -28,14 +29,21 @@
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@storybook/addon-actions": "^6.4.19",
|
||||||
|
"@storybook/addon-essentials": "^6.4.19",
|
||||||
|
"@storybook/addon-links": "6.4.19",
|
||||||
|
"@storybook/addon-svelte-csf": "^1.1.0",
|
||||||
|
"@storybook/svelte": "^6.4.19",
|
||||||
"@sveltejs/adapter-node": "^1.0.0-next.0",
|
"@sveltejs/adapter-node": "^1.0.0-next.0",
|
||||||
"@yanick/updeep": "link:/home/yanick/work/javascript/updeep",
|
"@yanick/updeep": "link:/home/yanick/work/javascript/updeep",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"redux": "^4.1.2",
|
"redux": "^4.1.2",
|
||||||
"reselect": "^4.1.5",
|
"reselect": "^4.1.5",
|
||||||
"rollup-plugin-analyzer": "^4.0.0",
|
"rollup-plugin-analyzer": "^4.0.0",
|
||||||
|
"svelte-knobby": "^0.3.4",
|
||||||
"ts-action": "^11.0.0",
|
"ts-action": "^11.0.0",
|
||||||
"updux": "link:/home/yanick/work/javascript/updux/"
|
"updux": "link:/home/yanick/work/javascript/updux/",
|
||||||
|
"webpack": "5"
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"svelteSortOrder": "options-markup-scripts-styles",
|
"svelteSortOrder": "options-markup-scripts-styles",
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import { action } from '@storybook/addon-actions';
|
|
||||||
|
|
||||||
import Carrier from './index.svelte';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Carrier',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const basic = () => ({
|
|
||||||
Component: Carrier,
|
|
||||||
props: {
|
|
||||||
bays: 3,
|
|
||||||
squadrons: [
|
|
||||||
{ id: 1, type: "standard", ftl: false, nbr_fighters: 6 },
|
|
||||||
{ id: 2, type: "fast", ftl: false, nbr_fighters: 6 },
|
|
||||||
{ id: 3, type: "none", ftl: false, nbr_fighters: 6 },
|
|
||||||
],
|
|
||||||
ship_change: action('ship_change'),
|
|
||||||
},
|
|
||||||
})
|
|
@ -1,5 +0,0 @@
|
|||||||
<Cost cost={12}/>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Cost from './Cost.svelte';
|
|
||||||
</script>
|
|
@ -1,21 +0,0 @@
|
|||||||
<div class="mass">{ mass }</div>
|
|
||||||
<div class="cost">{ cost }</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export let mass;
|
|
||||||
export let cost;
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.cost { grid-column: 3; }
|
|
||||||
.mass { grid-column: 2; }
|
|
||||||
img {
|
|
||||||
width: 0.75em;
|
|
||||||
}
|
|
||||||
.cost:after { content: '\00A4'; margin-left: 0.5em; }
|
|
||||||
.mass:after { content: url("/mass.svg"); width: 0.75em; display:
|
|
||||||
inline-block; margin-left: 0.5em; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,40 +0,0 @@
|
|||||||
<ShipItem {cost} {mass}>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Field label="thrust rating">
|
|
||||||
<input type="number" bind:value={ rating }
|
|
||||||
min="0" max="20" step="1" />
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
<label><input type="checkbox" bind:checked={advanced} /> advanced</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</ShipItem>
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
|
|
||||||
import Field from '$lib/components/Field/index.svelte';
|
|
||||||
import ShipItem from '$lib/components/ShipItem/index.svelte';
|
|
||||||
|
|
||||||
export let cost;
|
|
||||||
export let mass;
|
|
||||||
export let advanced = false;
|
|
||||||
export let rating = 0;
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
|
|
||||||
console.log(advanced);
|
|
||||||
$: dispatch( 'change_engine', { rating, advanced } );
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
div {
|
|
||||||
display: flex;
|
|
||||||
align-items: end;
|
|
||||||
}
|
|
||||||
label { margin-left: 2em; }
|
|
||||||
input[type="number"] { width: 5em; }
|
|
||||||
</style>
|
|
@ -1,29 +0,0 @@
|
|||||||
<div>
|
|
||||||
{#if label}
|
|
||||||
<label>{label}</label>
|
|
||||||
{/if}
|
|
||||||
<slot>
|
|
||||||
<input type="text" {placeholder} {value} on:change />
|
|
||||||
</slot>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export let label = "";
|
|
||||||
export let value = "";
|
|
||||||
export let placeholder;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
div > :global(*) {
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
div > label {
|
|
||||||
margin-left: 0em;
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
font-size: var(--font-scale-8);
|
|
||||||
font-weight: lighter;
|
|
||||||
font-family: Dosis;
|
|
||||||
color: var(--indigo-dye);
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,12 +0,0 @@
|
|||||||
import Component from './index.svelte';
|
|
||||||
import BasicStory from './BasicStory.svelte';
|
|
||||||
|
|
||||||
import '../../../public/global.css';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Field'
|
|
||||||
};
|
|
||||||
|
|
||||||
export const basic = () => ({
|
|
||||||
Component: BasicStory,
|
|
||||||
});
|
|
@ -1,20 +0,0 @@
|
|||||||
<ShipItem {cost} {mass}>
|
|
||||||
<Field label="firecons">
|
|
||||||
<input type="number" class="short" bind:value={nbr} />
|
|
||||||
</Field>
|
|
||||||
</ShipItem>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
import ShipItem from './ShipItem/index.svelte';
|
|
||||||
import Field from './Field/index.svelte';
|
|
||||||
|
|
||||||
export let nbr, cost, mass = (0,0,0);
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
$: dispatch( 'change_firecons', nbr);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
</style>
|
|
@ -1,35 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
|
|
||||||
import ShipItem from '../ShipItem/index.svelte';
|
|
||||||
import Field from '../Field/index.svelte';
|
|
||||||
|
|
||||||
export let type = 'none';
|
|
||||||
export let cost = 0;
|
|
||||||
export let mass = 0;
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
|
|
||||||
const change = () => dispatch( 'change_ftl', type );
|
|
||||||
|
|
||||||
const types = [ 'none', 'standard', 'advanced' ];
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ShipItem {mass} {cost}>
|
|
||||||
<Field label="FTL drive">
|
|
||||||
|
|
||||||
{#each types as t (t)}
|
|
||||||
<label><input type="radio" bind:group={type} value={t}
|
|
||||||
on:change={change} /> {t} </label>
|
|
||||||
{/each}
|
|
||||||
</Field>
|
|
||||||
</ShipItem>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
label {
|
|
||||||
display: inline;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,13 +0,0 @@
|
|||||||
export default {
|
|
||||||
title: 'FTL Drive'
|
|
||||||
};
|
|
||||||
|
|
||||||
import Component from '.';
|
|
||||||
import shipStore from '../../stores/ship.js';
|
|
||||||
|
|
||||||
export const basic = () => ({
|
|
||||||
Component,
|
|
||||||
props: {
|
|
||||||
ship: shipStore()
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,28 +0,0 @@
|
|||||||
<header>
|
|
||||||
<h1>The Docks</h1>
|
|
||||||
<h2>a <a
|
|
||||||
href="https://shop.groundzerogames.co.uk/rules.html">Full Thrust</a> ship builder</h2>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
header {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
width: var(--main-width);
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
h1, h2 {
|
|
||||||
font-family: Faktos;
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
text-align: right;
|
|
||||||
flex: 1;
|
|
||||||
padding-left: 2em;
|
|
||||||
font-size: var(--font-scale-12);
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,24 +0,0 @@
|
|||||||
<Field label={ `layer ${layer}` }>
|
|
||||||
<input type="number" min="0" bind:value={rating} />
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getContext} from 'svelte';
|
|
||||||
|
|
||||||
import Field from '$lib/components/Field/index.svelte';
|
|
||||||
|
|
||||||
export let layer = 1;
|
|
||||||
export let rating = 0;
|
|
||||||
|
|
||||||
const ship = getContext('ship');
|
|
||||||
|
|
||||||
$: ship?.dispatch_action( 'set_armour_layer', {layer,rating} );
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
input {
|
|
||||||
width: 5em;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,56 +0,0 @@
|
|||||||
<ShipItem {cost} {mass} >
|
|
||||||
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<div class="nbr_layers">
|
|
||||||
<Field label="armour layers">
|
|
||||||
<input type="number" min="0" bind:value={nbr_layers} />
|
|
||||||
</Field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="layers">
|
|
||||||
{#each armour as layer ( layer.layer )}
|
|
||||||
<Layer {...layer} on:ship_change/>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</ShipItem>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { createEventDispatcher} from 'svelte';
|
|
||||||
|
|
||||||
import ShipItem from '$lib/components/ShipItem/index.svelte';
|
|
||||||
import Field from '$lib/components/Field/index.svelte';
|
|
||||||
import Layer from './Layer/index.svelte';
|
|
||||||
import dux from '$lib/dux/structure/armour';
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
export let armour = [];
|
|
||||||
export let cost = 0;
|
|
||||||
export let mass = 0;
|
|
||||||
|
|
||||||
$: cost = _.sum( _.map( armour, 'cost' ) );
|
|
||||||
$: mass = _.sum( _.map( armour, 'mass' ) );
|
|
||||||
|
|
||||||
let nbr_layers = armour.length;
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
|
|
||||||
$: dispatch( 'ship_change', dux.actions.set_armour_nbr_layers(nbr_layers) );
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.layers {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
width: 5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,18 +0,0 @@
|
|||||||
import Armour from './index.svelte';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: "Armour",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const basic = () => ({
|
|
||||||
Component: Armour,
|
|
||||||
props: {
|
|
||||||
armour: [
|
|
||||||
{ layer: 1, rating: 12, cost: 1, mass: 2 },
|
|
||||||
{ layer: 2, rating: 12, cost: 1, mass: 2 },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
on: {
|
|
||||||
ship_change: ({detail}) => console.log(detail)
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,42 +0,0 @@
|
|||||||
<ShipItem { cost } { mass }>
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<Field label="screens">
|
|
||||||
<input type="number" bind:value={standard} min="0" />
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
<Field label="advanced screens">
|
|
||||||
<input type="number" bind:value={advanced} min="0" />
|
|
||||||
</Field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</ShipItem>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
|
|
||||||
import Section from '$lib/components/Section/index.svelte';
|
|
||||||
import Field from '$lib/components/Field/index.svelte';
|
|
||||||
import ShipItem from '../../ShipItem/index.svelte';
|
|
||||||
|
|
||||||
export let cost = 0;
|
|
||||||
export let mass = 0;
|
|
||||||
export let standard = 0;
|
|
||||||
export let advanced = 0;
|
|
||||||
|
|
||||||
let nbr_regular, nbr_advanced;
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
|
|
||||||
$: dispatch( 'set_screens', { standard, advanced } );
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
input {
|
|
||||||
width: 3em;
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
display: flex;
|
|
||||||
gap: 2em;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,38 +0,0 @@
|
|||||||
<ShipItem {cost} {mass}>
|
|
||||||
<Field label="streamlining">
|
|
||||||
<div>
|
|
||||||
<label>
|
|
||||||
<input type="radio" bind:group={type} value="none" />
|
|
||||||
none</label>
|
|
||||||
<label>
|
|
||||||
|
|
||||||
<input type="radio" bind:group={type} value="partial" />
|
|
||||||
partial</label>
|
|
||||||
<label>
|
|
||||||
<input type="radio" bind:group={type} value="full" />
|
|
||||||
full</label>
|
|
||||||
</div>
|
|
||||||
</Field>
|
|
||||||
</ShipItem>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import ShipItem from '$lib/components/ShipItem/index.svelte';
|
|
||||||
import Field from '$lib/components/Field/index.svelte';
|
|
||||||
|
|
||||||
import {getContext } from 'svelte';
|
|
||||||
|
|
||||||
export let type = 'none';
|
|
||||||
export let cost = 0;
|
|
||||||
export let mass = 0;
|
|
||||||
export let ship = getContext('ship');
|
|
||||||
|
|
||||||
$: ship?.dispatch_action( 'set_streamlining', type);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
div { display: flex }
|
|
||||||
label {
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,51 +0,0 @@
|
|||||||
<Section label="hull">
|
|
||||||
|
|
||||||
<ShipItem {cost} {mass} >
|
|
||||||
<Field label="integrity">
|
|
||||||
<input
|
|
||||||
bind:value={rating}
|
|
||||||
type="number" {min} {max} />
|
|
||||||
</Field>
|
|
||||||
</ShipItem>
|
|
||||||
|
|
||||||
|
|
||||||
<Screens {...screens} on:set_screens />
|
|
||||||
|
|
||||||
<Armour {armour} on:ship_change />
|
|
||||||
|
|
||||||
<Cargo {...cargo} on:set_cargo />
|
|
||||||
|
|
||||||
<Streamlining {...streamlining} />
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
|
|
||||||
import Section from '../Section/index.svelte';
|
|
||||||
import Field from '../Field/index.svelte';
|
|
||||||
import ShipItem from '../ShipItem/index.svelte';
|
|
||||||
import Screens from './Screens/index.svelte';
|
|
||||||
import Armour from './Armour/index.svelte';
|
|
||||||
import Cargo from './Cargo/index.svelte';
|
|
||||||
import Streamlining from './Streamlining/index.svelte';
|
|
||||||
|
|
||||||
export let cost, mass, ship_mass, rating, screens, armour = (
|
|
||||||
0, 0, 10, 1, [], []
|
|
||||||
);
|
|
||||||
|
|
||||||
export let cargo = {};
|
|
||||||
export let streamlining = {};
|
|
||||||
|
|
||||||
let min, max;
|
|
||||||
$: min = Math.ceil(ship_mass / 10);
|
|
||||||
$: max = ship_mass;
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
|
|
||||||
$: dispatch( 'change_hull', { rating } );
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
input { width: 5em; }
|
|
||||||
</style>
|
|
@ -1,23 +0,0 @@
|
|||||||
import Component from '.';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: "printouts/hull/integrity"
|
|
||||||
};
|
|
||||||
|
|
||||||
export const basic = () => ({
|
|
||||||
Component,
|
|
||||||
props: {
|
|
||||||
ship_mass: 50,
|
|
||||||
rating: 14,
|
|
||||||
advanced: false,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export const advanced = () => ({
|
|
||||||
Component,
|
|
||||||
props: {
|
|
||||||
ship_mass: 50,
|
|
||||||
rating: 14,
|
|
||||||
advanced: true,
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,13 +0,0 @@
|
|||||||
import Component from '.';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: "printouts/main_systems"
|
|
||||||
};
|
|
||||||
|
|
||||||
export const basic = () => ({
|
|
||||||
Component,
|
|
||||||
props: {
|
|
||||||
ftl: 'standard',
|
|
||||||
engine: 4,
|
|
||||||
}
|
|
||||||
})
|
|
@ -1,33 +0,0 @@
|
|||||||
import Component from '.';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: "printouts/weapons"
|
|
||||||
};
|
|
||||||
|
|
||||||
export const basic = () => ({
|
|
||||||
Component,
|
|
||||||
props: {
|
|
||||||
"weapons": [
|
|
||||||
{
|
|
||||||
"weapon_type": "submunition",
|
|
||||||
"arcs": [
|
|
||||||
"F"
|
|
||||||
],
|
|
||||||
"mass": 1,
|
|
||||||
"cost": 3,
|
|
||||||
"id": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_type": "beam",
|
|
||||||
"weapon_class": "2",
|
|
||||||
"arcs": [
|
|
||||||
"A",
|
|
||||||
"AS",
|
|
||||||
"FS"
|
|
||||||
],
|
|
||||||
"mass": 2,
|
|
||||||
"cost": 6,
|
|
||||||
"id": 2
|
|
||||||
}, ]
|
|
||||||
}
|
|
||||||
})
|
|
@ -1,53 +0,0 @@
|
|||||||
<aside class="ship-sheet" transition:fade>
|
|
||||||
<Identification {...ship.general} />
|
|
||||||
|
|
||||||
<Weapons weapons={ship.weaponry.weapons} />
|
|
||||||
|
|
||||||
<div class="section-2">
|
|
||||||
<Hull structure={ship.structure}
|
|
||||||
ship_mass={ship.general.mass} />
|
|
||||||
|
|
||||||
<Systems
|
|
||||||
firecons={ship.weaponry.firecons.nbr}
|
|
||||||
screens={ship.structure.screens}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<MainSystems
|
|
||||||
ftl={ship.ftl.type}
|
|
||||||
engine={ship.engine.rating}
|
|
||||||
/>
|
|
||||||
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
import Identification from './Identification/index.svelte';
|
|
||||||
import MainSystems from './MainSystems/index.svelte';
|
|
||||||
import Hull from './Hull/index.svelte';
|
|
||||||
import Weapons from './Weapons/index.svelte';
|
|
||||||
import Systems from './Systems/index.svelte';
|
|
||||||
|
|
||||||
export let ship;
|
|
||||||
|
|
||||||
import { fly, fade } from 'svelte/transition';
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.ship-sheet {
|
|
||||||
width: 4.25in;
|
|
||||||
height: 5.5in;
|
|
||||||
border: 1px solid black;
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-2 {
|
|
||||||
display: flex;
|
|
||||||
align-items: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,114 +0,0 @@
|
|||||||
export default {
|
|
||||||
"ftl": {
|
|
||||||
"mass": 0,
|
|
||||||
"cost": 0,
|
|
||||||
"type": "standard"
|
|
||||||
},
|
|
||||||
"engine": {
|
|
||||||
"mass": 40,
|
|
||||||
"cost": 80,
|
|
||||||
"rating": 6,
|
|
||||||
"advanced": false
|
|
||||||
},
|
|
||||||
"general": {
|
|
||||||
"ship_class": "Deviant",
|
|
||||||
"name": "",
|
|
||||||
"ship_type": "Battleship",
|
|
||||||
"mass": 132,
|
|
||||||
"used_mass": 131,
|
|
||||||
"cost": 415
|
|
||||||
},
|
|
||||||
"weaponry": {
|
|
||||||
"firecons": {
|
|
||||||
"nbr": 5,
|
|
||||||
"mass": 5,
|
|
||||||
"cost": 20
|
|
||||||
},
|
|
||||||
"weapons": [
|
|
||||||
{
|
|
||||||
"weapon_type": "submunition",
|
|
||||||
"arcs": [
|
|
||||||
"F"
|
|
||||||
],
|
|
||||||
"mass": 1,
|
|
||||||
"cost": 3,
|
|
||||||
"id": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_type": "beam",
|
|
||||||
"weapon_class": "2",
|
|
||||||
"arcs": [
|
|
||||||
"A",
|
|
||||||
"AS",
|
|
||||||
"FS"
|
|
||||||
],
|
|
||||||
"mass": 2,
|
|
||||||
"cost": 6,
|
|
||||||
"id": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_type": "pds",
|
|
||||||
"mass": 1,
|
|
||||||
"cost": 3,
|
|
||||||
"id": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"adfc": {
|
|
||||||
"rating": 0,
|
|
||||||
"cost": 0,
|
|
||||||
"mass": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"structure": {
|
|
||||||
"mass": 0,
|
|
||||||
"cost": 0,
|
|
||||||
"hull": {
|
|
||||||
"rating": 22,
|
|
||||||
"advanced": false,
|
|
||||||
"cost": 44,
|
|
||||||
"mass": 22
|
|
||||||
},
|
|
||||||
"screens": {
|
|
||||||
"standard": 2,
|
|
||||||
"advanced": 1,
|
|
||||||
"cost": 105,
|
|
||||||
"mass": 35
|
|
||||||
},
|
|
||||||
"armour": [
|
|
||||||
{
|
|
||||||
"layer": 1,
|
|
||||||
"rating": 7,
|
|
||||||
"cost": 14,
|
|
||||||
"mass": 14
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"layer": 2,
|
|
||||||
"rating": 2,
|
|
||||||
"cost": 8,
|
|
||||||
"mass": 4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"layer": 3,
|
|
||||||
"rating": 0,
|
|
||||||
"cost": 0,
|
|
||||||
"mass": 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"cargo": {
|
|
||||||
"space": 7,
|
|
||||||
"cost": 0,
|
|
||||||
"mass": 7
|
|
||||||
},
|
|
||||||
"streamlining": {
|
|
||||||
"type": "none",
|
|
||||||
"cost": 0,
|
|
||||||
"mass": 0
|
|
||||||
},
|
|
||||||
"carrier": {
|
|
||||||
"bays": 0,
|
|
||||||
"cost": 0,
|
|
||||||
"mass": 0,
|
|
||||||
"squadrons": []
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
import Print from './index.svelte';
|
|
||||||
import sample from './sample';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: "printouts"
|
|
||||||
};
|
|
||||||
|
|
||||||
export const basic = () => ({
|
|
||||||
Component: Print,
|
|
||||||
props: {
|
|
||||||
ship: sample
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,18 +0,0 @@
|
|||||||
|
|
||||||
<Section label="propulsion">
|
|
||||||
|
|
||||||
<Engine {...engine} on:change_engine />
|
|
||||||
|
|
||||||
<Ftl {...ftl} on:change_ftl />
|
|
||||||
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Ftl from '../Ftl/index.svelte';
|
|
||||||
import Engine from '../Engine/index.svelte';
|
|
||||||
import Section from '../Section/index.svelte';
|
|
||||||
|
|
||||||
export let ftl = {};
|
|
||||||
export let engine = {};
|
|
||||||
|
|
||||||
</script>
|
|
@ -1,47 +0,0 @@
|
|||||||
<div>
|
|
||||||
<Field label="ship class" value={general.ship_class}
|
|
||||||
on:change={change_class} />
|
|
||||||
|
|
||||||
<Field label="ship type">
|
|
||||||
<select value={ship_type} on:change={change_ship_type}>
|
|
||||||
{#each ship_types as type (type)}
|
|
||||||
<option>{type}</option>
|
|
||||||
{/each}
|
|
||||||
</select>
|
|
||||||
</Field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getContext } from 'svelte';
|
|
||||||
|
|
||||||
import Field from '$lib/components/Field/index.svelte';
|
|
||||||
import { candidate_ship_types } from '../../dux/ship_types';
|
|
||||||
|
|
||||||
export let ship = getContext('ship');
|
|
||||||
let general;
|
|
||||||
$: general = $ship.general;
|
|
||||||
|
|
||||||
const change_class = (event) => ship.dispatch(
|
|
||||||
ship.actions.set_ship_class(event.target.value)
|
|
||||||
);
|
|
||||||
|
|
||||||
let ship_type;
|
|
||||||
$: ship_type = $ship.general.ship_type;
|
|
||||||
|
|
||||||
const change_ship_type = ({ target: {value}}) =>
|
|
||||||
ship.dispatch.set_ship_type(value);
|
|
||||||
|
|
||||||
let ship_types;
|
|
||||||
$: ship_types = candidate_ship_types($ship.general.mass,$ship.carrier.bays>0).map(
|
|
||||||
({name}) => name
|
|
||||||
);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
div {
|
|
||||||
display: flex;
|
|
||||||
align-items: end;
|
|
||||||
gap: 2em;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
<svg width="{size}px" height="{size}px">
|
|
||||||
{#each all_arcs as arc (arc)}
|
|
||||||
<Arc {arc} radius={size/2}
|
|
||||||
active={selected.includes(arc)}
|
|
||||||
on:click={()=>click_arc(arc)}
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
<circle cx="50%" cy="50%" r={size /3} />
|
|
||||||
<slot />
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Arc from '../../Weapons/Arc.svelte';
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
|
|
||||||
const all_arcs = [ 'FS', 'F', 'FP', 'AP', 'A', 'AS' ];
|
|
||||||
|
|
||||||
export let selected = [];
|
|
||||||
export let size = 60;
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
|
|
||||||
const click_arc = arc => dispatch('click_arc',arc);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
circle {
|
|
||||||
fill: white;
|
|
||||||
}
|
|
||||||
</style>
|
|
Before Width: | Height: | Size: 637 B |
@ -1,37 +0,0 @@
|
|||||||
<label> needle weapon</label>
|
|
||||||
<Arcs selected={arcs} on:click_arc={({detail}) => click_arc(detail)} />
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {getContext } from 'svelte';
|
|
||||||
import Arcs from '../Arcs/index.svelte';
|
|
||||||
import dux from '$lib/dux';
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
|
|
||||||
const all_arcs = [ 'FS', 'F', 'FP', 'AP', 'A', 'AS' ];
|
|
||||||
|
|
||||||
export let arcs = ['F'];
|
|
||||||
export let ship_change = getContext('ship_change') || ( () => {} );
|
|
||||||
|
|
||||||
const click_arc = (arc) => {
|
|
||||||
if( arcs[0] === arc ) return;
|
|
||||||
arcs = [ arc ];
|
|
||||||
}
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
let cache;
|
|
||||||
$: cache = arcs.join(":");
|
|
||||||
|
|
||||||
$: dispatch( 'change', {
|
|
||||||
arcs: cache.split(":"),
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.arc {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
<label> submunition pack</label>
|
|
||||||
<Arcs selected={arcs} on:click_arc={({detail}) => click_arc(detail)} />
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {getContext } from 'svelte';
|
|
||||||
import Arcs from '../Arcs/index.svelte';
|
|
||||||
import dux from '$lib/dux';
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
|
|
||||||
const all_arcs = [ 'FS', 'F', 'FP', 'AP', 'A', 'AS' ];
|
|
||||||
|
|
||||||
export let arcs = ['F'];
|
|
||||||
export let ship_change = getContext('ship_change') || ( () => {} );
|
|
||||||
|
|
||||||
const click_arc = (arc) => {
|
|
||||||
if( arcs[0] === arc ) return;
|
|
||||||
arcs = [ arc ];
|
|
||||||
}
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
let cache;
|
|
||||||
$: cache = arcs.join(":");
|
|
||||||
|
|
||||||
$: dispatch( 'change', {
|
|
||||||
arcs: cache.split(":"),
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.arc {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,202 +0,0 @@
|
|||||||
<input class="add-weapon button small blue" type="button" value="add"
|
|
||||||
on:click={add} />
|
|
||||||
|
|
||||||
<div class="weapon">
|
|
||||||
|
|
||||||
<select bind:value={weapon_type}>
|
|
||||||
<option>beam</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<select bind:value={weapon_class}>
|
|
||||||
<option>1</option>
|
|
||||||
<option>2</option>
|
|
||||||
<option>3</option>
|
|
||||||
<option>4</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<select bind:value={nbr_arcs}>
|
|
||||||
{#each arc_options[weapon_class] as opt (opt)}
|
|
||||||
<option>{opt}</option>
|
|
||||||
{/each}
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<svg width="60px" height="60px">
|
|
||||||
{#each arcs as arc (arc)}
|
|
||||||
<Arc {arc} radius={30}
|
|
||||||
active={selected_arc[arc]}
|
|
||||||
on:click={()=>click_arc(arc)}
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
<circle cx="30" cy="30" r="15" />
|
|
||||||
|
|
||||||
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<div>{weapon.cost}</div>
|
|
||||||
<div>{weapon.mass}</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
let weapon_type = 'beam';
|
|
||||||
let weapon_class = 1;
|
|
||||||
let nbr_arcs = 6;
|
|
||||||
$: nbr_arcs = arc_options[weapon_class][0];
|
|
||||||
|
|
||||||
import Arc from './Arc.svelte';
|
|
||||||
import { weapon_cost_mass } from '../../dux/weapons/rules.js';
|
|
||||||
|
|
||||||
const arcs = [
|
|
||||||
'FS', 'F', 'FP', 'AP', 'A', 'AS'
|
|
||||||
];
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
|
|
||||||
let arc_options = {
|
|
||||||
1: [ 6],
|
|
||||||
2: [ 3, 6 ],
|
|
||||||
3: [ 1, 2, 3, 4, 5, 6, 'broadside' ],
|
|
||||||
4: [ 1, 2, 3, 4, 5, 6, 'broadside' ]
|
|
||||||
};
|
|
||||||
|
|
||||||
let selected_arc = Object.fromEntries(
|
|
||||||
arcs.map( arc => [ arc, false ] )
|
|
||||||
);
|
|
||||||
|
|
||||||
const nbr_selected_arcs = () => Object.values(selected_arc).filter(
|
|
||||||
x => x ).length;
|
|
||||||
|
|
||||||
$: if ( nbr_selected_arcs() !== nbr_arcs ) {
|
|
||||||
if( nbr_arcs === 'broadside' ) {
|
|
||||||
const new_arcs = {};
|
|
||||||
arcs.forEach( arc => new_arcs[arc] = true );
|
|
||||||
new_arcs.A = false;
|
|
||||||
new_arcs.F = false;
|
|
||||||
selected_arc = new_arcs;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
|
|
||||||
let first_index = arcs.findIndex( arc => selected_arc[arc] );
|
|
||||||
if( first_index === -1 ) first_index = 0;
|
|
||||||
|
|
||||||
const new_arcs = {};
|
|
||||||
arcs.forEach( arc => new_arcs[arc] = false );
|
|
||||||
|
|
||||||
_.range(nbr_arcs).forEach( i => {
|
|
||||||
new_arcs[ arcs[first_index] ] = true;
|
|
||||||
first_index = ( first_index + 1 ) % arcs.length;
|
|
||||||
});
|
|
||||||
|
|
||||||
selected_arc = new_arcs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const click_arc = (first_arc) => {
|
|
||||||
if( nbr_arcs === 'broadside' ) return;
|
|
||||||
|
|
||||||
let first_index = arcs.findIndex( arc => arc === first_arc );
|
|
||||||
|
|
||||||
const new_arcs = {};
|
|
||||||
arcs.forEach( arc => new_arcs[arc] = false );
|
|
||||||
|
|
||||||
_.range(nbr_arcs).forEach( i => {
|
|
||||||
console.log(first_index);
|
|
||||||
console.log(selected_arc);
|
|
||||||
new_arcs[ arcs[first_index] ] = true;
|
|
||||||
first_index = ( first_index + 1 ) % arcs.length;
|
|
||||||
});
|
|
||||||
|
|
||||||
selected_arc = new_arcs;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
let weapon = {};
|
|
||||||
$: weapon= {
|
|
||||||
weapon_type,
|
|
||||||
weapon_class,
|
|
||||||
arcs,
|
|
||||||
...weapon_cost_mass({ weapon_type, weapon_class, arcs: arcs.filter(
|
|
||||||
arc => selected_arc[arc]
|
|
||||||
) })
|
|
||||||
};
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
|
|
||||||
const add = () => {
|
|
||||||
dispatch('add_weapon', weapon);
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
.weapon {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.weapon > * {
|
|
||||||
margin-right: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arcs {
|
|
||||||
display: grid;
|
|
||||||
grid-template-rows: 1fr 1fr 1fr 1fr;
|
|
||||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
|
||||||
align-items: center;
|
|
||||||
justify-items: center;
|
|
||||||
width: 6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.arc input {
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.arc.F {
|
|
||||||
grid-column: 2 / span 2;
|
|
||||||
grid-row: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arc.FS {
|
|
||||||
grid-column: 1;
|
|
||||||
grid-row: 1 / span 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arc.FP {
|
|
||||||
grid-column: 4;
|
|
||||||
grid-row: 1 / span 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arc.AS {
|
|
||||||
grid-column: 1;
|
|
||||||
grid-row: 3 / span 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arc.AP {
|
|
||||||
grid-column: 4;
|
|
||||||
grid-row: 3 / span 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arc.A {
|
|
||||||
grid-column: 2 / span 2;
|
|
||||||
grid-row: 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arc {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-weapon {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
circle {
|
|
||||||
fill: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,50 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let arc;
|
|
||||||
export let radius;
|
|
||||||
export let active = false;
|
|
||||||
|
|
||||||
const rotation = {
|
|
||||||
F: 0,
|
|
||||||
FS: 300,
|
|
||||||
AS: 240,
|
|
||||||
A: 180,
|
|
||||||
AP: 120,
|
|
||||||
FP: 60,
|
|
||||||
};
|
|
||||||
|
|
||||||
let y, x_delta;
|
|
||||||
$: y = Math.round( radius * ( 1 - Math.sin(60/180*Math.PI) ) );
|
|
||||||
$: x_delta = Math.round( radius*Math.cos(60/180*Math.PI) );
|
|
||||||
|
|
||||||
let path;
|
|
||||||
$: path = `M ${radius},${radius} L ${radius-x_delta},${y} A ${radius},${radius} 0 0 1 ${radius+x_delta},${y} Z`;
|
|
||||||
|
|
||||||
let transform;
|
|
||||||
$: transform = `rotate(${rotation[arc]},${radius},${radius})`
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<g { transform }>
|
|
||||||
<path d={path} class:active on:click />
|
|
||||||
</g>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
path {
|
|
||||||
fill: lightgrey;
|
|
||||||
stroke: white;
|
|
||||||
stroke-width: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
path:hover {
|
|
||||||
fill: pink;
|
|
||||||
}
|
|
||||||
|
|
||||||
path.active:hover {
|
|
||||||
fill: pink;
|
|
||||||
}
|
|
||||||
|
|
||||||
path.active {
|
|
||||||
fill: #313131;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
import AddWeapon from './Add.svelte';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: "add weapon",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const beam = () => ({
|
|
||||||
Component: AddWeapon,
|
|
||||||
});
|
|
||||||
|
|
3
src/global.d.ts
vendored
3
src/global.d.ts
vendored
@ -1,3 +0,0 @@
|
|||||||
/// <reference types="@sveltejs/kit" />
|
|
||||||
/// <reference types="svelte" />
|
|
||||||
/// <reference types="vite/client" />
|
|
@ -1,10 +1,5 @@
|
|||||||
<Ribbon />
|
|
||||||
<Header />
|
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
<button class="button is-danger" type="button" on:click={reset}
|
<button class="button is-danger" type="button" on:click={reset}>reset</button>
|
||||||
>reset</button
|
|
||||||
>
|
|
||||||
|
|
||||||
<div class="spacer" />
|
<div class="spacer" />
|
||||||
|
|
||||||
@ -18,9 +13,7 @@
|
|||||||
<button class="button" on:click={() => set_output("json")}>json</button>
|
<button class="button" on:click={() => set_output("json")}>json</button>
|
||||||
</p>
|
</p>
|
||||||
<p class="control">
|
<p class="control">
|
||||||
<button class="button" on:click={() => set_output("print")}
|
<button class="button" on:click={() => set_output("print")}>print</button>
|
||||||
>print</button
|
|
||||||
>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@ -68,12 +61,7 @@
|
|||||||
<AddWeapon />
|
<AddWeapon />
|
||||||
|
|
||||||
{#each weapons as weapon (weapon.id)}
|
{#each weapons as weapon (weapon.id)}
|
||||||
<Weapon
|
<Weapon {weapon} id={weapon.id} cost={weapon.cost} mass={weapon.mass} />
|
||||||
{weapon}
|
|
||||||
id={weapon.id}
|
|
||||||
cost={weapon.cost}
|
|
||||||
mass={weapon.mass}
|
|
||||||
/>
|
|
||||||
{/each}
|
{/each}
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
@ -89,7 +77,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { setContext } from "svelte";
|
import { setContext } from "svelte";
|
||||||
|
|
||||||
import Header from "./Header.svelte";
|
|
||||||
import Ribbon from "./Ribbon.svelte";
|
import Ribbon from "./Ribbon.svelte";
|
||||||
import shipStore from "../stores/ship";
|
import shipStore from "../stores/ship";
|
||||||
import OutputJson from "./Output/Json.svelte";
|
import OutputJson from "./Output/Json.svelte";
|
10
src/lib/components/App.svelte
Normal file
10
src/lib/components/App.svelte
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Ribbon />
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Ribbon from "./Ribbon.svelte";
|
||||||
|
import Header from "./Header.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
14
src/lib/components/Carrier/Carrier.story.svelte
Normal file
14
src/lib/components/Carrier/Carrier.story.svelte
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<Carrier />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Carrier from "./index.svelte";
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
bays: 3,
|
||||||
|
squadrons: [
|
||||||
|
{ id: 1, type: "standard", ftl: false, nbr_fighters: 6 },
|
||||||
|
{ id: 2, type: "fast", ftl: false, nbr_fighters: 6 },
|
||||||
|
{ id: 3, type: "none", ftl: false, nbr_fighters: 6 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
</script>
|
@ -1,4 +1,4 @@
|
|||||||
<ShipItem {cost} {mass} >
|
<ShipItem {cost} {mass}>
|
||||||
<Field label={`squadron ${id}`}>
|
<Field label={`squadron ${id}`}>
|
||||||
<select bind:value={type}>
|
<select bind:value={type}>
|
||||||
{#each types as type (type)}
|
{#each types as type (type)}
|
||||||
@ -9,30 +9,29 @@
|
|||||||
</ShipItem>
|
</ShipItem>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {getContext } from 'svelte';
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
import Section from "$lib/components/Section/index.svelte";
|
import Section from "$lib/components/Section/index.svelte";
|
||||||
import Field from "$lib/components/Field/index.svelte";
|
import Field from "$lib/components/Field/index.svelte";
|
||||||
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
||||||
import dux from '$lib/dux/carrier';
|
import dux from "$lib/dux/carrier";
|
||||||
import squadron_types from '$lib/dux/carrier/squadron_types';
|
import squadron_types from "$lib/dux/carrier/squadron_types";
|
||||||
|
|
||||||
const types = squadron_types.map( ({type}) => type );
|
const types = squadron_types.map(({ type }) => type);
|
||||||
|
|
||||||
export let id = 1;
|
export let id = 1;
|
||||||
export let type = "standard";
|
export let type = "standard";
|
||||||
export let ftl = false;
|
export let ftl = false;
|
||||||
export let cost =0;
|
export let cost = 0;
|
||||||
export let mass = 0;
|
export let mass = 0;
|
||||||
|
|
||||||
export let ship = getContext('ship');
|
export let ship = getContext("ship");
|
||||||
|
|
||||||
$: ship?.dispatch_action('set_squadron',{ id, type, });
|
|
||||||
|
|
||||||
|
$: ship?.dispatch_action("set_squadron", { id, type });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
div {
|
div {
|
||||||
background-color: red;
|
background-color: red;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,3 +1,4 @@
|
|||||||
|
<!--
|
||||||
<Section label="carrier">
|
<Section label="carrier">
|
||||||
<ShipItem {cost} {mass}>
|
<ShipItem {cost} {mass}>
|
||||||
<Field label="bays">
|
<Field label="bays">
|
||||||
@ -9,15 +10,18 @@
|
|||||||
<Squadron {...squad} />
|
<Squadron {...squad} />
|
||||||
{/each}
|
{/each}
|
||||||
</Section>
|
</Section>
|
||||||
|
-->
|
||||||
|
|
||||||
|
Hey!
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte";
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
import Section from "../Section/index.svelte";
|
/* import Section from "../Section/index.svelte"; */
|
||||||
import Field from "../Field/index.svelte";
|
/* import Field from "../Field/index.svelte"; */
|
||||||
import ShipItem from "../ShipItem/index.svelte";
|
/* import ShipItem from "../ShipItem/index.svelte"; */
|
||||||
import Squadron from "./Squadron/index.svelte";
|
// import Squadron from "./Squadron/index.svelte";
|
||||||
import dux from "../../dux/carrier";
|
// import dux from "../../dux/carrier";
|
||||||
|
|
||||||
export let bays = 0;
|
export let bays = 0;
|
||||||
export let squadrons = [];
|
export let squadrons = [];
|
||||||
@ -26,6 +30,5 @@
|
|||||||
|
|
||||||
export let ship = getContext("ship");
|
export let ship = getContext("ship");
|
||||||
|
|
||||||
$: ship?.dispatch_action('set_carrier_bays',bays);
|
$: ship?.dispatch_action("set_carrier_bays", bays);
|
||||||
|
|
||||||
</script>
|
</script>
|
20
src/lib/components/Carrier/stories.js
Normal file
20
src/lib/components/Carrier/stories.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { action } from "@storybook/addon-actions";
|
||||||
|
|
||||||
|
import Carrier from "./index.svelte";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "Carrier",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const basic = () => ({
|
||||||
|
Component: Carrier,
|
||||||
|
props: {
|
||||||
|
bays: 3,
|
||||||
|
squadrons: [
|
||||||
|
{ id: 1, type: "standard", ftl: false, nbr_fighters: 6 },
|
||||||
|
{ id: 2, type: "fast", ftl: false, nbr_fighters: 6 },
|
||||||
|
{ id: 3, type: "none", ftl: false, nbr_fighters: 6 },
|
||||||
|
],
|
||||||
|
ship_change: action("ship_change"),
|
||||||
|
},
|
||||||
|
});
|
5
src/lib/components/Cost.story.svelte
Normal file
5
src/lib/components/Cost.story.svelte
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<Cost cost={12} />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Cost from "./Cost.svelte";
|
||||||
|
</script>
|
@ -5,5 +5,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
div:after { content: '\00A4'; margin-left: 0.5em; }
|
div:after {
|
||||||
|
content: "\00A4";
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
29
src/lib/components/CostMass.svelte
Normal file
29
src/lib/components/CostMass.svelte
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<div class="mass">{mass}</div>
|
||||||
|
<div class="cost">{cost}</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export let mass;
|
||||||
|
export let cost;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.cost {
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
|
.mass {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 0.75em;
|
||||||
|
}
|
||||||
|
.cost:after {
|
||||||
|
content: "\00A4";
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
.mass:after {
|
||||||
|
content: url("/mass.svg");
|
||||||
|
width: 0.75em;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
</style>
|
33
src/lib/components/Engine/Engine.stories.svelte
Normal file
33
src/lib/components/Engine/Engine.stories.svelte
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<Meta
|
||||||
|
title="Engine"
|
||||||
|
component={Engine}
|
||||||
|
argTypes={{
|
||||||
|
rating: { type: "number", defaultValue: 6 },
|
||||||
|
advanced: { type: "boolean", defaultValue: false },
|
||||||
|
reqs: { type: "object", defaultValue: { cost: 6, mass: 3 } },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Story name="Primary" args={{}} />
|
||||||
|
|
||||||
|
<Template let:args>
|
||||||
|
<div style="width: 50em">
|
||||||
|
<Engine {...args} />
|
||||||
|
</div>
|
||||||
|
</Template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
|
||||||
|
import { action } from "@storybook/addon-actions";
|
||||||
|
|
||||||
|
import { setContext } from "svelte";
|
||||||
|
|
||||||
|
import Engine from "./index.svelte";
|
||||||
|
|
||||||
|
setContext("ship", {
|
||||||
|
dispatch: (type, detail) => action(type)(detail),
|
||||||
|
});
|
||||||
|
|
||||||
|
let advanced = false;
|
||||||
|
let rating = 0;
|
||||||
|
</script>
|
39
src/lib/components/Engine/index.svelte
Normal file
39
src/lib/components/Engine/index.svelte
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<ShipItem {...reqs}>
|
||||||
|
<div>
|
||||||
|
<Field label="thrust rating">
|
||||||
|
<input type="number" bind:value={rating} min="0" max="20" step="1" />
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<label><input type="checkbox" bind:checked={advanced} /> advanced</label>
|
||||||
|
</div>
|
||||||
|
</ShipItem>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
import Field from "$lib/components/Field/index.svelte";
|
||||||
|
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
||||||
|
|
||||||
|
export let reqs = {};
|
||||||
|
export let advanced = false;
|
||||||
|
export let rating = 0;
|
||||||
|
|
||||||
|
const ship = getContext("ship") || {
|
||||||
|
dispatch: (...args) => console.log(args),
|
||||||
|
};
|
||||||
|
|
||||||
|
$: ship.dispatch("setEngine", { rating, advanced });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
align-items: end;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
font-family: var(--main-font-family);
|
||||||
|
margin-left: 2em;
|
||||||
|
}
|
||||||
|
input[type="number"] {
|
||||||
|
width: 5em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,5 +1,5 @@
|
|||||||
<Field label="the label" />
|
<Field label="the label" />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Field from './index.svelte';
|
import Field from "./index.svelte";
|
||||||
</script>
|
</script>
|
32
src/lib/components/Field/index.svelte
Normal file
32
src/lib/components/Field/index.svelte
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<div>
|
||||||
|
{#if label}
|
||||||
|
<label>{label}</label>
|
||||||
|
{/if}
|
||||||
|
<slot>
|
||||||
|
<input type="text" {placeholder} {value} on:change />
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export let label = "";
|
||||||
|
export let value = "";
|
||||||
|
export let placeholder;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
font-family: var(--main-font-family);
|
||||||
|
}
|
||||||
|
div > :global(*) {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
div > label {
|
||||||
|
margin-left: 0em;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
font-size: var(--font-scale-8);
|
||||||
|
font-weight: lighter;
|
||||||
|
font-family: Dosis;
|
||||||
|
color: var(--indigo-dye);
|
||||||
|
}
|
||||||
|
</style>
|
12
src/lib/components/Field/stories.js
Normal file
12
src/lib/components/Field/stories.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import Component from "./index.svelte";
|
||||||
|
import BasicStory from "./BasicStory.svelte";
|
||||||
|
|
||||||
|
import "../../../public/global.css";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "Field",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const basic = () => ({
|
||||||
|
Component: BasicStory,
|
||||||
|
});
|
21
src/lib/components/Firecons.svelte
Normal file
21
src/lib/components/Firecons.svelte
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<ShipItem {cost} {mass}>
|
||||||
|
<Field label="firecons">
|
||||||
|
<input type="number" class="short" bind:value={nbr} />
|
||||||
|
</Field>
|
||||||
|
</ShipItem>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
import ShipItem from "./ShipItem/index.svelte";
|
||||||
|
import Field from "./Field/index.svelte";
|
||||||
|
|
||||||
|
export let nbr,
|
||||||
|
cost,
|
||||||
|
mass = (0, 0, 0);
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
$: dispatch("change_firecons", nbr);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
34
src/lib/components/Ftl/index.svelte
Normal file
34
src/lib/components/Ftl/index.svelte
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<ShipItem {mass} {cost}>
|
||||||
|
<Field label="FTL drive">
|
||||||
|
{#each types as t (t)}
|
||||||
|
<label
|
||||||
|
><input type="radio" bind:group={type} value={t} on:change={change} />
|
||||||
|
{t}
|
||||||
|
</label>
|
||||||
|
{/each}
|
||||||
|
</Field>
|
||||||
|
</ShipItem>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
import ShipItem from "../ShipItem/index.svelte";
|
||||||
|
import Field from "../Field/index.svelte";
|
||||||
|
|
||||||
|
export let type = "none";
|
||||||
|
export let cost = 0;
|
||||||
|
export let mass = 0;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
const change = () => dispatch("change_ftl", type);
|
||||||
|
|
||||||
|
const types = ["none", "standard", "advanced"];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
label {
|
||||||
|
display: inline;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
13
src/lib/components/Ftl/stories.js
Normal file
13
src/lib/components/Ftl/stories.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export default {
|
||||||
|
title: "FTL Drive",
|
||||||
|
};
|
||||||
|
|
||||||
|
import Component from ".";
|
||||||
|
import shipStore from "../../stores/ship.js";
|
||||||
|
|
||||||
|
export const basic = () => ({
|
||||||
|
Component,
|
||||||
|
props: {
|
||||||
|
ship: shipStore(),
|
||||||
|
},
|
||||||
|
});
|
30
src/lib/components/Header.svelte
Normal file
30
src/lib/components/Header.svelte
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<header>
|
||||||
|
<h1>The Docks</h1>
|
||||||
|
<h2>
|
||||||
|
a <a href="https://shop.groundzerogames.co.uk/rules.html">Full Thrust</a> ship
|
||||||
|
builder
|
||||||
|
</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
header {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
width: var(--main-width);
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
h1,
|
||||||
|
h2 {
|
||||||
|
font-family: Faktos;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: right;
|
||||||
|
flex: 1;
|
||||||
|
padding-left: 2em;
|
||||||
|
font-size: var(--font-scale-12);
|
||||||
|
}
|
||||||
|
</style>
|
22
src/lib/components/Hull/Armour/Layer/index.svelte
Normal file
22
src/lib/components/Hull/Armour/Layer/index.svelte
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<Field label={`layer ${layer}`}>
|
||||||
|
<input type="number" min="0" bind:value={rating} />
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
|
import Field from "$lib/components/Field/index.svelte";
|
||||||
|
|
||||||
|
export let layer = 1;
|
||||||
|
export let rating = 0;
|
||||||
|
|
||||||
|
const ship = getContext("ship");
|
||||||
|
|
||||||
|
$: ship?.dispatch_action("set_armour_layer", { layer, rating });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input {
|
||||||
|
width: 5em;
|
||||||
|
}
|
||||||
|
</style>
|
48
src/lib/components/Hull/Armour/index.svelte
Normal file
48
src/lib/components/Hull/Armour/index.svelte
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<ShipItem {cost} {mass}>
|
||||||
|
<div>
|
||||||
|
<div class="nbr_layers">
|
||||||
|
<Field label="armour layers">
|
||||||
|
<input type="number" min="0" bind:value={nbr_layers} />
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layers">
|
||||||
|
{#each armour as layer (layer.layer)}
|
||||||
|
<Layer {...layer} on:ship_change />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ShipItem>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
||||||
|
import Field from "$lib/components/Field/index.svelte";
|
||||||
|
import Layer from "./Layer/index.svelte";
|
||||||
|
import dux from "$lib/dux/structure/armour";
|
||||||
|
import _ from "lodash";
|
||||||
|
|
||||||
|
export let armour = [];
|
||||||
|
export let cost = 0;
|
||||||
|
export let mass = 0;
|
||||||
|
|
||||||
|
$: cost = _.sum(_.map(armour, "cost"));
|
||||||
|
$: mass = _.sum(_.map(armour, "mass"));
|
||||||
|
|
||||||
|
let nbr_layers = armour.length;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
$: dispatch("ship_change", dux.actions.set_armour_nbr_layers(nbr_layers));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.layers {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 5em;
|
||||||
|
}
|
||||||
|
</style>
|
18
src/lib/components/Hull/Armour/stories.js
Normal file
18
src/lib/components/Hull/Armour/stories.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import Armour from "./index.svelte";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "Armour",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const basic = () => ({
|
||||||
|
Component: Armour,
|
||||||
|
props: {
|
||||||
|
armour: [
|
||||||
|
{ layer: 1, rating: 12, cost: 1, mass: 2 },
|
||||||
|
{ layer: 2, rating: 12, cost: 1, mass: 2 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
ship_change: ({ detail }) => console.log(detail),
|
||||||
|
},
|
||||||
|
});
|
@ -17,12 +17,10 @@
|
|||||||
export let mass = 0;
|
export let mass = 0;
|
||||||
|
|
||||||
$: ship?.dispatch_action("set_cargo", space);
|
$: ship?.dispatch_action("set_cargo", space);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
input {
|
input {
|
||||||
width: 5em;
|
width: 5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
40
src/lib/components/Hull/Screens/index.svelte
Normal file
40
src/lib/components/Hull/Screens/index.svelte
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<ShipItem {cost} {mass}>
|
||||||
|
<div>
|
||||||
|
<Field label="screens">
|
||||||
|
<input type="number" bind:value={standard} min="0" />
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<Field label="advanced screens">
|
||||||
|
<input type="number" bind:value={advanced} min="0" />
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
</ShipItem>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
import Section from "$lib/components/Section/index.svelte";
|
||||||
|
import Field from "$lib/components/Field/index.svelte";
|
||||||
|
import ShipItem from "../../ShipItem/index.svelte";
|
||||||
|
|
||||||
|
export let cost = 0;
|
||||||
|
export let mass = 0;
|
||||||
|
export let standard = 0;
|
||||||
|
export let advanced = 0;
|
||||||
|
|
||||||
|
let nbr_regular, nbr_advanced;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
$: dispatch("set_screens", { standard, advanced });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input {
|
||||||
|
width: 3em;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
gap: 2em;
|
||||||
|
}
|
||||||
|
</style>
|
41
src/lib/components/Hull/Streamlining/index.svelte
Normal file
41
src/lib/components/Hull/Streamlining/index.svelte
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<ShipItem {cost} {mass}>
|
||||||
|
<Field label="streamlining">
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
<input type="radio" bind:group={type} value="none" />
|
||||||
|
none</label
|
||||||
|
>
|
||||||
|
<label>
|
||||||
|
<input type="radio" bind:group={type} value="partial" />
|
||||||
|
partial</label
|
||||||
|
>
|
||||||
|
<label>
|
||||||
|
<input type="radio" bind:group={type} value="full" />
|
||||||
|
full</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</Field>
|
||||||
|
</ShipItem>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
||||||
|
import Field from "$lib/components/Field/index.svelte";
|
||||||
|
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
|
export let type = "none";
|
||||||
|
export let cost = 0;
|
||||||
|
export let mass = 0;
|
||||||
|
export let ship = getContext("ship");
|
||||||
|
|
||||||
|
$: ship?.dispatch_action("set_streamlining", type);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
51
src/lib/components/Hull/index.svelte
Normal file
51
src/lib/components/Hull/index.svelte
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<Section label="hull">
|
||||||
|
<ShipItem {cost} {mass}>
|
||||||
|
<Field label="integrity">
|
||||||
|
<input bind:value={rating} type="number" {min} {max} />
|
||||||
|
</Field>
|
||||||
|
</ShipItem>
|
||||||
|
|
||||||
|
<Screens {...screens} on:set_screens />
|
||||||
|
|
||||||
|
<Armour {armour} on:ship_change />
|
||||||
|
|
||||||
|
<Cargo {...cargo} on:set_cargo />
|
||||||
|
|
||||||
|
<Streamlining {...streamlining} />
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
import Section from "../Section/index.svelte";
|
||||||
|
import Field from "../Field/index.svelte";
|
||||||
|
import ShipItem from "../ShipItem/index.svelte";
|
||||||
|
import Screens from "./Screens/index.svelte";
|
||||||
|
import Armour from "./Armour/index.svelte";
|
||||||
|
import Cargo from "./Cargo/index.svelte";
|
||||||
|
import Streamlining from "./Streamlining/index.svelte";
|
||||||
|
|
||||||
|
export let cost,
|
||||||
|
mass,
|
||||||
|
ship_mass,
|
||||||
|
rating,
|
||||||
|
screens,
|
||||||
|
armour = (0, 0, 10, 1, [], []);
|
||||||
|
|
||||||
|
export let cargo = {};
|
||||||
|
export let streamlining = {};
|
||||||
|
|
||||||
|
let min, max;
|
||||||
|
$: min = Math.ceil(ship_mass / 10);
|
||||||
|
$: max = ship_mass;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
$: dispatch("change_hull", { rating });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input {
|
||||||
|
width: 5em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -24,9 +24,9 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The app is mostly developed for Firefox. I also check as much as I can
|
The app is mostly developed for Firefox. I also check as much as I can that
|
||||||
that I don't mess things too badly on Chrome. For the other browsers...
|
I don't mess things too badly on Chrome. For the other browsers... caveat
|
||||||
caveat emptor.
|
emptor.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
@ -5,13 +5,13 @@
|
|||||||
<script>
|
<script>
|
||||||
export let ship = {};
|
export let ship = {};
|
||||||
let json;
|
let json;
|
||||||
$: json = JSON.stringify(ship,null,2);
|
$: json = JSON.stringify(ship, null, 2);
|
||||||
|
|
||||||
import { fly, fade } from 'svelte/transition';
|
import { fly, fade } from "svelte/transition";
|
||||||
import {createEventDispatcher} from 'svelte';
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
const close = () => dispatch('close');
|
const close = () => dispatch("close");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -20,13 +20,11 @@
|
|||||||
font-size: var(--font-scale-9);
|
font-size: var(--font-scale-9);
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
height: 90%;
|
height: 90%;
|
||||||
|
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
aside {
|
aside {
|
||||||
|
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
border: 3px solid var(--indigo-dye);
|
border: 3px solid var(--indigo-dye);
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
@ -1,17 +1,15 @@
|
|||||||
<div class="layers">
|
<div class="layers">
|
||||||
{#each armour as layer (layer)}
|
{#each armour as layer (layer)}
|
||||||
<div class="layer">
|
<div class="layer">
|
||||||
{#each _.range(layer.rating) as i (i) }
|
{#each _.range(layer.rating) as i (i)}
|
||||||
<div class="cell">
|
<div class="cell" />
|
||||||
</div>
|
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import _ from 'lodash';
|
import _ from "lodash";
|
||||||
|
|
||||||
export let armour = [];
|
export let armour = [];
|
||||||
|
|
||||||
@ -19,14 +17,14 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.cell {
|
.cell {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
}
|
}
|
||||||
.layers {
|
.layers {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
@ -1,7 +1,7 @@
|
|||||||
<div>
|
<div>
|
||||||
{#each rows as row,i (i)}
|
{#each rows as row, i (i)}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{#each row as item,j (j)}
|
{#each row as item, j (j)}
|
||||||
<div class="cell">
|
<div class="cell">
|
||||||
{#if item}
|
{#if item}
|
||||||
<img src="icons/crew-star.svg" alt="crew loss threshold" />
|
<img src="icons/crew-star.svg" alt="crew loss threshold" />
|
||||||
@ -10,11 +10,10 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ceil } from '$lib/dux/utils';
|
import { ceil } from "$lib/dux/utils";
|
||||||
|
|
||||||
export let ship_mass = 0;
|
export let ship_mass = 0;
|
||||||
export let rating = 0;
|
export let rating = 0;
|
||||||
@ -27,45 +26,40 @@
|
|||||||
$: cells = Array(rating).fill(false);
|
$: cells = Array(rating).fill(false);
|
||||||
|
|
||||||
let dcp;
|
let dcp;
|
||||||
$: dcp= ceil(ship_mass/20);
|
$: dcp = ceil(ship_mass / 20);
|
||||||
|
|
||||||
$: cells = divide(cells, dcp).map(
|
$: cells = divide(cells, dcp)
|
||||||
g => {
|
.map((g) => {
|
||||||
g[g.length-1] = true;
|
g[g.length - 1] = true;
|
||||||
return g;
|
return g;
|
||||||
}
|
})
|
||||||
).flat();
|
.flat();
|
||||||
|
|
||||||
function divide(list, divider) {
|
function divide(list, divider) {
|
||||||
if( divider <= 1 ) return [ list ];
|
if (divider <= 1) return [list];
|
||||||
|
|
||||||
let div = list.length / divider;
|
let div = list.length / divider;
|
||||||
const mod = list.length % divider;
|
const mod = list.length % divider;
|
||||||
|
|
||||||
if(mod) div++;
|
if (mod) div++;
|
||||||
|
|
||||||
return [
|
return [list.slice(0, div), ...divide(list.slice(div), divider - 1)];
|
||||||
list.slice(0,div),
|
|
||||||
...divide( list.slice(div), divider-1 )
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let rows = [];
|
let rows = [];
|
||||||
$: rows = divide( cells, nbr_rows );
|
$: rows = divide(cells, nbr_rows);
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.row {
|
.row {
|
||||||
}
|
}
|
||||||
.cell {
|
.cell {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
}
|
}
|
||||||
img {
|
img {
|
||||||
width: 1em;
|
width: 1em;
|
||||||
}
|
}
|
23
src/lib/components/Output/Print/Hull/Integrity/stories.js
Normal file
23
src/lib/components/Output/Print/Hull/Integrity/stories.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import Component from ".";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "printouts/hull/integrity",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const basic = () => ({
|
||||||
|
Component,
|
||||||
|
props: {
|
||||||
|
ship_mass: 50,
|
||||||
|
rating: 14,
|
||||||
|
advanced: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const advanced = () => ({
|
||||||
|
Component,
|
||||||
|
props: {
|
||||||
|
ship_mass: 50,
|
||||||
|
rating: 14,
|
||||||
|
advanced: true,
|
||||||
|
},
|
||||||
|
});
|
@ -8,8 +8,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Integrity from './Integrity/index.svelte';
|
import Integrity from "./Integrity/index.svelte";
|
||||||
import Armour from './Armour/index.svelte';
|
import Armour from "./Armour/index.svelte";
|
||||||
|
|
||||||
export let structure = {};
|
export let structure = {};
|
||||||
export let ship_mass = 0;
|
export let ship_mass = 0;
|
@ -1,4 +1,6 @@
|
|||||||
<h1>ship name: <div class="fill"></div> </h1>
|
<h1>
|
||||||
|
ship name: <div class="fill" />
|
||||||
|
</h1>
|
||||||
|
|
||||||
<div class="details">
|
<div class="details">
|
||||||
<h2>{ship_class}-class, {ship_type}</h2>
|
<h2>{ship_class}-class, {ship_type}</h2>
|
||||||
@ -10,12 +12,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Cost from '../../../Cost.svelte';
|
import Cost from "../../../Cost.svelte";
|
||||||
import Mass from '$lib/components/Mass.svelte';
|
import Mass from "$lib/components/Mass.svelte";
|
||||||
|
|
||||||
export let ship_class;
|
export let ship_class;
|
||||||
export let ship_type;
|
export let ship_type;
|
||||||
export let cost, mass = ( 0, 0 );
|
export let cost,
|
||||||
|
mass = (0, 0);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
@ -1,6 +1,5 @@
|
|||||||
<div class="main_systems">
|
<div class="main_systems">
|
||||||
|
{#if ftl !== "none"}
|
||||||
{#if ftl !== "none" }
|
|
||||||
<img class="ftl" src="icons/ftl-drive.svg" alt="ftl drive" />
|
<img class="ftl" src="icons/ftl-drive.svg" alt="ftl drive" />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@ -8,13 +7,16 @@
|
|||||||
<div class="thrust">{engine}</div>
|
<div class="thrust">{engine}</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<img class="internal" src="icons/internal-systems.svg" alt="internal systems"/>
|
<img
|
||||||
</div>
|
class="internal"
|
||||||
|
src="icons/internal-systems.svg"
|
||||||
|
alt="internal systems"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export let ftl = 'none';
|
export let ftl = "none";
|
||||||
export let engine = 0;
|
export let engine = 0;
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -27,14 +29,16 @@
|
|||||||
line-height: 2em;
|
line-height: 2em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.main_systems {
|
.main_systems {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
img.ftl { height: 2em; }
|
img.ftl {
|
||||||
|
height: 2em;
|
||||||
|
}
|
||||||
img.internal {
|
img.internal {
|
||||||
height: 2em;
|
height: 2em;
|
||||||
}
|
}
|
13
src/lib/components/Output/Print/MainSystems/stories.js
Normal file
13
src/lib/components/Output/Print/MainSystems/stories.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Component from ".";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "printouts/main_systems",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const basic = () => ({
|
||||||
|
Component,
|
||||||
|
props: {
|
||||||
|
ftl: "standard",
|
||||||
|
engine: 4,
|
||||||
|
},
|
||||||
|
});
|
@ -1,15 +1,14 @@
|
|||||||
<div>
|
<div>
|
||||||
{#each _.range(standard) as i }
|
{#each _.range(standard) as i}
|
||||||
<img src="icons/screen.svg" alt="screen" />
|
<img src="icons/screen.svg" alt="screen" />
|
||||||
{/each}
|
{/each}
|
||||||
{#each _.range(advanced) as i }
|
{#each _.range(advanced) as i}
|
||||||
<img src="icons/screen-advanced.svg" alt="advanced screen" />
|
<img src="icons/screen-advanced.svg" alt="advanced screen" />
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import _ from 'lodash';
|
import _ from "lodash";
|
||||||
|
|
||||||
export let standard = 0;
|
export let standard = 0;
|
||||||
export let advanced = 0;
|
export let advanced = 0;
|
@ -1,16 +1,15 @@
|
|||||||
<div>
|
<div>
|
||||||
<Firecons {firecons}/>
|
<Firecons {firecons} />
|
||||||
|
|
||||||
<Screens {...screens} />
|
<Screens {...screens} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Firecons from './Firecons/index.svelte';
|
import Firecons from "./Firecons/index.svelte";
|
||||||
import Screens from './Screens/index.svelte';
|
import Screens from "./Screens/index.svelte";
|
||||||
|
|
||||||
export let firecons = 0;
|
export let firecons = 0;
|
||||||
export let screens = {};
|
export let screens = {};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -23,6 +22,5 @@
|
|||||||
}
|
}
|
||||||
div > :global(*) {
|
div > :global(*) {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,13 +1,13 @@
|
|||||||
<div>
|
<div>
|
||||||
<Arcs selected={arcs} size="40">
|
<Arcs selected={arcs} size="40">
|
||||||
<text x="50%" y="50%" >
|
<text x="50%" y="50%">
|
||||||
{weapon_class}
|
{weapon_class}
|
||||||
</text>
|
</text>
|
||||||
</Arcs>
|
</Arcs>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Arcs from '$lib/components/Weapon/Arcs/index.svelte';
|
import Arcs from "$lib/components/Weapon/Arcs/index.svelte";
|
||||||
export let weapon_class = 1;
|
export let weapon_class = 1;
|
||||||
export let arcs = [];
|
export let arcs = [];
|
||||||
</script>
|
</script>
|
@ -1,21 +1,17 @@
|
|||||||
<div class="weapons">
|
<div class="weapons">
|
||||||
|
|
||||||
<div class="beams">
|
<div class="beams">
|
||||||
{#each beams as beam}
|
{#each beams as beam}
|
||||||
<Beam {...beam} />
|
<Beam {...beam} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Beam from './Beam/index.svelte';
|
import Beam from "./Beam/index.svelte";
|
||||||
export let weapons = [];
|
export let weapons = [];
|
||||||
|
|
||||||
let beams = [];
|
let beams = [];
|
||||||
$: beams = weapons.filter( ({ weapon_type }) => weapon_type === 'beam' );
|
$: beams = weapons.filter(({ weapon_type }) => weapon_type === "beam");
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
28
src/lib/components/Output/Print/Weapons/stories.js
Normal file
28
src/lib/components/Output/Print/Weapons/stories.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import Component from ".";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "printouts/weapons",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const basic = () => ({
|
||||||
|
Component,
|
||||||
|
props: {
|
||||||
|
weapons: [
|
||||||
|
{
|
||||||
|
weapon_type: "submunition",
|
||||||
|
arcs: ["F"],
|
||||||
|
mass: 1,
|
||||||
|
cost: 3,
|
||||||
|
id: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
weapon_type: "beam",
|
||||||
|
weapon_class: "2",
|
||||||
|
arcs: ["A", "AS", "FS"],
|
||||||
|
mass: 2,
|
||||||
|
cost: 6,
|
||||||
|
id: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
44
src/lib/components/Output/Print/index.svelte
Normal file
44
src/lib/components/Output/Print/index.svelte
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<aside class="ship-sheet" transition:fade>
|
||||||
|
<Identification {...ship.general} />
|
||||||
|
|
||||||
|
<Weapons weapons={ship.weaponry.weapons} />
|
||||||
|
|
||||||
|
<div class="section-2">
|
||||||
|
<Hull structure={ship.structure} ship_mass={ship.general.mass} />
|
||||||
|
|
||||||
|
<Systems
|
||||||
|
firecons={ship.weaponry.firecons.nbr}
|
||||||
|
screens={ship.structure.screens}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<MainSystems ftl={ship.ftl.type} engine={ship.engine.rating} />
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import _ from "lodash";
|
||||||
|
|
||||||
|
import Identification from "./Identification/index.svelte";
|
||||||
|
import MainSystems from "./MainSystems/index.svelte";
|
||||||
|
import Hull from "./Hull/index.svelte";
|
||||||
|
import Weapons from "./Weapons/index.svelte";
|
||||||
|
import Systems from "./Systems/index.svelte";
|
||||||
|
|
||||||
|
export let ship;
|
||||||
|
|
||||||
|
import { fly, fade } from "svelte/transition";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.ship-sheet {
|
||||||
|
width: 4.25in;
|
||||||
|
height: 5.5in;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-2 {
|
||||||
|
display: flex;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
</style>
|
108
src/lib/components/Output/Print/sample.js
Normal file
108
src/lib/components/Output/Print/sample.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
export default {
|
||||||
|
ftl: {
|
||||||
|
mass: 0,
|
||||||
|
cost: 0,
|
||||||
|
type: "standard",
|
||||||
|
},
|
||||||
|
engine: {
|
||||||
|
mass: 40,
|
||||||
|
cost: 80,
|
||||||
|
rating: 6,
|
||||||
|
advanced: false,
|
||||||
|
},
|
||||||
|
general: {
|
||||||
|
ship_class: "Deviant",
|
||||||
|
name: "",
|
||||||
|
ship_type: "Battleship",
|
||||||
|
mass: 132,
|
||||||
|
used_mass: 131,
|
||||||
|
cost: 415,
|
||||||
|
},
|
||||||
|
weaponry: {
|
||||||
|
firecons: {
|
||||||
|
nbr: 5,
|
||||||
|
mass: 5,
|
||||||
|
cost: 20,
|
||||||
|
},
|
||||||
|
weapons: [
|
||||||
|
{
|
||||||
|
weapon_type: "submunition",
|
||||||
|
arcs: ["F"],
|
||||||
|
mass: 1,
|
||||||
|
cost: 3,
|
||||||
|
id: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
weapon_type: "beam",
|
||||||
|
weapon_class: "2",
|
||||||
|
arcs: ["A", "AS", "FS"],
|
||||||
|
mass: 2,
|
||||||
|
cost: 6,
|
||||||
|
id: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
weapon_type: "pds",
|
||||||
|
mass: 1,
|
||||||
|
cost: 3,
|
||||||
|
id: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
adfc: {
|
||||||
|
rating: 0,
|
||||||
|
cost: 0,
|
||||||
|
mass: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
structure: {
|
||||||
|
mass: 0,
|
||||||
|
cost: 0,
|
||||||
|
hull: {
|
||||||
|
rating: 22,
|
||||||
|
advanced: false,
|
||||||
|
cost: 44,
|
||||||
|
mass: 22,
|
||||||
|
},
|
||||||
|
screens: {
|
||||||
|
standard: 2,
|
||||||
|
advanced: 1,
|
||||||
|
cost: 105,
|
||||||
|
mass: 35,
|
||||||
|
},
|
||||||
|
armour: [
|
||||||
|
{
|
||||||
|
layer: 1,
|
||||||
|
rating: 7,
|
||||||
|
cost: 14,
|
||||||
|
mass: 14,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
layer: 2,
|
||||||
|
rating: 2,
|
||||||
|
cost: 8,
|
||||||
|
mass: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
layer: 3,
|
||||||
|
rating: 0,
|
||||||
|
cost: 0,
|
||||||
|
mass: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
cargo: {
|
||||||
|
space: 7,
|
||||||
|
cost: 0,
|
||||||
|
mass: 7,
|
||||||
|
},
|
||||||
|
streamlining: {
|
||||||
|
type: "none",
|
||||||
|
cost: 0,
|
||||||
|
mass: 0,
|
||||||
|
},
|
||||||
|
carrier: {
|
||||||
|
bays: 0,
|
||||||
|
cost: 0,
|
||||||
|
mass: 0,
|
||||||
|
squadrons: [],
|
||||||
|
},
|
||||||
|
};
|
13
src/lib/components/Output/Print/stories.js
Normal file
13
src/lib/components/Output/Print/stories.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Print from "./index.svelte";
|
||||||
|
import sample from "./sample";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "printouts",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const basic = () => ({
|
||||||
|
Component: Print,
|
||||||
|
props: {
|
||||||
|
ship: sample,
|
||||||
|
},
|
||||||
|
});
|
14
src/lib/components/Propulsion/index.svelte
Normal file
14
src/lib/components/Propulsion/index.svelte
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<Section label="propulsion">
|
||||||
|
<Engine {...engine} on:change_engine />
|
||||||
|
|
||||||
|
<Ftl {...ftl} on:change_ftl />
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Ftl from "../Ftl/index.svelte";
|
||||||
|
import Engine from "../Engine/index.svelte";
|
||||||
|
import Section from "../Section/index.svelte";
|
||||||
|
|
||||||
|
export let ftl = {};
|
||||||
|
export let engine = {};
|
||||||
|
</script>
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export let label;
|
export let label;
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -24,5 +23,4 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
background: #333;
|
background: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
@ -1,7 +1,11 @@
|
|||||||
<div><slot /></div>
|
<div class="ship-item">
|
||||||
|
<div><slot /></div>
|
||||||
|
|
||||||
<div class="mass" bind:this={mass_el}>{mass}</div>
|
<div class="reqs">
|
||||||
<div class="cost" bind:this={cost_el}>{cost}</div>
|
<div class="mass" bind:this={mass_el}>{mass}</div>
|
||||||
|
<div class="cost" bind:this={cost_el}>{cost}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { tick } from "svelte";
|
import { tick } from "svelte";
|
||||||
@ -21,24 +25,19 @@
|
|||||||
|
|
||||||
$: update_el(mass_el, mass);
|
$: update_el(mass_el, mass);
|
||||||
$: update_el(cost_el, cost);
|
$: update_el(cost_el, cost);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
div {
|
div {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cost,
|
.cost,
|
||||||
.mass {
|
.mass {
|
||||||
padding: 0px 2em;
|
width: 4em;
|
||||||
|
padding: 0px 0.5em;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.cost {
|
|
||||||
grid-column: 3;
|
|
||||||
}
|
|
||||||
.mass {
|
|
||||||
grid-column: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ship-item {
|
.ship-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -87,4 +86,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ship-item {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.reqs {
|
||||||
|
flex: 0;
|
||||||
|
width: 10em;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
49
src/lib/components/ShipSpecs/Identification.svelte
Normal file
49
src/lib/components/ShipSpecs/Identification.svelte
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<div>
|
||||||
|
<Field
|
||||||
|
label="ship class"
|
||||||
|
value={general.ship_class}
|
||||||
|
on:change={change_class}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Field label="ship type">
|
||||||
|
<select value={ship_type} on:change={change_ship_type}>
|
||||||
|
{#each ship_types as type (type)}
|
||||||
|
<option>{type}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
|
import Field from "$lib/components/Field/index.svelte";
|
||||||
|
import { candidate_ship_types } from "../../dux/ship_types";
|
||||||
|
|
||||||
|
export let ship = getContext("ship");
|
||||||
|
let general;
|
||||||
|
$: general = $ship.general;
|
||||||
|
|
||||||
|
const change_class = (event) =>
|
||||||
|
ship.dispatch(ship.actions.set_ship_class(event.target.value));
|
||||||
|
|
||||||
|
let ship_type;
|
||||||
|
$: ship_type = $ship.general.ship_type;
|
||||||
|
|
||||||
|
const change_ship_type = ({ target: { value } }) =>
|
||||||
|
ship.dispatch.set_ship_type(value);
|
||||||
|
|
||||||
|
let ship_types;
|
||||||
|
$: ship_types = candidate_ship_types(
|
||||||
|
$ship.general.mass,
|
||||||
|
$ship.carrier.bays > 0
|
||||||
|
).map(({ name }) => name);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
align-items: end;
|
||||||
|
gap: 2em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -5,8 +5,9 @@
|
|||||||
on:change={change_tonnage}
|
on:change={change_tonnage}
|
||||||
type="number"
|
type="number"
|
||||||
min="10"
|
min="10"
|
||||||
max="300" />
|
max="300"
|
||||||
<span class="mass_symbol"></span>
|
/>
|
||||||
|
<span class="mass_symbol" />
|
||||||
|
|
||||||
<div class="note" class:warning={!within_budget}>
|
<div class="note" class:warning={!within_budget}>
|
||||||
{#if within_budget}
|
{#if within_budget}
|
||||||
@ -18,7 +19,8 @@
|
|||||||
|
|
||||||
<div class="cost">
|
<div class="cost">
|
||||||
<Field label="cost">
|
<Field label="cost">
|
||||||
<span class="cost">{$ship.general.cost}</span></Field>
|
<span class="cost">{$ship.general.cost}</span></Field
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -60,8 +62,10 @@
|
|||||||
font-size: smaller;
|
font-size: smaller;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mass,div.cost {
|
.mass,
|
||||||
padding: 0px 2em; justify-self: right;
|
div.cost {
|
||||||
|
padding: 0px 2em;
|
||||||
|
justify-self: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mass {
|
.mass {
|
||||||
@ -71,7 +75,7 @@
|
|||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
}
|
}
|
||||||
span.cost:after {
|
span.cost:after {
|
||||||
content: '\00A4';
|
content: "\00A4";
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,16 +1,14 @@
|
|||||||
<Identification />
|
<Identification />
|
||||||
|
|
||||||
<ShipCost />
|
|
||||||
|
|
||||||
|
<ShipCost />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Identification from "./Identification.svelte";
|
import Identification from "./Identification.svelte";
|
||||||
import ShipCost from "./ShipCost.svelte";
|
import ShipCost from "./ShipCost.svelte";
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
div {
|
div {
|
||||||
background-color: red;
|
background-color: red;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
32
src/lib/components/Weapon/Arcs/index.svelte
Normal file
32
src/lib/components/Weapon/Arcs/index.svelte
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<svg width="{size}px" height="{size}px">
|
||||||
|
{#each all_arcs as arc (arc)}
|
||||||
|
<Arc
|
||||||
|
{arc}
|
||||||
|
radius={size / 2}
|
||||||
|
active={selected.includes(arc)}
|
||||||
|
on:click={() => click_arc(arc)}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
<circle cx="50%" cy="50%" r={size / 3} />
|
||||||
|
<slot />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Arc from "../../Weapons/Arc.svelte";
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
const all_arcs = ["FS", "F", "FP", "AP", "A", "AS"];
|
||||||
|
|
||||||
|
export let selected = [];
|
||||||
|
export let size = 60;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
const click_arc = (arc) => dispatch("click_arc", arc);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
circle {
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
|
</style>
|
After Width: | Height: | Size: 651 B |
@ -93,7 +93,6 @@
|
|||||||
weapon_class,
|
weapon_class,
|
||||||
arcs: cache.split(":"),
|
arcs: cache.split(":"),
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -102,5 +101,4 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
35
src/lib/components/Weapon/Needle/index.svelte
Normal file
35
src/lib/components/Weapon/Needle/index.svelte
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<label> needle weapon</label>
|
||||||
|
<Arcs selected={arcs} on:click_arc={({ detail }) => click_arc(detail)} />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
import Arcs from "../Arcs/index.svelte";
|
||||||
|
import dux from "$lib/dux";
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
const all_arcs = ["FS", "F", "FP", "AP", "A", "AS"];
|
||||||
|
|
||||||
|
export let arcs = ["F"];
|
||||||
|
export let ship_change = getContext("ship_change") || (() => {});
|
||||||
|
|
||||||
|
const click_arc = (arc) => {
|
||||||
|
if (arcs[0] === arc) return;
|
||||||
|
arcs = [arc];
|
||||||
|
};
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
let cache;
|
||||||
|
$: cache = arcs.join(":");
|
||||||
|
|
||||||
|
$: dispatch("change", {
|
||||||
|
arcs: cache.split(":"),
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.arc {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,2 +1 @@
|
|||||||
<label>point defence system</label>
|
<label>point defence system</label>
|
||||||
|
|
@ -1,2 +1 @@
|
|||||||
<label>scattergun</label>
|
<label>scattergun</label>
|
||||||
|
|
35
src/lib/components/Weapon/Submunition/index.svelte
Normal file
35
src/lib/components/Weapon/Submunition/index.svelte
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<label> submunition pack</label>
|
||||||
|
<Arcs selected={arcs} on:click_arc={({ detail }) => click_arc(detail)} />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
import Arcs from "../Arcs/index.svelte";
|
||||||
|
import dux from "$lib/dux";
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
const all_arcs = ["FS", "F", "FP", "AP", "A", "AS"];
|
||||||
|
|
||||||
|
export let arcs = ["F"];
|
||||||
|
export let ship_change = getContext("ship_change") || (() => {});
|
||||||
|
|
||||||
|
const click_arc = (arc) => {
|
||||||
|
if (arcs[0] === arc) return;
|
||||||
|
arcs = [arc];
|
||||||
|
};
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
let cache;
|
||||||
|
$: cache = arcs.join(":");
|
||||||
|
|
||||||
|
$: dispatch("change", {
|
||||||
|
arcs: cache.split(":"),
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.arc {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -56,7 +56,6 @@
|
|||||||
...detail,
|
...detail,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -124,5 +123,4 @@
|
|||||||
.weapon_row > :global(*) {
|
.weapon_row > :global(*) {
|
||||||
margin-right: 2em;
|
margin-right: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
@ -4,7 +4,6 @@
|
|||||||
</Field>
|
</Field>
|
||||||
</ShipItem>
|
</ShipItem>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ShipItem from "../../ShipItem/index.svelte";
|
import ShipItem from "../../ShipItem/index.svelte";
|
||||||
import Field from "../../Field/index.svelte";
|
import Field from "../../Field/index.svelte";
|
||||||
@ -16,5 +15,5 @@
|
|||||||
export let mass = 0;
|
export let mass = 0;
|
||||||
export let ship = getContext("ship");
|
export let ship = getContext("ship");
|
||||||
|
|
||||||
$: ship?.dispatch_action('set_adfc',rating);
|
$: ship?.dispatch_action("set_adfc", rating);
|
||||||
</script>
|
</script>
|
@ -23,5 +23,4 @@
|
|||||||
export let ship = getContext("ship");
|
export let ship = getContext("ship");
|
||||||
|
|
||||||
const add_weapon = () => ship?.dispatch_action("add_weapon", weapon_type);
|
const add_weapon = () => ship?.dispatch_action("add_weapon", weapon_type);
|
||||||
|
|
||||||
</script>
|
</script>
|
194
src/lib/components/Weapons/Add.svelte
Normal file
194
src/lib/components/Weapons/Add.svelte
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
<input
|
||||||
|
class="add-weapon button small blue"
|
||||||
|
type="button"
|
||||||
|
value="add"
|
||||||
|
on:click={add}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="weapon">
|
||||||
|
<select bind:value={weapon_type}>
|
||||||
|
<option>beam</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select bind:value={weapon_class}>
|
||||||
|
<option>1</option>
|
||||||
|
<option>2</option>
|
||||||
|
<option>3</option>
|
||||||
|
<option>4</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select bind:value={nbr_arcs}>
|
||||||
|
{#each arc_options[weapon_class] as opt (opt)}
|
||||||
|
<option>{opt}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<svg width="60px" height="60px">
|
||||||
|
{#each arcs as arc (arc)}
|
||||||
|
<Arc
|
||||||
|
{arc}
|
||||||
|
radius={30}
|
||||||
|
active={selected_arc[arc]}
|
||||||
|
on:click={() => click_arc(arc)}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
<circle cx="30" cy="30" r="15" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<div>{weapon.cost}</div>
|
||||||
|
<div>{weapon.mass}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let weapon_type = "beam";
|
||||||
|
let weapon_class = 1;
|
||||||
|
let nbr_arcs = 6;
|
||||||
|
$: nbr_arcs = arc_options[weapon_class][0];
|
||||||
|
|
||||||
|
import Arc from "./Arc.svelte";
|
||||||
|
import { weapon_cost_mass } from "../../dux/weapons/rules.js";
|
||||||
|
|
||||||
|
const arcs = ["FS", "F", "FP", "AP", "A", "AS"];
|
||||||
|
|
||||||
|
import _ from "lodash";
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
let arc_options = {
|
||||||
|
1: [6],
|
||||||
|
2: [3, 6],
|
||||||
|
3: [1, 2, 3, 4, 5, 6, "broadside"],
|
||||||
|
4: [1, 2, 3, 4, 5, 6, "broadside"],
|
||||||
|
};
|
||||||
|
|
||||||
|
let selected_arc = Object.fromEntries(arcs.map((arc) => [arc, false]));
|
||||||
|
|
||||||
|
const nbr_selected_arcs = () =>
|
||||||
|
Object.values(selected_arc).filter((x) => x).length;
|
||||||
|
|
||||||
|
$: if (nbr_selected_arcs() !== nbr_arcs) {
|
||||||
|
if (nbr_arcs === "broadside") {
|
||||||
|
const new_arcs = {};
|
||||||
|
arcs.forEach((arc) => (new_arcs[arc] = true));
|
||||||
|
new_arcs.A = false;
|
||||||
|
new_arcs.F = false;
|
||||||
|
selected_arc = new_arcs;
|
||||||
|
} else {
|
||||||
|
let first_index = arcs.findIndex((arc) => selected_arc[arc]);
|
||||||
|
if (first_index === -1) first_index = 0;
|
||||||
|
|
||||||
|
const new_arcs = {};
|
||||||
|
arcs.forEach((arc) => (new_arcs[arc] = false));
|
||||||
|
|
||||||
|
_.range(nbr_arcs).forEach((i) => {
|
||||||
|
new_arcs[arcs[first_index]] = true;
|
||||||
|
first_index = (first_index + 1) % arcs.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
selected_arc = new_arcs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const click_arc = (first_arc) => {
|
||||||
|
if (nbr_arcs === "broadside") return;
|
||||||
|
|
||||||
|
let first_index = arcs.findIndex((arc) => arc === first_arc);
|
||||||
|
|
||||||
|
const new_arcs = {};
|
||||||
|
arcs.forEach((arc) => (new_arcs[arc] = false));
|
||||||
|
|
||||||
|
_.range(nbr_arcs).forEach((i) => {
|
||||||
|
console.log(first_index);
|
||||||
|
console.log(selected_arc);
|
||||||
|
new_arcs[arcs[first_index]] = true;
|
||||||
|
first_index = (first_index + 1) % arcs.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
selected_arc = new_arcs;
|
||||||
|
};
|
||||||
|
|
||||||
|
let weapon = {};
|
||||||
|
$: weapon = {
|
||||||
|
weapon_type,
|
||||||
|
weapon_class,
|
||||||
|
arcs,
|
||||||
|
...weapon_cost_mass({
|
||||||
|
weapon_type,
|
||||||
|
weapon_class,
|
||||||
|
arcs: arcs.filter((arc) => selected_arc[arc]),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
const add = () => {
|
||||||
|
dispatch("add_weapon", weapon);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.weapon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon > * {
|
||||||
|
margin-right: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arcs {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 1fr 1fr 1fr 1fr;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||||
|
align-items: center;
|
||||||
|
justify-items: center;
|
||||||
|
width: 6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arc input {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arc.F {
|
||||||
|
grid-column: 2 / span 2;
|
||||||
|
grid-row: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arc.FS {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 1 / span 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arc.FP {
|
||||||
|
grid-column: 4;
|
||||||
|
grid-row: 1 / span 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arc.AS {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 3 / span 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arc.AP {
|
||||||
|
grid-column: 4;
|
||||||
|
grid-row: 3 / span 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arc.A {
|
||||||
|
grid-column: 2 / span 2;
|
||||||
|
grid-row: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arc {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-weapon {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
circle {
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
|
</style>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user