sml
This commit is contained in:
parent
bf99b8dd4e
commit
1b9a5ab253
@ -8,6 +8,8 @@ releases:
|
||||
changes:
|
||||
- desc: add SMRs
|
||||
type: feat
|
||||
- desc: add SMLs
|
||||
type: feat
|
||||
- version: 3.1.0
|
||||
changes:
|
||||
- desc: add version and changelog to the about section
|
||||
|
40
src/lib/components/ShipEdit/MissileMagazines.svelte
Normal file
40
src/lib/components/ShipEdit/MissileMagazines.svelte
Normal file
@ -0,0 +1,40 @@
|
||||
{#if magazines.length > 0}
|
||||
<ShipItem {...reqs}>
|
||||
<div>missile magazines</div>
|
||||
<div class="magazines">
|
||||
{#each magazines as magazine (magazine.id)}
|
||||
<Magazine {...magazine} unused={magazine.launchers.length === 0} />
|
||||
{/each}
|
||||
</div>
|
||||
</ShipItem>
|
||||
{/if}
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import ShipItem from "$lib/components/ShipItem.svelte";
|
||||
import Magazine from "./MissileMagazines/Magazine.svelte";
|
||||
|
||||
export let magazines = [];
|
||||
|
||||
let reqs = { cost: 0, mass: 0 };
|
||||
|
||||
const api = getContext("api");
|
||||
|
||||
$: {
|
||||
reqs = { cost: 0, mass: 0 };
|
||||
magazines.forEach(({ reqs: r }) => {
|
||||
reqs.cost += r.cost;
|
||||
reqs.mass += r.mass;
|
||||
});
|
||||
}
|
||||
|
||||
const handleMagazine = () => {};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.magazines {
|
||||
display: flex;
|
||||
margin-left: 2em;
|
||||
}
|
||||
</style>
|
42
src/lib/components/ShipEdit/MissileMagazines/Magazine.svelte
Normal file
42
src/lib/components/ShipEdit/MissileMagazines/Magazine.svelte
Normal file
@ -0,0 +1,42 @@
|
||||
<div class="magazine">
|
||||
<div class="field label">
|
||||
<input
|
||||
type="number"
|
||||
min={unused ? 0 : 1}
|
||||
disabled={unused}
|
||||
bind:value={maxAmmo}
|
||||
/>
|
||||
<label class="active">magazine {id}</label>
|
||||
</div>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" bind:checked={extended} disabled={unused} />
|
||||
<span>extended range</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
|
||||
export let id = 1;
|
||||
export let maxAmmo = 0;
|
||||
export let extended = false;
|
||||
export let unused = false;
|
||||
|
||||
export let api = getContext("api");
|
||||
|
||||
$: api?.dispatch?.setMissileMagazine?.(id, maxAmmo, extended);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.magazine {
|
||||
max-width: 20em;
|
||||
margin-right: 2em;
|
||||
}
|
||||
.magazine input {
|
||||
max-width: 8em;
|
||||
text-align: center;
|
||||
}
|
||||
.field {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
</style>
|
@ -3,15 +3,18 @@
|
||||
|
||||
<ADFC {...adfc} />
|
||||
|
||||
<MissileMagazines magazines={missileMagazines} />
|
||||
|
||||
<AddWeapon />
|
||||
|
||||
{#each weapons as weapon (weapon.id)}
|
||||
<Weapon {...weapon} />
|
||||
<Weapon {...weapon} nbrMissileMagazines={missileMagazines.length} />
|
||||
{/each}
|
||||
</Section>
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
import u from "@yanick/updeep-remeda";
|
||||
|
||||
import Section from "$lib/components/Section.svelte";
|
||||
|
||||
@ -21,11 +24,28 @@
|
||||
import Firecons from "./Weaponry/Firecons.svelte";
|
||||
import ADFC from "./Weaponry/ADFC.svelte";
|
||||
import AddWeapon from "./Weaponry/AddWeapon.svelte";
|
||||
import MissileMagazines from "./MissileMagazines.svelte";
|
||||
import Weapon from "./Weaponry/Weapon/index.svelte";
|
||||
|
||||
export let firecons = {};
|
||||
export let adfc = {};
|
||||
|
||||
import Weapon from "./Weaponry/Weapon/index.svelte";
|
||||
|
||||
export let missileMagazines = [];
|
||||
export let weapons = [];
|
||||
|
||||
$: missileMagazines = addLaunchersToMagazines(missileMagazines, weapons);
|
||||
|
||||
function addLaunchersToMagazines(magazines, weapons) {
|
||||
return u.map(magazines, (mag) =>
|
||||
u(mag, {
|
||||
launchers: weapons.filter(
|
||||
u.matches({
|
||||
specs: {
|
||||
type: "sml",
|
||||
missileMagazineId: mag.id,
|
||||
},
|
||||
})
|
||||
),
|
||||
})
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
@ -0,0 +1,18 @@
|
||||
import SML from "./index.svelte";
|
||||
|
||||
export default {
|
||||
title: "Salvo Missile Launcher",
|
||||
component: SML,
|
||||
};
|
||||
|
||||
export const Primary = {
|
||||
render: (args) => ({
|
||||
Component: SML,
|
||||
props: args,
|
||||
}),
|
||||
args: {
|
||||
availableMissileMagazineIds: [1, 2, 3],
|
||||
missileMagazineId: 1,
|
||||
arcs: ["F", "FS", "FP"],
|
||||
},
|
||||
};
|
@ -0,0 +1,8 @@
|
||||
<Hst.Story title="ShipEdit/Weaponry/Weapons/SML">
|
||||
<SML />
|
||||
</Hst.Story>
|
||||
|
||||
<script>
|
||||
export let Hst;
|
||||
import SML from "./index.svelte";
|
||||
</script>
|
74
src/lib/components/ShipEdit/Weaponry/Weapon/SML/index.svelte
Normal file
74
src/lib/components/ShipEdit/Weaponry/Weapon/SML/index.svelte
Normal file
@ -0,0 +1,74 @@
|
||||
<span>salvo missile launcher</span>
|
||||
|
||||
<div class="arcs">
|
||||
<Arcs
|
||||
size={48}
|
||||
selected={arcs}
|
||||
on:clickArc={({ detail }) => setFirstArc(detail)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field label suffix">
|
||||
<select bind:value={missileMagazineId}>
|
||||
{#each availableMissileMagazineIds as id}
|
||||
<option value={id}>{id}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<label class:active={true}>magazine</label>
|
||||
</div>
|
||||
|
||||
<script lang="ts">
|
||||
import u from "@yanick/updeep-remeda";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import memoize from "memoize-one";
|
||||
|
||||
import Arcs from "../Arcs.svelte";
|
||||
import {
|
||||
weaponTypes,
|
||||
arcs as allArcs,
|
||||
} from "$lib/store/ship/weaponry/rules.ts";
|
||||
|
||||
export let arcs = ["F", "FS", "FP"];
|
||||
export let missileMagazineId;
|
||||
|
||||
export let nbrMissileMagazines = 1;
|
||||
$: availableMissileMagazineIds = Array.from({ length: nbrMissileMagazines })
|
||||
.fill(1)
|
||||
.map((_, i) => i + 1);
|
||||
|
||||
const nbrArcs = 3;
|
||||
|
||||
let firstArc = allArcs[0];
|
||||
const setFirstArc = (a) => (firstArc = a);
|
||||
|
||||
$: arcs = setArcs(firstArc, nbrArcs);
|
||||
|
||||
function setArcs(firstArc, nbrArcs) {
|
||||
let first_index = allArcs.findIndex((arc) => arc === firstArc);
|
||||
if (first_index === -1) first_index = 0;
|
||||
|
||||
return Array.from({ length: nbrArcs }).map(
|
||||
(_dummy, i) => allArcs[(first_index + i) % allArcs.length]
|
||||
);
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const memoChange = memoize((missileMagazineId, ...arcs) =>
|
||||
dispatch("change", {
|
||||
missileMagazineId,
|
||||
arcs,
|
||||
})
|
||||
);
|
||||
|
||||
$: memoChange(missileMagazineId, ...arcs);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.arcs {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
label span {
|
||||
padding-left: 1em;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,79 @@
|
||||
<span>salvo missile launcher</span>
|
||||
|
||||
<div class="arcs">
|
||||
<Arcs
|
||||
size={48}
|
||||
selected={arcs}
|
||||
on:clickArc={({ detail }) => setFirstArc(detail)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field label suffix">
|
||||
<select bind:value={missileMagazineId}>
|
||||
{#each availableMissileMagazineIds as id}
|
||||
<option value={id}>{id}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<label class:active={true}>magazine</label>
|
||||
</div>
|
||||
|
||||
<script lang="ts">
|
||||
import u from "@yanick/updeep-remeda";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import memoize from "memoize-one";
|
||||
|
||||
import Arcs from "../Arcs.svelte";
|
||||
import {
|
||||
weaponTypes,
|
||||
arcs as allArcs,
|
||||
} from "$lib/store/ship/weaponry/rules.ts";
|
||||
|
||||
export let arcs = ["F", "FS", "FP"];
|
||||
<<<<<<< HEAD
|
||||
export let missileMagazineId;
|
||||
=======
|
||||
export let availableMissileMagazineIds = [1];
|
||||
export let missileMagazineId = 1;
|
||||
>>>>>>> a5a09f9 (storybook is back)
|
||||
|
||||
export let nbrMissileMagazines = 1;
|
||||
$: availableMissileMagazineIds = Array.from({ length: nbrMissileMagazines })
|
||||
.fill(1)
|
||||
.map((_, i) => i + 1);
|
||||
|
||||
const nbrArcs = 3;
|
||||
|
||||
let firstArc = allArcs[0];
|
||||
const setFirstArc = (a) => (firstArc = a);
|
||||
|
||||
$: arcs = setArcs(firstArc, nbrArcs);
|
||||
|
||||
function setArcs(firstArc, nbrArcs) {
|
||||
let first_index = allArcs.findIndex((arc) => arc === firstArc);
|
||||
if (first_index === -1) first_index = 0;
|
||||
|
||||
return Array.from({ length: nbrArcs }).map(
|
||||
(_dummy, i) => allArcs[(first_index + i) % allArcs.length]
|
||||
);
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const memoChange = memoize((missileMagazineId, ...arcs) =>
|
||||
dispatch("change", {
|
||||
missileMagazineId,
|
||||
arcs,
|
||||
})
|
||||
);
|
||||
|
||||
$: memoChange(missileMagazineId, ...arcs);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.arcs {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
label span {
|
||||
padding-left: 1em;
|
||||
}
|
||||
</style>
|
@ -2,7 +2,12 @@
|
||||
<div class="weapon_row">
|
||||
<a on:click={remove}><i>Delete</i> </a>
|
||||
|
||||
<svelte:component this={component[type]} {...specs} on:change={update} />
|
||||
<svelte:component
|
||||
this={component[type]}
|
||||
{...specs}
|
||||
{nbrMissileMagazines}
|
||||
on:change={update}
|
||||
/>
|
||||
</div>
|
||||
</ShipItem>
|
||||
|
||||
@ -21,6 +26,7 @@
|
||||
import Torpedo from "./Torpedo/index.svelte";
|
||||
import Missile from "./HeavyMissile/index.svelte";
|
||||
import SalvoMissileRack from "./SalvoMissileRack.svelte";
|
||||
import SalvoMissileLauncher from "./SML/index.svelte";
|
||||
|
||||
const component = {
|
||||
beam: Beam,
|
||||
@ -32,11 +38,13 @@
|
||||
torpedo: Torpedo,
|
||||
heavyMissile: Missile,
|
||||
smr: SalvoMissileRack,
|
||||
sml: SalvoMissileLauncher,
|
||||
};
|
||||
|
||||
export let reqs = {};
|
||||
export let specs = {};
|
||||
export let id;
|
||||
export let nbrMissileMagazines = 0;
|
||||
|
||||
const api = getContext("api");
|
||||
|
||||
|
@ -17,6 +17,7 @@ import { armorDux } from "./ship/structure/armor";
|
||||
import { fireconsDux } from "./ship/weaponry/firecons";
|
||||
import { adfcDux } from "./ship/weaponry/adfc";
|
||||
import { weaponsDux } from "./ship/weaponry/weapons";
|
||||
import { weaponryDux } from "./ship/weaponry";
|
||||
|
||||
if (typeof process !== "undefined") {
|
||||
process.env.UPDEEP_MODE = "dangerously_never_freeze";
|
||||
@ -42,15 +43,6 @@ const propulsion = new Updux({
|
||||
},
|
||||
});
|
||||
|
||||
const weaponry = new Updux({
|
||||
initialState: {},
|
||||
subduxes: {
|
||||
adfc: adfcDux,
|
||||
firecons: fireconsDux,
|
||||
weapons: weaponsDux,
|
||||
},
|
||||
});
|
||||
|
||||
const restore = createPayloadAction<typeof shipDux.initialState>("restore");
|
||||
const importShip =
|
||||
createPayloadAction<typeof shipDux.initialState>("importShip");
|
||||
@ -68,7 +60,7 @@ const shipDux = new Updux({
|
||||
structure,
|
||||
propulsion,
|
||||
carrier: carrierDux,
|
||||
weaponry,
|
||||
weaponry: weaponryDux,
|
||||
},
|
||||
});
|
||||
|
||||
|
52
src/lib/store/ship/weaponry/index.test.ts
Normal file
52
src/lib/store/ship/weaponry/index.test.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { weaponryDux } from "./index.ts";
|
||||
|
||||
test("sml and magazine", () => {
|
||||
const store = weaponryDux.createStore();
|
||||
|
||||
expect(store.getState().missileMagazines).toHaveLength(0);
|
||||
|
||||
store.dispatch.addWeapon("sml");
|
||||
store.dispatch.addWeapon("sml");
|
||||
expect(store.getState().missileMagazines).toHaveLength(2);
|
||||
|
||||
expect(store.getState().missileMagazines[0]).toMatchObject({
|
||||
extended: false,
|
||||
maxAmmo: 1,
|
||||
});
|
||||
|
||||
store.dispatch.setMissileMagazine(1, 3, true);
|
||||
|
||||
expect(store.getState().missileMagazines[0]).toMatchObject({
|
||||
extended: true,
|
||||
maxAmmo: 3,
|
||||
});
|
||||
|
||||
store.dispatch.addWeapon("sml");
|
||||
expect(store.getState().missileMagazines).toHaveLength(3);
|
||||
|
||||
expect(store.getState().missileMagazines[2]).toHaveProperty("id", 3);
|
||||
// they all get assigned '1' at birth
|
||||
expect(store.getState().weapons[2].specs).toHaveProperty(
|
||||
"missileMagazineId",
|
||||
1
|
||||
);
|
||||
|
||||
store.dispatch.setWeapon(3, {
|
||||
missileMagazineId: 3,
|
||||
arcs: ["F", "FS", "FP"],
|
||||
});
|
||||
|
||||
expect(store.getState().weapons[2].specs).toHaveProperty(
|
||||
"missileMagazineId",
|
||||
3
|
||||
);
|
||||
|
||||
store.dispatch.removeWeapon(store.getState().weapons[1].id);
|
||||
|
||||
expect(store.getState().missileMagazines).toHaveLength(2);
|
||||
|
||||
console.log(store.getState());
|
||||
|
||||
expect(store.getState().weapons[1].specs.missileMagazineId).toEqual(2);
|
||||
expect(store.getState().missileMagazines[1].id).toEqual(2);
|
||||
});
|
116
src/lib/store/ship/weaponry/index.ts
Normal file
116
src/lib/store/ship/weaponry/index.ts
Normal file
@ -0,0 +1,116 @@
|
||||
import Updux, { createPayloadAction } from "updux";
|
||||
import { adfcDux } from "./adfc";
|
||||
import { fireconsDux } from "./firecons";
|
||||
import { weaponsDux } from "./weapons";
|
||||
import type { Reqs } from "$lib/shipDux/reqs";
|
||||
import u from "@yanick/updeep-remeda";
|
||||
import * as R from "remeda";
|
||||
|
||||
if (typeof process !== "undefined") {
|
||||
process.env.UPDEEP_MODE = "dangerously_never_freeze";
|
||||
}
|
||||
|
||||
type MissileMagazine = {
|
||||
id: number;
|
||||
maxAmmo: number;
|
||||
extended: boolean;
|
||||
};
|
||||
|
||||
const setMissileMagazine = createPayloadAction(
|
||||
"setMissileMagazine",
|
||||
(id, maxAmmo, extended = undefined) => ({ id, maxAmmo, extended })
|
||||
);
|
||||
|
||||
const moveMissileMagazine = createPayloadAction(
|
||||
"moveMissileMagazine",
|
||||
(from, to) => ({
|
||||
from,
|
||||
to,
|
||||
})
|
||||
);
|
||||
|
||||
const removeMissileMagazine = createPayloadAction<number>(
|
||||
"removeMissileMagazine"
|
||||
);
|
||||
|
||||
const magazinesDux = new Updux({
|
||||
actions: { setMissileMagazine, removeMissileMagazine, moveMissileMagazine },
|
||||
initialState: [] as MissileMagazine[],
|
||||
});
|
||||
|
||||
magazinesDux.addMutation(weaponsDux.actions.addWeapon, (payload) => (state) => {
|
||||
if (payload !== "sml") return state;
|
||||
|
||||
state.push({
|
||||
id: state.length + 1,
|
||||
extended: false,
|
||||
maxAmmo: 1,
|
||||
reqs: magazineReqs({ extended: false, maxAmmo: 1 }),
|
||||
});
|
||||
});
|
||||
|
||||
magazinesDux.addMutation(setMissileMagazine, (payload) =>
|
||||
u.map(
|
||||
u.if(u.matches({ id: payload.id }), (state) => {
|
||||
state = u(state, payload);
|
||||
return u(state, { reqs: magazineReqs(state) });
|
||||
})
|
||||
)
|
||||
);
|
||||
magazinesDux.addMutation(moveMissileMagazine, ({ from, to }) =>
|
||||
u.map(u.if(u.matches({ id: from }), { id: to }))
|
||||
);
|
||||
|
||||
magazinesDux.addMutation(removeMissileMagazine, (id) =>
|
||||
u.reject(u.matches({ id }))
|
||||
);
|
||||
|
||||
magazinesDux.addReaction((api) => (store) => {
|
||||
store
|
||||
.map(R.prop("id"))
|
||||
.filter(({ id }, i) => id !== i + 1)
|
||||
.forEach((id, i) => api.dispatch.moveMissileMagazine(id, i + 1));
|
||||
});
|
||||
|
||||
function magazineReqs(magazine: MissileMagazine): Reqs {
|
||||
let mass = magazine.maxAmmo * (magazine.extended ? 3 : 2);
|
||||
return { mass, cost: 3 * mass };
|
||||
}
|
||||
|
||||
export const weaponryDux = new Updux({
|
||||
initialState: {},
|
||||
subduxes: {
|
||||
adfc: adfcDux,
|
||||
firecons: fireconsDux,
|
||||
weapons: weaponsDux,
|
||||
missileMagazines: magazinesDux,
|
||||
},
|
||||
});
|
||||
|
||||
weaponryDux.addMutation(moveMissileMagazine, ({ from, to }) =>
|
||||
u({
|
||||
weapons: u.map(
|
||||
u.if(u.matches({ specs: { missileMagazineId: from } }), {
|
||||
specs: { missileMagazineId: to },
|
||||
})
|
||||
),
|
||||
})
|
||||
);
|
||||
|
||||
weaponryDux.addReaction((api) => (state) => {
|
||||
const smls = state.weapons.filter(u.matches({ specs: { type: "sml" } }));
|
||||
|
||||
const usedMagazines = smls.map(
|
||||
({ specs: { missileMagazineId } }) => missileMagazineId
|
||||
);
|
||||
|
||||
const unusedMags = state.missileMagazines
|
||||
.map(R.prop("id"))
|
||||
.filter((id) => !usedMagazines.includes(id));
|
||||
|
||||
unusedMags.forEach((id) => api.dispatch.setMissileMagazine(id, 0));
|
||||
|
||||
if (smls.length >= state.missileMagazines.length) return;
|
||||
|
||||
api.dispatch.removeMissileMagazine(unusedMags[0]);
|
||||
});
|
@ -40,6 +40,18 @@ type SalvoMissileRack = {
|
||||
extended: boolean;
|
||||
};
|
||||
|
||||
type MissileMagazine = {
|
||||
id: number;
|
||||
maxAmmo: number;
|
||||
extended: boolean;
|
||||
};
|
||||
|
||||
type SalvoMissileLauncher = {
|
||||
type: "salvoMissileLauncher";
|
||||
arcs: Arc[];
|
||||
missileMagazineId: number;
|
||||
};
|
||||
|
||||
type Graser = {
|
||||
type: "graser";
|
||||
weaponClass: 1 | 2 | 3;
|
||||
@ -60,7 +72,8 @@ export type Weapon =
|
||||
| Needle
|
||||
| Graser
|
||||
| Torpedo
|
||||
| HeavyMissile;
|
||||
| HeavyMissile
|
||||
| SalvoMissileLauncher;
|
||||
|
||||
export const weaponTypes = [
|
||||
{
|
||||
@ -155,6 +168,16 @@ export const weaponTypes = [
|
||||
type: "smr",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "salvo missile launcher",
|
||||
type: "sml",
|
||||
reqs: { cost: 9, mass: 3 },
|
||||
initial: {
|
||||
arcs: ["FP", "F", "FS"],
|
||||
type: "sml",
|
||||
missileMagazineId: 1,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export function weaponReqs(weapon): Reqs {
|
||||
|
@ -0,0 +1,16 @@
|
||||
import SML from "./index.svelte";
|
||||
|
||||
export default {
|
||||
title: "PrintShip/Weapons/SML",
|
||||
component: SML,
|
||||
tags: ["autodocs"],
|
||||
};
|
||||
|
||||
export const Primary = {
|
||||
args: {
|
||||
magazine: {
|
||||
maxAmmo: 3,
|
||||
},
|
||||
launchers: [{ arcs: ["F"] }, { arcs: ["FS"] }],
|
||||
},
|
||||
};
|
@ -0,0 +1,59 @@
|
||||
<div class="sml">
|
||||
<div class="launchers">
|
||||
{#each launchers as launcher, i (i)}
|
||||
<div>
|
||||
<SMR {...launcher} />
|
||||
<div class="line"> </div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="magazine">
|
||||
{#each Array.from({ length: magazine.maxAmmo }).fill(1) as a, i (i)}
|
||||
<img src="/icons/missile.svg" width="18" />
|
||||
{/each}
|
||||
</div>
|
||||
<div>
|
||||
{#if magazine.extended}
|
||||
<div>extended range</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
import SMR from "../SMR/index.svelte";
|
||||
|
||||
export let launchers = [];
|
||||
|
||||
/** the missile magazine feeding the launchers */
|
||||
export let magazine = {};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.sml {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.launchers {
|
||||
display: flex;
|
||||
}
|
||||
.launchers > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.line {
|
||||
width: 0.2em;
|
||||
background-color: black;
|
||||
top: -0.5em;
|
||||
}
|
||||
.magazine {
|
||||
border: 0.2em black solid;
|
||||
border-radius: 0.5em;
|
||||
padding: 0.3em;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
</style>
|
@ -7,6 +7,7 @@ import Graser from "./Graser/index.svelte";
|
||||
import Torpedo from "./Torpedo/index.svelte";
|
||||
import HeavyMissile from "./HeavyMissile/index.svelte";
|
||||
import SalvoMissileRack from "./SMR/index.svelte";
|
||||
import SalvoMissileLauncher from "./SML/index.svelte";
|
||||
|
||||
export default {
|
||||
torpedo: Torpedo,
|
||||
@ -18,4 +19,5 @@ export default {
|
||||
needle: Needlebeam,
|
||||
heavyMissile: HeavyMissile,
|
||||
smr: SalvoMissileRack,
|
||||
sml: SalvoMissileLauncher,
|
||||
};
|
||||
|
@ -15,6 +15,15 @@
|
||||
<HeavyMissiles {heavyMissiles} />
|
||||
</div>
|
||||
|
||||
<div class="weapon-group">
|
||||
{#each Object.keys(smls) as magId (magId)}
|
||||
<SML
|
||||
launchers={smls[magId].map(R.prop("specs"))}
|
||||
magazine={magazines.find(({ id }) => id == magId)}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<Beams {beams} />
|
||||
|
||||
<Weapons {weapons} />
|
||||
@ -61,6 +70,8 @@
|
||||
import Beams from "./Weapons/Beams.svelte";
|
||||
import HeavyMissiles from "./Weapons/HeavyMissiles.svelte";
|
||||
import SalvoMissileRack from "./Weapons/SMR/index.svelte";
|
||||
import SML from "./Weapons/SML/index.svelte";
|
||||
import * as R from "remeda";
|
||||
|
||||
export let identification = {};
|
||||
export let propulsion = {};
|
||||
@ -76,11 +87,14 @@
|
||||
weapons,
|
||||
u.matches({
|
||||
specs: {
|
||||
type: (t) => ["smr", "pds", "beam", "heavyMissile"].includes(t),
|
||||
type: (t) => ["sml", "smr", "pds", "beam", "heavyMissile"].includes(t),
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
$: magazines = weaponry.missileMagazines;
|
||||
$: console.log({ magazines });
|
||||
|
||||
$: pds = (weaponry?.weapons ?? []).filter(
|
||||
u.matches({ specs: { type: "pds" } })
|
||||
);
|
||||
@ -93,6 +107,14 @@
|
||||
$: smrs = (weaponry?.weapons ?? []).filter(
|
||||
u.matches({ specs: { type: "smr" } })
|
||||
);
|
||||
$: console.log(
|
||||
(weaponry?.weapons ?? []).filter(u.matches({ specs: { type: "sml" } }))
|
||||
);
|
||||
$: smls = R.groupBy(
|
||||
(weaponry?.weapons ?? []).filter(u.matches({ specs: { type: "sml" } })),
|
||||
({ specs: { missileMagazineId } }) => missileMagazineId
|
||||
);
|
||||
$: console.log({ smls });
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -7,7 +7,7 @@ import git from "git-describe";
|
||||
/** @type {import('vite').UserConfig} */
|
||||
const config = {
|
||||
plugins: [sveltekit()],
|
||||
// publicDir: "./static",
|
||||
publicDir: "./static",
|
||||
ssr: {},
|
||||
optimizeDeps: {},
|
||||
define: {
|
||||
|
Loading…
Reference in New Issue
Block a user