add salvo missile racks
This commit is contained in:
parent
11d65b375d
commit
e515ce2e74
@ -4,6 +4,10 @@ project:
|
|||||||
with_stats: true
|
with_stats: true
|
||||||
ticket_url: null
|
ticket_url: null
|
||||||
releases:
|
releases:
|
||||||
|
- version: NEXT
|
||||||
|
changes:
|
||||||
|
- desc: add SMRs
|
||||||
|
type: feat
|
||||||
- version: 3.1.0
|
- version: 3.1.0
|
||||||
changes:
|
changes:
|
||||||
- desc: add version and changelog to the about section
|
- desc: add version and changelog to the about section
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
<span>salvo missile rack</span>
|
||||||
|
|
||||||
|
<div class="arcs">
|
||||||
|
<Arcs
|
||||||
|
size={48}
|
||||||
|
selected={arcs}
|
||||||
|
on:clickArc={({ detail }) => setFirstArc(detail)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label class="switch">
|
||||||
|
<input type="checkbox" bind:checked={extended} />
|
||||||
|
<span>extended range</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<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 extended = false;
|
||||||
|
|
||||||
|
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((extended, ...arcs) =>
|
||||||
|
dispatch("change", {
|
||||||
|
extended,
|
||||||
|
arcs,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
$: memoChange(extended, ...arcs);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.arcs {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
label span {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -20,6 +20,7 @@
|
|||||||
import Graser from "./Graser/index.svelte";
|
import Graser from "./Graser/index.svelte";
|
||||||
import Torpedo from "./Torpedo/index.svelte";
|
import Torpedo from "./Torpedo/index.svelte";
|
||||||
import Missile from "./HeavyMissile/index.svelte";
|
import Missile from "./HeavyMissile/index.svelte";
|
||||||
|
import SalvoMissileRack from "./SalvoMissileRack.svelte";
|
||||||
|
|
||||||
const component = {
|
const component = {
|
||||||
beam: Beam,
|
beam: Beam,
|
||||||
@ -30,6 +31,7 @@
|
|||||||
graser: Graser,
|
graser: Graser,
|
||||||
torpedo: Torpedo,
|
torpedo: Torpedo,
|
||||||
heavyMissile: Missile,
|
heavyMissile: Missile,
|
||||||
|
smr: SalvoMissileRack,
|
||||||
};
|
};
|
||||||
|
|
||||||
export let reqs = {};
|
export let reqs = {};
|
||||||
|
@ -34,6 +34,12 @@ type HeavyMissile = {
|
|||||||
multiStage: boolean;
|
multiStage: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type SalvoMissileRack = {
|
||||||
|
type: "salvoMissileRack";
|
||||||
|
arcs: Arc[];
|
||||||
|
extended: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
type Graser = {
|
type Graser = {
|
||||||
type: "graser";
|
type: "graser";
|
||||||
weaponClass: 1 | 2 | 3;
|
weaponClass: 1 | 2 | 3;
|
||||||
@ -139,6 +145,16 @@ export const weaponTypes = [
|
|||||||
type: "heavyMissile",
|
type: "heavyMissile",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "salvo missile rack",
|
||||||
|
type: "smr",
|
||||||
|
reqs: smrReqs,
|
||||||
|
initial: {
|
||||||
|
arcs: ["FP", "F", "FS"],
|
||||||
|
extended: false,
|
||||||
|
type: "smr",
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export function weaponReqs(weapon): Reqs {
|
export function weaponReqs(weapon): Reqs {
|
||||||
@ -247,6 +263,15 @@ function missileReqs({ extended, multiStage }: HeavyMissile): Reqs {
|
|||||||
return { cost, mass };
|
return { cost, mass };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function smrReqs({ extended }: SalvoMissileRack): Reqs {
|
||||||
|
let mass = 4;
|
||||||
|
if (extended) mass += 1;
|
||||||
|
return {
|
||||||
|
mass,
|
||||||
|
cost: 3 * mass,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function torpedoReqs({ weaponClass, arcs }: Torpedo): Reqs {
|
function torpedoReqs({ weaponClass, arcs }: Torpedo): Reqs {
|
||||||
let mass: number = 4;
|
let mass: number = 4;
|
||||||
|
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
<div class="smr">
|
||||||
|
<Arcs selected={arcs} size={40}>
|
||||||
|
<image href="/icons/missile.svg" width="18" x="12" y="7" />
|
||||||
|
</Arcs>
|
||||||
|
<div>
|
||||||
|
{#if extended}
|
||||||
|
<div>extended range</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Arcs from "$lib/components/ShipEdit/Weaponry/Weapon/Arcs.svelte";
|
||||||
|
export let arcs = [];
|
||||||
|
export let extended = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
margin: 0px 0.5rem;
|
||||||
|
}
|
||||||
|
div :global(path.arc) {
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
div :global(path.active) {
|
||||||
|
fill: black;
|
||||||
|
}
|
||||||
|
div :global(path.active:hover) {
|
||||||
|
fill: black;
|
||||||
|
}
|
||||||
|
text {
|
||||||
|
text-anchor: middle;
|
||||||
|
dominant-baseline: central;
|
||||||
|
font-size: var(--font-scale-10);
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,12 @@
|
|||||||
|
import { render } from "@testing-library/svelte";
|
||||||
|
import SMR from "./index.svelte";
|
||||||
|
|
||||||
|
test("basic", () => {
|
||||||
|
const { queryByText } = render(SMR, {
|
||||||
|
props: {
|
||||||
|
extended: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(queryByText("extended range")).toBeTruthy();
|
||||||
|
});
|
@ -6,6 +6,7 @@ import Needlebeam from "./Needlebeam.svelte";
|
|||||||
import Graser from "./Graser/index.svelte";
|
import Graser from "./Graser/index.svelte";
|
||||||
import Torpedo from "./Torpedo/index.svelte";
|
import Torpedo from "./Torpedo/index.svelte";
|
||||||
import HeavyMissile from "./HeavyMissile/index.svelte";
|
import HeavyMissile from "./HeavyMissile/index.svelte";
|
||||||
|
import SalvoMissileRack from "./SMR/index.svelte";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
torpedo: Torpedo,
|
torpedo: Torpedo,
|
||||||
@ -16,4 +17,5 @@ export default {
|
|||||||
scattergun: Scattergun,
|
scattergun: Scattergun,
|
||||||
needle: Needlebeam,
|
needle: Needlebeam,
|
||||||
heavyMissile: HeavyMissile,
|
heavyMissile: HeavyMissile,
|
||||||
|
smr: SalvoMissileRack,
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,15 @@
|
|||||||
<div class="print-output">
|
<div class="print-output">
|
||||||
<Identification {...identification} />
|
<Identification {...identification} />
|
||||||
|
|
||||||
<HeavyMissiles {heavyMissiles} />
|
<div class="weapon-group">
|
||||||
|
{#each smrs as smr (smr.id)}
|
||||||
|
<SalvoMissileRack {...smr.specs} />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="weapon-group">
|
||||||
|
<HeavyMissiles {heavyMissiles} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<Beams {beams} />
|
<Beams {beams} />
|
||||||
|
|
||||||
@ -52,6 +60,7 @@
|
|||||||
import PDS from "./Weapons/PDS.svelte";
|
import PDS from "./Weapons/PDS.svelte";
|
||||||
import Beams from "./Weapons/Beams.svelte";
|
import Beams from "./Weapons/Beams.svelte";
|
||||||
import HeavyMissiles from "./Weapons/HeavyMissiles.svelte";
|
import HeavyMissiles from "./Weapons/HeavyMissiles.svelte";
|
||||||
|
import SalvoMissileRack from "./Weapons/SMR/index.svelte";
|
||||||
|
|
||||||
export let identification = {};
|
export let identification = {};
|
||||||
export let propulsion = {};
|
export let propulsion = {};
|
||||||
@ -66,7 +75,9 @@
|
|||||||
$: weapons = u.reject(
|
$: weapons = u.reject(
|
||||||
weapons,
|
weapons,
|
||||||
u.matches({
|
u.matches({
|
||||||
specs: { type: (t) => ["pds", "beam", "heavyMissiles"].includes(t) },
|
specs: {
|
||||||
|
type: (t) => ["smr", "pds", "beam", "heavyMissile"].includes(t),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -77,7 +88,10 @@
|
|||||||
u.matches({ specs: { type: "beam" } })
|
u.matches({ specs: { type: "beam" } })
|
||||||
);
|
);
|
||||||
$: heavyMissiles = (weaponry?.weapons ?? []).filter(
|
$: heavyMissiles = (weaponry?.weapons ?? []).filter(
|
||||||
u.matches({ specs: { type: "heavyMissiles" } })
|
u.matches({ specs: { type: "heavyMissile" } })
|
||||||
|
);
|
||||||
|
$: smrs = (weaponry?.weapons ?? []).filter(
|
||||||
|
u.matches({ specs: { type: "smr" } })
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -113,4 +127,9 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
.weapon-group {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
68
static/icons/missile.svg
Normal file
68
static/icons/missile.svg
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="90"
|
||||||
|
height="110"
|
||||||
|
viewBox="0 0 23.8125 29.104166"
|
||||||
|
version="1.1"
|
||||||
|
id="svg876"
|
||||||
|
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
|
||||||
|
sodipodi:docname="missile.svg">
|
||||||
|
<defs
|
||||||
|
id="defs870" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.35"
|
||||||
|
inkscape:cx="1138.8867"
|
||||||
|
inkscape:cy="-549.64407"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="957"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="34"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata873">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(327.78876,55.935586)">
|
||||||
|
<polygon
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:6.59100008;stroke-miterlimit:10"
|
||||||
|
id="polygon30"
|
||||||
|
points="543,438.6 580.2,462.1 543,378.1 505.8,462.1 "
|
||||||
|
stroke-miterlimit="10"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,-459.65684,-151.36374)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
Loading…
Reference in New Issue
Block a user