This commit is contained in:
Yanick Champoux 2023-03-23 10:44:54 -04:00
parent 1a19409645
commit 19293501cb
7 changed files with 246 additions and 79 deletions

View File

@ -9,5 +9,5 @@ export default defineConfig({
// Options here // Options here
}), }),
], ],
// setupFile: "./src/histoire.setup.js", setupFile: "./src/histoire.setup.js",
}); });

View File

@ -26,31 +26,31 @@
"globby": "^13.1.3", "globby": "^13.1.3",
"jest-image-snapshot": "^4.5.1", "jest-image-snapshot": "^4.5.1",
"pixelmatch": "^5.3.0", "pixelmatch": "^5.3.0",
"prettier": "~2.5.1", "prettier": "~2.8.6",
"prettier-plugin-svelte": "^2.6.0", "prettier-plugin-svelte": "^2.10.0",
"showdown": "^2.0.3", "showdown": "^2.0.3",
"svelte": "^3.55.1", "svelte": "^3.57.0",
"typescript": "^4.9.5", "typescript": "^5.0.2",
"vitest": "^0.29.7", "vitest": "^0.29.7"
"vitest-svelte-kit": "^0.0.6"
}, },
"dependencies": { "dependencies": {
"@picocss/pico": "^1.5.7", "@picocss/pico": "^1.5.7",
"@reduxjs/toolkit": "^1.9.3", "@reduxjs/toolkit": "^1.9.3",
"@sveltejs/adapter-node": "^1.0.0-next.0", "@sveltejs/adapter-node": "^1.0.0-next.0",
"@yanick/updeep-remeda": "^2.1.0", "@yanick/updeep-remeda": "^2.1.1",
"chota": "^0.8.0", "chota": "^0.8.0",
"effector": "^22.5.2", "effector": "^22.5.2",
"histoire": "^0.15.9", "histoire": "^0.15.9",
"jsdom": "^21.1.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"redux": "^4.1.2", "redux": "^4.1.2",
"remeda": "^1.1.0", "remeda": "^1.9.1",
"reselect": "^4.1.5", "reselect": "^4.1.5",
"svelte-chota": "^1.8.6", "svelte-chota": "^1.8.6",
"svelte-knobby": "^0.3.4", "svelte-knobby": "^0.3.4",
"svelte-moveable": "^0.20.0", "svelte-moveable": "^0.20.0",
"ts-action": "^11.0.0", "ts-action": "^11.0.0",
"vite": "^4.1.4" "vite": "^4.2.1"
}, },
"prettier": { "prettier": {
"svelteSortOrder": "options-markup-scripts-styles", "svelteSortOrder": "options-markup-scripts-styles",

View File

@ -11,4 +11,13 @@ test("misc", () => {
store.dispatch.setDrive({ rating: 3, advanced: true }); store.dispatch.setDrive({ rating: 3, advanced: true });
expect(store.getState().propulsion.drive.reqs).toEqual({ mass: 2, cost: 6 }); expect(store.getState().propulsion.drive.reqs).toEqual({ mass: 2, cost: 6 });
store.dispatch.setNbrCarrierBays(1);
expect(store.getState().carrier.nbrBays).toEqual(1);
store.dispatch.setNbrCarrierBays(2);
expect(store.getState().carrier.nbrBays).toEqual(2);
store.dispatch.setSquadronType(2, "fast");
expect(store.getState().carrier.squadrons[1]).toHaveProperty("type", "fast");
}); });

View File

@ -6,6 +6,7 @@ import identification from "./ship/identification";
import ftl, { calcFtlReqs } from "./ship/propulsion/ftl"; import ftl, { calcFtlReqs } from "./ship/propulsion/ftl";
import drive from "./ship/propulsion/drive"; import drive from "./ship/propulsion/drive";
import { calcDriveReqs } from "$lib/shipDux/engine"; import { calcDriveReqs } from "$lib/shipDux/engine";
import { carrierDux } from "./ship/carrier";
const shipDux = new Updux({ const shipDux = new Updux({
subduxes: { subduxes: {
@ -17,6 +18,7 @@ const shipDux = new Updux({
drive, drive,
}, },
}), }),
carrier: carrierDux,
}, },
}); });

View File

@ -0,0 +1,118 @@
import Updux, { createPayloadAction } from "updux";
import u from "@yanick/updeep-remeda";
import { reqs, type Reqs } from "$lib/shipDux/reqs";
type Squadron = {
type: string;
reqs: Reqs;
};
const initial = {
nbrBays: 0,
squadrons: [] as Squadron[],
reqs,
};
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 },
];
const setNbrCarrierBays = createPayloadAction<number>("setNbrCarrierBays");
const setSquadronType = createPayloadAction(
"setSquadronType",
(id: number, type: string) => ({ id, type })
);
export const carrierDux = new Updux({
initial,
actions: { setNbrCarrierBays, setSquadronType },
});
function calcBaysReqs(bays) {
return {
mass: 9 * bays,
cost: 18 * bays,
};
}
const adjustSquadrons = (bays: number) => (squadrons) => {
if (squadrons.length === bays) return squadrons;
if (squadrons.length > bays) {
return squadrons.slice(0, bays);
}
return [
...squadrons,
...Array.from({ length: bays - squadrons.length })
.fill({
type: squadronTypes[0].type,
reqs: {
cost: 6 * squadronTypes[0].cost,
mass: 6,
},
})
.map((s, i) => ({ ...s, id: squadrons.length + i + 1 })),
];
};
carrierDux.addMutation(setNbrCarrierBays, (nbrBays) =>
u({
nbrBays,
reqs: calcBaysReqs(nbrBays),
squadrons: adjustSquadrons(nbrBays),
})
);
carrierDux.addMutation(setSquadronType, ({ id, type }) => {
return u({
squadrons: u.map(
u.if(u.matches({ id }), (state) => {
return u(state, {
type,
reqs: squadronReqs(type),
});
})
),
});
});
function squadronReqs(type: string) {
return {
mass: 6,
cost: 6 * squadronTypes.find((s) => s.type === type)?.cost,
};
}
/*
export const { actions, reducer } = createSlice({
name: "carrier",
initialState,
reducers: {
setCarrierBays: (state, action: PayloadAction<number>) => {
state.bays = action.payload;
state.reqs = calcBaysReqs(action.payload);
state.squadrons = adjustSquadrons(action.payload)(state.squadrons);
},
setSquadronType: (
state,
action: PayloadAction<{ type: string; id: number }>
) => {
state.squadrons[action.payload.id - 1] = {
type: action.payload.type,
reqs: squadronReqs(action.payload.type),
};
},
},
});
*/

View File

@ -1,4 +1,26 @@
:root { @font-face {
font-family: "Faktos";
font-style: normal;
src: url(/fonts/Faktos.ttf) format("truetype");
}
@font-face {
font-family: "Dosis";
src: url(/fonts/dosis/Dosis-VariableFont_wght.ttf) format("truetype");
}
:root {
--main-font-family: "Dosis", -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
--font-family: "Dosis", -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
--font-scale-9: 0.75rem;
--font-scale-10: 1em;
--font-scale-11: 1.333rem;
--font-scale-12: 1.777rem;
--font-scale-13: 2.369rem;
--font-scale-14: 3.157rem;
--font-scale-15: 4.209rem;
--oxford-blue: hsla(226, 60%, 10%, 1); --oxford-blue: hsla(226, 60%, 10%, 1);
--royal-blue-dark: hsla(218, 100%, 16%, 1); --royal-blue-dark: hsla(218, 100%, 16%, 1);
@ -7,83 +29,95 @@
--white: hsla(20, 60%, 99%, 1); --white: hsla(20, 60%, 99%, 1);
--main-width: 60em; --main-width: 60em;
} }
small {font-size: var(--font-scale-9); } input.short {
width: 5em !important;
}
h1 { small {
font-size: var(--font-scale-9);
}
h1 {
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
font-size: var(--font-scale-14); font-size: var(--font-scale-14);
} }
h2 { h2 {
font-size: var(--font-scale-12); font-size: var(--font-scale-12);
} }
body {
html, body { position: relative;
position: relative; width: 100%;
width: 100%; height: 100%;
height: 100%;
}
body {
background-color: var(--white); background-color: var(--white);
color: #333; color: #333;
margin: 0; margin: 0;
padding: 8px; padding: 8px;
box-sizing: border-box; box-sizing: border-box;
font-family: "Dosis", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-family: "Dosis", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
} Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a { a {
color: rgb(0,100,200); color: rgb(0, 100, 200);
text-decoration: none; text-decoration: none;
} }
a:hover { a:hover {
text-decoration: underline; text-decoration: underline;
} }
a:visited { a:visited {
color: rgb(0,80,160); color: rgb(0, 80, 160);
} }
label { label {
display: block; display: block;
} }
input, button, select, textarea { input,
font-family: inherit; button,
font-size: inherit; select,
padding: 0.4em; textarea {
margin: 0 0 0.5em 0; font-family: inherit;
box-sizing: border-box; font-size: inherit;
border: 1px solid #ccc; padding: 0.4em;
border-radius: 2px; margin: 0 0 0.5em 0;
} box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled { input:disabled {
color: #ccc; color: #ccc;
} }
input[type="range"] { input[type="range"] {
height: 0; height: 0;
} }
/* ---- inputs --- */ /* input, */
/* select { */
/* border: 0px; */
/* border-bottom: 1px solid var(--indigo-dye); */
/* } */
input, select { input:focus,
select:focus {
border: 1px solid var(--indigo-dye);
}
input:not([type="checkbox"]):not([type="radio"]) {
border: 0px; border: 0px;
border-bottom: 1px solid var(--indigo-dye); border-bottom: 1px solid var(--indigo-dye);
} border-radius: 0px;
height: calc(
input:focus, select:focus { 1rem * var(--line-height) + var(--form-element-spacing-vertical) * 1
border: 1px solid var(--indigo-dye);; );
} padding: 0 0.5rem;
text-align: center;
input.short { }
width:5em;
}

View File

@ -1,9 +1,13 @@
import { extractFromSvelteConfig } from "vitest-svelte-kit"; import { mergeConfig } from "vite";
import { defineConfig } from "vitest/config";
import viteConfig from "./vite.config.js";
export default extractFromSvelteConfig().then((config) => ({ export default mergeConfig(
...config, viteConfig,
test: { defineConfig({
globals: true, test: {
environment: "jsdom", globals: true,
}, environment: "jsdom",
})); },
})
);