198 lines
4.6 KiB
JavaScript
198 lines
4.6 KiB
JavaScript
import * as R from 'remeda';
|
|
import PouchDB from 'pouchdb';
|
|
import { writable, derived, get } from 'svelte/store';
|
|
import { genNextBattle } from './genNextBattle.js';
|
|
import u from '@yanick/updeep-remeda';
|
|
|
|
const seedCampaign = {
|
|
status: 'ongoing', // win, lost
|
|
score: 0,
|
|
battles: [],
|
|
};
|
|
|
|
function campaignStatus(campaign) {
|
|
if (campaign.battles.length <= 6) return 'ongoing';
|
|
|
|
if (R.last(campaign.battles).status === 'won') return 'won';
|
|
|
|
if (
|
|
campaign.battles.length - 6 >=
|
|
campaign.battles.slice(0, 6).filter(({ status }) => status === 'won')
|
|
)
|
|
return 'lost';
|
|
|
|
return 'ongoing';
|
|
}
|
|
|
|
function calculateScore(campaign) {
|
|
const values = [
|
|
-campaign.battles.slice(0, 6).filter(({ wave }) => wave === 2).length,
|
|
-campaign.battles.slice(6).filter(({ status }) => status === 'lost')
|
|
.length,
|
|
...campaign.battles
|
|
.map(({ difficulty }) => parseInt(difficulty))
|
|
.map((x) => (Number.isNaN(x) ? 0 : x)),
|
|
];
|
|
return values.reduce((a, b) => a + b, 0);
|
|
}
|
|
|
|
export function updateBattle(campaign, battleId, status) {
|
|
const battle = campaign.battles[battleId - 1];
|
|
if (status === 'lost' && battle.wave == 1 && battle.id < 7) {
|
|
campaign = u.updateIn(campaign, `battles.${battleId - 1}`, {
|
|
wave: 2,
|
|
});
|
|
campaign = u.updateIn(campaign, 'score', calculateScore(campaign));
|
|
return campaign;
|
|
}
|
|
|
|
campaign = u.updateIn(campaign, `battles.${battleId - 1}`, {
|
|
status,
|
|
});
|
|
|
|
campaign = u.updateIn(campaign, 'score', calculateScore(campaign));
|
|
|
|
campaign = u(campaign, {
|
|
status: campaignStatus(campaign),
|
|
});
|
|
if (campaign.status === 'ongoing') {
|
|
campaign = u(campaign, {
|
|
battles: (battles) => [
|
|
...battles,
|
|
u(genNextBattle(battles), {
|
|
id: battles.length + 1,
|
|
}),
|
|
],
|
|
});
|
|
}
|
|
return campaign;
|
|
}
|
|
|
|
export function genApi(options = {}) {
|
|
// if (options.local) MyPouch.plugin(pouchMem);
|
|
if (options.pouch) options.pouch(PouchDB);
|
|
|
|
const pouchdb = new PouchDB(
|
|
'Campaigns',
|
|
options.local
|
|
? {
|
|
adapter: 'memory',
|
|
}
|
|
: {},
|
|
);
|
|
|
|
const campaignsCore = writable([]);
|
|
|
|
pouchdb
|
|
.allDocs({ include_docs: true })
|
|
.then((r) => r.rows.map(({ id, doc }) => [id, doc]))
|
|
.then(Object.fromEntries)
|
|
.then(campaignsCore.set);
|
|
|
|
pouchdb
|
|
.changes({ since: 'now', live: true, include_docs: true })
|
|
.on('change', (change) => {
|
|
if (change.deleted) {
|
|
campaignsCore.update(u.updateIn(change.id, u.skip));
|
|
} else {
|
|
campaignsCore.update(u.updateIn(change.id, change.doc));
|
|
}
|
|
});
|
|
|
|
const campaigns = derived(campaignsCore, Object.values);
|
|
|
|
const addCampaign = (name) =>
|
|
pouchdb.post({
|
|
name,
|
|
...seedCampaign,
|
|
battles: [{ id: 1, ...genNextBattle() }],
|
|
});
|
|
|
|
const activeCampaignId = writable(0);
|
|
|
|
const setActiveCampaign = activeCampaignId.set;
|
|
|
|
const activeCampaign = derived(
|
|
[campaignsCore, activeCampaignId],
|
|
([$c, $id]) => $c[$id],
|
|
);
|
|
|
|
const setBattleDifficulty = (battleId, difficulty) => {
|
|
pouchdb
|
|
.put(
|
|
u.updateIn(get(activeCampaign), `battles.${battleId - 1}`, {
|
|
difficulty,
|
|
}),
|
|
)
|
|
.catch((e) => console.error(e)); // eslint-disable-line
|
|
};
|
|
|
|
const setBattleVerdict = (battleId, status) => {
|
|
const campaign = updateBattle(get(activeCampaign), battleId, status);
|
|
// eslint-disable-next-line
|
|
pouchdb.put(campaign).catch((e) => console.error(e));
|
|
};
|
|
|
|
const deleteCampaign = (_id) =>
|
|
pouchdb.remove(get(campaigns).find(u.matches({ _id })));
|
|
|
|
const setCharacter = (battleId, characterId, value) => {
|
|
const campaign = u.updateIn(
|
|
get(activeCampaign),
|
|
['battles', battleId, 'additionalCharacters', 'selection'],
|
|
value,
|
|
);
|
|
|
|
pouchdb.put(campaign);
|
|
};
|
|
|
|
const setCity = (battleId, value) => {
|
|
const campaign = u.updateIn(
|
|
get(activeCampaign),
|
|
['battles', battleId, 'city', 'selection'],
|
|
value,
|
|
);
|
|
|
|
pouchdb.put(campaign);
|
|
};
|
|
|
|
return {
|
|
campaigns,
|
|
activeCampaign,
|
|
event: {
|
|
setCity,
|
|
setCharacter,
|
|
deleteCampaign,
|
|
addCampaign,
|
|
setActiveCampaign,
|
|
setBattleVerdict,
|
|
setBattleDifficulty,
|
|
},
|
|
};
|
|
|
|
/*
|
|
const activeCampaign = writeable();
|
|
|
|
addCampaign: (name) =>
|
|
storage.campaigns.add({
|
|
name,
|
|
...seedCampaign,
|
|
battles: [{ id: 1, ...genNextBattle() }],
|
|
}),
|
|
|
|
return {
|
|
campaigns,
|
|
event: {
|
|
,
|
|
addCampaign: (name) =>
|
|
storage.campaigns.add({
|
|
name,
|
|
...seedCampaign,
|
|
battles: [{ id: 1, ...genNextBattle() }],
|
|
}),
|
|
deleteCampaign: (id) => storage.campaigns.delete(id),
|
|
},
|
|
};
|
|
*/
|
|
}
|