Merge branch 'cumulative-cost' into version-2
This commit is contained in:
commit
e2560d6e16
@ -2,6 +2,7 @@ const path = require("path");
|
||||
const preprocess = require("svelte-preprocess");
|
||||
|
||||
module.exports = {
|
||||
// core: { builder: "storybook-builder-vite" },
|
||||
staticDirs: ["../static", "../pictures"],
|
||||
stories: [
|
||||
"../src/**/*.stories.mdx",
|
||||
@ -9,13 +10,20 @@ module.exports = {
|
||||
"../src/**/stories.svelte",
|
||||
],
|
||||
addons: [
|
||||
"@storybook/addon-links",
|
||||
"@storybook/addon-essentials",
|
||||
"@storybook/addon-svelte-csf",
|
||||
],
|
||||
framework: "@storybook/svelte",
|
||||
svelteOptions: {
|
||||
preprocess: preprocess(),
|
||||
},
|
||||
async viteFinal(config, { configType }) {
|
||||
// customize the Vite config here
|
||||
config.resolve.alias.$lib = path.resolve(__dirname, "../src/lib/");
|
||||
config.resolve.alias.$app = path.resolve(__dirname, "../fake/app/");
|
||||
|
||||
// return the customized config
|
||||
return config;
|
||||
},
|
||||
webpackFinal: async (config) => {
|
||||
return {
|
||||
|
@ -24,14 +24,13 @@
|
||||
"eslint-plugin-svelte3": "^3.4.1",
|
||||
"prettier": "~2.5.1",
|
||||
"prettier-plugin-svelte": "^2.6.0",
|
||||
"storybook-builder-vite": "0.1.17",
|
||||
"svelte": "^3.46.4",
|
||||
"vite": "^2.7.0"
|
||||
},
|
||||
"type": "module",
|
||||
"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",
|
||||
|
@ -66,22 +66,6 @@ dux.addSubscription((store) =>
|
||||
createSelector(calc_ship_req, (reqs) => store.dispatch(set_ship_reqs(reqs)))
|
||||
);
|
||||
|
||||
dux.addSubscription((store) =>
|
||||
createSelector(
|
||||
(store) => store.general.mass,
|
||||
(store) => store.streamlining.type,
|
||||
(ship_mass, streamlining) => {
|
||||
const mass = ceil(
|
||||
(ship_mass *
|
||||
(streamlining === "none" ? 0 : streamlining === "partial" ? 5 : 10)) /
|
||||
100
|
||||
);
|
||||
const cost = 2 * mass;
|
||||
|
||||
store.dispatch(dux.actions.set_streamlining_cost_mass({ cost, mass }));
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
dux.addSubscription((store) =>
|
||||
createSelector(
|
||||
@ -145,18 +129,6 @@ dux.addSubscription((store) =>
|
||||
)
|
||||
);
|
||||
|
||||
const calc_firecons_reqs = (nbr) => ({
|
||||
cost: 4 * nbr,
|
||||
mass: nbr,
|
||||
});
|
||||
|
||||
const set_firecons = action("set_firecons", payload());
|
||||
dux.addMutation(set_firecons, (nbr) =>
|
||||
u.updateIn("weaponry.firecons", {
|
||||
nbr,
|
||||
...calc_firecons_reqs(nbr),
|
||||
})
|
||||
);
|
||||
|
||||
export default dux.asDux;
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
import Updux from "updux";
|
||||
import { action, payload } from "ts-action";
|
||||
import u from "@yanick/updeep";
|
||||
|
||||
const dux = new Updux({
|
||||
initial: {
|
||||
rating: 0,
|
||||
cost: 0,
|
||||
mass: 0,
|
||||
},
|
||||
})
|
||||
|
||||
dux.addMutation( action( 'set_adfc', payload() ), rating =>
|
||||
u.update({ rating, mass: 2 * rating, cost: 8 * rating })
|
||||
);
|
||||
|
||||
export default dux.asDux;
|
@ -1,74 +0,0 @@
|
||||
|
||||
export function weapon_cost_mass(weapon){
|
||||
let cost = 0;
|
||||
let mass = 0;
|
||||
|
||||
if( weapon.weapon_type === 'beam' ) {
|
||||
return beam_cost_mass(weapon);
|
||||
}
|
||||
|
||||
if( weapon.weapon_type == 'submunition' ) {
|
||||
return { mass: 1, cost: 3 };
|
||||
}
|
||||
|
||||
if( weapon.weapon_type === 'pds' ) {
|
||||
return { mass: 1, cost: 3 };
|
||||
}
|
||||
|
||||
if( weapon.weapon_type === 'scattergun' ) {
|
||||
return { mass: 1, cost: 4 };
|
||||
}
|
||||
|
||||
if( weapon.weapon_type === 'needle' ) {
|
||||
return { mass: 2, cost: 6 };
|
||||
}
|
||||
|
||||
return { cost, mass };
|
||||
}
|
||||
|
||||
const is_broadside = arcs => {
|
||||
if( arcs.length !== 4 ) return false;
|
||||
|
||||
// that'd be A or F
|
||||
return !arcs.some( a => a.length === 1 );
|
||||
}
|
||||
|
||||
function beam_cost_mass({weapon_class, arcs}) {
|
||||
let mass;
|
||||
if( weapon_class === 1 ) {
|
||||
mass = 1;
|
||||
}
|
||||
|
||||
if( weapon_class == 2 ) {
|
||||
mass = 2 + (arcs.length > 3 ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
if( weapon_class == 3 ) {
|
||||
mass = 4;
|
||||
|
||||
if( is_broadside(arcs) ) {
|
||||
mass += 2;
|
||||
}
|
||||
else {
|
||||
mass += arcs.length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( weapon_class == 4 ) {
|
||||
mass = 8;
|
||||
|
||||
if( is_broadside(arcs) ) {
|
||||
mass += 4;
|
||||
}
|
||||
else {
|
||||
mass += 2*(arcs.length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
mass, cost: 3 * mass
|
||||
}
|
||||
|
||||
|
||||
}
|
33
src/lib/components/ShipEdit/Carrier/Carrier.stories.svelte
Normal file
33
src/lib/components/ShipEdit/Carrier/Carrier.stories.svelte
Normal file
@ -0,0 +1,33 @@
|
||||
<Meta title="ShipEdit/Carrier" component={Carrier} argTypes={{}} />
|
||||
|
||||
<Story name="Primary" args={{}} />
|
||||
|
||||
<Template let:args>
|
||||
<div style="width: 50em">
|
||||
<Carrier {...args} {...$state}/>
|
||||
</div>
|
||||
</Template>
|
||||
|
||||
<script>
|
||||
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
|
||||
import { setContext } from "svelte";
|
||||
import { readable, get, derived } from "svelte/store";
|
||||
|
||||
import Carrier from "./index.svelte";
|
||||
import carrierDux from '$lib/shipDux/carrier.js'
|
||||
|
||||
const carrierStore = carrierDux.createStore();
|
||||
const state = readable(carrierStore.getState(), (set) => {
|
||||
carrierStore.subscribe(() => {
|
||||
set(carrierStore.getState());
|
||||
});
|
||||
});
|
||||
|
||||
setContext("ship", {
|
||||
dispatch: carrierStore.dispatch,
|
||||
shipMass: readable(50),
|
||||
state,
|
||||
});
|
||||
</script>
|
@ -1,4 +1,4 @@
|
||||
<ShipItem {cost} {mass}>
|
||||
<ShipItem {...reqs}>
|
||||
<Field label={`squadron ${id}`}>
|
||||
<select bind:value={type}>
|
||||
{#each types as type (type)}
|
||||
@ -14,24 +14,20 @@
|
||||
import Section from "$lib/components/Section/index.svelte";
|
||||
import Field from "$lib/components/Field/index.svelte";
|
||||
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
||||
import dux from "$lib/dux/carrier";
|
||||
import squadron_types from "$lib/dux/carrier/squadron_types";
|
||||
import { squadronTypes } from "$lib/shipDux/carrier.js";
|
||||
|
||||
const types = squadron_types.map(({ type }) => type);
|
||||
const types = squadronTypes.map(({ type }) => type);
|
||||
|
||||
export let id = 1;
|
||||
export let type = "standard";
|
||||
export let ftl = false;
|
||||
export let cost = 0;
|
||||
export let mass = 0;
|
||||
export let type = types[0].type;
|
||||
export let reqs= {};
|
||||
|
||||
export let ship = getContext("ship");
|
||||
export let { dispatch } = getContext("ship");
|
||||
|
||||
$: console.log(type)
|
||||
$: dispatch.setSquadronType({type, id});
|
||||
|
||||
$: ship?.dispatch_action("set_squadron", { id, type });
|
||||
</script>
|
||||
|
||||
<style>
|
||||
div {
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
34
src/lib/components/ShipEdit/Carrier/index.svelte
Normal file
34
src/lib/components/ShipEdit/Carrier/index.svelte
Normal file
@ -0,0 +1,34 @@
|
||||
<Section label="carrier">
|
||||
<ShipItem {...reqs}>
|
||||
<Field label="bays">
|
||||
<input type="number" min="0" bind:value={bays} />
|
||||
</Field>
|
||||
</ShipItem>
|
||||
|
||||
{#each squadrons as squadron,id (id)}
|
||||
<Squadron {...squadron} id={id+1} />
|
||||
{/each}
|
||||
</Section>
|
||||
|
||||
<script>
|
||||
import { getContext } from 'svelte';
|
||||
import Field from '$lib/components/Field/index.svelte';
|
||||
import ShipItem from '$lib/components/ShipItem/index.svelte';
|
||||
import Section from '$lib/components/Section/index.svelte';
|
||||
import Squadron from './Squadron.svelte';
|
||||
|
||||
export let bays = 0;
|
||||
export let reqs = {};
|
||||
export let squadrons = [];
|
||||
|
||||
const { dispatch } = getContext('ship');
|
||||
|
||||
$: dispatch.setCarrierBays(bays);
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
input {
|
||||
width: 5em;
|
||||
}
|
||||
</style>
|
@ -1,4 +1,4 @@
|
||||
<Meta title="Identification" component={Identification} argTypes={{}} />
|
||||
<Meta title="ShipEdit/Identification" component={Identification} argTypes={{}} />
|
||||
|
||||
<Story name="Primary" args={{}} />
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
const ship_types = [
|
||||
{ name: "Scout", mass: [4, 10], abbrev: "SC" },
|
||||
{ name: "Scout", mass: [0, 10], abbrev: "SC" },
|
||||
{ name: "Courier", mass: [4, 10], abbrev: "SC" },
|
||||
{ name: "Corvette", mass: [8, 16], abbrev: "CT" },
|
||||
{ name: "Frigate", mass: [14, 28], abbrev: "FF" },
|
||||
@ -14,7 +14,7 @@ const ship_types = [
|
||||
{ name: "Heavy Battleship", mass: [120, 160], abbrev: "BDN" },
|
||||
{ name: "Dreadnought", mass: [140, 180], abbrev: "DN" },
|
||||
{ name: "Superdreadnought", mass: [160, 300], abbrev: "SDN" },
|
||||
{ name: "Escort Carrier", mass: [60, 140], abbrev: "CVE", carrier: true },
|
||||
{ name: "Escort Carrier", mass: [0, 140], abbrev: "CVE", carrier: true },
|
||||
{ name: "Light Carrier", mass: [120, 180], abbrev: "CVL", carrier: true },
|
||||
{ name: "Heavy Carrier", mass: [160, 300], abbrev: "CVH", carrier: true },
|
||||
{ name: "Attack Carrier", mass: [150, 300], abbrev: "CVA", carrier: true },
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
const ship = getContext("ship");
|
||||
|
||||
console.log( ship.dispatch )
|
||||
$: ship.dispatch.setDrive({ rating, advanced });
|
||||
</script>
|
||||
|
||||
|
41
src/lib/components/ShipEdit/Structure/Armor.svelte
Normal file
41
src/lib/components/ShipEdit/Structure/Armor.svelte
Normal file
@ -0,0 +1,41 @@
|
||||
<ShipItem {...reqs}>
|
||||
<div>
|
||||
<div class="nbr_layers">
|
||||
<Field label="armour layers">
|
||||
<input type="number" min="0" bind:value={nbr_layers} />
|
||||
</Field>
|
||||
</div>
|
||||
|
||||
<div class="layers">
|
||||
{#each layers as rating,i (i)}
|
||||
<Layer {rating} layer={i+1} />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</ShipItem>
|
||||
|
||||
<script>
|
||||
import { getContext } from 'svelte';
|
||||
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
||||
import Field from "$lib/components/Field/index.svelte";
|
||||
import Layer from "./Armor/Layer.svelte";
|
||||
|
||||
export let layers = [];
|
||||
export let reqs = {};
|
||||
|
||||
let nbr_layers = layers.length;
|
||||
|
||||
const { dispatch } = getContext('ship');
|
||||
|
||||
$: dispatch.setArmorLayers(nbr_layers);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.layers {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 5em;
|
||||
}
|
||||
</style>
|
22
src/lib/components/ShipEdit/Structure/Armor/Layer.svelte
Normal file
22
src/lib/components/ShipEdit/Structure/Armor/Layer.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.setArmorRating({ layer, rating });
|
||||
</script>
|
||||
|
||||
<style>
|
||||
input {
|
||||
width: 5em;
|
||||
}
|
||||
</style>
|
25
src/lib/components/ShipEdit/Structure/Cargo.svelte
Normal file
25
src/lib/components/ShipEdit/Structure/Cargo.svelte
Normal file
@ -0,0 +1,25 @@
|
||||
<ShipItem {...reqs}>
|
||||
<Field label="cargo">
|
||||
<input type="number" min="0" bind:value={space} />
|
||||
</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 ship = getContext("ship");
|
||||
|
||||
export let space = 0;
|
||||
export let reqs = {};
|
||||
|
||||
$: ship.dispatch.setCargo(space);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
input {
|
||||
width: 5em;
|
||||
}
|
||||
</style>
|
41
src/lib/components/ShipEdit/Structure/Streamlining.svelte
Normal file
41
src/lib/components/ShipEdit/Structure/Streamlining.svelte
Normal file
@ -0,0 +1,41 @@
|
||||
<ShipItem {...reqs}>
|
||||
<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 reqs = {};
|
||||
|
||||
export let {dispatch, shipMass} = getContext("ship");
|
||||
|
||||
$: dispatch.setStreamlining({type, shipMass: $shipMass});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
div {
|
||||
display: flex;
|
||||
}
|
||||
label {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
@ -1,15 +1,24 @@
|
||||
<Section label="structure">
|
||||
<Hull {...hull}/>
|
||||
<Screens {...screens} />
|
||||
<Armor {...armor} />
|
||||
<Cargo {...cargo} />
|
||||
<Streamlining {...streamlining} />
|
||||
</Section>
|
||||
|
||||
<script>
|
||||
import Section from "$lib/components/Section/index.svelte";
|
||||
import Hull from './Hull.svelte';
|
||||
import Screens from './Screens.svelte';
|
||||
import Cargo from './Cargo.svelte';
|
||||
import Armor from './Armor.svelte';
|
||||
import Streamlining from './Streamlining.svelte';
|
||||
|
||||
export let hull = {};
|
||||
export let screens = {};
|
||||
export let cargo = {};
|
||||
export let streamlining = {};
|
||||
export let armor = {};
|
||||
|
||||
|
||||
</script>
|
||||
|
18
src/lib/components/ShipEdit/Weaponry/ADFC.svelte
Normal file
18
src/lib/components/ShipEdit/Weaponry/ADFC.svelte
Normal file
@ -0,0 +1,18 @@
|
||||
<ShipItem {...reqs}>
|
||||
<Field label="ADFC">
|
||||
<input type="number" class="short" bind:value={rating} />
|
||||
</Field>
|
||||
</ShipItem>
|
||||
|
||||
<script>
|
||||
import { getContext } from 'svelte';
|
||||
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
||||
import Field from "$lib/components/Field/index.svelte";
|
||||
|
||||
export let rating = 0;
|
||||
export let reqs = {};
|
||||
|
||||
const { dispatch } = getContext('ship');
|
||||
|
||||
$: dispatch.setADFC(rating);
|
||||
</script>
|
22
src/lib/components/ShipEdit/Weaponry/AddWeapon.svelte
Normal file
22
src/lib/components/ShipEdit/Weaponry/AddWeapon.svelte
Normal file
@ -0,0 +1,22 @@
|
||||
<Field label="weapon type">
|
||||
<select bind:value={type}>
|
||||
{#each weaponTypes as weapon (weapon.type)}
|
||||
<option value={weapon.type}>{weapon.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
<button class="button small blue" on:click={addWeapon} >add weapon</button>
|
||||
</Field>
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
import Field from "../../Field/index.svelte";
|
||||
|
||||
import { weaponTypes } from '$lib/shipDux/weaponry/weapons.js';
|
||||
|
||||
export let ship = getContext("ship");
|
||||
|
||||
let type = weaponTypes[0].value;
|
||||
|
||||
const addWeapon = () => ship.dispatch.addWeapon(type);
|
||||
</script>
|
21
src/lib/components/ShipEdit/Weaponry/Firecons.svelte
Normal file
21
src/lib/components/ShipEdit/Weaponry/Firecons.svelte
Normal file
@ -0,0 +1,21 @@
|
||||
<ShipItem {...reqs}>
|
||||
<Field label="firecons">
|
||||
<input type="number" class="short" bind:value={stations} />
|
||||
</Field>
|
||||
</ShipItem>
|
||||
|
||||
<script>
|
||||
import { getContext } from 'svelte';
|
||||
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
||||
import Field from "$lib/components/Field/index.svelte";
|
||||
|
||||
export let stations = 0;
|
||||
export let reqs = {};
|
||||
|
||||
const { dispatch } = getContext('ship');
|
||||
|
||||
$: dispatch.setFirecons(stations);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -12,7 +12,7 @@
|
||||
</svg>
|
||||
|
||||
<script>
|
||||
import Arc from "../../Weapons/Arc.svelte";
|
||||
import Arc from "./Arc.svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
const all_arcs = ["FS", "F", "FP", "AP", "A", "AS"];
|
Before Width: | Height: | Size: 651 B After Width: | Height: | Size: 639 B |
@ -0,0 +1,83 @@
|
||||
<label>beam</label>
|
||||
|
||||
<Field label="beam class">
|
||||
<select bind:value={weaponClass}>
|
||||
<option value={1}>1</option>
|
||||
<option value={2}>2</option>
|
||||
<option value={3}>3</option>
|
||||
<option value={4}>4</option>
|
||||
</select>
|
||||
</Field>
|
||||
|
||||
<Field label="arcs">
|
||||
<select bind:value={nbrArcs}>
|
||||
{#each arc_options[weaponClass] || [] as nbrArcs (nbrArcs)}
|
||||
<option>{nbrArcs}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</Field>
|
||||
|
||||
<Arcs selected={arcs} on:click_arc={({ detail }) => setArcs(detail)} />
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import Arcs from "../Arcs.svelte";
|
||||
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
||||
import Field from "$lib/components/Field/index.svelte";
|
||||
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
const all_arcs = ["FS", "F", "FP", "AP", "A", "AS"];
|
||||
|
||||
export let weaponClass = 1;
|
||||
export let arcs = ["F"];
|
||||
|
||||
let arc_options = {
|
||||
1: [6],
|
||||
2: [3, 6],
|
||||
3: [1, 2, 3, 4, 5, 6, "broadside"],
|
||||
4: [1, 2, 3, 4, 5, 6, "broadside"],
|
||||
};
|
||||
|
||||
$: arcsCaches = arcs.join(',');
|
||||
|
||||
let nbrArcs = arcs.length;
|
||||
|
||||
$: if (!arc_options[weaponClass].includes(nbrArcs)) {
|
||||
nbrArcs = arc_options[weaponClass][0];
|
||||
console.log({nbrArcs, label:"in if"})
|
||||
}
|
||||
|
||||
const broadside = ["FS", "FP", "AP", "AS"];
|
||||
|
||||
|
||||
function setArcs(firstArc) {
|
||||
console.log(firstArc);
|
||||
if (nbrArcs === "broadside") {
|
||||
arcs = broadside;
|
||||
return;
|
||||
}
|
||||
let first_index = all_arcs.findIndex((arc) => arc === firstArc);
|
||||
if (first_index === -1) first_index = 0;
|
||||
|
||||
console.log({arcs, label:"before"});
|
||||
arcs = _.range(nbrArcs).map(
|
||||
(i) => all_arcs[(first_index + i) % all_arcs.length]
|
||||
);
|
||||
arcsCaches = arcs.join(',');
|
||||
console.log({arcs, label:"after"});
|
||||
}
|
||||
|
||||
$: if (arcs.length !== nbrArcs) setArcs(arcs[0]);
|
||||
|
||||
$: console.log("it changed!", arcs)
|
||||
$: console.log("it changed!", arcsCaches)
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
$: dispatch("change", {
|
||||
weaponClass,
|
||||
arcs: arcsCaches.split(','),
|
||||
});
|
||||
</script>
|
27
src/lib/components/ShipEdit/Weaponry/Weapon/Needle.svelte
Normal file
27
src/lib/components/ShipEdit/Weaponry/Weapon/Needle.svelte
Normal file
@ -0,0 +1,27 @@
|
||||
<label>needle weapon</label>
|
||||
|
||||
<Arcs selected={[arc]} on:click_arc={({ detail }) => click_arc(detail)} />
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
import Arcs from "./Arcs.svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
const all_arcs = ["FS", "F", "FP", "AP", "A", "AS"];
|
||||
|
||||
export let arc = "F";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const click_arc = (arc) => {
|
||||
dispatch("change",{arc});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.arc {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 1em;
|
||||
}
|
||||
</style>
|
1
src/lib/components/ShipEdit/Weaponry/Weapon/PDS.svelte
Normal file
1
src/lib/components/ShipEdit/Weaponry/Weapon/PDS.svelte
Normal file
@ -0,0 +1 @@
|
||||
<label>point defence system</label>
|
@ -0,0 +1,19 @@
|
||||
<label>submunition pack</label>
|
||||
|
||||
<Arcs selected={[arc]} on:click_arc={({ detail }) => click_arc(detail)} />
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
import Arcs from "./Arcs.svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
const all_arcs = ["FS", "F", "FP", "AP", "A", "AS"];
|
||||
|
||||
export let arc = "F";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const click_arc = (arc) => {
|
||||
dispatch("change",{arc});
|
||||
};
|
||||
</script>
|
121
src/lib/components/ShipEdit/Weaponry/Weapon/index.svelte
Normal file
121
src/lib/components/ShipEdit/Weaponry/Weapon/index.svelte
Normal file
@ -0,0 +1,121 @@
|
||||
<ShipItem {...reqs}>
|
||||
<div class="weapon_row">
|
||||
<button
|
||||
class="button small red remove"
|
||||
on:click={remove}>remove
|
||||
</button>
|
||||
|
||||
<svelte:component
|
||||
this={component[type]}
|
||||
{...weapon}
|
||||
on:change={update}
|
||||
/>
|
||||
</div>
|
||||
</ShipItem>
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import Arc from "./Arc.svelte";
|
||||
import ShipItem from "$lib/components/ShipItem/index.svelte";
|
||||
import Field from "$lib/components/Field/index.svelte";
|
||||
import Beam from "./Beam/index.svelte";
|
||||
import Submunition from "./Submunition.svelte";
|
||||
import PointDefenceSystem from "./PDS.svelte";
|
||||
import Scattergun from "./Scattergun.svelte";
|
||||
import Needle from "./Needle.svelte";
|
||||
|
||||
const component = {
|
||||
beam: Beam,
|
||||
submunition: Submunition,
|
||||
pds: PointDefenceSystem,
|
||||
scattergun: Scattergun,
|
||||
needle: Needle,
|
||||
};
|
||||
|
||||
export let weapon = {};
|
||||
$: reqs = weapon.reqs;
|
||||
export let id;
|
||||
|
||||
const ship = getContext("ship");
|
||||
|
||||
$: type = weapon.type;
|
||||
|
||||
const remove = () => ship.dispatch.removeWeapon(id);
|
||||
|
||||
const update = ({ detail }) => {
|
||||
console.log({id,type})
|
||||
ship.dispatch.setWeapon({
|
||||
id,
|
||||
type,
|
||||
...detail,
|
||||
});
|
||||
};
|
||||
</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;
|
||||
}
|
||||
|
||||
.add-weapon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.weapon_row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.weapon_row > :global(*) {
|
||||
margin-right: 2em;
|
||||
}
|
||||
</style>
|
34
src/lib/components/ShipEdit/Weaponry/Weaponry.stories.svelte
Normal file
34
src/lib/components/ShipEdit/Weaponry/Weaponry.stories.svelte
Normal file
@ -0,0 +1,34 @@
|
||||
<Meta title="ShipEdit/Weaponry" component={Weaponry} argTypes={{}} />
|
||||
|
||||
<Story name="Primary" args={{}} />
|
||||
|
||||
<Template let:args>
|
||||
<div style="width: 50em">
|
||||
<Weaponry {...args} {...$state}/>
|
||||
</div>
|
||||
</Template>
|
||||
|
||||
<script>
|
||||
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
|
||||
import { setContext } from "svelte";
|
||||
import { readable, get, derived } from "svelte/store";
|
||||
|
||||
import Weaponry from "./index.svelte";
|
||||
import weaponryDux from '$lib/shipDux/weaponry/index.js';
|
||||
|
||||
const store = weaponryDux.createStore();
|
||||
const state = readable(store.getState(), (set) => {
|
||||
store.subscribe(() => {
|
||||
console.log(store.getState());
|
||||
set(store.getState());
|
||||
});
|
||||
});
|
||||
|
||||
setContext("ship", {
|
||||
dispatch: store.dispatch,
|
||||
shipMass: readable(50),
|
||||
state,
|
||||
});
|
||||
</script>
|
34
src/lib/components/ShipEdit/Weaponry/index.svelte
Normal file
34
src/lib/components/ShipEdit/Weaponry/index.svelte
Normal file
@ -0,0 +1,34 @@
|
||||
<Section label="weaponry">
|
||||
<Firecons {...firecons} />
|
||||
|
||||
<ADFC {...adfc} />
|
||||
|
||||
<AddWeapon />
|
||||
|
||||
{#each weapons as weapon (weapon.id)}
|
||||
<Weapon {weapon} id={weapon.id} />
|
||||
{/each}
|
||||
|
||||
</Section>
|
||||
|
||||
<script>
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
import Section from "$lib/components/Section/index.svelte";
|
||||
import ShipItem from '$lib/components/ShipItem/index.svelte';
|
||||
import Field from '$lib/components/Field/index.svelte';
|
||||
|
||||
import Firecons from './Firecons.svelte';
|
||||
import ADFC from './ADFC.svelte';
|
||||
import AddWeapon from './AddWeapon.svelte';
|
||||
import Weapon from './Weapon/index.svelte';
|
||||
|
||||
export let firecons = {};
|
||||
export let adfc = {};
|
||||
|
||||
export let weapons = [];
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -8,6 +8,10 @@
|
||||
|
||||
<Structure {...$shipState.structure} />
|
||||
|
||||
<Weaponry {...$shipState.weaponry}/>
|
||||
|
||||
<Carrier {...$shipState.carrier} />
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
|
||||
@ -15,6 +19,8 @@
|
||||
import ShipCost from "./ShipCost.svelte";
|
||||
import Propulsion from "./Propulsion/index.svelte";
|
||||
import Structure from "./Structure/index.svelte";
|
||||
import Carrier from "./Carrier/index.svelte";
|
||||
import Weaponry from "./Weaponry/index.svelte";
|
||||
|
||||
const { state: shipState } = getContext("ship");
|
||||
</script>
|
||||
|
@ -1,35 +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>
|
76
src/lib/shipDux/carrier.js
Normal file
76
src/lib/shipDux/carrier.js
Normal file
@ -0,0 +1,76 @@
|
||||
import { Updux } from "updux";
|
||||
import u from "updeep";
|
||||
import _ from 'lodash';
|
||||
|
||||
import reqs from "./reqs.js";
|
||||
|
||||
const dux = new Updux({
|
||||
subduxes: { reqs },
|
||||
initial: {
|
||||
bays: 0,
|
||||
squadrons: [],
|
||||
},
|
||||
actions: {
|
||||
setCarrierBays: null,
|
||||
setSquadronType: null,
|
||||
}
|
||||
});
|
||||
|
||||
dux.setMutation( 'setCarrierBays', bays => u({bays, reqs:
|
||||
calcBaysReqs(bays),
|
||||
squadrons: adjustSquadrons(bays),
|
||||
}) );
|
||||
|
||||
dux.setMutation('setSquadronType', ({type, id}) => state => {
|
||||
|
||||
return u.updateIn(['squadrons', id-1], {
|
||||
type,
|
||||
reqs: squadronReqs(type)
|
||||
}, state )
|
||||
|
||||
} );
|
||||
|
||||
export const squadronTypes= [
|
||||
{ type: "standard", cost: 3 },
|
||||
{ type: "fast", cost: 4 },
|
||||
{ type: "heavy", cost: 5 },
|
||||
{ type: "interceptor", cost: 3 },
|
||||
{ type: "attack", cost: 4 },
|
||||
{ type: "long range", cost: 4 },
|
||||
{ type: "torpedo", cost: 6 },
|
||||
];
|
||||
|
||||
function squadronReqs(type) {
|
||||
return { mass: 6, cost: 6 * squadronTypes.find( s => s.type === type )?.cost }
|
||||
}
|
||||
|
||||
|
||||
const adjustSquadrons = bays => squadrons => {
|
||||
if( squadrons.length > bays ) {
|
||||
squadrons = squadrons.slice(0,bays);
|
||||
}
|
||||
|
||||
if( squadrons.length < bays ) {
|
||||
squadrons = [ ...squadrons, ..._.times(
|
||||
bays - squadrons.length, () => ({
|
||||
type: squadronTypes[0].type,
|
||||
reqs: {
|
||||
cost: 6 * squadronTypes[0].cost,
|
||||
mass: 6,
|
||||
},
|
||||
})
|
||||
)];
|
||||
}
|
||||
|
||||
return squadrons;
|
||||
|
||||
}
|
||||
|
||||
function calcBaysReqs(bays) {
|
||||
return {
|
||||
mass: 9 * bays,
|
||||
cost: 18 * bays,
|
||||
}
|
||||
}
|
||||
|
||||
export default dux;
|
@ -1,10 +1,13 @@
|
||||
import { Updux } from "updux";
|
||||
import u from "updeep";
|
||||
|
||||
import carrier from './carrier.js';
|
||||
|
||||
const dux = new Updux({
|
||||
actions: {
|
||||
setShipType: null,
|
||||
setShipClass: null,
|
||||
setCarrierBays: carrier.actions.setCarrierBays,
|
||||
},
|
||||
initial: {
|
||||
shipType: "",
|
||||
@ -16,5 +19,8 @@ const dux = new Updux({
|
||||
|
||||
dux.setMutation("setShipType", (shipType) => u({ shipType }));
|
||||
dux.setMutation("setShipClass", (shipClass) => u({ shipClass }));
|
||||
dux.setMutation('setCarrierBays', (bays) => u({
|
||||
isCarrier: bays > 0,
|
||||
}))
|
||||
|
||||
export default dux;
|
||||
|
@ -1,30 +1,59 @@
|
||||
import { Updux } from "updux";
|
||||
import u from 'updeep';
|
||||
import u from "updeep";
|
||||
|
||||
import propulsion from "./propulsion/index.js";
|
||||
import identification from "./identification.js";
|
||||
import { calculateDriveReqs } from './propulsion/drive.js';
|
||||
import { ftlReqsReaction } from './propulsion/ftl.js';
|
||||
import structure from './structure/index.js';
|
||||
import { screenReqsReaction, screensReqsReaction } from './structure/screens.js'
|
||||
import { calculateDriveReqs } from "./propulsion/drive.js";
|
||||
import { ftlReqsReaction } from "./propulsion/ftl.js";
|
||||
import structure from "./structure/index.js";
|
||||
import carrier from "./carrier.js";
|
||||
import weaponry from "./weaponry/index.js";
|
||||
import { screensReqsReaction } from "./structure/screens.js";
|
||||
|
||||
const dux = new Updux({
|
||||
subduxes: {
|
||||
identification,
|
||||
propulsion,
|
||||
structure
|
||||
},
|
||||
initial: {
|
||||
reqs: { cost: 0, mass: 10, usedMass: 0 },
|
||||
},
|
||||
subduxes: {
|
||||
identification,
|
||||
propulsion,
|
||||
structure,
|
||||
carrier,
|
||||
weaponry,
|
||||
},
|
||||
initial: {
|
||||
reqs: { cost: 0, mass: 10, usedMass: 0 },
|
||||
},
|
||||
actions: {
|
||||
}
|
||||
setShipReqs: null,
|
||||
},
|
||||
});
|
||||
|
||||
dux.setMutation( 'setShipMass', mass => u({reqs: {mass}}) );
|
||||
dux.setMutation("setShipMass", (mass) => u({ reqs: { mass } }));
|
||||
dux.setMutation('setShipReqs', reqs => u({reqs}));
|
||||
|
||||
dux.addReaction(calculateDriveReqs);
|
||||
dux.addReaction(ftlReqsReaction);
|
||||
dux.addReaction(screensReqsReaction);
|
||||
|
||||
dux.addReaction( (store) => (state) => {
|
||||
let cost = 0;
|
||||
let mass = 0;
|
||||
|
||||
let subsystems = Object.values(state);
|
||||
|
||||
while(subsystems.length>0) {
|
||||
const subsystem = subsystems.shift();
|
||||
if( typeof subsystem !== 'object' ) continue;
|
||||
|
||||
if( subsystem.reqs ) {
|
||||
cost += subsystem.reqs.cost;
|
||||
mass += subsystem.reqs.mass;
|
||||
}
|
||||
|
||||
subsystems.push( ...Object.values(subsystem));
|
||||
}
|
||||
|
||||
store.dispatch.setShipReqs({cost,usedMass: mass});
|
||||
|
||||
});
|
||||
|
||||
dux.addReaction( calculateDriveReqs );
|
||||
dux.addReaction( ftlReqsReaction );
|
||||
dux.addReaction( screenReqsReaction );
|
||||
|
||||
export default dux;
|
||||
|
50
src/lib/shipDux/structure/armor.js
Normal file
50
src/lib/shipDux/structure/armor.js
Normal file
@ -0,0 +1,50 @@
|
||||
import { Updux } from "updux";
|
||||
import u from "updeep";
|
||||
|
||||
import reqs from "../reqs.js";
|
||||
|
||||
const dux = new Updux({
|
||||
subduxes: {
|
||||
reqs,
|
||||
},
|
||||
initial: {
|
||||
layers: [],
|
||||
},
|
||||
actions: {
|
||||
setArmorLayers: null,
|
||||
setArmorRating: null,
|
||||
},
|
||||
});
|
||||
export default dux;
|
||||
|
||||
dux.setMutation('setArmorRating', ({layer, rating}) => state => {
|
||||
let layers = [ ...state.layers ].map( (v,k) => k === layer-1 ? rating : v );
|
||||
|
||||
return { layers, reqs: calcArmorReqs(layers) }
|
||||
} );
|
||||
|
||||
dux.setMutation( 'setArmorLayers', nbrLayers => state => {
|
||||
|
||||
let layers = [...state.layers];
|
||||
|
||||
if( nbrLayers < state.layers.length )
|
||||
layers = [ ...state.layers ].slice(0,nbrLayers);
|
||||
|
||||
while( layers.length < nbrLayers ) {
|
||||
layers.push(0);
|
||||
}
|
||||
|
||||
return {
|
||||
layers,
|
||||
reqs: calcArmorReqs(layers),
|
||||
}
|
||||
});
|
||||
|
||||
function calcArmorReqs(layers) {
|
||||
const mass = 2* layers.reduce( (a,b) => a+ b,0 );
|
||||
const cost = 2* layers.map( (v,k) => v * (k+1) ).reduce( (a,b) => a+ b,0 );
|
||||
|
||||
return {
|
||||
mass, cost
|
||||
}
|
||||
}
|
24
src/lib/shipDux/structure/cargo.js
Normal file
24
src/lib/shipDux/structure/cargo.js
Normal file
@ -0,0 +1,24 @@
|
||||
import { Updux } from "updux";
|
||||
import u from 'updeep';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import reqs from '../reqs.js';
|
||||
|
||||
const dux = new Updux({
|
||||
subduxes: {
|
||||
reqs
|
||||
},
|
||||
initial: {
|
||||
space: 0,
|
||||
},
|
||||
actions: {
|
||||
setCargo: null,
|
||||
}
|
||||
});
|
||||
export default dux;
|
||||
|
||||
dux.setMutation('setCargo', space => u({
|
||||
space,
|
||||
reqs: { mass: space }
|
||||
}));
|
||||
|
@ -2,8 +2,12 @@ import { Updux } from 'updux';
|
||||
|
||||
import hull from './hull.js';
|
||||
import screens from './screens.js';
|
||||
import cargo from './cargo.js';
|
||||
import armor from './armor.js';
|
||||
import streamlining from './streamlining.js';
|
||||
|
||||
const dux = new Updux({
|
||||
subduxes: { hull, screens }
|
||||
subduxes: { hull, screens, cargo, streamlining, armor }
|
||||
});
|
||||
export default dux;
|
||||
|
||||
|
@ -21,7 +21,7 @@ export default dux;
|
||||
dux.setMutation('setScreens', payload => u(payload));
|
||||
dux.setMutation('setScreensReqs', reqs => u({reqs}));
|
||||
|
||||
export const screenReqsReaction = store => createSelector(
|
||||
export const screensReqsReaction = store => createSelector(
|
||||
(ship) => ship.reqs.mass,
|
||||
(ship) => ship.structure.screens.standard,
|
||||
(ship) => ship.structure.screens.advanced,
|
||||
|
32
src/lib/shipDux/structure/streamlining.js
Normal file
32
src/lib/shipDux/structure/streamlining.js
Normal file
@ -0,0 +1,32 @@
|
||||
import { Updux } from "updux";
|
||||
import u from "updeep";
|
||||
|
||||
import reqs from "../reqs.js";
|
||||
|
||||
const dux = new Updux({
|
||||
subduxes: {
|
||||
reqs,
|
||||
},
|
||||
initial: {
|
||||
type: "none",
|
||||
},
|
||||
actions: {
|
||||
setStreamlining: null,
|
||||
},
|
||||
});
|
||||
export default dux;
|
||||
|
||||
dux.setMutation("setStreamlining", ({ shipMass, type }) =>
|
||||
u({
|
||||
type,
|
||||
reqs: calcStreamliningReqs({ shipMass, type }),
|
||||
})
|
||||
);
|
||||
|
||||
function calcStreamliningReqs({ shipMass, type }) {
|
||||
const mass = Math.ceil(
|
||||
(shipMass * (type === "none" ? 0 : type === "partial" ? 5 : 10)) / 100
|
||||
);
|
||||
|
||||
return { mass, cost: 2 * mass };
|
||||
}
|
46
src/lib/shipDux/weaponry/index.js
Normal file
46
src/lib/shipDux/weaponry/index.js
Normal file
@ -0,0 +1,46 @@
|
||||
import { Updux } from "updux";
|
||||
import u from "updeep";
|
||||
|
||||
import weapons from './weapons.js';
|
||||
|
||||
const reqs = { cost: 0, mass: 0 };
|
||||
|
||||
const dux = new Updux({
|
||||
subduxes: { weapons },
|
||||
initial: {
|
||||
firecons: {
|
||||
stations: 0,
|
||||
reqs,
|
||||
},
|
||||
adfc: { rating: 0, reqs },
|
||||
},
|
||||
actions: {
|
||||
setADFC: null,
|
||||
setFirecons: null,
|
||||
},
|
||||
});
|
||||
|
||||
dux.setMutation("setFirecons", (stations) =>
|
||||
u({
|
||||
firecons: {
|
||||
stations,
|
||||
reqs: {
|
||||
cost: 4 * stations,
|
||||
mass: stations,
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
dux.setMutation("setADFC", (rating) =>
|
||||
u({
|
||||
adfc: {
|
||||
rating,
|
||||
reqs: {
|
||||
cost: 8 * rating,
|
||||
mass: 2 * rating,
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
export default dux;
|
122
src/lib/shipDux/weaponry/weapons.js
Normal file
122
src/lib/shipDux/weaponry/weapons.js
Normal file
@ -0,0 +1,122 @@
|
||||
import { Updux } from "updux";
|
||||
import u from "updeep";
|
||||
|
||||
const reqs = { cost: 0, mass: 0 };
|
||||
|
||||
export const weaponTypes = [
|
||||
{ name: 'beam', type: 'beam', reqs: beam_cost_mass, initial: {
|
||||
weaponClass: 1
|
||||
}},
|
||||
{ name: 'submunition pack', type: 'submunition', reqs: { mass:1, cost:3 },
|
||||
initial: { arc: 'F' }
|
||||
},
|
||||
{ name: 'point defence system', type: 'pds', reqs: {mass:1,cost:3}, initial: {}},
|
||||
{ name: 'scattergun', type: 'scattergun', reqs: { mass:1,cost:4 }, initial: {}},
|
||||
{ name: 'needle weapon', type: 'needle', reqs: { mass: 2, cost: 6 },
|
||||
initial: { arc: 'F' }},
|
||||
];
|
||||
|
||||
const dux = new Updux({
|
||||
initial: [],
|
||||
actions: {
|
||||
addWeapon: null,
|
||||
removeWeapon: null,
|
||||
setWeapon: null,
|
||||
},
|
||||
});
|
||||
|
||||
dux.setMutation('setWeapon', ({id,...rest}) => state => {
|
||||
console.log(id,rest,state);
|
||||
state = u.map( u.if( (w) => w.id === id,
|
||||
weapon => {
|
||||
return {
|
||||
id,
|
||||
...rest,
|
||||
reqs: weaponReqs(rest),
|
||||
}
|
||||
} ), state );
|
||||
console.log(state);
|
||||
return state;
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
dux.setMutation('removeWeapon', id => state => [
|
||||
...state.filter( (w) => w.id !== id )
|
||||
]);
|
||||
|
||||
dux.setMutation('addWeapon', type => state => {
|
||||
const initial = weaponTypes.find(w => w.type === type ).initial;
|
||||
return [
|
||||
...state,
|
||||
{
|
||||
id: state.length === 0 ? 1 : state[state.length -1]+1,
|
||||
type,
|
||||
reqs: weaponReqs({type,...initial}),
|
||||
...initial,
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
function weaponReqs(weapon) {
|
||||
|
||||
const {reqs} = weaponTypes.find( wt => wt.type === weapon.type ) ||{};
|
||||
|
||||
if(!reqs) return {};
|
||||
|
||||
if( typeof reqs === 'function' ) return reqs(weapon);
|
||||
|
||||
return reqs;
|
||||
}
|
||||
|
||||
const isBroadside = arcs => {
|
||||
if( arcs.length !== 4 ) return false;
|
||||
|
||||
// that'd be A or F
|
||||
return !arcs.some( a => a.length === 1 );
|
||||
}
|
||||
|
||||
function beam_cost_mass({weaponClass, arcs}) {
|
||||
console.log({weaponClass,arcs})
|
||||
let mass;
|
||||
|
||||
if( weaponClass === 1 ) {
|
||||
mass = 1;
|
||||
}
|
||||
|
||||
if( weaponClass === 2 ) {
|
||||
mass = 2 + (arcs.length > 3 ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
if( weaponClass == 3 ) {
|
||||
mass = 4;
|
||||
|
||||
if( isBroadside(arcs) ) {
|
||||
mass += 2;
|
||||
}
|
||||
else {
|
||||
mass += arcs.length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( weaponClass == 4 ) {
|
||||
mass = 8;
|
||||
|
||||
if( isBroadside(arcs) ) {
|
||||
mass += 4;
|
||||
}
|
||||
else {
|
||||
mass += 2*(arcs.length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
mass, cost: 3 * mass
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default dux;
|
@ -1,5 +1,5 @@
|
||||
import { browser } from "$app/env";
|
||||
import { readable, get } from "svelte/store";
|
||||
import { readable, get, derived } from "svelte/store";
|
||||
import { compose, applyMiddleware } from "redux";
|
||||
|
||||
import shipDux from "../shipDux/index.js";
|
||||
@ -20,7 +20,6 @@ export default () => {
|
||||
duxStore.subscribe(() => {
|
||||
if (previous === duxStore.getState()) return;
|
||||
previous = duxStore.getState();
|
||||
console.log("Setting!", previous);
|
||||
set(previous);
|
||||
});
|
||||
});
|
||||
@ -28,5 +27,6 @@ export default () => {
|
||||
return {
|
||||
dispatch: duxStore.dispatch,
|
||||
state,
|
||||
shipMass: derived( state, state => state.reqs.mass )
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user