aotds-docks/src/lib/store/ship.ts

142 lines
3.7 KiB
TypeScript
Raw Normal View History

2023-03-22 17:04:47 +00:00
import { createSelector } from "@reduxjs/toolkit";
2023-04-22 14:37:49 +00:00
import Updux, { createPayloadAction } from "updux";
2023-03-22 17:04:47 +00:00
import * as R from "remeda";
2023-03-26 17:02:22 +00:00
import memoize from "memoize-one";
2023-03-21 19:42:45 +00:00
import identification from "./ship/identification";
2023-03-22 17:04:47 +00:00
import ftl, { calcFtlReqs } from "./ship/propulsion/ftl";
2023-03-22 20:18:10 +00:00
import drive from "./ship/propulsion/drive";
import { calcDriveReqs } from "$lib/shipDux/engine";
2023-03-23 14:44:54 +00:00
import { carrierDux } from "./ship/carrier";
2023-03-24 15:01:04 +00:00
import { streamliningDux as streamlining } from "./ship/structure/streamlining";
import { calcStreamliningReqs } from "./ship/structure/rules";
2023-03-26 15:51:54 +00:00
import { cargoDux } from "./ship/structure/cargo";
2023-03-26 17:02:22 +00:00
import { hullDux } from "./ship/structure/hull";
2023-03-26 18:40:20 +00:00
import { screensDux, screensReqsReaction } from "./ship/structure/screens";
2023-03-27 16:59:32 +00:00
import { armorDux } from "./ship/structure/armor";
import { fireconsDux } from "./ship/weaponry/firecons";
import { adfcDux } from "./ship/weaponry/adfc";
import { weaponsDux } from "./ship/weaponry/weapons";
2023-04-15 20:53:53 +00:00
if (typeof process !== "undefined") {
2023-05-09 16:06:39 +00:00
process.env.UPDEEP_MODE = "dangerously_never_freeze";
2023-04-15 20:53:53 +00:00
}
2023-03-27 16:59:32 +00:00
const structure = new Updux({
2023-05-09 16:06:39 +00:00
initialState: {},
subduxes: {
streamlining,
cargo: cargoDux,
hull: hullDux,
screens: screensDux,
armor: armorDux,
carrier: carrierDux,
},
2023-03-27 16:59:32 +00:00
});
const propulsion = new Updux({
2023-05-09 16:06:39 +00:00
initialState: {},
subduxes: {
ftl,
drive,
},
2023-03-27 16:59:32 +00:00
});
const weaponry = new Updux({
2023-05-09 16:06:39 +00:00
initialState: {},
subduxes: {
adfc: adfcDux,
firecons: fireconsDux,
weapons: weaponsDux,
},
2023-03-27 16:59:32 +00:00
});
2023-03-21 19:42:45 +00:00
2023-04-22 14:37:49 +00:00
const restore = createPayloadAction<typeof shipDux.initialState>("restore");
2023-05-09 16:06:39 +00:00
const importShip =
createPayloadAction<typeof shipDux.initialState>("importShip");
2023-04-22 14:37:49 +00:00
2023-03-21 19:42:45 +00:00
const shipDux = new Updux({
2023-05-09 16:06:39 +00:00
actions: {
restore,
importShip,
},
initialState: {
schemaVersion: "1",
},
subduxes: {
identification,
structure,
propulsion,
carrier: carrierDux,
weaponry,
},
2023-03-21 19:42:45 +00:00
});
2023-04-22 14:37:49 +00:00
shipDux.addMutation(restore, (state) => () => state);
2023-05-09 16:06:39 +00:00
shipDux.addMutation(importShip, (state) => () => state);
2023-04-22 14:37:49 +00:00
2023-03-26 17:02:22 +00:00
shipDux.addReaction((api) => {
2023-05-09 16:06:39 +00:00
return createSelector(
api.selectors.getFtlType,
api.selectors.getShipMass,
(type, mass) => api.dispatch.setFtlReqs(calcFtlReqs(type, mass))
);
2023-03-26 17:02:22 +00:00
});
2023-03-22 17:04:47 +00:00
2023-04-08 17:47:00 +00:00
shipDux.addReaction((api) => {
2023-05-09 16:06:39 +00:00
const setShipReqs = memoize((cost, usedMass) =>
api.dispatch.setShipReqs({ cost, usedMass })
);
2023-04-08 17:47:00 +00:00
2023-05-09 16:06:39 +00:00
return (state) => {
let cost = 0;
let mass = 0;
2023-03-22 17:04:47 +00:00
2023-05-09 16:06:39 +00:00
let subsystems = R.values(R.omit(state, ["identification"]));
2023-03-22 17:04:47 +00:00
2023-05-09 16:06:39 +00:00
while (subsystems.length > 0) {
const subsystem = subsystems.shift();
if (typeof subsystem !== "object") continue;
2023-03-22 17:04:47 +00:00
2023-05-09 16:06:39 +00:00
if (subsystem.reqs) {
cost += subsystem.reqs.cost ?? 0;
mass += subsystem.reqs.mass ?? 0;
}
2023-04-08 17:47:00 +00:00
2023-05-09 16:06:39 +00:00
subsystems.push(...Object.values(subsystem));
}
2023-03-22 17:04:47 +00:00
2023-05-09 16:06:39 +00:00
if (Number.isNaN(cost)) {
console.log(state.weaponry.weapons);
throw new Error();
}
2023-03-24 15:01:04 +00:00
2023-05-09 16:06:39 +00:00
setShipReqs(cost, mass);
};
2023-03-22 17:04:47 +00:00
});
2023-03-22 20:18:10 +00:00
shipDux.addReaction((api) =>
2023-05-09 16:06:39 +00:00
createSelector(
api.selectors.getShipMass,
(state) => state.propulsion.drive.rating,
(state) => state.propulsion.drive.advanced,
(mass, rating, advanced) =>
api.dispatch.setDriveReqs(calcDriveReqs(mass, rating, advanced))
)
2023-03-24 15:01:04 +00:00
);
shipDux.addReaction((api) =>
2023-05-09 16:06:39 +00:00
createSelector(
// (state) => state,
api.selectors.getShipMass,
api.selectors.getStreamlining,
(mass, type) => {
api.dispatch.setStreamliningReqs(calcStreamliningReqs(type, mass));
}
)
2023-03-22 20:18:10 +00:00
);
2023-03-26 18:40:20 +00:00
shipDux.addReaction(screensReqsReaction);
2023-03-21 19:42:45 +00:00
export default shipDux;