Merge branch 'torpedos'
28
.histoire/dist/histoire.json
vendored
@ -349,6 +349,34 @@
|
|||||||
],
|
],
|
||||||
"virtual": false,
|
"virtual": false,
|
||||||
"markdownFile": null
|
"markdownFile": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "src-routes-export-print-printship-weapons-torpedo-index-story-svelte",
|
||||||
|
"title": "Torpedo",
|
||||||
|
"group": null,
|
||||||
|
"layout": {
|
||||||
|
"type": "single",
|
||||||
|
"iframe": true
|
||||||
|
},
|
||||||
|
"icon": null,
|
||||||
|
"iconColor": null,
|
||||||
|
"docsOnly": false,
|
||||||
|
"variants": [
|
||||||
|
{
|
||||||
|
"id": "_default",
|
||||||
|
"title": "default"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"relativePath": "src/routes/export/print/PrintShip/Weapons/Torpedo/index.story.svelte",
|
||||||
|
"supportPluginId": "svelte3",
|
||||||
|
"treePath": [
|
||||||
|
"Export",
|
||||||
|
"PrintShip",
|
||||||
|
"Weapons",
|
||||||
|
"Torpedo"
|
||||||
|
],
|
||||||
|
"virtual": false,
|
||||||
|
"markdownFile": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"markdownFiles": []
|
"markdownFiles": []
|
||||||
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 23 KiB |
@ -17,7 +17,7 @@ tasks:
|
|||||||
deps:
|
deps:
|
||||||
- histoire:build
|
- histoire:build
|
||||||
cmds:
|
cmds:
|
||||||
- vitest run -u src
|
- vitest run -u src
|
||||||
|
|
||||||
check:
|
check:
|
||||||
deps:
|
deps:
|
||||||
@ -28,6 +28,7 @@ tasks:
|
|||||||
histoire:build:
|
histoire:build:
|
||||||
sources:
|
sources:
|
||||||
- src/lib/components/**
|
- src/lib/components/**
|
||||||
|
- src/routes/**
|
||||||
generates:
|
generates:
|
||||||
- .histoire/screenshots/**
|
- .histoire/screenshots/**
|
||||||
cmds:
|
cmds:
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@ -1,5 +1,5 @@
|
|||||||
<g {transform}>
|
<g {transform}>
|
||||||
<path d={path} class:active on:click />
|
<path d={path} class="arc" class:active on:click />
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
<span>torpedo</span>
|
||||||
|
|
||||||
|
<Field label="torpedo class" suffix>
|
||||||
|
<select bind:value={weaponClass}>
|
||||||
|
{#each Array.from({length: maxClass}) as _dummy,i (i)}
|
||||||
|
<option value={i+1}>{i+1}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
<i>arrow_drop_down</i>
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<Field label="arcs" suffix>
|
||||||
|
<select bind:value={nbrArcs}>
|
||||||
|
{#each nbrArcsOptions as value}
|
||||||
|
<option {value}>{value}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
<i>arrow_drop_down</i>
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<div class="arcs">
|
||||||
|
<Arcs
|
||||||
|
size={48}
|
||||||
|
selected={arcs}
|
||||||
|
on:clickArc={({ detail }) => setFirstArc(detail)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import * as R from "remeda";
|
||||||
|
import u from "@yanick/updeep-remeda";
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
import memoize from "memoize-one";
|
||||||
|
|
||||||
|
import Arcs from "../Arcs.svelte";
|
||||||
|
import ShipItem from "$lib/components/ShipItem.svelte";
|
||||||
|
import Field from "$lib/components/Field.svelte";
|
||||||
|
import {
|
||||||
|
weaponTypes,
|
||||||
|
broadsideArcs,
|
||||||
|
arcs as allArcs,
|
||||||
|
isBroadside,
|
||||||
|
} from "$lib/store/ship/weaponry/rules.ts";
|
||||||
|
|
||||||
|
const options = weaponTypes.find(u.matches({ type: "torpedo" }))?.options ??
|
||||||
|
{};
|
||||||
|
|
||||||
|
const maxClass = options.maxClass;
|
||||||
|
|
||||||
|
export let weaponClass = 1;
|
||||||
|
|
||||||
|
export let arcs = ["F"];
|
||||||
|
|
||||||
|
let nbrArcs = isBroadside(arcs) ? "broadside" : arcs.length;
|
||||||
|
|
||||||
|
$: nbrArcsOptions = options.nbrArcs;
|
||||||
|
|
||||||
|
$: if (!nbrArcsOptions.includes(nbrArcs)) nbrArcs = nbrArcsOptions[0];
|
||||||
|
|
||||||
|
function allowedArcs(arcs, options) {
|
||||||
|
if (options.broadside && isBroadside(arcs)) return true;
|
||||||
|
|
||||||
|
return options.nbrArcs.includes(arcs.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
let firstArc = allArcs[0];
|
||||||
|
const setFirstArc = (a) => (firstArc = a);
|
||||||
|
|
||||||
|
$: arcs = setArcs(firstArc, nbrArcs);
|
||||||
|
|
||||||
|
function setArcs(firstArc, nbrArcs) {
|
||||||
|
if (nbrArcs === "broadside") return broadsideArcs;
|
||||||
|
|
||||||
|
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((weaponClass, ...arcs) =>
|
||||||
|
dispatch("change", {
|
||||||
|
weaponClass,
|
||||||
|
arcs,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
$: memoChange(weaponClass, ...arcs);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.arcs {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
@ -18,6 +18,7 @@
|
|||||||
import Scattergun from "./Scattergun.svelte";
|
import Scattergun from "./Scattergun.svelte";
|
||||||
import Needle from "./Needle.svelte";
|
import Needle from "./Needle.svelte";
|
||||||
import Graser from "./Graser/index.svelte";
|
import Graser from "./Graser/index.svelte";
|
||||||
|
import Torpedo from "./Torpedo/index.svelte";
|
||||||
|
|
||||||
const component = {
|
const component = {
|
||||||
beam: Beam,
|
beam: Beam,
|
||||||
@ -26,6 +27,7 @@
|
|||||||
scattergun: Scattergun,
|
scattergun: Scattergun,
|
||||||
needle: Needle,
|
needle: Needle,
|
||||||
graser: Graser,
|
graser: Graser,
|
||||||
|
torpedo: Torpedo,
|
||||||
};
|
};
|
||||||
|
|
||||||
export let reqs = {};
|
export let reqs = {};
|
||||||
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 23 KiB |
@ -33,7 +33,20 @@ type Graser = {
|
|||||||
arcs: Arc[];
|
arcs: Arc[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Weapon = Beam | Submunition | PDS | Scattergun | Needle | Graser;
|
type Torpedo = {
|
||||||
|
type: "torpedo";
|
||||||
|
weaponClass: 1 | 2 | 3 | 4;
|
||||||
|
arcs: Arc[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Weapon =
|
||||||
|
| Beam
|
||||||
|
| Submunition
|
||||||
|
| PDS
|
||||||
|
| Scattergun
|
||||||
|
| Needle
|
||||||
|
| Graser
|
||||||
|
| Torpedo;
|
||||||
|
|
||||||
export const weaponTypes = [
|
export const weaponTypes = [
|
||||||
{
|
{
|
||||||
@ -67,6 +80,20 @@ export const weaponTypes = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "torpedo",
|
||||||
|
name: "torpedo",
|
||||||
|
reqs: torpedoReqs,
|
||||||
|
initial: {
|
||||||
|
type: "torpedo",
|
||||||
|
weaponClass: 1,
|
||||||
|
arcs: ["F"],
|
||||||
|
} as any as Torpedo,
|
||||||
|
options: {
|
||||||
|
maxClass: 4,
|
||||||
|
nbrArcs: [1, 2, 3, "broadside"],
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: "submunition",
|
type: "submunition",
|
||||||
name: "submunition pack",
|
name: "submunition pack",
|
||||||
@ -153,7 +180,7 @@ function beamReqs({ weaponClass, arcs }: Beam) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function graserReqs({ weaponClass, arcs }: Beam) {
|
function graserReqs({ weaponClass, arcs }: Graser) {
|
||||||
let mass: number;
|
let mass: number;
|
||||||
|
|
||||||
if (weaponClass === 1) {
|
if (weaponClass === 1) {
|
||||||
@ -185,3 +212,20 @@ function graserReqs({ weaponClass, arcs }: Beam) {
|
|||||||
cost: 4 * mass,
|
cost: 4 * mass,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function torpedoReqs({ weaponClass, arcs }: Torpedo): Reqs {
|
||||||
|
let mass: number = 4;
|
||||||
|
|
||||||
|
if (isBroadside(arcs)) {
|
||||||
|
mass += 2;
|
||||||
|
} else {
|
||||||
|
mass += arcs.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mass = mass * Math.pow(2, weaponClass - 1);
|
||||||
|
|
||||||
|
return {
|
||||||
|
mass,
|
||||||
|
cost: 3 * mass,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -10,15 +10,14 @@
|
|||||||
{shipType}
|
{shipType}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="reqs">
|
<div class="reqs">
|
||||||
{cost} <i>paid</i> {mass} <i>weight</i>
|
{reqs.cost} <i>paid</i> {reqs.mass} <i>weight</i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export let shipClass;
|
export let shipClass;
|
||||||
export let shipType;
|
export let shipType;
|
||||||
export let cost = 0;
|
export let reqs = { cost: 0, mass: 0 };
|
||||||
export let mass = 0;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
<Hst.Story title="Export/PrintShip/Weapons/Torpedo">
|
||||||
|
<Torpedo arcs={["F", "FS"]} weaponClass={2} />
|
||||||
|
</Hst.Story>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Torpedo from "./index.svelte";
|
||||||
|
|
||||||
|
export let Hst;
|
||||||
|
</script>
|
@ -0,0 +1,51 @@
|
|||||||
|
<div class="torpedo">
|
||||||
|
<Arcs selected={arcs} size={40}>
|
||||||
|
<g transform="scale(0.12) translate(-315,-100)">
|
||||||
|
<path
|
||||||
|
d="M480,162.8c-57.2,0-103.5,46.3-103.5,103.5S422.8,369.8,480,369.8c57.2,0,103.5-46.3,103.5-103.5S537.2,162.8,480,162.8z
|
||||||
|
M534.3,320.6l-38.2-22.8h-32.3l-38.2,22.8l22.8-38.2v-32.3L425.7,212l38.2,22.8h32.3l38.2-22.8l-22.8,38.2v32.3L534.3,320.6z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</Arcs>
|
||||||
|
{#if weaponClass > 1}
|
||||||
|
<div class="weaponClass">{weaponClass}</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Arcs from "$lib/components/ShipEdit/Weaponry/Weapon/Arcs.svelte";
|
||||||
|
export let weaponClass = 1;
|
||||||
|
export let arcs = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.torpedo {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.weaponClass {
|
||||||
|
text-align: center;
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
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>
|
@ -4,8 +4,10 @@ import PDS from "./PDS.svelte";
|
|||||||
import Scattergun from "./Scattergun.svelte";
|
import Scattergun from "./Scattergun.svelte";
|
||||||
import Needlebeam from "./Needlebeam.svelte";
|
import Needlebeam from "./Needlebeam.svelte";
|
||||||
import Graser from "./Graser/index.svelte";
|
import Graser from "./Graser/index.svelte";
|
||||||
|
import Torpedo from "./Torpedo/index.svelte";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
torpedo: Torpedo,
|
||||||
graser: Graser,
|
graser: Graser,
|
||||||
beam: Beam,
|
beam: Beam,
|
||||||
submunition: Submunition,
|
submunition: Submunition,
|
||||||
|