wip
This commit is contained in:
parent
9e7922066c
commit
7106e484b4
@ -1,30 +0,0 @@
|
||||
import tap from "tap";
|
||||
|
||||
import { calc_ship_req } from "./utils";
|
||||
|
||||
const sample = {
|
||||
general: {
|
||||
mass: 10,
|
||||
used_mass: 0,
|
||||
cost: 10,
|
||||
},
|
||||
ftl: {
|
||||
cost: 4,
|
||||
mass: 2,
|
||||
},
|
||||
structure: {
|
||||
hull: {
|
||||
cost: 2,
|
||||
mass: 1,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
tap.same(
|
||||
calc_ship_req(sample),
|
||||
{
|
||||
cost: 16,
|
||||
mass: 3,
|
||||
},
|
||||
"sample ship"
|
||||
);
|
@ -1,22 +0,0 @@
|
||||
import Updux from "updux";
|
||||
import { action, payload } from "ts-action";
|
||||
import u from "@yanick/updeep";
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
const dux = new Updux({
|
||||
initial: {
|
||||
space: 0,
|
||||
cost: 0,
|
||||
mass: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const set_cargo = action("set_cargo", payload());
|
||||
|
||||
dux.addMutation(set_cargo, (space) => () => ({
|
||||
space,
|
||||
cost: 0,
|
||||
mass: space,
|
||||
}));
|
||||
|
||||
export default dux.asDux;
|
@ -1,58 +0,0 @@
|
||||
import Updux from "updux";
|
||||
import { action, payload } from "ts-action";
|
||||
import u from "@yanick/updeep";
|
||||
import _ from 'lodash';
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
import squadron_types from './squadron_types';
|
||||
|
||||
const uu = transform => state => transform(state)(state);
|
||||
|
||||
const dux = new Updux({
|
||||
initial: {
|
||||
bays: 0,
|
||||
cost: 0,
|
||||
mass: 0,
|
||||
squadrons: [],
|
||||
},
|
||||
});
|
||||
|
||||
const set_squadron = action('set_squadron',payload());
|
||||
|
||||
dux.addMutation(set_squadron, ({id,type}) => u.update({ squadrons: u.map(
|
||||
u.if(_.matches({id}), u({type, cost: 6 * _.find(squadron_types,{type}).cost, mass: 6 }))
|
||||
)}));
|
||||
|
||||
const set_carrier_bays = action('set_carrier_bays', payload() );
|
||||
|
||||
dux.addMutation( set_carrier_bays, bays => state => {
|
||||
state = u.update({
|
||||
bays,
|
||||
mass: 1.5*6*bays,
|
||||
cost: 3 * 1.5 * 6 * bays,
|
||||
})(state);
|
||||
|
||||
if( state.squadrons.length > bays ) {
|
||||
state = u.update({
|
||||
squadrons: squadrons => squadrons.slice(0,bays)
|
||||
}, state)
|
||||
}
|
||||
|
||||
if( state.squadrons.length < bays ) {
|
||||
state = u.update({
|
||||
squadrons: squadrons => [ ...squadrons, ..._.times(
|
||||
bays - state.squadrons.length, i => ({
|
||||
id: 1 + i + state.squadrons.length,
|
||||
cost: 6 * squadron_types[0].cost,
|
||||
mass: 6,
|
||||
type: squadron_types[0].type,
|
||||
})
|
||||
)] }, state)
|
||||
}
|
||||
|
||||
return state;
|
||||
|
||||
});
|
||||
|
||||
|
||||
export default dux.asDux;
|
@ -1,9 +0,0 @@
|
||||
export default [
|
||||
{ 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 },
|
||||
];
|
@ -1,27 +0,0 @@
|
||||
import Updux from 'updux';
|
||||
import { action, payload } from 'ts-action';
|
||||
import u from "@yanick/updeep";
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
const set_engine = action('set_engine',payload());
|
||||
const set_drive_reqs = action('set_drive_reqs',payload());
|
||||
|
||||
const dux = new Updux({
|
||||
initial: {
|
||||
mass: 1,
|
||||
cost: 2,
|
||||
rating: 1,
|
||||
}
|
||||
});
|
||||
|
||||
dux.addMutation(set_engine, engine => u.update(engine));
|
||||
dux.addMutation(set_drive_reqs, rate => u.update(rate));
|
||||
|
||||
export function calc_drive_reqs(ship_mass,rating,advanced=false) {
|
||||
const mass = Math.ceil(rating * 0.05 * ship_mass);
|
||||
const cost = mass * ( advanced ? 3 : 2 );
|
||||
|
||||
return { mass, cost };
|
||||
}
|
||||
|
||||
export default dux.asDux;
|
@ -1,25 +0,0 @@
|
||||
import Updux from "updux";
|
||||
import { action, payload } from 'ts-action';
|
||||
import u from "@yanick/updeep";
|
||||
import { createSelector } from 'reselect';
|
||||
import { calc_ftl_reqs } from './rules';
|
||||
|
||||
// 'none' | 'standard' | 'advanced'
|
||||
const set_ftl = action('set_ftl',payload());
|
||||
|
||||
const set_ftl_reqs = action('set_ftl_reqs', payload() );
|
||||
|
||||
console.log(Updux);
|
||||
const dux = new Updux({
|
||||
initial: {
|
||||
mass: 0,
|
||||
cost: 0,
|
||||
type: 'none'
|
||||
}
|
||||
});
|
||||
|
||||
dux.addMutation(set_ftl, type => u.update({type}));
|
||||
dux.addMutation(set_ftl_reqs, reqs => u.update(reqs) );
|
||||
|
||||
export default dux.asDux;
|
||||
|
@ -1,10 +0,0 @@
|
||||
export function calc_ftl_reqs(type,ship_mass) {
|
||||
if(type==="none") return { cost: 0, mass: 0 };
|
||||
|
||||
const mass = Math.ceil(ship_mass / 10);
|
||||
|
||||
return {
|
||||
mass,
|
||||
cost: mass * ( type === 'advanced' ? 3 : 2 ),
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import tap from 'tap';
|
||||
|
||||
import { calc_ftl_rate } from './rules';
|
||||
|
||||
tap.same( calc_ftl_rate(111,'standard'), { mass: 12, cost: 24 },
|
||||
'mass rounded up' );
|
||||
|
135
src/dux/index.js
135
src/dux/index.js
@ -1,135 +0,0 @@
|
||||
import Updux from "updux";
|
||||
import { action, payload } from "ts-action";
|
||||
import u from "@yanick/updeep";
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
import ftl from "./ftl";
|
||||
import engine, { calc_drive_reqs } from "./engine";
|
||||
import weaponry from "./weaponry";
|
||||
import { calc_ftl_reqs } from "./ftl/rules";
|
||||
import { calc_ship_req } from "./utils";
|
||||
import { candidate_ship_types } from "./ship_types";
|
||||
import structure from "./structure";
|
||||
import cargo from "./cargo";
|
||||
import streamlining from "./streamlining";
|
||||
import carrier from "./carrier";
|
||||
import { ceil } from "./utils";
|
||||
|
||||
const set_ship_mass = action("set_ship_mass", payload());
|
||||
const set_name = action("set_name", payload());
|
||||
|
||||
const set_ship_reqs = action("set_ship_reqs", payload());
|
||||
const set_hull = action("set_hull", payload());
|
||||
|
||||
const set_ship_type = action("set_ship_type", payload());
|
||||
|
||||
const reset = action("reset");
|
||||
|
||||
const initial = {
|
||||
general: {
|
||||
ship_class: "",
|
||||
name: "",
|
||||
ship_type: "",
|
||||
mass: 10,
|
||||
used_mass: 0,
|
||||
cost: 10,
|
||||
},
|
||||
};
|
||||
|
||||
const dux = new Updux({
|
||||
subduxes: { ftl, engine, weaponry, structure, cargo, streamlining, carrier },
|
||||
initial,
|
||||
});
|
||||
|
||||
dux.addMutation(reset, () => () => initial);
|
||||
|
||||
dux.addMutation(set_hull, ({ rating }) => (state) => {
|
||||
return u.updateIn("structure.hull", {
|
||||
cost: 2 * rating,
|
||||
rating,
|
||||
mass: rating,
|
||||
})(state);
|
||||
});
|
||||
dux.addMutation(set_ship_mass, (mass) => u.updateIn("general", { mass }));
|
||||
dux.addMutation(set_name, (name) => u.updateIn("general", { name }));
|
||||
|
||||
dux.addMutation(action("set_ship_class", payload()), (ship_class) =>
|
||||
u.updateIn("general", { ship_class })
|
||||
);
|
||||
|
||||
dux.addMutation(set_ship_reqs, ({ cost, mass: used_mass }) =>
|
||||
u.updateIn("general", { cost, used_mass })
|
||||
);
|
||||
|
||||
// set ship's req
|
||||
dux.addSubscription((store) =>
|
||||
createSelector(calc_ship_req, (reqs) => store.dispatch(set_ship_reqs(reqs)))
|
||||
);
|
||||
|
||||
|
||||
dux.addSubscription((store) =>
|
||||
createSelector(
|
||||
(store) => store.general.mass,
|
||||
(store) => store.general.ship_type,
|
||||
(store) => store.carrier.bays,
|
||||
(mass, type, bays) => {
|
||||
console.log({ bays });
|
||||
const candidates = candidate_ship_types(mass, bays > 0);
|
||||
|
||||
console.log({ candidates });
|
||||
if (candidates.length === 0) return;
|
||||
|
||||
if (candidates.find(({ name }) => name === type)) return;
|
||||
|
||||
store.dispatch(store.actions.set_ship_type(candidates[0].name));
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
dux.addMutation(set_ship_type, (type) => u.updateIn("general.ship_type", type));
|
||||
|
||||
dux.addSubscription((store) =>
|
||||
createSelector(
|
||||
[(ship) => ship.general.mass, (ship) => ship.ftl.type],
|
||||
(ship_mass, type) =>
|
||||
store.dispatch(ftl.actions.set_ftl_reqs(calc_ftl_reqs(type, ship_mass)))
|
||||
)
|
||||
);
|
||||
|
||||
dux.addSubscription((store) =>
|
||||
createSelector(
|
||||
(ship) => ship.general.mass,
|
||||
(ship) => ship.structure.screens.standard,
|
||||
(ship) => ship.structure.screens.advanced,
|
||||
(mass, standard, advanced) => {
|
||||
const standard_mass = standard * Math.max(3, ceil(0.05 * mass));
|
||||
const advanced_mass = advanced * Math.max(4, ceil(0.075 * mass));
|
||||
|
||||
store.dispatch(
|
||||
dux.actions.set_screens_reqs({
|
||||
mass: standard_mass + advanced_mass,
|
||||
cost: 3 * standard_mass + 4 * advanced_mass,
|
||||
})
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
dux.addSubscription((store) =>
|
||||
createSelector(
|
||||
[
|
||||
(ship) => ship.general.mass,
|
||||
(ship) => ship.engine.rating,
|
||||
(ship) => ship.engine.advanced,
|
||||
],
|
||||
(ship_mass, rating, advanced) =>
|
||||
store.dispatch(
|
||||
dux.actions.set_drive_reqs(calc_drive_reqs(ship_mass, rating, advanced))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
export default dux.asDux;
|
||||
|
||||
export const actions = dux.actions;
|
@ -1,22 +0,0 @@
|
||||
import Updux from "updux";
|
||||
import { action, payload } from "ts-action";
|
||||
import u from "@yanick/updeep";
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
const dux = new Updux({
|
||||
initial: {
|
||||
type: 'none',
|
||||
cost: 0,
|
||||
mass: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const set_streamlining = action('set_streamlining',payload());
|
||||
|
||||
dux.addMutation(set_streamlining, type => u.update({type}) );
|
||||
|
||||
const set_streamlining_cost_mass = action('set_streamlining_cost_mass',payload());
|
||||
|
||||
dux.addMutation( set_streamlining_cost_mass, reqs => u.update(reqs) );
|
||||
|
||||
export default dux.asDux;
|
@ -1,36 +0,0 @@
|
||||
import Updux from "updux";
|
||||
import { action, payload } from "ts-action";
|
||||
import u from "@yanick/updeep";
|
||||
import { createSelector } from "reselect";
|
||||
import _ from 'lodash';
|
||||
|
||||
const dux = new Updux({
|
||||
initial: [],
|
||||
});
|
||||
|
||||
const set_armour_nbr_layers = action('set_armour_nbr_layers',payload());
|
||||
|
||||
dux.addMutation( set_armour_nbr_layers, nbr_layers => state => {
|
||||
if( state.length > nbr_layers ) state = state.slice(0,nbr_layers);
|
||||
|
||||
if( state.length < nbr_layers ) {
|
||||
state = [ state, _.times( nbr_layers - state.length, () => [] ) ].flat();
|
||||
}
|
||||
|
||||
state = u.map( (el,i) => ({layer: i +1, rating: 0, cost: 0, mass: 0, ...el }), state);
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
dux.addMutation(
|
||||
action('set_armour_layer', payload()),
|
||||
({layer, rating}) => u.map(
|
||||
u.if(_.matches({layer}), u({
|
||||
rating,
|
||||
cost: 2 * layer * rating,
|
||||
mass: 2 * rating,
|
||||
}))
|
||||
)
|
||||
);
|
||||
|
||||
export default dux.asDux;
|
@ -1,26 +0,0 @@
|
||||
import Updux from "updux";
|
||||
import { action, payload } from "ts-action";
|
||||
import u from "@yanick/updeep";
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
import screens from './screens';
|
||||
import armour from './armour';
|
||||
|
||||
const dux = new Updux({
|
||||
initial: {
|
||||
mass: 0,
|
||||
cost: 0,
|
||||
hull: {
|
||||
rating: 1,
|
||||
advanced: false,
|
||||
cost: 2,
|
||||
mass: 1,
|
||||
}
|
||||
},
|
||||
subduxes: {
|
||||
screens,
|
||||
armour,
|
||||
}
|
||||
})
|
||||
|
||||
export default dux.asDux;
|
@ -1,17 +0,0 @@
|
||||
import tap from 'tap';
|
||||
|
||||
import ship, { actions } from '.';
|
||||
|
||||
ship.dispatch( actions.set_ship_mass(100));
|
||||
|
||||
ship.dispatch( actions.set_ftl('standard'));
|
||||
|
||||
tap.match(
|
||||
ship.getState(),
|
||||
{
|
||||
ship_type: { mass: 100 },
|
||||
ftl: { type: 'standard', cost: 20, mass: 10 },
|
||||
},
|
||||
'standard ftl drive'
|
||||
);
|
||||
|
@ -1,38 +0,0 @@
|
||||
import flow from 'lodash/fp/flow.js';
|
||||
import sumBy from 'lodash/fp/sumBy.js';
|
||||
import pick from 'lodash/fp/pick.js';
|
||||
import filter from 'lodash/fp/filter.js';
|
||||
import flattenDeep from 'lodash/fp/flattenDeep.js';
|
||||
import has from 'lodash/fp/has.js';
|
||||
|
||||
const expand_cost_mass = (obj={}) => ([
|
||||
pick(['cost','mass'],obj),
|
||||
...Object.values(obj || {}).filter( val => typeof val === 'object' ).map(
|
||||
val => expand_cost_mass(val)
|
||||
)
|
||||
]);
|
||||
|
||||
export function calc_ship_req(ship) {
|
||||
|
||||
console.log(ship);
|
||||
let { general, ...rest } = ship;
|
||||
|
||||
//if(!general) general = {};
|
||||
|
||||
const items = flow(
|
||||
expand_cost_mass,
|
||||
flattenDeep,
|
||||
filter(has('cost'))
|
||||
)({
|
||||
...rest,
|
||||
cost: general.mass, mass: 0
|
||||
})
|
||||
|
||||
return {
|
||||
mass: sumBy('mass',items),
|
||||
cost: sumBy('cost',items),
|
||||
}
|
||||
}
|
||||
|
||||
// to get around 3.00001 ceiling up to 4
|
||||
export const ceil = number => Math.ceil( Math.round(10*number)/10 );
|
@ -1,21 +0,0 @@
|
||||
import Updux from "updux";
|
||||
import { action, payload } from "ts-action";
|
||||
import u from "@yanick/updeep";
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
import weapons from './weapons';
|
||||
import adfc from './adfc';
|
||||
|
||||
const dux = new Updux({
|
||||
initial: {
|
||||
firecons: {
|
||||
nbr: 0, cost: 0, mass: 0
|
||||
}
|
||||
},
|
||||
subduxes: {
|
||||
weapons,
|
||||
adfc,
|
||||
}
|
||||
})
|
||||
|
||||
export default dux.asDux;
|
@ -1,51 +0,0 @@
|
||||
import matches from 'lodash/matches.js';
|
||||
import Updux from "updux";
|
||||
import { action, payload } from "ts-action";
|
||||
import u from "@yanick/updeep";
|
||||
import { createSelector } from "reselect";
|
||||
import { weapon_cost_mass } from "../../weapons/rules";
|
||||
|
||||
const add_weapon = action("add_weapon", payload());
|
||||
const remove_weapon = action("remove_weapon", payload());
|
||||
|
||||
const uu = (transform) => (state) => transform(state)(state);
|
||||
|
||||
const with_reqs = uu((weapon) => u(weapon_cost_mass(weapon)));
|
||||
|
||||
const dux = new Updux({
|
||||
initial: [],
|
||||
});
|
||||
|
||||
const weapon_initial = {
|
||||
beam: {
|
||||
weapon_type: "beam",
|
||||
weapon_class: 1,
|
||||
arcs: ["F", "A", "FS", "FP", "AS", "AP"],
|
||||
},
|
||||
submunition: {
|
||||
weapon_type: "submunition",
|
||||
arcs: ["F"],
|
||||
},
|
||||
pds: { weapon_type: "pds" },
|
||||
scattergun: { weapon_type: "scattergun" },
|
||||
needle: { weapon_type: "needle", arcs: ["F"] },
|
||||
};
|
||||
|
||||
dux.addMutation(add_weapon, (type) => (state) => {
|
||||
const id = 1 + Math.max(0, ...state.map(({ id }) => id));
|
||||
return [...state, { ...with_reqs(weapon_initial[type]), id }];
|
||||
});
|
||||
|
||||
dux.addMutation(remove_weapon, (id) => (state) =>
|
||||
state.filter((w) => w.id !== id)
|
||||
);
|
||||
|
||||
const set_weapon = action("set_weapon", payload());
|
||||
|
||||
dux.addMutation(set_weapon, (payload) =>
|
||||
u.map(
|
||||
u.if(matches({ id: payload.id }), (state) => with_reqs(u(payload, state)))
|
||||
)
|
||||
);
|
||||
|
||||
export default dux.asDux;
|
@ -1,5 +0,0 @@
|
||||
import dux from ".";
|
||||
import tap from "tap";
|
||||
|
||||
const state = dux.upreducer(dux.actions.add_weapon("beam"))([]);
|
||||
tap.equal(state[0].arcs.length, 6, "default beam is all arcs");
|
@ -1,29 +0,0 @@
|
||||
import tap from 'tap';
|
||||
import { weapon_cost_mass } from './rules';
|
||||
|
||||
const cases = [
|
||||
[{
|
||||
weapon_type: "beam",
|
||||
weapon_class: 2,
|
||||
arcs: [ 'AP', 'A', 'AF' ]
|
||||
},{
|
||||
cost: 6,
|
||||
mass: 2,
|
||||
}
|
||||
],
|
||||
[{
|
||||
weapon_type: "beam",
|
||||
weapon_class: 1,
|
||||
arcs: [ 'AP', 'A', 'AF' ]
|
||||
},{
|
||||
mass: 1,
|
||||
cost: 3,
|
||||
}
|
||||
],
|
||||
[{ weapon_type: "beam", weapon_class: 3, arcs: [ 'AP', 'A', 'AF' ] },{ mass: 6, cost: 18, } ],
|
||||
[{ weapon_type: "beam", weapon_class: 4, arcs: [ 'AP', 'A', 'AF' ] },{ mass: 12, cost: 36, } ],
|
||||
]
|
||||
|
||||
cases.forEach( ([weapon,expected]) =>
|
||||
tap.match(
|
||||
weapon_cost_mass(weapon), expected, JSON.stringify(weapon) ) );
|
Loading…
Reference in New Issue
Block a user