Yanick Champoux 2021-06-13 11:36:59 -04:00
parent 511c93de8a
commit 95646cebd8
15 changed files with 216 additions and 232 deletions

View File

@ -1 +1 @@
15.14.0 16.2.0

View File

@ -9,7 +9,7 @@
"format": "prettier --write ." "format": "prettier --write ."
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/kit": "^1.0.0-next.107", "@sveltejs/kit": "^1.0.0-next.115",
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.10", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.10",
"eslint": "^7.22.0", "eslint": "^7.22.0",
"eslint-config-prettier": "^8.1.0", "eslint-config-prettier": "^8.1.0",
@ -23,12 +23,13 @@
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@sveltejs/adapter-node": "^1.0.0-next.18", "@sveltejs/adapter-node": "^1.0.0-next.18",
"@sveltejs/adapter-static": "^1.0.0-next.9", "@sveltejs/adapter-static": "^1.0.0-next.13",
"@yanick/updeep": "link:/home/yanick/work/javascript/updeep", "@yanick/updeep": "link:/home/yanick/work/javascript/updeep",
"bulma": "^0.9.2", "bulma": "^0.9.2",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"redux": "^4.1.0", "redux": "^4.1.0",
"reselect": "^4.0.0", "reselect": "^4.0.0",
"rollup-plugin-analyzer": "^4.0.0",
"ts-action": "^11.0.0", "ts-action": "^11.0.0",
"updux": "link:/home/yanick/work/javascript/updux/" "updux": "link:/home/yanick/work/javascript/updux/"
}, },

View File

@ -129,8 +129,6 @@
const ship_dispatch = ({ detail }) => ship.dispatch(detail); const ship_dispatch = ({ detail }) => ship.dispatch(detail);
setContext("ship_change", ship.dispatch);
let show_notes = false; let show_notes = false;
const toggle_notes = () => (show_notes = !show_notes); const toggle_notes = () => (show_notes = !show_notes);

View File

@ -2,7 +2,7 @@
<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)}
<option>{type}</option> <option>{type}</option>
{/each} {/each}
</select> </select>
</Field> </Field>
@ -21,13 +21,13 @@
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_change = getContext('ship_change') || ( () => {} ); export let ship = getContext('ship');
$: ship_change( dux.actions.set_squadron({ id, type, }) ); $: ship?.dispatch_action('set_squadron',{ id, type, });
</script> </script>

View File

@ -1,5 +1,5 @@
<Section label="carrier"> <Section label="carrier">
<ShipItem {cost} {mass} > <ShipItem {cost} {mass}>
<Field label="bays"> <Field label="bays">
<input type="number" min="0" bind:value={bays} /> <input type="number" min="0" bind:value={bays} />
</Field> </Field>
@ -8,30 +8,24 @@
{#each squadrons as squad (squad.id)} {#each squadrons as squad (squad.id)}
<Squadron {...squad} /> <Squadron {...squad} />
{/each} {/each}
</Section> </Section>
<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 = [];
export let cost = 0; export let cost = 0;
export let mass = 0; export let mass = 0;
export let ship_change = getContext('ship_change') || ( () => {} );
$: ship_change( dux.actions.set_carrier_bays(bays) ); export let ship = getContext("ship");
$: ship?.dispatch_action('set_carrier_bays',bays);
</script> </script>
<style>
div {
background-color: red;
}
</style>

View File

@ -4,21 +4,16 @@
<script> <script>
import { createEventDispatcher} from 'svelte'; import { getContext} from 'svelte';
import dux from '$lib/dux/structure/armour';
import ShipItem from '$lib/components/ShipItem/index.svelte';
import Field from '$lib/components/Field/index.svelte'; import Field from '$lib/components/Field/index.svelte';
export let layer = 1; export let layer = 1;
export let rating = 0; export let rating = 0;
const dispatch = createEventDispatcher(); const ship = getContext('ship');
$: dispatch( 'ship_change', $: ship?.dispatch_action( 'set_armour_layer', {layer,rating} );
dux.actions.set_armour_layer({layer,rating})
);
</script> </script>

View File

@ -1,30 +1,28 @@
<ShipItem {cost} {mass}> <ShipItem {cost} {mass}>
<Field label="cargo"> <Field label="cargo">
<input type="number" min="0" bind:value={space}/> <input type="number" min="0" bind:value={space} />
</Field> </Field>
</ShipItem> </ShipItem>
<script> <script>
import get from 'lodash/get.js'; import ShipItem from "$lib/components/ShipItem/index.svelte";
import ShipItem from '$lib/components/ShipItem/index.svelte'; import Field from "$lib/components/Field/index.svelte";
import Field from '$lib/components/Field/index.svelte';
import dux from '$lib/dux/cargo';
import {getContext, createEventDispatcher} from 'svelte'; import { getContext } from "svelte";
const ship = getContext('ship'); export let ship = getContext("ship");
export let space = 0; export let space = 0;
export let cost = 0; export let cost = 0;
export let mass = 0; export let mass = 0;
const dispatch = createEventDispatcher(); $: ship?.dispatch_action("set_cargo", space);
$: dispatch( 'set_cargo', dux.actions.set_cargo( space ) );
</script> </script>
<style> <style>
input { input {
width: 5em; width: 5em;
} }
</style>
</style>

View File

@ -16,19 +16,17 @@
</ShipItem> </ShipItem>
<script> <script>
import get from 'lodash/get.js';
import ShipItem from '$lib/components/ShipItem/index.svelte'; import ShipItem from '$lib/components/ShipItem/index.svelte';
import Field from '$lib/components/Field/index.svelte'; import Field from '$lib/components/Field/index.svelte';
import dux from '$lib/dux/streamlining';
import {getContext } from 'svelte'; import {getContext } from 'svelte';
export let type = 'none'; export let type = 'none';
export let cost = 0; export let cost = 0;
export let mass = 0; export let mass = 0;
export let ship_change = getContext('ship_change') || ( () => {} ); export let ship = getContext('ship');
$: ship_change( dux.actions.set_streamlining(type)); $: ship?.dispatch_action( 'set_streamlining', type);
</script> </script>

View File

@ -1,111 +1,106 @@
<label>beam</label> <label>beam</label>
<Field label="beam class"> <Field label="beam class">
<select bind:value={weapon_class}> <select bind:value={weapon_class}>
<option>1</option> <option>1</option>
<option>2</option> <option>2</option>
<option>3</option> <option>3</option>
<option>4</option> <option>4</option>
</select> </select>
</Field> </Field>
<Field label="arcs"> <Field label="arcs">
<select bind:value={nbr_arcs}> <select bind:value={nbr_arcs}>
{#each arc_options[weapon_class]||[] as nbr_arcs (nbr_arcs)} {#each arc_options[weapon_class] || [] as nbr_arcs (nbr_arcs)}
<option>{nbr_arcs}</option> <option>{nbr_arcs}</option>
{/each} {/each}
</select> </select>
</Field> </Field>
<Arcs selected={arcs} on:click_arc={({detail}) => click_arc(detail)} /> <Arcs selected={arcs} on:click_arc={({ detail }) => click_arc(detail)} />
<script> <script>
import {getContext } from 'svelte'; import { getContext } from "svelte";
import Arc from '../../Weapons/Arc.svelte'; import Arc from "../../Weapons/Arc.svelte";
import Arcs from '../Arcs/index.svelte'; import Arcs from "../Arcs/index.svelte";
import { weapon_cost_mass } from '$lib/dux/weapons/rules'; import { weapon_cost_mass } from "$lib/dux/weapons/rules";
import _ from 'lodash'; import _ from "lodash";
import ShipItem from '$lib/components/ShipItem/index.svelte'; import ShipItem from "$lib/components/ShipItem/index.svelte";
import Field from '$lib/components/Field/index.svelte'; import Field from "$lib/components/Field/index.svelte";
import dux from '$lib/dux'; import dux from "$lib/dux";
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from "svelte";
const all_arcs = [ 'FS', 'F', 'FP', 'AP', 'A', 'AS' ]; const all_arcs = ["FS", "F", "FP", "AP", "A", "AS"];
export let weapon_type; export let weapon_class = 1;
export let id; export let arcs = ["F"];
export let weapon_class = 1; export let id;
export let arcs = ['F'];
export let ship_change = getContext('ship_change') || ( () => {} );
let arc_options = { let arc_options = {
1: [ 6], 1: [6],
2: [ 3, 6 ], 2: [3, 6],
3: [ 1, 2, 3, 4, 5, 6, 'broadside' ], 3: [1, 2, 3, 4, 5, 6, "broadside"],
4: [ 1, 2, 3, 4, 5, 6, 'broadside' ] 4: [1, 2, 3, 4, 5, 6, "broadside"],
}; };
let nbr_arcs = 6; let nbr_arcs = 6;
$: nbr_arcs = arc_options[weapon_class][0]; $: nbr_arcs = arc_options[weapon_class][0];
$: console.log({arcs,nbr_arcs}) $: console.log({ arcs, nbr_arcs });
$: if ( arcs.length !== nbr_arcs ) { $: if (arcs.length !== nbr_arcs) {
if( nbr_arcs === 'broadside' ) { if (nbr_arcs === "broadside") {
arcs = all_arcs.filter( arc => arc.length === 1 ) arcs = all_arcs.filter((arc) => arc.length === 1);
} } else {
else{ let first_index = all_arcs.findIndex((arc) => arcs[0]);
if (first_index === -1) first_index = 0;
let first_index = all_arcs.findIndex( arc => arcs[0] ); const new_arcs = [];
if( first_index === -1 ) first_index = 0;
const new_arcs = []; _.range(nbr_arcs).forEach((i) => {
new_arcs.push(all_arcs[first_index]);
first_index = (first_index + 1) % all_arcs.length;
});
_.range(nbr_arcs).forEach( i => { arcs = new_arcs;
new_arcs.push( all_arcs[first_index] )
first_index = ( first_index + 1 ) % all_arcs.length;
});
arcs = new_arcs;
}
} }
}
const click_arc = (first_arc) => { const click_arc = (first_arc) => {
if( nbr_arcs === 'broadside' ) return; if (nbr_arcs === "broadside") return;
let first_index = all_arcs.findIndex( arc => arc === first_arc ); let first_index = all_arcs.findIndex((arc) => arc === first_arc);
const new_arcs = []; const new_arcs = [];
_.range(nbr_arcs).forEach( i => { _.range(nbr_arcs).forEach((i) => {
new_arcs.push( all_arcs[first_index] ); new_arcs.push(all_arcs[first_index]);
first_index = ( first_index + 1 ) % all_arcs.length; first_index = (first_index + 1) % all_arcs.length;
}); });
arcs = new_arcs; arcs = new_arcs;
};
} let i = 1;
$: if (weapon_class) i = 1;
let i = 1; let cache = "";
$: if(weapon_class) i = 1; $: cache = arcs.join(":");
let cache = ''; const dispatch = createEventDispatcher();
$: cache = arcs.join(":");
const dispatch = createEventDispatcher(); $: dispatch("change", {
weapon_class,
arcs: cache.split(":"),
});
$: dispatch( 'change', {
weapon_class,
arcs: cache.split(":"),
})
</script> </script>
<style> <style>
.arc { .arc {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-right: 1em; margin-right: 1em;
} }
</style>
</style>

View File

@ -1,117 +1,120 @@
<ShipItem {cost} {mass}> <ShipItem {cost} {mass}>
<div class="weapon_row"> <div class="weapon_row">
<input
type="button"
class="button small red remove"
value="remove"
on:click={remove}
/>
<input type="button" class="button small red remove" value="remove" <svelte:component
on:click={remove} /> this={weapon_component[weapon_type]}
{...weapon}
on:change={update}
<svelte:component this={weapon_component[weapon_type]} {...weapon} />
on:change={update}/> </div>
</div>
</ShipItem> </ShipItem>
<script> <script>
import {getContext } from 'svelte'; import { getContext } from "svelte";
import Arc from '../Weapons/Arc.svelte'; import Arc from "../Weapons/Arc.svelte";
import { weapon_cost_mass } from '../../dux/weapons/rules.js'; import { weapon_cost_mass } from "../../dux/weapons/rules.js";
import _ from 'lodash'; import _ from "lodash";
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from "svelte";
import ShipItem from '../ShipItem/index.svelte'; import ShipItem from "../ShipItem/index.svelte";
import Field from '../Field/index.svelte'; import Field from "../Field/index.svelte";
import Beam from './Beam/index.svelte'; import Beam from "./Beam/index.svelte";
import Submunition from './Submunition/index.svelte'; import Submunition from "./Submunition/index.svelte";
import PointDefenceSystem from './PointDefenceSystem/index.svelte'; import PointDefenceSystem from "./PointDefenceSystem/index.svelte";
import Scattergun from './Scattergun/index.svelte'; import Scattergun from "./Scattergun/index.svelte";
import Needle from './Needle/index.svelte'; import Needle from "./Needle/index.svelte";
import dux from '../../dux'; import dux from "../../dux";
const weapon_component = { const weapon_component = {
beam: Beam, beam: Beam,
'submunition': Submunition, submunition: Submunition,
'pds': PointDefenceSystem, pds: PointDefenceSystem,
scattergun: Scattergun, scattergun: Scattergun,
needle: Needle, needle: Needle,
}; };
export let weapon = {}; export let weapon = {};
export let id; export let id;
export let cost; export let cost;
export let mass; export let mass;
export let ship_change = getContext('ship_change') || ( () => {} ); export let ship = getContext("ship");
let weapon_type = weapon.weapon_type; let weapon_type = weapon.weapon_type;
const remove = () => ship_change( dux.actions.remove_weapon(id) ); const remove = () => ship?.dispatch_action("remove_weapon", id);
const update = ({ detail }) => {
ship?.dispatch_action("set_weapon", {
id,
weapon_type,
...detail,
});
};
const update = ({detail}) => {
ship_change( dux.actions.set_weapon({
id, weapon_type, ...detail
}) );
}
</script> </script>
<style> <style>
.weapon {
.weapon {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.weapon > * { .weapon > * {
margin-right: 2em; margin-right: 2em;
} }
.arcs { .arcs {
display: grid; display: grid;
grid-template-rows: 1fr 1fr 1fr 1fr; grid-template-rows: 1fr 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr 1fr;
align-items: center; align-items: center;
justify-items: center; justify-items: center;
width: 6em; width: 6em;
} }
.arc input {
margin: 0px;
}
.arc input { .arc.F {
margin: 0px; grid-column: 2 / span 2;
} grid-row: 1;
}
.arc.FS {
grid-column: 1;
grid-row: 1 / span 2;
}
.arc.F { .arc.FP {
grid-column: 2 / span 2; grid-column: 4;
grid-row: 1; grid-row: 1 / span 2;
} }
.arc.FS { .arc.AS {
grid-column: 1; grid-column: 1;
grid-row: 1 / span 2; grid-row: 3 / span 2;
} }
.arc.FP { .arc.AP {
grid-column: 4; grid-column: 4;
grid-row: 1 / span 2; grid-row: 3 / span 2;
} }
.arc.AS { .arc.A {
grid-column: 1; grid-column: 2 / span 2;
grid-row: 3 / span 2; grid-row: 4;
} }
.arc.AP { .add-weapon {
grid-column: 4;
grid-row: 3 / span 2;
}
.arc.A {
grid-column: 2 / span 2;
grid-row: 4;
}
.add-weapon {
display: block; display: block;
} }
.weapon_row { .weapon_row {
display: flex; display: flex;
@ -122,5 +125,4 @@
margin-right: 2em; margin-right: 2em;
} }
</style> </style>

View File

@ -6,17 +6,15 @@
<script> <script>
import get from "lodash/get.js";
import ShipItem from "../../ShipItem/index.svelte"; import ShipItem from "../../ShipItem/index.svelte";
import Field from "../../Field/index.svelte"; import Field from "../../Field/index.svelte";
import dux from "../../../dux";
import { getContext } from "svelte"; import { getContext } from "svelte";
export let rating = 0; export let rating = 0;
export let cost = 0; export let cost = 0;
export let mass = 0; export let mass = 0;
export let ship_change = getContext("ship_change") || (() => {}); export let ship = getContext("ship");
$: ship_change(dux.actions.set_adfc(rating)); $: ship?.dispatch_action('set_adfc',rating);
</script> </script>

View File

@ -1,24 +1,27 @@
<Field label="weapon type"> <Field label="weapon type">
<select bind:value={weapon_type}> <select bind:value={weapon_type}>
<option>beam</option> <option>beam</option>
<option value="submunition">submunition pack</option> <option value="submunition">submunition pack</option>
<option value="pds">point defence system</option> <option value="pds">point defence system</option>
<option>scattergun</option> <option>scattergun</option>
<option value="needle">needle weapon</option> <option value="needle">needle weapon</option>
</select> </select>
<input type="button" value="add weapon" class="button small blue" on:click={ add_weapon }/>
<input
type="button"
value="add weapon"
class="button small blue"
on:click={add_weapon}
/>
</Field> </Field>
<script> <script>
import Field from '../../Field/index.svelte'; import { getContext } from "svelte";
import {getContext } from 'svelte'; import Field from "../../Field/index.svelte";
import dux from '../../../dux';
export let weapon_type = "beam"; export let weapon_type = "beam";
export let ship_change = getContext('ship_change') || ( () => {} ); export let ship = getContext("ship");
const add_weapon = () => ship?.dispatch_action("add_weapon", weapon_type);
const add_weapon = () => ship_change( dux.actions.add_weapon(weapon_type) );
</script> </script>

View File

@ -1,3 +1,4 @@
import matches from 'lodash/matches.js';
import Updux from "updux"; import Updux from "updux";
import { action, payload } from "ts-action"; import { action, payload } from "ts-action";
import u from "@yanick/updeep"; import u from "@yanick/updeep";
@ -43,7 +44,7 @@ const set_weapon = action("set_weapon", payload());
dux.addMutation(set_weapon, (payload) => dux.addMutation(set_weapon, (payload) =>
u.map( u.map(
u.if(_.matches({ id: payload.id }), (state) => with_reqs(u(payload, state))) u.if(matches({ id: payload.id }), (state) => with_reqs(u(payload, state)))
) )
); );

View File

@ -1,4 +1,4 @@
import { browser } from '$app/env'; import { browser } from "$app/env";
import { readable } from "svelte/store"; import { readable } from "svelte/store";
import { compose, applyMiddleware } from "redux"; import { compose, applyMiddleware } from "redux";
@ -6,25 +6,22 @@ import { calc_ship_req } from "../dux/utils";
let composeEnhancers = compose; let composeEnhancers = compose;
if(browser) { if (browser) {
composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__; composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
} }
import shipDux from "../dux"; import shipDux from "../dux";
export default () => { export default () => {
let saved; let saved;
if(browser) saved = window.localStorage.getItem('aotds-shipyard'); if (browser) saved = window.localStorage.getItem("aotds-shipyard");
if( saved ) {
saved = JSON.parse(saved);
}
else {
saved = undefined;
}
console.log(saved);
if (saved) {
saved = JSON.parse(saved);
} else {
saved = undefined;
}
const duxStore = shipDux.createStore(saved, (mw) => const duxStore = shipDux.createStore(saved, (mw) =>
composeEnhancers(applyMiddleware(mw)) composeEnhancers(applyMiddleware(mw))
@ -34,20 +31,18 @@ export default () => {
duxStore.actions.set_ship_reqs(calc_ship_req(duxStore.getState())) duxStore.actions.set_ship_reqs(calc_ship_req(duxStore.getState()))
); );
Object.entries(duxStore.actions).forEach( ([type,action]) => { Object.entries(duxStore.actions).forEach(([type, action]) => {
duxStore.dispatch[ type ] = payload => duxStore.dispatch( action(payload) ) duxStore.dispatch[type] = (payload) => duxStore.dispatch(action(payload));
}); });
let previous = undefined; let previous = undefined;
duxStore.subscribe( () => { duxStore.subscribe(() => {
let current = duxStore.getState(); let current = duxStore.getState();
if ( previous === current ) return; if (previous === current) return;
previous = current; previous = current;
console.log(current);
if(browser)window.localStorage.setItem( if (browser)
'aotds-shipyard', JSON.stringify(current) window.localStorage.setItem("aotds-shipyard", JSON.stringify(current));
);
}); });
const state = readable(duxStore.getState(), (set) => const state = readable(duxStore.getState(), (set) =>
@ -56,10 +51,14 @@ export default () => {
}) })
); );
const dispatch_action = (action, payload) =>
duxStore.dispatch[action](payload);
return { return {
subscribe: state.subscribe, subscribe: state.subscribe,
dispatch: duxStore.dispatch, dispatch: duxStore.dispatch,
actions: duxStore.actions, actions: duxStore.actions,
selectors: duxStore.selectors, selectors: duxStore.selectors,
dispatch_action,
}; };
}; };

View File

@ -1,4 +1,5 @@
import adapter from '@sveltejs/adapter-static'; import adapter from '@sveltejs/adapter-static';
import analyze from 'rollup-plugin-analyzer';
/** @type {import('@sveltejs/kit').Config} */ /** @type {import('@sveltejs/kit').Config} */
export default { export default {
@ -13,6 +14,7 @@ export default {
vite: { vite: {
build: { build: {
rollupOptions: { rollupOptions: {
plugins: [ analyze() ],
// external: ['updux','@yanick/updeep'] // external: ['updux','@yanick/updeep']
} }
} }