Merge branch 'graser'

This commit is contained in:
Yanick Champoux 2023-05-02 16:34:58 -04:00
commit cf264e4748
22 changed files with 368 additions and 91 deletions

View File

@ -293,6 +293,62 @@
], ],
"virtual": false, "virtual": false,
"markdownFile": null "markdownFile": null
},
{
"id": "src-lib-components-shipedit-weaponry-weapon-graser-index-story-svelte",
"title": "Graser",
"group": null,
"layout": {
"type": "single",
"iframe": true
},
"icon": null,
"iconColor": null,
"docsOnly": false,
"variants": [
{
"id": "_default",
"title": "default"
}
],
"relativePath": "src/lib/components/ShipEdit/Weaponry/Weapon/Graser/index.story.svelte",
"supportPluginId": "svelte3",
"treePath": [
"ShipEdit",
"Weaponry",
"Weapon",
"Graser"
],
"virtual": false,
"markdownFile": null
},
{
"id": "src-routes-export-print-printship-weapons-graser-index-story-svelte",
"title": "Graser",
"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/Graser/index.story.svelte",
"supportPluginId": "svelte3",
"treePath": [
"Export",
"PrintShip",
"Weapons",
"Graser"
],
"virtual": false,
"markdownFile": null
} }
], ],
"markdownFiles": [] "markdownFiles": []

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -60,7 +60,6 @@
const broadside = ["FS", "FP", "AP", "AS"]; const broadside = ["FS", "FP", "AP", "AS"];
function setArcs(firstArc) { function setArcs(firstArc) {
console.log(firstArc);
let newArcs; let newArcs;
if (nbrArcs === "broadside") { if (nbrArcs === "broadside") {
newArcs = broadside; newArcs = broadside;

View File

@ -0,0 +1,13 @@
<Hst.Story title="ShipEdit/Weaponry/Weapon/Graser">
<Graser {api} />
</Hst.Story>
<script>
export let Hst;
import { logEvent } from "histoire/client";
import Graser from "./index.svelte";
const api = {
dispatch: {},
};
</script>

View File

@ -0,0 +1,100 @@
<span>graser</span>
<Field label="graser class" suffix>
<select bind:value={weaponClass}>
{#each weaponClasses as value}
<option {value}>{value}</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: "graser" })).options;
const weaponClasses = options.map(R.prop("weaponClass"));
export let weaponClass = weaponClasses[0];
export let arcs = ["F"];
let nbrArcs = isBroadside(arcs) ? "broadside" : arcs.length;
$: classOptions = options.find(u.matches({ weaponClass }));
$: nbrArcsOptions = classOptions.nbrArcs;
$: broadside = classOptions.broadside;
$: 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>

View File

@ -17,6 +17,7 @@
import PointDefenceSystem from "./PDS.svelte"; import PointDefenceSystem from "./PDS.svelte";
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";
const component = { const component = {
beam: Beam, beam: Beam,
@ -24,6 +25,7 @@
pds: PointDefenceSystem, pds: PointDefenceSystem,
scattergun: Scattergun, scattergun: Scattergun,
needle: Needle, needle: Needle,
graser: Graser,
}; };
export let reqs = {}; export let reqs = {};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -2,125 +2,186 @@ import type { Reqs } from "$lib/shipDux/reqs";
export const arcs = ["FS", "F", "FP", "AP", "A", "AS"] as const; export const arcs = ["FS", "F", "FP", "AP", "A", "AS"] as const;
export const broadsideArcs = ["FP", "AP", "AS", "FS"];
export type Arc = (typeof arcs)[number]; export type Arc = (typeof arcs)[number];
export type WeaponType = "beam"; export type WeaponType = "beam";
type Beam = { type Beam = {
type: "beam"; type: "beam";
weaponClass: 1 | 2 | 3 | 4; weaponClass: 1 | 2 | 3 | 4;
arcs: Arc[]; arcs: Arc[];
}; };
type Submunition = { type Submunition = {
type: "submunition"; type: "submunition";
arc: Arc; arc: Arc;
}; };
type PDS = { type PDS = {
type: "pds"; type: "pds";
}; };
type Scattergun = { type: "scattergun" }; type Scattergun = { type: "scattergun" };
type Needle = { type: "needle"; arc: Arc }; type Needle = { type: "needle"; arc: Arc };
export type Weapon = Beam | Submunition | PDS | Scattergun | Needle; type Graser = {
type: "graser";
weaponClass: 1 | 2 | 3;
arcs: Arc[];
};
export type Weapon = Beam | Submunition | PDS | Scattergun | Needle | Graser;
export const weaponTypes = [ export const weaponTypes = [
{ {
type: "beam", type: "beam",
name: "beam", name: "beam",
reqs: beamReqs, reqs: beamReqs,
initial: { initial: {
type: "beam", type: "beam",
weaponClass: 1, weaponClass: 1,
arcs, arcs,
} as any as Beam, } as any as Beam,
}, },
{ {
type: "submunition", type: "graser",
name: "submunition pack", name: "graser",
reqs: { mass: 1, cost: 3 }, reqs: graserReqs,
initial: { type: "submunition", arc: "F" } as Submunition, initial: {
}, type: "graser",
{ weaponClass: 1,
name: "point defence system", arcs: ["F"],
type: "pds", } as any as Graser,
reqs: { mass: 1, cost: 3 }, options: [
initial: { { weaponClass: 1, nbrArcs: [1, 3, 6, "broadside"] },
type: "pds", {
weaponClass: 2,
nbrArcs: [1, 2, 3, 4, 5, 6, "broadside"],
},
{
weaponClass: 3,
nbrArcs: [1, 2, 3, 4, 5, 6, "broadside"],
},
],
},
{
type: "submunition",
name: "submunition pack",
reqs: { mass: 1, cost: 3 },
initial: { type: "submunition", arc: "F" } as Submunition,
},
{
name: "point defence system",
type: "pds",
reqs: { mass: 1, cost: 3 },
initial: {
type: "pds",
},
},
{
name: "scattergun",
type: "scattergun",
reqs: { mass: 1, cost: 4 },
initial: { type: "scattergun" },
},
{
name: "needle beam",
type: "needle",
reqs: { mass: 2, cost: 6 },
initial: { arc: "F", type: "needle" },
}, },
},
{
name: "scattergun",
type: "scattergun",
reqs: { mass: 1, cost: 4 },
initial: { type: "scattergun" },
},
{
name: "needle beam",
type: "needle",
reqs: { mass: 2, cost: 6 },
initial: { arc: "F", type: "needle" },
},
]; ];
export function weaponReqs(weapon): Reqs { export function weaponReqs(weapon): Reqs {
const { reqs } = weaponTypes.find((wt) => wt.type === weapon.type) || {}; const { reqs } = weaponTypes.find((wt) => wt.type === weapon.type) || {};
if (!reqs) if (!reqs)
return { return {
cost: 0, cost: 0,
mass: 0, mass: 0,
}; };
if (typeof reqs === "function") return reqs(weapon); if (typeof reqs === "function") return reqs(weapon);
return reqs; return reqs;
} }
const isBroadside = (arcs: Arc[]) => { export const isBroadside = (arcs: Arc[]) => {
if (arcs.length !== 4) return false; if (arcs.length !== 4) return false;
// that'd be A or F // that'd be A or F
return !arcs.some((a) => a.length === 1); return !arcs.some((a) => a.length === 1);
}; };
function beamReqs({ weaponClass, arcs }: Beam) { function beamReqs({ weaponClass, arcs }: Beam) {
console.log(weaponClass, arcs); let mass;
let mass;
if (weaponClass === 1) { if (weaponClass === 1) {
mass = 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) { if (weaponClass === 2) {
mass = 8; mass = 2 + (arcs.length > 3 ? 1 : 0);
if (isBroadside(arcs)) {
mass += 4;
} else {
mass += 2 * (arcs.length - 1);
} }
}
return { if (weaponClass == 3) {
mass, mass = 4;
cost: 3 * mass,
}; 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,
};
}
function graserReqs({ weaponClass, arcs }: Beam) {
let mass: number;
if (weaponClass === 1) {
if (arcs.length === 1) {
mass = 2;
} else if (arcs.length === 3) {
mass = 3;
} else {
mass = 4;
}
} else if (weaponClass === 2) {
mass = 9;
if (isBroadside(arcs)) {
mass += 6;
} else {
mass += 3 * (arcs.length - 1);
}
} else if (weaponClass === 3) {
mass = 24;
if (isBroadside(arcs)) {
mass += 12;
} else {
mass += 6 * (arcs.length - 1);
}
}
return {
mass,
cost: 4 * mass,
};
} }

View File

@ -1,5 +1,5 @@
<div> <div>
<Arcs selected={arcs} size="40"> <Arcs selected={arcs} size={40}>
<text x="50%" y="50%"> <text x="50%" y="50%">
{weaponClass} {weaponClass}
</text> </text>

View File

@ -0,0 +1,9 @@
<Hst.Story title="Export/PrintShip/Weapons/Graser">
<Graser arcs={["F", "FS"]} weaponClass={2} />
</Hst.Story>
<script>
import Graser from "./index.svelte";
export let Hst;
</script>

View File

@ -0,0 +1,35 @@
<div>
<Arcs selected={arcs} size={40}>
<polygon
points="0,30 30,30 15,4"
style="fill:black"
transform="translate(7,2) scale(0.85)"
/>
<text x="50%" y="50%" style="color: white">
{weaponClass}
</text>
</Arcs>
</div>
<script>
import Arcs from "$lib/components/ShipEdit/Weaponry/Weapon/Arcs.svelte";
export let weaponClass = 1;
export let arcs = [];
</script>
<style>
div {
margin: 0px 0.5rem;
}
div :global(path:hover) {
fill: white;
}
div :global(path.active:hover) {
fill: black;
}
text {
text-anchor: middle;
dominant-baseline: central;
font-size: var(--font-scale-10);
}
</style>

View File

@ -3,11 +3,13 @@ import Submunition from "./Submunition.svelte";
import PDS from "./PDS.svelte"; 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";
export default { export default {
beam: Beam, graser: Graser,
submunition: Submunition, beam: Beam,
pds: PDS, submunition: Submunition,
scattergun: Scattergun, pds: PDS,
needle: Needlebeam, scattergun: Scattergun,
needle: Needlebeam,
}; };